refactor player options

This commit is contained in:
Bnyro 2022-09-10 16:32:40 +02:00
parent 915795eaf0
commit 1d5d254457
8 changed files with 127 additions and 303 deletions

View File

@ -60,7 +60,7 @@ import com.github.libretube.extensions.await
import com.github.libretube.extensions.formatShort import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.hideKeyboard import com.github.libretube.extensions.hideKeyboard
import com.github.libretube.extensions.toID import com.github.libretube.extensions.toID
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.models.PlayerViewModel import com.github.libretube.models.PlayerViewModel
import com.github.libretube.obj.ChapterSegment import com.github.libretube.obj.ChapterSegment
import com.github.libretube.obj.Segment import com.github.libretube.obj.Segment
@ -399,7 +399,7 @@ class PlayerFragment : BaseFragment() {
} }
} }
private val onlinePlayerOptionsInterface = object : OnlinePlayerOptionsInterface { private val onlinePlayerOptionsInterface = object : PlayerOptionsInterface {
override fun onCaptionClicked() { override fun onCaptionClicked() {
if (!this@PlayerFragment::streams.isInitialized || if (!this@PlayerFragment::streams.isInitialized ||
streams.subtitles == null || streams.subtitles == null ||

View File

@ -1,7 +0,0 @@
package com.github.libretube.interfaces
interface OnlinePlayerOptionsInterface {
fun onCaptionClicked()
fun onQualityClicked()
}

View File

@ -1,11 +1,7 @@
package com.github.libretube.interfaces package com.github.libretube.interfaces
interface PlayerOptionsInterface { interface PlayerOptionsInterface {
fun onAutoplayClicked() fun onCaptionClicked()
fun onPlaybackSpeedClicked() fun onQualityClicked()
fun onResizeModeClicked()
fun onRepeatModeClicked()
} }

View File

@ -18,8 +18,8 @@ import com.github.libretube.databinding.DoubleTapOverlayBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.extensions.setSliderRangeAndValue import com.github.libretube.extensions.setSliderRangeAndValue
import com.github.libretube.interfaces.DoubleTapInterface import com.github.libretube.interfaces.DoubleTapInterface
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface
import com.github.libretube.interfaces.PlayerOptionsInterface import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.obj.BottomSheetItem
import com.github.libretube.util.DoubleTapListener import com.github.libretube.util.DoubleTapListener
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.google.android.exoplayer2.trackselection.TrackSelector import com.google.android.exoplayer2.trackselection.TrackSelector
@ -40,7 +40,7 @@ internal class CustomExoPlayerView(
* Objects from the parent fragment * Objects from the parent fragment
*/ */
private var doubleTapListener: DoubleTapInterface? = null private var doubleTapListener: DoubleTapInterface? = null
private var onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface? = null private var playerOptionsInterface: PlayerOptionsInterface? = null
private lateinit var childFragmentManager: FragmentManager private lateinit var childFragmentManager: FragmentManager
private var trackSelector: TrackSelector? = null private var trackSelector: TrackSelector? = null
@ -85,12 +85,12 @@ internal class CustomExoPlayerView(
fun initialize( fun initialize(
childFragmentManager: FragmentManager, childFragmentManager: FragmentManager,
playerViewInterface: OnlinePlayerOptionsInterface?, playerViewInterface: PlayerOptionsInterface?,
doubleTapOverlayBinding: DoubleTapOverlayBinding, doubleTapOverlayBinding: DoubleTapOverlayBinding,
trackSelector: TrackSelector? trackSelector: TrackSelector?
) { ) {
this.childFragmentManager = childFragmentManager this.childFragmentManager = childFragmentManager
this.onlinePlayerOptionsInterface = playerViewInterface this.playerOptionsInterface = playerViewInterface
this.doubleTapOverlayBinding = doubleTapOverlayBinding this.doubleTapOverlayBinding = doubleTapOverlayBinding
this.trackSelector = trackSelector this.trackSelector = trackSelector
@ -141,46 +141,59 @@ internal class CustomExoPlayerView(
private fun initializeAdvancedOptions() { private fun initializeAdvancedOptions() {
binding.toggleOptions.setOnClickListener { binding.toggleOptions.setOnClickListener {
val bottomSheetFragment = PlayerOptionsBottomSheet().apply { val bottomSheetFragment = BottomSheet().apply {
setOnClickListeners( val items = listOf(
playerOptionsInterface, BottomSheetItem(
onlinePlayerOptionsInterface context?.getString(R.string.player_autoplay) + if (autoplayEnabled) {
)
// set the auto play mode
currentAutoplayMode = if (autoplayEnabled) {
context?.getString(R.string.enabled) context?.getString(R.string.enabled)
} else { } else {
context?.getString(R.string.disabled) context?.getString(R.string.disabled)
} },
// set the current caption language R.drawable.ic_play
currentCaptions = ),
if (trackSelector != null && trackSelector!!.parameters.preferredTextLanguages.isNotEmpty()) { BottomSheetItem(
trackSelector!!.parameters.preferredTextLanguages[0] context?.getString(R.string.playback_speed) + "${
} else {
context?.getString(R.string.none)
}
// set the playback speed
currentPlaybackSpeed = "${
player?.playbackParameters?.speed.toString() player?.playbackParameters?.speed.toString()
.replace(".0", "") .replace(".0", "")
}x" }x",
// set the quality text R.drawable.ic_speed
val quality = player?.videoSize?.height ),
if (quality != 0) { BottomSheetItem(
currentQuality = "${quality}p" context?.getString(R.string.repeat_mode) + if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
}
// set the repeat mode
currentRepeatMode =
if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
context?.getString(R.string.repeat_mode_none) context?.getString(R.string.repeat_mode_none)
} else { } else {
context?.getString(R.string.repeat_mode_current) context?.getString(R.string.repeat_mode_current)
} },
// set the aspect ratio mode R.drawable.ic_repeat
currentResizeMode = when (resizeMode) { ),
BottomSheetItem(
context?.getString(R.string.player_resize_mode) + when (resizeMode) {
AspectRatioFrameLayout.RESIZE_MODE_FIT -> context?.getString(R.string.resize_mode_fit) AspectRatioFrameLayout.RESIZE_MODE_FIT -> context?.getString(R.string.resize_mode_fit)
AspectRatioFrameLayout.RESIZE_MODE_FILL -> context?.getString(R.string.resize_mode_fill) AspectRatioFrameLayout.RESIZE_MODE_FILL -> context?.getString(R.string.resize_mode_fill)
else -> context?.getString(R.string.resize_mode_zoom) else -> context?.getString(R.string.resize_mode_zoom)
},
R.drawable.ic_aspect_ratio
),
BottomSheetItem(
context?.getString(R.string.quality) + "${player?.videoSize?.height}p",
R.drawable.ic_hd
),
BottomSheetItem(
context?.getString(R.string.captions) + if (trackSelector != null && trackSelector!!.parameters.preferredTextLanguages.isNotEmpty()) {
trackSelector!!.parameters.preferredTextLanguages[0]
} else context?.getString(R.string.none),
R.drawable.ic_caption
)
)
setItems(items) { index ->
when (index) {
0 -> onAutoplayClicked()
1 -> onPlaybackSpeedClicked()
2 -> onRepeatModeClicked()
3 -> onResizeModeClicked()
4 -> playerOptionsInterface?.onQualityClicked()
5 -> playerOptionsInterface?.onQualityClicked()
}
} }
} }
bottomSheetFragment.show(childFragmentManager, null) bottomSheetFragment.show(childFragmentManager, null)
@ -282,8 +295,7 @@ internal class CustomExoPlayerView(
} }
} }
private val playerOptionsInterface = object : PlayerOptionsInterface { fun onAutoplayClicked() {
override fun onAutoplayClicked() {
// autoplay options dialog // autoplay options dialog
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle(R.string.player_autoplay) .setTitle(R.string.player_autoplay)
@ -301,7 +313,7 @@ internal class CustomExoPlayerView(
.show() .show()
} }
override fun onPlaybackSpeedClicked() { fun onPlaybackSpeedClicked() {
val playbackSpeedBinding = DialogSliderBinding.inflate( val playbackSpeedBinding = DialogSliderBinding.inflate(
LayoutInflater.from(context) LayoutInflater.from(context)
) )
@ -322,7 +334,7 @@ internal class CustomExoPlayerView(
.show() .show()
} }
override fun onResizeModeClicked() { fun onResizeModeClicked() {
// switching between original aspect ratio (black bars) and zoomed to fill device screen // switching between original aspect ratio (black bars) and zoomed to fill device screen
val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode) val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode)
@ -340,7 +352,7 @@ internal class CustomExoPlayerView(
.show() .show()
} }
override fun onRepeatModeClicked() { fun onRepeatModeClicked() {
val repeatModeNames = arrayOf( val repeatModeNames = arrayOf(
context.getString(R.string.repeat_mode_none), context.getString(R.string.repeat_mode_none),
context.getString(R.string.repeat_mode_current) context.getString(R.string.repeat_mode_current)
@ -358,5 +370,4 @@ internal class CustomExoPlayerView(
} }
.show() .show()
} }
}
} }

View File

@ -1,118 +0,0 @@
package com.github.libretube.views
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.github.libretube.databinding.PlayerOptionsBottomSheetBinding
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface
import com.github.libretube.interfaces.PlayerOptionsInterface
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* Bottom Sheet including all the player options
*/
class PlayerOptionsBottomSheet : BottomSheetDialogFragment() {
lateinit var binding: PlayerOptionsBottomSheetBinding
private lateinit var playerOptionsInterface: PlayerOptionsInterface
private var onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface? = null
/**
* current values
*/
var currentPlaybackSpeed: String? = null
var currentAutoplayMode: String? = null
var currentRepeatMode: String? = null
var currentQuality: String? = null
var currentResizeMode: String? = null
var currentCaptions: String? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// expand the bottom sheet on creation
dialog!!.setOnShowListener { dialog ->
val d = dialog as BottomSheetDialog
val bottomSheetInternal =
d.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)!!
BottomSheetBehavior.from(bottomSheetInternal).state =
BottomSheetBehavior.STATE_EXPANDED
}
binding = PlayerOptionsBottomSheetBinding.inflate(layoutInflater, container, false)
return binding.root
}
fun setOnClickListeners(
playerOptionsInterface: PlayerOptionsInterface,
onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface?
) {
this.playerOptionsInterface = playerOptionsInterface
this.onlinePlayerOptionsInterface = onlinePlayerOptionsInterface
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (onlinePlayerOptionsInterface == null) {
binding.captions.visibility = View.GONE
binding.quality.visibility = View.GONE
}
/**
* update the text if a value is selected
*/
binding.autoplay.updateText(currentAutoplayMode)
binding.captions.updateText(currentCaptions)
binding.playbackSpeed.updateText(currentPlaybackSpeed)
binding.quality.updateText(currentQuality)
binding.repeatMode.updateText(currentRepeatMode)
binding.resizeMode.updateText(currentResizeMode)
binding.resizeMode.setOnClickListener {
playerOptionsInterface.onResizeModeClicked()
this.dismiss()
}
binding.quality.setOnClickListener {
onlinePlayerOptionsInterface?.onQualityClicked()
this.dismiss()
}
binding.playbackSpeed.setOnClickListener {
playerOptionsInterface.onPlaybackSpeedClicked()
this.dismiss()
}
binding.captions.setOnClickListener {
onlinePlayerOptionsInterface?.onCaptionClicked()
this.dismiss()
}
binding.autoplay.setOnClickListener {
playerOptionsInterface.onAutoplayClicked()
this.dismiss()
}
binding.repeatMode.setOnClickListener {
playerOptionsInterface.onRepeatModeClicked()
this.dismiss()
}
}
private fun TextView.updateText(currentValue: String?) {
if (currentValue == null) return
this.text = "${this.text} ($currentValue)"
}
}

View File

@ -18,6 +18,7 @@
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="16sp"
tools:text="Option" /> tools:text="Option" />
</LinearLayout> </LinearLayout>

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="7dp"
android:paddingVertical="10dp">
<TextView
android:id="@+id/quality"
style="@style/BottomSheetItem"
android:text="@string/quality"
app:drawableStartCompat="@drawable/ic_hd" />
<TextView
android:id="@+id/playbackSpeed"
style="@style/BottomSheetItem"
android:text="@string/playback_speed"
app:drawableStartCompat="@drawable/ic_speed" />
<TextView
android:id="@+id/captions"
style="@style/BottomSheetItem"
android:text="@string/captions"
app:drawableStartCompat="@drawable/ic_caption" />
<TextView
android:id="@+id/autoplay"
style="@style/BottomSheetItem"
android:text="@string/player_autoplay"
app:drawableStartCompat="@drawable/ic_play" />
<TextView
android:id="@+id/repeatMode"
style="@style/BottomSheetItem"
android:text="@string/repeat_mode"
app:drawableStartCompat="@drawable/ic_repeat" />
<TextView
android:id="@+id/resizeMode"
style="@style/BottomSheetItem"
android:text="@string/player_resize_mode"
app:drawableStartCompat="@drawable/ic_aspect_ratio" />
</LinearLayout>

View File

@ -151,19 +151,6 @@
</style> </style>
<style name="BottomSheetItem">
<item name="android:textSize">16sp</item>
<item name="android:drawablePadding">20dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">10dp</item>
<item name="android:layout_marginTop">2dp</item>
<item name="android:layout_marginBottom">2dp</item>
<item name="background">?attr/selectableItemBackground</item>
</style>
<style name="ItemRow"> <style name="ItemRow">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>