mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-15 06:56:30 +00:00
feat: add in-app language picker
This commit is contained in:
parent
96340a35aa
commit
8f2585d8eb
@ -80,11 +80,21 @@
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.BitchatAndroid"
|
||||
tools:targetApi="31">
|
||||
tools:targetApi="33">
|
||||
<service
|
||||
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
|
||||
android:enabled="false"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="autoStoreLocales"
|
||||
android:value="true" />
|
||||
</service>
|
||||
|
||||
<!-- FileProvider for sharing temp/cache files with external viewers -->
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
|
||||
@ -37,6 +37,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.filled.ChevronRight
|
||||
import androidx.compose.material.icons.filled.CloudDownload
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material.icons.filled.Lock
|
||||
import androidx.compose.material.icons.filled.Public
|
||||
import androidx.compose.material.icons.filled.Share
|
||||
@ -52,6 +53,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@ -120,6 +122,114 @@ private fun ThemeChip(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LanguagePickerDialog(
|
||||
languages: List<AppLanguage>,
|
||||
selectedLanguageTag: String,
|
||||
onLanguageSelected: (String) -> Unit,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.about_select_language)) },
|
||||
text = {
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
||||
item(key = "system") {
|
||||
LanguageOptionRow(
|
||||
label = stringResource(R.string.about_system_default),
|
||||
selected = selectedLanguageTag.isEmpty(),
|
||||
onClick = { onLanguageSelected("") },
|
||||
)
|
||||
}
|
||||
items(
|
||||
count = languages.size,
|
||||
key = { index -> languages[index].languageTag },
|
||||
) { index ->
|
||||
val language = languages[index]
|
||||
LanguageOptionRow(
|
||||
label = language.endonym,
|
||||
selected = selectedLanguageTag == language.languageTag,
|
||||
onClick = { onLanguageSelected(language.languageTag) },
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(stringResource(android.R.string.cancel))
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LanguageOptionRow(
|
||||
label: String,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
RadioButton(
|
||||
selected = selected,
|
||||
onClick = null,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LanguageSettingsRow(
|
||||
selectedLanguageName: String,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 13.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Language,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(22.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.about_language),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.Medium,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Text(
|
||||
text = selectedLanguageName,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f, fill = false),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ChevronRight,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified settings toggle row with icon, title, subtitle, and switch
|
||||
* Apple-like design with proper spacing
|
||||
@ -259,6 +369,28 @@ fun AboutSheet(
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val palette = LocalBitchatPalette.current
|
||||
var selectedTab by remember { mutableStateOf(AboutTab.Info) }
|
||||
val supportedLanguages = remember(context) {
|
||||
LanguagePreferenceManager.supportedLanguages(context)
|
||||
}
|
||||
var selectedLanguageTag by remember {
|
||||
mutableStateOf(LanguagePreferenceManager.currentLanguageTag())
|
||||
}
|
||||
var showLanguagePicker by remember { mutableStateOf(false) }
|
||||
|
||||
if (showLanguagePicker) {
|
||||
LanguagePickerDialog(
|
||||
languages = supportedLanguages,
|
||||
selectedLanguageTag = selectedLanguageTag,
|
||||
onLanguageSelected = { languageTag ->
|
||||
showLanguagePicker = false
|
||||
if (languageTag != selectedLanguageTag) {
|
||||
selectedLanguageTag = languageTag
|
||||
LanguagePreferenceManager.setLanguage(languageTag)
|
||||
}
|
||||
},
|
||||
onDismiss = { showLanguagePicker = false },
|
||||
)
|
||||
}
|
||||
|
||||
if (isPresented) {
|
||||
BitchatBottomSheet(
|
||||
@ -342,6 +474,29 @@ fun AboutSheet(
|
||||
}
|
||||
}
|
||||
|
||||
item(key = "language") {
|
||||
val selectedLanguageName = supportedLanguages
|
||||
.firstOrNull { it.languageTag == selectedLanguageTag }
|
||||
?.endonym
|
||||
?: stringResource(R.string.about_system_default)
|
||||
|
||||
Column {
|
||||
AboutSectionLabel(text = stringResource(R.string.about_language))
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = AboutHorizontalPadding),
|
||||
color = colorScheme.surface,
|
||||
shape = AboutCardShape,
|
||||
) {
|
||||
LanguageSettingsRow(
|
||||
selectedLanguageName = selectedLanguageName,
|
||||
onClick = { showLanguagePicker = true },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Settings Section - Unified Card with Toggles
|
||||
item(key = "settings") {
|
||||
LaunchedEffect(Unit) { PoWPreferenceManager.init(context) }
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package com.bitchat.android.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.XmlRes
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import com.bitchat.android.R
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import java.util.Locale
|
||||
|
||||
data class AppLanguage(
|
||||
val languageTag: String,
|
||||
val endonym: String,
|
||||
)
|
||||
|
||||
object LanguagePreferenceManager {
|
||||
fun currentLanguageTag(): String =
|
||||
AppCompatDelegate.getApplicationLocales().toLanguageTags()
|
||||
|
||||
fun setLanguage(languageTag: String) {
|
||||
AppCompatDelegate.setApplicationLocales(
|
||||
LocaleListCompat.forLanguageTags(languageTag)
|
||||
)
|
||||
}
|
||||
|
||||
fun supportedLanguages(
|
||||
context: Context,
|
||||
@XmlRes localeConfig: Int = R.xml.locales_config,
|
||||
): List<AppLanguage> = readLanguageTags(context, localeConfig)
|
||||
.map { languageTag ->
|
||||
val locale = Locale.forLanguageTag(languageTag)
|
||||
AppLanguage(
|
||||
languageTag = languageTag,
|
||||
endonym = locale.getDisplayName(locale)
|
||||
.replaceFirstChar { first ->
|
||||
if (first.isLowerCase()) first.titlecase(locale) else first.toString()
|
||||
},
|
||||
)
|
||||
}
|
||||
.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.endonym })
|
||||
|
||||
internal fun readLanguageTags(
|
||||
context: Context,
|
||||
@XmlRes localeConfig: Int,
|
||||
): List<String> {
|
||||
val parser = context.resources.getXml(localeConfig)
|
||||
return buildList {
|
||||
var event = parser.eventType
|
||||
while (event != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG && parser.name == "locale") {
|
||||
parser.getAttributeValue(ANDROID_NAMESPACE, "name")
|
||||
?.takeIf(String::isNotBlank)
|
||||
?.let(::add)
|
||||
}
|
||||
event = parser.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"
|
||||
}
|
||||
@ -2,14 +2,14 @@ package com.bitchat.android.ui
|
||||
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.bitchat.android.utils.DeviceUtils
|
||||
|
||||
/**
|
||||
* Base activity that automatically sets orientation based on device type.
|
||||
* Tablets can rotate to landscape, phones are locked to portrait.
|
||||
*/
|
||||
abstract class OrientationAwareActivity : ComponentActivity() {
|
||||
abstract class OrientationAwareActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">تحقّق من الملاحظات المتروكة هنا</string>
|
||||
<string name="nearby_notes_one">تُركت ملاحظة واحدة هنا — انقر للقراءة</string>
|
||||
<string name="nearby_notes_many">تُركت %d ملاحظات هنا — انقر للقراءة</string>
|
||||
<string name="about_language">اللغة</string>
|
||||
<string name="about_system_default">إعداد النظام الافتراضي</string>
|
||||
<string name="about_select_language">اختر اللغة</string>
|
||||
</resources>
|
||||
|
||||
@ -376,4 +376,7 @@
|
||||
<string name="nearby_notes_reveal">এখানে রাখা নোট আছে কি না দেখুন</string>
|
||||
<string name="nearby_notes_one">এখানে 1টি নোট রাখা আছে — পড়তে ট্যাপ করুন</string>
|
||||
<string name="nearby_notes_many">এখানে %dটি নোট রাখা আছে — পড়তে ট্যাপ করুন</string>
|
||||
<string name="about_language">ভাষা</string>
|
||||
<string name="about_system_default">সিস্টেম ডিফল্ট</string>
|
||||
<string name="about_select_language">ভাষা নির্বাচন করুন</string>
|
||||
</resources>
|
||||
|
||||
@ -390,4 +390,7 @@
|
||||
<string name="nearby_notes_reveal">nachsehen, ob hier notizen hinterlassen wurden</string>
|
||||
<string name="nearby_notes_one">1 notiz hier hinterlassen — tippen zum lesen</string>
|
||||
<string name="nearby_notes_many">%d notizen hier hinterlassen — tippen zum lesen</string>
|
||||
<string name="about_language">Sprache</string>
|
||||
<string name="about_system_default">Systemstandard</string>
|
||||
<string name="about_select_language">Sprache auswählen</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">buscar notas dejadas aquí</string>
|
||||
<string name="nearby_notes_one">1 nota dejada aquí — toca para leer</string>
|
||||
<string name="nearby_notes_many">%d notas dejadas aquí — toca para leer</string>
|
||||
<string name="about_language">Idioma</string>
|
||||
<string name="about_system_default">Predeterminado del sistema</string>
|
||||
<string name="about_select_language">Seleccionar idioma</string>
|
||||
</resources>
|
||||
|
||||
@ -376,4 +376,7 @@
|
||||
<string name="nearby_notes_reveal">یادداشتهای باقیمانده در اینجا را بررسی کنید</string>
|
||||
<string name="nearby_notes_one">۱ یادداشت اینجا باقی مانده — برای خواندن ضربه بزنید</string>
|
||||
<string name="nearby_notes_many">%d یادداشت اینجا باقی مانده — برای خواندن ضربه بزنید</string>
|
||||
<string name="about_language">زبان</string>
|
||||
<string name="about_system_default">پیشفرض سیستم</string>
|
||||
<string name="about_select_language">انتخاب زبان</string>
|
||||
</resources>
|
||||
|
||||
@ -393,4 +393,7 @@
|
||||
<string name="nearby_notes_reveal">tingnan kung may mga note na naiwan dito</string>
|
||||
<string name="nearby_notes_one">1 note ang naiwan dito — i-tap para basahin</string>
|
||||
<string name="nearby_notes_many">%d note ang naiwan dito — i-tap para basahin</string>
|
||||
<string name="about_language">Wika</string>
|
||||
<string name="about_system_default">Default ng system</string>
|
||||
<string name="about_select_language">Pumili ng wika</string>
|
||||
</resources>
|
||||
|
||||
@ -407,4 +407,7 @@
|
||||
<string name="nearby_notes_reveal">vérifier s\'il y a des notes laissées ici</string>
|
||||
<string name="nearby_notes_one">1 note laissée ici — appuyez pour lire</string>
|
||||
<string name="nearby_notes_many">%d notes laissées ici — appuyez pour lire</string>
|
||||
<string name="about_language">Langue</string>
|
||||
<string name="about_system_default">Langue du système</string>
|
||||
<string name="about_select_language">Choisir la langue</string>
|
||||
</resources>
|
||||
|
||||
@ -57,4 +57,7 @@
|
||||
<string name="nearby_notes_reveal">בדיקה אם הושארו כאן פתקים</string>
|
||||
<string name="nearby_notes_one">פתק אחד הושאר כאן — הקש לקריאה</string>
|
||||
<string name="nearby_notes_many">%d פתקים הושארו כאן — הקש לקריאה</string>
|
||||
<string name="about_language">שפה</string>
|
||||
<string name="about_system_default">ברירת המחדל של המערכת</string>
|
||||
<string name="about_select_language">בחירת שפה</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">देखें कि यहाँ नोट छोड़े गए हैं या नहीं</string>
|
||||
<string name="nearby_notes_one">यहाँ 1 नोट छोड़ा गया है — पढ़ने के लिए टैप करें</string>
|
||||
<string name="nearby_notes_many">यहाँ %d नोट छोड़े गए हैं — पढ़ने के लिए टैप करें</string>
|
||||
<string name="about_language">भाषा</string>
|
||||
<string name="about_system_default">सिस्टम डिफ़ॉल्ट</string>
|
||||
<string name="about_select_language">भाषा चुनें</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">periksa catatan yang ditinggalkan di sini</string>
|
||||
<string name="nearby_notes_one">1 catatan ditinggalkan di sini — ketuk untuk membaca</string>
|
||||
<string name="nearby_notes_many">%d catatan ditinggalkan di sini — ketuk untuk membaca</string>
|
||||
<string name="about_language">Bahasa</string>
|
||||
<string name="about_system_default">Default sistem</string>
|
||||
<string name="about_select_language">Pilih bahasa</string>
|
||||
</resources>
|
||||
|
||||
@ -422,4 +422,7 @@
|
||||
<string name="nearby_notes_reveal">controlla se ci sono note lasciate qui</string>
|
||||
<string name="nearby_notes_one">1 nota lasciata qui — tocca per leggere</string>
|
||||
<string name="nearby_notes_many">%d note lasciate qui — tocca per leggere</string>
|
||||
<string name="about_language">Lingua</string>
|
||||
<string name="about_system_default">Predefinita di sistema</string>
|
||||
<string name="about_select_language">Seleziona lingua</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">ここに残されたメモを確認</string>
|
||||
<string name="nearby_notes_one">ここに1件のメモがあります — タップして読む</string>
|
||||
<string name="nearby_notes_many">ここに%d件のメモがあります — タップして読む</string>
|
||||
<string name="about_language">言語</string>
|
||||
<string name="about_system_default">システムのデフォルト</string>
|
||||
<string name="about_select_language">言語を選択</string>
|
||||
</resources>
|
||||
|
||||
@ -376,4 +376,7 @@
|
||||
<string name="nearby_notes_reveal">აქ დატოვებული ჩანაწერების შემოწმება</string>
|
||||
<string name="nearby_notes_one">აქ 1 ჩანაწერია დატოვებული — წასაკითხად შეეხეთ</string>
|
||||
<string name="nearby_notes_many">აქ %d ჩანაწერია დატოვებული — წასაკითხად შეეხეთ</string>
|
||||
<string name="about_language">ენა</string>
|
||||
<string name="about_system_default">სისტემის ნაგულისხმევი</string>
|
||||
<string name="about_select_language">ენის არჩევა</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">여기 남겨진 쪽지 확인</string>
|
||||
<string name="nearby_notes_one">여기 남겨진 쪽지 1개 — 탭하여 읽기</string>
|
||||
<string name="nearby_notes_many">여기 남겨진 쪽지 %d개 — 탭하여 읽기</string>
|
||||
<string name="about_language">언어</string>
|
||||
<string name="about_system_default">시스템 기본값</string>
|
||||
<string name="about_select_language">언어 선택</string>
|
||||
</resources>
|
||||
|
||||
@ -402,4 +402,7 @@
|
||||
<string name="nearby_notes_reveal">hizaha raha misy naoty navela teto</string>
|
||||
<string name="nearby_notes_one">naoty 1 no navela teto — tsindrio raha hamaky</string>
|
||||
<string name="nearby_notes_many">naoty %d no navela teto — tsindrio raha hamaky</string>
|
||||
<string name="about_language">Fiteny</string>
|
||||
<string name="about_system_default">Fitenin’ny rafitra</string>
|
||||
<string name="about_select_language">Safidio ny fiteny</string>
|
||||
</resources>
|
||||
|
||||
@ -44,4 +44,7 @@
|
||||
<string name="nearby_notes_reveal">semak nota yang ditinggalkan di sini</string>
|
||||
<string name="nearby_notes_one">1 nota ditinggalkan di sini — ketik untuk baca</string>
|
||||
<string name="nearby_notes_many">%d nota ditinggalkan di sini — ketik untuk baca</string>
|
||||
<string name="about_language">Bahasa</string>
|
||||
<string name="about_system_default">Lalai sistem</string>
|
||||
<string name="about_select_language">Pilih bahasa</string>
|
||||
</resources>
|
||||
|
||||
@ -393,4 +393,7 @@
|
||||
<string name="nearby_notes_reveal">यहाँ छोडिएका नोटहरू छन् कि हेर्नुहोस्</string>
|
||||
<string name="nearby_notes_one">यहाँ 1 नोट छोडिएको छ — पढ्न ट्याप गर्नुहोस्</string>
|
||||
<string name="nearby_notes_many">यहाँ %d नोटहरू छोडिएका छन् — पढ्न ट्याप गर्नुहोस्</string>
|
||||
<string name="about_language">भाषा</string>
|
||||
<string name="about_system_default">प्रणालीको पूर्वनिर्धारित</string>
|
||||
<string name="about_select_language">भाषा छान्नुहोस्</string>
|
||||
</resources>
|
||||
|
||||
@ -420,4 +420,7 @@
|
||||
<string name="nearby_notes_reveal">kijk of hier notities zijn achtergelaten</string>
|
||||
<string name="nearby_notes_one">1 notitie hier achtergelaten — tik om te lezen</string>
|
||||
<string name="nearby_notes_many">%d notities hier achtergelaten — tik om te lezen</string>
|
||||
<string name="about_language">Taal</string>
|
||||
<string name="about_system_default">Systeemstandaard</string>
|
||||
<string name="about_select_language">Taal selecteren</string>
|
||||
</resources>
|
||||
|
||||
@ -376,4 +376,7 @@
|
||||
<string name="nearby_notes_reveal">ایتھے چھڈے نوٹس ویکھو</string>
|
||||
<string name="nearby_notes_one">ایتھے 1 نوٹ چھڈیا گیا — پڑھݨ لئی ٹیپ کرو</string>
|
||||
<string name="nearby_notes_many">ایتھے %d نوٹس چھڈے گئے — پڑھݨ لئی ٹیپ کرو</string>
|
||||
<string name="about_language">بولی</string>
|
||||
<string name="about_system_default">سسٹم دی ڈیفالٹ</string>
|
||||
<string name="about_select_language">بولی چݨو</string>
|
||||
</resources>
|
||||
|
||||
@ -57,4 +57,7 @@
|
||||
<string name="nearby_notes_reveal">sprawdź, czy zostawiono tutaj notatki</string>
|
||||
<string name="nearby_notes_one">1 notatka zostawiona tutaj — stuknij, aby przeczytać</string>
|
||||
<string name="nearby_notes_many">%d notatek zostawionych tutaj — stuknij, aby przeczytać</string>
|
||||
<string name="about_language">Język</string>
|
||||
<string name="about_system_default">Domyślny systemu</string>
|
||||
<string name="about_select_language">Wybierz język</string>
|
||||
</resources>
|
||||
|
||||
@ -388,4 +388,7 @@
|
||||
<string name="nearby_notes_reveal">ver se há notas deixadas aqui</string>
|
||||
<string name="nearby_notes_one">1 nota deixada aqui — toque para ler</string>
|
||||
<string name="nearby_notes_many">%d notas deixadas aqui — toque para ler</string>
|
||||
<string name="about_language">Idioma</string>
|
||||
<string name="about_system_default">Padrão do sistema</string>
|
||||
<string name="about_select_language">Selecionar idioma</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">ver se há notas deixadas aqui</string>
|
||||
<string name="nearby_notes_one">1 nota deixada aqui — toque para ler</string>
|
||||
<string name="nearby_notes_many">%d notas deixadas aqui — toque para ler</string>
|
||||
<string name="about_language">Idioma</string>
|
||||
<string name="about_system_default">Predefinição do sistema</string>
|
||||
<string name="about_select_language">Selecionar idioma</string>
|
||||
</resources>
|
||||
|
||||
@ -383,4 +383,7 @@
|
||||
<string name="nearby_notes_reveal">проверить, есть ли здесь заметки</string>
|
||||
<string name="nearby_notes_one">здесь оставлена 1 заметка — нажмите, чтобы прочитать</string>
|
||||
<string name="nearby_notes_many">здесь оставлено заметок: %d — нажмите, чтобы прочитать</string>
|
||||
<string name="about_language">Язык</string>
|
||||
<string name="about_system_default">Системный язык</string>
|
||||
<string name="about_select_language">Выбрать язык</string>
|
||||
</resources>
|
||||
|
||||
@ -381,4 +381,7 @@
|
||||
<string name="nearby_notes_reveal">kolla om anteckningar lämnats här</string>
|
||||
<string name="nearby_notes_one">1 anteckning lämnad här — tryck för att läsa</string>
|
||||
<string name="nearby_notes_many">%d anteckningar lämnade här — tryck för att läsa</string>
|
||||
<string name="about_language">Språk</string>
|
||||
<string name="about_system_default">Systemstandard</string>
|
||||
<string name="about_select_language">Välj språk</string>
|
||||
</resources>
|
||||
|
||||
@ -44,4 +44,7 @@
|
||||
<string name="nearby_notes_reveal">இங்கே விடப்பட்ட குறிப்புகள் உள்ளதா எனப் பார்க்கவும்</string>
|
||||
<string name="nearby_notes_one">இங்கே 1 குறிப்பு விடப்பட்டுள்ளது — படிக்க தட்டவும்</string>
|
||||
<string name="nearby_notes_many">இங்கே %d குறிப்புகள் விடப்பட்டுள்ளன — படிக்க தட்டவும்</string>
|
||||
<string name="about_language">மொழி</string>
|
||||
<string name="about_system_default">கணினி இயல்புநிலை</string>
|
||||
<string name="about_select_language">மொழியைத் தேர்ந்தெடுக்கவும்</string>
|
||||
</resources>
|
||||
|
||||
@ -376,4 +376,7 @@
|
||||
<string name="nearby_notes_reveal">ดูว่ามีโน้ตทิ้งไว้ที่นี่หรือไม่</string>
|
||||
<string name="nearby_notes_one">มี 1 โน้ตทิ้งไว้ที่นี่ — แตะเพื่ออ่าน</string>
|
||||
<string name="nearby_notes_many">มี %d โน้ตทิ้งไว้ที่นี่ — แตะเพื่ออ่าน</string>
|
||||
<string name="about_language">ภาษา</string>
|
||||
<string name="about_system_default">ค่าเริ่มต้นของระบบ</string>
|
||||
<string name="about_select_language">เลือกภาษา</string>
|
||||
</resources>
|
||||
|
||||
@ -381,4 +381,7 @@
|
||||
<string name="nearby_notes_reveal">buraya bırakılan notlara bak</string>
|
||||
<string name="nearby_notes_one">buraya 1 not bırakıldı — okumak için dokun</string>
|
||||
<string name="nearby_notes_many">buraya %d not bırakıldı — okumak için dokun</string>
|
||||
<string name="about_language">Dil</string>
|
||||
<string name="about_system_default">Sistem varsayılanı</string>
|
||||
<string name="about_select_language">Dil seçin</string>
|
||||
</resources>
|
||||
|
||||
@ -44,4 +44,7 @@
|
||||
<string name="nearby_notes_reveal">перевірити, чи залишено тут нотатки</string>
|
||||
<string name="nearby_notes_one">тут залишено 1 нотатку — торкніться, щоб прочитати</string>
|
||||
<string name="nearby_notes_many">тут залишено %d нотаток — торкніться, щоб прочитати</string>
|
||||
<string name="about_language">Мова</string>
|
||||
<string name="about_system_default">Системна мова</string>
|
||||
<string name="about_select_language">Вибрати мову</string>
|
||||
</resources>
|
||||
|
||||
@ -389,4 +389,7 @@
|
||||
<string name="nearby_notes_reveal">دیکھیں کہ یہاں نوٹ چھوڑے گئے ہیں یا نہیں</string>
|
||||
<string name="nearby_notes_one">یہاں 1 نوٹ چھوڑا گیا ہے — پڑھنے کے لیے تھپتھپائیں</string>
|
||||
<string name="nearby_notes_many">یہاں %d نوٹ چھوڑے گئے ہیں — پڑھنے کے لیے تھپتھپائیں</string>
|
||||
<string name="about_language">زبان</string>
|
||||
<string name="about_system_default">سسٹم ڈیفالٹ</string>
|
||||
<string name="about_select_language">زبان منتخب کریں</string>
|
||||
</resources>
|
||||
|
||||
@ -376,4 +376,7 @@
|
||||
<string name="nearby_notes_reveal">kiểm tra ghi chú để lại ở đây</string>
|
||||
<string name="nearby_notes_one">có 1 ghi chú để lại ở đây — chạm để đọc</string>
|
||||
<string name="nearby_notes_many">có %d ghi chú để lại ở đây — chạm để đọc</string>
|
||||
<string name="about_language">Ngôn ngữ</string>
|
||||
<string name="about_system_default">Mặc định hệ thống</string>
|
||||
<string name="about_select_language">Chọn ngôn ngữ</string>
|
||||
</resources>
|
||||
|
||||
@ -56,4 +56,7 @@
|
||||
<string name="nearby_notes_reveal">查看这里留下的留言</string>
|
||||
<string name="nearby_notes_one">这里留有 1 条留言 — 点按阅读</string>
|
||||
<string name="nearby_notes_many">这里留有 %d 条留言 — 点按阅读</string>
|
||||
<string name="about_language">语言</string>
|
||||
<string name="about_system_default">跟随系统</string>
|
||||
<string name="about_select_language">选择语言</string>
|
||||
</resources>
|
||||
|
||||
@ -56,4 +56,7 @@
|
||||
<string name="nearby_notes_reveal">查看這裡留下的留言</string>
|
||||
<string name="nearby_notes_one">這裡留有 1 則留言 — 點按閱讀</string>
|
||||
<string name="nearby_notes_many">這裡留有 %d 則留言 — 點按閱讀</string>
|
||||
<string name="about_language">語言</string>
|
||||
<string name="about_system_default">跟隨系統</string>
|
||||
<string name="about_select_language">選擇語言</string>
|
||||
</resources>
|
||||
|
||||
@ -406,4 +406,7 @@
|
||||
<string name="nearby_notes_reveal">查看这里留下的留言</string>
|
||||
<string name="nearby_notes_one">这里留有 1 条留言 — 点按阅读</string>
|
||||
<string name="nearby_notes_many">这里留有 %d 条留言 — 点按阅读</string>
|
||||
<string name="about_language">语言</string>
|
||||
<string name="about_system_default">跟随系统</string>
|
||||
<string name="about_select_language">选择语言</string>
|
||||
</resources>
|
||||
|
||||
@ -567,4 +567,7 @@
|
||||
</plurals>
|
||||
|
||||
<string name="bluetooth_recommended">Bluetooth Recommended</string>
|
||||
<string name="about_language">Language</string>
|
||||
<string name="about_system_default">System default</string>
|
||||
<string name="about_select_language">Select language</string>
|
||||
</resources>
|
||||
|
||||
36
app/src/main/res/xml/locales_config.xml
Normal file
36
app/src/main/res/xml/locales_config.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<locale android:name="ar" />
|
||||
<locale android:name="bn" />
|
||||
<locale android:name="de" />
|
||||
<locale android:name="es" />
|
||||
<locale android:name="fa" />
|
||||
<locale android:name="fil" />
|
||||
<locale android:name="fr" />
|
||||
<locale android:name="he" />
|
||||
<locale android:name="hi" />
|
||||
<locale android:name="id" />
|
||||
<locale android:name="it" />
|
||||
<locale android:name="ja" />
|
||||
<locale android:name="ka" />
|
||||
<locale android:name="ko" />
|
||||
<locale android:name="mg" />
|
||||
<locale android:name="ms" />
|
||||
<locale android:name="ne" />
|
||||
<locale android:name="nl" />
|
||||
<locale android:name="pa-PK" />
|
||||
<locale android:name="pl" />
|
||||
<locale android:name="pt" />
|
||||
<locale android:name="pt-BR" />
|
||||
<locale android:name="ru" />
|
||||
<locale android:name="sv" />
|
||||
<locale android:name="ta" />
|
||||
<locale android:name="th" />
|
||||
<locale android:name="tr" />
|
||||
<locale android:name="uk" />
|
||||
<locale android:name="ur" />
|
||||
<locale android:name="vi" />
|
||||
<locale android:name="zh" />
|
||||
<locale android:name="zh-CN" />
|
||||
<locale android:name="zh-TW" />
|
||||
</locale-config>
|
||||
@ -0,0 +1,71 @@
|
||||
package com.bitchat.android.ui
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
class LanguageCatalogContractTest {
|
||||
private val resourcesDirectory = File("src/main/res")
|
||||
|
||||
@Test
|
||||
fun `locale config contains every shipped locale exactly once`() {
|
||||
val shippedLanguageTags = resourcesDirectory
|
||||
.listFiles()
|
||||
.orEmpty()
|
||||
.filter { it.isDirectory && it.name.startsWith("values-") }
|
||||
.mapNotNull { directory -> directory.name.toLanguageTagOrNull() }
|
||||
.toSet()
|
||||
|
||||
val configuredLanguageTags = Regex("""android:name="([^"]+)"""")
|
||||
.findAll(File(resourcesDirectory, "xml/locales_config.xml").readText())
|
||||
.map { match -> match.groupValues[1] }
|
||||
.toList()
|
||||
|
||||
assertEquals(
|
||||
"Locale configuration must not contain duplicate entries",
|
||||
configuredLanguageTags.toSet().size,
|
||||
configuredLanguageTags.size,
|
||||
)
|
||||
assertEquals(shippedLanguageTags, configuredLanguageTags.toSet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `language picker strings exist in every locale pack`() {
|
||||
val requiredKeys = setOf(
|
||||
"about_language",
|
||||
"about_system_default",
|
||||
"about_select_language",
|
||||
)
|
||||
|
||||
resourcesDirectory
|
||||
.listFiles()
|
||||
.orEmpty()
|
||||
.filter { directory ->
|
||||
directory.isDirectory &&
|
||||
(directory.name == "values" || directory.name.toLanguageTagOrNull() != null)
|
||||
}
|
||||
.forEach { directory ->
|
||||
val strings = File(directory, "strings.xml").readText()
|
||||
requiredKeys.forEach { key ->
|
||||
assertTrue(
|
||||
"$key is missing from ${directory.name}/strings.xml",
|
||||
"""name="$key""" in strings,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.toLanguageTagOrNull(): String? {
|
||||
if (!startsWith("values-") || this == "values-night") return null
|
||||
return removePrefix("values-")
|
||||
.split("-")
|
||||
.joinToString("-") { qualifier ->
|
||||
if (qualifier.startsWith("r") && qualifier.length == 3) {
|
||||
qualifier.drop(1)
|
||||
} else {
|
||||
qualifier
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user