add support for dedicated subtitle and audio language settings
This commit is contained in:
parent
59a457430e
commit
1a012cba7d
|
@ -12,8 +12,8 @@ android {
|
||||||
applicationId "org.mosad.teapod"
|
applicationId "org.mosad.teapod"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 100991 //01.00.000
|
versionCode 100992 //01.00.000
|
||||||
versionName "1.1.0-beta2"
|
versionName "1.1.0-beta3"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resValue "string", "build_time", buildTime()
|
resValue "string", "build_time", buildTime()
|
||||||
|
|
|
@ -64,10 +64,6 @@ object Crunchyroll {
|
||||||
private var accountID = ""
|
private var accountID = ""
|
||||||
private var externalID = ""
|
private var externalID = ""
|
||||||
|
|
||||||
private var policy = ""
|
|
||||||
private var signature = ""
|
|
||||||
private var keyPairID = ""
|
|
||||||
|
|
||||||
private val browsingCache = hashMapOf<String, BrowseResult>()
|
private val browsingCache = hashMapOf<String, BrowseResult>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,27 +208,10 @@ object Crunchyroll {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic functions: index, account
|
* Basic functions: account
|
||||||
* Needed for other functions to work properly!
|
* 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.
|
* Retrieve the account id and set the corresponding global var.
|
||||||
* The account id is needed for other calls.
|
* The account id is needed for other calls.
|
||||||
|
@ -757,7 +736,7 @@ object Crunchyroll {
|
||||||
*
|
*
|
||||||
* @param languageTag the preferred language as language tag
|
* @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 profileEndpoint = "/accounts/v1/me/profile"
|
||||||
val json = buildJsonObject {
|
val json = buildJsonObject {
|
||||||
put("preferred_content_subtitle_language", languageTag)
|
put("preferred_content_subtitle_language", languageTag)
|
||||||
|
@ -766,6 +745,20 @@ object Crunchyroll {
|
||||||
requestPatch(profileEndpoint, bodyObject = json)
|
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.
|
* Get additional profile (benefits) information for the currently logged in account.
|
||||||
*
|
*
|
||||||
|
|
|
@ -26,17 +26,45 @@ import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
val supportedLocals = listOf(
|
val supportedAudioLocals = listOf(
|
||||||
Locale.forLanguageTag("ar-SA"),
|
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("de-DE"),
|
||||||
Locale.forLanguageTag("en-US"),
|
Locale.forLanguageTag("en-US"),
|
||||||
Locale.forLanguageTag("es-419"),
|
Locale.forLanguageTag("es-419"),
|
||||||
Locale.forLanguageTag("es-ES"),
|
Locale.forLanguageTag("es-ES"),
|
||||||
Locale.forLanguageTag("fr-FR"),
|
Locale.forLanguageTag("fr-FR"),
|
||||||
|
Locale.forLanguageTag("hi-IN"),
|
||||||
Locale.forLanguageTag("it-IT"),
|
Locale.forLanguageTag("it-IT"),
|
||||||
|
Locale.forLanguageTag("ms-MY"),
|
||||||
|
Locale.forLanguageTag("pl-PL"),
|
||||||
Locale.forLanguageTag("pt-BR"),
|
Locale.forLanguageTag("pt-BR"),
|
||||||
Locale.forLanguageTag("pt-PT"),
|
Locale.forLanguageTag("pt-PT"),
|
||||||
Locale.forLanguageTag("ru-RU"),
|
Locale.forLanguageTag("ru-RU"),
|
||||||
|
Locale.forLanguageTag("tr-TR"),
|
||||||
Locale.ROOT
|
Locale.ROOT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,6 @@ object Preferences {
|
||||||
internal set
|
internal set
|
||||||
var preferredSubtitleLocale: Locale = Locale.forLanguageTag("en-US")
|
var preferredSubtitleLocale: Locale = Locale.forLanguageTag("en-US")
|
||||||
internal set
|
internal set
|
||||||
var preferSubbed = false
|
|
||||||
internal set
|
|
||||||
var autoplay = true
|
var autoplay = true
|
||||||
internal set
|
internal set
|
||||||
var devSettings = false
|
var devSettings = false
|
||||||
|
@ -50,15 +48,6 @@ object Preferences {
|
||||||
this.preferredSubtitleLocale = preferredLocale
|
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) {
|
fun saveAutoplay(context: Context, autoplay: Boolean) {
|
||||||
with(getSharedPref(context).edit()) {
|
with(getSharedPref(context).edit()) {
|
||||||
putBoolean(context.getString(R.string.save_key_autoplay), autoplay)
|
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"
|
context.getString(R.string.save_key_preferred_local), "en-US"
|
||||||
) ?: "en-US"
|
) ?: "en-US"
|
||||||
)
|
)
|
||||||
preferSubbed = sharedPref.getBoolean(
|
|
||||||
context.getString(R.string.save_key_prefer_secondary), false
|
|
||||||
)
|
|
||||||
autoplay = sharedPref.getBoolean(
|
autoplay = sharedPref.getBoolean(
|
||||||
context.getString(R.string.save_key_autoplay), true
|
context.getString(R.string.save_key_autoplay), true
|
||||||
)
|
)
|
||||||
|
|
|
@ -173,7 +173,6 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen
|
||||||
private fun initCrunchyroll(): List<Job> {
|
private fun initCrunchyroll(): List<Job> {
|
||||||
val scope = CoroutineScope(Dispatchers.IO + CoroutineName("InitialCrunchyLoading"))
|
val scope = CoroutineScope(Dispatchers.IO + CoroutineName("InitialCrunchyLoading"))
|
||||||
return listOf(
|
return listOf(
|
||||||
scope.launch { Crunchyroll.index() },
|
|
||||||
scope.launch { Crunchyroll.account() },
|
scope.launch { Crunchyroll.account() },
|
||||||
scope.launch {
|
scope.launch {
|
||||||
// update the local preferred content language, since it may have changed
|
// update the local preferred content language, since it may have changed
|
||||||
|
|
|
@ -15,7 +15,8 @@ import org.mosad.teapod.databinding.FragmentAccountBinding
|
||||||
import org.mosad.teapod.parser.crunchyroll.Benefits
|
import org.mosad.teapod.parser.crunchyroll.Benefits
|
||||||
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
|
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
|
||||||
import org.mosad.teapod.parser.crunchyroll.Profile
|
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.EncryptedPreferences
|
||||||
import org.mosad.teapod.preferences.Preferences
|
import org.mosad.teapod.preferences.Preferences
|
||||||
import org.mosad.teapod.ui.activity.main.MainActivity
|
import org.mosad.teapod.ui.activity.main.MainActivity
|
||||||
|
@ -61,11 +62,13 @@ class AccountFragment : Fragment() {
|
||||||
|
|
||||||
// add preferred subtitles
|
// add preferred subtitles
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
binding.textSettingsContentLanguageDesc.text = Locale.forLanguageTag(
|
binding.textSettingsAudioLanguageDesc.text = Locale.forLanguageTag(
|
||||||
|
profile.await().preferredContentAudioLanguage
|
||||||
|
).displayLanguage
|
||||||
|
binding.textSettingsSubtitleLanguageDesc.text = Locale.forLanguageTag(
|
||||||
profile.await().preferredContentSubtitleLanguage
|
profile.await().preferredContentSubtitleLanguage
|
||||||
).displayLanguage
|
).displayLanguage
|
||||||
}
|
}
|
||||||
binding.switchSecondary.isChecked = Preferences.preferSubbed
|
|
||||||
binding.switchAutoplay.isChecked = Preferences.autoplay
|
binding.switchAutoplay.isChecked = Preferences.autoplay
|
||||||
binding.textThemeSelected.text = when (Preferences.theme) {
|
binding.textThemeSelected.text = when (Preferences.theme) {
|
||||||
Theme.SYSTEM -> getString(R.string.theme_system)
|
Theme.SYSTEM -> getString(R.string.theme_system)
|
||||||
|
@ -86,12 +89,12 @@ class AccountFragment : Fragment() {
|
||||||
showLoginDialog()
|
showLoginDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.linearSettingsContentLanguage.setOnClickListener {
|
binding.linearSettingsAudioLanguage.setOnClickListener {
|
||||||
showContentLanguageSelection()
|
showAudioLanguageSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.switchSecondary.setOnClickListener {
|
binding.linearSettingsSubtitleLanguage.setOnClickListener {
|
||||||
Preferences.savePreferSecondary(requireContext(), binding.switchSecondary.isChecked)
|
showSubtitleLanguageSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.switchAutoplay.setOnClickListener {
|
binding.switchAutoplay.setOnClickListener {
|
||||||
|
@ -136,43 +139,86 @@ class AccountFragment : Fragment() {
|
||||||
activity?.let { loginModal.show(it.supportFragmentManager, LoginModalBottomSheet.TAG) }
|
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
|
// 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))
|
it.toDisplayString(getString(R.string.settings_content_language_none))
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
|
||||||
var initialSelection: Int
|
var initialSelection: Int
|
||||||
// profile should be completed here, therefore blocking
|
// profile should be completed here, therefore blocking
|
||||||
runBlocking {
|
runBlocking {
|
||||||
initialSelection = supportedLocals.indexOf(Locale.forLanguageTag(
|
initialSelection = supportedAudioLocals.indexOf(Locale.forLanguageTag(
|
||||||
profile.await().preferredContentSubtitleLanguage))
|
profile.await().preferredContentAudioLanguage))
|
||||||
if (initialSelection < 0) initialSelection = supportedLocals.lastIndex
|
if (initialSelection < 0) initialSelection = supportedAudioLocals.lastIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle(R.string.settings_content_language)
|
.setTitle(R.string.settings_audio_language)
|
||||||
.setSingleChoiceItems(items, initialSelection){ dialog, which ->
|
.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()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
private fun updatePrefContentLanguage(preferredLocale: Locale) {
|
private fun updateAudioLanguage(preferredLocale: Locale) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
Crunchyroll.postPrefSubLanguage(preferredLocale.toLanguageTag())
|
Crunchyroll.setPreferredAudioLanguage(preferredLocale.toLanguageTag())
|
||||||
|
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
// update the local preferred content language
|
// update the local preferred audio language
|
||||||
Preferences.savePreferredSubtitleLocal(requireContext(), preferredLocale)
|
Preferences.savePreferredAudioLocal(requireContext(), preferredLocale)
|
||||||
|
|
||||||
// update profile since the language selection might have changed
|
// update profile since the language selection might have changed
|
||||||
profile = lifecycleScope.async { Crunchyroll.profile() }
|
profile = lifecycleScope.async { Crunchyroll.profile() }
|
||||||
profile.invokeOnCompletion {
|
profile.invokeOnCompletion {
|
||||||
// update language once loading profile is completed
|
// 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
|
profile.getCompleted().preferredContentSubtitleLanguage
|
||||||
).displayLanguage
|
).displayLanguage
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,12 +222,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
||||||
// needs to be blocking, currentPlayback must be present when calling playCurrentMedia()
|
// needs to be blocking, currentPlayback must be present when calling playCurrentMedia()
|
||||||
joinAll(
|
joinAll(
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
currentVersion = if (Preferences.preferSubbed) {
|
currentVersion = currentEpisode.versions?.firstOrNull {
|
||||||
currentEpisode.versions?.first { it.original } ?: NoneVersion
|
it.audioLocale == currentAudioLocale.toLanguageTag()
|
||||||
} else {
|
} ?: currentEpisode.versions?.first() ?: NoneVersion
|
||||||
currentEpisode.versions?.firstOrNull { it.audioLocale == currentAudioLocale.toLanguageTag() }
|
|
||||||
?: currentEpisode.versions?.first() ?: NoneVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the current streams object, if no version is set, use streamsLink
|
// get the current streams object, if no version is set, use streamsLink
|
||||||
currentStreams = if (currentVersion != NoneVersion) {
|
currentStreams = if (currentVersion != NoneVersion) {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,3v9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12 6,14.01 6,16.5S8.01,21 10.5,21c2.31,0 4.2,-1.75 4.45,-4H15V6h4V3h-7z"/>
|
||||||
|
</vector>
|
|
@ -141,7 +141,7 @@
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linear_settings_content_language"
|
android:id="@+id/linear_settings_audio_language"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
@ -151,12 +151,12 @@
|
||||||
android:id="@+id/imageView4"
|
android:id="@+id/imageView4"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/settings_content_language"
|
android:contentDescription="@string/settings_audio_language"
|
||||||
android:minWidth="48dp"
|
android:minWidth="48dp"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:padding="9dp"
|
android:padding="9dp"
|
||||||
android:scaleType="fitXY"
|
android:scaleType="fitXY"
|
||||||
android:src="@drawable/ic_baseline_language_24" />
|
android:src="@drawable/ic_baseline_audiotrack_24" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -167,11 +167,11 @@
|
||||||
android:id="@+id/text_settings_content_language"
|
android:id="@+id/text_settings_content_language"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/settings_content_language"
|
android:text="@string/settings_audio_language"
|
||||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
|
android:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_settings_content_language_desc"
|
android:id="@+id/text_settings_audio_language_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/settings_content_language_desc" />
|
android:text="@string/settings_content_language_desc" />
|
||||||
|
@ -179,67 +179,41 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linear_settings_secondary"
|
android:id="@+id/linear_settings_subtitle_language"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="7dp">
|
android:padding="7dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView3"
|
android:id="@+id/imageView7"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/settings_prefer_subbed"
|
android:contentDescription="@string/settings_subtitle_language"
|
||||||
android:minWidth="48dp"
|
android:minWidth="48dp"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:padding="9dp"
|
android:padding="9dp"
|
||||||
android:scaleType="fitXY"
|
android:scaleType="fitXY"
|
||||||
android:src="@drawable/ic_baseline_subtitles_24" />
|
android:src="@drawable/ic_baseline_subtitles_24" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:id="@+id/linearLayout"
|
android:id="@+id/text_settings_subtitle_language"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:text="@string/settings_subtitle_language"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
|
||||||
app:layout_constraintEnd_toStartOf="@+id/switch_secondary"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_settings_secondary"
|
android:id="@+id/text_settings_subtitle_language_desc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/settings_prefer_subbed"
|
|
||||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_settings_secondary_desc"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:maxLines="2"
|
|
||||||
android:text="@string/settings_prefer_subbed_desc" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
|
||||||
android:id="@+id/switch_secondary"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checked="true"
|
android:text="@string/settings_content_language_desc" />
|
||||||
android:contentDescription="@string/settings_prefer_subbed"
|
</LinearLayout>
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -45,7 +45,8 @@
|
||||||
<string name="info">Info</string>
|
<string name="info">Info</string>
|
||||||
<string name="info_about_desc">Version %1$s (%2$s)</string>
|
<string name="info_about_desc">Version %1$s (%2$s)</string>
|
||||||
<string name="settings">Einstellungen</string>
|
<string name="settings">Einstellungen</string>
|
||||||
<string name="settings_content_language">Bevorzuge Inhaltssprache</string>
|
<string name="settings_audio_language">Audio Sprache</string>
|
||||||
|
<string name="settings_subtitle_language">Untertielsprache</string>
|
||||||
<string name="settings_content_language_desc">Englisch</string>
|
<string name="settings_content_language_desc">Englisch</string>
|
||||||
<string name="settings_content_language_none">Keine</string>
|
<string name="settings_content_language_none">Keine</string>
|
||||||
<string name="settings_prefer_subbed">Bevorzuge OmU</string>
|
<string name="settings_prefer_subbed">Bevorzuge OmU</string>
|
||||||
|
|
|
@ -59,7 +59,8 @@
|
||||||
<string name="account_tier_mega_fan" translatable="false">Mega Fan</string>
|
<string name="account_tier_mega_fan" translatable="false">Mega Fan</string>
|
||||||
<string name="account_tier_ultimate_fan" translatable="false">Ultimate Fan</string>
|
<string name="account_tier_ultimate_fan" translatable="false">Ultimate Fan</string>
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="settings_content_language">Preferred content language</string>
|
<string name="settings_audio_language">Audio language</string>
|
||||||
|
<string name="settings_subtitle_language">Subtitle language</string>
|
||||||
<string name="settings_content_language_desc">English</string>
|
<string name="settings_content_language_desc">English</string>
|
||||||
<string name="settings_content_language_none">None</string>
|
<string name="settings_content_language_none">None</string>
|
||||||
<string name="settings_prefer_subbed">Prefer subbed</string>
|
<string name="settings_prefer_subbed">Prefer subbed</string>
|
||||||
|
|
Loading…
Reference in New Issue