diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt index dfc8c1d4e7..79dceda1b3 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Files.android.kt @@ -15,6 +15,7 @@ actual val dataDir: File = androidAppContext.dataDir actual val tmpDir: File = androidAppContext.getDir("temp", Application.MODE_PRIVATE) actual val filesDir: File = File(dataDir.absolutePath + File.separator + "files") actual val appFilesDir: File = File(filesDir.absolutePath + File.separator + "app_files") +actual val appearanceDir: File = File(filesDir.absolutePath + File.separator + "appearance") actual val coreTmpDir: File = File(filesDir.absolutePath + File.separator + "temp_files") actual val dbAbsolutePrefixPath: String = dataDir.absolutePath + File.separator + "files" diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt index 5a60e1d1b0..256e38e009 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt @@ -150,6 +150,9 @@ fun AppearanceScope.AppearanceLayout( SectionDividerSpaced(maxTopPadding = true) ThemesSection(systemDarkTheme, showSettingsModal, editColor) + + SectionDividerSpaced(maxTopPadding = true) + BackgroundImageSection() SectionBottomSpacer() } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 3838cd45a6..73a8574231 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -4,7 +4,7 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateMap -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.* import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.font.* import androidx.compose.ui.text.style.TextDecoration @@ -137,6 +137,8 @@ object ChatModel { val processedCriticalError: ProcessedErrors = ProcessedErrors(60_000) val processedInternalError: ProcessedErrors = ProcessedErrors(20_000) + val backgroundImage by lazy { mutableStateOf(getBackgroundImageOrDefault()) } + fun getUser(userId: Long): User? = if (currentUser.value?.userId == userId) { currentUser.value } else { 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 494f400fbc..755678c15f 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 @@ -1,8 +1,10 @@ package chat.simplex.common.model +import androidx.compose.material.MaterialTheme import chat.simplex.common.views.helpers.* import androidx.compose.runtime.* import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter import chat.simplex.common.model.ChatController.getNetCfg import chat.simplex.common.model.ChatController.setNetCfg @@ -11,6 +13,7 @@ import chat.simplex.common.model.ChatModel.changingActiveUserMutex import dev.icerock.moko.resources.compose.painterResource import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex import chat.simplex.common.views.call.* import chat.simplex.common.views.migration.MigrationFileLinkData import chat.simplex.common.views.onboarding.OnboardingStage @@ -172,6 +175,18 @@ class AppPreferences { json.decodeFromString(MapSerializer(String.serializer(), ThemeOverrides.serializer()), it) }, settingsThemes) val profileImageCornerRadius = mkFloatPreference(SHARED_PREFS_PROFILE_IMAGE_CORNER_RADIUS, 22.5f) + private val _backgroundImageType = mkStrPreference(SHARED_PREFS_BACKGROUND_IMAGE, json.encodeToString(BackgroundImageType.default)) + val backgroundImageType: SharedPreference = SharedPreference( + get = fun(): BackgroundImageType { + val value = _backgroundImageType.get() ?: return BackgroundImageType.default + return try { + json.decodeFromString(value) + } catch (e: Throwable) { + BackgroundImageType.default + } + }, + set = fun(type: BackgroundImageType) { _backgroundImageType.set(json.encodeToString(type)) } + ) val whatsNewVersion = mkStrPreference(SHARED_PREFS_WHATS_NEW_VERSION, null) val lastMigratedVersionCode = mkIntPreference(SHARED_PREFS_LAST_MIGRATED_VERSION_CODE, 0) @@ -339,6 +354,7 @@ class AppPreferences { private const val SHARED_PREFS_SYSTEM_DARK_THEME = "SystemDarkTheme" private const val SHARED_PREFS_THEMES = "Themes" private const val SHARED_PREFS_PROFILE_IMAGE_CORNER_RADIUS = "ProfileImageCornerRadius" + private const val SHARED_PREFS_BACKGROUND_IMAGE = "BackgroundImage" private const val SHARED_PREFS_WHATS_NEW_VERSION = "WhatsNewVersion" private const val SHARED_PREFS_LAST_MIGRATED_VERSION_CODE = "LastMigratedVersionCode" private const val SHARED_PREFS_CUSTOM_DISAPPEARING_MESSAGE_TIME = "CustomDisappearingMessageTime" 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 c788a6902e..57f268f064 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 @@ -14,6 +14,7 @@ expect val dataDir: File expect val tmpDir: File expect val filesDir: File expect val appFilesDir: File +expect val appearanceDir: File expect val coreTmpDir: File expect val dbAbsolutePrefixPath: String @@ -78,6 +79,18 @@ fun getAppFilePath(fileName: String): String { } } +fun getBackgroundImageFilePath(fileName: String): String { + val rh = chatModel.currentRemoteHost.value + val s = File.separator + val path = if (rh == null) { + appearanceDir.absolutePath + s + fileName + } else { + remoteHostsDir.absolutePath + s + rh.storePath + s + "simplex_v1_appearance" + s + fileName + } + File(path).parentFile.mkdirs() + return path +} + fun getLoadedFilePath(file: CIFile?): String? { val f = file?.fileSource?.filePath return if (f != null && file.loaded) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt index 62acc13bfe..e6709d056a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt @@ -10,6 +10,8 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import chat.simplex.common.model.ChatController import chat.simplex.common.platform.isInNightMode +import chat.simplex.common.ui.theme.ThemeManager.colorFromReadableHex +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex import chat.simplex.common.views.helpers.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.serialization.SerialName @@ -145,11 +147,6 @@ data class ThemeColors( } } -private fun String.colorFromReadableHex(): Color = - Color(this.replace("#", "").toLongOrNull(16) ?: Color.White.toArgb().toLong()) - -private fun Color.toReadableHex(): String = "#" + Integer.toHexString(toArgb()) - @Serializable data class ThemeOverrides ( val base: DefaultTheme, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt index 49d3203455..4a25af8355 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/ThemeManager.kt @@ -152,6 +152,9 @@ object ThemeManager { appPrefs.themeOverrides.set(overrides) CurrentColors.value = currentColors(!CurrentColors.value.colors.isLight) } -} -private fun Color.toReadableHex(): String = "#" + Integer.toHexString(toArgb()) + fun String.colorFromReadableHex(): Color = + Color(this.replace("#", "").toLongOrNull(16) ?: Color.White.toArgb().toLong()) + + fun Color.toReadableHex(): String = "#" + Integer.toHexString(toArgb()) +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index ff5364adc2..b3d3b09ee5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -13,17 +13,18 @@ import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.* import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.* import androidx.compose.ui.platform.* import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.text.* import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.ui.theme.* import chat.simplex.common.views.call.* @@ -34,6 +35,7 @@ import chat.simplex.common.views.helpers.* import chat.simplex.common.model.GroupInfo import chat.simplex.common.platform.* import chat.simplex.common.platform.AudioPlayer +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex import chat.simplex.common.views.newchat.ContactConnectionInfoView import chat.simplex.res.MR import kotlinx.coroutines.* @@ -551,6 +553,8 @@ fun ChatLayout( ) { val scope = rememberCoroutineScope() val attachmentDisabled = remember { derivedStateOf { composeState.value.attachmentDisabled } } + val backgroundImage = remember { chatModel.backgroundImage } + val backgroundImageType = remember { appPrefs.backgroundImageType.state } Box( Modifier .fillMaxWidth() @@ -596,9 +600,13 @@ fun ChatLayout( floatingActionButton = { floatingButton.value() }, contentColor = LocalContentColor.current, drawerContentColor = LocalContentColor.current, + backgroundColor = Color.Unspecified ) { contentPadding -> + val primaryColor = MaterialTheme.colors.primary BoxWithConstraints(Modifier .fillMaxHeight() + .background(MaterialTheme.colors.background) + .drawBehind { chatViewBackground(backgroundImage.value, backgroundImageType.value, primaryColor) } .padding(contentPadding) ) { ChatItemsList( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatViewBackground.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatViewBackground.kt new file mode 100644 index 0000000000..f2f2bd573c --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatViewBackground.kt @@ -0,0 +1,84 @@ +package chat.simplex.common.views.helpers + +import androidx.compose.material.MaterialTheme +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.* +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntSize +import chat.simplex.res.MR +import chat.simplex.common.ui.theme.ThemeManager.colorFromReadableHex +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex +import dev.icerock.moko.resources.ImageResource +import dev.icerock.moko.resources.StringResource +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlin.math.max +import kotlin.math.roundToInt + +@Serializable +enum class PredefinedBackgroundImage(val res: ImageResource, val filename: String, val text: StringResource, val type: BackgroundImageType) { + @SerialName("cat") CAT(MR.images.background_cat, "background_cat", MR.strings.background_cat, BackgroundImageType.Repeated(false, "background_cat", 1f, null)); + + companion object { + fun from(filename: String): PredefinedBackgroundImage? = + entries.firstOrNull { it.filename == filename } + } +} + +@Serializable +enum class BackgroundImageScale(val contentScale: ContentScale) { + @SerialName("crop") CROP(ContentScale.Crop), + @SerialName("fit") FIT(ContentScale.Fit), + @SerialName("fillWidth") FILL_WIDTH(ContentScale.FillWidth), + @SerialName("fillHeight") FILL_HEIGHT(ContentScale.FillHeight), + @SerialName("fillBounds") FILL_BOUNDS((ContentScale.FillBounds)) +} + +@Serializable +sealed class BackgroundImageType { + abstract val custom: Boolean + abstract val filename: String + @Serializable @SerialName("repeated") data class Repeated(override val custom: Boolean = true, override val filename: String, val scale: Float, val tint: String?): BackgroundImageType() + @Serializable @SerialName("static") data class Static(override val custom: Boolean = true, override val filename: String, val scale: BackgroundImageScale, val tint: String?): BackgroundImageType() + + val tintColor: Color? by lazy { + when (this) { + is Repeated -> tint?.colorFromReadableHex() + is Static -> tint?.colorFromReadableHex() + } + } + + fun toPredefined(): PredefinedBackgroundImage? = + when (this) { + is Repeated -> if (!custom) PredefinedBackgroundImage.from(filename) else null + is Static -> if (!custom) PredefinedBackgroundImage.from(filename) else null + } + + companion object { + val default: BackgroundImageType = + Repeated(custom = false, PredefinedBackgroundImage.CAT.filename, 1f, null) + } +} + +fun DrawScope.chatViewBackground(image: ImageBitmap, imageType: BackgroundImageType, defaultTint: Color) { + if (imageType is BackgroundImageType.Repeated) { + val scale = imageType.scale + for (h in 0..(size.height / image.height / scale).roundToInt()) { + for (w in 0..(size.width / image.width / scale).roundToInt()) { + drawImage( + image, + dstOffset = IntOffset(x = (w * image.width * scale).roundToInt(), y = (h * image.height * scale).roundToInt()), + dstSize = IntSize((image.width * scale).roundToInt(), (image.height * scale).roundToInt()), + colorFilter = ColorFilter.tint(imageType.tintColor ?: defaultTint) + ) + } + } + } else if (imageType is BackgroundImageType.Static) { + val scale = imageType.scale.contentScale.computeScaleFactor(Size(image.width.toFloat(), image.height.toFloat()), Size(size.width, size.height)) + val scaledWidth = (image.width * scale.scaleX).roundToInt() + val scaledHeight = (image.height * scale.scaleY).roundToInt() + drawImage(image, dstOffset = IntOffset(x = (max(0f, size.width - scaledWidth) / 2).roundToInt(), y = (max(0f, size.height - scaledHeight) / 2).roundToInt()), dstSize = IntSize(scaledWidth, scaledHeight)) + } +} \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt index 9a6e3a0f9a..c69bbf63a6 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt @@ -16,6 +16,7 @@ import com.charleskorn.kaml.decodeFromStream import dev.icerock.moko.resources.StringResource import kotlinx.coroutines.* import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.decodeFromStream import java.io.* import java.net.URI import java.nio.file.Files @@ -156,6 +157,34 @@ fun getThemeFromUri(uri: URI, withAlertOnException: Boolean = true): ThemeOverri return null } +fun getBackgroundImageFromUri(uri: URI, withAlertOnException: Boolean = true): Pair? { + uri.inputStream().use { + runCatching { + return uri.toFile().name to loadImageBitmap(it!!) + }.onFailure { + if (withAlertOnException) { + AlertManager.shared.showAlertMsg( + title = generalGetString(MR.strings.import_background_image_error), + text = generalGetString(MR.strings.import_background_image_desc), + ) + } + } + } + return null +} + +fun getBackgroundImageOrDefault(): ImageBitmap { + val type = appPreferences.backgroundImageType.get() + val res = if (type.custom) { + File(getBackgroundImageFilePath(type.filename)).inputStream().use { + loadImageBitmap(it) + } + } else { + PredefinedBackgroundImage.from(type.filename)?.res?.image?.toComposeImageBitmap() + } + return res ?: BackgroundImageType.default.toPredefined()!!.res.image.toComposeImageBitmap() +} + fun saveImage(uri: URI): CryptoFile? { val bitmap = getBitmapFromUri(uri) ?: return null return saveImage(bitmap) @@ -280,6 +309,23 @@ fun saveFileFromUri(uri: URI, withAlertOnException: Boolean = true): CryptoFile? } } +fun saveBackgroundImage(uri: URI): Pair? { + val res = getBackgroundImageFromUri(uri, true) ?: return null + val destFile = File(getBackgroundImageFilePath(res.first)) + val inputStream = uri.inputStream() + try { + Files.copy(inputStream!!, destFile.toPath()) + } catch (e: Exception) { + Log.e(TAG, "Error saving background image: ${e.stackTraceToString()}") + return null + } + return res +} + +fun removeBackgroundImage(fileName: String) { + File(getBackgroundImageFilePath(fileName)).delete() +} + fun createTmpFileAndDelete(onCreated: (File) -> T): T { val tmpFile = File(tmpDir, UUID.randomUUID().toString()) tmpFile.deleteOnExit() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt index 78e24e5e7e..2162c90f1d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt @@ -19,14 +19,18 @@ import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.model.ChatModel import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.ThemeManager.toReadableHex +import chat.simplex.common.views.chat.SendReceipts import chat.simplex.res.MR import com.godaddy.android.colorpicker.* import kotlinx.serialization.encodeToString import java.net.URI +import java.nio.file.Files import java.util.* import kotlin.collections.ArrayList @@ -87,6 +91,49 @@ object AppearanceScope { SectionItemView(showSettingsModal { _ -> CustomizeThemeView(editColor) }) { Text(stringResource(MR.strings.customize_theme_title)) } } + @Composable + fun BackgroundImageSection() { + SectionView(stringResource(MR.strings.settings_section_title_background_image).uppercase()) { + val pref = remember { appPrefs.backgroundImageType.state } + val state = remember { + val type = appPrefs.backgroundImageType.get() + mutableStateOf(if (type.custom) "" else type.filename) + } + val values = remember { + PredefinedBackgroundImage.entries.map { it.filename to generalGetString(it.text) } + ("" to generalGetString(MR.strings.background_choose_own_image)) + } + val importBackgroundImageLauncher = rememberFileChooserLauncher(true) { to: URI? -> + if (to != null) { + val res = saveBackgroundImage(to) + if (res != null) { + val (filename, backgroundImage) = res + state.value = "" + chatModel.backgroundImage.value = backgroundImage + appPrefs.backgroundImageType.set(BackgroundImageType.Static(custom = true, filename, BackgroundImageScale.CROP, null)) + } + } + } + ExposedDropDownSettingRow( + stringResource(MR.strings.settings_section_title_background_image), + values, + state, + enabled = remember { mutableStateOf(true) }, + onSelected = { filename -> + if (filename.isEmpty()) { + withLongRunningApi { importBackgroundImageLauncher.launch("image/*") } + } else { + if (state.value.isEmpty()) { + removeBackgroundImage(appPrefs.backgroundImageType.get().filename) + } + state.value = filename + appPrefs.backgroundImageType.set(PredefinedBackgroundImage.from(filename)!!.type) + chatModel.backgroundImage.value = getBackgroundImageOrDefault() + } + } + ) + } + } + @Composable fun CustomizeThemeView(editColor: (ThemeColor, Color) -> Unit) { ColumnWithScrollBar( 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 6ca14aace2..cdc79e2759 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -1034,6 +1034,7 @@ APP ICON THEMES Profile images + Background image MESSAGES AND FILES CALLS Network connection @@ -1519,6 +1520,8 @@ Import theme Import theme error Make sure the file has correct YAML syntax. Export theme to have an example of the theme file structure. + Import background image error + Make sure the file can be read correctly. Export theme Reset colors Accent @@ -1531,6 +1534,10 @@ Sent message Received message + + Choose you own… + Cat + You allow Contact allows diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/background_cat@4x.png b/apps/multiplatform/common/src/commonMain/resources/MR/images/background_cat@4x.png new file mode 100644 index 0000000000..5643b00e0e Binary files /dev/null and b/apps/multiplatform/common/src/commonMain/resources/MR/images/background_cat@4x.png differ diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt index 9b2368fcd3..43fd42b396 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Files.desktop.kt @@ -13,6 +13,7 @@ actual val dataDir: File = File(desktopPlatform.dataPath) actual val tmpDir: File = File(System.getProperty("java.io.tmpdir") + File.separator + "simplex").also { it.deleteOnExit() } actual val filesDir: File = File(dataDir.absolutePath + File.separator + "simplex_v1_files") actual val appFilesDir: File = filesDir +actual val appearanceDir: File = File(dataDir.absolutePath + File.separator + "simplex_v1_appearance") actual val coreTmpDir: File = File(dataDir.absolutePath + File.separator + "tmp") actual val dbAbsolutePrefixPath: String = dataDir.absolutePath + File.separator + "simplex_v1" diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt index 4e4846bc9f..e21ffe24e7 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt @@ -67,6 +67,9 @@ fun AppearanceScope.AppearanceLayout( SectionDividerSpaced(maxTopPadding = true) ThemesSection(systemDarkTheme, showSettingsModal, editColor) + + SectionDividerSpaced(maxTopPadding = true) + BackgroundImageSection() SectionBottomSpacer() } }