diff --git a/app/build.gradle b/app/build.gradle index 2eff5221..8dc011c2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -127,6 +127,10 @@ android { lint { lintConfig = file("lint.xml") } + + androidResources { + generateLocaleConfig true + } } allOpen { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 672e2624..e2c13b7c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -55,5 +55,14 @@ + + + + diff --git a/app/src/main/kotlin/com/vrem/util/LocaleUtils.kt b/app/src/main/kotlin/com/vrem/util/LocaleUtils.kt index 2fba582a..17395ae8 100644 --- a/app/src/main/kotlin/com/vrem/util/LocaleUtils.kt +++ b/app/src/main/kotlin/com/vrem/util/LocaleUtils.kt @@ -20,43 +20,27 @@ package com.vrem.util import java.util.Locale import java.util.SortedMap -private object SyncAvoid { - val defaultLocale: Locale = Locale.getDefault() - val countryCodes: Set = Locale.getISOCountries().toSet() - val availableLocales: List = Locale.getAvailableLocales().filter { countryCodes.contains(it.country) } - - val countriesLocales: SortedMap = - availableLocales - .associateBy { it.country.toCapitalize(Locale.getDefault()) } - .toSortedMap() - val supportedLocales: List = - setOf( - BULGARIAN, - DUTCH, - GREEK, - HUNGARIAN, - Locale.SIMPLIFIED_CHINESE, - Locale.TRADITIONAL_CHINESE, - Locale.ENGLISH, - Locale.FRENCH, - Locale.GERMAN, - Locale.ITALIAN, - Locale.JAPANESE, - POLISH, - PORTUGUESE_BRAZIL, - PORTUGUESE_PORTUGAL, - SPANISH, - RUSSIAN, - TURKISH, - UKRAINIAN, - defaultLocale, - ).toList() -} +private val currentLocale: Locale get() = Locale.getDefault() +private val countryCodes: Set = Locale.getISOCountries().toSet() +private val availableLocales: List = Locale.getAvailableLocales().filter { countryCodes.contains(it.country) } +private val countriesLocales: SortedMap = + availableLocales + .associateBy { it.country.toCapitalize(currentLocale) } + .toSortedMap() val BULGARIAN: Locale = Locale.forLanguageTag("bg") + +val CHINESE_SIMPLIFIED: Locale = Locale.forLanguageTag("zh-Hans") + +val CHINESE_TRADITIONAL: Locale = Locale.forLanguageTag("zh-Hant") val DUTCH: Locale = Locale.forLanguageTag("nl") +val ENGLISH: Locale = Locale.forLanguageTag("en") +val FRENCH: Locale = Locale.forLanguageTag("fr") +val GERMAN: Locale = Locale.forLanguageTag("de") val GREEK: Locale = Locale.forLanguageTag("el") val HUNGARIAN: Locale = Locale.forLanguageTag("hu") +val ITALIAN: Locale = Locale.forLanguageTag("it") +val JAPANESE: Locale = Locale.forLanguageTag("ja") val POLISH: Locale = Locale.forLanguageTag("pl") val PORTUGUESE_PORTUGAL: Locale = Locale.forLanguageTag("pt-PT") val PORTUGUESE_BRAZIL: Locale = Locale.forLanguageTag("pt-BR") @@ -65,35 +49,58 @@ val RUSSIAN: Locale = Locale.forLanguageTag("ru") val TURKISH: Locale = Locale.forLanguageTag("tr") val UKRAINIAN: Locale = Locale.forLanguageTag("uk") -private const val SEPARATOR: String = "_" +val baseSupportedLocales: List = + setOf( + BULGARIAN, + DUTCH, + GREEK, + HUNGARIAN, + CHINESE_SIMPLIFIED, + CHINESE_TRADITIONAL, + ENGLISH, + FRENCH, + GERMAN, + ITALIAN, + JAPANESE, + POLISH, + PORTUGUESE_BRAZIL, + PORTUGUESE_PORTUGAL, + SPANISH, + RUSSIAN, + TURKISH, + UKRAINIAN, + ).toList() fun findByCountryCode(countryCode: String): Locale = - SyncAvoid.availableLocales.firstOrNull { countryCode.toCapitalize(Locale.getDefault()) == it.country } - ?: SyncAvoid.defaultLocale + availableLocales.firstOrNull { countryCode.uppercase(Locale.ROOT) == it.country } + ?: currentLocale -fun allCountries(): List = SyncAvoid.countriesLocales.values.toList() +fun allCountries(): List = countriesLocales.values.toList() -fun findByLanguageTag(languageTag: String): Locale { - val languageTagPredicate: (Locale) -> Boolean = { - val locale: Locale = fromLanguageTag(languageTag) - it.language == locale.language && it.country == locale.country - } - return SyncAvoid.supportedLocales.firstOrNull(languageTagPredicate) ?: SyncAvoid.defaultLocale -} +fun supportedLanguages(): List = (baseSupportedLocales + currentLocale).distinct() -fun supportedLanguages(): List = SyncAvoid.supportedLocales +fun supportedLanguageTags(): List = listOf("") + baseSupportedLocales.map { it.toLanguageTag() } -fun defaultCountryCode(): String = SyncAvoid.defaultLocale.country +private fun normalizeLanguageTag(languageTag: String): String = languageTag.replace('_', '-').trim() -fun defaultLanguageTag(): String = toLanguageTag(SyncAvoid.defaultLocale) +fun findByLanguageTag(languageTag: String): Locale { + val normalizedLanguageTag = normalizeLanguageTag(languageTag) + if (normalizedLanguageTag.isEmpty()) return currentLocale -fun toLanguageTag(locale: Locale): String = locale.language + SEPARATOR + locale.country + val target = Locale.forLanguageTag(normalizedLanguageTag) + if (target.language.isEmpty()) return currentLocale -private fun fromLanguageTag(languageTag: String): Locale { - val codes: Array = languageTag.split(SEPARATOR).toTypedArray() - return when (codes.size) { - 1 -> Locale.forLanguageTag(codes[0]) - 2 -> Locale.forLanguageTag("${codes[0]}-${codes[1].toCapitalize(Locale.getDefault())}") - else -> SyncAvoid.defaultLocale - } + return baseSupportedLocales.find { it == target } + ?: baseSupportedLocales.find { it.language == target.language && it.script == target.script } + ?: baseSupportedLocales.find { it.language == target.language && it.country == target.country } + ?: baseSupportedLocales.find { it.language == target.language } + ?: currentLocale } + +fun currentCountryCode(): String = currentLocale.country + +fun currentLanguageTag(): String = currentLocale.toLanguageTag() + +fun toLanguageTag(locale: Locale): String = locale.toLanguageTag() + +fun Locale.toSupportedLocaleTag(): String = findByLanguageTag(this.toLanguageTag()).toLanguageTag() diff --git a/app/src/main/kotlin/com/vrem/util/StringUtils.kt b/app/src/main/kotlin/com/vrem/util/StringUtils.kt index e96df0c2..afc68e67 100644 --- a/app/src/main/kotlin/com/vrem/util/StringUtils.kt +++ b/app/src/main/kotlin/com/vrem/util/StringUtils.kt @@ -27,3 +27,5 @@ fun String.Companion.nullToEmpty(value: String?): String = value ?: String.EMPTY fun String.specialTrim(): String = this.trim { it <= ' ' }.replace(" +".toRegex(), String.SPACE_SEPARATOR) fun String.toCapitalize(locale: Locale): String = this.replaceFirstChar { word -> word.uppercase(locale) } + +fun String.titlecaseFirst(locale: Locale): String = replaceFirstChar { it.titlecase(locale) } diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/MainActivity.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/MainActivity.kt index 7c59a14d..c0a9d2e3 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/MainActivity.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/MainActivity.kt @@ -17,7 +17,6 @@ */ package com.vrem.wifianalyzer -import android.content.Context import android.content.SharedPreferences import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.content.res.Configuration @@ -26,18 +25,17 @@ import android.view.Menu import android.view.MenuItem import android.view.View import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.os.LocaleListCompat import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import com.google.android.material.navigation.NavigationView import com.vrem.annotation.OpenClass -import com.vrem.util.createContext import com.vrem.wifianalyzer.navigation.NavigationMenu import com.vrem.wifianalyzer.navigation.NavigationMenuControl import com.vrem.wifianalyzer.navigation.NavigationMenuController import com.vrem.wifianalyzer.navigation.options.OptionMenu -import com.vrem.wifianalyzer.settings.Repository -import com.vrem.wifianalyzer.settings.Settings import com.vrem.wifianalyzer.wifi.accesspoint.ConnectionView import com.vrem.wifianalyzer.wifi.scanner.ScannerService @@ -52,15 +50,13 @@ class MainActivity : internal lateinit var optionMenu: OptionMenu internal lateinit var connectionView: ConnectionView - override fun attachBaseContext(newBase: Context) = - super.attachBaseContext(newBase.createContext(Settings(Repository(newBase)).languageLocale())) - override fun onCreate(savedInstanceState: Bundle?) { val mainContext = MainContext.INSTANCE mainContext.initialize(this, largeScreen) val settings = mainContext.settings settings.initializeDefaultValues() + settings.syncLanguage() setTheme(settings.themeStyle().themeNoActionBar) mainReload = MainReload(settings) @@ -120,6 +116,18 @@ class MainActivity : sharedPreferences: SharedPreferences, key: String?, ) { + val languageKey = getString(R.string.language_key) + if (key == languageKey) { + val languageTag = sharedPreferences.getString(languageKey, "") + val locales = + languageTag + ?.takeIf { it.isNotEmpty() } + ?.let(LocaleListCompat::forLanguageTags) + ?: LocaleListCompat.getEmptyLocaleList() + + AppCompatDelegate.setApplicationLocales(locales) + } + val mainContext = MainContext.INSTANCE if (mainReload.shouldReload(mainContext.settings)) { MainContext.INSTANCE.scannerService.stop() diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/MainReload.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/MainReload.kt index 33caa01f..67b10edf 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/MainReload.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/MainReload.kt @@ -20,7 +20,6 @@ package com.vrem.wifianalyzer import com.vrem.wifianalyzer.settings.Settings import com.vrem.wifianalyzer.settings.ThemeStyle import com.vrem.wifianalyzer.wifi.accesspoint.ConnectionViewType -import java.util.Locale class MainReload( settings: Settings, @@ -29,11 +28,8 @@ class MainReload( private set var connectionViewType: ConnectionViewType private set - var languageLocale: Locale - private set - fun shouldReload(settings: Settings): Boolean = - themeChanged(settings) || connectionViewTypeChanged(settings) || languageChanged(settings) + fun shouldReload(settings: Settings): Boolean = themeChanged(settings) || connectionViewTypeChanged(settings) private fun connectionViewTypeChanged(settings: Settings): Boolean { val currentConnectionViewType = settings.connectionViewType() @@ -53,18 +49,8 @@ class MainReload( return themeChanged } - private fun languageChanged(settings: Settings): Boolean { - val settingLanguageLocale = settings.languageLocale() - val languageLocaleChanged = languageLocale != settingLanguageLocale - if (languageLocaleChanged) { - languageLocale = settingLanguageLocale - } - return languageLocaleChanged - } - init { themeStyle = settings.themeStyle() connectionViewType = settings.connectionViewType() - languageLocale = settings.languageLocale() } } diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/settings/CountryPreference.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/settings/CountryPreference.kt index 6aaf8ed2..b1bda240 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/settings/CountryPreference.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/settings/CountryPreference.kt @@ -19,13 +19,13 @@ package com.vrem.wifianalyzer.settings import android.content.Context import android.util.AttributeSet -import com.vrem.util.defaultCountryCode +import com.vrem.util.currentCountryCode import com.vrem.wifianalyzer.MainContext import com.vrem.wifianalyzer.wifi.band.WiFiChannelCountry import java.util.Locale private fun data(): List { - val currentLocale: Locale = MainContext.INSTANCE.settings.languageLocale() + val currentLocale: Locale = MainContext.INSTANCE.settings.appLocale() return WiFiChannelCountry .findAll() .map { Data(it.countryCode, it.countryName(currentLocale)) } @@ -35,4 +35,4 @@ private fun data(): List { class CountryPreference( context: Context, attrs: AttributeSet, -) : CustomPreference(context, attrs, data(), defaultCountryCode()) +) : CustomPreference(context, attrs, data(), currentCountryCode()) diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/settings/LanguagePreference.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/settings/LanguagePreference.kt index 4abf77fd..e94d8215 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/settings/LanguagePreference.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/settings/LanguagePreference.kt @@ -19,20 +19,22 @@ package com.vrem.wifianalyzer.settings import android.content.Context import android.util.AttributeSet -import com.vrem.util.defaultLanguageTag -import com.vrem.util.supportedLanguages -import com.vrem.util.toCapitalize -import com.vrem.util.toLanguageTag +import com.vrem.util.supportedLanguageTags +import com.vrem.util.titlecaseFirst +import com.vrem.wifianalyzer.R import java.util.Locale -private fun data(): List = - supportedLanguages() - .map { map(it) } - .sorted() - -private fun map(it: Locale): Data = Data(toLanguageTag(it), it.getDisplayName(it).toCapitalize(Locale.getDefault())) +private fun data(context: Context): List = + supportedLanguageTags().map { tag -> + if (tag.isEmpty()) { + Data("", context.getString(R.string.system_default)) + } else { + val locale = Locale.forLanguageTag(tag) + Data(tag, locale.getDisplayName(locale).titlecaseFirst(locale)) + } + } class LanguagePreference( context: Context, attrs: AttributeSet, -) : CustomPreference(context, attrs, data(), defaultLanguageTag()) +) : CustomPreference(context, attrs, data(context), "") diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/settings/Settings.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/settings/Settings.kt index 8dc3b772..05563b27 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/settings/Settings.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/settings/Settings.kt @@ -18,14 +18,15 @@ package com.vrem.wifianalyzer.settings import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import androidx.appcompat.app.AppCompatDelegate import com.vrem.annotation.OpenClass import com.vrem.util.buildMinVersionQ -import com.vrem.util.defaultCountryCode -import com.vrem.util.defaultLanguageTag +import com.vrem.util.currentCountryCode import com.vrem.util.findByLanguageTag import com.vrem.util.findOne import com.vrem.util.findSet import com.vrem.util.ordinals +import com.vrem.util.toSupportedLocaleTag import com.vrem.wifianalyzer.R import com.vrem.wifianalyzer.navigation.MAIN_NAVIGATION import com.vrem.wifianalyzer.navigation.NavigationMenu @@ -67,12 +68,15 @@ class Settings( fun wiFiBand(wiFiBand: WiFiBand): Unit = repository.save(R.string.wifi_band_key, wiFiBand.ordinal) - fun countryCode(): String = repository.string(R.string.country_code_key, defaultCountryCode()) + fun countryCode(): String = repository.string(R.string.country_code_key, currentCountryCode()) - fun languageLocale(): Locale { - val defaultLanguageTag = defaultLanguageTag() - val languageTag = repository.string(R.string.language_key, defaultLanguageTag) - return findByLanguageTag(languageTag) + fun appLocale(): Locale = findByLanguageTag(AppCompatDelegate.getApplicationLocales().toLanguageTags()) + + fun syncLanguage() { + val appLocaleTag = appLocale().toSupportedLocaleTag() + if (appLocaleTag != repository.string(R.string.language_key, "")) { + repository.save(R.string.language_key, appLocaleTag) + } } fun sortBy(): SortBy = settingsFind(SortBy.entries, R.string.sort_by_key, SortBy.STRENGTH) diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/vendor/model/VendorService.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/vendor/model/VendorService.kt index 6091bfc2..b1545ac7 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/vendor/model/VendorService.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/vendor/model/VendorService.kt @@ -34,10 +34,10 @@ class VendorService( fun findVendorName(address: String = String.EMPTY): String = vendorData.macs[address.clean()].orEmpty() fun findMacAddresses(vendorName: String = String.EMPTY): List = - vendorData.vendors[vendorName.uppercase(Locale.getDefault())].orEmpty() + vendorData.vendors[vendorName.uppercase(Locale.ROOT)].orEmpty() fun findVendors(vendorName: String = String.EMPTY): List { - val name = vendorName.uppercase(Locale.getDefault()) + val name = vendorName.uppercase(Locale.ROOT) return vendorData.vendors .filterKeys { filter(it, name) } .keys diff --git a/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragment.kt b/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragment.kt index f0063ea7..a9bf4b67 100644 --- a/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragment.kt +++ b/app/src/main/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragment.kt @@ -44,7 +44,7 @@ class ChannelAvailableFragment : Fragment() { private fun update() { val settings = MainContext.INSTANCE.settings val countryCode = settings.countryCode() - val languageLocale = settings.languageLocale() + val languageLocale = settings.appLocale() binding.apply { val textViews = listOf( diff --git a/app/src/main/res/resources.properties b/app/src/main/res/resources.properties new file mode 100644 index 00000000..467b3efe --- /dev/null +++ b/app/src/main/res/resources.properties @@ -0,0 +1 @@ +unqualifiedResLocale=en-US diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 5265d93f..49b11f26 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -103,4 +103,5 @@ "Изключи Wi-Fi при изход" "Регулирането на Wi-Fi сканирането е изключено" "Регулирането на Wi-Fi сканирането е включено" + Стандартно за системата diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a448b204..44c9fa39 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -103,4 +103,5 @@ "WLAN beim Verlassen deaktivieren" "Die WLAN-Scan-Drosselung ist deaktiviert" "Die WLAN-Scan-Drosselung ist aktiviert" + Standardeinstellung des Systems diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 6eb67f2e..918fb8fe 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -103,4 +103,5 @@ "Απενεργοποίηση Wi-Fi κατά την έξοδο" "Ο περιορισμός σάρωσης Wi-Fi είναι απενεργοποιημένος" "Ο περιορισμός σάρωσης Wi-Fi είναι ενεργοποιημένος" + Προεπιλογή συστήματος diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index e5035666..874a3b16 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -103,4 +103,5 @@ "Apagar Wi-Fi al salir" "La aceleración del escaneo de Wi-Fi está deshabilitada" "La aceleración del escaneo de Wi-Fi está habilitada" + Predeterminado del sistema diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 829afd73..84cf463b 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -102,4 +102,5 @@ "Arrêter le Wi-Fi en quittant" "La limitation de l'analyse Wi-Fi est désactivée" "La limitation de l'analyse Wi-Fi est activée" + Paramètre système par défaut diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 2a0b5fcc..692549f2 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -102,5 +102,6 @@ "Wi‑Fi kikapcsolása kilépéskor" "A Wi‑Fi szkennelés korlátozása tiltva" "A Wi‑Fi szkennelés korlátozása engedélyezve" + Rendszerbeállítás diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index afff650e..12c6958f 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -103,4 +103,5 @@ "Spegni Wi-Fi all\'uscita" "La limitazione della scansione Wi-Fi è disabilitata" "La limitazione della scansione Wi-Fi è abilitata" + Predefinita di sistema diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index cb375412..551cbbc5 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -103,4 +103,5 @@ "閉じる時 Wi-Fi をオフにする" "Wi-Fi スキャンのスロットリングが無効になっています" "Wi-Fi スキャンのスロットルが有効になっています" + システムのデフォルト diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index aa7a1ff6..0d9fdc12 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -102,4 +102,5 @@ "Wifi uitsch. bij afsluiten" "Wifi-scanbeperking is uitgeschakeld" "Wifi-scanbeperking is ingeschakeld" + Systeemstandaard diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index fcd16e6a..12340e68 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -103,4 +103,5 @@ "Wyłączanie Wi-Fi przy wyjściu" "Ograniczanie skanowania Wi-Fi jest wyłączone" "Ograniczanie skanowania Wi-Fi jest włączone" + Ustawienie domyślne systemu diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index b14b11cb..037d4794 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -103,4 +103,5 @@ "Desativar o Wi-Fi ao sair" "A limitação da busca por Wi-Fi está desativada" "A limitação da busca por Wi-Fi está ativada" + Padrão do sistema diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index d5a7000c..df86f795 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -103,4 +103,5 @@ "Desligar o Wi-Fi ao sair" "A limitação da procura de Wi-Fi está desativada" "A limitação da procura de Wi-Fi está ativada" + Padrão do sistema diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 8f5704f5..64b9634a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -103,4 +103,5 @@ "Wi-Fi выключен при выходе" "Регулирование сканирования Wi-Fi отключено" "Регулирование сканирования Wi-Fi включено" + Язык системы diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 5d9352bc..c92bbb4c 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -103,4 +103,5 @@ "Çıkışta Wi-Fi'yi kapat" "Wi-Fi tarama kısıtlaması devre dışı" "Wi-Fi tarama kısıtlaması etkin" + Sistem varsayılanı diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index a713d2f9..572020e6 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -114,4 +114,5 @@ "Wi-Fi вимкнений при виході" "Регулювання сканування Wi-Fi вимкнено" "Регулювання сканування Wi-Fi увімкнено" + Налаштування системи за умовчанням diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index cf09e803..ff868aed 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -103,4 +103,5 @@ "退出时关闭 Wi-Fi" "WLAN 扫描调节已禁用" "WLAN 扫描调节已启用" + 系统默认设置 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 8b432bbc..3f064206 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -103,4 +103,5 @@ "退出時關閉 Wi-Fi" "Wi-Fi 掃描限制已停用" "Wi-Fi 掃描限制已啟用" + 系統預設 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d2301aed..3fa5a579 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -217,4 +217,5 @@ "80 MHz" "160 MHz" "320 MHz" + System default diff --git a/app/src/test/kotlin/com/vrem/util/LocaleUtilsTest.kt b/app/src/test/kotlin/com/vrem/util/LocaleUtilsTest.kt index c615260c..21c3c238 100644 --- a/app/src/test/kotlin/com/vrem/util/LocaleUtilsTest.kt +++ b/app/src/test/kotlin/com/vrem/util/LocaleUtilsTest.kt @@ -69,8 +69,10 @@ class LocaleUtilsTest { @Test fun toLanguageTagWithKnownCode() { - assertThat(toLanguageTag(Locale.US)).isEqualTo(Locale.US.language + "_" + Locale.US.country) - assertThat(toLanguageTag(Locale.ENGLISH)).isEqualTo(Locale.ENGLISH.language + "_") + assertThat(toLanguageTag(Locale.US)).isEqualTo("en-US") + assertThat(toLanguageTag(ENGLISH)).isEqualTo("en") + assertThat(toLanguageTag(CHINESE_SIMPLIFIED)).isEqualTo("zh-Hans") + assertThat(toLanguageTag(CHINESE_TRADITIONAL)).isEqualTo("zh-Hant") } @Test @@ -83,9 +85,16 @@ class LocaleUtilsTest { @Test fun findByLanguageTagWithKnownTag() { - assertThat(findByLanguageTag(toLanguageTag(Locale.SIMPLIFIED_CHINESE))).isEqualTo(Locale.SIMPLIFIED_CHINESE) - assertThat(findByLanguageTag(toLanguageTag(Locale.TRADITIONAL_CHINESE))).isEqualTo(Locale.TRADITIONAL_CHINESE) - assertThat(findByLanguageTag(toLanguageTag(Locale.ENGLISH))).isEqualTo(Locale.ENGLISH) + // BCP-47 format (new) + assertThat(findByLanguageTag("zh-Hans")).isEqualTo(CHINESE_SIMPLIFIED) + assertThat(findByLanguageTag("zh-Hant")).isEqualTo(CHINESE_TRADITIONAL) + assertThat(findByLanguageTag("en")).isEqualTo(ENGLISH) + assertThat(findByLanguageTag("en-US")).isEqualTo(ENGLISH) + + // Backward compatibility: underscore format (old) + assertThat(findByLanguageTag("zh_Hans")).isEqualTo(CHINESE_SIMPLIFIED) + assertThat(findByLanguageTag("zh_Hant")).isEqualTo(CHINESE_TRADITIONAL) + assertThat(findByLanguageTag("en_US")).isEqualTo(ENGLISH) } @Test @@ -97,13 +106,13 @@ class LocaleUtilsTest { DUTCH, GREEK, HUNGARIAN, - Locale.SIMPLIFIED_CHINESE, - Locale.TRADITIONAL_CHINESE, - Locale.ENGLISH, - Locale.FRENCH, - Locale.GERMAN, - Locale.ITALIAN, - Locale.JAPANESE, + CHINESE_SIMPLIFIED, + CHINESE_TRADITIONAL, + ENGLISH, + FRENCH, + GERMAN, + ITALIAN, + JAPANESE, POLISH, PORTUGUESE_BRAZIL, PORTUGUESE_PORTUGAL, @@ -123,12 +132,12 @@ class LocaleUtilsTest { } @Test - fun currentDefaultCountryCode() { - assertThat(defaultCountryCode()).isEqualTo(Locale.getDefault().country) + fun currentCurrentCountryCode() { + assertThat(currentCountryCode()).isEqualTo(Locale.getDefault().country) } @Test - fun currentDefaultLanguageTag() { - assertThat(defaultLanguageTag()).isEqualTo(toLanguageTag(Locale.getDefault())) + fun currentCurrentLanguageTag() { + assertThat(currentLanguageTag()).isEqualTo(toLanguageTag(Locale.getDefault())) } } diff --git a/app/src/test/kotlin/com/vrem/wifianalyzer/MainReloadTest.kt b/app/src/test/kotlin/com/vrem/wifianalyzer/MainReloadTest.kt index bbb0191b..3d50b18d 100644 --- a/app/src/test/kotlin/com/vrem/wifianalyzer/MainReloadTest.kt +++ b/app/src/test/kotlin/com/vrem/wifianalyzer/MainReloadTest.kt @@ -27,7 +27,6 @@ import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever -import java.util.Locale class MainReloadTest { private val settings = MainContextHelper.INSTANCE.settings @@ -37,7 +36,6 @@ class MainReloadTest { fun setUp() { whenever(settings.themeStyle()).thenReturn(ThemeStyle.DARK) whenever(settings.connectionViewType()).thenReturn(ConnectionViewType.COMPLETE) - whenever(settings.languageLocale()).thenReturn(Locale.UK) fixture = MainReload(settings) } @@ -45,7 +43,6 @@ class MainReloadTest { fun tearDown() { verify(settings, atLeastOnce()).themeStyle() verify(settings, atLeastOnce()).connectionViewType() - verify(settings, atLeastOnce()).languageLocale() verifyNoMoreInteractions(settings) MainContextHelper.INSTANCE.restore() } @@ -91,25 +88,4 @@ class MainReloadTest { assertThat(actual).isTrue assertThat(fixture.connectionViewType).isEqualTo(expected) } - - @Test - fun shouldNotReloadWithNoLanguageLocaleChanges() { - // execute - val actual = fixture.shouldReload(settings) - // validate - assertThat(actual).isFalse - assertThat(fixture.languageLocale).isEqualTo(Locale.UK) - } - - @Test - fun shouldReloadWithLanguageLocaleChange() { - // setup - val expected = Locale.US - whenever(settings.languageLocale()).thenReturn(expected) - // execute - val actual = fixture.shouldReload(settings) - // validate - assertThat(actual).isTrue - assertThat(fixture.languageLocale).isEqualTo(expected) - } } diff --git a/app/src/test/kotlin/com/vrem/wifianalyzer/settings/LanguagePreferenceTest.kt b/app/src/test/kotlin/com/vrem/wifianalyzer/settings/LanguagePreferenceTest.kt index 32b90514..dd2ab5be 100644 --- a/app/src/test/kotlin/com/vrem/wifianalyzer/settings/LanguagePreferenceTest.kt +++ b/app/src/test/kotlin/com/vrem/wifianalyzer/settings/LanguagePreferenceTest.kt @@ -19,9 +19,8 @@ package com.vrem.wifianalyzer.settings import android.os.Build import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vrem.util.supportedLanguages -import com.vrem.util.toCapitalize -import com.vrem.util.toLanguageTag +import com.vrem.util.supportedLanguageTags +import com.vrem.util.titlecaseFirst import com.vrem.wifianalyzer.R import com.vrem.wifianalyzer.RobolectricUtil import org.assertj.core.api.Assertions.assertThat @@ -35,7 +34,7 @@ import java.util.Locale @Config(sdk = [Build.VERSION_CODES.BAKLAVA]) class LanguagePreferenceTest { private val mainActivity = RobolectricUtil.INSTANCE.activity - private val languages = supportedLanguages() + private val languageTags = supportedLanguageTags() private val attributeSet = Robolectric.getAttributeSetFromXml(R.xml.test_attrs) private val fixture = LanguagePreference(mainActivity, attributeSet) @@ -44,9 +43,16 @@ class LanguagePreferenceTest { // execute val actual: Array = fixture.entries // validate - assertThat(actual).hasSize(languages.size) - languages.forEach { - assertThat(actual).contains(it.getDisplayName(it).toCapitalize(Locale.getDefault())) + assertThat(actual).hasSize(languageTags.size) + + // Check system default entry + assertThat(actual[0]).isEqualTo(mainActivity.getString(R.string.system_default)) + + // Check language entries + languageTags.drop(1).forEachIndexed { index, tag -> + val locale = Locale.forLanguageTag(tag) + val displayName = locale.getDisplayName(locale).titlecaseFirst(locale) + assertThat(actual[index + 1]).isEqualTo(displayName) } } @@ -55,9 +61,7 @@ class LanguagePreferenceTest { // execute val actual: Array = fixture.entryValues // validate - assertThat(actual).hasSize(languages.size) - languages.forEach { - assertThat(actual).contains(toLanguageTag(it)) - } + assertThat(actual).hasSize(languageTags.size) + assertThat(actual).containsExactlyElementsOf(languageTags) } } diff --git a/app/src/test/kotlin/com/vrem/wifianalyzer/settings/SettingsTest.kt b/app/src/test/kotlin/com/vrem/wifianalyzer/settings/SettingsTest.kt index 9ba01f56..cfb36c71 100644 --- a/app/src/test/kotlin/com/vrem/wifianalyzer/settings/SettingsTest.kt +++ b/app/src/test/kotlin/com/vrem/wifianalyzer/settings/SettingsTest.kt @@ -20,10 +20,8 @@ package com.vrem.wifianalyzer.settings import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.os.Build import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vrem.util.defaultCountryCode -import com.vrem.util.defaultLanguageTag +import com.vrem.util.currentCountryCode import com.vrem.util.ordinals -import com.vrem.util.toLanguageTag import com.vrem.wifianalyzer.R import com.vrem.wifianalyzer.navigation.NavigationMenu import com.vrem.wifianalyzer.wifi.accesspoint.AccessPointViewType @@ -46,7 +44,6 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever import org.robolectric.annotation.Config -import java.util.Locale @RunWith(AndroidJUnit4::class) @Config(sdk = [Build.VERSION_CODES.BAKLAVA]) @@ -353,7 +350,7 @@ class SettingsTest { @Test fun countryCode() { // setup - val defaultValue = defaultCountryCode() + val defaultValue = currentCountryCode() val expected = "WW" doReturn(expected).whenever(repository).string(R.string.country_code_key, defaultValue) // execute @@ -364,16 +361,14 @@ class SettingsTest { } @Test - fun languageLocale() { - // setup - val defaultValue = defaultLanguageTag() - val expected = Locale.FRENCH - doReturn(toLanguageTag(expected)).whenever(repository).string(R.string.language_key, defaultValue) + fun appLocale() { + // Note: appLocale() uses AppCompatDelegate.getApplicationLocales() which is system API + // and returns the current application locale (device default in test environment) // execute - val actual = fixture.languageLocale() - // validate - assertThat(actual).isEqualTo(expected) - verify(repository).string(R.string.language_key, defaultValue) + val actual = fixture.appLocale() + // validate: should return a valid Locale (default in test) + assertThat(actual).isNotNull + assertThat(actual.language).isNotEmpty() } @Test diff --git a/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiChannelCountryTest.kt b/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiChannelCountryTest.kt index 42272a22..4082ca97 100644 --- a/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiChannelCountryTest.kt +++ b/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/band/WiFiChannelCountryTest.kt @@ -30,10 +30,14 @@ class WiFiChannelCountryTest { @Test fun find() { - val expected = Locale.US - val actual = WiFiChannelCountry.find(expected.country) - assertThat(actual.countryCode).isEqualTo(expected.country) - assertThat(actual.countryName(expected)).isEqualTo(expected.displayCountry) + val countryLocale = Locale.US + val displayLocale = Locale.getDefault() + + val actual = WiFiChannelCountry.find(countryLocale.country) + + assertThat(actual.countryCode).isEqualTo(countryLocale.country) + assertThat(actual.countryName(displayLocale)) + .isEqualTo(countryLocale.getDisplayCountry(displayLocale)) } @Test diff --git a/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragmentTest.kt b/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragmentTest.kt index 27e3ea49..ff88c4bc 100644 --- a/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragmentTest.kt +++ b/app/src/test/kotlin/com/vrem/wifianalyzer/wifi/channelavailable/ChannelAvailableFragmentTest.kt @@ -62,13 +62,13 @@ class ChannelAvailableFragmentTest { @Before fun setUp() { whenever(settings.countryCode()).thenReturn(locale.country) - whenever(settings.languageLocale()).thenReturn(Locale.US) + whenever(settings.appLocale()).thenReturn(Locale.US) } @After fun tearDown() { verify(settings, atLeastOnce()).countryCode() - verify(settings, atLeastOnce()).languageLocale() + verify(settings, atLeastOnce()).appLocale() INSTANCE.restore() }