diff --git a/app/build.gradle b/app/build.gradle index ea65893e..83f404fb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 80dfee89..4f56a2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + + + + + = 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()) { diff --git a/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt b/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt index a7db465b..a413384e 100644 --- a/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt @@ -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("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("notification") + findPreference("notification") ?.let { preferenceScreen.removePreference(it) } } } } -} \ No newline at end of file +} +class LanguageSettingFragment : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val list: MutableList = 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() + } +} diff --git a/app/src/main/java/org/pixeldroid/app/utils/BaseActivity.kt b/app/src/main/java/org/pixeldroid/app/utils/BaseActivity.kt index 87c5ed98..f47d5e48 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/BaseActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/BaseActivity.kt @@ -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 - } - } \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e5d5d537..162feaea 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -10,61 +10,4 @@ @string/light_theme @string/dark_theme - - - - @string/default_system - العربية - বাংলা (বাংলাদেশ) - Català - Čeština - Deutsch - Español - Euskara - English - فارسی - Suomi - Français - Gaeilge - Magyar - bahasa Indonesia - Italiano - 日本語 - മലയാളം - Nederlands - Polski - Português (Brasil) - Русский - Svenska - Українська - 中文(简体) - - - - default - ar - bn-bd - ca - cs - de - es - eu - en - fa - fi - fr - gl - hu - id - it - ja - ml - nl - pl - pt-br - ru - sv - uk - zh-CN - \ No newline at end of file diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml new file mode 100644 index 00000000..e5d422c9 --- /dev/null +++ b/app/src/main/res/xml/locales_config.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 08aff2c9..11ed9ee1 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -19,12 +19,8 @@ + app:icon="@drawable/note" /> false - - - + + + @@ -102,26 +102,26 @@ - - - + + + - - + + - - + + - - - + + + - - + + - - + + @@ -328,11 +328,6 @@ - - - - - @@ -403,14 +398,6 @@ - - - - - - - - @@ -422,12 +409,15 @@ - - - + + + - - + + + + + @@ -438,12 +428,12 @@ - - - + + + - - + + @@ -454,12 +444,12 @@ - - - + + + - - + + @@ -470,12 +460,12 @@ - - - + + + - - + + @@ -489,12 +479,15 @@ - - - + + + - - + + + + + @@ -508,12 +501,15 @@ - - - + + + - - + + + + + @@ -527,6 +523,17 @@ + + + + + + + + + + + @@ -572,26 +579,26 @@ - - - + + + - - + + - - + + - - - + + + - - + + - - + + @@ -1743,14 +1750,6 @@ - - - - - - - - @@ -1759,12 +1758,12 @@ - - - + + + - - + + @@ -1775,12 +1774,12 @@ - - - + + + - - + + @@ -1791,6 +1790,14 @@ + + + + + + + + @@ -1871,14 +1878,6 @@ - - - - - - - - @@ -1887,12 +1886,12 @@ - - - + + + - - + + @@ -1903,12 +1902,12 @@ - - - + + + - - + + @@ -1919,14 +1918,6 @@ - - - - - - - - @@ -1935,14 +1926,6 @@ - - - - - - - - @@ -1951,6 +1934,14 @@ + + + + + + + + @@ -1959,12 +1950,12 @@ - - - + + + - - + + @@ -1975,12 +1966,12 @@ - - - + + + - - + + @@ -1991,12 +1982,12 @@ - - - + + + - - + + @@ -2007,12 +1998,12 @@ - - - + + + - - + + @@ -2023,12 +2014,12 @@ - - - + + + - - + + @@ -2039,12 +2030,12 @@ - - - + + + - - + + @@ -2055,12 +2046,12 @@ - - - + + + - - + + @@ -2071,39 +2062,28 @@ - - - + + + - - + + - - - - - - + + + - - - - - - - - - - + + @@ -2114,12 +2094,12 @@ - - - + + + - - + + @@ -2130,12 +2110,12 @@ - - - + + + - - + + @@ -2146,12 +2126,12 @@ - - - + + + - - + + @@ -2162,12 +2142,12 @@ - - - + + + - - + + @@ -2178,12 +2158,12 @@ - - - + + + - - + + @@ -2194,12 +2174,12 @@ - - - + + + - - + + @@ -2210,6 +2190,14 @@ + + + + + + + + @@ -2218,22 +2206,6 @@ - - - - - - - - - - - - - - - - @@ -2242,12 +2214,12 @@ - - - + + + - - + + @@ -2258,6 +2230,14 @@ + + + + + + + + @@ -2266,12 +2246,12 @@ - - - + + + - - + + @@ -2282,6 +2262,14 @@ + + + + + + + + @@ -2306,14 +2294,6 @@ - - - - - - - - @@ -2322,12 +2302,12 @@ - - - + + + - - + + @@ -2338,12 +2318,12 @@ - - - + + + - - + + @@ -2354,12 +2334,12 @@ - - - + + + - - + + @@ -2370,12 +2350,12 @@ - - - + + + - - + + @@ -2386,12 +2366,12 @@ - - - + + + - - + + @@ -2402,12 +2382,12 @@ - - - + + + - - + + @@ -2418,12 +2398,12 @@ - - - + + + - - + + @@ -2434,12 +2414,12 @@ - - - + + + - - + + @@ -2450,12 +2430,12 @@ - - - + + + - - + + @@ -2466,12 +2446,12 @@ - - - + + + - - + + @@ -2482,12 +2462,12 @@ - - - + + + - - + + @@ -2498,12 +2478,12 @@ - - - + + + - - + + @@ -2514,12 +2494,12 @@ - - - + + + - - + + @@ -2530,12 +2510,12 @@ - - - + + + - - + + @@ -2546,12 +2526,12 @@ - - - + + + - - + + @@ -2562,12 +2542,12 @@ - - - + + + - - + + @@ -2578,6 +2558,14 @@ + + + + + + + + @@ -2916,9 +2904,6 @@ - - - @@ -2954,6 +2939,14 @@ + + + + + + + + @@ -3055,22 +3048,6 @@ - - - - - - - - - - - - - - - - @@ -3099,16 +3076,6 @@ - - - - - - - - - - @@ -3156,14 +3123,6 @@ - - - - - - - - @@ -3185,11 +3144,6 @@ - - - - - @@ -3237,22 +3191,14 @@ - - - - - - - - - - - + + + @@ -3263,12 +3209,12 @@ - - - + + + - - + + @@ -3279,9 +3225,12 @@ - - - + + + + + + @@ -3289,12 +3238,9 @@ - - - - - - + + + @@ -3305,14 +3251,6 @@ - - - - - - - - @@ -3784,14 +3722,6 @@ - - - - - - - - @@ -3800,14 +3730,6 @@ - - - - - - - - @@ -3816,14 +3738,6 @@ - - - - - - - - @@ -3832,14 +3746,6 @@ - - - - - - - - @@ -3848,14 +3754,6 @@ - - - - - - - - @@ -3864,14 +3762,6 @@ - - - - - - - - @@ -3880,14 +3770,6 @@ - - - - - - - - @@ -3896,14 +3778,6 @@ - - - - - - - - @@ -3912,14 +3786,6 @@ - - - - - - - - @@ -3928,14 +3794,6 @@ - - - - - - - - @@ -3944,14 +3802,6 @@ - - - - - - - - @@ -3960,14 +3810,6 @@ - - - - - - - - @@ -3976,14 +3818,6 @@ - - - - - - - - @@ -3992,14 +3826,6 @@ - - - - - - - - @@ -4008,14 +3834,6 @@ - - - - - - - - @@ -4024,24 +3842,11 @@ - - - - - - - - - - - - - @@ -4063,14 +3868,6 @@ - - - - - - - - @@ -4106,14 +3903,6 @@ - - - - - - - - @@ -4427,11 +4216,6 @@ - - - - - @@ -4452,14 +4236,6 @@ - - - - - - - - @@ -4555,14 +4331,6 @@ - - - - - - - - @@ -4571,14 +4339,6 @@ - - - - - - - - @@ -4880,9 +4640,6 @@ - - - @@ -4996,14 +4753,6 @@ - - - - - - - - @@ -5175,14 +4924,6 @@ - - - - - - - - @@ -5260,18 +5001,7 @@ - - - - - - - - - - - @@ -5308,23 +5038,12 @@ - - - - - - - - - - - @@ -5358,14 +5077,6 @@ - - - - - - - - @@ -5374,14 +5085,6 @@ - - - - - - - - @@ -5411,14 +5114,6 @@ - - - - - - - - @@ -5428,9 +5123,6 @@ - - - @@ -5712,14 +5404,6 @@ - - - - - - - -