feat: support Monet dynamic color (Android 12+) - Add toggle in UI settings, default enabled, auto-disable on unsupported devices (#6067)
This commit is contained in:
1 parent
9cdbc5cebb
commit
2607b5cbff
13 files changed
+66
-1
No files matched your search
@@ -58,6 +58,7 @@ object AppConfig {
|
||||
const val PREF_LANGUAGE = "pref_language"
|
||||
const val PREF_APP_LOCALE_MIGRATED = "pref_app_locale_migrated"
|
||||
const val PREF_UI_MODE_NIGHT = "pref_ui_mode_night"
|
||||
const val PREF_DYNAMIC_COLOR = "pref_dynamic_color"
|
||||
const val PREF_IPV6_ENABLED = "pref_ipv6_enabled"
|
||||
const val PREF_PREFER_IPV6 = "pref_prefer_ipv6"
|
||||
const val PREF_PROXY_SHARING = "pref_proxy_sharing_enabled"
|
||||
|
||||
@@ -19,6 +19,7 @@ object SettingsChangeManager {
|
||||
AppConfig.PREF_GROUP_ALL_DISPLAY,
|
||||
AppConfig.PREF_LANGUAGE,
|
||||
AppConfig.PREF_UI_MODE_NIGHT,
|
||||
AppConfig.PREF_DYNAMIC_COLOR,
|
||||
AppConfig.PREF_IS_BOOTED,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.v2ray.ang.ui.compose
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
@@ -15,6 +18,7 @@ import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.v2ray.ang.AppConfig
|
||||
@@ -122,14 +126,26 @@ object ThemeManager {
|
||||
)
|
||||
val themeMode: StateFlow<String> = _themeMode.asStateFlow()
|
||||
|
||||
private val _dynamicColorEnabled = MutableStateFlow(
|
||||
MmkvManager.decodeSettingsBool(AppConfig.PREF_DYNAMIC_COLOR, true)
|
||||
)
|
||||
val dynamicColorEnabled: StateFlow<Boolean> = _dynamicColorEnabled.asStateFlow()
|
||||
|
||||
fun setThemeMode(mode: String) {
|
||||
MmkvManager.encodeSettings(AppConfig.PREF_UI_MODE_NIGHT, mode)
|
||||
_themeMode.value = mode
|
||||
}
|
||||
|
||||
fun setDynamicColorEnabled(enabled: Boolean) {
|
||||
MmkvManager.encodeSettings(AppConfig.PREF_DYNAMIC_COLOR, enabled)
|
||||
_dynamicColorEnabled.value = enabled
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
_themeMode.value =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_UI_MODE_NIGHT, "0") ?: "0"
|
||||
_dynamicColorEnabled.value =
|
||||
MmkvManager.decodeSettingsBool(AppConfig.PREF_DYNAMIC_COLOR, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +166,15 @@ fun AppTheme(
|
||||
darkTheme: Boolean = resolveDarkTheme(),
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = if (darkTheme) DarkColor else LightColor
|
||||
val dynamicColor by ThemeManager.dynamicColorEnabled.collectAsState()
|
||||
val context = LocalContext.current
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
}
|
||||
darkTheme -> DarkColor
|
||||
else -> LightColor
|
||||
}
|
||||
val snackbarController = rememberAppSnackbarController()
|
||||
|
||||
val view = LocalView.current
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.v2ray.ang.ui.settings
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -13,6 +14,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ScaffoldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -129,6 +131,7 @@ fun SettingsScreen(
|
||||
)
|
||||
}
|
||||
var uiModeNight by rememberMmkvString(AppConfig.PREF_UI_MODE_NIGHT, "0")
|
||||
var dynamicColor by rememberMmkvBool(AppConfig.PREF_DYNAMIC_COLOR, true)
|
||||
|
||||
var ipv6Enabled by rememberMmkvBool(AppConfig.PREF_IPV6_ENABLED, false)
|
||||
var preferIpv6 by rememberMmkvBool(AppConfig.PREF_PREFER_IPV6, false)
|
||||
@@ -151,6 +154,14 @@ fun SettingsScreen(
|
||||
val effectiveLocalProxy = enableLocalProxy || localProxyForced
|
||||
val muxXudpConcurrencyInt = muxXudpConcurrency.toIntOrNull() ?: 8
|
||||
|
||||
val dynamicColorSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
LaunchedEffect(dynamicColorSupported) {
|
||||
if (!dynamicColorSupported && dynamicColor) {
|
||||
dynamicColor = false
|
||||
ThemeManager.setDynamicColorEnabled(false)
|
||||
}
|
||||
}
|
||||
|
||||
val languageEntries = stringArrayResource(R.array.language_select).toList()
|
||||
val languageValues = stringArrayResource(R.array.language_select_value).toList()
|
||||
val uiModeNightEntries = stringArrayResource(R.array.ui_mode_night).toList()
|
||||
@@ -227,6 +238,16 @@ fun SettingsScreen(
|
||||
SettingsChangeManager.makeSetupGroupTab()
|
||||
}
|
||||
)
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.title_pref_dynamic_color),
|
||||
summary = stringResource(R.string.summary_pref_dynamic_color),
|
||||
checked = dynamicColor,
|
||||
enabled = dynamicColorSupported,
|
||||
onCheckedChange = {
|
||||
dynamicColor = it
|
||||
ThemeManager.setDynamicColorEnabled(it)
|
||||
}
|
||||
)
|
||||
SettingsListItem(
|
||||
title = stringResource(R.string.title_language),
|
||||
entries = languageEntries,
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">اللغة</string>
|
||||
<string name="title_ui_settings">إعدادات واجهة المستخدم</string>
|
||||
<string name="title_pref_ui_mode_night">إعدادات وضع واجهة المستخدم ليلاً</string>
|
||||
<string name="title_pref_dynamic_color">تفعيل الألوان الديناميكية</string>
|
||||
<string name="summary_pref_dynamic_color">يعمل فقط على أندرويد 12+</string>
|
||||
<string name="title_pref_use_hev_tunnel">تمكين ميزة Hev TUN</string>
|
||||
<string name="summary_pref_use_hev_tunnel">عند التمكين، سيستخدم TUN hev-socks5-tunnel؛ وإلا فسيستخدم xray-core.</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">مستوى سجل Hev TUN</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">ভাষা</string>
|
||||
<string name="title_ui_settings">ইউআই সেটিংস</string>
|
||||
<string name="title_pref_ui_mode_night">ইউআই মোড সেটিংস</string>
|
||||
<string name="title_pref_dynamic_color">ডায়নামিক রঙ চালু করুন</string>
|
||||
<string name="summary_pref_dynamic_color">শুধুমাত্র Android 12+ ডিভাইসে কাজ করে</string>
|
||||
<string name="title_pref_use_hev_tunnel">Hev TUN সুবিধা চালু করুন</string>
|
||||
<string name="summary_pref_use_hev_tunnel">চালু থাকলে TUN hev-socks5-tunnel ব্যবহার করবে; অন্যথায় xray-core ব্যবহার করবে।</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Hev TUN লগ স্তর</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">زووݩ</string>
|
||||
<string name="title_ui_settings">سامووا رابط منتوری</string>
|
||||
<string name="title_pref_ui_mode_night">سامووا حالت رابط منتوری</string>
|
||||
<string name="title_pref_dynamic_color">فعالسازی رنگ پویا</string>
|
||||
<string name="summary_pref_dynamic_color">فقط روی اندروید ۱۲+ کار میکند</string>
|
||||
<string name="title_pref_use_hev_tunnel">و کار گرؽڌن ویژیی Hev TUN</string>
|
||||
<string name="summary_pref_use_hev_tunnel">مجالی ک ره ونده بۊ، TUN ایا hev-socks5-tunnel ن و کار اگره؛ ٱر ره نوۊفته بۊ، همو xray-core ن و کار اگره.</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Hev TUN سئت گوزارشا</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">زبان</string>
|
||||
<string name="title_ui_settings">تنظیمات رابط کاربری</string>
|
||||
<string name="title_pref_ui_mode_night">تنظیمات حالت رابط کاربری</string>
|
||||
<string name="title_pref_dynamic_color">فعالسازی رنگ پویا</string>
|
||||
<string name="summary_pref_dynamic_color">فقط روی اندروید ۱۲+ کار میکند</string>
|
||||
<string name="title_pref_use_hev_tunnel">استفاده از Hev TUN</string>
|
||||
<string name="summary_pref_use_hev_tunnel">اگر فعال باشد، تونل VPN از hev-socks5-tunnel استفاده میکند؛ در غیر این صورت از xray-core استفاده خواهد شد.</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">سطح گزارشهای Hev TUN</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">Язык</string>
|
||||
<string name="title_ui_settings">Настройки интерфейса</string>
|
||||
<string name="title_pref_ui_mode_night">Тема интерфейса</string>
|
||||
<string name="title_pref_dynamic_color">Включить динамические цвета</string>
|
||||
<string name="summary_pref_dynamic_color">Работает только на Android 12+</string>
|
||||
<string name="title_pref_use_hev_tunnel">Использовать Hev TUN</string>
|
||||
<string name="summary_pref_use_hev_tunnel">Если включено, TUN будет использовать hev-socks5-tunnel; иначе будет использован xray-core</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Уровень журналирования Hev TUN</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">Ngôn ngữ</string>
|
||||
<string name="title_ui_settings">Cài đặt UI</string>
|
||||
<string name="title_pref_ui_mode_night">Cài đặt chế độ UI</string>
|
||||
<string name="title_pref_dynamic_color">Bật màu động</string>
|
||||
<string name="summary_pref_dynamic_color">Chỉ hoạt động trên Android 12+</string>
|
||||
<string name="title_pref_use_hev_tunnel">Dùng Hev TUN</string>
|
||||
<string name="summary_pref_use_hev_tunnel">Khi bật, TUN sẽ dùng hev-socks5-tunnel; nếu không, TUN sẽ dùng xray-core.</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Mức nhật ký Hev TUN</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">语言</string>
|
||||
<string name="title_ui_settings">用户界面设置</string>
|
||||
<string name="title_pref_ui_mode_night">深色模式</string>
|
||||
<string name="title_pref_dynamic_color">开启莫奈取色</string>
|
||||
<string name="summary_pref_dynamic_color">仅在 Android 12+ 设备上工作</string>
|
||||
<string name="title_pref_use_hev_tunnel">启用 Hev TUN 功能</string>
|
||||
<string name="summary_pref_use_hev_tunnel">选择启用后 TUN 将使用 hev-socks5-tunnel 否则使用 xray-core</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Hev TUN 日志级别</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">語言</string>
|
||||
<string name="title_ui_settings">介面顯示設定</string>
|
||||
<string name="title_pref_ui_mode_night">深色模式</string>
|
||||
<string name="title_pref_dynamic_color">開啟莫奈取色</string>
|
||||
<string name="summary_pref_dynamic_color">僅在 Android 12+ 裝置上工作</string>
|
||||
<string name="title_pref_use_hev_tunnel">啟用 Hev TUN 功能</string>
|
||||
<string name="summary_pref_use_hev_tunnel">啟用後,TUN 會使用 hev-socks5-tunnel;否則使用 xray-core。</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Hev TUN 日誌層級</string>
|
||||
|
||||
@@ -298,6 +298,8 @@
|
||||
<string name="title_language">Language</string>
|
||||
<string name="title_ui_settings">UI settings</string>
|
||||
<string name="title_pref_ui_mode_night">UI mode settings</string>
|
||||
<string name="title_pref_dynamic_color">Enable dynamic color</string>
|
||||
<string name="summary_pref_dynamic_color">Only works on Android 12+ devices</string>
|
||||
<string name="title_pref_use_hev_tunnel">Use Hev TUN</string>
|
||||
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use xray-core.</string>
|
||||
<string name="title_pref_hev_tunnel_loglevel">Hev TUN log level</string>
|
||||
|
||||
Reference in new issue
Block a user