diff --git a/app/build.gradle b/app/build.gradle
index df29021..8db4cfa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,8 +12,8 @@ android {
applicationId "org.mosad.teapod"
minSdkVersion 23
targetSdkVersion 33
- versionCode 100991 //01.00.000
- versionName "1.1.0-beta2"
+ versionCode 100992 //01.00.000
+ versionName "1.1.0-beta3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "build_time", buildTime()
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 b7c1be5..2ddd151 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
@@ -64,10 +64,6 @@ object Crunchyroll {
private var accountID = ""
private var externalID = ""
- private var policy = ""
- private var signature = ""
- private var keyPairID = ""
-
private val browsingCache = hashMapOf()
/**
@@ -212,27 +208,10 @@ object Crunchyroll {
}
/**
- * Basic functions: index, account
+ * Basic functions: account
* Needed for other functions to work properly!
*/
- /**
- * Retrieve the identifiers necessary for streaming. If the identifiers are
- * retrieved, set the corresponding global var. The identifiers are valid for 24h.
- */
- suspend fun index() {
- val indexEndpoint = "/index/v2"
-
- val index: Index = requestGet(indexEndpoint)
- policy = index.cms.policy
- signature = index.cms.signature
- keyPairID = index.cms.keyPairId
-
- Log.i(TAG, "Policy : $policy")
- Log.i(TAG, "Signature : $signature")
- Log.i(TAG, "Key Pair ID : $keyPairID")
- }
-
/**
* Retrieve the account id and set the corresponding global var.
* The account id is needed for other calls.
@@ -757,7 +736,7 @@ object Crunchyroll {
*
* @param languageTag the preferred language as language tag
*/
- suspend fun postPrefSubLanguage(languageTag: String) {
+ suspend fun setPreferredSubtitleLanguage(languageTag: String) {
val profileEndpoint = "/accounts/v1/me/profile"
val json = buildJsonObject {
put("preferred_content_subtitle_language", languageTag)
@@ -766,6 +745,20 @@ object Crunchyroll {
requestPatch(profileEndpoint, bodyObject = json)
}
+ /**
+ * Patch the preferred content audio language.
+ *
+ * @param languageTag the preferred language as language tag
+ */
+ suspend fun setPreferredAudioLanguage(languageTag: String) {
+ val profileEndpoint = "/accounts/v1/me/profile"
+ val json = buildJsonObject {
+ put("preferred_content_audio_language", languageTag)
+ }
+
+ requestPatch(profileEndpoint, bodyObject = json)
+ }
+
/**
* Get additional profile (benefits) information for the currently logged in account.
*
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 6cc85c4..2222e0c 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
@@ -26,17 +26,45 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.util.Locale
-val supportedLocals = listOf(
+val supportedAudioLocals = listOf(
Locale.forLanguageTag("ar-SA"),
+ Locale.forLanguageTag("ca-ES"),
+ Locale.forLanguageTag("de-DE"),
+ Locale.forLanguageTag("en-US"),
+ Locale.forLanguageTag("en-IN"),
+ Locale.forLanguageTag("es-419"),
+ Locale.forLanguageTag("es-ES"),
+ Locale.forLanguageTag("fr-FR"),
+ Locale.forLanguageTag("hi-IN"),
+ Locale.forLanguageTag("it-IT"),
+ Locale.forLanguageTag("ko-KR"),
+ Locale.forLanguageTag("pl-PL"),
+ Locale.forLanguageTag("pt-BR"),
+ Locale.forLanguageTag("pt-PT"),
+ Locale.forLanguageTag("ru-RU"),
+ Locale.forLanguageTag("ta-IN"),
+ Locale.forLanguageTag("th-TH"),
+ Locale.forLanguageTag("zh-CN"),
+ Locale.forLanguageTag("zh-TW"),
+ Locale.ROOT
+)
+
+val supportedSubtitleLocals = listOf(
+ Locale.forLanguageTag("ar-SA"),
+ Locale.forLanguageTag("ca-ES"),
Locale.forLanguageTag("de-DE"),
Locale.forLanguageTag("en-US"),
Locale.forLanguageTag("es-419"),
Locale.forLanguageTag("es-ES"),
Locale.forLanguageTag("fr-FR"),
+ Locale.forLanguageTag("hi-IN"),
Locale.forLanguageTag("it-IT"),
+ Locale.forLanguageTag("ms-MY"),
+ Locale.forLanguageTag("pl-PL"),
Locale.forLanguageTag("pt-BR"),
Locale.forLanguageTag("pt-PT"),
Locale.forLanguageTag("ru-RU"),
+ Locale.forLanguageTag("tr-TR"),
Locale.ROOT
)
diff --git a/app/src/main/java/org/mosad/teapod/preferences/Preferences.kt b/app/src/main/java/org/mosad/teapod/preferences/Preferences.kt
index 2bb3963..91f0f21 100644
--- a/app/src/main/java/org/mosad/teapod/preferences/Preferences.kt
+++ b/app/src/main/java/org/mosad/teapod/preferences/Preferences.kt
@@ -12,8 +12,6 @@ object Preferences {
internal set
var preferredSubtitleLocale: Locale = Locale.forLanguageTag("en-US")
internal set
- var preferSubbed = false
- internal set
var autoplay = true
internal set
var devSettings = false
@@ -50,15 +48,6 @@ object Preferences {
this.preferredSubtitleLocale = preferredLocale
}
- fun savePreferSecondary(context: Context, preferSubbed: Boolean) {
- with(getSharedPref(context).edit()) {
- putBoolean(context.getString(R.string.save_key_prefer_secondary), preferSubbed)
- apply()
- }
-
- this.preferSubbed = preferSubbed
- }
-
fun saveAutoplay(context: Context, autoplay: Boolean) {
with(getSharedPref(context).edit()) {
putBoolean(context.getString(R.string.save_key_autoplay), autoplay)
@@ -111,9 +100,6 @@ object Preferences {
context.getString(R.string.save_key_preferred_local), "en-US"
) ?: "en-US"
)
- preferSubbed = sharedPref.getBoolean(
- context.getString(R.string.save_key_prefer_secondary), false
- )
autoplay = sharedPref.getBoolean(
context.getString(R.string.save_key_autoplay), true
)
diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/MainActivity.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/MainActivity.kt
index 0144b60..1185e8c 100644
--- a/app/src/main/java/org/mosad/teapod/ui/activity/main/MainActivity.kt
+++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/MainActivity.kt
@@ -173,7 +173,6 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen
private fun initCrunchyroll(): List {
val scope = CoroutineScope(Dispatchers.IO + CoroutineName("InitialCrunchyLoading"))
return listOf(
- scope.launch { Crunchyroll.index() },
scope.launch { Crunchyroll.account() },
scope.launch {
// update the local preferred content language, since it may have changed
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 e04866a..f02e6c2 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
@@ -15,7 +15,8 @@ import org.mosad.teapod.databinding.FragmentAccountBinding
import org.mosad.teapod.parser.crunchyroll.Benefits
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.parser.crunchyroll.supportedAudioLocals
+import org.mosad.teapod.parser.crunchyroll.supportedSubtitleLocals
import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.activity.main.MainActivity
@@ -61,11 +62,13 @@ class AccountFragment : Fragment() {
// add preferred subtitles
lifecycleScope.launch {
- binding.textSettingsContentLanguageDesc.text = Locale.forLanguageTag(
+ binding.textSettingsAudioLanguageDesc.text = Locale.forLanguageTag(
+ profile.await().preferredContentAudioLanguage
+ ).displayLanguage
+ binding.textSettingsSubtitleLanguageDesc.text = Locale.forLanguageTag(
profile.await().preferredContentSubtitleLanguage
).displayLanguage
}
- binding.switchSecondary.isChecked = Preferences.preferSubbed
binding.switchAutoplay.isChecked = Preferences.autoplay
binding.textThemeSelected.text = when (Preferences.theme) {
Theme.SYSTEM -> getString(R.string.theme_system)
@@ -86,12 +89,12 @@ class AccountFragment : Fragment() {
showLoginDialog()
}
- binding.linearSettingsContentLanguage.setOnClickListener {
- showContentLanguageSelection()
+ binding.linearSettingsAudioLanguage.setOnClickListener {
+ showAudioLanguageSelection()
}
- binding.switchSecondary.setOnClickListener {
- Preferences.savePreferSecondary(requireContext(), binding.switchSecondary.isChecked)
+ binding.linearSettingsSubtitleLanguage.setOnClickListener {
+ showSubtitleLanguageSelection()
}
binding.switchAutoplay.setOnClickListener {
@@ -136,43 +139,86 @@ class AccountFragment : Fragment() {
activity?.let { loginModal.show(it.supportFragmentManager, LoginModalBottomSheet.TAG) }
}
- private fun showContentLanguageSelection() {
+ private fun showAudioLanguageSelection() {
// we should be able to use the index of supportedLocals for language selection, items is GUI only
- val items = supportedLocals.map {
+ val items = supportedAudioLocals.map {
it.toDisplayString(getString(R.string.settings_content_language_none))
}.toTypedArray()
var initialSelection: Int
// profile should be completed here, therefore blocking
runBlocking {
- initialSelection = supportedLocals.indexOf(Locale.forLanguageTag(
- profile.await().preferredContentSubtitleLanguage))
- if (initialSelection < 0) initialSelection = supportedLocals.lastIndex
+ initialSelection = supportedAudioLocals.indexOf(Locale.forLanguageTag(
+ profile.await().preferredContentAudioLanguage))
+ if (initialSelection < 0) initialSelection = supportedAudioLocals.lastIndex
}
MaterialAlertDialogBuilder(requireContext())
- .setTitle(R.string.settings_content_language)
+ .setTitle(R.string.settings_audio_language)
.setSingleChoiceItems(items, initialSelection){ dialog, which ->
- updatePrefContentLanguage(supportedLocals[which])
+ updateAudioLanguage(supportedAudioLocals[which])
+ dialog.dismiss()
+ }
+ .show()
+ }
+
+ private fun showSubtitleLanguageSelection() {
+ // we should be able to use the index of supportedLocals for language selection, items is GUI only
+ val items = supportedSubtitleLocals.map {
+ it.toDisplayString(getString(R.string.settings_content_language_none))
+ }.toTypedArray()
+
+ var initialSelection: Int
+ // profile should be completed here, therefore blocking
+ runBlocking {
+ initialSelection = supportedSubtitleLocals.indexOf(Locale.forLanguageTag(
+ profile.await().preferredContentSubtitleLanguage))
+ if (initialSelection < 0) initialSelection = supportedSubtitleLocals.lastIndex
+ }
+
+ MaterialAlertDialogBuilder(requireContext())
+ .setTitle(R.string.settings_audio_language)
+ .setSingleChoiceItems(items, initialSelection){ dialog, which ->
+ updateSubtitleLanguage(supportedSubtitleLocals[which])
dialog.dismiss()
}
.show()
}
@OptIn(ExperimentalCoroutinesApi::class)
- private fun updatePrefContentLanguage(preferredLocale: Locale) {
+ private fun updateAudioLanguage(preferredLocale: Locale) {
lifecycleScope.launch {
- Crunchyroll.postPrefSubLanguage(preferredLocale.toLanguageTag())
+ Crunchyroll.setPreferredAudioLanguage(preferredLocale.toLanguageTag())
}.invokeOnCompletion {
- // update the local preferred content language
- Preferences.savePreferredSubtitleLocal(requireContext(), preferredLocale)
+ // update the local preferred audio language
+ Preferences.savePreferredAudioLocal(requireContext(), preferredLocale)
// update profile since the language selection might have changed
profile = lifecycleScope.async { Crunchyroll.profile() }
profile.invokeOnCompletion {
// update language once loading profile is completed
- binding.textSettingsContentLanguageDesc.text = Locale.forLanguageTag(
+ binding.textSettingsAudioLanguageDesc.text = Locale.forLanguageTag(
+ profile.getCompleted().preferredContentAudioLanguage
+ ).displayLanguage
+ }
+ }
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ private fun updateSubtitleLanguage(preferredLocal: Locale) {
+ lifecycleScope.launch {
+ Crunchyroll.setPreferredSubtitleLanguage(preferredLocal.toLanguageTag())
+
+ }.invokeOnCompletion {
+ // update the local preferred subtitle language
+ Preferences.savePreferredSubtitleLocal(requireContext(), preferredLocal)
+
+ // update profile since the language selection might have changed
+ profile = lifecycleScope.async { Crunchyroll.profile() }
+ profile.invokeOnCompletion {
+ // update language once loading profile is completed
+ binding.textSettingsAudioLanguageDesc.text = Locale.forLanguageTag(
profile.getCompleted().preferredContentSubtitleLanguage
).displayLanguage
}
diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt b/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt
index 24bafa0..6ade794 100644
--- a/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt
+++ b/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt
@@ -222,12 +222,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
// needs to be blocking, currentPlayback must be present when calling playCurrentMedia()
joinAll(
viewModelScope.launch(Dispatchers.IO) {
- currentVersion = if (Preferences.preferSubbed) {
- currentEpisode.versions?.first { it.original } ?: NoneVersion
- } else {
- currentEpisode.versions?.firstOrNull { it.audioLocale == currentAudioLocale.toLanguageTag() }
- ?: currentEpisode.versions?.first() ?: NoneVersion
- }
+ currentVersion = currentEpisode.versions?.firstOrNull {
+ it.audioLocale == currentAudioLocale.toLanguageTag()
+ } ?: currentEpisode.versions?.first() ?: NoneVersion
// get the current streams object, if no version is set, use streamsLink
currentStreams = if (currentVersion != NoneVersion) {
diff --git a/app/src/main/res/drawable/ic_baseline_audiotrack_24.xml b/app/src/main/res/drawable/ic_baseline_audiotrack_24.xml
new file mode 100644
index 0000000..9ba72ee
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_audiotrack_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/fragment_account.xml b/app/src/main/res/layout/fragment_account.xml
index 1422a5f..277a5bb 100644
--- a/app/src/main/res/layout/fragment_account.xml
+++ b/app/src/main/res/layout/fragment_account.xml
@@ -141,7 +141,7 @@
android:textStyle="bold" />
+ android:src="@drawable/ic_baseline_audiotrack_24" />
@@ -179,67 +179,41 @@
-
+ android:layout_height="match_parent"
+ android:orientation="vertical">
-
+ android:text="@string/settings_subtitle_language"
+ android:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
-
-
-
-
-
-
-
-
-
+ android:text="@string/settings_content_language_desc" />
+
Info
Version %1$s (%2$s)
Einstellungen
- Bevorzuge Inhaltssprache
+ Audio Sprache
+ Untertielsprache
Englisch
Keine
Bevorzuge OmU
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a6896bb..c995ffb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -59,7 +59,8 @@
Mega Fan
Ultimate Fan
Settings
- Preferred content language
+ Audio language
+ Subtitle language
English
None
Prefer subbed