Fix multiple language related issues
* fix playback for other shows with no language set in cr API * fix selection of preferred season for languages other than german * add support for all content languages to TMDBApiController * preferSecondary is now preferSubbed, this describes the function more clearly * remove jsoup, not used anymore
This commit is contained in:
parent
75204e522d
commit
0797e9fa3d
|
@ -59,14 +59,13 @@ dependencies {
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
implementation 'com.google.code.gson:gson:2.8.8'
|
implementation 'com.google.code.gson:gson:2.8.8' // TODO remove, still used by metadb
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0'
|
implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.0'
|
implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-dash:2.15.0'
|
implementation 'com.google.android.exoplayer:exoplayer-dash:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.0'
|
implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.0'
|
||||||
implementation 'com.google.android.exoplayer:extension-mediasession:2.15.0'
|
implementation 'com.google.android.exoplayer:extension-mediasession:2.15.0'
|
||||||
|
|
||||||
implementation 'org.jsoup:jsoup:1.14.2'
|
|
||||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||||
implementation 'com.afollestad.material-dialogs:core:3.3.0'
|
implementation 'com.afollestad.material-dialogs:core:3.3.0'
|
||||||
|
|
|
@ -224,22 +224,13 @@ data class Seasons(
|
||||||
@SerialName("items") val items: List<Season>
|
@SerialName("items") val items: List<Season>
|
||||||
) {
|
) {
|
||||||
fun getPreferredSeason(local: Locale): Season {
|
fun getPreferredSeason(local: Locale): Season {
|
||||||
|
return items.firstOrNull { season ->
|
||||||
// try to get the the first seasons which matches the preferred local
|
// try to get the the first seasons which matches the preferred local
|
||||||
items.forEach { season ->
|
season.slugTitle.endsWith("${local.displayLanguage}-dub", true)
|
||||||
if (season.title.startsWith("(${local.language})", true)) {
|
} ?: items.firstOrNull { season ->
|
||||||
return season
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there is no season with the preferred local, try to find a subbed season
|
// if there is no season with the preferred local, try to find a subbed season
|
||||||
items.forEach { season ->
|
season.isSubbed
|
||||||
if (season.isSubbed) {
|
} ?: items.first() // if no preferred language and no sub, use the first season
|
||||||
return season
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there is no preferred language season and no sub, use the first season
|
|
||||||
return items.first()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +238,7 @@ data class Seasons(
|
||||||
data class Season(
|
data class Season(
|
||||||
@SerialName("id") val id: String,
|
@SerialName("id") val id: String,
|
||||||
@SerialName("title") val title: String,
|
@SerialName("title") val title: String,
|
||||||
|
@SerialName("slug_title") val slugTitle: String,
|
||||||
@SerialName("series_id") val seriesId: String,
|
@SerialName("series_id") val seriesId: String,
|
||||||
@SerialName("season_number") val seasonNumber: Int,
|
@SerialName("season_number") val seasonNumber: Int,
|
||||||
@SerialName("is_subbed") val isSubbed: Boolean,
|
@SerialName("is_subbed") val isSubbed: Boolean,
|
||||||
|
@ -254,7 +246,7 @@ data class Season(
|
||||||
)
|
)
|
||||||
|
|
||||||
val NoneSeasons = Seasons(0, emptyList())
|
val NoneSeasons = Seasons(0, emptyList())
|
||||||
val NoneSeason = Season("", "", "", 0, isSubbed = false, isDubbed = false)
|
val NoneSeason = Season("", "", "", "", 0, isSubbed = false, isDubbed = false)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,10 +8,10 @@ import java.util.*
|
||||||
|
|
||||||
object Preferences {
|
object Preferences {
|
||||||
|
|
||||||
var preferSecondary = false
|
|
||||||
internal set
|
|
||||||
var preferredLocale: Locale = Locale.forLanguageTag("en-US") // TODO this should be saved (potential offline usage) but fetched on start
|
var preferredLocale: Locale = Locale.forLanguageTag("en-US") // TODO this should be saved (potential offline usage) but fetched on start
|
||||||
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
|
||||||
|
@ -26,15 +26,6 @@ object Preferences {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun savePreferSecondary(context: Context, preferSecondary: Boolean) {
|
|
||||||
with(getSharedPref(context).edit()) {
|
|
||||||
putBoolean(context.getString(R.string.save_key_prefer_secondary), preferSecondary)
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.preferSecondary = preferSecondary
|
|
||||||
}
|
|
||||||
|
|
||||||
fun savePreferredLocal(context: Context, preferredLocale: Locale) {
|
fun savePreferredLocal(context: Context, preferredLocale: Locale) {
|
||||||
with(getSharedPref(context).edit()) {
|
with(getSharedPref(context).edit()) {
|
||||||
putString(context.getString(R.string.save_key_preferred_local), preferredLocale.toLanguageTag())
|
putString(context.getString(R.string.save_key_preferred_local), preferredLocale.toLanguageTag())
|
||||||
|
@ -44,6 +35,15 @@ object Preferences {
|
||||||
this.preferredLocale = preferredLocale
|
this.preferredLocale = 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)
|
||||||
|
@ -77,14 +77,14 @@ object Preferences {
|
||||||
fun load(context: Context) {
|
fun load(context: Context) {
|
||||||
val sharedPref = getSharedPref(context)
|
val sharedPref = getSharedPref(context)
|
||||||
|
|
||||||
preferSecondary = sharedPref.getBoolean(
|
|
||||||
context.getString(R.string.save_key_prefer_secondary), false
|
|
||||||
)
|
|
||||||
preferredLocale = Locale.forLanguageTag(
|
preferredLocale = Locale.forLanguageTag(
|
||||||
sharedPref.getString(
|
sharedPref.getString(
|
||||||
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
|
||||||
)
|
)
|
||||||
|
|
|
@ -113,9 +113,9 @@ class AboutFragment : Fragment() {
|
||||||
"https://github.com/google/material-design-icons", License.APACHE2),
|
"https://github.com/google/material-design-icons", License.APACHE2),
|
||||||
ThirdPartyComponent("Material Dialogs", "", "Aidan Follestad",
|
ThirdPartyComponent("Material Dialogs", "", "Aidan Follestad",
|
||||||
"https://github.com/afollestad/material-dialogs", License.APACHE2),
|
"https://github.com/afollestad/material-dialogs", License.APACHE2),
|
||||||
ThirdPartyComponent("Jsoup", "2009 - 2020", "Jonathan Hedley",
|
ThirdPartyComponent("Ktor", "2014-2021", "JetBrains s.r.o and contributors",
|
||||||
"https://jsoup.org/", License.MIT),
|
"https://ktor.io/", License.APACHE2),
|
||||||
ThirdPartyComponent("kotlinx.coroutines", "2016 - 2019", "JetBrains",
|
ThirdPartyComponent("kotlinx.coroutines", "2016-2021", "JetBrains s.r.o",
|
||||||
"https://github.com/Kotlin/kotlinx.coroutines", License.APACHE2),
|
"https://github.com/Kotlin/kotlinx.coroutines", License.APACHE2),
|
||||||
ThirdPartyComponent("Glide", "2014", "Google Inc.",
|
ThirdPartyComponent("Glide", "2014", "Google Inc.",
|
||||||
"https://github.com/bumptech/glide", License.BSD2),
|
"https://github.com/bumptech/glide", License.BSD2),
|
||||||
|
|
|
@ -85,7 +85,7 @@ class AccountFragment : Fragment() {
|
||||||
profile.await().preferredContentSubtitleLanguage
|
profile.await().preferredContentSubtitleLanguage
|
||||||
).displayLanguage
|
).displayLanguage
|
||||||
}
|
}
|
||||||
binding.switchSecondary.isChecked = Preferences.preferSecondary
|
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.DARK -> getString(R.string.theme_dark)
|
Theme.DARK -> getString(R.string.theme_dark)
|
||||||
|
|
|
@ -51,9 +51,6 @@ class MediaFragment(private val mediaIdStr: String) : Fragment() {
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
println("onViewCreated")
|
|
||||||
|
|
||||||
binding.frameLoading.visibility = View.VISIBLE
|
binding.frameLoading.visibility = View.VISIBLE
|
||||||
|
|
||||||
// tab layout and pager
|
// tab layout and pager
|
||||||
|
|
|
@ -47,8 +47,6 @@ import org.mosad.teapod.parser.crunchyroll.NoneEpisodes
|
||||||
import org.mosad.teapod.parser.crunchyroll.NonePlayback
|
import org.mosad.teapod.parser.crunchyroll.NonePlayback
|
||||||
import org.mosad.teapod.preferences.Preferences
|
import org.mosad.teapod.preferences.Preferences
|
||||||
import org.mosad.teapod.util.EpisodeMeta
|
import org.mosad.teapod.util.EpisodeMeta
|
||||||
import org.mosad.teapod.util.Meta
|
|
||||||
import org.mosad.teapod.util.TVShowMeta
|
|
||||||
import org.mosad.teapod.util.tmdb.TMDBTVSeason
|
import org.mosad.teapod.util.tmdb.TMDBTVSeason
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -64,12 +62,12 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
||||||
private val mediaSession = MediaSessionCompat(application, "TEAPOD_PLAYER_SESSION")
|
private val mediaSession = MediaSessionCompat(application, "TEAPOD_PLAYER_SESSION")
|
||||||
|
|
||||||
val currentEpisodeChangedListener = ArrayList<() -> Unit>()
|
val currentEpisodeChangedListener = ArrayList<() -> Unit>()
|
||||||
private val preferredLanguage = if (Preferences.preferSecondary) Locale.JAPANESE else Locale.GERMAN
|
|
||||||
private var currentPlayhead: Long = 0
|
private var currentPlayhead: Long = 0
|
||||||
|
|
||||||
// tmdb/meta data TODO currently not implemented for cr
|
// tmdb/meta data
|
||||||
var mediaMeta: Meta? = null
|
// TODO meta data currently not implemented for cr
|
||||||
internal set
|
// var mediaMeta: Meta? = null
|
||||||
|
// internal set
|
||||||
var tmdbTVSeason: TMDBTVSeason? =null
|
var tmdbTVSeason: TMDBTVSeason? =null
|
||||||
internal set
|
internal set
|
||||||
var currentEpisodeMeta: EpisodeMeta? = null
|
var currentEpisodeMeta: EpisodeMeta? = null
|
||||||
|
@ -224,8 +222,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
||||||
currentPlayback.streams.adaptive_hls[fallbackLocal.toLanguageTag()]?.url
|
currentPlayback.streams.adaptive_hls[fallbackLocal.toLanguageTag()]?.url
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
// if no language tag is present use the first entry
|
||||||
currentLanguage = Locale.ROOT
|
currentLanguage = Locale.ROOT
|
||||||
currentPlayback.streams.adaptive_hls[Locale.ROOT.toLanguageTag()]?.url ?: ""
|
currentPlayback.streams.adaptive_hls.entries.first().value.url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println("stream url: $url")
|
println("stream url: $url")
|
||||||
|
@ -267,25 +266,25 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
||||||
return episodes.items.lastOrNull()?.id == currentEpisode.id
|
return episodes.items.lastOrNull()?.id == currentEpisode.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEpisodeMetaByAoDMediaId(aodMediaId: Int): EpisodeMeta? {
|
|
||||||
val meta = mediaMeta
|
|
||||||
return if (meta is TVShowMeta) {
|
|
||||||
meta.episodes.firstOrNull { it.aodMediaId == aodMediaId }
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO reimplement for cr
|
// TODO reimplement for cr
|
||||||
private suspend fun loadMediaMeta(aodId: Int): Meta? {
|
// fun getEpisodeMetaByAoDMediaId(aodMediaId: Int): EpisodeMeta? {
|
||||||
|
// val meta = mediaMeta
|
||||||
|
// return if (meta is TVShowMeta) {
|
||||||
|
// meta.episodes.firstOrNull { it.aodMediaId == aodMediaId }
|
||||||
|
// } else {
|
||||||
|
// null
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private suspend fun loadMediaMeta(aodId: Int): Meta? {
|
||||||
// return if (media.type == DataTypes.MediaType.TVSHOW) {
|
// return if (media.type == DataTypes.MediaType.TVSHOW) {
|
||||||
// MetaDBController().getTVShowMetadata(aodId)
|
// MetaDBController().getTVShowMetadata(aodId)
|
||||||
// } else {
|
// } else {
|
||||||
// null
|
// null
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
return null
|
// return null
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the playhead of the current episode, if currentPosition > 1000ms.
|
* Update the playhead of the current episode, if currentPosition > 1000ms.
|
||||||
|
|
|
@ -34,6 +34,7 @@ import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.invoke
|
import kotlinx.coroutines.invoke
|
||||||
import kotlinx.serialization.SerializationException
|
import kotlinx.serialization.SerializationException
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import org.mosad.teapod.preferences.Preferences
|
||||||
import org.mosad.teapod.util.concatenate
|
import org.mosad.teapod.util.concatenate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +55,6 @@ class TMDBApiController {
|
||||||
|
|
||||||
private val apiUrl = "https://api.themoviedb.org/3"
|
private val apiUrl = "https://api.themoviedb.org/3"
|
||||||
private val apiKey = "de959cf9c07a08b5ca7cb51cda9a40c2"
|
private val apiKey = "de959cf9c07a08b5ca7cb51cda9a40c2"
|
||||||
private val language = "de"
|
|
||||||
|
|
||||||
companion object{
|
companion object{
|
||||||
const val imageUrl = "https://image.tmdb.org/t/p/w500"
|
const val imageUrl = "https://image.tmdb.org/t/p/w500"
|
||||||
|
@ -65,7 +65,10 @@ class TMDBApiController {
|
||||||
parameters: List<Pair<String, Any?>> = emptyList()
|
parameters: List<Pair<String, Any?>> = emptyList()
|
||||||
): T = coroutineScope {
|
): T = coroutineScope {
|
||||||
val path = "$apiUrl$endpoint"
|
val path = "$apiUrl$endpoint"
|
||||||
val params = concatenate(listOf("api_key" to apiKey, "language" to language), parameters)
|
val params = concatenate(
|
||||||
|
listOf("api_key" to apiKey, "language" to Preferences.preferredLocale.language),
|
||||||
|
parameters
|
||||||
|
)
|
||||||
|
|
||||||
// TODO handle FileNotFoundException
|
// TODO handle FileNotFoundException
|
||||||
return@coroutineScope (Dispatchers.IO) {
|
return@coroutineScope (Dispatchers.IO) {
|
||||||
|
|
|
@ -198,7 +198,7 @@
|
||||||
android:id="@+id/imageView3"
|
android:id="@+id/imageView3"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/settings_secondary"
|
android:contentDescription="@string/settings_prefer_subbed"
|
||||||
android:minWidth="48dp"
|
android:minWidth="48dp"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
android:padding="9dp"
|
android:padding="9dp"
|
||||||
|
@ -225,7 +225,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/settings_secondary"
|
android:text="@string/settings_prefer_subbed"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -234,7 +234,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:maxLines="2"
|
android:maxLines="2"
|
||||||
android:text="@string/settings_secondary_desc"
|
android:text="@string/settings_prefer_subbed_desc"
|
||||||
android:textColor="?textSecondary" />
|
android:textColor="?textSecondary" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
<string name="settings_content_language">Bevorzuge Inhaltssprache</string>
|
<string name="settings_content_language">Bevorzuge Inhaltssprache</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_secondary">Bevorzuge Japanisch (OmU)</string>
|
<string name="settings_prefer_subbed">Bevorzuge OmU</string>
|
||||||
<string name="settings_secondary_desc">Japanisch verwenden, sofern vorhanden</string>
|
<string name="settings_prefer_subbed_desc">Original Sprache verwenden, sofern vorhanden</string>
|
||||||
<string name="settings_autoplay">Autoplay</string>
|
<string name="settings_autoplay">Autoplay</string>
|
||||||
<string name="settings_autoplay_desc">Nächste Episode automatisch abspielen</string>
|
<string name="settings_autoplay_desc">Nächste Episode automatisch abspielen</string>
|
||||||
<string name="theme">Design</string>
|
<string name="theme">Design</string>
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<string name="component_poster_desc" translatable="false">episode poster</string>
|
<string name="component_poster_desc" translatable="false">episode poster</string>
|
||||||
<string name="component_watched_desc" translatable="false">already watched</string>
|
<string name="component_watched_desc" translatable="false">already watched</string>
|
||||||
|
|
||||||
<!-- settings fragment -->
|
<!-- account fragment -->
|
||||||
<string name="account">Account</string>
|
<string name="account">Account</string>
|
||||||
<string name="account_login_ex" translatable="false">user@example.com</string>
|
<string name="account_login_ex" translatable="false">user@example.com</string>
|
||||||
<string name="account_login_desc">Tap to edit</string>
|
<string name="account_login_desc">Tap to edit</string>
|
||||||
|
@ -50,8 +50,8 @@
|
||||||
<string name="settings_content_language">Preferred content language</string>
|
<string name="settings_content_language">Preferred content 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_secondary">Prefer japanese (sub)</string>
|
<string name="settings_prefer_subbed">Prefer subbed</string>
|
||||||
<string name="settings_secondary_desc">Use japanese, if present</string>
|
<string name="settings_prefer_subbed_desc">Use original language, if present</string>
|
||||||
<string name="settings_autoplay">Autoplay</string>
|
<string name="settings_autoplay">Autoplay</string>
|
||||||
<string name="settings_autoplay_desc">Play next episode automatically</string>
|
<string name="settings_autoplay_desc">Play next episode automatically</string>
|
||||||
<string name="theme">Theme</string>
|
<string name="theme">Theme</string>
|
||||||
|
@ -131,6 +131,7 @@
|
||||||
<string name="preference_file_key" translatable="false">org.mosad.teapod.preferences</string>
|
<string name="preference_file_key" translatable="false">org.mosad.teapod.preferences</string>
|
||||||
<string name="save_key_user_login" translatable="false">org.mosad.teapod.user_login</string>
|
<string name="save_key_user_login" translatable="false">org.mosad.teapod.user_login</string>
|
||||||
<string name="save_key_user_password" translatable="false">org.mosad.teapod.user_password</string>
|
<string name="save_key_user_password" translatable="false">org.mosad.teapod.user_password</string>
|
||||||
|
<!-- for legacy reasons the prefer subbed key is called prefer_secondary-->
|
||||||
<string name="save_key_prefer_secondary" translatable="false">org.mosad.teapod.prefer_secondary</string>
|
<string name="save_key_prefer_secondary" translatable="false">org.mosad.teapod.prefer_secondary</string>
|
||||||
<string name="save_key_preferred_local" translatable="false">org.mosad.teapod.preferred_local</string>
|
<string name="save_key_preferred_local" translatable="false">org.mosad.teapod.preferred_local</string>
|
||||||
<string name="save_key_autoplay" translatable="false">org.mosad.teapod.autoplay</string>
|
<string name="save_key_autoplay" translatable="false">org.mosad.teapod.autoplay</string>
|
||||||
|
|
Loading…
Reference in New Issue