Merge branch 'language_chooser_native' into 'master'

Use native language chooser

See merge request pixeldroid/PixelDroid!507
This commit is contained in:
Matthieu 2022-11-25 21:10:22 +00:00
commit 3d4e32cf4b
10 changed files with 455 additions and 768 deletions

View File

@ -35,6 +35,8 @@ android {
versionCode 19
versionName "1.0.beta" + versionCode
//TODO add resConfigs("en", "fr", "ja",...) ?
testInstrumentationRunner "org.pixeldroid.app.testUtility.TestRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
}
@ -130,7 +132,7 @@ dependencies {
/**
* AndroidX dependencies:
*/
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.appcompat:appcompat:1.6.0-rc01'
implementation 'androidx.core:core-splashscreen:1.0.0'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.preference:preference-ktx:1.2.0'

View File

@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
@ -25,7 +26,17 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:localeConfig="@xml/locales_config"
android:theme="@style/AppTheme">
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
<activity
android:name=".posts.AlbumActivity"
android:exported="false"

View File

@ -257,8 +257,9 @@ class LoginActivity : BaseThemedWithoutBarActivity() {
//Successful authorization
pixelfedAPI = PixelfedAPI.createFromUrl(domain)
val nodeInfo: NodeInfo? = Gson().fromJson(preferences.getString("nodeInfo", null), NodeInfo::class.java)
val instance: Instance? = Gson().fromJson(preferences.getString("instance", null), Instance::class.java)
val gson = Gson()
val nodeInfo: NodeInfo? = gson.fromJson(preferences.getString("nodeInfo", null), NodeInfo::class.java)
val instance: Instance? = gson.fromJson(preferences.getString("instance", null), Instance::class.java)
lifecycleScope.launch {
try {

View File

@ -9,6 +9,7 @@ import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.DisplayMetrics
@ -204,14 +205,19 @@ class CameraFragment : BaseFragment() {
// Update gallery thumbnail
if (ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_EXTERNAL_STORAGE
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
) {
updateGalleryThumbnail()
}
else if (!filePermissionDialogLaunched) {
// Ask for external storage permission.
updateGalleryThumbnailPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
updateGalleryThumbnailPermissionLauncher.launch(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else Manifest.permission.READ_EXTERNAL_STORAGE
)
}
cameraLifecycleOwner.resume()
@ -273,14 +279,14 @@ class CameraFragment : BaseFragment() {
// Find the last picture
val projection = arrayOf(
MediaStore.Images.ImageColumns._ID,
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) MediaStore.Images.ImageColumns.DATE_TAKEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) MediaStore.Images.ImageColumns.DATE_TAKEN
else MediaStore.Images.ImageColumns.DATE_MODIFIED,
)
val cursor = requireContext().contentResolver
.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
null,
(if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) MediaStore.Images.ImageColumns.DATE_TAKEN
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) MediaStore.Images.ImageColumns.DATE_TAKEN
else MediaStore.Images.ImageColumns.DATE_MODIFIED) + " DESC"
)
if (cursor != null && cursor.moveToFirst()) {

View File

@ -1,10 +1,16 @@
package org.pixeldroid.app.settings
import android.app.Dialog
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.XmlResourceParser
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import androidx.fragment.app.DialogFragment
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
@ -13,6 +19,7 @@ import org.pixeldroid.app.R
import org.pixeldroid.app.utils.BaseThemedWithBarActivity
import org.pixeldroid.app.utils.setThemeFromPreferences
class SettingsActivity : BaseThemedWithBarActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
private var restartMainOnExit = false
@ -57,9 +64,6 @@ class SettingsActivity : BaseThemedWithBarActivity(), SharedPreferences.OnShared
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
when (key) {
"language" -> {
recreateWithRestartStatus()
}
"theme" -> {
setThemeFromPreferences(sharedPreferences, resources)
recreateWithRestartStatus()
@ -88,6 +92,8 @@ class SettingsActivity : BaseThemedWithBarActivity(), SharedPreferences.OnShared
var dialogFragment: DialogFragment? = null
if (preference is ColorPreference) {
dialogFragment = ColorPreferenceDialog((preference as ColorPreference?)!!)
} else if(preference.key == "language"){
dialogFragment = LanguageSettingFragment()
}
if (dialogFragment != null) {
dialogFragment.setTargetFragment(this, 0)
@ -100,12 +106,62 @@ class SettingsActivity : BaseThemedWithBarActivity(), SharedPreferences.OnShared
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
findPreference<ListPreference>("language")?.let {
it.setSummaryProvider {
val locale = AppCompatDelegate.getApplicationLocales().get(0)
locale?.getDisplayName(locale) ?: getString(R.string.default_system)
}
}
//Hide Notification setting for Android versions where it doesn't work
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
preferenceManager.findPreference<Preference>("notification")
findPreference<Preference>("notification")
?.let { preferenceScreen.removePreference(it) }
}
}
}
}
}
class LanguageSettingFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val list: MutableList<String> = mutableListOf()
resources.getXml(R.xml.locales_config).use {
var eventType = it.eventType
while (eventType != XmlResourceParser.END_DOCUMENT) {
when (eventType) {
XmlResourceParser.START_TAG -> {
if (it.name == "locale") {
list.add(it.getAttributeValue(0))
}
}
}
eventType = it.next()
}
}
val locales = AppCompatDelegate.getApplicationLocales()
val checkedItem: Int =
if(locales.isEmpty) 0
else {
// For some reason we get a bit inconsistent language tags. This normalises it for
// the currently used languages, but it might break in the future if we add some
val index = list.indexOf(locales.get(0)?.toLanguageTag()?.lowercase()?.replace('_', '-'))
// If found, we want to compensate for the first in the list being the default
if(index == -1) -1
else index + 1
}
return AlertDialog.Builder(requireContext()).apply {
setIcon(R.drawable.translate_black_24dp)
setTitle(R.string.language)
setSingleChoiceItems((mutableListOf(getString(R.string.default_system)) + list.map {
val appLocale = LocaleListCompat.forLanguageTags(it)
appLocale.get(0)!!.getDisplayName(appLocale.get(0)!!)
}).toTypedArray(), checkedItem) { dialog, which ->
val languageTag = if(which in 1..list.size) list[which - 1] else null
dialog.dismiss()
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(languageTag))
}
setNegativeButton(android.R.string.ok) { _, _ -> }
}.create()
}
}

View File

@ -1,15 +1,9 @@
package org.pixeldroid.app.utils
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import org.pixeldroid.app.utils.db.AppDatabase
import org.pixeldroid.app.utils.di.PixelfedAPIHolder
import java.util.*
import javax.inject.Inject
open class BaseActivity : AppCompatActivity() {
@ -24,40 +18,8 @@ open class BaseActivity : AppCompatActivity() {
(this.application as PixelDroidApplication).getAppComponent().inject(this)
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(updateBaseContextLocale(base))
}
override fun onSupportNavigateUp(): Boolean {
onBackPressed()
return true
}
private fun updateBaseContextLocale(context: Context): Context {
val language = PreferenceManager.getDefaultSharedPreferences(context).getString("language", "default") ?: "default"
if(language == "default"){
return context
}
val locale = Locale.forLanguageTag(language)
Locale.setDefault(locale)
return if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
updateResourcesLocale(context, locale)
} else updateResourcesLocaleLegacy(context, locale)
}
private fun updateResourcesLocale(context: Context, locale: Locale): Context =
context.createConfigurationContext(
Configuration(context.resources.configuration)
.apply { setLocale(locale) }
)
@Suppress("DEPRECATION")
private fun updateResourcesLocaleLegacy(context: Context, locale: Locale): Context {
val resources: Resources = context.resources
val configuration: Configuration = resources.configuration
configuration.locale = locale
resources.updateConfiguration(configuration, resources.displayMetrics)
return context
}
}

View File

@ -10,61 +10,4 @@
<item>@string/light_theme</item>
<item>@string/dark_theme</item>
</string-array>
<string-array name="languages_entries">
<item>@string/default_system</item>
<item>العربية</item>
<item>বাংলা (বাংলাদেশ)</item>
<item>Català</item>
<item>Čeština</item>
<item>Deutsch</item>
<item>Español</item>
<item>Euskara</item>
<item>English</item>
<item>فارسی</item>
<item>Suomi</item>
<item>Français</item>
<item>Gaeilge</item>
<item>Magyar</item>
<item>bahasa Indonesia</item>
<item>Italiano</item>
<item>日本語</item>
<item>മലയാളം</item>
<item>Nederlands</item>
<item>Polski</item>
<item>Português (Brasil)</item>
<item>Русский</item>
<item>Svenska</item>
<item>Українська</item>
<item>中文(简体)</item>
</string-array>
<string-array name="languages_values">
<item>default</item>
<item>ar</item>
<item>bn-bd</item>
<item>ca</item>
<item>cs</item>
<item>de</item>
<item>es</item>
<item>eu</item>
<item>en</item>
<item>fa</item>
<item>fi</item>
<item>fr</item>
<item>gl</item>
<item>hu</item>
<item>id</item>
<item>it</item>
<item>ja</item>
<item>ml</item>
<item>nl</item>
<item>pl</item>
<item>pt-br</item>
<item>ru</item>
<item>sv</item>
<item>uk</item>
<item>zh-CN</item>
</string-array>
</resources>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en"/>
<locale android:name="ar"/>
<locale android:name="bn-bd"/>
<locale android:name="ca"/>
<locale android:name="cs"/>
<locale android:name="de"/>
<locale android:name="es"/>
<locale android:name="eu"/>
<locale android:name="fa"/>
<locale android:name="fi"/>
<locale android:name="fr"/>
<locale android:name="gl"/>
<locale android:name="hu"/>
<locale android:name="id"/>
<locale android:name="it"/>
<locale android:name="ja"/>
<locale android:name="ml"/>
<locale android:name="nl"/>
<locale android:name="pl"/>
<locale android:name="pt-br"/>
<locale android:name="ru"/>
<locale android:name="sv"/>
<locale android:name="uk"/>
<locale android:name="zh-CN"/>
</locale-config>

View File

@ -19,12 +19,8 @@
</PreferenceCategory>
<ListPreference
app:defaultValue="default"
app:entries="@array/languages_entries"
app:entryValues="@array/languages_values"
app:key="language"
app:title="@string/language"
app:useSimpleSummaryProvider="true"
app:icon="@drawable/translate_black_24dp" />
<Preference android:title="@string/notifications_settings"
@ -40,8 +36,7 @@
<EditTextPreference android:title="@string/description_template"
android:key="prefill_description"
android:summary="@string/description_template_summary"
app:icon="@drawable/note"
/>
app:icon="@drawable/note" />
<Preference android:title="@string/about"
android:key="about"

File diff suppressed because it is too large Load Diff