diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt index e2fe19f6..6416d201 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.multidex.MultiDexApplication import androidx.work.Configuration import com.tencent.mmkv.MMKV +import com.v2ray.ang.util.Utils class AngApplication : MultiDexApplication(), Configuration.Provider { companion object { @@ -31,6 +32,8 @@ class AngApplication : MultiDexApplication(), Configuration.Provider { //Logger.init().logLevel(if (BuildConfig.DEBUG) LogLevel.FULL else LogLevel.NONE) MMKV.initialize(this) + + Utils.setNightMode(application) } override fun getWorkManagerConfiguration(): Configuration { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt index c148294b..996e3763 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt @@ -49,6 +49,7 @@ object AppConfig { const val PREF_CONFIRM_REMOVE = "pref_confirm_remove" const val PREF_START_SCAN_IMMEDIATE = "pref_start_scan_immediate" const val PREF_LANGUAGE = "pref_language" + const val PREF_UI_MODE_NIGHT = "pref_ui_mode_night" const val PREF_PREFER_IPV6 = "pref_prefer_ipv6" const val PREF_PROXY_SHARING = "pref_proxy_sharing_enabled" diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt index 79c9d5c0..691320c5 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt @@ -68,52 +68,11 @@ class SettingsActivity : BaseActivity() { override fun onCreatePreferences(bundle: Bundle?, s: String?) { addPreferencesFromResource(R.xml.pref_settings) - routingCustom?.setOnPreferenceClickListener { - startActivity(Intent(activity, RoutingSettingsActivity::class.java)) - false - } - - autoUpdateCheck?.setOnPreferenceChangeListener { _, newValue -> - val value = newValue as Boolean - autoUpdateCheck?.isChecked = value - autoUpdateInterval?.isEnabled = value - autoUpdateInterval?.text?.toLong()?.let { - if (newValue) configureUpdateTask(it) else cancelUpdateTask() - } - true - } - - autoUpdateInterval?.setOnPreferenceChangeListener { _, any -> - var nval = any as String - - // It must be greater than 15 minutes because WorkManager couldn't run tasks under 15 minutes intervals - nval = - if (TextUtils.isEmpty(nval) || nval.toLong() < 15) AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL else nval - autoUpdateInterval?.summary = nval - configureUpdateTask(nval.toLong()) - true - } - - perAppProxy?.setOnPreferenceClickListener { startActivity(Intent(activity, PerAppProxyActivity::class.java)) perAppProxy?.isChecked = true false } - - remoteDns?.setOnPreferenceChangeListener { _, any -> - // remoteDns.summary = any as String - val nval = any as String - remoteDns?.summary = if (nval == "") AppConfig.DNS_PROXY else nval - true - } - domesticDns?.setOnPreferenceChangeListener { _, any -> - // domesticDns.summary = any as String - val nval = any as String - domesticDns?.summary = if (nval == "") AppConfig.DNS_DIRECT else nval - true - } - localDns?.setOnPreferenceChangeListener { _, any -> updateLocalDns(any as Boolean) true @@ -128,22 +87,12 @@ class SettingsActivity : BaseActivity() { vpnDns?.summary = any as String true } - socksPort?.setOnPreferenceChangeListener { _, any -> - val nval = any as String - socksPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_SOCKS else nval - true + + routingCustom?.setOnPreferenceClickListener { + startActivity(Intent(activity, RoutingSettingsActivity::class.java)) + false } - httpPort?.setOnPreferenceChangeListener { _, any -> - val nval = any as String - httpPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_HTTP else nval - true - } - mode?.setOnPreferenceChangeListener { _, newValue -> - updateMode(newValue.toString()) - true - } - mode?.dialogLayoutResource = R.layout.preference_with_help_link - //loglevel.summary = "LogLevel" + mux?.setOnPreferenceChangeListener { _, newValue -> updateMux(newValue as Boolean) true @@ -173,6 +122,56 @@ class SettingsActivity : BaseActivity() { updateFragmentInterval(newValue as String) true } + + autoUpdateCheck?.setOnPreferenceChangeListener { _, newValue -> + val value = newValue as Boolean + autoUpdateCheck?.isChecked = value + autoUpdateInterval?.isEnabled = value + autoUpdateInterval?.text?.toLong()?.let { + if (newValue) configureUpdateTask(it) else cancelUpdateTask() + } + true + } + autoUpdateInterval?.setOnPreferenceChangeListener { _, any -> + var nval = any as String + + // It must be greater than 15 minutes because WorkManager couldn't run tasks under 15 minutes intervals + nval = + if (TextUtils.isEmpty(nval) || nval.toLong() < 15) AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL else nval + autoUpdateInterval?.summary = nval + configureUpdateTask(nval.toLong()) + true + } + + remoteDns?.setOnPreferenceChangeListener { _, any -> + // remoteDns.summary = any as String + val nval = any as String + remoteDns?.summary = if (nval == "") AppConfig.DNS_PROXY else nval + true + } + domesticDns?.setOnPreferenceChangeListener { _, any -> + // domesticDns.summary = any as String + val nval = any as String + domesticDns?.summary = if (nval == "") AppConfig.DNS_DIRECT else nval + true + } + socksPort?.setOnPreferenceChangeListener { _, any -> + val nval = any as String + socksPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_SOCKS else nval + true + } + httpPort?.setOnPreferenceChangeListener { _, any -> + val nval = any as String + httpPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_HTTP else nval + true + } + mode?.setOnPreferenceChangeListener { _, newValue -> + updateMode(newValue.toString()) + true + } + mode?.dialogLayoutResource = R.layout.preference_with_help_link + //loglevel.summary = "LogLevel" + } override fun onStart() { @@ -249,6 +248,7 @@ class SettingsActivity : BaseActivity() { AppConfig.PREF_MUX_XUDP_QUIC, AppConfig.PREF_FRAGMENT_PACKETS, AppConfig.PREF_LANGUAGE, + AppConfig.PREF_UI_MODE_NIGHT, AppConfig.PREF_LOGLEVEL, AppConfig.PREF_MODE ).forEach { key -> diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt index 6b051008..ccccf44f 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt @@ -16,6 +16,7 @@ import android.util.Base64 import android.util.Log import android.util.Patterns import android.webkit.URLUtil +import androidx.appcompat.app.AppCompatDelegate import com.tencent.mmkv.MMKV import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig.ANG_PACKAGE @@ -371,6 +372,14 @@ object Utils { return mode != UI_MODE_NIGHT_NO } + fun setNightMode(context: Context) { + when (settingsStorage?.decodeString(AppConfig.PREF_UI_MODE_NIGHT, "0")) { + "0" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) + "1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) + "2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + } + } + fun getIpv6Address(address: String): String { return if (isIpv6Address(address) && !address.contains('[') && !address.contains(']')) { String.format("[%s]", address) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SettingsViewModel.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SettingsViewModel.kt index d112dd36..9fbbdcfb 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SettingsViewModel.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/viewmodel/SettingsViewModel.kt @@ -8,24 +8,33 @@ import androidx.preference.PreferenceManager import com.tencent.mmkv.MMKV import com.v2ray.ang.AppConfig import com.v2ray.ang.util.MmkvManager +import com.v2ray.ang.util.Utils -class SettingsViewModel(application: Application) : AndroidViewModel(application), SharedPreferences.OnSharedPreferenceChangeListener { +class SettingsViewModel(application: Application) : AndroidViewModel(application), + SharedPreferences.OnSharedPreferenceChangeListener { - private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) } + private val settingsStorage by lazy { + MMKV.mmkvWithID( + MmkvManager.ID_SETTING, + MMKV.MULTI_PROCESS_MODE + ) + } fun startListenPreferenceChange() { - PreferenceManager.getDefaultSharedPreferences(getApplication()).registerOnSharedPreferenceChangeListener(this) + PreferenceManager.getDefaultSharedPreferences(getApplication()) + .registerOnSharedPreferenceChangeListener(this) } override fun onCleared() { - PreferenceManager.getDefaultSharedPreferences(getApplication()).unregisterOnSharedPreferenceChangeListener(this) + PreferenceManager.getDefaultSharedPreferences(getApplication()) + .unregisterOnSharedPreferenceChangeListener(this) Log.i(AppConfig.ANG_PACKAGE, "Settings ViewModel is cleared") super.onCleared() } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) { Log.d(AppConfig.ANG_PACKAGE, "Observe settings changed: $key") - when(key) { + when (key) { AppConfig.PREF_MODE, AppConfig.PREF_VPN_DNS, AppConfig.PREF_REMOTE_DNS, @@ -35,6 +44,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application AppConfig.PREF_HTTP_PORT, AppConfig.PREF_LOGLEVEL, AppConfig.PREF_LANGUAGE, + AppConfig.PREF_UI_MODE_NIGHT, AppConfig.PREF_ROUTING_DOMAIN_STRATEGY, AppConfig.PREF_ROUTING_MODE, AppConfig.PREF_V2RAY_ROUTING_AGENT, @@ -44,9 +54,11 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application AppConfig.PREF_FRAGMENT_PACKETS, AppConfig.PREF_FRAGMENT_LENGTH, AppConfig.PREF_FRAGMENT_INTERVAL, - AppConfig.PREF_MUX_XUDP_QUIC, -> { + AppConfig.PREF_MUX_XUDP_QUIC, + -> { settingsStorage?.encode(key, sharedPreferences.getString(key, "")) } + AppConfig.PREF_SPEED_ENABLED, AppConfig.PREF_PROXY_SHARING, AppConfig.PREF_LOCAL_DNS_ENABLED, @@ -59,19 +71,29 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application AppConfig.PREF_START_SCAN_IMMEDIATE, AppConfig.SUBSCRIPTION_AUTO_UPDATE, AppConfig.PREF_FRAGMENT_ENABLED, - AppConfig.PREF_MUX_ENABLED, -> { + AppConfig.PREF_MUX_ENABLED, + -> { settingsStorage?.encode(key, sharedPreferences.getBoolean(key, false)) } + AppConfig.PREF_SNIFFING_ENABLED -> { settingsStorage?.encode(key, sharedPreferences.getBoolean(key, true)) } + AppConfig.PREF_MUX_CONCURRENCY, AppConfig.PREF_MUX_XUDP_CONCURRENCY -> { - settingsStorage?.encode(key, sharedPreferences.getString(key, "8")?.toIntOrNull() ?: 8) + settingsStorage?.encode( + key, + sharedPreferences.getString(key, "8")?.toIntOrNull() ?: 8 + ) } + AppConfig.PREF_PER_APP_PROXY_SET -> { settingsStorage?.encode(key, sharedPreferences.getStringSet(key, setOf())) } } + if (key == AppConfig.PREF_UI_MODE_NIGHT) { + Utils.setNightMode(getApplication()) + } } } diff --git a/V2rayNG/app/src/main/res/values-ar/strings.xml b/V2rayNG/app/src/main/res/values-ar/strings.xml index 5a1ef352..d772631b 100644 --- a/V2rayNG/app/src/main/res/values-ar/strings.xml +++ b/V2rayNG/app/src/main/res/values-ar/strings.xml @@ -163,6 +163,7 @@ انقر علي للمزيد من المساعدة اللغة إعدادات واجهة المستخدم + UI mode settings Logcat نسخ مسح @@ -230,4 +231,10 @@ يضيف إضافة رابط + + + Follow system + Light + Dark + diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index cb9edb67..8056fe4e 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -188,6 +188,7 @@ برای راهنمایی بیشتر روی این متن، کلیک کنید زبان تنظیمات رابط کاربری + UI mode settings گزارشات کپی @@ -270,4 +271,10 @@ افزودن افزودن لینک + + Follow system + Light + Dark + + diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 21458bd2..820eb8dd 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -192,6 +192,7 @@ Нажмите для получения дополнительной информации Язык Настройки интерфейса + UI mode settings Журнал Копировать @@ -273,4 +274,10 @@ Только прокси + + Follow system + Light + Dark + + diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index 047aef2b..eaa8f37a 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -191,6 +191,7 @@ Nhấn vào đây nếu bạn cần trợ giúp! Ngôn ngữ Cài đặt giao diện + UI mode settings Logcat Sao chép @@ -269,4 +270,10 @@ Thêm vào Thêm liên kết + + Follow system + Light + Dark + + diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index a40135ea..b7627d46 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -190,6 +190,7 @@ 点此查看更多帮助 语言 用户界面设置 + 界面颜色设置 Logcat 复制 @@ -274,4 +275,10 @@ 仅代理 + + 跟随系统 + 浅色 + 深色 + + diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index 5ac04f3e..c0a69c31 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -189,7 +189,8 @@ 模式 輕觸以檢視說明 語言 - 使用者介面設定 + 介面顏色設定 + UI mode settings Logcat 複製 @@ -273,4 +274,10 @@ 僅 Proxy + + 跟隨系統 + 淺色 + 深色 + + diff --git a/V2rayNG/app/src/main/res/values/arrays.xml b/V2rayNG/app/src/main/res/values/arrays.xml index 861200e3..b5eef4df 100644 --- a/V2rayNG/app/src/main/res/values/arrays.xml +++ b/V2rayNG/app/src/main/res/values/arrays.xml @@ -196,4 +196,10 @@ allow skip - + + + 0 + 1 + 2 + + \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index a15db1c2..be8cdcb9 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -203,6 +203,7 @@ Click me for more help Language UI settings + UI mode settings Logcat Copy @@ -284,4 +285,10 @@ Proxy only + + Follow system + Light + Dark + + diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml index 6d6d5757..36c7b5da 100644 --- a/V2rayNG/app/src/main/res/xml/pref_settings.xml +++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml @@ -146,6 +146,13 @@ android:summary="%s" android:title="@string/title_language" /> +