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" />
+