mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 22:30:30 +05:30
commit
7f13fd1689
@ -0,0 +1,42 @@
|
|||||||
|
package com.github.libretube.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.github.libretube.databinding.BottomSheetItemBinding
|
||||||
|
import com.github.libretube.obj.BottomSheetItem
|
||||||
|
|
||||||
|
class BottomSheetAdapter(
|
||||||
|
private val items: List<BottomSheetItem>,
|
||||||
|
private val listener: (index: Int) -> Unit
|
||||||
|
) : RecyclerView.Adapter<BottomSheetViewHolder>() {
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BottomSheetViewHolder {
|
||||||
|
val binding = BottomSheetItemBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
return BottomSheetViewHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: BottomSheetViewHolder, position: Int) {
|
||||||
|
val item = items[position]
|
||||||
|
holder.binding.apply {
|
||||||
|
title.text = if (item.currentValue != null) "${item.title} (${item.currentValue})" else item.title
|
||||||
|
if (item.drawable != null) drawable.setImageResource(item.drawable) else drawable.visibility = View.GONE
|
||||||
|
|
||||||
|
root.setOnClickListener {
|
||||||
|
listener.invoke(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return items.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BottomSheetViewHolder(
|
||||||
|
val binding: BottomSheetItemBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root)
|
@ -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 ||
|
||||||
|
@ -16,8 +16,9 @@ import com.github.libretube.constants.PreferenceKeys
|
|||||||
import com.github.libretube.databinding.FragmentSubscriptionsBinding
|
import com.github.libretube.databinding.FragmentSubscriptionsBinding
|
||||||
import com.github.libretube.extensions.BaseFragment
|
import com.github.libretube.extensions.BaseFragment
|
||||||
import com.github.libretube.models.SubscriptionsViewModel
|
import com.github.libretube.models.SubscriptionsViewModel
|
||||||
|
import com.github.libretube.obj.BottomSheetItem
|
||||||
import com.github.libretube.util.PreferenceHelper
|
import com.github.libretube.util.PreferenceHelper
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.github.libretube.views.BottomSheet
|
||||||
|
|
||||||
class SubscriptionsFragment : BaseFragment() {
|
class SubscriptionsFragment : BaseFragment() {
|
||||||
private lateinit var binding: FragmentSubscriptionsBinding
|
private lateinit var binding: FragmentSubscriptionsBinding
|
||||||
@ -107,15 +108,20 @@ class SubscriptionsFragment : BaseFragment() {
|
|||||||
private fun showSortDialog() {
|
private fun showSortDialog() {
|
||||||
val sortOptions = resources.getStringArray(R.array.sortOptions)
|
val sortOptions = resources.getStringArray(R.array.sortOptions)
|
||||||
val sortOptionValues = resources.getStringArray(R.array.sortOptionsValues)
|
val sortOptionValues = resources.getStringArray(R.array.sortOptionsValues)
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
val items = mutableListOf<BottomSheetItem>()
|
||||||
.setTitle(R.string.sort)
|
sortOptions.forEach {
|
||||||
.setItems(sortOptions) { _, index ->
|
items += BottomSheetItem(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bottomSheet = BottomSheet().apply {
|
||||||
|
setItems(items) { index ->
|
||||||
binding.sortTV.text = sortOptions[index]
|
binding.sortTV.text = sortOptions[index]
|
||||||
sortOrder = sortOptionValues[index]
|
sortOrder = sortOptionValues[index]
|
||||||
showFeed()
|
showFeed()
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
}
|
||||||
.show()
|
|
||||||
|
bottomSheet.show(childFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showFeed() {
|
private fun showFeed() {
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package com.github.libretube.interfaces
|
|
||||||
|
|
||||||
interface OnlinePlayerOptionsInterface {
|
|
||||||
fun onCaptionClicked()
|
|
||||||
|
|
||||||
fun onQualityClicked()
|
|
||||||
}
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.github.libretube.obj
|
||||||
|
|
||||||
|
data class BottomSheetItem(
|
||||||
|
val title: String,
|
||||||
|
val drawable: Int? = null,
|
||||||
|
val currentValue: String? = null
|
||||||
|
)
|
51
app/src/main/java/com/github/libretube/views/BottomSheet.kt
Normal file
51
app/src/main/java/com/github/libretube/views/BottomSheet.kt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package com.github.libretube.views
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.github.libretube.adapters.BottomSheetAdapter
|
||||||
|
import com.github.libretube.databinding.BottomSheetBinding
|
||||||
|
import com.github.libretube.obj.BottomSheetItem
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
|
|
||||||
|
class BottomSheet : BottomSheetDialogFragment() {
|
||||||
|
private lateinit var items: List<BottomSheetItem>
|
||||||
|
private lateinit var listener: (index: Int) -> Unit
|
||||||
|
private lateinit var binding: BottomSheetBinding
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
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 = BottomSheetBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
binding.optionsRecycler.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
binding.optionsRecycler.adapter = BottomSheetAdapter(items, listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setItems(items: List<BottomSheetItem>, listener: (index: Int) -> Unit) {
|
||||||
|
this.items = items
|
||||||
|
this.listener = { index ->
|
||||||
|
listener.invoke(index)
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ internal class CustomExoPlayerView(
|
|||||||
|
|
||||||
enableDoubleTapToSeek()
|
enableDoubleTapToSeek()
|
||||||
|
|
||||||
initializeAdvancedOptions()
|
initializeAdvancedOptions(context)
|
||||||
|
|
||||||
// locking the player
|
// locking the player
|
||||||
binding.lockPlayer.setOnClickListener {
|
binding.lockPlayer.setOnClickListener {
|
||||||
@ -139,48 +139,77 @@ internal class CustomExoPlayerView(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeAdvancedOptions() {
|
private fun initializeAdvancedOptions(context: Context) {
|
||||||
binding.toggleOptions.setOnClickListener {
|
binding.toggleOptions.setOnClickListener {
|
||||||
val bottomSheetFragment = PlayerOptionsBottomSheet().apply {
|
val bottomSheetFragment = BottomSheet().apply {
|
||||||
setOnClickListeners(
|
val items = mutableListOf(
|
||||||
playerOptionsInterface,
|
BottomSheetItem(
|
||||||
onlinePlayerOptionsInterface
|
context.getString(R.string.player_autoplay),
|
||||||
|
R.drawable.ic_play,
|
||||||
|
if (autoplayEnabled) {
|
||||||
|
context.getString(R.string.enabled)
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.disabled)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
BottomSheetItem(
|
||||||
|
context.getString(R.string.repeat_mode),
|
||||||
|
R.drawable.ic_repeat,
|
||||||
|
if (player?.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
|
||||||
|
context.getString(R.string.repeat_mode_none)
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.repeat_mode_current)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
BottomSheetItem(
|
||||||
|
context.getString(R.string.player_resize_mode),
|
||||||
|
R.drawable.ic_aspect_ratio,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
BottomSheetItem(
|
||||||
|
context.getString(R.string.playback_speed),
|
||||||
|
R.drawable.ic_speed,
|
||||||
|
"${player?.playbackParameters?.speed
|
||||||
|
.toString()
|
||||||
|
.replace(".0", "")
|
||||||
|
}x"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
// set the auto play mode
|
|
||||||
currentAutoplayMode = if (autoplayEnabled) {
|
if (playerOptionsInterface != null) {
|
||||||
context?.getString(R.string.enabled)
|
items.add(
|
||||||
} else {
|
BottomSheetItem(
|
||||||
context?.getString(R.string.disabled)
|
context.getString(R.string.quality),
|
||||||
|
R.drawable.ic_hd,
|
||||||
|
"${player?.videoSize?.height}p"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
items.add(
|
||||||
|
BottomSheetItem(
|
||||||
|
context.getString(R.string.captions),
|
||||||
|
R.drawable.ic_caption,
|
||||||
|
if (trackSelector != null && trackSelector!!.parameters.preferredTextLanguages.isNotEmpty()) {
|
||||||
|
trackSelector!!.parameters.preferredTextLanguages[0]
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.none)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// set the current caption language
|
|
||||||
currentCaptions =
|
setItems(items) { index ->
|
||||||
if (trackSelector != null && trackSelector!!.parameters.preferredTextLanguages.isNotEmpty()) {
|
when (index) {
|
||||||
trackSelector!!.parameters.preferredTextLanguages[0]
|
0 -> onAutoplayClicked()
|
||||||
} else {
|
1 -> onRepeatModeClicked()
|
||||||
context?.getString(R.string.none)
|
2 -> onResizeModeClicked()
|
||||||
|
3 -> onPlaybackSpeedClicked()
|
||||||
|
4 -> playerOptionsInterface?.onQualityClicked()
|
||||||
|
5 -> playerOptionsInterface?.onCaptionClicked()
|
||||||
}
|
}
|
||||||
// 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)
|
bottomSheetFragment.show(childFragmentManager, null)
|
||||||
@ -282,81 +311,80 @@ 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)
|
.setItems(
|
||||||
.setItems(
|
arrayOf(
|
||||||
arrayOf(
|
context.getString(R.string.enabled),
|
||||||
context.getString(R.string.enabled),
|
context.getString(R.string.disabled)
|
||||||
context.getString(R.string.disabled)
|
)
|
||||||
)
|
) { _, index ->
|
||||||
) { _, index ->
|
when (index) {
|
||||||
when (index) {
|
0 -> autoplayEnabled = true
|
||||||
0 -> autoplayEnabled = true
|
1 -> autoplayEnabled = false
|
||||||
1 -> autoplayEnabled = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.show()
|
}
|
||||||
}
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPlaybackSpeedClicked() {
|
fun onPlaybackSpeedClicked() {
|
||||||
val playbackSpeedBinding = DialogSliderBinding.inflate(
|
val playbackSpeedBinding = DialogSliderBinding.inflate(
|
||||||
LayoutInflater.from(context)
|
LayoutInflater.from(context)
|
||||||
)
|
)
|
||||||
playbackSpeedBinding.slider.setSliderRangeAndValue(
|
playbackSpeedBinding.slider.setSliderRangeAndValue(
|
||||||
PreferenceRanges.playbackSpeed
|
PreferenceRanges.playbackSpeed
|
||||||
)
|
)
|
||||||
playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f
|
playbackSpeedBinding.slider.value = player?.playbackParameters?.speed ?: 1f
|
||||||
// change playback speed dialog
|
// change playback speed dialog
|
||||||
MaterialAlertDialogBuilder(context)
|
MaterialAlertDialogBuilder(context)
|
||||||
.setTitle(R.string.change_playback_speed)
|
.setTitle(R.string.change_playback_speed)
|
||||||
.setView(playbackSpeedBinding.root)
|
.setView(playbackSpeedBinding.root)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.okay) { _, _ ->
|
.setPositiveButton(R.string.okay) { _, _ ->
|
||||||
player?.setPlaybackSpeed(
|
player?.setPlaybackSpeed(
|
||||||
playbackSpeedBinding.slider.value
|
playbackSpeedBinding.slider.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.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)
|
||||||
|
|
||||||
val aspectRatioModes = arrayOf(
|
val aspectRatioModes = arrayOf(
|
||||||
AspectRatioFrameLayout.RESIZE_MODE_FIT,
|
AspectRatioFrameLayout.RESIZE_MODE_FIT,
|
||||||
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
|
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
|
||||||
AspectRatioFrameLayout.RESIZE_MODE_FILL
|
AspectRatioFrameLayout.RESIZE_MODE_FILL
|
||||||
)
|
)
|
||||||
|
|
||||||
MaterialAlertDialogBuilder(context)
|
MaterialAlertDialogBuilder(context)
|
||||||
.setTitle(R.string.aspect_ratio)
|
.setTitle(R.string.aspect_ratio)
|
||||||
.setItems(aspectRatioModeNames) { _, index ->
|
.setItems(aspectRatioModeNames) { _, index ->
|
||||||
resizeMode = aspectRatioModes[index]
|
resizeMode = aspectRatioModes[index]
|
||||||
}
|
}
|
||||||
.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)
|
||||||
)
|
)
|
||||||
|
|
||||||
val repeatModes = arrayOf(
|
val repeatModes = arrayOf(
|
||||||
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL,
|
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE,
|
||||||
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
|
RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL
|
||||||
)
|
|
||||||
// repeat mode options dialog
|
)
|
||||||
MaterialAlertDialogBuilder(context)
|
// repeat mode options dialog
|
||||||
.setTitle(R.string.repeat_mode)
|
MaterialAlertDialogBuilder(context)
|
||||||
.setItems(repeatModeNames) { _, index ->
|
.setTitle(R.string.repeat_mode)
|
||||||
player?.repeatMode = repeatModes[index]
|
.setItems(repeatModeNames) { _, index ->
|
||||||
}
|
player?.repeatMode = repeatModes[index]
|
||||||
.show()
|
}
|
||||||
}
|
.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.BottomSheetBinding
|
|
||||||
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: BottomSheetBinding
|
|
||||||
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 = BottomSheetBinding.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)"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +1,34 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout 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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
android:paddingHorizontal="7dp"
|
|
||||||
android:paddingVertical="10dp">
|
|
||||||
|
|
||||||
<TextView
|
<FrameLayout
|
||||||
android:id="@+id/quality"
|
android:id="@+id/standard_bottom_sheet"
|
||||||
style="@style/BottomSheetItem"
|
style="@style/Widget.Material3.BottomSheet"
|
||||||
android:text="@string/quality"
|
android:layout_width="match_parent"
|
||||||
app:drawableStartCompat="@drawable/ic_hd" />
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/playbackSpeed"
|
android:orientation="vertical"
|
||||||
style="@style/BottomSheetItem"
|
android:layout_width="match_parent"
|
||||||
android:text="@string/playback_speed"
|
android:layout_height="wrap_content" >
|
||||||
app:drawableStartCompat="@drawable/ic_speed" />
|
|
||||||
|
|
||||||
<TextView
|
<!-- Drag handle for accessibility -->
|
||||||
android:id="@+id/captions"
|
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||||
style="@style/BottomSheetItem"
|
android:id="@+id/drag_handle"
|
||||||
android:text="@string/captions"
|
android:layout_width="match_parent"
|
||||||
app:drawableStartCompat="@drawable/ic_caption" />
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<TextView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/autoplay"
|
android:id="@+id/options_recycler"
|
||||||
style="@style/BottomSheetItem"
|
android:layout_width="match_parent"
|
||||||
android:text="@string/player_autoplay"
|
android:layout_height="wrap_content" />
|
||||||
app:drawableStartCompat="@drawable/ic_play" />
|
|
||||||
|
|
||||||
<TextView
|
</LinearLayout>
|
||||||
android:id="@+id/repeatMode"
|
|
||||||
style="@style/BottomSheetItem"
|
|
||||||
android:text="@string/repeat_mode"
|
|
||||||
app:drawableStartCompat="@drawable/ic_repeat" />
|
|
||||||
|
|
||||||
<TextView
|
</FrameLayout>
|
||||||
android:id="@+id/resizeMode"
|
|
||||||
style="@style/BottomSheetItem"
|
|
||||||
android:text="@string/player_resize_mode"
|
|
||||||
app:drawableStartCompat="@drawable/ic_aspect_ratio" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
24
app/src/main/res/layout/bottom_sheet_item.xml
Normal file
24
app/src/main/res/layout/bottom_sheet_item.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/drawable"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
tools:src="@drawable/ic_download" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="Option" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user