Show progress indicator when importing/exporting messages
One small step towards https://github.com/FossifyOrg/General-Discussion/issues/120
This commit is contained in:
parent
5ed8c0aacd
commit
f66aa77831
5 changed files with 157 additions and 66 deletions
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +153,7 @@ class SettingsActivity : SimpleActivity() {
|
|||
|
||||
private fun setupMessagesExport() {
|
||||
binding.settingsExportMessagesHolder.setOnClickListener {
|
||||
ExportMessagesDialog(this) { fileName ->
|
||||
exportMessagesDialog = ExportMessagesDialog(this) { fileName ->
|
||||
saveDocument.launch("$fileName.json")
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
@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 {
|
||||
val binding = DialogExportMessagesBinding.inflate(activity.layoutInflater).apply {
|
||||
exportSmsCheckbox.isChecked = config.exportSms
|
||||
exportMmsCheckbox.isChecked = config.exportMms
|
||||
exportMessagesFilename.setText(
|
||||
activity.getString(R.string.messages) + "_" + activity.getCurrentFormattedDateTime()
|
||||
)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue