Dismiss playback actions popups on fragment detach (#4365)

* Dismiss playback actions popups on fragment detach

* Update CONTRIBUTORS.md

(cherry picked from commit d91d873c61)
This commit is contained in:
Catherine Gilbert authored and Niels van Velzen committed 2025-01-06 12:36:37 +01:00
1 parent 3ca8667d32
commit f7839968b2
7 files changed
+77 -19

No files matched your search

+1
View File
@@ -14,6 +14,7 @@
- [mohd-akram](https://github.com/mohd-akram)
- [3l0w](https://github.com/3l0w)
- [MajMongoose](https://github.com/majmongoose)
- [Olaren15](https://github.com/Olaren15)
# Emby Contributors
@@ -109,6 +109,13 @@ public class CustomPlaybackTransportControlGlue extends PlaybackTransportControl
protected void onDetachedFromHost() {
mHandler.removeCallbacks(mRefreshEndTime);
mHandler.removeCallbacks(mRefreshViewVisibility);
closedCaptionsAction.removePopup();
playbackSpeedAction.dismissPopup();
selectAudioAction.dismissPopup();
selectQualityAction.dismissPopup();
zoomAction.dismissPopup();
super.onDetachedFromHost();
}
@@ -169,6 +176,7 @@ public class CustomPlaybackTransportControlGlue extends PlaybackTransportControl
super.onBindRowViewHolder(vh, item);
vh.setOnKeyListener(CustomPlaybackTransportControlGlue.this);
}
@Override
protected void onUnbindRowViewHolder(RowPresenter.ViewHolder vh) {
super.onUnbindRowViewHolder(vh);
@@ -17,6 +17,8 @@ class ClosedCaptionsAction(
context: Context,
customPlaybackTransportControlGlue: CustomPlaybackTransportControlGlue,
) : CustomAction(context, customPlaybackTransportControlGlue) {
private var popup: PopupMenu? = null
init {
initializeWithIcon(R.drawable.ic_select_subtitle)
}
@@ -34,7 +36,8 @@ class ClosedCaptionsAction(
}
videoPlayerAdapter.leanbackOverlayFragment.setFading(false)
PopupMenu(context, view, Gravity.END).apply {
removePopup()
popup = PopupMenu(context, view, Gravity.END).apply {
with(menu) {
var order = 0
add(0, -1, order++, context.getString(R.string.lbl_none)).apply {
@@ -51,11 +54,19 @@ class ClosedCaptionsAction(
setGroupCheckable(0, true, false)
}
setOnDismissListener { videoPlayerAdapter.leanbackOverlayFragment.setFading(true) }
setOnDismissListener {
videoPlayerAdapter.leanbackOverlayFragment.setFading(true)
popup = null
}
setOnMenuItemClickListener { item ->
playbackController.setSubtitleIndex(item.itemId)
true
}
}.show()
}
popup?.show()
}
fun removePopup() {
popup?.dismiss()
}
}
@@ -18,6 +18,7 @@ class PlaybackSpeedAction(
) : CustomAction(context, customPlaybackTransportControlGlue) {
private val speedController = VideoSpeedController(playbackController)
private val speeds = VideoSpeedController.SpeedSteps.entries.toTypedArray()
private var popup: PopupMenu? = null
init {
initializeWithIcon(R.drawable.ic_playback_speed)
@@ -30,17 +31,20 @@ class PlaybackSpeedAction(
view: View,
) {
videoPlayerAdapter.leanbackOverlayFragment.setFading(false)
val speedMenu = populateMenu(context, view, speedController)
dismissPopup()
popup = populateMenu(context, view, speedController)
speedMenu.setOnDismissListener { videoPlayerAdapter.leanbackOverlayFragment.setFading(true) }
popup?.setOnDismissListener {
videoPlayerAdapter.leanbackOverlayFragment.setFading(true)
popup = null
}
speedMenu.setOnMenuItemClickListener { menuItem ->
popup?.setOnMenuItemClickListener { menuItem ->
speedController.currentSpeed = speeds[menuItem.itemId]
speedMenu.dismiss()
true
}
speedMenu.show()
popup?.show()
}
private fun populateMenu(
@@ -57,4 +61,7 @@ class PlaybackSpeedAction(
menu.getItem(speeds.indexOf(speedController.currentSpeed)).isChecked = true
}
fun dismissPopup() {
popup?.dismiss()
}
}
@@ -8,7 +8,6 @@ import org.jellyfin.androidtv.R
import org.jellyfin.androidtv.ui.playback.PlaybackController
import org.jellyfin.androidtv.ui.playback.PlaybackManager
import org.jellyfin.androidtv.ui.playback.overlay.CustomPlaybackTransportControlGlue
import org.jellyfin.androidtv.ui.playback.overlay.LeanbackOverlayFragment
import org.jellyfin.androidtv.ui.playback.overlay.VideoPlayerAdapter
class SelectAudioAction(
@@ -16,6 +15,8 @@ class SelectAudioAction(
customPlaybackTransportControlGlue: CustomPlaybackTransportControlGlue,
private val playbackManager: PlaybackManager,
) : CustomAction(context, customPlaybackTransportControlGlue) {
private var popup: PopupMenu? = null
init {
initializeWithIcon(R.drawable.ic_select_audio)
}
@@ -31,7 +32,8 @@ class SelectAudioAction(
?: return
val currentAudioIndex = playbackController.audioStreamIndex
PopupMenu(context, view, Gravity.END).apply {
dismissPopup()
popup = PopupMenu(context, view, Gravity.END).apply {
with(menu) {
for (track in audioTracks) {
add(0, track.index, track.index, track.displayTitle).apply {
@@ -41,11 +43,19 @@ class SelectAudioAction(
setGroupCheckable(0, true, false)
}
setOnDismissListener { videoPlayerAdapter.leanbackOverlayFragment.setFading(true) }
setOnDismissListener {
videoPlayerAdapter.leanbackOverlayFragment.setFading(true)
popup = null
}
setOnMenuItemClickListener { item ->
playbackController.switchAudioStream(item.itemId)
true
}
}.show()
}
popup?.show()
}
fun dismissPopup() {
popup?.dismiss()
}
}
@@ -20,6 +20,7 @@ class SelectQualityAction(
private val previousQualitySelection = userPreferences[UserPreferences.maxBitrate]
private val qualityController = VideoQualityController(previousQualitySelection, userPreferences)
private val qualityProfiles = getQualityProfiles(context)
private var popup: PopupMenu? = null
init {
initializeWithIcon(R.drawable.ic_select_quality)
@@ -32,7 +33,8 @@ class SelectQualityAction(
view: View,
) {
videoPlayerAdapter.leanbackOverlayFragment.setFading(false)
PopupMenu(context, view, Gravity.END).apply {
dismissPopup()
popup = PopupMenu(context, view, Gravity.END).apply {
qualityProfiles.values.forEachIndexed { i, selected ->
menu.add(0, i, i, selected)
}
@@ -45,13 +47,21 @@ class SelectQualityAction(
}
}
setOnDismissListener { videoPlayerAdapter.leanbackOverlayFragment.setFading(true) }
setOnDismissListener {
videoPlayerAdapter.leanbackOverlayFragment.setFading(true)
popup = null
}
setOnMenuItemClickListener { menuItem ->
qualityController.currentQuality = qualityProfiles.keys.elementAt(menuItem.itemId)
playbackController.refreshStream()
dismiss()
true
}
}.show()
}
popup?.show()
}
fun dismissPopup() {
popup?.dismiss()
}
}
@@ -3,6 +3,7 @@ package org.jellyfin.androidtv.ui.playback.overlay.action
import android.content.Context
import android.view.Gravity
import android.view.View
import android.widget.PopupMenu
import org.jellyfin.androidtv.R
import org.jellyfin.androidtv.preference.constant.ZoomMode
import org.jellyfin.androidtv.ui.playback.PlaybackController
@@ -14,6 +15,8 @@ class ZoomAction(
context: Context,
customPlaybackTransportControlGlue: CustomPlaybackTransportControlGlue,
) : CustomAction(context, customPlaybackTransportControlGlue) {
private var popup: PopupMenu? = null
init {
initializeWithIcon(R.drawable.ic_aspect_ratio)
}
@@ -25,7 +28,8 @@ class ZoomAction(
view: View,
) {
videoPlayerAdapter.leanbackOverlayFragment.setFading(false)
val popup = popupMenu(context, view, Gravity.END) {
dismissPopup()
popup = popupMenu(context, view, Gravity.END) {
item(context.getString(R.string.lbl_fit)) {
playbackController.setZoom(ZoomMode.FIT)
}.apply {
@@ -44,8 +48,15 @@ class ZoomAction(
isChecked = playbackController.zoomMode == ZoomMode.STRETCH
}
}
popup.menu.setGroupCheckable(0, true, true)
popup.setOnDismissListener { videoPlayerAdapter.leanbackOverlayFragment.setFading(true) }
popup.show()
popup?.menu?.setGroupCheckable(0, true, true)
popup?.setOnDismissListener {
videoPlayerAdapter.leanbackOverlayFragment.setFading(true)
popup = null
}
popup?.show()
}
fun dismissPopup() {
popup?.dismiss()
}
}