From 0b5a8e69fb420383a2025aebdf911385ca174f67 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 5 Feb 2022 20:02:33 +0100 Subject: [PATCH] add preferred content language selection to AccountFragment this contains only gui work --- .../teapod/parser/crunchyroll/Crunchyroll.kt | 21 ++++- .../teapod/parser/crunchyroll/DataTypes.kt | 30 +++++++ .../main/fragments/AccountFragment.kt | 85 +++++++++++++------ .../res/drawable/ic_baseline_language_24.xml | 5 ++ app/src/main/res/layout/fragment_account.xml | 40 +++++++++ app/src/main/res/values-de-rDE/strings.xml | 3 + app/src/main/res/values/strings.xml | 11 ++- app/src/main/res/values/styles.xml | 17 +++- 8 files changed, 179 insertions(+), 33 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_language_24.xml diff --git a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt index a55a552..a77a103 100644 --- a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt +++ b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt @@ -456,8 +456,8 @@ object Crunchyroll { val watchlistEndpoint = "/content/v1/$accountID/watchlist" val parameters = listOf("locale" to locale, "n" to n) - val watchlistResult = request(watchlistEndpoint, parameters) - val list: ContinueWatchingList = watchlistResult.component1()?.obj()?.let { + val result = request(watchlistEndpoint, parameters) + val list: ContinueWatchingList = result.component1()?.obj()?.let { json.decodeFromString(it.toString()) } ?: NoneContinueWatchingList @@ -475,10 +475,23 @@ object Crunchyroll { val watchlistEndpoint = "/content/v1/$accountID/up_next_account" val parameters = listOf("locale" to locale, "n" to n) - val resultUpNextAccount = request(watchlistEndpoint, parameters) - return resultUpNextAccount.component1()?.obj()?.let { + val result = request(watchlistEndpoint, parameters) + return result.component1()?.obj()?.let { json.decodeFromString(it.toString()) } ?: NoneContinueWatchingList } + /** + * Account/Profile functions + */ + + suspend fun profile(): Profile { + val profileEndpoint = "/accounts/v1/me/profile" + + val result = request(profileEndpoint) + return result.component1()?.obj()?.let { + json.decodeFromString(it.toString()) + } ?: NoneProfile + } + } diff --git a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt index c0335c7..3c34a49 100644 --- a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt +++ b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt @@ -4,6 +4,20 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.util.* +val supportedLocals = listOf( + Locale.forLanguageTag("ar-SA"), + Locale.forLanguageTag("de-DE"), + Locale.forLanguageTag("en-US"), + Locale.forLanguageTag("es-419"), + Locale.forLanguageTag("es-ES"), + Locale.forLanguageTag("fr-FR"), + Locale.forLanguageTag("it-IT"), + Locale.forLanguageTag("pt-BR"), + Locale.forLanguageTag("pt-PT"), + Locale.forLanguageTag("ru-RU"), + Locale.ROOT +) + /** * data classes for browse * TODO make class names more clear/possibly overlapping for now @@ -295,3 +309,19 @@ val NonePlayback = Playback( mapOf(), mapOf(), mapOf(), mapOf(), mapOf(), mapOf(), ) ) + +@Serializable +data class Profile( + @SerialName("avatar") val avatar: String, + @SerialName("email") val email: String, + @SerialName("maturity_rating") val maturityRating: String, + @SerialName("preferred_content_subtitle_language") val preferredContentSubtitleLanguage: String, + @SerialName("username") val username: String, +) +val NoneProfile = Profile( + avatar = "", + email = "", + maturityRating = "", + preferredContentSubtitleLanguage = "", + username = "" +) diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/AccountFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/AccountFragment.kt index 6f3c0b6..55a8f74 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/AccountFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/AccountFragment.kt @@ -6,27 +6,34 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope -import com.afollestad.materialdialogs.MaterialDialog -import com.afollestad.materialdialogs.list.listItemsSingleChoice +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.async import kotlinx.coroutines.launch import org.mosad.teapod.BuildConfig import org.mosad.teapod.R import org.mosad.teapod.databinding.FragmentAccountBinding +import org.mosad.teapod.parser.crunchyroll.Crunchyroll +import org.mosad.teapod.parser.crunchyroll.Profile +import org.mosad.teapod.parser.crunchyroll.supportedLocals import org.mosad.teapod.preferences.EncryptedPreferences import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.ui.activity.main.MainActivity import org.mosad.teapod.ui.components.LoginDialog import org.mosad.teapod.util.DataTypes.Theme import org.mosad.teapod.util.showFragment +import java.util.* class AccountFragment : Fragment() { private lateinit var binding: FragmentAccountBinding + private val profile: Deferred = lifecycleScope.async { + Crunchyroll.profile() + } private val getUriExport = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { @@ -58,7 +65,9 @@ class AccountFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - // TODO reimplement for ct, if possible (maybe account status would be better? (premium)) + binding.textAccountLogin.text = EncryptedPreferences.login + + // TODO reimplement for cr, if possible (maybe account status would be better? (premium)) // load subscription (async) info before anything else binding.textAccountSubscription.text = getString(R.string.account_subscription, getString(R.string.loading)) lifecycleScope.launch { @@ -68,18 +77,23 @@ class AccountFragment : Fragment() { ) } - binding.textAccountLogin.text = EncryptedPreferences.login - binding.textInfoAboutDesc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time)) + // add preferred subtitles + lifecycleScope.launch { + binding.textSettingsContentLanguageDesc.text = Locale.forLanguageTag( + profile.await().preferredContentSubtitleLanguage + ).displayLanguage + } + binding.switchSecondary.isChecked = Preferences.preferSecondary + binding.switchAutoplay.isChecked = Preferences.autoplay binding.textThemeSelected.text = when (Preferences.theme) { Theme.DARK -> getString(R.string.theme_dark) else -> getString(R.string.theme_light) } - binding.switchSecondary.isChecked = Preferences.preferSecondary - binding.switchAutoplay.isChecked = Preferences.autoplay - binding.linearDevSettings.isVisible = Preferences.devSettings + binding.textInfoAboutDesc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time)) + initActions() } @@ -93,12 +107,8 @@ class AccountFragment : Fragment() { //startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(AoDParser.getSubscriptionUrl()))) } - binding.linearTheme.setOnClickListener { - showThemeDialog() - } - - binding.linearInfo.setOnClickListener { - activity?.showFragment(AboutFragment()) + binding.linearSettingsContentLanguage.setOnClickListener { + showContentLanguageSelection() } binding.switchSecondary.setOnClickListener { @@ -109,6 +119,14 @@ class AccountFragment : Fragment() { Preferences.saveAutoplay(requireContext(), binding.switchAutoplay.isChecked) } + binding.linearTheme.setOnClickListener { + showThemeDialog() + } + + binding.linearInfo.setOnClickListener { + activity?.showFragment(AboutFragment()) + } + binding.linearExportData.setOnClickListener { val i = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) @@ -142,24 +160,43 @@ class AccountFragment : Fragment() { } } + private fun showContentLanguageSelection() { + val items = supportedLocals.map { + if (it.displayLanguage.isNotEmpty() && it.displayCountry.isNotEmpty()) { + "${it.displayLanguage} (${it.displayCountry})" + } else if (it.displayCountry.isNotEmpty()) { + it.displayLanguage + } else { + getString(R.string.settings_content_language_none) + } + }.toTypedArray() + + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.settings_content_language) + .setSingleChoiceItems(items, 0){ _, which -> + // TODO + } + .show() + } + private fun showThemeDialog() { - val themes = listOf( + val items = arrayOf( resources.getString(R.string.theme_light), resources.getString(R.string.theme_dark) ) - MaterialDialog(requireContext()).show { - title(R.string.theme) - listItemsSingleChoice(items = themes, initialSelection = Preferences.theme.ordinal) { _, index, _ -> - when(index) { - 0 -> Preferences.saveTheme(context, Theme.LIGHT) - 1 -> Preferences.saveTheme(context, Theme.DARK) - else -> Preferences.saveTheme(context, Theme.DARK) + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.settings_content_language) + .setSingleChoiceItems(items, Preferences.theme.ordinal){ _, which -> + when(which) { + 0 -> Preferences.saveTheme(requireContext(), Theme.LIGHT) + 1 -> Preferences.saveTheme(requireContext(), Theme.DARK) + else -> Preferences.saveTheme(requireContext(), Theme.DARK) } (activity as MainActivity).restart() } - } + .show() } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_baseline_language_24.xml b/app/src/main/res/drawable/ic_baseline_language_24.xml new file mode 100644 index 0000000..0335ca0 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_language_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_account.xml b/app/src/main/res/layout/fragment_account.xml index 54fda09..71df005 100644 --- a/app/src/main/res/layout/fragment_account.xml +++ b/app/src/main/res/layout/fragment_account.xml @@ -146,6 +146,46 @@ android:textSize="16sp" android:textStyle="bold" /> + + + + + + + + + + + + Info Version %1$s (%2$s) Einstellungen + Bevorzuge Inhaltssprache + Englisch + Keine Bevorzuge Japanisch (OmU) Japanisch verwenden, sofern vorhanden Autoplay diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 75966da..8630404 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,12 +46,12 @@ Tap to edit Subscription %1$s Tap to extend - Info - Teapod by @Seil0 - Version %1$s (%2$s) Settings + Preferred content language + English + None Prefer japanese (sub) - Use the japanese, if present + Use japanese, if present Autoplay Play next episode automatically Theme @@ -63,6 +63,9 @@ import data import "My list" from a file imported "My list" successfully + Info + Teapod by @Seil0 + Version %1$s (%2$s) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 11cccbf..fdeacc0 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -36,15 +36,30 @@ @color/textBackgroundDark @color/iconColorDark @color/buttonBackgroundDark + @color/themeSecondaryDark @color/textSecondaryDark - @color/textSecondaryDark + + @style/ThemeOverlay.App.MaterialAlertDialog.Dark @color/controlHighlightDark + + + + +