Skip to content

Commit

Permalink
Show progress indicator when importing/exporting messages
Browse files Browse the repository at this point in the history
One small step towards FossifyOrg/General-Discussion#120
  • Loading branch information
naveensingh committed Jan 3, 2025
1 parent 5ed8c0a commit f66aa77
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package org.fossify.messages.activities

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.DocumentsContract
import androidx.activity.result.contract.ActivityResultContracts
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream
import org.fossify.commons.activities.ManageBlockedNumbersActivity
import org.fossify.commons.dialogs.ChangeDateTimeFormatDialog
import org.fossify.commons.dialogs.ConfirmationDialog
Expand All @@ -24,7 +20,6 @@ import org.fossify.commons.extensions.getFontSizeText
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.isOrWasThankYouInstalled
import org.fossify.commons.extensions.launchPurchaseThankYouIntent
import org.fossify.commons.extensions.showErrorToast
import org.fossify.commons.extensions.toast
import org.fossify.commons.extensions.updateTextColors
import org.fossify.commons.extensions.viewBinding
Expand Down Expand Up @@ -56,7 +51,6 @@ import org.fossify.messages.helpers.LOCK_SCREEN_NOTHING
import org.fossify.messages.helpers.LOCK_SCREEN_SENDER
import org.fossify.messages.helpers.LOCK_SCREEN_SENDER_MESSAGE
import org.fossify.messages.helpers.MessagesImporter
import org.fossify.messages.helpers.MessagesReader
import org.fossify.messages.helpers.refreshMessages
import java.util.Locale
import kotlin.system.exitProcess
Expand All @@ -81,11 +75,13 @@ class SettingsActivity : SimpleActivity() {
}
}

private var exportMessagesDialog: ExportMessagesDialog? = null

private val saveDocument =
registerForActivityResult(ActivityResultContracts.CreateDocument(messagesFileType)) { uri ->
if (uri != null) {
toast(org.fossify.commons.R.string.exporting)
exportMessages(uri)
exportMessagesDialog?.exportMessages(uri)
}
}

Expand Down Expand Up @@ -157,7 +153,7 @@ class SettingsActivity : SimpleActivity() {

private fun setupMessagesExport() {
binding.settingsExportMessagesHolder.setOnClickListener {
ExportMessagesDialog(this) { fileName ->
exportMessagesDialog = ExportMessagesDialog(this) { fileName ->
saveDocument.launch("$fileName.json")
}
}
Expand All @@ -169,41 +165,6 @@ class SettingsActivity : SimpleActivity() {
}
}

@OptIn(kotlinx.serialization.ExperimentalSerializationApi::class)
private fun exportMessages(uri: Uri) {
ensureBackgroundThread {
var success = false
try {
MessagesReader(this).getMessagesToExport(
config.exportSms,
config.exportMms
) { messagesToExport ->
if (messagesToExport.isEmpty()) {
toast(org.fossify.commons.R.string.no_entries_for_exporting)
return@getMessagesToExport
}
val json = Json { encodeDefaults = true }
contentResolver.openOutputStream(uri)!!.buffered().use { outputStream ->
json.encodeToStream(messagesToExport, outputStream)
}
success = true
toast(org.fossify.commons.R.string.exporting_successful)
}
} catch (e: Throwable) { // also catch OutOfMemoryError etc.
showErrorToast(e.toString())
} finally {
if (!success) {
// delete the file to avoid leaving behind an empty/corrupt file
try {
DocumentsContract.deleteDocument(contentResolver, uri)
} catch (ignored: Exception) {
// ignored because we don't want to overwhelm the user with two error messages
}
}
}
}
}

override fun onPause() {
super.onPause()
blockedNumbersAtPause = getBlockedNumbers().hashCode()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,126 @@
package org.fossify.messages.dialogs

import android.annotation.SuppressLint
import android.net.Uri
import android.provider.DocumentsContract
import androidx.appcompat.app.AlertDialog
import org.fossify.commons.extensions.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream
import org.fossify.commons.extensions.getAlertDialogBuilder
import org.fossify.commons.extensions.getCurrentFormattedDateTime
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.isAValidFilename
import org.fossify.commons.extensions.setupDialogStuff
import org.fossify.commons.extensions.showErrorToast
import org.fossify.commons.extensions.toast
import org.fossify.commons.extensions.value
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.messages.R
import org.fossify.messages.activities.SimpleActivity
import org.fossify.messages.databinding.DialogExportMessagesBinding
import org.fossify.messages.extensions.config
import org.fossify.messages.helpers.MessagesReader

class ExportMessagesDialog(
private val activity: SimpleActivity,
private val callback: (fileName: String) -> Unit,
) {
private val config = activity.config
private var dialog: AlertDialog? = null

init {
val binding = DialogExportMessagesBinding.inflate(activity.layoutInflater).apply {
exportSmsCheckbox.isChecked = config.exportSms
exportMmsCheckbox.isChecked = config.exportMms
exportMessagesFilename.setText(
activity.getString(R.string.messages) + "_" + activity.getCurrentFormattedDateTime()
)
}
@SuppressLint("SetTextI18n")
private val binding = DialogExportMessagesBinding.inflate(activity.layoutInflater).apply {
exportSmsCheckbox.isChecked = config.exportSms
exportMmsCheckbox.isChecked = config.exportMms
exportMessagesFilename.setText(
"${activity.getString(R.string.messages)}_${activity.getCurrentFormattedDateTime()}"
)
}

init {
activity.getAlertDialogBuilder()
.setPositiveButton(org.fossify.commons.R.string.ok, null)
.setNegativeButton(org.fossify.commons.R.string.cancel, null)
.apply {
activity.setupDialogStuff(binding.root, this, R.string.export_messages) { alertDialog ->
activity.setupDialogStuff(
view = binding.root,
dialog = this,
titleId = R.string.export_messages
) { alertDialog ->
dialog = alertDialog
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
config.exportSms = binding.exportSmsCheckbox.isChecked
config.exportMms = binding.exportMmsCheckbox.isChecked
val filename = binding.exportMessagesFilename.value
when {
filename.isEmpty() -> activity.toast(org.fossify.commons.R.string.empty_name)
filename.isAValidFilename() -> {
callback(filename)
alertDialog.dismiss()
}

filename.isAValidFilename() -> callback(filename)
else -> activity.toast(org.fossify.commons.R.string.invalid_name)
}
}
}
}
}

fun exportMessages(uri: Uri) {
dialog!!.apply {
setCanceledOnTouchOutside(false)
arrayOf(
binding.exportMmsCheckbox,
binding.exportSmsCheckbox,
getButton(AlertDialog.BUTTON_POSITIVE),
getButton(AlertDialog.BUTTON_NEGATIVE)
).forEach {
it.isEnabled = false
it.alpha = 0.6f
}

binding.exportProgress.setIndicatorColor(activity.getProperPrimaryColor())
binding.exportProgress.post {
binding.exportProgress.show()
}
export(uri)
}
}

@OptIn(kotlinx.serialization.ExperimentalSerializationApi::class)
private fun export(uri: Uri) {
ensureBackgroundThread {
var success = false
try {
MessagesReader(activity).getMessagesToExport(
getSms = config.exportSms,
getMms = config.exportMms
) { messagesToExport ->
if (messagesToExport.isEmpty()) {
activity.toast(org.fossify.commons.R.string.no_entries_for_exporting)
dismiss()
return@getMessagesToExport
}
val json = Json { encodeDefaults = true }
activity.contentResolver.openOutputStream(uri)!!.buffered()
.use { outputStream ->
json.encodeToStream(messagesToExport, outputStream)
}
success = true
activity.toast(org.fossify.commons.R.string.exporting_successful)
}
} catch (e: Throwable) {
activity.showErrorToast(e.toString())
} finally {
if (!success) {
// delete the file to avoid leaving behind an empty/corrupt file
try {
DocumentsContract.deleteDocument(activity.contentResolver, uri)
} catch (ignored: Exception) {
// ignored because we don't want to show two error messages
}
}

dismiss()
}
}
}

private fun dismiss() = dialog?.dismiss()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.fossify.messages.dialogs

import androidx.appcompat.app.AlertDialog
import org.fossify.commons.extensions.getAlertDialogBuilder
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.setupDialogStuff
import org.fossify.commons.extensions.toast
import org.fossify.commons.helpers.ensureBackgroundThread
Expand All @@ -27,12 +28,20 @@ class ImportMessagesDialog(
importMmsCheckbox.isChecked = config.importMms
}

binding.importProgress.setIndicatorColor(activity.getProperPrimaryColor())

activity.getAlertDialogBuilder()
.setPositiveButton(org.fossify.commons.R.string.ok, null)
.setNegativeButton(org.fossify.commons.R.string.cancel, null)
.apply {
activity.setupDialogStuff(binding.root, this, R.string.import_messages) { alertDialog ->
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
activity.setupDialogStuff(
view = binding.root,
dialog = this,
titleId = R.string.import_messages
) { alertDialog ->
val positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
val negativeButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE)
positiveButton.setOnClickListener {
if (ignoreClicks) {
return@setOnClickListener
}
Expand All @@ -46,6 +55,19 @@ class ImportMessagesDialog(
activity.toast(org.fossify.commons.R.string.importing)
config.importSms = binding.importSmsCheckbox.isChecked
config.importMms = binding.importMmsCheckbox.isChecked

alertDialog.setCanceledOnTouchOutside(false)
binding.importProgress.show()
arrayOf(
binding.importMmsCheckbox,
binding.importSmsCheckbox,
positiveButton,
negativeButton
).forEach {
it.isEnabled = false
it.alpha = 0.6f
}

ensureBackgroundThread {
MessagesImporter(activity).restoreMessages(messages) {
handleParseResult(it)
Expand Down
20 changes: 17 additions & 3 deletions app/src/main/res/layout/dialog_export_messages.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/export_messages_scrollview"
android:layout_width="match_parent"
Expand All @@ -10,14 +11,25 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin">
android:paddingTop="@dimen/activity_margin">

<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/export_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_margin"
android:indeterminate="true"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:showAnimationBehavior="inward" />

<org.fossify.commons.views.MyTextInputLayout
android:id="@+id/export_messages_filename_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/activity_margin"
android:hint="@string/filename_without_json">

<com.google.android.material.textfield.TextInputEditText
Expand All @@ -36,12 +48,14 @@
android:id="@+id/export_sms_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/activity_margin"
android:text="@string/export_sms" />

<org.fossify.commons.views.MyAppCompatCheckbox
android:id="@+id/export_mms_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/activity_margin"
android:text="@string/export_mms" />

</LinearLayout>
Expand Down
21 changes: 18 additions & 3 deletions app/src/main/res/layout/dialog_import_messages.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/import_messages_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
Expand All @@ -9,14 +11,26 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin">
android:paddingTop="@dimen/activity_margin">

<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/import_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/normal_margin"
android:indeterminate="true"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:showAnimationBehavior="inward"
tools:visibility="visible" />

<org.fossify.commons.views.MyAppCompatCheckbox
android:id="@+id/import_sms_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/activity_margin"
android:paddingTop="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:text="@string/import_sms" />
Expand All @@ -25,6 +39,7 @@
android:id="@+id/import_mms_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/activity_margin"
android:paddingTop="@dimen/small_margin"
android:paddingBottom="@dimen/small_margin"
android:text="@string/import_mms" />
Expand Down

0 comments on commit f66aa77

Please sign in to comment.