mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-29 09:49:04 +00:00
android, desktop, ios: warn on low storage before exporting or migrating the database, reject oversized migration
This commit is contained in:
+24
@@ -594,12 +594,36 @@ fun deleteChatDatabaseFilesAndState() {
|
||||
ntfManager.cancelAllNotifications()
|
||||
}
|
||||
|
||||
// Advisory check before exporting the database — export transiently uses ~2x the data on disk.
|
||||
suspend fun confirmExportStorage(): Boolean {
|
||||
databaseExportDir.mkdirs()
|
||||
val requiredBytes = 2L * (
|
||||
directoryFileCountAndSize(appFilesDir.absolutePath).second +
|
||||
directoryFileCountAndSize(wallpapersDir.absolutePath).second +
|
||||
File(dataDir, chatDatabaseFileName).length() +
|
||||
File(dataDir, agentDatabaseFileName).length()
|
||||
)
|
||||
val availableBytes = databaseExportDir.usableSpace
|
||||
if (availableBytes >= requiredBytes) return true
|
||||
val proceed = CompletableDeferred<Boolean>()
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(MR.strings.not_enough_storage_title),
|
||||
text = String.format(generalGetString(MR.strings.not_enough_storage_desc), formatBytes(requiredBytes), formatBytes(availableBytes)),
|
||||
confirmText = generalGetString(MR.strings.chat_database_exported_continue),
|
||||
onConfirm = { proceed.complete(true) },
|
||||
onDismiss = { proceed.complete(false) },
|
||||
onDismissRequest = { proceed.complete(false) },
|
||||
)
|
||||
return proceed.await()
|
||||
}
|
||||
|
||||
private suspend fun exportArchive(
|
||||
m: ChatModel,
|
||||
progressIndicator: MutableState<Boolean>,
|
||||
chatArchiveFile: MutableState<String?>,
|
||||
saveArchiveLauncher: FileChooserLauncher
|
||||
): Boolean {
|
||||
if (!confirmExportStorage()) return false
|
||||
progressIndicator.value = true
|
||||
try {
|
||||
val (archiveFile, archiveErrors) = exportChatArchive(m, null, chatArchiveFile)
|
||||
|
||||
+4
@@ -126,6 +126,10 @@ const val MAX_FILE_SIZE_SMP: Long = 8000000
|
||||
|
||||
const val MAX_FILE_SIZE_XFTP: Long = 1_073_741_824 // 1GB
|
||||
|
||||
// Hard limit for standalone XFTP uploads (e.g. device migration archive);
|
||||
// mirrors maxFileSizeHard (gb 5) in simplexmq Simplex/FileTransfer/Description.hs
|
||||
const val MAX_FILE_SIZE_XFTP_HARD: Long = 5_368_709_120 // 5GB
|
||||
|
||||
const val MAX_FILE_SIZE_LOCAL: Long = Long.MAX_VALUE
|
||||
|
||||
expect fun getAppFileUri(fileName: String): URI
|
||||
|
||||
+17
-2
@@ -274,7 +274,7 @@ private fun MutableState<MigrationFromState>.ArchivingView() {
|
||||
ProgressView()
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
exportArchive()
|
||||
exportArchiveCheckingStorage()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,6 +480,13 @@ private suspend fun MutableState<MigrationFromState>.verifyDatabasePassphrase(db
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableState<MigrationFromState>.exportArchiveCheckingStorage() {
|
||||
withBGApi {
|
||||
if (confirmExportStorage()) exportArchive()
|
||||
else state = MigrationFromState.UploadConfirmation
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableState<MigrationFromState>.exportArchive() {
|
||||
withLongRunningApi {
|
||||
try {
|
||||
@@ -506,7 +513,15 @@ 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)
|
||||
if (totalBytes > MAX_FILE_SIZE_XFTP_HARD) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.migrate_from_device_database_too_large_title),
|
||||
String.format(generalGetString(MR.strings.migrate_from_device_database_too_large_desc), formatBytes(totalBytes), formatBytes(MAX_FILE_SIZE_XFTP_HARD))
|
||||
)
|
||||
state = MigrationFromState.UploadConfirmation
|
||||
} else {
|
||||
state = MigrationFromState.DatabaseInit(totalBytes, archivePath)
|
||||
}
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.migrate_from_device_exported_file_doesnt_exist))
|
||||
state = MigrationFromState.UploadConfirmation
|
||||
|
||||
@@ -2831,6 +2831,10 @@
|
||||
<string name="migrate_from_device_to_another_device">Migrate to another device</string>
|
||||
<string name="migrate_from_device_error_saving_settings">Error saving settings</string>
|
||||
<string name="migrate_from_device_exported_file_doesnt_exist">Exported file doesn\'t exist</string>
|
||||
<string name="migrate_from_device_database_too_large_title">Database is too large</string>
|
||||
<string name="migrate_from_device_database_too_large_desc">The exported archive (%1$s) is larger than the maximum size supported for migration (%2$s).</string>
|
||||
<string name="not_enough_storage_title">You may not have enough storage</string>
|
||||
<string name="not_enough_storage_desc">Exporting the database may need about %1$s of free space, but only %2$s is available. Continue anyway?</string>
|
||||
<string name="migrate_from_device_error_exporting_archive">Error exporting chat database</string>
|
||||
<string name="migrate_from_device_database_init">Preparing upload</string>
|
||||
<string name="migrate_from_device_error_uploading_archive">Error uploading the archive</string>
|
||||
|
||||
Reference in New Issue
Block a user