diff --git a/apps/android/app/src/main/AndroidManifest.xml b/apps/android/app/src/main/AndroidManifest.xml index d75a79b49f..5f2de04a24 100644 --- a/apps/android/app/src/main/AndroidManifest.xml +++ b/apps/android/app/src/main/AndroidManifest.xml @@ -38,7 +38,6 @@ android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.SimpleX"> - @@ -65,6 +64,35 @@ + + + + + + + + + + + + + + + diff --git a/apps/android/app/src/main/icon_dark_blue-playstore.png b/apps/android/app/src/main/icon_dark_blue-playstore.png new file mode 100644 index 0000000000..cf0d517bba Binary files /dev/null and b/apps/android/app/src/main/icon_dark_blue-playstore.png differ diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt new file mode 100644 index 0000000000..8a35d64916 --- /dev/null +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/Appearance.kt @@ -0,0 +1,118 @@ +package chat.simplex.app.views.usersettings + +import SectionView +import android.content.ComponentName +import android.content.pm.PackageManager +import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT +import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED +import androidx.compose.foundation.* +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.material.* +import androidx.compose.material.MaterialTheme.colors +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.toBitmap +import chat.simplex.app.* +import chat.simplex.app.R +import chat.simplex.app.ui.theme.* + +enum class AppIcon(val resId: Int) { + DEFAULT(R.mipmap.icon), + DARK_BLUE(R.mipmap.icon_dark_blue), +} + +@Composable +fun AppearanceView() { + val appIcon = remember { mutableStateOf(findEnabledIcon()) } + + fun setAppIcon(newIcon: AppIcon) { + if (appIcon.value == newIcon) return + val newComponent = ComponentName(BuildConfig.APPLICATION_ID, "chat.simplex.app.MainActivity_${newIcon.name.lowercase()}") + val oldComponent = ComponentName(BuildConfig.APPLICATION_ID, "chat.simplex.app.MainActivity_${appIcon.value.name.lowercase()}") + SimplexApp.context.packageManager.setComponentEnabledSetting( + newComponent, + COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP + ) + + SimplexApp.context.packageManager.setComponentEnabledSetting( + oldComponent, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP + ) + + appIcon.value = newIcon + } + + AppearanceLayout( + appIcon, + changeIcon = ::setAppIcon + ) +} + +@Composable fun AppearanceLayout( + icon: MutableState, + changeIcon: (AppIcon) -> Unit +) { + Column( + Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Text( + stringResource(R.string.appearance_settings), + Modifier.padding(start = 16.dp, bottom = 24.dp), + style = MaterialTheme.typography.h1 + ) + SectionView(stringResource(R.string.settings_section_title_icon)) { + LazyRow( + Modifier + .padding(horizontal = 8.dp) + ) { + items(AppIcon.values().size, { index -> AppIcon.values()[index] }) { index -> + val item = AppIcon.values()[index] + val mipmap = ContextCompat.getDrawable(LocalContext.current, item.resId)!! + Image( + bitmap = mipmap.toBitmap().asImageBitmap(), + contentDescription = "", + contentScale = ContentScale.Fit, + modifier = Modifier + .shadow(if (item == icon.value) 1.dp else 0.dp, ambientColor = colors.secondary) + .size(70.dp) + .clickable { changeIcon(item) } + .padding(10.dp) + ) + + if (index + 1 != AppIcon.values().size) { + Spacer(Modifier.padding(horizontal = 4.dp)) + } + } + } + } + } +} + +private fun findEnabledIcon(): AppIcon = AppIcon.values().first { icon -> + SimplexApp.context.packageManager.getComponentEnabledSetting( + ComponentName(BuildConfig.APPLICATION_ID, "chat.simplex.app.MainActivity_${icon.name.lowercase()}") + ).let { it == COMPONENT_ENABLED_STATE_DEFAULT || it == COMPONENT_ENABLED_STATE_ENABLED } +} + +@Preview(showBackground = true) +@Composable +fun PreviewAppearanceSettings() { + SimpleXTheme { + AppearanceLayout( + icon = remember { mutableStateOf(AppIcon.DARK_BLUE) }, + changeIcon = {} + ) + } +} diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt index 49a52784ef..d1c68259a4 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SettingsView.kt @@ -75,6 +75,18 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit) { } } } + }, + showAppearance = { + withApi { + ModalManager.shared.showCustomModal { close -> + ModalView( + close = close, modifier = Modifier, + background = if (isSystemInDarkTheme()) MaterialTheme.colors.background else SettingsBackgroundLight + ) { + AppearanceView() + } + } + } } // showVideoChatPrototype = { ModalManager.shared.showCustomModal { close -> CallViewDebug(close) } }, ) @@ -106,7 +118,8 @@ fun SettingsLayout( showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), showCustomModal: (@Composable (ChatModel, () -> Unit) -> Unit) -> (() -> Unit), showTerminal: () -> Unit, - showNetworkSettings: () -> Unit + showNetworkSettings: () -> Unit, + showAppearance: () -> Unit // showVideoChatPrototype: () -> Unit ) { val uriHandler = LocalUriHandler.current @@ -145,6 +158,8 @@ fun SettingsLayout( SettingsActionItem(Icons.Outlined.Dns, stringResource(R.string.smp_servers), showModal { SMPServersView(it) }, disabled = stopped) SectionDivider() SettingsActionItem(Icons.Outlined.SettingsEthernet, stringResource(R.string.network_settings), showNetworkSettings, disabled = stopped) + SectionDivider() + SettingsActionItem(Icons.Outlined.LightMode, stringResource(R.string.appearance_settings), showAppearance, disabled = stopped) } SectionSpacer() @@ -355,7 +370,8 @@ fun PreviewSettingsLayout() { showSettingsModal = { {} }, showCustomModal = { {} }, showTerminal = {}, - showNetworkSettings = {} + showNetworkSettings = {}, + showAppearance = {}, // showVideoChatPrototype = {} ) } diff --git a/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_dark_blue.xml b/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_dark_blue.xml new file mode 100644 index 0000000000..1d211342c6 --- /dev/null +++ b/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_dark_blue.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_dark_blue_round.xml b/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_dark_blue_round.xml new file mode 100644 index 0000000000..1d211342c6 --- /dev/null +++ b/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_dark_blue_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_round_dark_blue.xml b/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_round_dark_blue.xml new file mode 100644 index 0000000000..4407fbbf70 --- /dev/null +++ b/apps/android/app/src/main/res/mipmap-anydpi-v26/icon_round_dark_blue.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue.png b/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue.png new file mode 100644 index 0000000000..979790eb2f Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue.png differ diff --git a/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue_foreground.png b/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue_foreground.png new file mode 100644 index 0000000000..1a2098ea45 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue_foreground.png differ diff --git a/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue_round.png b/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue_round.png new file mode 100644 index 0000000000..fa6670116b Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-hdpi/icon_dark_blue_round.png differ diff --git a/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue.png b/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue.png new file mode 100644 index 0000000000..6dbcaf2f1e Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue.png differ diff --git a/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue_foreground.png b/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue_foreground.png new file mode 100644 index 0000000000..09829fe1dc Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue_foreground.png differ diff --git a/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue_round.png b/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue_round.png new file mode 100644 index 0000000000..b9c14794c2 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-mdpi/icon_dark_blue_round.png differ diff --git a/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue.png b/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue.png new file mode 100644 index 0000000000..ec2311a5bc Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue.png differ diff --git a/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue_foreground.png b/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue_foreground.png new file mode 100644 index 0000000000..ee55a65ebf Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue_foreground.png differ diff --git a/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue_round.png b/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue_round.png new file mode 100644 index 0000000000..0d42619d36 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xhdpi/icon_dark_blue_round.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue.png b/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue.png new file mode 100644 index 0000000000..8cd4f06cea Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue_foreground.png b/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue_foreground.png new file mode 100644 index 0000000000..478551101b Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue_foreground.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue_round.png b/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue_round.png new file mode 100644 index 0000000000..e413ad857d Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxhdpi/icon_dark_blue_round.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue.png b/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue.png new file mode 100644 index 0000000000..f6570e9177 Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue_foreground.png b/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue_foreground.png new file mode 100644 index 0000000000..11c7bc696b Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue_foreground.png differ diff --git a/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue_round.png b/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue_round.png new file mode 100644 index 0000000000..53b181722b Binary files /dev/null and b/apps/android/app/src/main/res/mipmap-xxxhdpi/icon_dark_blue_round.png differ diff --git a/apps/android/app/src/main/res/values-ru/strings.xml b/apps/android/app/src/main/res/values-ru/strings.xml index d38fc837bc..19e3001102 100644 --- a/apps/android/app/src/main/res/values-ru/strings.xml +++ b/apps/android/app/src/main/res/values-ru/strings.xml @@ -279,6 +279,7 @@ Соединяться с серверами через SOCKS прокси через порт 9050? Прокси должен быть запущен до включения этой опции. Использовать прямое соединение с Интернет? Если вы подтвердите, серверы смогут видеть ваш IP адрес, а провайдер - с какими серверами вы соединяетесь. + Интерфейс Создать адрес @@ -456,6 +457,7 @@ Инструменты разработчика Экспериментальные функции SOCKS ПРОКСИ + ИКОНКА Данные чата diff --git a/apps/android/app/src/main/res/values/icon_dark_blue_background.xml b/apps/android/app/src/main/res/values/icon_dark_blue_background.xml new file mode 100644 index 0000000000..0c13586f05 --- /dev/null +++ b/apps/android/app/src/main/res/values/icon_dark_blue_background.xml @@ -0,0 +1,4 @@ + + + #030749 + \ No newline at end of file diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index 6ffc49f79b..9eb7c81c60 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -284,6 +284,7 @@ Access the servers via SOCKS proxy on port 9050? Proxy must be started before enabling this option. Use direct Internet connection? If you confirm, the messaging servers will be able to see your IP address, and your provider - which servers you are connecting to. + Appearance Create address @@ -458,6 +459,7 @@ Developer tools Experimental features SOCKS PROXY + APP ICON Your chat database