Merge pull request #1028 from Bnyro/master

Advanced Player Options refactor
This commit is contained in:
Bnyro 2022-08-12 15:06:40 +02:00 committed by GitHub
commit 260fc738d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 361 additions and 304 deletions

View File

@ -6,7 +6,6 @@ import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.Rect
import android.net.Uri
import android.os.Build
@ -45,6 +44,8 @@ import com.github.libretube.dialogs.AddToPlaylistDialog
import com.github.libretube.dialogs.DownloadDialog
import com.github.libretube.dialogs.ShareDialog
import com.github.libretube.extensions.BaseFragment
import com.github.libretube.interfaces.DoubleTapInterface
import com.github.libretube.interfaces.PlayerOptionsInterface
import com.github.libretube.obj.ChapterSegment
import com.github.libretube.obj.Segment
import com.github.libretube.obj.Segments
@ -57,13 +58,13 @@ import com.github.libretube.util.BackgroundHelper
import com.github.libretube.util.ConnectionHelper
import com.github.libretube.util.CronetHelper
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.OnDoubleTapEventListener
import com.github.libretube.util.PlayerHelper
import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.SubscriptionHelper
import com.github.libretube.util.formatShort
import com.github.libretube.util.hideKeyboard
import com.github.libretube.util.toID
import com.github.libretube.views.BottomSheetFragment
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.ExoPlayer
@ -206,8 +207,6 @@ class PlayerFragment : BaseFragment() {
setUserPrefs()
if (autoplayEnabled) playerBinding.autoplayIV.setImageResource(R.drawable.ic_toggle_on)
val mainActivity = activity as MainActivity
if (autoRotationEnabled) {
// enable auto rotation
@ -397,6 +396,160 @@ class PlayerFragment : BaseFragment() {
}
}
private val playerOptionsInterface = object : PlayerOptionsInterface {
override fun onAutoplayClicked() {
// autoplay options dialog
MaterialAlertDialogBuilder(requireContext())
.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()
}
override fun onCaptionClicked() {
if (!this@PlayerFragment::streams.isInitialized ||
streams.subtitles == null ||
streams.subtitles!!.isEmpty()
) {
Toast.makeText(context, R.string.no_subtitles_available, Toast.LENGTH_SHORT).show()
return
}
val subtitlesNamesList = mutableListOf(context?.getString(R.string.none)!!)
val subtitleCodesList = mutableListOf("")
streams.subtitles!!.forEach {
subtitlesNamesList += it.name!!
subtitleCodesList += it.code!!
}
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.captions)
.setItems(subtitlesNamesList.toTypedArray()) { _, index ->
val newParams = if (index != 0) {
// caption selected
// get the caption name and language
val captionLanguage = subtitlesNamesList[index]
val captionLanguageCode = subtitleCodesList[index]
// select the new caption preference
trackSelector.buildUponParameters()
.setPreferredTextLanguages(
captionLanguage,
captionLanguageCode
)
.setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION)
} else {
// none selected
// disable captions
trackSelector.buildUponParameters()
.setPreferredTextLanguage("")
}
// set the new caption language
trackSelector.setParameters(newParams)
}
.show()
}
override fun onQualityClicked() {
// get the available resolutions
val (videosNameArray, videosUrlArray) = getAvailableResolutions()
// Dialog for quality selection
val lastPosition = exoPlayer.currentPosition
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.choose_quality_dialog)
.setItems(
videosNameArray
) { _, which ->
if (
videosNameArray[which] == getString(R.string.hls) ||
videosNameArray[which] == "LBRY HLS"
) {
// no need to merge sources if using hls
val mediaItem: MediaItem = MediaItem.Builder()
.setUri(videosUrlArray[which])
.setSubtitleConfigurations(subtitle)
.build()
exoPlayer.setMediaItem(mediaItem)
} else {
val videoUri = videosUrlArray[which]
val audioUrl = PlayerHelper.getAudioSource(streams.audioStreams!!)
setMediaSource(videoUri, audioUrl)
}
exoPlayer.seekTo(lastPosition)
}
.show()
}
override fun onPlaybackSpeedClicked() {
val playbackSpeeds = context?.resources?.getStringArray(R.array.playbackSpeed)!!
val playbackSpeedValues =
context?.resources?.getStringArray(R.array.playbackSpeedValues)!!
// change playback speed dialog
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.change_playback_speed)
.setItems(playbackSpeeds) { _, index ->
// set the new playback speed
val newPlaybackSpeed = playbackSpeedValues[index].toFloat()
exoPlayer.setPlaybackSpeed(newPlaybackSpeed)
}
.show()
}
override fun onAspectRatioClicked() {
// switching between original aspect ratio (black bars) and zoomed to fill device screen
val aspectRatioModeNames = arrayOf(
context?.getString(R.string.resize_mode_fit),
context?.getString(R.string.resize_mode_zoom),
context?.getString(R.string.resize_mode_fill)
)
val aspectRatioModes = arrayOf(
AspectRatioFrameLayout.RESIZE_MODE_FIT,
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
AspectRatioFrameLayout.RESIZE_MODE_FILL
)
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.aspect_ratio)
.setItems(aspectRatioModeNames) { _, index ->
exoPlayerView.resizeMode = aspectRatioModes[index]
}
.show()
}
override 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(requireContext())
.setTitle(R.string.repeat_mode)
.setItems(repeatModeNames) { _, index ->
exoPlayer.repeatMode = repeatModes[index]
}
.show()
}
}
// actions that don't depend on video information
private fun initializeOnClickActions() {
binding.closeImageView.setOnClickListener {
@ -417,24 +570,12 @@ class PlayerFragment : BaseFragment() {
}
// show the advanced player options
playerBinding.toggleOptions.setOnClickListener {
if (playerBinding.advancedOptions.isVisible) {
playerBinding.toggleOptions.animate().rotation(0F).setDuration(250).start()
playerBinding.advancedOptions.visibility = View.GONE
} else {
playerBinding.toggleOptions.animate().rotation(180F).setDuration(250).start()
playerBinding.advancedOptions.visibility = View.VISIBLE
}
}
// autoplay toggle button
playerBinding.autoplayLL.setOnClickListener {
autoplayEnabled = if (autoplayEnabled) {
playerBinding.autoplayIV.setImageResource(R.drawable.ic_toggle_off)
false
} else {
playerBinding.autoplayIV.setImageResource(R.drawable.ic_toggle_on)
true
val bottomSheetFragment = BottomSheetFragment().apply {
setOnClickListeners(playerOptionsInterface)
}
bottomSheetFragment.show(childFragmentManager, null)
}
binding.playImageView.setOnClickListener {
if (!exoPlayer.isPlaying) {
// start or go on playing
@ -471,20 +612,6 @@ class PlayerFragment : BaseFragment() {
}
}
// switching between original aspect ratio (black bars) and zoomed to fill device screen
val aspectRatioModes = arrayOf(
AspectRatioFrameLayout.RESIZE_MODE_FIT,
AspectRatioFrameLayout.RESIZE_MODE_ZOOM,
AspectRatioFrameLayout.RESIZE_MODE_FILL
)
playerBinding.aspectRatioButton.setOnClickListener {
val index = aspectRatioModes.indexOf(exoPlayerView.resizeMode)
val newAspectRatioMode =
if (index + 1 < aspectRatioModes.size) aspectRatioModes[index + 1]
else aspectRatioModes[0]
exoPlayerView.resizeMode = newAspectRatioMode
}
// lock and unlock the player
playerBinding.lockPlayer.setOnClickListener {
// change the locked/unlocked icon
@ -502,37 +629,7 @@ class PlayerFragment : BaseFragment() {
}
// set default playback speed
val playbackSpeeds = context?.resources?.getStringArray(R.array.playbackSpeed)!!
val playbackSpeedValues =
context?.resources?.getStringArray(R.array.playbackSpeedValues)!!
exoPlayer.setPlaybackSpeed(playbackSpeed.toFloat())
val speedIndex = playbackSpeedValues.indexOf(playbackSpeed)
playerBinding.speedText.text = playbackSpeeds[speedIndex]
// change playback speed button
playerBinding.speedText.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.change_playback_speed)
.setItems(playbackSpeeds) { _, index ->
// set the new playback speed
val newPlaybackSpeed = playbackSpeedValues[index].toFloat()
exoPlayer.setPlaybackSpeed(newPlaybackSpeed)
playerBinding.speedText.text = playbackSpeeds[index]
}
.show()
}
// repeat toggle button
playerBinding.repeatToggle.setOnClickListener {
if (exoPlayer.repeatMode == RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL) {
// turn off repeat mode
exoPlayer.repeatMode = RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
playerBinding.repeatToggle.setColorFilter(Color.GRAY)
} else {
exoPlayer.repeatMode = RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL
playerBinding.repeatToggle.setColorFilter(Color.WHITE)
}
}
// share button
binding.relPlayerShare.setOnClickListener {
@ -733,7 +830,7 @@ class PlayerFragment : BaseFragment() {
runOnUiThread {
// set media sources for the player
setResolutionAndSubtitles(streams)
setResolutionAndSubtitles()
prepareExoPlayerView()
initializePlayerView(streams)
if (!isLive) seekToWatchPosition()
@ -785,7 +882,6 @@ class PlayerFragment : BaseFragment() {
// switch back to normal speed when on the end of live stream
if (exoPlayer.duration - exoPlayer.currentPosition < 7000) {
exoPlayer.setPlaybackSpeed(1F)
playerBinding.speedText.text = "1x"
playerBinding.liveSeparator.visibility = View.GONE
playerBinding.liveDiff.text = ""
} else {
@ -911,12 +1007,6 @@ class PlayerFragment : BaseFragment() {
override fun onVideoSizeChanged(
videoSize: VideoSize
) {
// show the resolution in the video resolution text view
if (playerBinding.qualityText.text == context?.getString(R.string.hls)) {
playerBinding.qualityText.text =
"${context?.getString(R.string.hls)} (${videoSize.height}p)"
}
// Set new width/height of view
// height or width must be cast to float as int/int will give 0
@ -1075,7 +1165,7 @@ class PlayerFragment : BaseFragment() {
doubleTapOverlayBinding.rewindTV.text = seekIncrementText
doubleTapOverlayBinding.forwardTV.text = seekIncrementText
binding.player.setOnDoubleTapListener(
object : OnDoubleTapEventListener {
object : DoubleTapInterface {
override fun onEvent(x: Float) {
val width = exoPlayerView.width
when {
@ -1234,17 +1324,19 @@ class PlayerFragment : BaseFragment() {
exoPlayer.setMediaSource(mergeSource)
}
private fun setResolutionAndSubtitles(response: Streams) {
var videosNameArray: Array<CharSequence> = arrayOf()
private fun getAvailableResolutions(): Pair<Array<String>, Array<Uri>> {
if (!this::streams.isInitialized) return Pair(arrayOf(), arrayOf())
var videosNameArray: Array<String> = arrayOf()
var videosUrlArray: Array<Uri> = arrayOf()
// append hls to list if available
if (response.hls != null) {
if (streams.hls != null) {
videosNameArray += getString(R.string.hls)
videosUrlArray += response.hls.toUri()
videosUrlArray += streams.hls!!.toUri()
}
for (vid in response.videoStreams!!) {
for (vid in streams.videoStreams!!) {
// append quality to list if it has the preferred format (e.g. MPEG)
val preferredMimeType = "video/$videoFormatPreference"
if (vid.url != null && vid.mimeType == preferredMimeType) { // preferred format
@ -1255,11 +1347,18 @@ class PlayerFragment : BaseFragment() {
videosUrlArray += vid.url!!.toUri()
}
}
return Pair(videosNameArray, videosUrlArray)
}
private fun setResolutionAndSubtitles() {
// get the available resolutions
val (videosNameArray, videosUrlArray) = getAvailableResolutions()
// create a list of subtitles
subtitle = mutableListOf()
val subtitlesNamesList = mutableListOf(context?.getString(R.string.none)!!)
val subtitleCodesList = mutableListOf("")
response.subtitles!!.forEach {
streams.subtitles!!.forEach {
subtitle.add(
SubtitleConfiguration.Builder(it.url!!.toUri())
.setMimeType(it.mimeType!!) // The correct MIME type (required).
@ -1276,91 +1375,19 @@ class PlayerFragment : BaseFragment() {
.setPreferredTextLanguage(defaultSubtitleCode)
.setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION)
trackSelector.setParameters(newParams)
playerBinding.captions.setImageResource(R.drawable.ic_caption)
}
// captions selection dialog
// hide caption selection view if no subtitles available
if (response.subtitles.isEmpty()) playerBinding.captions.visibility = View.GONE
playerBinding.captions.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.captions)
.setItems(subtitlesNamesList.toTypedArray()) { _, index ->
val newParams = if (index != 0) {
// caption selected
// get the caption name and language
val captionLanguage = subtitlesNamesList[index]
val captionLanguageCode = subtitleCodesList[index]
// update the icon of the captions button
playerBinding.captions.setImageResource(R.drawable.ic_caption)
// select the new caption preference
trackSelector.buildUponParameters()
.setPreferredTextLanguages(
captionLanguage,
captionLanguageCode
)
.setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION)
} else {
// none selected
playerBinding.captions.setImageResource(R.drawable.ic_caption_outlined)
// disable captions
trackSelector.buildUponParameters()
.setPreferredTextLanguage("")
}
// set the new caption language
trackSelector.setParameters(newParams)
}
.show()
}
// set media source and resolution in the beginning
setStreamSource(
response,
streams,
videosNameArray,
videosUrlArray
)
playerBinding.qualityText.setOnClickListener {
// Dialog for quality selection
val builder: MaterialAlertDialogBuilder? = activity?.let {
MaterialAlertDialogBuilder(it)
}
val lastPosition = exoPlayer.currentPosition
builder!!.setTitle(R.string.choose_quality_dialog)
.setItems(
videosNameArray
) { _, which ->
if (
videosNameArray[which] == getString(R.string.hls) ||
videosNameArray[which] == "LBRY HLS"
) {
// no need to merge sources if using hls
val mediaItem: MediaItem = MediaItem.Builder()
.setUri(videosUrlArray[which])
.setSubtitleConfigurations(subtitle)
.build()
exoPlayer.setMediaItem(mediaItem)
} else {
val videoUri = videosUrlArray[which]
val audioUrl = PlayerHelper.getAudioSource(response.audioStreams!!)
setMediaSource(videoUri, audioUrl)
}
exoPlayer.seekTo(lastPosition)
playerBinding.qualityText.text = videosNameArray[which]
}
val dialog = builder.create()
dialog.show()
}
}
private fun setStreamSource(
streams: Streams,
videosNameArray: Array<CharSequence>,
videosNameArray: Array<String>,
videosUrlArray: Array<Uri>
) {
if (defRes != "") {
@ -1370,7 +1397,6 @@ class PlayerFragment : BaseFragment() {
val videoUri = videosUrlArray[index]
val audioUrl = PlayerHelper.getAudioSource(streams.audioStreams!!)
setMediaSource(videoUri, audioUrl)
playerBinding.qualityText.text = videosNameArray[index]
return
}
}
@ -1383,7 +1409,6 @@ class PlayerFragment : BaseFragment() {
.setSubtitleConfigurations(subtitle)
.build()
exoPlayer.setMediaItem(mediaItem)
playerBinding.qualityText.text = context?.getString(R.string.hls)
return
}
@ -1392,7 +1417,6 @@ class PlayerFragment : BaseFragment() {
val videoUri = videosUrlArray[0]
val audioUrl = PlayerHelper.getAudioSource(streams.audioStreams!!)
setMediaSource(videoUri, audioUrl)
playerBinding.qualityText.text = videosNameArray[0]
}
}
@ -1588,6 +1612,7 @@ class PlayerFragment : BaseFragment() {
private fun isServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
@Suppress("DEPRECATION")
for (service in manager.getRunningServices(Int.MAX_VALUE)) {
if (serviceClass.name == service.service.className) {
return true

View File

@ -0,0 +1,5 @@
package com.github.libretube.interfaces
interface DoubleTapInterface {
fun onEvent(x: Float)
}

View File

@ -0,0 +1,16 @@
package com.github.libretube.interfaces
interface PlayerOptionsInterface {
fun onAutoplayClicked()
fun onCaptionClicked()
fun onQualityClicked()
fun onPlaybackSpeedClicked()
fun onAspectRatioClicked()
fun onRepeatModeClicked()
}

View File

@ -1,5 +0,0 @@
package com.github.libretube.util
interface OnDoubleTapEventListener {
fun onEvent(x: Float)
}

View File

@ -18,7 +18,7 @@ import com.google.android.material.color.DynamicColors
object ThemeHelper {
fun updateTheme(activity: AppCompatActivity) {
val themeMode = PreferenceHelper.getString(PreferenceKeys.THEME_MODE, "A")!!
val themeMode = PreferenceHelper.getString(PreferenceKeys.THEME_MODE, "A")
val pureThemeEnabled = PreferenceHelper.getBoolean(PreferenceKeys.PURE_THEME, false)
updateAccentColor(activity, pureThemeEnabled)
@ -37,8 +37,8 @@ object ThemeHelper {
) {
"my" -> {
applyDynamicColors(activity)
if (pureThemeEnabled) R.style.MaterialYou_Pure
else R.style.MaterialYou
if (pureThemeEnabled) R.style.BaseTheme_Pure
else R.style.BaseTheme
}
// set the theme, use the pure theme if enabled
"red" -> if (pureThemeEnabled) R.style.Theme_Red_Pure else R.style.Theme_Red

View File

@ -0,0 +1,61 @@
package com.github.libretube.views
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.github.libretube.databinding.BottomSheetBinding
import com.github.libretube.interfaces.PlayerOptionsInterface
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class BottomSheetFragment : BottomSheetDialogFragment() {
private lateinit var binding: BottomSheetBinding
private lateinit var playerOptionsInterface: PlayerOptionsInterface
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = BottomSheetBinding.inflate(layoutInflater, container, false)
return binding.root
}
fun setOnClickListeners(playerOptionsInterface: PlayerOptionsInterface) {
this.playerOptionsInterface = playerOptionsInterface
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.aspectRatio.setOnClickListener {
playerOptionsInterface.onAspectRatioClicked()
this.dismiss()
}
binding.quality.setOnClickListener {
playerOptionsInterface.onQualityClicked()
this.dismiss()
}
binding.playbackSpeed.setOnClickListener {
playerOptionsInterface.onPlaybackSpeedClicked()
this.dismiss()
}
binding.captions.setOnClickListener {
playerOptionsInterface.onCaptionClicked()
this.dismiss()
}
binding.autoplay.setOnClickListener {
playerOptionsInterface.onAutoplayClicked()
this.dismiss()
}
binding.repeatMode.setOnClickListener {
playerOptionsInterface.onRepeatModeClicked()
this.dismiss()
}
}
}

View File

@ -4,10 +4,9 @@ import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.interfaces.DoubleTapInterface
import com.github.libretube.util.DoubleTapListener
import com.github.libretube.util.OnDoubleTapEventListener
import com.google.android.exoplayer2.ui.StyledPlayerView
@SuppressLint("ClickableViewAccessibility")
@ -18,13 +17,13 @@ internal class CustomExoPlayerView(
val TAG = "CustomExoPlayerView"
val binding: ExoStyledPlayerControlViewBinding = ExoStyledPlayerControlViewBinding.bind(this)
private var doubleTapListener: OnDoubleTapEventListener? = null
private var doubleTapListener: DoubleTapInterface? = null
// the x-position of where the user clicked
private var xPos = 0F
fun setOnDoubleTapListener(
eventListener: OnDoubleTapEventListener?
eventListener: DoubleTapInterface?
) {
doubleTapListener = eventListener
}
@ -44,11 +43,6 @@ internal class CustomExoPlayerView(
}
init {
setControllerVisibilityListener {
// hide the advanced options
binding.toggleOptions.animate().rotation(0F).setDuration(250).start()
binding.advancedOptions.visibility = View.GONE
}
// set the double click listener for rewind/forward
setOnClickListener(doubleTouchListener)
}

View File

@ -1,7 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/white"
android:tint="?attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48">
<path

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/white" />
<corners
android:topLeftRadius="100dp"
android:topRightRadius="100dp" />
</shape>

View File

@ -0,0 +1,46 @@
<?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="wrap_content"
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:layout_marginTop="8dp"
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/aspectRatio"
style="@style/BottomSheetItem"
android:text="@string/aspect_ratio"
app:drawableStartCompat="@drawable/ic_aspect_ratio" />
</LinearLayout>

View File

@ -67,17 +67,6 @@
android:layout_gravity="center"
android:layoutDirection="ltr">
<TextView
android:id="@+id/speed_text"
style="@style/PlayerControlTop"
android:text="1x"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/quality_text"
style="@style/PlayerControlTop"
android:text="@string/hls" />
<ImageButton
android:id="@+id/toggle_options"
style="@style/PlayerControlTop"
@ -89,68 +78,6 @@
</LinearLayout>
<LinearLayout
android:id="@+id/advanced_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="-12dp"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/autoplayLL"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="1.5dp"
android:text="@string/player_autoplay"
android:textColor="@android:color/white" />
<ImageView
android:id="@+id/autoplayIV"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:src="@drawable/ic_toggle_off" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/captions"
style="@style/PlayerControlTop"
android:src="@drawable/ic_caption_outlined"
app:tint="@android:color/white" />
<ImageButton
android:id="@+id/repeat_toggle"
style="@style/PlayerControlTop"
android:src="@drawable/ic_repeat"
app:tint="@android:color/darker_gray" />
<ImageView
android:id="@+id/aspect_ratio_button"
style="@style/PlayerControlTop"
android:src="@drawable/ic_aspect_ratio" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout

View File

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="MaterialYou">
<style name="BaseTheme" parent="Theme.Material3.Dark.NoActionBar">
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
@ -8,14 +8,14 @@
</style>
<style name="MaterialYou.Pure" parent="MaterialYou">
<style name="BaseTheme.Pure" parent="BaseTheme">
<item name="android:colorBackground">@android:color/black</item>
<item name="colorSurface">@android:color/black</item>
</style>
<style name="Theme.Red" parent="Theme.Material3.Dark.NoActionBar">
<style name="Theme.Red" parent="BaseTheme">
<item name="colorPrimary">@color/red_dark_accentLight</item>
<item name="colorOnPrimary">@color/red_dark_accentDark</item>
@ -27,10 +27,6 @@
<item name="android:colorBackground">@color/red_dark_background</item>
<item name="colorOnBackground">@color/red_dark_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Red.Pure" parent="Theme.Red">
@ -40,7 +36,7 @@
</style>
<style name="Theme.Blue" parent="Theme.Material3.Dark.NoActionBar">
<style name="Theme.Blue" parent="BaseTheme">
<item name="colorPrimary">@color/blue_dark_accentLight</item>
<item name="colorOnPrimary">@color/blue_dark_accentDark</item>
@ -52,10 +48,6 @@
<item name="android:colorBackground">@color/blue_dark_background</item>
<item name="colorOnBackground">@color/blue_dark_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Blue.Pure" parent="Theme.Blue">
@ -65,7 +57,7 @@
</style>
<style name="Theme.Yellow" parent="Theme.Material3.Dark.NoActionBar">
<style name="Theme.Yellow" parent="BaseTheme">
<item name="colorPrimary">@color/yellow_dark_accentLight</item>
<item name="colorOnPrimary">@color/yellow_dark_accentDark</item>
@ -77,10 +69,6 @@
<item name="android:colorBackground">@color/yellow_dark_background</item>
<item name="colorOnBackground">@color/yellow_dark_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Yellow.Pure" parent="Theme.Yellow">
@ -90,7 +78,7 @@
</style>
<style name="Theme.Green" parent="Theme.Material3.Dark.NoActionBar">
<style name="Theme.Green" parent="BaseTheme">
<item name="colorPrimary">@color/green_dark_accentLight</item>
<item name="colorOnPrimary">@color/green_dark_accentDark</item>
@ -102,10 +90,6 @@
<item name="android:colorBackground">@color/green_dark_background</item>
<item name="colorOnBackground">@color/green_dark_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Green.Pure" parent="Theme.Green">
@ -115,7 +99,7 @@
</style>
<style name="Theme.Purple" parent="Theme.Material3.Dark.NoActionBar">
<style name="Theme.Purple" parent="BaseTheme">
<item name="colorPrimary">@color/purple_dark_accentLight</item>
<item name="colorOnPrimary">@color/purple_dark_accentDark</item>
@ -127,10 +111,6 @@
<item name="android:colorBackground">@color/purple_dark_background</item>
<item name="colorOnBackground">@color/purple_dark_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Purple.Pure" parent="Theme.Purple">

View File

@ -217,7 +217,7 @@
<string name="github">GitHub</string>
<string name="audio_video">Audio and video</string>
<string name="fullscreen_orientation">Fullscreen orientation</string>
<string name="aspect_ratio">Aspect ratio for videos</string>
<string name="aspect_ratio">Video aspect ratio</string>
<string name="auto_rotation">Auto-rotation</string>
<string name="landscape">Landscape</string>
<string name="portrait">Portrait</string>
@ -303,4 +303,11 @@
<string name="take_a_break">Time to take a break</string>
<string name="already_spent_time">You already spent %1$s minutes in the app, time to take a break.</string>
<string name="yt_shorts">Shorts</string>
<string name="no_subtitles_available">No subtitles available</string>
<string name="repeat_mode">Repeat Mode</string>
<string name="resize_mode_fit">Fit</string>
<string name="resize_mode_fill">Fill</string>
<string name="resize_mode_zoom">Zoom</string>
<string name="repeat_mode_none">None</string>
<string name="repeat_mode_current">Current</string>
</resources>

View File

@ -157,4 +157,15 @@
</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="background">?attr/selectableItemBackground</item>
</style>
</resources>

View File

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="MaterialYou">
<style name="BaseTheme" parent="Theme.Material3.Light.NoActionBar">
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
@ -8,14 +8,14 @@
</style>
<style name="Theme.MaterialYou.Pure" parent="MaterialYou">
<style name="Theme.BaseTheme.Pure" parent="BaseTheme">
<item name="android:colorBackground">@android:color/white</item>
<item name="colorSurface">@android:color/white</item>
</style>
<style name="Theme.Red" parent="Theme.Material3.Light.NoActionBar">
<style name="Theme.Red" parent="BaseTheme">
<item name="colorPrimary">@color/red_light_accentLight</item>
<item name="colorOnPrimary">@color/red_light_accentDark</item>
@ -28,10 +28,6 @@
<item name="android:colorBackground">@color/red_light_background</item>
<item name="colorOnBackground">@color/red_light_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Red.Pure" parent="Theme.Red">
@ -41,7 +37,7 @@
</style>
<style name="Theme.Blue" parent="Theme.Material3.Light.NoActionBar">
<style name="Theme.Blue" parent="BaseTheme">
<item name="colorPrimary">@color/blue_light_accentLight</item>
<item name="colorOnPrimary">@color/blue_light_accentDark</item>
@ -54,10 +50,6 @@
<item name="android:colorBackground">@color/blue_light_background</item>
<item name="colorOnBackground">@color/blue_light_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Blue.Pure" parent="Theme.Blue">
@ -67,7 +59,7 @@
</style>
<style name="Theme.Yellow" parent="Theme.Material3.Light.NoActionBar">
<style name="Theme.Yellow" parent="BaseTheme">
<item name="colorPrimary">@color/yellow_light_accentLight</item>
<item name="colorOnPrimary">@color/yellow_light_accentDark</item>
@ -80,10 +72,6 @@
<item name="android:colorBackground">@color/yellow_light_background</item>
<item name="colorOnBackground">@color/yellow_light_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Yellow.Pure" parent="Theme.Yellow">
@ -93,7 +81,7 @@
</style>
<style name="Theme.Green" parent="Theme.Material3.Light.NoActionBar">
<style name="Theme.Green" parent="BaseTheme">
<item name="colorPrimary">@color/green_light_accentLight</item>
<item name="colorOnPrimary">@color/green_light_accentDark</item>
@ -106,10 +94,6 @@
<item name="android:colorBackground">@color/green_light_background</item>
<item name="colorOnBackground">@color/green_light_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Green.Pure" parent="Theme.Green">
@ -119,7 +103,7 @@
</style>
<style name="Theme.Purple" parent="Theme.Material3.Light.NoActionBar">
<style name="Theme.Purple" parent="BaseTheme">
<item name="colorPrimary">@color/purple_light_accentLight</item>
<item name="colorOnPrimary">@color/purple_light_accentDark</item>
@ -132,10 +116,6 @@
<item name="android:colorBackground">@color/purple_light_background</item>
<item name="colorOnBackground">@color/purple_light_background</item>
<item name="android:statusBarColor" tools:targetApi="m">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="Theme.Purple.Pure" parent="Theme.Purple">

View File

@ -27,7 +27,7 @@
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/start"></ConstraintSet>
<ConstraintSet android:id="@+id/start" />
<ConstraintSet android:id="@+id/end"></ConstraintSet>
<ConstraintSet android:id="@+id/end" />
</MotionScene>