android, desktop: show database import/export errors (#4601)

* android, desktop: show database import/export errors

* no line
This commit is contained in:
Stanislav Dmitrenko
2024-08-06 15:37:55 +01:00
committed by GitHub
parent 240131a023
commit 5a42c0c1d2
4 changed files with 60 additions and 16 deletions
@@ -522,9 +522,17 @@ private fun exportArchive(
progressIndicator.value = true
withLongRunningApi {
try {
val archiveFile = exportChatArchive(m, null, chatArchiveName, chatArchiveTime, chatArchiveFile)
val (archiveFile, archiveErrors) = exportChatArchive(m, null, chatArchiveName, chatArchiveTime, chatArchiveFile)
chatArchiveFile.value = archiveFile
saveArchiveLauncher.launch(archiveFile.substringAfterLast(File.separator))
if (archiveErrors.isEmpty()) {
saveArchiveLauncher.launch(archiveFile.substringAfterLast(File.separator))
} else {
showArchiveExportedWithErrorsAlert(generalGetString(MR.strings.chat_database_exported_save), archiveErrors) {
withLongRunningApi {
saveArchiveLauncher.launch(archiveFile.substringAfterLast(File.separator))
}
}
}
progressIndicator.value = false
} catch (e: Error) {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_exporting_chat_database), e.toString())
@@ -539,7 +547,7 @@ suspend fun exportChatArchive(
chatArchiveName: MutableState<String?>,
chatArchiveTime: MutableState<Instant?>,
chatArchiveFile: MutableState<String?>
): String {
): Pair<String, List<ArchiveError>> {
val archiveTime = Clock.System.now()
val ts = SimpleDateFormat("yyyy-MM-dd'T'HHmmss", Locale.US).format(Date.from(archiveTime.toJavaInstant()))
val archiveName = "simplex-chat.$ts.zip"
@@ -550,7 +558,7 @@ suspend fun exportChatArchive(
controller.apiSaveAppSettings(AppSettings.current.prepareForExport())
}
wallpapersDir.mkdirs()
m.controller.apiExportArchive(config)
val archiveErrors = m.controller.apiExportArchive(config)
if (storagePath == null) {
deleteOldArchive(m)
m.controller.appPrefs.chatArchiveName.set(archiveName)
@@ -559,7 +567,7 @@ suspend fun exportChatArchive(
chatArchiveName.value = archiveName
chatArchiveTime.value = archiveTime
chatArchiveFile.value = archivePath
return archivePath
return archivePath to archiveErrors
}
private fun deleteOldArchive(m: ChatModel) {
@@ -592,6 +600,28 @@ private fun importArchiveAlert(
)
}
fun showArchiveImportedWithErrorsAlert(archiveErrors: List<ArchiveError>) {
AlertManager.shared.showAlertMsg(
title = generalGetString(MR.strings.chat_database_imported),
text = generalGetString(MR.strings.restart_the_app_to_use_imported_chat_database) + "\n\n" + generalGetString(MR.strings.non_fatal_errors_occured_during_import) + archiveErrorsText(archiveErrors))
}
fun showArchiveExportedWithErrorsAlert(description: String, archiveErrors: List<ArchiveError>, onConfirm: () -> Unit) {
AlertManager.shared.showAlertMsg(
title = generalGetString(MR.strings.chat_database_exported_title),
text = description + "\n\n" + generalGetString(MR.strings.chat_database_exported_not_all_files) + archiveErrorsText(archiveErrors),
confirmText = generalGetString(MR.strings.chat_database_exported_continue),
onConfirm = onConfirm
)
}
private fun archiveErrorsText(errs: List<ArchiveError>): String = "\n" + errs.map {
when (it) {
is ArchiveError.ArchiveErrorImport -> it.importError
is ArchiveError.ArchiveErrorFile -> "${it.file}: ${it.fileError}"
}
}.joinToString(separator = "\n")
private fun importArchive(
m: ChatModel,
importedArchiveURI: URI,
@@ -621,7 +651,7 @@ private fun importArchive(
}
} else {
operationEnded(m, progressIndicator) {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.chat_database_imported), text = generalGetString(MR.strings.restart_the_app_to_use_imported_chat_database) + "\n" + generalGetString(MR.strings.non_fatal_errors_occured_during_import))
showArchiveImportedWithErrorsAlert(archiveErrors)
}
}
} catch (e: Error) {
@@ -480,12 +480,13 @@ private fun MutableState<MigrationFromState>.exportArchive() {
withLongRunningApi {
try {
getMigrationTempFilesDirectory().mkdir()
val archivePath = exportChatArchive(chatModel, getMigrationTempFilesDirectory(), mutableStateOf(""), mutableStateOf(Instant.DISTANT_PAST), mutableStateOf(""))
val totalBytes = File(archivePath).length()
if (totalBytes > 0L) {
state = MigrationFromState.DatabaseInit(totalBytes, archivePath)
val (archivePath, archiveErrors) = exportChatArchive(chatModel, getMigrationTempFilesDirectory(), mutableStateOf(""), mutableStateOf(Instant.DISTANT_PAST), mutableStateOf(""))
if (archiveErrors.isEmpty()) {
uploadArchive(archivePath)
} else {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.migrate_from_device_exported_file_doesnt_exist))
showArchiveExportedWithErrorsAlert(generalGetString(MR.strings.chat_database_exported_migrate), archiveErrors) {
uploadArchive(archivePath)
}
state = MigrationFromState.UploadConfirmation
}
} catch (e: Exception) {
@@ -498,6 +499,17 @@ private fun MutableState<MigrationFromState>.exportArchive() {
}
}
private fun MutableState<MigrationFromState>.uploadArchive(archivePath: String) {
val totalBytes = File(archivePath).length()
if (totalBytes > 0L) {
state = MigrationFromState.DatabaseInit(totalBytes, archivePath)
} else {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.migrate_from_device_exported_file_doesnt_exist))
state = MigrationFromState.UploadConfirmation
}
}
suspend fun initTemporaryDatabase(tempDatabaseFile: File, netCfg: NetCfg): Pair<ChatCtrl, User>? {
val (status, ctrl) = chatInitTemporaryDatabase(tempDatabaseFile.absolutePath)
showErrorOnMigrationIfNeeded(status)
@@ -597,10 +597,7 @@ private fun MutableState<MigrationToState?>.importArchive(archivePath: String, n
val config = ArchiveConfig(archivePath, parentTempDirectory = databaseExportDir.toString())
val archiveErrors = controller.apiImportArchive(config)
if (archiveErrors.isNotEmpty()) {
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.chat_database_imported),
generalGetString(MR.strings.non_fatal_errors_occured_during_import)
)
showArchiveImportedWithErrorsAlert(archiveErrors)
}
state = MigrationToState.Passphrase("", netCfg)
MigrationToDeviceState.save(MigrationToDeviceState.Passphrase(netCfg))
@@ -1196,7 +1196,7 @@
<string name="error_importing_database">Error importing chat database</string>
<string name="chat_database_imported">Chat database imported</string>
<string name="restart_the_app_to_use_imported_chat_database">Restart the app to use imported chat database.</string>
<string name="non_fatal_errors_occured_during_import">Some non-fatal errors occurred during import - you may see Chat console for more details.</string>
<string name="non_fatal_errors_occured_during_import">Some non-fatal errors occurred during import:</string>
<string name="delete_chat_profile_question">Delete chat profile?</string>
<string name="delete_chat_profile_action_cannot_be_undone_warning">This action cannot be undone - your profile, contacts, messages and files will be irreversibly lost.</string>
<string name="chat_database_deleted">Chat database deleted</string>
@@ -1222,6 +1222,11 @@
<string name="enable_automatic_deletion_message">This action cannot be undone - the messages sent and received earlier than selected will be deleted. It may take several minutes.</string>
<string name="delete_messages">Delete messages</string>
<string name="error_changing_message_deletion">Error changing setting</string>
<string name="chat_database_exported_title">Chat database exported</string>
<string name="chat_database_exported_save">You may save the exported archive.</string>
<string name="chat_database_exported_migrate">You may migrate the exported database.</string>
<string name="chat_database_exported_not_all_files">Some file(s) were not exported</string>
<string name="chat_database_exported_continue">Continue</string>
<!-- DatabaseEncryptionView.kt -->
<string name="save_passphrase_in_keychain">Save passphrase in Keystore</string>