Skip to content

Commit c128f6c

Browse files
committed
add language setting
1 parent 2cf4e98 commit c128f6c

14 files changed

Lines changed: 1494 additions & 2 deletions

File tree

app/src/main/java/io/nekohasekai/sagernet/Constants.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ object Key {
1414
const val APP_EXPERT = "isExpert"
1515
const val APP_THEME = "appTheme"
1616
const val NIGHT_THEME = "nightTheme"
17+
const val APP_LANGUAGE = "appLanguage"
1718
const val SERVICE_MODE = "serviceMode"
1819
const val MODE_VPN = "vpn"
1920
const val MODE_PROXY = "proxy"

app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class SagerNet : Application(),
8181
if (isMainProcess) {
8282
Theme.apply(this)
8383
Theme.applyNightTheme()
84+
AppLocale.apply()
8485
runOnDefaultDispatcher {
8586
DefaultNetworkListener.start(this) {
8687
underlyingNetwork = it

app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
9999
var isExpert by configurationStore.boolean(Key.APP_EXPERT)
100100
var appTheme by configurationStore.int(Key.APP_THEME)
101101
var nightTheme by configurationStore.stringToInt(Key.NIGHT_THEME)
102+
var appLanguage by configurationStore.string(Key.APP_LANGUAGE) { "" }
102103
var serviceMode by configurationStore.string(Key.SERVICE_MODE) { Key.MODE_VPN }
103104

104105
var trafficSniffing by configurationStore.stringToInt(Key.TRAFFIC_SNIFFING) { 1 }

app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import io.nekohasekai.sagernet.SagerNet
1515
import io.nekohasekai.sagernet.database.DataStore
1616
import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers
1717
import io.nekohasekai.sagernet.ktx.*
18+
import io.nekohasekai.sagernet.utils.AppLocale
1819
import io.nekohasekai.sagernet.utils.Theme
1920
import moe.matsuri.nb4a.ui.*
2021
import android.os.Handler
@@ -65,6 +66,11 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
6566
Theme.applyNightTheme()
6667
true
6768
}
69+
val appLanguage = findPreference<SimpleMenuPreference>(Key.APP_LANGUAGE)!!
70+
appLanguage.setOnPreferenceChangeListener { _, newValue ->
71+
AppLocale.apply(newValue as String)
72+
true
73+
}
6874
val mixedPort = findPreference<EditTextPreference>(Key.MIXED_PORT)!!
6975
val serviceMode = findPreference<Preference>(Key.SERVICE_MODE)!!
7076
val allowAccess = findPreference<Preference>(Key.ALLOW_ACCESS)!!
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.nekohasekai.sagernet.utils
2+
3+
import androidx.appcompat.app.AppCompatDelegate
4+
import androidx.core.os.LocaleListCompat
5+
import io.nekohasekai.sagernet.database.DataStore
6+
7+
object AppLocale {
8+
9+
// Empty tag means "follow system".
10+
fun localeList(tag: String?): LocaleListCompat {
11+
return if (tag.isNullOrEmpty()) {
12+
LocaleListCompat.getEmptyLocaleList()
13+
} else {
14+
LocaleListCompat.forLanguageTags(tag)
15+
}
16+
}
17+
18+
// Applies the in-app language. AppCompat handles persistence (API 33+ via the
19+
// framework, below via SharedPreferences) and recreates active activities.
20+
fun apply(tag: String? = DataStore.appLanguage) {
21+
AppCompatDelegate.setApplicationLocales(localeList(tag))
22+
}
23+
24+
}

app/src/main/res/values-fa/strings.xml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,4 +531,106 @@
531531
<string name="global_allow_insecure">به اتصال محافظت‌نشده همیشه اجازه داده شود.</string>
532532
<string name="network_change_reset_connections">بازنشانی اتصال خروجی، هنگام تغییر شبکه</string>
533533
<string name="wake_reset_connections">بازنشانی اتصال خروجی، هنگام روشن‌شدن صفحه موبایل</string>
534+
<string name="layout">چیدمان</string>
535+
<string name="layout_single_column">تک‌ستونه</string>
536+
<string name="layout_double_column">دوستونه</string>
537+
<string name="sort_and_layout">مرتب‌سازی و چیدمان</string>
538+
<string name="kcp_seed">mKCP Seed</string>
539+
<string name="kcp_header_type">نوع هدر</string>
540+
<string name="kcp_mtu">mKCP MTU</string>
541+
<string name="kcp_tti">mKCP TTI</string>
542+
<string name="kcp_cwnd_multiplier">ضریب CWND</string>
543+
<string name="mux_mode">حالت</string>
544+
<string name="mux_mode_max_streams">حداکثر جریان‌ها</string>
545+
<string name="mux_mode_connections">اتصال‌ها</string>
546+
<string name="mux_max_connections">حداکثر اتصال‌ها</string>
547+
<string name="mux_min_streams">حداقل جریان‌ها</string>
548+
<string name="mux_brutal">TCP Brutal</string>
549+
<string name="mux_brutal_up_mbps">آپلود (Mbps)</string>
550+
<string name="mux_brutal_down_mbps">دانلود (Mbps)</string>
551+
<string name="confirm_profile_delete">تأیید حذف نمایه</string>
552+
<string name="language">زبان</string>
553+
<string name="strict_route">مسیریابی سخت‌گیرانه</string>
554+
<string name="filter">فیلتر</string>
555+
<string name="filter_disabled">غیرفعال</string>
556+
<string name="filter_include">شامل</string>
557+
<string name="filter_exclude">مستثنا</string>
558+
<string name="filter_regex">فیلتر (عبارت باقاعده)</string>
559+
<string name="hide_from_recent_apps">پنهان کردن از کارهای اخیر</string>
560+
<string name="hide_from_recent_apps_summary">پنهان کردن برنامه از کارهای اخیر هنگام اجرا در پس‌زمینه</string>
561+
<string name="custom_rules_provider">سفارشی</string>
562+
<string name="rules_geosite_url">نشانی geosite</string>
563+
<string name="rules_geoip_url">نشانی geoip</string>
564+
<string name="pinned_certchain_sha256">SHA256 گواهی پین‌شده</string>
565+
<string name="fragment_settings">تنظیمات Fragment</string>
566+
<string name="enable_tls_fragment">فعال‌سازی Fragment در TLS Client Hello</string>
567+
<string name="fragment_length">طول Fragment (کمینه-بیشینه)</string>
568+
<string name="fragment_interval">بازه Fragment (کمینه-بیشینه)</string>
569+
<string name="backup_local">پشتیبان محلی</string>
570+
<string name="backup_webdav">پشتیبان WebDAV</string>
571+
<string name="webdav_settings">تنظیمات WebDAV</string>
572+
<string name="webdav_server">نشانی سرور</string>
573+
<string name="webdav_username">نام کاربری</string>
574+
<string name="webdav_password">گذرواژه</string>
575+
<string name="webdav_path">مسیر پشتیبان</string>
576+
<string name="webdav_test">آزمایش اتصال</string>
577+
<string name="webdav_test_success">اتصال موفق بود</string>
578+
<string name="webdav_test_failed" formatted="false">اتصال ناموفق بود: %s</string>
579+
<string name="backup_to_webdav">پشتیبان‌گیری در WebDAV</string>
580+
<string name="restore_from_webdav">بازیابی از WebDAV</string>
581+
<string name="webdav_backup_success">پشتیبان‌گیری در WebDAV موفق بود</string>
582+
<string name="webdav_backup_failed">پشتیبان‌گیری در WebDAV ناموفق بود: %s</string>
583+
<string name="webdav_restore_success">بازیابی از WebDAV موفق بود</string>
584+
<string name="webdav_restore_failed">بازیابی از WebDAV ناموفق بود: %s</string>
585+
<string name="webdav_server_empty">لطفاً ابتدا سرور WebDAV را پیکربندی کنید</string>
586+
<string name="webdav_auth_error">احراز هویت ناموفق بود: نام کاربری یا گذرواژه نامعتبر است</string>
587+
<string name="webdav_permission_denied">دسترسی رد شد</string>
588+
<string name="webdav_server_not_found">سرور یافت نشد</string>
589+
<string name="webdav_server_error">خطای سرور</string>
590+
<string name="webdav_connect_failed">اتصال ناموفق بود با کد: %d</string>
591+
<string name="webdav_create_dir_failed">ایجاد یا دسترسی به پوشهٔ پشتیبان ناموفق بود</string>
592+
<string name="global_mode">حالت سراسری</string>
593+
<string name="global_mode_summary">دور زدن همهٔ قواعد مسیریابی و عبور همهٔ ترافیک از گرهٔ فعلی</string>
594+
<string name="mux_preference">Multiplex</string>
595+
<string name="padding">Padding</string>
596+
<string name="backup_in_progress">پشتیبان‌گیری از قبل در حال انجام است</string>
597+
<string name="restore_in_progress">بازیابی از قبل در حال انجام است</string>
598+
<string name="restore_cancelled">عملیات بازیابی لغو شد</string>
599+
<string name="ruleset_update_interval">بازهٔ به‌روزرسانی مجموعه‌قواعد</string>
600+
<string name="ruleset_update_interval_summary">فاصلهٔ زمانی بین به‌روزرسانی مجموعه‌قواعد راه دور. مثال‌ها: 1h، 30m، 3600s. برای غیرفعال‌کردن به‌روزرسانی خودکار روی 0 بگذارید</string>
601+
<string name="ruleset_prefix_error">خطای قالب مجموعه‌قواعد: باید با rsip: یا rssite: شروع شود</string>
602+
<string name="clear_cache">پاک‌سازی حافظهٔ پنهان</string>
603+
<string name="clear_cache_summary">پاک‌سازی فایل‌های حافظهٔ پنهان برنامه برای رفع برخی مشکلات غیرعادی</string>
604+
<string name="clear_cache_confirm">آیا مطمئنید می‌خواهید حافظهٔ پنهان را پاک کنید؟</string>
605+
<string name="clear_cache_success">حافظهٔ پنهان پاک شد</string>
606+
<string name="clear_cache_failed">پاک‌سازی حافظهٔ پنهان ناموفق بود: %s</string>
607+
<string name="concurrent_dial">اتصال هم‌زمان</string>
608+
<string name="concurrent_dial_summary">فعال‌سازی اتصال‌های هم‌زمان برای برقراری سریع‌تر شبکه؛ ممکن است مصرف باتری را افزایش دهد</string>
609+
<string name="connection_test_timeout">مهلت آزمایش (ms)</string>
610+
<string name="preview_version_hint">این برنامه نسخهٔ پیش‌نمایش است و ممکن است مشکلات زیادی داشته باشد. اگر نمی‌خواهید آن را آزمایش کنید، لطفاً برای دانلود نسخهٔ Release به GitHub بروید!</string>
611+
<string name="check_update_preview">بررسی به‌روزرسانی نسخهٔ پیش‌نمایش</string>
612+
<string name="check_update_release">بررسی به‌روزرسانی نسخهٔ Release</string>
613+
<string name="update_dialog_title">نسخهٔ جدید در دسترس است</string>
614+
<string name="update_dialog_message">نسخهٔ فعلی: %1$s\nنسخهٔ موجود: %2$s\nآیا می‌خواهید آن را دانلود کنید؟</string>
615+
<string name="check_update_no">بررسی موفق بود، اما به‌روزرسانی‌ای نیست.</string>
616+
<string name="reset_settings">بازگردانی تنظیمات پیش‌فرض</string>
617+
<string name="reset_settings_message">بازگردانی تنظیمات پیش‌فرض؛ اما داده‌هایی مانند گره‌ها و گروه‌ها حفظ می‌شوند. برای پاک‌سازی کامل داده‌ها، داده‌های برنامه را مستقیماً در تنظیمات سیستم پاک کنید.</string>
618+
<string name="minimize">کوچک کردن</string>
619+
<string name="xhttp_host">XHTTP Host</string>
620+
<string name="xhttp_path">XHTTP Path</string>
621+
<string name="xhttp_mode">XHTTP Mode</string>
622+
<string name="xhttp_extra">XHTTP Extra</string>
623+
<string name="xhttp_settings">تنظیمات XHTTP</string>
624+
<string name="vless_encryption">رمزنگاری</string>
625+
<string name="vless_encryption_hint">mlkem768x25519plus.native.0rtt.KEY1.KEY2...</string>
626+
<string name="app_list_permission_denied">خواندن برنامه‌های نصب‌شده ممکن نیست.\nاین معمولاً به این دلیل است که سیستم دسترسی خواندن برنامه‌ها را محدود کرده است.\nلطفاً در تنظیمات سیستم دسترسی بدهید.</string>
627+
<string name="open_app_settings">باز کردن تنظیمات سیستم</string>
628+
<string name="action_snell">Snell</string>
629+
<string name="snell_psk">کلید</string>
630+
<string name="snell_version">نسخه</string>
631+
<string name="snell_network">پروتکل</string>
632+
<string name="snell_obfs_mode">حالت Obfs</string>
633+
<string name="snell_obfs_host">میزبان Obfs</string>
634+
<string name="snell_reuse">استفادهٔ مجدد</string>
635+
<string name="snell_reuse_summary">فقط v4/v5</string>
534636
</resources>

0 commit comments

Comments
 (0)