add option to prefer the secondary stream, if present

This commit is contained in:
Jannik 2020-10-23 11:28:47 +02:00
parent f0ed6aa379
commit c138ab4587
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
8 changed files with 164 additions and 23 deletions

View File

@ -35,6 +35,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.EncryptedPreferences import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.components.LoginDialog import org.mosad.teapod.ui.components.LoginDialog
import org.mosad.teapod.ui.fragments.* import org.mosad.teapod.ui.fragments.*
import org.mosad.teapod.util.StorageController import org.mosad.teapod.util.StorageController
@ -104,7 +105,9 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
private fun load() { private fun load() {
// running login and list in parallel does not bring any speed improvements // running login and list in parallel does not bring any speed improvements
val time = measureTimeMillis { val time = measureTimeMillis {
// make sure credentials are set Preferences.load(this)
// make sure credentials are set
EncryptedPreferences.readCredentials(this) EncryptedPreferences.readCredentials(this)
if (EncryptedPreferences.password.isEmpty()) { if (EncryptedPreferences.password.isEmpty()) {
showLoginDialog(true) showLoginDialog(true)

View File

@ -1,22 +1,40 @@
package org.mosad.teapod.preferences package org.mosad.teapod.preferences
import android.content.Context
import org.mosad.teapod.R
object Preferences { object Preferences {
var login = "" var preferSecondary = false
internal set
var password = ""
internal set internal set
fun savePreferSecondary(context: Context, preferSecondary: Boolean) {
val sharedPref = context.getSharedPreferences(
context.getString(R.string.preference_file_key),
Context.MODE_PRIVATE
)
fun saveCredentials(login: String, password: String) { with(sharedPref.edit()) {
this.login = login putBoolean(context.getString(R.string.save_key_prefer_secondary), preferSecondary)
this.password = password apply()
}
// TODO save this.preferSecondary = preferSecondary
} }
fun load() { /**
// TODO * initially load the stored values
*/
fun load(context: Context) {
val sharedPref = context.getSharedPreferences(
context.getString(R.string.preference_file_key),
Context.MODE_PRIVATE
)
preferSecondary = sharedPref.getBoolean(
context.getString(R.string.save_key_prefer_secondary), false
)
} }
} }

View File

@ -13,6 +13,7 @@ import org.mosad.teapod.BuildConfig
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.EncryptedPreferences import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.components.LoginDialog import org.mosad.teapod.ui.components.LoginDialog
class AccountFragment : Fragment() { class AccountFragment : Fragment() {
@ -26,6 +27,7 @@ class AccountFragment : Fragment() {
text_account_login.text = EncryptedPreferences.login text_account_login.text = EncryptedPreferences.login
text_info_about_desc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time)) text_info_about_desc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time))
switch_secondary.isChecked = Preferences.preferSecondary
initActions() initActions()
} }
@ -51,6 +53,10 @@ class AccountFragment : Fragment() {
.build() .build()
.show() .show()
} }
switch_secondary.setOnClickListener {
Preferences.savePreferSecondary(requireContext(), switch_secondary.isChecked)
}
} }
private fun showLoginDialog(firstTry: Boolean) { private fun showLoginDialog(firstTry: Boolean) {

View File

@ -17,7 +17,9 @@ import kotlinx.android.synthetic.main.fragment_media.*
import org.mosad.teapod.MainActivity import org.mosad.teapod.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.util.DataTypes.MediaType import org.mosad.teapod.util.DataTypes.MediaType
import org.mosad.teapod.util.Episode
import org.mosad.teapod.util.Media import org.mosad.teapod.util.Media
import org.mosad.teapod.util.StorageController import org.mosad.teapod.util.StorageController
import org.mosad.teapod.util.TMDBResponse import org.mosad.teapod.util.TMDBResponse
@ -88,8 +90,8 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
private fun initActions() { private fun initActions() {
button_play.setOnClickListener { button_play.setOnClickListener {
when (media.type) { when (media.type) {
MediaType.MOVIE -> playStream(media.episodes.first().priStreamUrl) MediaType.MOVIE -> playStream(media.episodes.first())
MediaType.TVSHOW -> playStream(media.episodes.first().priStreamUrl) MediaType.TVSHOW -> playStream(media.episodes.first())
else -> Log.e(javaClass.name, "Wrong Type: $media.type") else -> Log.e(javaClass.name, "Wrong Type: $media.type")
} }
} }
@ -114,13 +116,7 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
// set onItemClick only in adapter is initialized // set onItemClick only in adapter is initialized
if (this::adapterRecEpisodes.isInitialized) { if (this::adapterRecEpisodes.isInitialized) {
adapterRecEpisodes.onImageClick = { _, position -> adapterRecEpisodes.onImageClick = { _, position ->
// TODO add option to prefer secondary stream playStream(media.episodes[position])
// try to use secondary stream if primary is missing
if (media.episodes[position].priStreamUrl.isNotEmpty()) {
playStream(media.episodes[position].priStreamUrl)
} else if (media.episodes[position].secStreamUrl.isNotEmpty()) {
playStream(media.episodes[position].secStreamUrl)
}
// update watched state // update watched state
AoDParser.sendCallback(media.episodes[position].watchedCallback) AoDParser.sendCallback(media.episodes[position].watchedCallback)
@ -130,9 +126,23 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
} }
} }
private fun playStream(url: String) { /**
Log.d(javaClass.name, "Playing stream: $url") * Play the media's stream
(activity as MainActivity).startPlayer(url) * If prefer secondary or primary is empty and secondary is present (secStreamOmU),
* use the secondary stream. Else, if the primary stream is set use the primary stream.
*/
private fun playStream(ep: Episode) {
val streamUrl = if ((Preferences.preferSecondary || ep.priStreamUrl.isEmpty()) && ep.secStreamOmU) {
ep.secStreamUrl
} else if (ep.priStreamUrl.isNotEmpty()) {
ep.priStreamUrl
} else {
Log.e(javaClass.name, "No stream url set.")
""
}
Log.d(javaClass.name, "Playing stream: $streamUrl")
(activity as MainActivity).startPlayer(streamUrl)
} }
} }

View File

@ -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="M20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM4,12h4v2L4,14v-2zM14,18L4,18v-2h10v2zM20,18h-4v-2h4v2zM20,14L10,14v-2h10v2z"/>
</vector>

View File

@ -81,6 +81,91 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/linear_settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="12dp"
android:background="#ffffff"
android:orientation="vertical">
<TextView
android:id="@+id/text_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="7dp"
android:paddingEnd="7dp"
android:text="@string/settings"
android:textColor="@android:color/primary_text_light"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/linear_settings_secondary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="7dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/account"
android:minWidth="48dp"
android:minHeight="48dp"
android:padding="5dp"
android:scaleType="fitXY"
android:src="@drawable/ic_baseline_subtitles_24" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/switch_secondary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/text_settings_secondary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/settings_secondary"
android:textColor="@android:color/primary_text_light"
android:textSize="16sp" />
<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_secondary_desc"
android:textColor="@android:color/secondary_text_light" />
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/linear_info" android:id="@+id/linear_info"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -157,10 +242,11 @@
android:layout_margin="7dp" android:layout_margin="7dp"
android:paddingStart="48dp" android:paddingStart="48dp"
android:paddingEnd="48dp" android:paddingEnd="48dp"
android:text="Licenses" android:text="@string/licenses"
android:textColor="@android:color/primary_text_light" android:textColor="@android:color/primary_text_light"
android:textSize="16sp" /> android:textSize="16sp" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -26,6 +26,9 @@
<string name="info_about_desc">Version %1$s (%2$s)</string> <string name="info_about_desc">Version %1$s (%2$s)</string>
<string name="info_about_dialog">Diese App wird unter den Bedingungen der GNU GPL 3 oder höher zur Verfügung gestellt. Weiter Informationen findest du unter: \ngit.mosad.xyz/Seil0/teapod \n\n© 2020 seil0@mosad.xyz</string> <string name="info_about_dialog">Diese App wird unter den Bedingungen der GNU GPL 3 oder höher zur Verfügung gestellt. Weiter Informationen findest du unter: \ngit.mosad.xyz/Seil0/teapod \n\n© 2020 seil0@mosad.xyz</string>
<string name="licenses">Lizenzen</string> <string name="licenses">Lizenzen</string>
<string name="settings">Einstellungen</string>
<string name="settings_secondary">Bevorzuge alternativen Stream</string>
<string name="settings_secondary_desc">Untertitle-Stream verwenden, sofern vorhanden</string>
<!-- dialogs --> <!-- dialogs -->
<string name="save">speichern</string> <string name="save">speichern</string>

View File

@ -35,6 +35,9 @@
<string name="info_about_desc">Version %1$s (%2$s)</string> <string name="info_about_desc">Version %1$s (%2$s)</string>
<string name="info_about_dialog">This app is published under the terms and conditions of the GNU GPL 3 or later. For further information visit: \ngit.mosad.xyz/Seil0/teapod \n\n© 2020 seil0@mosad.xyz</string> <string name="info_about_dialog">This app is published under the terms and conditions of the GNU GPL 3 or later. For further information visit: \ngit.mosad.xyz/Seil0/teapod \n\n© 2020 seil0@mosad.xyz</string>
<string name="licenses">Licenses</string> <string name="licenses">Licenses</string>
<string name="settings">Settings</string>
<string name="settings_secondary">Prefer secondary (sub) stream</string>
<string name="settings_secondary_desc">Use the subtitles stream if present</string>
<!-- dialogs --> <!-- dialogs -->
<string name="save">save</string> <string name="save">save</string>
@ -48,8 +51,10 @@
<!-- save keys --> <!-- save keys -->
<string name="encrypted_preference_file_key" translatable="false">org.mosad.teapod.encrypted_preferences</string> <string name="encrypted_preference_file_key" translatable="false">org.mosad.teapod.encrypted_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>
<string name="save_key_prefer_secondary" translatable="false">org.mosad.teapod.prefer_secondary</string>
<!-- intents & states --> <!-- intents & states -->
<string name="intent_stream_url" translatable="false">intent_stream_url</string> <string name="intent_stream_url" translatable="false">intent_stream_url</string>