mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 04:39:53 +00:00
desktop: saving settings in a safer way to handle process death (#4687)
* desktop: saving settings in a safer way to handle process death * enhancements * unused * changes * rename
This commit is contained in:
parent
912aaa2741
commit
05a5d161fb
9 changed files with 73 additions and 24 deletions
|
@ -19,6 +19,8 @@ actual val wallpapersDir: File = File(filesDir.absolutePath + File.separator + "
|
|||
actual val coreTmpDir: File = File(filesDir.absolutePath + File.separator + "temp_files")
|
||||
actual val dbAbsolutePrefixPath: String = dataDir.absolutePath + File.separator + "files"
|
||||
actual val preferencesDir = File(dataDir.absolutePath + File.separator + "shared_prefs")
|
||||
actual val preferencesTmpDir = File(tmpDir, "prefs_tmp")
|
||||
.also { it.deleteRecursively() }
|
||||
|
||||
actual val chatDatabaseFileName: String = "files_chat.db"
|
||||
actual val agentDatabaseFileName: String = "files_agent.db"
|
||||
|
|
|
@ -3168,8 +3168,12 @@ class SharedPreference<T>(val get: () -> T, set: (T) -> Unit) {
|
|||
|
||||
init {
|
||||
this.set = { value ->
|
||||
set(value)
|
||||
_state.value = value
|
||||
try {
|
||||
set(value)
|
||||
_state.value = value
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error saving settings: ${e.stackTraceToString()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package chat.simplex.common.platform
|
|||
import androidx.compose.runtime.Composable
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.generalGetString
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
import com.charleskorn.kaml.*
|
||||
import kotlinx.serialization.encodeToString
|
||||
|
@ -11,6 +11,8 @@ import java.io.*
|
|||
import java.net.URI
|
||||
import java.net.URLDecoder
|
||||
import java.net.URLEncoder
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
expect val dataDir: File
|
||||
expect val tmpDir: File
|
||||
|
@ -20,6 +22,7 @@ expect val wallpapersDir: File
|
|||
expect val coreTmpDir: File
|
||||
expect val dbAbsolutePrefixPath: String
|
||||
expect val preferencesDir: File
|
||||
expect val preferencesTmpDir: File
|
||||
|
||||
expect val chatDatabaseFileName: String
|
||||
expect val agentDatabaseFileName: String
|
||||
|
@ -142,16 +145,23 @@ fun readThemeOverrides(): List<ThemeOverrides> {
|
|||
}
|
||||
}
|
||||
|
||||
private const val lock = "themesWriter"
|
||||
|
||||
fun writeThemeOverrides(overrides: List<ThemeOverrides>): Boolean =
|
||||
try {
|
||||
File(getPreferenceFilePath("themes.yaml")).outputStream().use {
|
||||
val string = yaml.encodeToString(ThemesFile(themes = overrides))
|
||||
it.bufferedWriter().use { it.write(string) }
|
||||
synchronized(lock) {
|
||||
try {
|
||||
val themesFile = File(getPreferenceFilePath("themes.yaml"))
|
||||
createTmpFileAndDelete(preferencesTmpDir) { tmpFile ->
|
||||
val string = yaml.encodeToString(ThemesFile(themes = overrides))
|
||||
tmpFile.bufferedWriter().use { it.write(string) }
|
||||
themesFile.parentFile.mkdirs()
|
||||
Files.move(tmpFile.toPath(), themesFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||
}
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error writing themes file: ${e.stackTraceToString()}")
|
||||
false
|
||||
}
|
||||
true
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "Error while writing themes file: ${e.stackTraceToString()}")
|
||||
false
|
||||
}
|
||||
|
||||
private fun fileReady(file: CIFile, filePath: String) =
|
||||
|
|
|
@ -102,7 +102,9 @@ object ThemeManager {
|
|||
}
|
||||
|
||||
fun applyTheme(theme: String) {
|
||||
appPrefs.currentTheme.set(theme)
|
||||
if (appPrefs.currentTheme.get() != theme) {
|
||||
appPrefs.currentTheme.set(theme)
|
||||
}
|
||||
CurrentColors.value = currentColors(null, null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get())
|
||||
platform.androidSetNightModeIfSupported()
|
||||
val c = CurrentColors.value.colors
|
||||
|
|
|
@ -316,8 +316,9 @@ fun removeWallpaperFile(fileName: String? = null) {
|
|||
WallpaperType.cachedImages.remove(fileName)
|
||||
}
|
||||
|
||||
fun <T> createTmpFileAndDelete(onCreated: (File) -> T): T {
|
||||
val tmpFile = File(tmpDir, UUID.randomUUID().toString())
|
||||
fun <T> createTmpFileAndDelete(dir: File = tmpDir, onCreated: (File) -> T): T {
|
||||
val tmpFile = File(dir, UUID.randomUUID().toString())
|
||||
tmpFile.parentFile.mkdirs()
|
||||
tmpFile.deleteOnExit()
|
||||
ChatModel.filesToDelete.add(tmpFile)
|
||||
try {
|
||||
|
|
|
@ -16,6 +16,8 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ChatController.setConditionsNotified
|
||||
import chat.simplex.common.model.ServerOperator.Companion.dummyOperatorInfo
|
||||
|
@ -766,7 +768,9 @@ private val versionDescriptions: List<VersionDescription> = listOf(
|
|||
private val lastVersion = versionDescriptions.last().version
|
||||
|
||||
fun setLastVersionDefault(m: ChatModel) {
|
||||
m.controller.appPrefs.whatsNewVersion.set(lastVersion)
|
||||
if (appPrefs.whatsNewVersion.get() != lastVersion) {
|
||||
appPrefs.whatsNewVersion.set(lastVersion)
|
||||
}
|
||||
}
|
||||
|
||||
fun shouldShowWhatsNew(m: ChatModel): Boolean {
|
||||
|
|
|
@ -943,6 +943,7 @@
|
|||
<string name="show_slow_api_calls">Show slow API calls</string>
|
||||
<string name="shutdown_alert_question">Shutdown?</string>
|
||||
<string name="shutdown_alert_desc">Notifications will stop working until you re-launch the app</string>
|
||||
<string name="prefs_error_saving_settings">Error saving settings</string>
|
||||
|
||||
<!-- Address Items - UserAddressView.kt -->
|
||||
<string name="create_address">Create address</string>
|
||||
|
|
|
@ -17,6 +17,8 @@ actual val wallpapersDir: File = File(dataDir.absolutePath + File.separator + "s
|
|||
actual val coreTmpDir: File = File(dataDir.absolutePath + File.separator + "tmp")
|
||||
actual val dbAbsolutePrefixPath: String = dataDir.absolutePath + File.separator + "simplex_v1"
|
||||
actual val preferencesDir = File(desktopPlatform.configPath).also { it.parentFile.mkdirs() }
|
||||
actual val preferencesTmpDir = File(desktopPlatform.configPath, "tmp")
|
||||
.also { it.deleteRecursively() }
|
||||
|
||||
actual val chatDatabaseFileName: String = "simplex_v1_chat.db"
|
||||
actual val agentDatabaseFileName: String = "simplex_v1_agent.db"
|
||||
|
|
|
@ -9,15 +9,16 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.simplexWindowState
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
import com.jthemedetecor.OsThemeDetector
|
||||
import com.russhwolf.settings.*
|
||||
import dev.icerock.moko.resources.ImageResource
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import dev.icerock.moko.resources.desc.desc
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Composable
|
||||
actual fun font(name: String, res: String, weight: FontWeight, style: FontStyle): Font =
|
||||
|
@ -37,10 +38,8 @@ catch (e: Exception) {
|
|||
|
||||
private val settingsFile =
|
||||
File(desktopPlatform.configPath + File.separator + "settings.properties")
|
||||
.also { it.parentFile.mkdirs() }
|
||||
private val settingsThemesFile =
|
||||
File(desktopPlatform.configPath + File.separator + "themes.properties")
|
||||
.also { it.parentFile.mkdirs() }
|
||||
|
||||
private val settingsProps =
|
||||
Properties()
|
||||
|
@ -61,11 +60,35 @@ private val settingsThemesProps =
|
|||
Properties()
|
||||
.also { props -> try { settingsThemesFile.reader().use { props.load(it) } } catch (e: Exception) { /**/ } }
|
||||
|
||||
|
||||
private val settingsWriterThread = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
|
||||
actual val settings: Settings = PropertiesSettings(settingsProps) { CoroutineScope(settingsWriterThread).launch { settingsFile.writer().use { settingsProps.store(it, "") } } }
|
||||
actual val settingsThemes: Settings = PropertiesSettings(settingsThemesProps) { CoroutineScope(settingsWriterThread).launch { settingsThemesFile.writer().use { settingsThemesProps.store(it, "") } } }
|
||||
private const val lock = "settingsSaver"
|
||||
actual val settings: Settings = PropertiesSettings(settingsProps) {
|
||||
synchronized(lock) {
|
||||
try {
|
||||
createTmpFileAndDelete(preferencesTmpDir) { tmpFile ->
|
||||
tmpFile.writer().use { settingsProps.store(it, "") }
|
||||
settingsFile.parentFile.mkdirs()
|
||||
Files.move(tmpFile.toPath(), settingsFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.prefs_error_saving_settings), e.stackTraceToString())
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
actual val settingsThemes: Settings = PropertiesSettings(settingsThemesProps) {
|
||||
synchronized(lock) {
|
||||
try {
|
||||
createTmpFileAndDelete(preferencesTmpDir) { tmpFile ->
|
||||
tmpFile.writer().use { settingsThemesProps.store(it, "") }
|
||||
settingsThemesFile.parentFile.mkdirs()
|
||||
Files.move(tmpFile.toPath(), settingsThemesFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.prefs_error_saving_settings), e.stackTraceToString())
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun windowOrientation(): WindowOrientation =
|
||||
if (simplexWindowState.windowState.size.width > simplexWindowState.windowState.size.height) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue