mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 06:10:31 +05:30
refactor player options
This commit is contained in:
parent
915795eaf0
commit
1d5d254457
@ -60,7 +60,7 @@ import com.github.libretube.extensions.await
|
||||
import com.github.libretube.extensions.formatShort
|
||||
import com.github.libretube.extensions.hideKeyboard
|
||||
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.obj.ChapterSegment
|
||||
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() {
|
||||
if (!this@PlayerFragment::streams.isInitialized ||
|
||||
streams.subtitles == null ||
|
||||
|
@ -1,7 +0,0 @@
|
||||
package com.github.libretube.interfaces
|
||||
|
||||
interface OnlinePlayerOptionsInterface {
|
||||
fun onCaptionClicked()
|
||||
|
||||
fun onQualityClicked()
|
||||
}
|
@ -1,11 +1,7 @@
|
||||
package com.github.libretube.interfaces
|
||||
|
||||
interface PlayerOptionsInterface {
|
||||
fun onAutoplayClicked()
|
||||
fun onCaptionClicked()
|
||||
|
||||
fun onPlaybackSpeedClicked()
|
||||
|
||||
fun onResizeModeClicked()
|
||||
|
||||
fun onRepeatModeClicked()
|
||||
fun onQualityClicked()
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ import com.github.libretube.databinding.DoubleTapOverlayBinding
|
||||
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
|
||||
import com.github.libretube.extensions.setSliderRangeAndValue
|
||||
import com.github.libretube.interfaces.DoubleTapInterface
|
||||
import com.github.libretube.interfaces.OnlinePlayerOptionsInterface
|
||||
import com.github.libretube.interfaces.PlayerOptionsInterface
|
||||
import com.github.libretube.obj.BottomSheetItem
|
||||
import com.github.libretube.util.DoubleTapListener
|
||||
import com.github.libretube.util.PreferenceHelper
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector
|
||||
@ -40,7 +40,7 @@ internal class CustomExoPlayerView(
|
||||
* Objects from the parent fragment
|
||||
*/
|
||||
private var doubleTapListener: DoubleTapInterface? = null
|
||||
private var onlinePlayerOptionsInterface: OnlinePlayerOptionsInterface? = null
|
||||
private var playerOptionsInterface: PlayerOptionsInterface? = null
|
||||
private lateinit var childFragmentManager: FragmentManager
|
||||
private var trackSelector: TrackSelector? = null
|
||||
|
||||
@ -85,12 +85,12 @@ internal class CustomExoPlayerView(
|
||||
|
||||
fun initialize(
|
||||
childFragmentManager: FragmentManager,
|
||||
playerViewInterface: OnlinePlayerOptionsInterface?,
|
||||
playerViewInterface: PlayerOptionsInterface?,
|
||||
doubleTapOverlayBinding: DoubleTapOverlayBinding,
|
||||
trackSelector: TrackSelector?
|
||||
) {
|
||||
this.childFragmentManager = childFragmentManager
|
||||
this.onlinePlayerOptionsInterface = playerViewInterface
|
||||
this.playerOptionsInterface = playerViewInterface
|
||||
this.doubleTapOverlayBinding = doubleTapOverlayBinding
|
||||
this.trackSelector = trackSelector
|
||||
|
||||
@ -141,46 +141,59 @@ internal class CustomExoPlayerView(
|
||||
|
||||
private fun initializeAdvancedOptions() {
|
||||
binding.toggleOptions.setOnClickListener {
|
||||
val bottomSheetFragment = PlayerOptionsBottomSheet().apply {
|
||||
setOnClickListeners(
|
||||
playerOptionsInterface,
|
||||
onlinePlayerOptionsInterface
|
||||
val bottomSheetFragment = BottomSheet().apply {
|
||||
val items = listOf(
|
||||
BottomSheetItem(
|
||||
context?.getString(R.string.player_autoplay) + if (autoplayEnabled) {
|
||||
context?.getString(R.string.enabled)
|
||||
} else {
|
||||
context?.getString(R.string.disabled)
|
||||
},
|
||||
R.drawable.ic_play
|
||||
),
|
||||
BottomSheetItem(
|
||||
context?.getString(R.string.playback_speed) + "${
|
||||
player?.playbackParameters?.speed.toString()
|
||||
.replace(".0", "")
|
||||
}x",
|
||||
R.drawable.ic_speed
|
||||
),
|
||||
BottomSheetItem(
|
||||
context?.getString(R.string.repeat_mode) + if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
|
||||
context?.getString(R.string.repeat_mode_none)
|
||||
} else {
|
||||
context?.getString(R.string.repeat_mode_current)
|
||||
},
|
||||
R.drawable.ic_repeat
|
||||
),
|
||||
BottomSheetItem(
|
||||
context?.getString(R.string.player_resize_mode) + when (resizeMode) {
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FIT -> context?.getString(R.string.resize_mode_fit)
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FILL -> context?.getString(R.string.resize_mode_fill)
|
||||
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
|
||||
)
|
||||
)
|
||||
// set the auto play mode
|
||||
currentAutoplayMode = if (autoplayEnabled) {
|
||||
context?.getString(R.string.enabled)
|
||||
} else {
|
||||
context?.getString(R.string.disabled)
|
||||
}
|
||||
// set the current caption language
|
||||
currentCaptions =
|
||||
if (trackSelector != null && trackSelector!!.parameters.preferredTextLanguages.isNotEmpty()) {
|
||||
trackSelector!!.parameters.preferredTextLanguages[0]
|
||||
} else {
|
||||
context?.getString(R.string.none)
|
||||
setItems(items) { index ->
|
||||
when (index) {
|
||||
0 -> onAutoplayClicked()
|
||||
1 -> onPlaybackSpeedClicked()
|
||||
2 -> onRepeatModeClicked()
|
||||
3 -> onResizeModeClicked()
|
||||
4 -> playerOptionsInterface?.onQualityClicked()
|
||||
5 -> playerOptionsInterface?.onQualityClicked()
|
||||
}
|
||||
// set the playback speed
|
||||
currentPlaybackSpeed = "${
|
||||
player?.playbackParameters?.speed.toString()
|
||||
.replace(".0", "")
|
||||
}x"
|
||||
// set the quality text
|
||||
val quality = player?.videoSize?.height
|
||||
if (quality != 0) {
|
||||
currentQuality = "${quality}p"
|
||||
}
|
||||
// set the repeat mode
|
||||
currentRepeatMode =
|
||||
if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
|
||||
context?.getString(R.string.repeat_mode_none)
|
||||
} else {
|
||||
context?.getString(R.string.repeat_mode_current)
|
||||
}
|
||||
// set the aspect ratio mode
|
||||
currentResizeMode = when (resizeMode) {
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FIT -> context?.getString(R.string.resize_mode_fit)
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FILL -> context?.getString(R.string.resize_mode_fill)
|
||||
else -> context?.getString(R.string.resize_mode_zoom)
|
||||
}
|
||||
}
|
||||
bottomSheetFragment.show(childFragmentManager, null)
|
||||
@ -282,81 +295,79 @@ internal class CustomExoPlayerView(
|
||||
}
|
||||
}
|
||||
|
||||
private val playerOptionsInterface = object : PlayerOptionsInterface {
|
||||
override fun onAutoplayClicked() {
|
||||
// autoplay options dialog
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.player_autoplay)
|
||||
.setItems(
|
||||
arrayOf(
|
||||
context.getString(R.string.enabled),
|
||||
context.getString(R.string.disabled)
|
||||
)
|
||||
) { _, index ->
|
||||
when (index) {
|
||||
0 -> autoplayEnabled = true
|
||||
1 -> autoplayEnabled = false
|
||||
}
|
||||
fun onAutoplayClicked() {
|
||||
// autoplay options dialog
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.player_autoplay)
|
||||
.setItems(
|
||||
arrayOf(
|
||||
context.getString(R.string.enabled),
|
||||
context.getString(R.string.disabled)
|
||||
)
|
||||
) { _, index ->
|
||||
when (index) {
|
||||
0 -> autoplayEnabled = true
|
||||
1 -> autoplayEnabled = false
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onPlaybackSpeedClicked() {
|
||||
val playbackSpeedBinding = DialogSliderBinding.inflate(
|
||||
LayoutInflater.from(context)
|
||||
)
|
||||
playbackSpeedBinding.slider.setSliderRangeAndValue(
|
||||
PreferenceRanges.playbackSpeed
|
||||
)
|
||||
playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f
|
||||
// change playback speed dialog
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.change_playback_speed)
|
||||
.setView(playbackSpeedBinding.root)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.okay) { _, _ ->
|
||||
player?.setPlaybackSpeed(
|
||||
playbackSpeedBinding.slider.value
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
fun onPlaybackSpeedClicked() {
|
||||
val playbackSpeedBinding = DialogSliderBinding.inflate(
|
||||
LayoutInflater.from(context)
|
||||
)
|
||||
playbackSpeedBinding.slider.setSliderRangeAndValue(
|
||||
PreferenceRanges.playbackSpeed
|
||||
)
|
||||
playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f
|
||||
// change playback speed dialog
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.change_playback_speed)
|
||||
.setView(playbackSpeedBinding.root)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.okay) { _, _ ->
|
||||
player?.setPlaybackSpeed(
|
||||
playbackSpeedBinding.slider.value
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onResizeModeClicked() {
|
||||
// switching between original aspect ratio (black bars) and zoomed to fill device screen
|
||||
val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode)
|
||||
fun onResizeModeClicked() {
|
||||
// switching between original aspect ratio (black bars) and zoomed to fill device screen
|
||||
val aspectRatioModeNames = context.resources?.getStringArray(R.array.resizeMode)
|
||||
|
||||
val aspectRatioModes = arrayOf(
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FIT,
|
||||
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FILL
|
||||
)
|
||||
val aspectRatioModes = arrayOf(
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FIT,
|
||||
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
|
||||
AspectRatioFrameLayout.RESIZE_MODE_FILL
|
||||
)
|
||||
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.aspect_ratio)
|
||||
.setItems(aspectRatioModeNames) { _, index ->
|
||||
resizeMode = aspectRatioModes[index]
|
||||
}
|
||||
.show()
|
||||
}
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.aspect_ratio)
|
||||
.setItems(aspectRatioModeNames) { _, index ->
|
||||
resizeMode = aspectRatioModes[index]
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onRepeatModeClicked() {
|
||||
val repeatModeNames = arrayOf(
|
||||
context.getString(R.string.repeat_mode_none),
|
||||
context.getString(R.string.repeat_mode_current)
|
||||
)
|
||||
fun onRepeatModeClicked() {
|
||||
val repeatModeNames = arrayOf(
|
||||
context.getString(R.string.repeat_mode_none),
|
||||
context.getString(R.string.repeat_mode_current)
|
||||
)
|
||||
|
||||
val repeatModes = arrayOf(
|
||||
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL,
|
||||
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
|
||||
)
|
||||
// repeat mode options dialog
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.repeat_mode)
|
||||
.setItems(repeatModeNames) { _, index ->
|
||||
player?.repeatMode = repeatModes[index]
|
||||
}
|
||||
.show()
|
||||
}
|
||||
val repeatModes = arrayOf(
|
||||
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL,
|
||||
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
|
||||
)
|
||||
// repeat mode options dialog
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.repeat_mode)
|
||||
.setItems(repeatModeNames) { _, index ->
|
||||
player?.repeatMode = repeatModes[index]
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
@ -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)"
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
tools:text="Option" />
|
||||
|
||||
</LinearLayout>
|
@ -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>
|
@ -151,19 +151,6 @@
|
||||
|
||||
</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">
|
||||
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
|
Loading…
Reference in New Issue
Block a user