From 4738286f4e2fb8726da2ad2fe80f155c5a6316c5 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:33:38 +0700 Subject: [PATCH] android, desktop: start/stop chat toggle refactoring (#5261) * android, desktop: start/stop chat toggle refactoring * changes * translations * better * better * do not start chat after export, always show run toggle (#5283) * update heading --------- Co-authored-by: Evgeny Poberezkin --- .../main/java/chat/simplex/app/SimplexApp.kt | 2 + apps/multiplatform/common/build.gradle.kts | 4 +- .../chat/simplex/common/model/SimpleXAPI.kt | 6 +- .../chat/simplex/common/platform/Core.kt | 9 + .../chat/simplex/common/platform/Files.kt | 2 +- .../common/views/database/ChatArchiveView.kt | 108 ------- .../views/database/DatabaseEncryptionView.kt | 8 +- .../common/views/database/DatabaseView.kt | 297 +++++++++--------- .../views/migration/MigrateFromDevice.kt | 2 +- .../common/views/migration/MigrateToDevice.kt | 60 +++- .../common/views/usersettings/SettingsView.kt | 2 +- .../commonMain/resources/MR/ar/strings.xml | 6 - .../commonMain/resources/MR/base/strings.xml | 10 +- .../commonMain/resources/MR/bg/strings.xml | 6 - .../commonMain/resources/MR/cs/strings.xml | 6 - .../commonMain/resources/MR/de/strings.xml | 6 - .../commonMain/resources/MR/el/strings.xml | 3 - .../commonMain/resources/MR/es/strings.xml | 6 - .../commonMain/resources/MR/fa/strings.xml | 6 - .../commonMain/resources/MR/fi/strings.xml | 6 - .../commonMain/resources/MR/fr/strings.xml | 6 - .../commonMain/resources/MR/hi/strings.xml | 4 - .../commonMain/resources/MR/hu/strings.xml | 6 - .../commonMain/resources/MR/in/strings.xml | 4 - .../commonMain/resources/MR/it/strings.xml | 6 - .../commonMain/resources/MR/iw/strings.xml | 6 - .../commonMain/resources/MR/ja/strings.xml | 6 - .../commonMain/resources/MR/ko/strings.xml | 6 - .../commonMain/resources/MR/lt/strings.xml | 6 - .../commonMain/resources/MR/nl/strings.xml | 6 - .../commonMain/resources/MR/pl/strings.xml | 6 - .../resources/MR/pt-rBR/strings.xml | 6 - .../commonMain/resources/MR/pt/strings.xml | 6 - .../commonMain/resources/MR/ro/strings.xml | 6 - .../commonMain/resources/MR/ru/strings.xml | 6 - .../commonMain/resources/MR/th/strings.xml | 6 - .../commonMain/resources/MR/tr/strings.xml | 6 - .../commonMain/resources/MR/uk/strings.xml | 6 - .../commonMain/resources/MR/vi/strings.xml | 5 - .../resources/MR/zh-rCN/strings.xml | 6 - .../resources/MR/zh-rTW/strings.xml | 6 - .../common/platform/AppCommon.desktop.kt | 2 + .../views/database/DatabaseView.desktop.kt | 4 +- 43 files changed, 236 insertions(+), 446 deletions(-) delete mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt index 13f9b888b9..f46ed4775f 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt @@ -28,6 +28,7 @@ import chat.simplex.common.model.ChatModel.withChats import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.call.* +import chat.simplex.common.views.database.deleteOldChatArchive import chat.simplex.common.views.helpers.* import chat.simplex.common.views.onboarding.OnboardingStage import com.jakewharton.processphoenix.ProcessPhoenix @@ -72,6 +73,7 @@ class SimplexApp: Application(), LifecycleEventObserver { runMigrations() tmpDir.deleteRecursively() tmpDir.mkdir() + deleteOldChatArchive() // Present screen for continue migration if it wasn't finished yet if (chatModel.migrationState.value != null) { diff --git a/apps/multiplatform/common/build.gradle.kts b/apps/multiplatform/common/build.gradle.kts index b9b307c8f4..ad67b7cf1e 100644 --- a/apps/multiplatform/common/build.gradle.kts +++ b/apps/multiplatform/common/build.gradle.kts @@ -266,7 +266,9 @@ afterEvaluate { if (isBase) { baseFormatting[lineId] = fixedLine.formatting(file.absolutePath) } else if (baseFormatting[lineId] != fixedLine.formatting(file.absolutePath)) { - errors.add("Incorrect formatting in string: $fixedLine \nin ${file.absolutePath}") + errors.add("Incorrect formatting in string: $fixedLine \nin ${file.absolutePath}.\n" + + "If you want to remove non-base translation, search this Regex and replace with empty value in IDE:\n" + + "[ ]*<.*\"${line.substringAfter("\"").substringBefore("\"")}\"[^/]*\\n*.*string>\\n") } finalLines.add(fixedLine) } else if (multiline.isEmpty() && startStringRegex.containsMatchIn(line)) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index def6d81897..7ada27d000 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -211,6 +211,9 @@ class AppPreferences { // Note that this situation can only happen if passphrase for the first database is incorrect because, otherwise, backend will re-create second database automatically val newDatabaseInitialized = mkBoolPreference(SHARED_PREFS_NEW_DATABASE_INITIALIZED, false) + /** after importing new database, this flag will be set and unset only after importing app settings in [initChatController] */ + val shouldImportAppSettings = mkBoolPreference(SHARED_PREFS_SHOULD_IMPORT_APP_SETTINGS, false) + val currentTheme = mkStrPreference(SHARED_PREFS_CURRENT_THEME, DefaultTheme.SYSTEM_THEME_NAME) val systemDarkTheme = mkStrPreference(SHARED_PREFS_SYSTEM_DARK_THEME, DefaultTheme.SIMPLEX.themeName) val currentThemeIds = mkMapPreference(SHARED_PREFS_CURRENT_THEME_IDs, mapOf(), encode = { @@ -425,6 +428,7 @@ class AppPreferences { private const val SHARED_PREFS_INITIALIZATION_VECTOR_SELF_DESTRUCT_PASSPHRASE = "InitializationVectorSelfDestructPassphrase" private const val SHARED_PREFS_ENCRYPTION_STARTED_AT = "EncryptionStartedAt" private const val SHARED_PREFS_NEW_DATABASE_INITIALIZED = "NewDatabaseInitialized" + private const val SHARED_PREFS_SHOULD_IMPORT_APP_SETTINGS = "ShouldImportAppSettings" private const val SHARED_PREFS_CONFIRM_DB_UPGRADES = "ConfirmDBUpgrades" private const val SHARED_PREFS_ONE_HAND_UI = "OneHandUI" private const val SHARED_PREFS_SELF_DESTRUCT = "LocalAuthenticationSelfDestruct" @@ -6909,7 +6913,7 @@ data class AppSettings( uiDarkColorScheme?.let { def.systemDarkTheme.set(it) } uiCurrentThemeIds?.let { def.currentThemeIds.set(it) } uiThemes?.let { def.themeOverrides.set(it.skipDuplicates()) } - oneHandUI?.let { def.oneHandUI.set(if (appPlatform.isAndroid) it else false) } + oneHandUI?.let { def.oneHandUI.set(it) } } companion object { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt index 08ca72c6bd..5262714099 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt @@ -119,6 +119,15 @@ suspend fun initChatController(useKey: String? = null, confirmMigrations: Migrat val user = chatController.apiGetActiveUser(null) chatModel.currentUser.value = user chatModel.conditions.value = chatController.getServerOperators(null) ?: ServerOperatorConditionsDetail.empty + if (appPrefs.shouldImportAppSettings.get()) { + try { + val appSettings = controller.apiGetAppSettings(AppSettings.current.prepareForExport()) + appSettings.importIntoApp() + appPrefs.shouldImportAppSettings.set(false) + } catch (e: Exception) { + Log.e(TAG, "Error while importing app settings: " + e.stackTraceToString()) + } + } if (user == null) { chatModel.controller.appPrefs.privacyDeliveryReceiptsSet.set(true) chatModel.currentUser.value = null diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt index 9110987190..e9fc8c97f9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt @@ -26,7 +26,7 @@ expect val agentDatabaseFileName: String /** * This is used only for temporary storing db archive for export. -* Providing [tmpDir] instead crashes the app. Check db export before moving from this path to something else +* Providing [tmpDir] instead crashes the app on Android (only). Check db export before moving from this path to something else * */ expect val databaseExportDir: File diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt deleted file mode 100644 index 96acea5446..0000000000 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt +++ /dev/null @@ -1,108 +0,0 @@ -package chat.simplex.common.views.database - -import SectionBottomSpacer -import SectionTextFooter -import SectionView -import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.foundation.layout.* -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import dev.icerock.moko.resources.compose.painterResource -import dev.icerock.moko.resources.compose.stringResource -import chat.simplex.common.model.ChatModel -import chat.simplex.common.platform.* -import chat.simplex.common.ui.theme.SimpleXTheme -import chat.simplex.common.views.helpers.* -import chat.simplex.common.views.usersettings.* -import chat.simplex.res.MR -import kotlinx.datetime.* -import java.io.File -import java.net.URI -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun ChatArchiveView(m: ChatModel, title: String, archiveName: String, archiveTime: Instant) { - val archivePath = filesDir.absolutePath + File.separator + archiveName - val saveArchiveLauncher = rememberFileChooserLauncher(false) { to: URI? -> - if (to != null) { - copyFileToFile(File(archivePath), to) {} - } - } - ChatArchiveLayout( - title, - archiveTime, - saveArchive = { withLongRunningApi { saveArchiveLauncher.launch(archivePath.substringAfterLast(File.separator)) }}, - deleteArchiveAlert = { deleteArchiveAlert(m, archivePath) } - ) -} - -@Composable -fun ChatArchiveLayout( - title: String, - archiveTime: Instant, - saveArchive: () -> Unit, - deleteArchiveAlert: () -> Unit -) { - ColumnWithScrollBar { - AppBarTitle(title) - SectionView(stringResource(MR.strings.chat_archive_section)) { - SettingsActionItem( - painterResource(MR.images.ic_ios_share), - stringResource(MR.strings.save_archive), - saveArchive, - textColor = MaterialTheme.colors.primary, - iconColor = MaterialTheme.colors.primary, - ) - SettingsActionItem( - painterResource(MR.images.ic_delete), - stringResource(MR.strings.delete_archive), - deleteArchiveAlert, - textColor = Color.Red, - iconColor = Color.Red, - ) - } - val archiveTs = SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.US).format(Date.from(archiveTime.toJavaInstant())) - SectionTextFooter( - String.format(generalGetString(MR.strings.archive_created_on_ts), archiveTs) - ) - SectionBottomSpacer() - } -} - -private fun deleteArchiveAlert(m: ChatModel, archivePath: String) { - AlertManager.shared.showAlertDialog( - title = generalGetString(MR.strings.delete_chat_archive_question), - confirmText = generalGetString(MR.strings.delete_verb), - onConfirm = { - val fileDeleted = File(archivePath).delete() - if (fileDeleted) { - m.controller.appPrefs.chatArchiveName.set(null) - m.controller.appPrefs.chatArchiveTime.set(null) - ModalManager.start.closeModal() - } else { - Log.e(TAG, "deleteArchiveAlert delete() error") - } - }, - destructive = true, - ) -} - -@Preview/*( - uiMode = Configuration.UI_MODE_NIGHT_YES, - showBackground = true, - name = "Dark Mode" -)*/ -@Composable -fun PreviewChatArchiveLayout() { - SimpleXTheme { - ChatArchiveLayout( - "New database archive", - archiveTime = Clock.System.now(), - saveArchive = {}, - deleteArchiveAlert = {} - ) - } -} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt index 654d250274..c2e1d67d50 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt @@ -48,6 +48,7 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { val currentKey = remember { mutableStateOf(if (initialRandomDBPassphrase.value) DatabaseUtils.ksDatabasePassword.get() ?: "" else "") } val newKey = rememberSaveable { mutableStateOf("") } val confirmNewKey = rememberSaveable { mutableStateOf("") } + val chatLastStart = remember { mutableStateOf(appPrefs.chatLastStart.get()) } Box( Modifier.fillMaxSize(), @@ -63,8 +64,9 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { progressIndicator, migration, onConfirmEncrypt = { - withLongRunningApi { - encryptDatabase( + // it will try to stop and start the chat in case of: non-migration && successful encryption. In migration the chat will remain stopped + stopChatRunBlockStartChat(migration, chatLastStart, progressIndicator, ) { + val success = encryptDatabase( currentKey = currentKey, newKey = newKey, confirmNewKey = confirmNewKey, @@ -74,6 +76,7 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { progressIndicator = progressIndicator, migration = migration ) + success && !migration } } ) @@ -306,7 +309,6 @@ private fun operationEnded(m: ChatModel, progressIndicator: MutableState, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index 3dd7e673c4..8185122089 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -26,7 +26,6 @@ import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.* import chat.simplex.common.platform.* import chat.simplex.res.MR -import kotlinx.coroutines.sync.withLock import kotlinx.datetime.* import java.io.* import java.net.URI @@ -36,18 +35,14 @@ import java.util.* import kotlin.collections.ArrayList @Composable -fun DatabaseView( - m: ChatModel, - showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit) -) { - val currentRemoteHost by remember { chatModel.currentRemoteHost } +fun DatabaseView() { + val m = chatModel val progressIndicator = remember { mutableStateOf(false) } val prefs = m.controller.appPrefs val useKeychain = remember { mutableStateOf(prefs.storeDBPassphrase.get()) } - val chatArchiveName = remember { mutableStateOf(prefs.chatArchiveName.get()) } - val chatArchiveTime = remember { mutableStateOf(prefs.chatArchiveTime.get()) } val chatLastStart = remember { mutableStateOf(prefs.chatLastStart.get()) } val chatArchiveFile = remember { mutableStateOf(null) } + val stopped = remember { m.chatRunning }.value == false val saveArchiveLauncher = rememberFileChooserLauncher(false) { to: URI? -> val file = chatArchiveFile.value if (file != null && to != null) { @@ -59,8 +54,11 @@ fun DatabaseView( val appFilesCountAndSize = remember { mutableStateOf(directoryFileCountAndSize(appFilesDir.absolutePath)) } val importArchiveLauncher = rememberFileChooserLauncher(true) { to: URI? -> if (to != null) { - importArchiveAlert(m, to, appFilesCountAndSize, progressIndicator) { - startChat(m, chatLastStart, m.chatDbChanged) + importArchiveAlert { + stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) { + importArchive(to, appFilesCountAndSize, progressIndicator) + true + } } } } @@ -71,27 +69,40 @@ fun DatabaseView( val user = m.currentUser.value val rhId = user?.remoteHostId DatabaseLayout( - currentRemoteHost = currentRemoteHost, progressIndicator.value, - remember { m.chatRunning }.value != false, - m.chatDbChanged.value, + stopped, useKeychain.value, m.chatDbEncrypted.value, m.controller.appPrefs.storeDBPassphrase.state.value, m.controller.appPrefs.initialRandomDBPassphrase, importArchiveLauncher, - chatArchiveName, - chatArchiveTime, - chatLastStart, appFilesCountAndSize, chatItemTTL, user, m.users, startChat = { startChat(m, chatLastStart, m.chatDbChanged, progressIndicator) }, stopChatAlert = { stopChatAlert(m, progressIndicator) }, - exportArchive = { exportArchive(m, progressIndicator, chatArchiveName, chatArchiveTime, chatArchiveFile, saveArchiveLauncher) }, - deleteChatAlert = { deleteChatAlert(m, progressIndicator) }, - deleteAppFilesAndMedia = { deleteFilesAndMediaAlert(appFilesCountAndSize) }, + exportArchive = { + stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) { + exportArchive(m, progressIndicator, chatArchiveFile, saveArchiveLauncher) + } + }, + deleteChatAlert = { + deleteChatAlert { + stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) { + deleteChat(m, progressIndicator) + true + } + } + }, + deleteAppFilesAndMedia = { + deleteFilesAndMediaAlert { + stopChatRunBlockStartChat(stopped, chatLastStart, progressIndicator) { + deleteFiles(appFilesCountAndSize) + true + } + } + }, onChatItemTTLSelected = { val oldValue = chatItemTTL.value chatItemTTL.value = it @@ -101,7 +112,6 @@ fun DatabaseView( setCiTTL(m, rhId, chatItemTTL, progressIndicator, appFilesCountAndSize) } }, - showSettingsModal, disconnectAllHosts = { val connected = chatModel.remoteHosts.filter { it.sessionState is RemoteHostSessionState.Connected } connected.forEachIndexed { index, h -> @@ -128,18 +138,13 @@ fun DatabaseView( @Composable fun DatabaseLayout( - currentRemoteHost: RemoteHostInfo?, progressIndicator: Boolean, - runChat: Boolean, - chatDbChanged: Boolean, + stopped: Boolean, useKeyChain: Boolean, chatDbEncrypted: Boolean?, passphraseSaved: Boolean, initialRandomDBPassphrase: SharedPreference, importArchiveLauncher: FileChooserLauncher, - chatArchiveName: MutableState, - chatArchiveTime: MutableState, - chatLastStart: MutableState, appFilesCountAndSize: MutableState>, chatItemTTL: MutableState, currentUser: User?, @@ -150,11 +155,9 @@ fun DatabaseLayout( deleteChatAlert: () -> Unit, deleteAppFilesAndMedia: () -> Unit, onChatItemTTLSelected: (ChatItemTTL) -> Unit, - showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), disconnectAllHosts: () -> Unit, ) { - val stopped = !runChat - val operationsDisabled = (!stopped || progressIndicator) && !chatModel.desktopNoUserNoRemote + val operationsDisabled = progressIndicator && !chatModel.desktopNoUserNoRemote ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.your_chat_database)) @@ -178,13 +181,16 @@ fun DatabaseLayout( } val toggleEnabled = remember { chatModel.remoteHosts }.none { it.sessionState is RemoteHostSessionState.Connected } if (chatModel.localUserCreated.value == true) { + // still show the toggle in case database was stopped when the user opened this screen because it can be in the following situations: + // - database was stopped after migration and the app relaunched + // - something wrong happened with database operations and the database couldn't be launched when it should SectionView(stringResource(MR.strings.run_chat_section)) { if (!toggleEnabled) { SectionItemView(disconnectAllHosts) { Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange) } } - RunChatSetting(runChat, stopped, toggleEnabled && !progressIndicator, startChat, stopChatAlert) + RunChatSetting(stopped, toggleEnabled && !progressIndicator, startChat, stopChatAlert) } SectionTextFooter( if (stopped) { @@ -207,7 +213,7 @@ fun DatabaseLayout( if (unencrypted) painterResource(MR.images.ic_lock_open_right) else if (useKeyChain) painterResource(MR.images.ic_vpn_key_filled) else painterResource(MR.images.ic_lock), stringResource(MR.strings.database_passphrase), - click = showSettingsModal() { DatabaseEncryptionView(it, false) }, + click = { ModalManager.start.showModal { DatabaseEncryptionView(chatModel, false) } }, iconColor = if (unencrypted || (appPlatform.isDesktop && passphraseSaved)) WarningOrange else MaterialTheme.colors.secondary, disabled = operationsDisabled ) @@ -225,6 +231,9 @@ fun DatabaseLayout( click = { if (initialRandomDBPassphrase.get()) { exportProhibitedAlert() + ModalManager.start.showModal { + DatabaseEncryptionView(chatModel, false) + } } else { exportArchive() } @@ -241,18 +250,6 @@ fun DatabaseLayout( iconColor = Color.Red, disabled = operationsDisabled ) - val chatArchiveNameVal = chatArchiveName.value - val chatArchiveTimeVal = chatArchiveTime.value - val chatLastStartVal = chatLastStart.value - if (chatArchiveNameVal != null && chatArchiveTimeVal != null && chatLastStartVal != null) { - val title = chatArchiveTitle(chatArchiveTimeVal, chatLastStartVal) - SettingsActionItem( - painterResource(MR.images.ic_inventory_2), - title, - click = showSettingsModal { ChatArchiveView(it, title, chatArchiveNameVal, chatArchiveTimeVal) }, - disabled = operationsDisabled - ) - } SettingsActionItem( painterResource(MR.images.ic_delete_forever), stringResource(MR.strings.delete_database), @@ -333,7 +330,6 @@ private fun TtlOptions(current: State, enabled: State, onS @Composable fun RunChatSetting( - runChat: Boolean, stopped: Boolean, enabled: Boolean, startChat: () -> Unit, @@ -346,7 +342,7 @@ fun RunChatSetting( iconColor = if (stopped) Color.Red else MaterialTheme.colors.primary, ) { DefaultSwitch( - checked = runChat, + checked = !stopped, onCheckedChange = { runChatSwitch -> if (runChatSwitch) { startChat() @@ -359,12 +355,12 @@ fun RunChatSetting( } } -@Composable -fun chatArchiveTitle(chatArchiveTime: Instant, chatLastStart: Instant): String { - return stringResource(if (chatArchiveTime < chatLastStart) MR.strings.old_database_archive else MR.strings.new_database_archive) -} - -fun startChat(m: ChatModel, chatLastStart: MutableState, chatDbChanged: MutableState, progressIndicator: MutableState? = null) { +fun startChat( + m: ChatModel, + chatLastStart: MutableState, + chatDbChanged: MutableState, + progressIndicator: MutableState? = null +) { withLongRunningApi { try { progressIndicator?.value = true @@ -469,6 +465,40 @@ suspend fun stopChatAsync(m: ChatModel) { controller.appPrefs.chatStopped.set(true) } +fun stopChatRunBlockStartChat( + stopped: Boolean, + chatLastStart: MutableState, + progressIndicator: MutableState, + block: suspend () -> Boolean +) { + // if the chat was running, the sequence is: stop chat, run block, start chat. + // Otherwise, just run block and do nothing - the toggle will be visible anyway and the user can start the chat or not + if (stopped) { + withLongRunningApi { + try { + block() + } catch (e: Throwable) { + Log.e(TAG, e.stackTraceToString()) + } + } + } else { + authStopChat(chatModel, progressIndicator) { + withLongRunningApi { + // if it throws, let's start chat again anyway + val canStart = try { + block() + } catch (e: Throwable) { + Log.e(TAG, e.stackTraceToString()) + true + } + if (canStart) { + startChat(chatModel, chatLastStart, chatModel.chatDbChanged, progressIndicator) + } + } + } + } +} + suspend fun deleteChatAsync(m: ChatModel) { m.controller.apiDeleteStorage() DatabaseUtils.ksDatabasePassword.remove() @@ -511,47 +541,42 @@ fun deleteChatDatabaseFilesAndState() { ntfManager.cancelAllNotifications() } -private fun exportArchive( +private suspend fun exportArchive( m: ChatModel, progressIndicator: MutableState, - chatArchiveName: MutableState, - chatArchiveTime: MutableState, chatArchiveFile: MutableState, saveArchiveLauncher: FileChooserLauncher -) { +): Boolean { progressIndicator.value = true - withLongRunningApi { - try { - val (archiveFile, archiveErrors) = exportChatArchive(m, null, chatArchiveName, chatArchiveTime, chatArchiveFile) - chatArchiveFile.value = archiveFile - 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)) - } + try { + val (archiveFile, archiveErrors) = exportChatArchive(m, null, chatArchiveFile) + chatArchiveFile.value = archiveFile + 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()) - progressIndicator.value = false } + progressIndicator.value = false + } catch (e: Throwable) { + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_exporting_chat_database), e.toString()) + progressIndicator.value = false } + return false } suspend fun exportChatArchive( m: ChatModel, storagePath: File?, - chatArchiveName: MutableState, - chatArchiveTime: MutableState, chatArchiveFile: MutableState ): Pair> { 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" - val archivePath = "${(storagePath ?: filesDir).absolutePath}${File.separator}$archiveName" + val archivePath = "${(storagePath ?: databaseExportDir).absolutePath}${File.separator}$archiveName" val config = ArchiveConfig(archivePath, parentTempDirectory = databaseExportDir.toString()) // Settings should be saved before changing a passphrase, otherwise the database needs to be migrated first if (!m.chatDbChanged.value) { @@ -560,42 +585,37 @@ suspend fun exportChatArchive( wallpapersDir.mkdirs() val archiveErrors = m.controller.apiExportArchive(config) if (storagePath == null) { - deleteOldArchive(m) + deleteOldChatArchive() m.controller.appPrefs.chatArchiveName.set(archiveName) m.controller.appPrefs.chatArchiveTime.set(archiveTime) } - chatArchiveName.value = archiveName - chatArchiveTime.value = archiveTime chatArchiveFile.value = archivePath return archivePath to archiveErrors } -private fun deleteOldArchive(m: ChatModel) { - val chatArchiveName = m.controller.appPrefs.chatArchiveName.get() +// Deprecated. Remove in the end of 2025. All unused archives should be deleted for the most users til then. +/** Remove [AppPreferences.chatArchiveName] and [AppPreferences.chatArchiveTime] as well */ +fun deleteOldChatArchive() { + val chatArchiveName = chatModel.controller.appPrefs.chatArchiveName.get() if (chatArchiveName != null) { - val file = File("${filesDir.absolutePath}${File.separator}$chatArchiveName") - val fileDeleted = file.delete() - if (fileDeleted) { - m.controller.appPrefs.chatArchiveName.set(null) - m.controller.appPrefs.chatArchiveTime.set(null) + val file1 = File("${filesDir.absolutePath}${File.separator}$chatArchiveName") + val file2 = File("${databaseExportDir.absolutePath}${File.separator}$chatArchiveName") + val fileDeleted = file1.delete() || file2.delete() + if (fileDeleted || (!file1.exists() && !file2.exists())) { + chatModel.controller.appPrefs.chatArchiveName.set(null) + chatModel.controller.appPrefs.chatArchiveTime.set(null) } else { Log.e(TAG, "deleteOldArchive file.delete() error") } } } -private fun importArchiveAlert( - m: ChatModel, - importedArchiveURI: URI, - appFilesCountAndSize: MutableState>, - progressIndicator: MutableState, - startChat: () -> Unit, -) { +private fun importArchiveAlert(onConfirm: () -> Unit, ) { AlertManager.shared.showAlertDialog( title = generalGetString(MR.strings.import_database_question), text = generalGetString(MR.strings.your_current_chat_database_will_be_deleted_and_replaced_with_the_imported_one), confirmText = generalGetString(MR.strings.import_database_confirmation), - onConfirm = { importArchive(m, importedArchiveURI, appFilesCountAndSize, progressIndicator, startChat) }, + onConfirm = onConfirm, destructive = true, ) } @@ -622,52 +642,51 @@ private fun archiveErrorsText(errs: List): String = "\n" + errs.ma } }.joinToString(separator = "\n") -private fun importArchive( - m: ChatModel, +suspend fun importArchive( importedArchiveURI: URI, appFilesCountAndSize: MutableState>, progressIndicator: MutableState, - startChat: () -> Unit, -) { +): Boolean { + val m = chatModel progressIndicator.value = true val archivePath = saveArchiveFromURI(importedArchiveURI) if (archivePath != null) { - withLongRunningApi { + try { + m.controller.apiDeleteStorage() + wallpapersDir.mkdirs() try { - m.controller.apiDeleteStorage() - wallpapersDir.mkdirs() - try { - val config = ArchiveConfig(archivePath, parentTempDirectory = databaseExportDir.toString()) - val archiveErrors = m.controller.apiImportArchive(config) - DatabaseUtils.ksDatabasePassword.remove() - appFilesCountAndSize.value = directoryFileCountAndSize(appFilesDir.absolutePath) - if (archiveErrors.isEmpty()) { - operationEnded(m, progressIndicator) { - AlertManager.shared.showAlertMsg(generalGetString(MR.strings.chat_database_imported), text = generalGetString(MR.strings.restart_the_app_to_use_imported_chat_database)) - } - if (chatModel.localUserCreated.value == false) { - chatModel.chatRunning.value = false - startChat() - } - } else { - operationEnded(m, progressIndicator) { - showArchiveImportedWithErrorsAlert(archiveErrors) - } - } - } catch (e: Error) { + val config = ArchiveConfig(archivePath, parentTempDirectory = databaseExportDir.toString()) + val archiveErrors = m.controller.apiImportArchive(config) + appPrefs.shouldImportAppSettings.set(true) + DatabaseUtils.ksDatabasePassword.remove() + appFilesCountAndSize.value = directoryFileCountAndSize(appFilesDir.absolutePath) + if (archiveErrors.isEmpty()) { operationEnded(m, progressIndicator) { - AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_importing_database), e.toString()) + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.chat_database_imported), text = generalGetString(MR.strings.restart_the_app_to_use_imported_chat_database)) + } + if (chatModel.localUserCreated.value == false) { + chatModel.chatRunning.value = false + } + } else { + operationEnded(m, progressIndicator) { + showArchiveImportedWithErrorsAlert(archiveErrors) } } + return true } catch (e: Error) { operationEnded(m, progressIndicator) { - AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_deleting_database), e.toString()) + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_importing_database), e.toString()) } - } finally { - File(archivePath).delete() } + } catch (e: Error) { + operationEnded(m, progressIndicator) { + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_deleting_database), e.toString()) + } + } finally { + File(archivePath).delete() } } + return false } private fun saveArchiveFromURI(importedArchiveURI: URI): String? { @@ -689,28 +708,26 @@ private fun saveArchiveFromURI(importedArchiveURI: URI): String? { } } -private fun deleteChatAlert(m: ChatModel, progressIndicator: MutableState) { +private fun deleteChatAlert(onConfirm: () -> Unit) { AlertManager.shared.showAlertDialog( title = generalGetString(MR.strings.delete_chat_profile_question), text = generalGetString(MR.strings.delete_chat_profile_action_cannot_be_undone_warning), confirmText = generalGetString(MR.strings.delete_verb), - onConfirm = { deleteChat(m, progressIndicator) }, + onConfirm = onConfirm, destructive = true, ) } -private fun deleteChat(m: ChatModel, progressIndicator: MutableState) { +private suspend fun deleteChat(m: ChatModel, progressIndicator: MutableState) { progressIndicator.value = true - withBGApi { - try { - deleteChatAsync(m) - operationEnded(m, progressIndicator) { - AlertManager.shared.showAlertMsg(generalGetString(MR.strings.chat_database_deleted), generalGetString(MR.strings.restart_the_app_to_create_a_new_chat_profile)) - } - } catch (e: Error) { - operationEnded(m, progressIndicator) { - AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_deleting_database), e.toString()) - } + try { + deleteChatAsync(m) + operationEnded(m, progressIndicator) { + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.chat_database_deleted), generalGetString(MR.strings.restart_the_app_to_create_a_new_chat_profile)) + } + } catch (e: Error) { + operationEnded(m, progressIndicator) { + AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_deleting_database), e.toString()) } } } @@ -759,12 +776,12 @@ private fun afterSetCiTTL( } } -private fun deleteFilesAndMediaAlert(appFilesCountAndSize: MutableState>) { +private fun deleteFilesAndMediaAlert(onConfirm: () -> Unit) { AlertManager.shared.showAlertDialog( title = generalGetString(MR.strings.delete_files_and_media_question), text = generalGetString(MR.strings.delete_files_and_media_desc), confirmText = generalGetString(MR.strings.delete_verb), - onConfirm = { deleteFiles(appFilesCountAndSize) }, + onConfirm = onConfirm, destructive = true ) } @@ -789,18 +806,13 @@ private fun operationEnded(m: ChatModel, progressIndicator: MutableState.exportArchive() { withLongRunningApi { try { getMigrationTempFilesDirectory().mkdir() - val (archivePath, archiveErrors) = exportChatArchive(chatModel, getMigrationTempFilesDirectory(), mutableStateOf(""), mutableStateOf(Instant.DISTANT_PAST), mutableStateOf("")) + val (archivePath, archiveErrors) = exportChatArchive(chatModel, getMigrationTempFilesDirectory(), mutableStateOf("")) if (archiveErrors.isEmpty()) { uploadArchive(archivePath) } else { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt index 28ec77de70..f4f537aab7 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt @@ -35,6 +35,7 @@ import kotlinx.datetime.Clock import kotlinx.datetime.toJavaInstant import kotlinx.serialization.* import java.io.File +import java.net.URI import java.text.SimpleDateFormat import java.util.* import kotlin.math.max @@ -180,7 +181,7 @@ private fun ModalData.SectionByState( ) { when (val s = migrationState.value) { null -> {} - is MigrationToState.PasteOrScanLink -> migrationState.PasteOrScanLinkView() + is MigrationToState.PasteOrScanLink -> migrationState.PasteOrScanLinkView(close) is MigrationToState.Onion -> OnionView(s.link, s.legacySocksProxy, s.networkProxy, s.hostMode, s.requiredHostMode, migrationState) is MigrationToState.DatabaseInit -> migrationState.DatabaseInitView(s.link, tempDatabaseFile, s.netCfg, s.networkProxy) is MigrationToState.LinkDownloading -> migrationState.LinkDownloadingView(s.link, s.ctrl, s.user, s.archivePath, tempDatabaseFile, chatReceiver, s.netCfg, s.networkProxy) @@ -195,18 +196,30 @@ private fun ModalData.SectionByState( } @Composable -private fun MutableState.PasteOrScanLinkView() { - if (appPlatform.isAndroid) { - SectionView(stringResource(MR.strings.scan_QR_code).replace('\n', ' ').uppercase()) { - QRCodeScanner(showQRCodeScanner = remember { mutableStateOf(true) }) { text -> - withBGApi { checkUserLink(text) } +private fun MutableState.PasteOrScanLinkView(close: () -> Unit) { + Box { + val progressIndicator = remember { mutableStateOf(false) } + Column { + if (appPlatform.isAndroid) { + SectionView(stringResource(MR.strings.scan_QR_code).replace('\n', ' ').uppercase()) { + QRCodeScanner(showQRCodeScanner = remember { mutableStateOf(true) }) { text -> + withBGApi { checkUserLink(text) } + } + } + SectionSpacer() + } + + SectionView(stringResource(if (appPlatform.isAndroid) MR.strings.or_paste_archive_link else MR.strings.paste_archive_link).uppercase()) { + PasteLinkView() + } + SectionSpacer() + + SectionView(stringResource(MR.strings.chat_archive).uppercase()) { + ArchiveImportView(progressIndicator, close) } } - SectionSpacer() - } - - SectionView(stringResource(if (appPlatform.isAndroid) MR.strings.or_paste_archive_link else MR.strings.paste_archive_link).uppercase()) { - PasteLinkView() + if (progressIndicator.value) + ProgressView() } } @@ -221,6 +234,31 @@ private fun MutableState.PasteLinkView() { } } +@Composable +private fun ArchiveImportView(progressIndicator: MutableState, close: () -> Unit) { + val importArchiveLauncher = rememberFileChooserLauncher(true) { to: URI? -> + if (to != null) { + withLongRunningApi { + val success = importArchive(to, mutableStateOf(0 to 0), progressIndicator) + if (success) { + startChat( + chatModel, + mutableStateOf(Clock.System.now()), + chatModel.chatDbChanged, + progressIndicator + ) + hideView(close) + } + } + } + } + SectionItemView({ + withLongRunningApi { importArchiveLauncher.launch("application/zip") } + }) { + Text(stringResource(MR.strings.import_database)) + } +} + @Composable private fun ModalData.OnionView(link: String, legacyLinkSocksProxy: String?, linkNetworkProxy: NetworkProxy?, hostMode: HostMode, requiredHostMode: Boolean, state: MutableState) { val onionHosts = remember { stateGetOrPut("onionHosts") { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt index f3d22e0cdf..ac6431f6fc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt @@ -109,7 +109,7 @@ fun SettingsLayout( SectionDividerSpaced() SectionView(stringResource(MR.strings.settings_section_title_chat_database)) { - DatabaseItem(encrypted, passphraseSaved, showSettingsModal { DatabaseView(it, showSettingsModal) }, stopped) + DatabaseItem(encrypted, passphraseSaved, showSettingsModal { DatabaseView() }, stopped) SettingsActionItem(painterResource(MR.images.ic_ios_share), stringResource(MR.strings.migrate_from_device_to_another_device), { withAuth(generalGetString(MR.strings.auth_open_migration_to_another_device), generalGetString(MR.strings.auth_log_in_using_credential)) { ModalManager.fullscreen.showCustomModal { close -> MigrateFromDeviceView(close) } } }, disabled = stopped) } diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml index d9d86634b1..b2cb0acc4b 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ar/strings.xml @@ -242,7 +242,6 @@ تغيير وضع التدمير الذاتي تغيير رمز المرور التدمير الذاتي تأكيد ترقيات قاعدة البيانات - أرشيف الدردشة الاتصال (دعوة مقدمة) مسح خطأ في إنشاء رابط المجموعة @@ -252,8 +251,6 @@ جار الاتصال… أرسلت طلب الاتصال! حُذفت قاعدة بيانات الدردشة - أرشيف الدردشة - نشأ في %1$s جارِ تغيير العنوان… جار الاتصال (قُبِل) فُحصت جهة الاتصال @@ -349,7 +346,6 @@ تختلف عبارة مرور قاعدة البيانات عن تلك المحفوظة في Keystore. خطأ في قاعدة البيانات ترقية قاعدة البيانات - حذف أرشيف الدردشة؟ حُددت %d جهة اتصال حذف المجموعة حذف المجموعة؟ @@ -372,7 +368,6 @@ أيام حذف العنوان سيتم تحديث عبارة مرور تعمية قاعدة البيانات. - حذف الأرشيف حذف الرابط؟ الرجوع إلى إصدار سابق من قاعدة البيانات قاعدة البيانات مُعمّاة باستخدام عبارة مرور عشوائية. يُرجى تغييره قبل التصدير. @@ -844,7 +839,6 @@ دليل المستخدم.]]> افتح ملفات تعريف الدردشة اسحب الوصول - حفظ الأرشيف كشف سيتم إيقاف استلام الملف. رفض diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 5f095fbf7c..6d0200256c 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -1263,6 +1263,7 @@ Your chat database RUN CHAT + Remote mobiles Chat is running Chat is stopped CHAT DATABASE @@ -1404,14 +1405,6 @@ Start chat? Chat is stopped. If you already used this database on another device, you should transfer it back before starting chat. - - Chat archive - CHAT ARCHIVE - Save archive - Delete archive - Created on %1$s - Delete chat archive? - invitation to group %1$s Join group? @@ -2292,6 +2285,7 @@ Or paste archive link Paste archive link Invalid link + Or import archive file Migrating Preparing download Downloading link details diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml index 54eb0e9034..042089e226 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/bg/strings.xml @@ -228,7 +228,6 @@ Базата данни на чат е импортирана Потвърди новата парола… Потвърди актуализаациите на базата данни - Архив на чата свързан промяна на адреса… промяна на адреса за %s… @@ -317,7 +316,6 @@ Промени режима на самоунищожение Промени кода за достъп за самоунищожение ЧАТОВЕ - АРХИВ НА ЧАТА промяна на адреса… В момента максималният поддържан размер на файла е %1$s. ID в базата данни @@ -341,9 +339,6 @@ Понижаване на версията на базата данни Актуализация на базата данни версията на базата данни е по-нова от приложението, но няма миграция надолу за: %s - Създаден на %1$s - Изтрий архив - Изтриване на архива на чата\? групата изтрита Контактът е проверен създател @@ -996,7 +991,6 @@ Режим на заключване Моля, докладвайте го на разработчиците. Защити екрана на приложението - Запази архив ЧЛЕН Премахване PING бройка diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml index 59c531f3d3..64a87736c4 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/cs/strings.xml @@ -303,8 +303,6 @@ Obnovte zálohu databáze Po obnovení zálohy databáze zadejte předchozí frázi. Tuto akci nelze vrátit zpět. Chat je zastaven - Chat se archivuje - Smazat archiv chatu? Připojit se ke skupině\? Připojte se na Opustit @@ -352,7 +350,6 @@ Databáze chatu importována Nová přístupová fráze… Uložte přístupovou frázi a otevřete chat - ARCHIV CHATU Nebyl vybrán žádný kontakt Snažíte se pozvat kontakt, se kterým jste sdíleli inkognito profil, do skupiny, ve které používáte svůj hlavní profil Skupina @@ -776,10 +773,7 @@ Chyba při obnovování databáze Přístupová fráze nebyla v klíčence nalezena, zadejte jej prosím ručně. K této situaci mohlo dojít, pokud jste obnovili data aplikace pomocí zálohovacího nástroje. Pokud tomu tak není, obraťte se na vývojáře. Chat můžete spustit v Nastavení / Databáze nebo restartováním aplikace. - Uložit archiv - Smazat archiv pozvánka do skupiny %1$s - Vytvořeno dne %1$s Jste zváni do skupiny. Připojte se k členům skupiny. Připojit se inkognito Připojit ke skupině diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml index 912f3fb84e..75f6ac2c29 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/de/strings.xml @@ -672,12 +672,6 @@ Der Chat wurde beendet Sie können den Chat über die App-Einstellungen/Datenbank oder durch Neustart der App starten. - Datenbank-Archiv - CHAT-ARCHIV - Archiv speichern - Archiv löschen - Erstellt am %1$s - Chat-Archiv löschen\? Einladung zur Gruppe %1$s Der Gruppe beitreten? diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/el/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/el/strings.xml index 4b1d1b8838..179c7fec52 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/el/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/el/strings.xml @@ -100,7 +100,6 @@ Δεν είναι δυνατή η προετοιμασία της βάσης δεδομένων Ένα νέο τυχαίο προφίλ θα μοιραστεί. Δεν είναι δυνατή η πρόσκληση επαφών! - Αρχείο συνομιλίας Αλλαγή διεύθυνσης λήψης Πιστοποίηση μη διαθέσιμη Αλλαγή @@ -112,7 +111,6 @@ %1$d αποτυχία κρυπτογράφησης μηνύματος αλλαγή διεύθυνσης για %s… Αλλαγή ρόλου ομάδας; - ΑΡΧΕΙΟ ΣΥΝΟΜΙΛΙΑΣ Δεν είναι δυνατή η πρόσκληση επαφής! Αυτόματη αποδοχή αιτήματος επαφής Κλήση… @@ -189,7 +187,6 @@ συνδέεται… Δημιουργία σύνδεσμο ομάδας Σύνδεση σε επιφάνεια εργασίας - Δημιουργήθηκε στις %1$s Συνδεδεμένο στο κινητό Σύνδεση μέσω σύνδεσμο Επαφές diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml index 5ce86cd374..1cde9ed7c7 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/es/strings.xml @@ -191,7 +191,6 @@ conectando… Descentralizada La base de datos será cifrada. - ¿Eliminar archivo del chat\? Crear enlace de grupo Eliminar enlace ¿Eliminar perfil? @@ -215,8 +214,6 @@ %dd %d días ¿Eliminar archivos y multimedia\? - Creado: %1$s - Eliminar archivo conectado directa El contacto permite @@ -289,8 +286,6 @@ Llamada en curso ¿Cambiar contraseña de la base de datos\? No se puede acceder a Keystore para guardar la base de datos de contraseñas - Archivo del chat - ARCHIVOS DE CHAT Cancelar Cancelar mensaje en directo Confirmar @@ -662,7 +657,6 @@ Llamada pendiente Privacidad y Seguridad Guarda la contraseña de forma segura, NO podrás acceder al chat si la pierdes. - Guardar archivo Introduce la contraseña anterior después de restaurar la copia de seguridad de la base de datos. Esta acción no se puede deshacer. te ha expulsado Recibiendo vía diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fa/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fa/strings.xml index 2fe4ec452e..dc4552a33e 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fa/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fa/strings.xml @@ -956,9 +956,6 @@ حذف خودکار پیام فعال شود؟ برگرداندن ارتقا و گشودن گپ - آرشیو گپ - ذخیره آرشیو - حذف آرشیو دعوت به گروه %1$s به گروه می‌پیوندید؟ ترک @@ -1092,9 +1089,6 @@ نسخه پایگاه داده از برنامه جدیدتر است، اما بدون جابه‌جایی تنزلی برای: %s جابه‌جایی متفاوت در برنامه/پایگاه داده: %s / %s جابه‌جایی‌ها: %s - آرشیو گپ - ایجاد شده در %1$s - آرشیو گپ حذف شود؟ شما به گروه دعوت شده‌اید. برای متصل شدن به اعضای گروه، به گروه بپیوندید. پیوستن به صورت ناشناس این گروه دیگر وجود ندارد. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml index c3ea7d89f7..682854f9dd 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fi/strings.xml @@ -108,7 +108,6 @@ Tietoja SimpleX:stä Hajautettu Ääni pois päältä - ARKISTO Vaihda rooli Poista kaikilta Luodaan tyhjä chat-profiili annetulla nimellä, ja sovellus avautuu normaalisti. @@ -168,9 +167,6 @@ Tumma Tunnistautuminen epäonnistui Lisää esiasetettuja palvelimia - Arkisto - Poista keskusteluarkisto\? - Luotu %1$s poistettu ryhmä yhdistää yhdistäminen (hyväksytty) @@ -326,7 +322,6 @@ Tietokannan alentaminen Tietokannan päivitys Tietokanta salataan. - Poista arkisto yhdistäminen (esittelykutsu) Poistettu klo Muuta @@ -969,7 +964,6 @@ Turvallinen jono Tunnuslausetta ei löydy Keystoresta, kirjoita se manuaalisesti. Tämä on saattanut tapahtua, jos olet palauttanut sovelluksen tiedot varmuuskopiointityökalulla. Jos näin ei ole, ota yhteyttä kehittäjiin. Anna edellinen salasana tietokannan varmuuskopion palauttamisen jälkeen. Tätä toimintoa ei voi kumota. - Tallenna arkisto Tuonnin aikana tapahtui joitakin ei-vakavia virheitä – saatat nähdä Chat-konsolissa lisätietoja. Tietue päivitetty klo Moderoitu klo diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml index 8c88c1ea67..3bef77138e 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/fr/strings.xml @@ -475,7 +475,6 @@ La phrase secrète n\'a pas été trouvée dans le Keystore, veuillez la saisir manuellement. Cela a pu se produire si vous avez restauré les données de l\'app à l\'aide d\'un outil de sauvegarde. Si ce n\'est pas le cas, veuillez contacter les développeurs. Veuillez entrer le mot de passe précédent après avoir restauré la sauvegarde de la base de données. Cette action ne peut pas être annulée. Erreur de restauration de la base de données - Créé le %1$s appel vidéo (chiffrement de bout en bout) appel audio (sans chiffrement) appel audio (chiffrement de bout en bout) @@ -653,11 +652,6 @@ Restaurer Le chat est arrêté Vous pouvez lancer le chat via les Paramètres / la Base de données de l\'app ou en la redémarrant. - Archives du chat - ARCHIVE DU CHAT - Enregistrer l\'archive - Supprimer l\'archive - Supprimer l\'archive du chat \? Invitation au groupe %1$s Rejoindre le groupe \? Vous êtes invité·e dans un groupe. Rejoignez le pour vous connecter avec ses membres. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml index 9c283a98e9..9e0d476dc1 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/hi/strings.xml @@ -117,7 +117,6 @@ नेटवर्क की स्थिति नया संपर्क अनुरोध सभी फाइलों को मिटा दें - संग्रह हटा देना नया डेटाबेस संग्रह नए सदस्य की भूमिका अधिसूचना सेवा @@ -129,7 +128,6 @@ अधिसूचना पूर्वावलोकन सूचनाएं सभी के लिए हटाएं - लिखचीत संग्रह हटा दे\? चैट प्रोफ़ाइल हटाएं\? चैट प्रोफ़ाइल हटाएं\? के लिए चैट प्रोफ़ाइल हटाएं @@ -218,9 +216,7 @@ कॉल समाप्त कॉल चल रहा है छवियों को स्वत: स्वीकार करें - चैट संग्रह चैट रोक दी गई है - चैट संग्रह आप इस समूह से संदेश प्राप्त करना बंद कर देंगे। चैट इतिहास संरक्षित किया जाएगा। %s की भूमिका को %s में बदला पूर्ण diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml index 6fe624d621..f0355d51ac 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/hu/strings.xml @@ -262,7 +262,6 @@ Törlés az összes tagnál Hivatkozás létrehozása Csevegési beállítások - Csevegési archívum Profil törlése Jelenlegi jelkód kapcsolódás @@ -277,7 +276,6 @@ Hamarosan! cím megváltoztatása nála: %s … Csevegési adatbázis importálva - CSEVEGÉSI ARCHÍVUM Üzenetek törlése Kiürítés Bezárás gomb @@ -329,7 +327,6 @@ Fájlok törlése az összes csevegési profilból Sorbaállítás törlése Ismerős törlése - Létrehozva ekkor: %1$s cím megváltoztatása… Társítva a hordozható eszközhöz Jelenlegi jelmondat… @@ -413,7 +410,6 @@ Kézbesítés jelentések letiltása a csoportok számára? nap %d nap - Csevegési archívum törlése? Duplikált megjelenített név! Letiltás (felülírások megtartásával) Adatbázis fejlesztése @@ -451,7 +447,6 @@ Eszközök Látható a helyi hálózaton Ne engedélyezze - Archívum törlése Az eltűnő üzenetek küldése le van tiltva ebben a csevegésben. alapértelmezett (%s) duplikált üzenet @@ -998,7 +993,6 @@ %s: %s A SimpleX nem tud a háttérben futni. Csak akkor fog értesítéseket kapni, amikor az alkalmazás meg van nyitva. Túl sok kép! - Archívum mentése %s, %s és %d tag Csevegési szolgáltatás megállítása SimpleX-hivatkozások diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/in/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/in/strings.xml index 29c6430839..dec20e2a36 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/in/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/in/strings.xml @@ -450,7 +450,6 @@ Kode sandi aplikasi Kode sandi %s detik - Simpan arsip Ketuk untuk gabung diblokir %s Buka @@ -548,7 +547,6 @@ pesan buka Sistem - Arsip obrolan setel alamat kontak baru Tema gelap Tema @@ -862,7 +860,6 @@ Pesan suara tidak diizinkan Hapus alamat? Keluar dari grup? - ARSIP OBROLAN Rangkaian ini bukan tautan koneksi! Tempel tautan yang Anda terima Bagikan dengan kontak @@ -890,7 +887,6 @@ gandakan pesan hash pesan buruk Mulai obrolan? - Hapus arsip Jelajah dan gabung ke grup Perutean pesan pribadi 🚀 Lindungi alamat IP Anda dari relai pesan yang dipilih oleh kontak Anda.\nAktifkan di pengaturan *Jaringan & server*. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml index f5334d4e61..e699714a6a 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml @@ -277,7 +277,6 @@ Impossibile accedere al Keystore per salvare la password del database Impossibile invitare i contatti! Cambia ruolo - ARCHIVIO CHAT cambio indirizzo… Chat fermata in connessione (presentato) @@ -398,13 +397,9 @@ Funzionalità sperimentali Esporta database AIUTO - Archivio chat Chat fermata - Creato il %1$s Errore del database La password del database è diversa da quella salvata nel Keystore. - Elimina archivio - Eliminare l\'archivio della chat\? Database crittografato Inserisci la password giusta. Inserisci la password… @@ -745,7 +740,6 @@ Ripristina backup del database Ripristinare il backup del database\? Errore di ripristino del database - Salva archivio Salva la password e apri la chat Il tentativo di cambiare la password del database non è stato completato. Errore del database sconosciuto: %s diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml index d207057d0c..64f86a6ecb 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/iw/strings.xml @@ -165,8 +165,6 @@ מסד הנתונים של הצ׳אט נמחק ‬מסד הנתונים של הצ׳אט יובא אשר שדרוגי מסד נתונים - ארכיון צ׳אט - ארכיון צ׳אט צ׳אט מופסק לא ניתן להזמין את אנשי הקשר! שונה תפקידך ל%s @@ -222,7 +220,6 @@ צור צור פרופיל יצירת הפרופיל שלך - נוצר ב־%1$s צור קישור קבוצה צור קישור יוצר הקבוצה @@ -253,7 +250,6 @@ צרו כתובת כדי לאפשר לאנשים להתחבר אליכם. מבוזר מסד הנתונים מוצפן באמצעות סיסמה אקראית. אנא שנו אותה לפני הייצוא. - למחוק ארכיון צ׳אט\? מחק פרופיל צ׳אט ברירת מחדל (%s) %d יום @@ -307,7 +303,6 @@ סיסמה וייצוא של מסד הנתונים מחק אחרי מחק את כל הקבצים - מחק ארכיון מחק עבורי מחק קישור למחוק פרופיל צ׳אט\? @@ -893,7 +888,6 @@ שחזור גיבוי מסד נתונים לשחזר גיבוי מסד נתונים\? שמור סיסמה ופתח את הצ׳אט - שמור ארכיון בחירת אנשי קשר קוד גישה להשמדה עצמית שניות diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml index cce95b5286..632e62ef09 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ja/strings.xml @@ -77,8 +77,6 @@ 電池消費が最少:アプリがアクティブ時のみに通知が出ます(バックグラウンドサービス無し)。]]> 設定メニューにてオフにできます。 アプリがアクティブ時に通知が出ます。]]> あなたと連絡相手が送信済みメッセージを永久削除できます。(24時間) - チャットのアーカイブ - チャットのアーカイブを削除しますか? シークレットモードで参加 接続待ち (招待) 接続待ち (承諾済み) @@ -369,8 +367,6 @@ データベース暗号化のパスフレーズが更新されます。 チャットを開くにはデータベースパスフレーズが必要です。 ファイル: %s - 作成日時 %1$s - アーカイブを削除 参加 グループに参加しますか? グループに参加 @@ -551,7 +547,6 @@ 端末 送受信済みのファイルがありません メッセージを削除 - チャットのアーカイブ 接続中 あなたを除名しました。 グループのリンク @@ -921,7 +916,6 @@ データベースのエクスポート、読み込み、削除するにはチャット機能を停止する必要があります。チャット機能を停止すると送受信ができなくなります。 あなたのプロフィール、連絡先、メッセージ、ファイルが完全削除されます (※元に戻せません※)。 データベースパスフレーズを更新 - アーカイブを保存 あなたが自分の役割を次に変えました:%s アドレスを変えました %sのアドレスを変えました diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml index eab9df3b92..6af84d88c1 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ko/strings.xml @@ -90,7 +90,6 @@ 주의: 암호를 분실하면 복구하거나 비밀번호 변경을 할 수 없어요.]]> 데이터베이스 암호를 바꾸시겠습니까? 새로운 암호 확인… - 채팅 기록 보관함 내 역할이 %s 역할로 변경됨 주소 바꾸는 중… 주소 바꾸는 중… @@ -179,7 +178,6 @@ 채팅 데이터베이스 대화 상대를 초대할 수 없습니다! 변경 - 채팅 기록 보관함 역할 변경 채팅 데이터베이스가 삭제됨 채팅이 멈춤 @@ -197,7 +195,6 @@ 대화 상대와 모든 메시지가 삭제됩니다. 이 결정은 되돌릴 수 없습니다! 대화 상대와 종단 간 암호화됨 대화 상대와 아직 연결되지 않았습니다! - %1$s에 생성 완료 비밀 그룹 생성 익명 수락 1개월 @@ -232,8 +229,6 @@ 데이터베이스 에러 데이터베이스 암호가 암호 저장소에 저장된 것과 일치하지 않습니다. 채팅을 열려면 데이터베이스 암호가 필요합니다. - 보관함 삭제 - 보관된 채팅을 삭제할까요\? %d 개의 대화 상대가 선택되었습니다. 데이터베이스 ID 다음 채팅 프로필 삭제 @@ -751,7 +746,6 @@ 저장하고 그룹 멤버들에게 알리기 저장하고 대화 상대에게 알리기 지우기 - 보관함 저장하기 암호 저장소에 암호 저장하기 데이터베이스 백업 복원하기 데이터베이스 백업을 복원한 후 이전 비밀번호를 입력해 주십시오. 이 결정은 되돌릴 수 없습니다. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml index bf50e67bb8..c3505460ae 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/lt/strings.xml @@ -125,8 +125,6 @@ Failai ir medija Ištrinti visus failus Ištrinti failus ir mediją\? - Ištrinti archyvą - Ištrinti pokalbio archyvą\? grupės profilis atnaujintas Grupė Ištrinti pokalbio profilį\? @@ -393,7 +391,6 @@ Žymėti kaip patvirtintą SimpleX užraktas Įrašyti WebRTC ICE serveriai bus pašalinti. - Įrašyti archyvą Siųsti tiesioginę žinutę Šalinti narį Šviesus @@ -834,7 +831,6 @@ Prašome įvesti praeitą slaptažodį po duomenų bazės atsarginės kopijos atstatymo. Šis veiksmas negali būti atšauktas. duomenų bazė naujesnė nei programėlė, bet nėra perkėlimo į senesnę versiją: %s skirtinga migracija programėlėje/duomenų bazėje: %s / %s - Pokalbio archyvas Grupė neaktyvi Gauta Užblokuota administratoriaus @@ -903,7 +899,6 @@ Atsitiktinė slaptafrazė yra saugoma nustatymuose kaip paprastas tekstas. \nJūs galite tai pakeisti vėliau. Pokalbiai veikia - POKALBIO ARCHYVAS Pokalbiai sustabdyti. Jei jau naudojote šią duomenų bazę kitame įrenginyje, turėtumėte perkelti ją atgal prieš pradedant pokalbius. užblokavo %s Keisti gavimo adresą @@ -1061,7 +1056,6 @@ Pokalbiai sustabdyti jungiamasi (priimtas) Kontaktas patikrintas - Sukurta %1$s Duomenų bazės slaptafrazė yra kitokia nei išsaugota raktų saugykloje. Duomenų bazė bus užšifruota ir slaptafrazė bus saugoma nustatymuose. Grupės pakvietimas nebegalioja, siuntėjas jį pašalino. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml index 22112a8376..649f586620 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml @@ -24,7 +24,6 @@ Chat is actief Wissen CHAT DATABASE - CHAT ARCHIEF Chat console Chat database geïmporteerd Chat database verwijderd @@ -117,7 +116,6 @@ Chat is gestopt Controleert nieuwe berichten elke 10 minuten gedurende maximaal 1 minuut je rol gewijzigd in %s - Gesprek archief Wachtwoord database wijzigen\? Chat is gestopt Chat voorkeuren @@ -215,7 +213,6 @@ Huidige wachtwoord… Database versleuteld! is toegetreden - Gemaakt op %1$s compleet Wissen verbonden @@ -230,8 +227,6 @@ Contact personen kunnen berichten markeren voor verwijdering; u kunt ze wel bekijken. Donker standaard (%s) - Chat archief verwijderen\? - Archief verwijderen Verwijder contact\? Chatprofiel verwijderen? Verwijderen voor iedereen @@ -621,7 +616,6 @@ Video aan Deze actie kan niet ongedaan worden gemaakt. Uw profiel, contacten, berichten en bestanden gaan onomkeerbaar verloren. Deze instelling is van toepassing op berichten in uw huidige chatprofiel - Bewaar archief bijgewerkt groep profiel verwijderd Uw chatprofiel wordt verzonden naar de groepsleden diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml index 8056422e5f..e793ff2a72 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pl/strings.xml @@ -601,14 +601,11 @@ Nieprawidłowe hasło bazy danych Nieprawidłowe hasło! Musisz wprowadzić hasło przy każdym uruchomieniu aplikacji - nie jest one przechowywane na urządzeniu. - Archiwum czatu - ARCHIWUM CZATU Czat jest zatrzymany Potwierdź aktualizacje bazy danych Obniż wersję bazy danych Aktualizacja bazy danych wersja bazy danych jest nowsza od aplikacji, ale nie ma migracji w dół dla: %s - Usuń archiwum różne migracje w aplikacji/bazy danych: %s / %s Obniż wersję i otwórz czat Grupa nieaktywna @@ -630,7 +627,6 @@ Przywróć kopię zapasową bazy danych Przywrócić kopię zapasową bazy danych\? Błąd przywracania bazy danych - Zapisz archiwum Próba zmiany hasła bazy danych nie została zakończona. Ta grupa już nie istnieje. Zaktualizuj i otwórz czat @@ -925,13 +921,11 @@ Kontakt i wszystkie wiadomości zostaną usunięte - nie można tego cofnąć! Błąd połączenia (UWIERZYTELNIANIE) Połącz się przez link / kod QR - Utworzony na %1$s Utwórz tajną grupę Utwórz tajną grupę Baza danych jest zaszyfrowana przy użyciu losowego hasła. Proszę zmienić je przed eksportem. %d dni Usuń - Usunąć archiwum czatu\? Usuń wiadomości po Znikające wiadomości są zabronione w tej grupie. Błąd usuwania prośby o kontakt diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml index d683d194ba..140b208db9 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pt-rBR/strings.xml @@ -57,7 +57,6 @@ Android Keystore é usada para armazenar a senha com segurança - permite que o serviço de notificação funcione. A Android Keystore será usada para armazenar a senha com segurança depois que você reiniciar o aplicativo ou alterar a senha - isso permitirá o recebimento de notificações. Não é possível acessar a Keystore para salvar a senha do banco de dados - ARQUIVO DE BATE-PAPO O bate-papo está parado Limpar Preferências de bate-papo @@ -81,7 +80,6 @@ O bate-papo está em execução O bate-papo está parado Alterar senha do banco de dados\? - Arquivo de chat endereço alterado para você Você e seu contato podem enviar mensagens temporárias. Backup de dados do aplicativo @@ -180,8 +178,6 @@ Confirmar nova senha… Senha atual… Senha do banco de dados é necessária para abrir o chat. - Excluir arquivo - Excluir arquivo de chat\? cargo alterado de %s para %s conectado Excluir link @@ -218,7 +214,6 @@ Erro de conexão (AUTH) conexão estabelecida conexão %1$d - Criado em %1$s Atualmente, o tamanho máximo de arquivo suportado é %1$s. Excluir Ssnha de criptografia do banco de dados será atualizada e armazenada na Keystore. @@ -685,7 +680,6 @@ Esta ação não pode ser desfeita - seu perfil, contatos, mensagens e arquivos serão irreversivelmente perdidos. Remover Senha do banco de dados incorreta - Salvar arquivo Senha não encontrada na Keystore, por favor digite-a manualmente. Isso pode ter ocorrido se você recuperou os dados do app usando uma ferramenta de backup. Se esse não é o caso, por favor, contate os desenvolvedores. Você se juntou a este grupo. Conectando-se a um membro convidado do grupo. Sair do grupo\? diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml index 548a495222..ee5b82d490 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/pt/strings.xml @@ -33,7 +33,6 @@ ÍCONE DA APLICAÇÃO 1 mês Mensagens - ARQUIVO DE CONVERSA Adicionar mensagem de boas-vindas Adicional perfil Apenas dados de perfil local @@ -135,11 +134,8 @@ Eliminar após Eliminar Eliminar - Arquivo de conversa Eliminar Eliminar todos os ficheiros - Eliminar arquivo - Eliminar arquivo de conversa\? Eliminar base de dados BASE DE DADOS DE CONVERSA Base de dados de conversa eliminada @@ -355,7 +351,6 @@ Contribuir Copiar Versão principal: v%s - Criado a %1$s Criar ligação de grupo Ligações de grupo conectando chamada… @@ -383,7 +378,6 @@ Salvar e atualizar o perfil do grupo Salvar Salvar senha e abrir conversa - Salvar arquivo Junte-se em modo anónimo Apagar ligação Endereço diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ro/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ro/strings.xml index 498d3282de..7f8e0e2743 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ro/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ro/strings.xml @@ -229,7 +229,6 @@ Salvezi servere? Apel respins Mesaj salvat - Salvează arhiva Repornește aplicația pentru a crea un nou profil Salvează fraza de acces în Keystore Salvează profilul grupului @@ -441,7 +440,6 @@ Baza ta de date a conversațiilor Baza ta de date a conversațiilor nu este criptată - setează frază de acces pentru a o proteja. Fraza de acces de criptare a bazei de date va fi actualizată și stocată în setări. - Creat pe %1$s ai schimbat rolul %s la %s Nu se pot invita contactele! Te-ai alăturat grupului @@ -595,7 +593,6 @@ Consolă conversație Confirmați parola colorat - Arhivă conversație Toate contactele, conversațiile și fișierele dumneavoastră vor fi encriptate într-un mod sigur și încărcate pe bucăți pe releurile XFTP configurate. Rugat să primească videoclipul Comparați fișierul @@ -616,7 +613,6 @@ Vă rugăm să rețineți: folosind aceeași bază de date pe două dispozitive, va intrerupe decripția mesajelor de la conexiunile dumneavoastră, ca protecție de securitate.]]> Confirmați încărcarea Confirmați că țineți minte parola de la baza de date pentru a o migra. - ARHIVĂ CONVERSAȚIE Conexiune Ștergi profilul de conversație? Șterge pentru mine @@ -626,7 +622,6 @@ Șters la Versiunea aplicației desktop %s nu este compatibilă cu această aplicație. Ștergi mesajul membrului? - Șterge arhiva Șterge grup Șterge și notifică contactele Decentralizat @@ -652,7 +647,6 @@ Șterge Șterge Ștergi fișiere și media? - Ștergi arhiva conversației? %d zile %d zi Șterge adresa diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml index aa9856eb9f..10d1de26ae 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/ru/strings.xml @@ -676,12 +676,6 @@ Чат остановлен Вы можете запустить чат через Настройки приложения или перезапустив приложение. - Архив чата - АРХИВ ЧАТА - Сохранить архив - Удалить архив - Дата создания %1$s - Удалить архив чата? приглашение в группу %1$s Вступить в группу? diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml index 03bf9f0f27..c1f88cf3b1 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/th/strings.xml @@ -160,7 +160,6 @@ หมดเวลาการเชื่อมต่อ เชื่อมต่อผ่านลิงค์กลุ่ม\? ผู้ติดต่อและข้อความทั้งหมดจะถูกลบ - ไม่สามารถยกเลิกได้! - สร้างเมื่อ %1$s ขนาดไฟล์สูงสุดที่รองรับในปัจจุบันคือ %1$s ธีมที่กำหนดเอง ID ฐานข้อมูลและตัวเลือกการแยกการส่งผ่าน @@ -239,8 +238,6 @@ ความผิดพลาดในฐานข้อมูล ยืนยันการอัพเกรดฐานข้อมูล ดาวน์เกรดฐานข้อมูล - ที่เก็บแชทถาวร - ที่เก็บแชทถาวร การแชทหยุดทํางานแล้ว เชื่อมต่อสำเร็จ กำลังเปลี่ยนที่อยู่… @@ -432,8 +429,6 @@ เวอร์ชันฐานข้อมูลใหม่กว่าแอป แต่ไม่มีการย้ายข้อมูลลงสำหรับ: %s การย้ายข้อมูลที่แตกต่างกันในแอป/ฐานข้อมูล: %s / %s ปรับลดรุ่นและเปิดแชท - ลบที่เก็บถาวร - ลบที่เก็บแชทถาวร\? กลุ่มที่ไม่ได้ใช้งาน ไม่พบกลุ่ม! คำเชิญเข้าร่วมกลุ่มหมดอายุแล้ว @@ -837,7 +832,6 @@ คืนค่า คืนค่าฐานข้อมูลสำรองไหม\? กู้คืนข้อผิดพลาดของฐานข้อมูล - บันทึกไฟล์เก็บถาวร ลบแล้ว %1$s ลบคุณออกแล้ว ถูกลบแล้ว diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml index 30afe21e50..9dcc45e6c4 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/tr/strings.xml @@ -106,7 +106,6 @@ Veri tabanı yedeğini geri yükle\? Veri tabanını geri yüklerken hata Veritabanı sürüm düşürme - Arşivi kaydet %s (mevcut) Kaydet ve grup profilini güncelle Karşılama mesajı kaydedilsin mi? @@ -429,9 +428,6 @@ Veri tabanı, rastgele bir parola ile şifrelendi. Dışa aktarmadan önce lütfen değiştir. Dosyaları ve medyayı sil\? Veri tabanı şifrelenecektir. - %1$s tarihinde oluşturuldu - Belgeliği sil - Konuşma belgeliğini sil\? %s üyesinin yetkisi %s olarak değiştirildi silinmiş grup kendi yetkini, %s olarak değiştirdin @@ -740,8 +736,6 @@ kişi uçtan uca şifrelemeye sahip değildir Sohbet durduruldu Aklınızda bulunsun: kaybederseniz, parolayı kurtaramaz veya değiştiremezsiniz.]]> - Sohbet arşivi - SOHBET ARŞİVİ %1$s grubuna davet Gruba katıl\? %1$s davet edildi diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml index 604fd1fa1a..732f85e473 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/uk/strings.xml @@ -294,8 +294,6 @@ Зашифрувати базу даних\? Неправильна ключова фраза! Введіть правильну ключову фразу. - Архів чату - АРХІВ ЧАТУ підключив(лась) змінив(ла) вашу роль на %s ви змінили свою роль на %s @@ -375,7 +373,6 @@ Виклики на екрані блокування: від абонента до абонента Завершити дзвінок - Створено %1$s Розгорнути вибір ролі так Налаштування контакту @@ -528,7 +525,6 @@ Відео увімкнено Це може трапитися, якщо ви або ваше з\'єднання використовували застарілу резервну копію бази даних. Відновити резервну копію бази даних - Зберегти архів запрошення до групи %1$s Вас запрошено в групу. Приєднуйтесь, щоб спілкуватися з учасниками групи. Реакції на повідомлення @@ -1070,8 +1066,6 @@ Для відкриття чату потрібна ключова фраза бази даних. Приєднатися до групи\? Оновлення бази даних - Видалити архів - Видалити архів чату\? Вийти з групи? Групу не знайдено! Ця група більше не існує. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/vi/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/vi/strings.xml index eb19247a12..d12db70de6 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/vi/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/vi/strings.xml @@ -226,8 +226,6 @@ Thay đổi quyền hạn đang thay đổi địa chỉ… đang thay đổi địa chỉ… - KHO LƯU TRỮ SIMPLEX CHAT - Kho lưu trữ SimpleX Chat Bảng điều khiển trò chuyện Ứng dụng SimpleX Chat đang hoạt động Cơ sở dữ liệu SimpleX Chat đã bị xóa @@ -361,7 +359,6 @@ Tạo liên kết Được tạo ra tại Tạo địa chỉ - Được tạo ra vào %1$s Được tạo ra tại: %s Tạo hồ sơ trò chuyện Tạo nhóm @@ -437,9 +434,7 @@ Xóa cơ sở dữ liệu Xóa tất cả các tệp Xóa tệp và đa phương tiện? - Xóa kho lữu trữ mặc định (%s) - Xóa kho lữu trữ SimpleX Chat? đã xóa nhóm Xóa tệp Xóa liên hệ? diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml index eefd310fd0..ed60383eb1 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml @@ -47,7 +47,6 @@ 删除 删除地址? 在此后删除 - 删除档案 已删除 删除文件和媒体文件? 为所有人删除 @@ -81,7 +80,6 @@ 允许向成员发送私信。 允许发送限时消息。 删除地址 - 删除聊天档案? 删除聊天资料? 删除联系人 删除联系人? @@ -161,8 +159,6 @@ 聊天数据库已删除 聊天数据库已导入 钥匙串错误 - 聊天档案 - 聊天档案 聊天控制台 聊天数据库 聊天已停止 @@ -719,7 +715,6 @@ 回复 重置为默认 运行聊天程序 - 保存存档 扫码 从您联系人的应用程序中扫描安全码。 安全码 @@ -873,7 +868,6 @@ 接收消息,您的联系人 - 您用来向他们发送消息的服务器。]]> 您将在组主设备上线时连接到该群组,请稍等或稍后再检查! 当您启动应用或在应用程序驻留后台超过30 秒后,您将需要进行身份验证。 - 创建于 %1$s 连接到 SimpleX Chat 开发者提出任何问题并接收更新 。]]> 您已接受连接 您的 SMP 服务器 diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml index 17cc45334e..58372bfa7a 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rTW/strings.xml @@ -632,7 +632,6 @@ %s 秒(s) 加密數據庫時出錯 在金鑰庫儲存密碼 - 建立於 %1$s 還原數據庫的備份 群組為不活躍狀態 邀請連結過時! @@ -700,8 +699,6 @@ 還原 還原數據庫的備份? 還原數據庫時出錯 - 儲存存檔 - 刪除存檔 加入 確定要加入群組? 加入匿名聊天模式 @@ -777,7 +774,6 @@ 匯出數據庫時出錯 匯入數據庫時出錯 受加密的數據庫密碼會再次更新。 - 刪除封存對話? 加密數據庫? 邀請至群組 %1$s 邀請成員 @@ -799,13 +795,11 @@ 對話沒有經過端對端加密 數據庫已加密! 已加密數據庫 - 封存對話 群組資料已經更新 成員 你:%1$s 刪除群組 即時訊息 - 封存對話 移除成員時出錯 修改身份時出錯 群組 diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt index 38d87fc497..d425d81875 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt @@ -3,6 +3,7 @@ package chat.simplex.common.platform import chat.simplex.common.model.* import chat.simplex.common.simplexWindowState import chat.simplex.common.views.call.RcvCallInvitation +import chat.simplex.common.views.database.deleteOldChatArchive import chat.simplex.common.views.helpers.* import java.util.* import chat.simplex.res.MR @@ -30,6 +31,7 @@ fun initApp() { override fun showMessage(title: String, text: String) = chat.simplex.common.model.NtfManager.showMessage(title, text) } applyAppLocale() + deleteOldChatArchive() if (DatabaseUtils.ksSelfDestructPassword.get() == null) { initChatControllerOnStart() } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/database/DatabaseView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/database/DatabaseView.desktop.kt index 889ac98e2d..9ed7170a31 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/database/DatabaseView.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/database/DatabaseView.desktop.kt @@ -9,14 +9,14 @@ import kotlinx.datetime.Instant actual fun restartChatOrApp() { if (chatModel.chatRunning.value == false) { chatModel.chatDbChanged.value = true - startChat(chatModel, mutableStateOf(Instant.DISTANT_PAST), chatModel.chatDbChanged) + startChat(chatModel, mutableStateOf(Instant.DISTANT_PAST), chatModel.chatDbChanged, mutableStateOf(false)) } else { authStopChat(chatModel) { withBGApi { // adding delay in order to prevent locked database by previous initialization delay(1000) chatModel.chatDbChanged.value = true - startChat(chatModel, mutableStateOf(Instant.DISTANT_PAST), chatModel.chatDbChanged) + startChat(chatModel, mutableStateOf(Instant.DISTANT_PAST), chatModel.chatDbChanged, mutableStateOf(false)) } } }