Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move some player view related code to OnlinePlayerView.kt #5993

Merged
merged 1 commit into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,9 @@ object PlayerHelper {
}
}

/**
* Handle basic [PlayerEvent]'s that can be handled by the player itself without context
*/
fun handlePlayerAction(player: Player, playerEvent: PlayerEvent): Boolean {
return when (playerEvent) {
PlayerEvent.PlayPause -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.PowerManager
import android.text.format.DateUtils
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
Expand All @@ -32,7 +31,6 @@ import androidx.core.os.postDelayed
import androidx.core.view.SoftwareKeyboardControllerCompat
import androidx.core.view.WindowCompat
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
Expand Down Expand Up @@ -102,7 +100,6 @@ import com.github.libretube.ui.models.CommentsViewModel
import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.ui.sheets.BaseBottomSheet
import com.github.libretube.ui.sheets.CommentsSheet
import com.github.libretube.ui.sheets.PlayingQueueSheet
import com.github.libretube.ui.sheets.StatsSheet
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.OnlineTimeFrameReceiver
Expand Down Expand Up @@ -160,9 +157,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
Executors.newCachedThreadPool()
)

// SponsorBlock
private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled

private val handler = Handler(Looper.getMainLooper())

private var seekBarPreviewListener: SeekbarPreviewListener? = null
Expand Down Expand Up @@ -271,7 +265,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}

override fun onEvents(player: Player, events: Player.Events) {
updateDisplayedDuration()
super.onEvents(player, events)

if (events.containsAny(
Expand Down Expand Up @@ -522,7 +515,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
playerBinding.closeImageButton.setOnClickListener {
onManualPlayerClose()
}
playerBinding.autoPlay.isVisible = true

binding.playImageView.setOnClickListener {
exoPlayer.togglePlayPauseState()
Expand All @@ -540,28 +532,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
CommentsSheet().show(childFragmentManager)
}

playerBinding.queueToggle.isVisible = true
playerBinding.queueToggle.setOnClickListener {
PlayingQueueSheet().show(childFragmentManager, null)
}

// FullScreen button trigger
// hide fullscreen button if autorotation enabled
playerBinding.fullscreen.setOnClickListener {
toggleFullscreen()
}

val updateSbImageResource = {
playerBinding.sbToggle.setImageResource(
if (sponsorBlockEnabled) R.drawable.ic_sb_enabled else R.drawable.ic_sb_disabled
)
}
updateSbImageResource()
playerBinding.sbToggle.setOnClickListener {
sponsorBlockEnabled = !sponsorBlockEnabled
updateSbImageResource()
}

// share button
binding.relPlayerShare.setOnClickListener {
if (!this::streams.isInitialized) return@setOnClickListener
Expand Down Expand Up @@ -695,16 +671,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
updateFullscreenOrientation()

commentsViewModel.setCommentSheetExpand(null)
playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen_exit)
playerBinding.exoTitle.isVisible = true

updateResolutionOnFullscreenChange(true)

openOrCloseFullscreenDialog(true)

binding.player.updateMarginsByFullscreenMode()

updateFullscreenButtonVisibility()
}

@SuppressLint("SourceLockedOrientationActivity")
Expand All @@ -718,8 +690,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}

viewModel.isFullscreen.value = false
playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen)
playerBinding.exoTitle.isInvisible = true

if (!PlayerHelper.autoFullscreenEnabled) {
mainActivity.requestedOrientation = mainActivity.screenOrientationPref
Expand All @@ -729,12 +699,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
updateResolutionOnFullscreenChange(false)

binding.player.updateMarginsByFullscreenMode()

updateFullscreenButtonVisibility()
}

private fun updateFullscreenButtonVisibility() {
playerBinding.fullscreen.isInvisible = PlayerHelper.autoFullscreenEnabled
}

/**
Expand Down Expand Up @@ -881,7 +845,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
if (!exoPlayer.isPlaying || !PlayerHelper.sponsorBlockEnabled) return

handler.postDelayed(this::checkForSegments, 100)
if (!sponsorBlockEnabled || viewModel.segments.isEmpty()) return
if (!viewModel.sponsorBlockEnabled || viewModel.segments.isEmpty()) return

exoPlayer.checkForSegments(
requireContext(),
Expand Down Expand Up @@ -949,7 +913,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
) {
setFullscreen()
}
updateFullscreenButtonVisibility()

binding.player.apply {
useController = false
Expand Down Expand Up @@ -1000,7 +963,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
withContext(Dispatchers.Main) {
playerBinding.exoProgress.setSegments(viewModel.segments)
playerBinding.sbToggle.isVisible = true
updateDisplayedDuration()
}
viewModel.segments.firstOrNull { it.category == PlayerHelper.SPONSOR_HIGHLIGHT_CATEGORY }
?.let {
Expand Down Expand Up @@ -1082,8 +1044,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
this.streams.uploader
)

syncQueueButtons()

// seekbar preview setup
playerBinding.seekbarPreview.isGone = true
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
Expand Down Expand Up @@ -1137,39 +1097,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}
}

/**
* Update the displayed duration of the video
*/
private fun updateDisplayedDuration() {
if (!this::streams.isInitialized || streams.livestream || _binding == null) return

val duration = exoPlayer.duration / 1000
if (duration < 0) return

val durationWithoutSegments = duration - viewModel.segments.sumOf {
val (start, end) = it.segmentStartAndEnd
end.toDouble() - start.toDouble()
}.toLong()
val durationString = DateUtils.formatElapsedTime(duration)

playerBinding.duration.text = if (durationWithoutSegments < duration) {
"$durationString (${DateUtils.formatElapsedTime(durationWithoutSegments)})"
} else {
durationString
}
}

private fun syncQueueButtons() {
if (!PlayerHelper.skipButtonsEnabled) return

// toggle the visibility of next and prev buttons based on queue and whether the player view is locked
val isPlayerLocked = binding.player.isPlayerLocked
playerBinding.skipPrev.isInvisible = !PlayingQueue.hasPrev() || isPlayerLocked
playerBinding.skipNext.isInvisible = !PlayingQueue.hasNext() || isPlayerLocked

handler.postDelayed(this::syncQueueButtons, 100)
}

private fun updatePlayPauseButton() {
binding.playImageView.setImageResource(PlayerHelper.getPlayPauseActionIcon(exoPlayer))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import com.github.libretube.api.obj.Segment
import com.github.libretube.api.obj.Streams
import com.github.libretube.api.obj.Subtitle
import com.github.libretube.constants.PreferenceKeys

Check failure on line 18 in app/src/main/java/com/github/libretube/ui/models/PlayerViewModel.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Unused import Raw Output: app/src/main/java/com/github/libretube/ui/models/PlayerViewModel.kt:18:1: error: Unused import (standard:no-unused-imports)
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.helpers.PreferenceHelper

Check failure on line 20 in app/src/main/java/com/github/libretube/ui/models/PlayerViewModel.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Unused import Raw Output: app/src/main/java/com/github/libretube/ui/models/PlayerViewModel.kt:20:1: error: Unused import (standard:no-unused-imports)
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.deArrow
import java.io.IOException
Expand Down Expand Up @@ -51,6 +53,7 @@
val chaptersLiveData = MutableLiveData<List<ChapterSegment>>()

val chapters get() = chaptersLiveData.value.orEmpty()
var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled

/**
* @return pair of the stream info and the error message if the request was not successful
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,7 @@
player?.addListener(object : Player.Listener {
override fun onEvents(player: Player, events: Player.Events) {
super.onEvents(player, events)
if (events.containsAny(
Player.EVENT_PLAYBACK_STATE_CHANGED,
Player.EVENT_IS_PLAYING_CHANGED,
Player.EVENT_PLAY_WHEN_READY_CHANGED
)
) {
binding.playPauseBTN.setImageResource(
PlayerHelper.getPlayPauseActionIcon(player)
)

// keep screen on if the video is playing
keepScreenOn = player.isPlaying == true
onPlayerEvent(player, events)
}
this@CustomExoPlayerView.onPlaybackEvents(player, events)
}
})

Expand Down Expand Up @@ -820,6 +807,23 @@
return true
}

open fun onPlaybackEvents(player: Player, events: Player.Events) {

Check failure on line 810 in app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Newline expected after opening parenthesis Raw Output: app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt:810:31: error: Newline expected after opening parenthesis (standard:function-signature)

Check failure on line 810 in app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Parameter should start on a newline Raw Output: app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt:810:47: error: Parameter should start on a newline (standard:function-signature)

Check failure on line 810 in app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Newline expected before closing parenthesis Raw Output: app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt:810:68: error: Newline expected before closing parenthesis (standard:function-signature)
if (events.containsAny(
Player.EVENT_PLAYBACK_STATE_CHANGED,
Player.EVENT_IS_PLAYING_CHANGED,
Player.EVENT_PLAY_WHEN_READY_CHANGED

Check failure on line 814 in app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt:814:53: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)
)
) {
binding.playPauseBTN.setImageResource(
PlayerHelper.getPlayPauseActionIcon(player)

Check failure on line 818 in app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt:818:60: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)
)

// keep screen on if the video is playing
keepScreenOn = player.isPlaying == true
onPlayerEvent(player, events)
}
}

open fun minimizeOrExitPlayer() = Unit

abstract fun getChapters(): List<ChapterSegment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import android.content.Context
import android.os.Bundle
import android.text.format.DateUtils
import android.util.AttributeSet
import android.view.Window
import androidx.core.os.bundleOf
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import androidx.media3.common.C
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.trackselection.TrackSelector
import com.github.libretube.R
Expand All @@ -24,6 +27,7 @@
import com.github.libretube.ui.dialogs.SubmitSegmentDialog
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.ui.sheets.PlayingQueueSheet
import com.github.libretube.util.PlayingQueue

@UnstableApi
Expand Down Expand Up @@ -154,14 +158,39 @@
playerViewModel.isFullscreen.observe(viewLifecycleOwner) { isFullscreen ->
WindowHelper.toggleFullscreen(activity.window, isFullscreen)
updateTopBarMargin()

binding.fullscreen.isInvisible = PlayerHelper.autoFullscreenEnabled
val fullscreenDrawable = if (isFullscreen) R.drawable.ic_fullscreen_exit else R.drawable.ic_fullscreen
binding.fullscreen.setImageResource(fullscreenDrawable)

binding.exoTitle.isInvisible = !isFullscreen
}

binding.autoPlay.isVisible = true
binding.autoPlay.isChecked = PlayerHelper.autoPlayEnabled

binding.autoPlay.setOnCheckedChangeListener { _, isChecked ->
PlayerHelper.autoPlayEnabled = isChecked
}

binding.queueToggle.isVisible = true
binding.queueToggle.setOnClickListener {
PlayingQueueSheet().show(activity.supportFragmentManager, null)
}

val updateSbImageResource = {
binding.sbToggle.setImageResource(
if (playerViewModel.sponsorBlockEnabled) R.drawable.ic_sb_enabled else R.drawable.ic_sb_disabled

Check failure on line 183 in app/src/main/java/com/github/libretube/ui/views/OnlinePlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/ui/views/OnlinePlayerView.kt:183:113: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)
)
}
updateSbImageResource()
binding.sbToggle.setOnClickListener {
playerViewModel.sponsorBlockEnabled = !playerViewModel.sponsorBlockEnabled
updateSbImageResource()
}

syncQueueButtons()

binding.sbSubmit.isVisible = PreferenceHelper.getBoolean(PreferenceKeys.CONTRIBUTE_TO_SB, false)
binding.sbSubmit.setOnClickListener {
val submitSegmentDialog = SubmitSegmentDialog()
Expand Down Expand Up @@ -189,6 +218,38 @@
)
}

private fun syncQueueButtons() {
if (!PlayerHelper.skipButtonsEnabled) return

// toggle the visibility of next and prev buttons based on queue and whether the player view is locked
binding.skipPrev.isInvisible = !PlayingQueue.hasPrev() || isPlayerLocked
binding.skipNext.isInvisible = !PlayingQueue.hasNext() || isPlayerLocked

handler.postDelayed(this::syncQueueButtons, 100)
}

/**
* Update the displayed duration of the video
*/
private fun updateDisplayedDuration() {
if (isLive) return

val duration = player?.duration?.div(1000) ?: return
if (duration < 0) return

val durationWithoutSegments = duration - playerViewModel?.segments.orEmpty().sumOf {

Check failure on line 240 in app/src/main/java/com/github/libretube/ui/views/OnlinePlayerView.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 A multiline expression should start on a new line Raw Output: app/src/main/java/com/github/libretube/ui/views/OnlinePlayerView.kt:240:39: error: A multiline expression should start on a new line (standard:multiline-expression-wrapping)
val (start, end) = it.segmentStartAndEnd
end.toDouble() - start.toDouble()
}.toLong()
val durationString = DateUtils.formatElapsedTime(duration)

binding.duration.text = if (durationWithoutSegments < duration) {
"$durationString (${DateUtils.formatElapsedTime(durationWithoutSegments)})"
} else {
durationString
}
}

override fun getWindow(): Window = currentWindow ?: activity.window

override fun hideController() {
Expand Down Expand Up @@ -219,4 +280,9 @@
override fun getChapters(): List<ChapterSegment> {
return playerViewModel?.chapters.orEmpty()
}

override fun onPlaybackEvents(player: Player, events: Player.Events) {
super.onPlaybackEvents(player, events)
updateDisplayedDuration()
}
}
Loading