Skip to content

Commit e2cbc0e

Browse files
committed
fix(player): fullscreen handling and display related streams
1 parent 04cd435 commit e2cbc0e

4 files changed

Lines changed: 72 additions & 63 deletions

File tree

app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
478478
DatabaseHolder.Database.downloadDao().findById(videoId)
479479
}
480480

481-
if (localDownloadVersion != null && createNewSession) {
481+
if (!isOffline && localDownloadVersion != null && createNewSession) {
482482
// the dialog must also be visible when in fullscreen, thus we need to use the activity's
483483
// fragment manager and not the one from [PlayerFragment]
484484
val fragmentManager = requireActivity().supportFragmentManager
@@ -718,12 +718,6 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
718718
.show(childFragmentManager)
719719
}
720720

721-
// FullScreen button trigger
722-
// hide fullscreen button if autorotation enabled
723-
playerControlsBinding.fullscreen.setOnClickListener {
724-
toggleFullscreen()
725-
}
726-
727721
// share button
728722
binding.relPlayerShare.setOnClickListener {
729723
if (!this::streams.isInitialized) return@setOnClickListener
@@ -784,7 +778,6 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
784778

785779
DownloadHelper.startDownloadDialog(requireContext(), childFragmentManager, videoId)
786780
}
787-
binding.relPlayerDownload.isVisible = !isOffline
788781

789782
binding.relPlayerScreenshot.setOnClickListener {
790783
if (!this::streams.isInitialized) return@setOnClickListener
@@ -893,12 +886,11 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
893886
/**
894887
* Enter/exit fullscreen or toggle it depending on the current state
895888
*/
896-
fun toggleFullscreen(
897-
isFullscreen: Boolean = commonPlayerViewModel.isFullscreen.value == false
898-
) {
889+
override fun toggleFullscreen() {
899890
binding.player.hideController()
900891

901-
if (isFullscreen) {
892+
val isFullscreen = commonPlayerViewModel.isFullscreen.value == true
893+
if (!isFullscreen) {
902894
// go to fullscreen mode
903895
setFullscreen()
904896
} else {
@@ -1158,7 +1150,13 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
11581150
}
11591151

11601152
// initialize the player view actions
1161-
binding.player.initialize(chaptersViewModel, viewModel, viewLifecycleOwner, this)
1153+
binding.player.initialize(
1154+
chaptersViewModel,
1155+
commonPlayerViewModel,
1156+
viewModel,
1157+
viewLifecycleOwner,
1158+
this
1159+
)
11621160

11631161
if (binding.playerMotionLayout.progress != 1.0f) {
11641162
// show controllers when not in picture in picture mode
@@ -1184,20 +1182,15 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
11841182
streams.uploaderSubscriberCount.formatShort()
11851183
)
11861184
player.isLive = streams.isLive
1187-
relPlayerDownload.isVisible = !streams.isLive
1185+
relPlayerDownload.isVisible = !streams.isLive && !isOffline
11881186
}
11891187
playerControlsBinding.exoTitle.text = streams.title
11901188

11911189
// init the chapters recyclerview
11921190
chaptersViewModel.chaptersLiveData.postValue(streams.chapters)
11931191

1194-
if (PlayerHelper.relatedStreamsEnabled) {
1195-
val relatedLayoutManager = binding.relatedRecView.layoutManager as LinearLayoutManager
1196-
binding.relatedRecView.adapter = VideoCardsAdapter(
1197-
columnWidthDp = if (relatedLayoutManager.orientation == LinearLayoutManager.HORIZONTAL) 250f else null
1198-
).also { adapter ->
1199-
adapter.submitList(streams.relatedStreams.filter { !it.title.isNullOrBlank() })
1200-
}
1192+
lifecycleScope.launch {
1193+
showRelatedStreams()
12011194
}
12021195

12031196
// update the subscribed state
@@ -1227,6 +1220,27 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
12271220
}
12281221
}
12291222

1223+
private suspend fun showRelatedStreams() {
1224+
if (!PlayerHelper.relatedStreamsEnabled) return
1225+
1226+
val relatedStreams = if (isOffline) {
1227+
withContext(Dispatchers.IO) {
1228+
DatabaseHolder.Database.downloadDao().getAll()
1229+
.filter { it.download.videoId != videoId }
1230+
.map { it.download.toStreamItem() }
1231+
}
1232+
} else {
1233+
streams.relatedStreams.filter { !it.title.isNullOrBlank() }
1234+
}
1235+
1236+
val relatedLayoutManager = binding.relatedRecView.layoutManager as LinearLayoutManager
1237+
binding.relatedRecView.adapter = VideoCardsAdapter(
1238+
columnWidthDp = if (relatedLayoutManager.orientation == LinearLayoutManager.HORIZONTAL) 250f else null
1239+
).also { adapter ->
1240+
adapter.submitList(relatedStreams)
1241+
}
1242+
}
1243+
12301244
private fun showAutoPlayCountdown() {
12311245
if (!PlayingQueue.hasNext()) return
12321246

@@ -1281,7 +1295,8 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
12811295

12821296
private suspend fun getTimeFrameReceiver(): TimeFrameReceiver? = withContext(Dispatchers.IO) {
12831297
return@withContext if (isOffline) {
1284-
val downloadItems = DatabaseHolder.Database.downloadDao().getDownloadById(videoId)?.downloadItems
1298+
val downloadItems =
1299+
DatabaseHolder.Database.downloadDao().getDownloadById(videoId)?.downloadItems
12851300
downloadItems?.firstOrNull { it.path.exists() && it.type == FileType.VIDEO }?.path?.let {
12861301
OfflineTimeFrameReceiver(requireContext(), it)
12871302
}
@@ -1449,10 +1464,6 @@ class PlayerFragment : Fragment(R.layout.fragment_player), CustomPlayerCallback
14491464
_binding = null
14501465
}
14511466

1452-
override fun exitFullscreen() {
1453-
unsetFullscreen()
1454-
}
1455-
14561467
override fun getVideoId(): String {
14571468
return videoId
14581469
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.github.libretube.ui.interfaces
22

33
interface CustomPlayerCallback {
4-
fun exitFullscreen()
4+
fun toggleFullscreen()
55
fun getVideoId(): String
66
fun isVideoShort(): Boolean
77
}

app/src/main/java/com/github/libretube/ui/interfaces/PlayerOptions.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ interface PlayerOptions {
99
fun onQualityClicked()
1010
fun onAudioStreamClicked()
1111
fun onStatsClicked()
12-
fun exitFullscreen()
1312
}

app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,24 @@ class CustomExoPlayerView(
192192
playerView = this,
193193
videoFrameView = backgroundBinding.exoContentFrame,
194194
onSwipeUpCompleted = {
195-
if (!isFullscreen()) togglePlayerFullscreen(true)
195+
if (!isFullscreen()) playerCallback?.toggleFullscreen()
196196
},
197-
onSwipeDownCompleted = ::minimizeOrExitPlayer
197+
onSwipeDownCompleted = {
198+
if (isFullscreen()) playerCallback?.toggleFullscreen()
199+
}
198200
)
199201
}
200202

201-
fun initialize(chaptersViewModel: ChaptersViewModel, playerViewModel: PlayerViewModel, viewLifecycleOwner: LifecycleOwner, playerCallback: CustomPlayerCallback) {
203+
fun initialize(
204+
chaptersViewModel: ChaptersViewModel,
205+
commonPlayerViewModel: CommonPlayerViewModel,
206+
playerViewModel: PlayerViewModel,
207+
viewLifecycleOwner: LifecycleOwner,
208+
playerCallback: CustomPlayerCallback
209+
) {
202210
this.chaptersViewModel = chaptersViewModel
203211
this.playerViewModel = playerViewModel
212+
this.commonPlayerViewModel = commonPlayerViewModel
204213
this.viewLifecycleOwner = viewLifecycleOwner
205214
this.playerCallback = playerCallback
206215

@@ -217,6 +226,7 @@ class CustomExoPlayerView(
217226
// don't let the player view show its controls automatically
218227
controllerAutoShow = false
219228

229+
binding.fullscreen.setOnClickListener { playerCallback.toggleFullscreen() }
220230
// locking the player
221231
binding.lockPlayer.setOnClickListener {
222232
// change the locked/unlocked icon
@@ -372,6 +382,7 @@ class CustomExoPlayerView(
372382
updateMarginsByFullscreenMode()
373383

374384
commonPlayerViewModel?.isFullscreen?.observe(viewLifecycleOwner) { isFullscreen ->
385+
Log.e("is full", isFullscreen.toString())
375386
updateTopBarMargin()
376387

377388
binding.fullscreen.isInvisible = PlayerHelper.autoFullscreenEnabled
@@ -977,14 +988,15 @@ class CustomExoPlayerView(
977988
// put normal tracks before auto-generated tracks
978989
.sortedBy { it.roleFlags == PlayerHelper.ROLE_FLAG_AUTO_GEN_SUBTITLE }
979990
.associateWith {
980-
val displayName = Locale.forLanguageTag(it.language.orEmpty()).getDisplayLanguage(Locale.getDefault())
991+
val displayName = Locale.forLanguageTag(it.language.orEmpty())
992+
.getDisplayLanguage(Locale.getDefault())
981993

982-
if (it.roleFlags == PlayerHelper.ROLE_FLAG_AUTO_GEN_SUBTITLE) {
983-
"$displayName (${context.getString(R.string.auto_generated)})"
984-
} else {
985-
displayName
994+
if (it.roleFlags == PlayerHelper.ROLE_FLAG_AUTO_GEN_SUBTITLE) {
995+
"$displayName (${context.getString(R.string.auto_generated)})"
996+
} else {
997+
displayName
998+
}
986999
}
987-
}
9881000

9891001
val currentSubtitle = PlayerHelper.getCurrentPlayedCaptionFormat(player)
9901002
BaseBottomSheet()
@@ -994,10 +1006,11 @@ class CustomExoPlayerView(
9941006
track == currentSubtitle
9951007
}?.value ?: context.getString(R.string.none)
9961008
) { index ->
997-
val captionsFormat = captions.keys.toList().getOrNull(index - 1) ?: return@setSimpleItems
1009+
val captionsFormat =
1010+
captions.keys.toList().getOrNull(index - 1) ?: return@setSimpleItems
9981011

999-
updateCurrentSubtitle(captionsFormat.id)
1000-
playerViewModel?.currentCaptionId = captionsFormat.id
1012+
updateCurrentSubtitle(captionsFormat.id)
1013+
playerViewModel?.currentCaptionId = captionsFormat.id
10011014
}
10021015
.show(supportFragmentManager)
10031016
}
@@ -1070,11 +1083,12 @@ class CustomExoPlayerView(
10701083
fun setPlayerResolution(resolution: Int, isSelectedByUser: Boolean = false) {
10711084
val player = player as? MediaController ?: return
10721085

1073-
val transformedResolution = if (!isSelectedByUser && playerCallback?.isVideoShort() ?: false) {
1074-
ceil(resolution * 16.0 / 9.0).toInt()
1075-
} else {
1076-
resolution
1077-
}
1086+
val transformedResolution =
1087+
if (!isSelectedByUser && playerCallback?.isVideoShort() ?: false) {
1088+
ceil(resolution * 16.0 / 9.0).toInt()
1089+
} else {
1090+
resolution
1091+
}
10781092

10791093
player.sendCustomCommand(
10801094
AbstractPlayerService.runPlayerActionCommand, bundleOf(
@@ -1138,14 +1152,11 @@ class CustomExoPlayerView(
11381152
baseBottomSheet.show(supportFragmentManager)
11391153
}
11401154

1141-
override fun exitFullscreen() {
1142-
playerCallback?.exitFullscreen()
1143-
}
1144-
11451155
override fun onStatsClicked() {
11461156
val player = player ?: return
11471157

1148-
val videoStats = PlayerHelper.getVideoStats(player.currentTracks, playerCallback?.getVideoId().orEmpty())
1158+
val videoStats =
1159+
PlayerHelper.getVideoStats(player.currentTracks, playerCallback?.getVideoId().orEmpty())
11491160
StatsSheet()
11501161
.apply { arguments = bundleOf(IntentData.videoStats to videoStats) }
11511162
.show(supportFragmentManager)
@@ -1414,7 +1425,7 @@ class CustomExoPlayerView(
14141425
}
14151426

14161427
KeyEvent.KEYCODE_F -> {
1417-
togglePlayerFullscreen()
1428+
playerCallback?.toggleFullscreen()
14181429
}
14191430

14201431
else -> return false
@@ -1423,14 +1434,6 @@ class CustomExoPlayerView(
14231434
return true
14241435
}
14251436

1426-
fun togglePlayerFullscreen(isFullscreen: Boolean = !isFullscreen()) {
1427-
try {
1428-
findFragment<PlayerFragment>().toggleFullscreen(isFullscreen)
1429-
} catch (error: IllegalStateException) {
1430-
Log.e(this::class.simpleName, error.message.toString())
1431-
}
1432-
}
1433-
14341437
override fun getViewMeasures(): Pair<Int, Int> {
14351438
return width to height
14361439
}
@@ -1458,10 +1461,6 @@ class CustomExoPlayerView(
14581461
updateDisplayedDuration()
14591462
}
14601463

1461-
fun minimizeOrExitPlayer() {
1462-
exitFullscreen()
1463-
}
1464-
14651464
fun getWindow(): Window = currentWindow ?: activity.window
14661465

14671466
companion object {

0 commit comments

Comments
 (0)