Skip to content

Commit 836a039

Browse files
Merge pull request #16714 from nextcloud/fix/preview-video-buttons
fix(preview-video): controls, back button behaviour
2 parents 21f6d0d + e73ce9f commit 836a039

7 files changed

Lines changed: 90 additions & 34 deletions

File tree

app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public abstract class FileActivity extends DrawerActivity
181181
@Inject public ConnectivityService connectivityService;
182182

183183
@Inject
184-
BackgroundJobManager backgroundJobManager;
184+
protected BackgroundJobManager backgroundJobManager;
185185

186186
@Inject
187187
EditorUtils editorUtils;

app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,6 +2828,7 @@ class FileDisplayActivity :
28282828
initFile()
28292829
}
28302830

2831+
@Suppress("LongMethod")
28312832
private fun initFile() {
28322833
val userOpt = user
28332834
if (userOpt.isEmpty) {

app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ internal class LinkShareViewHolder(itemView: View) : RecyclerView.ViewHolder(ite
9898
}
9999
}
100100

101+
@Suppress("ReturnCount")
101102
private fun setSubline(binding: FileDetailsShareLinkShareItemBinding?, context: Context?, publicShare: OCShare) {
102103
if (binding == null || context == null) {
103104
return

app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ class OCFileListDelegate(
344344
fileUploadHelper.isUploading(file.remotePath, user.accountName)
345345
}
346346

347+
@Suppress("ComplexCondition")
347348
private fun showLocalFileIndicator(file: OCFile, holder: ListViewHolder) {
348349
var isFolderDown = false
349350
if (file.isFolder && !file.isEncrypted && file.fileLength != 0L && file.etag.isNotBlank()) {

app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaActivity.kt

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,15 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
5959
import com.google.common.util.concurrent.ListenableFuture
6060
import com.google.common.util.concurrent.MoreExecutors
6161
import com.nextcloud.client.account.User
62-
import com.nextcloud.client.account.UserAccountManager
6362
import com.nextcloud.client.di.Injectable
64-
import com.nextcloud.client.jobs.BackgroundJobManager
6563
import com.nextcloud.client.jobs.download.FileDownloadHelper
6664
import com.nextcloud.client.media.BackgroundPlayerService
6765
import com.nextcloud.client.media.ErrorFormat
6866
import com.nextcloud.client.media.ExoplayerListener
6967
import com.nextcloud.client.media.NextcloudExoPlayer.createNextcloudExoplayer
7068
import com.nextcloud.client.network.ClientFactory
7169
import com.nextcloud.client.network.ClientFactory.CreationException
70+
import com.nextcloud.common.NextcloudClient
7271
import com.nextcloud.ui.fileactions.FileAction
7372
import com.nextcloud.ui.fileactions.FileActionsBottomSheet.Companion.newInstance
7473
import com.nextcloud.ui.fileactions.FileActionsBottomSheet.ResultListener
@@ -101,7 +100,6 @@ import kotlinx.coroutines.Dispatchers
101100
import kotlinx.coroutines.launch
102101
import kotlinx.coroutines.withContext
103102
import java.lang.ref.WeakReference
104-
import javax.inject.Inject
105103

106104
/**
107105
* This activity shows a preview of a downloaded media file (audio or video).
@@ -126,15 +124,7 @@ class PreviewMediaActivity :
126124
private var savedPlaybackPosition: Long = 0
127125
private var autoplay = true
128126
private var streamUri: Uri? = null
129-
130-
@Inject
131-
lateinit var clientFactory: ClientFactory
132-
133-
@Inject
134-
lateinit var accountManager: UserAccountManager
135-
136-
@Inject
137-
lateinit var backgroundJobManager: BackgroundJobManager
127+
private var nextcloudClient: NextcloudClient? = null
138128

139129
private lateinit var binding: ActivityPreviewMediaBinding
140130
private var emptyListView: ViewGroup? = null
@@ -332,6 +322,7 @@ class PreviewMediaActivity :
332322
val client = clientRepository.getNextcloudClient() ?: return@launch
333323

334324
withContext(Dispatchers.Main) {
325+
nextcloudClient = client
335326
videoPlayer = createNextcloudExoplayer(this@PreviewMediaActivity, client)
336327
val uniqueSessionId = "preview_session_" + System.currentTimeMillis()
337328
videoMediaSession = MediaSession.Builder(this@PreviewMediaActivity, videoPlayer as Player)
@@ -491,17 +482,36 @@ class PreviewMediaActivity :
491482
PlayerView.ControllerVisibilityListener { visibility ->
492483
if (visibility == View.VISIBLE) {
493484
windowInsetsController.show(type)
494-
supportActionBar!!.show()
485+
supportActionBar?.show()
495486
} else if (visibility == View.GONE) {
496487
windowInsetsController.hide(type)
497-
supportActionBar!!.hide()
488+
supportActionBar?.hide()
498489
}
499490
}
500491
)
501492
it.player = videoPlayer
493+
it.setFullscreenButtonClickListener { startFullScreenVideo() }
502494
}
503495
}
504496

497+
private fun startFullScreenVideo() {
498+
val client = nextcloudClient ?: return
499+
val player = videoPlayer ?: return
500+
val dialog = PreviewVideoFullscreenDialog(
501+
this,
502+
client,
503+
player,
504+
binding.exoplayerView
505+
)
506+
.apply {
507+
setOnDismissListener {
508+
setupVideoView()
509+
}
510+
}
511+
512+
dialog.show()
513+
}
514+
505515
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
506516
menuInflater.inflate(R.menu.custom_menu_placeholder, menu)
507517

@@ -592,7 +602,7 @@ class PreviewMediaActivity :
592602
list,
593603
this,
594604
binding.root,
595-
backgroundJobManager
605+
this.backgroundJobManager
596606
)
597607
}
598608

app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ import android.view.MotionEvent
2727
import android.view.View
2828
import android.view.View.OnTouchListener
2929
import android.view.ViewGroup
30+
import android.widget.FrameLayout
3031
import androidx.annotation.OptIn
3132
import androidx.annotation.StringRes
3233
import androidx.core.net.toUri
3334
import androidx.core.view.MenuHost
3435
import androidx.core.view.MenuProvider
36+
import androidx.core.view.ViewCompat
37+
import androidx.core.view.WindowInsetsCompat
38+
import androidx.core.view.marginBottom
39+
import androidx.core.view.updateLayoutParams
40+
import androidx.core.view.updatePadding
3541
import androidx.drawerlayout.widget.DrawerLayout
3642
import androidx.lifecycle.Lifecycle
3743
import androidx.lifecycle.lifecycleScope
@@ -40,6 +46,7 @@ import androidx.media3.common.Player
4046
import androidx.media3.common.util.UnstableApi
4147
import androidx.media3.exoplayer.ExoPlayer
4248
import androidx.media3.session.MediaSession
49+
import androidx.media3.ui.DefaultTimeBar
4350
import com.nextcloud.client.account.User
4451
import com.nextcloud.client.account.UserAccountManager
4552
import com.nextcloud.client.di.Injectable
@@ -55,7 +62,6 @@ import com.nextcloud.ui.fileactions.FileAction
5562
import com.nextcloud.ui.fileactions.FileActionsBottomSheet.Companion.newInstance
5663
import com.nextcloud.utils.extensions.getParcelableArgument
5764
import com.nextcloud.utils.extensions.getTypedActivity
58-
import com.nextcloud.utils.extensions.logFileSize
5965
import com.owncloud.android.R
6066
import com.owncloud.android.databinding.FragmentPreviewMediaBinding
6167
import com.owncloud.android.datamodel.OCFile
@@ -89,7 +95,7 @@ import javax.inject.Inject
8995
*
9096
* DO NOT CALL IT: an [OCFile] and [User] must be provided for a successful construction
9197
*/
92-
@Suppress("NestedBlockDepth", "ComplexMethod", "LongMethod", "TooManyFunctions")
98+
@Suppress("NestedBlockDepth", "ComplexMethod", "LongMethod", "TooManyFunctions", "ReturnCount")
9399
class PreviewMediaFragment :
94100
FileFragment(),
95101
OnTouchListener,
@@ -117,6 +123,7 @@ class PreviewMediaFragment :
117123
private var exoPlayer: ExoPlayer? = null
118124
private var mediaSession: MediaSession? = null
119125
private var nextcloudClient: NextcloudClient? = null
126+
private var isFullscreenActive = false
120127

121128
@OptIn(UnstableApi::class)
122129
override fun onCreate(savedInstanceState: Bundle?) {
@@ -167,7 +174,6 @@ class PreviewMediaFragment :
167174
}
168175

169176
private fun initArguments(bundle: Bundle) {
170-
file.logFileSize(TAG)
171177
file = bundle.getParcelableArgument(FILE, OCFile::class.java)
172178
user = bundle.getParcelableArgument(USER, User::class.java)
173179

@@ -176,6 +182,36 @@ class PreviewMediaFragment :
176182
isLivePhoto = bundle.getBoolean(IS_LIVE_PHOTO)
177183
}
178184

185+
override fun onResume() {
186+
super.onResume()
187+
applyWindowInsets()
188+
}
189+
190+
@OptIn(UnstableApi::class)
191+
private fun applyWindowInsets() {
192+
binding.root.post {
193+
val rootInsets = ViewCompat.getRootWindowInsets(binding.root) ?: return@post
194+
val insets = rootInsets.getInsets(
195+
WindowInsetsCompat.Type.systemBars() or
196+
WindowInsetsCompat.Type.displayCutout()
197+
)
198+
val playerView = binding.exoplayerView
199+
val exoControls = playerView
200+
.findViewById<FrameLayout>(androidx.media3.ui.R.id.exo_bottom_bar)
201+
val exoProgress = playerView
202+
.findViewById<DefaultTimeBar>(androidx.media3.ui.R.id.exo_progress)
203+
val progressOriginalMargin = exoProgress?.marginBottom ?: 0
204+
exoControls?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
205+
bottomMargin = insets.bottom
206+
}
207+
exoProgress?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
208+
bottomMargin = insets.bottom + progressOriginalMargin
209+
}
210+
exoControls?.updatePadding(left = insets.left, right = insets.right)
211+
exoProgress?.updatePadding(left = insets.left, right = insets.right)
212+
}
213+
}
214+
179215
private fun setLoadingView() {
180216
binding.progress.visibility = View.VISIBLE
181217
binding.emptyView.emptyListView.visibility = View.GONE
@@ -196,7 +232,6 @@ class PreviewMediaFragment :
196232

197233
override fun onSaveInstanceState(outState: Bundle) {
198234
super.onSaveInstanceState(outState)
199-
file.logFileSize(TAG)
200235
toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
201236

202237
outState.run {
@@ -431,7 +466,6 @@ class PreviewMediaFragment :
431466
}
432467
}
433468

434-
@Suppress("ReturnCount")
435469
private fun loadStreamUrl(user: User?, clientFactory: ClientFactory?, fileId: Long): Uri? {
436470
val client: OwnCloudClient? = try {
437471
clientFactory?.create(user)
@@ -466,6 +500,9 @@ class PreviewMediaFragment :
466500
}
467501

468502
override fun onStop() {
503+
if (!isFullscreenActive) {
504+
releaseVideoPlayer()
505+
}
469506
releaseVideoPlayer()
470507
super.onStop()
471508
}
@@ -483,13 +520,24 @@ class PreviewMediaFragment :
483520
}
484521

485522
private fun startFullScreenVideo() {
486-
activity?.let { activity ->
487-
nextcloudClient?.let { client ->
488-
exoPlayer?.let { player ->
489-
PreviewVideoFullscreenDialog(activity, client, player, binding.exoplayerView).show()
490-
}
523+
val activity = activity ?: return
524+
val client = nextcloudClient ?: return
525+
val player = exoPlayer ?: return
526+
527+
isFullscreenActive = true
528+
val dialog = PreviewVideoFullscreenDialog(
529+
activity,
530+
client,
531+
player,
532+
binding.exoplayerView
533+
).apply {
534+
setOnDismissListener {
535+
isFullscreenActive = false
536+
setupVideoView()
491537
}
492538
}
539+
540+
dialog.show()
493541
}
494542

495543
override fun onConfigurationChanged(newConfig: Configuration) {
@@ -576,20 +624,14 @@ class PreviewMediaFragment :
576624
startPlaybackPosition: Long,
577625
autoplay: Boolean,
578626
isLivePhoto: Boolean
579-
): PreviewMediaFragment {
580-
val previewMediaFragment = PreviewMediaFragment()
581-
582-
val bundle = Bundle().apply {
627+
): PreviewMediaFragment = PreviewMediaFragment().apply {
628+
arguments = Bundle().apply {
583629
putParcelable(FILE, fileToDetail)
584630
putParcelable(USER, user)
585631
putLong(PLAYBACK_POSITION, startPlaybackPosition)
586632
putBoolean(AUTOPLAY, autoplay)
587633
putBoolean(IS_LIVE_PHOTO, isLivePhoto)
588634
}
589-
590-
previewMediaFragment.arguments = bundle
591-
592-
return previewMediaFragment
593635
}
594636

595637
/**

app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class PreviewVideoFullscreenDialog(
131131
sourceView.showController()
132132
}
133133
dismiss()
134+
isEnabled = false
134135
}
135136
}
136137

0 commit comments

Comments
 (0)