diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java index 47e079c1f67e..f9cb5f21c85c 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java @@ -181,7 +181,7 @@ public abstract class FileActivity extends DrawerActivity @Inject public ConnectivityService connectivityService; @Inject - BackgroundJobManager backgroundJobManager; + protected BackgroundJobManager backgroundJobManager; @Inject EditorUtils editorUtils; diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 2f4bfa23c424..c21b7e7db188 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -2828,6 +2828,7 @@ class FileDisplayActivity : initFile() } + @Suppress("LongMethod") private fun initFile() { val userOpt = user if (userOpt.isEmpty) { diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.kt b/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.kt index 83b9d152a4dd..dd6a506c1036 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.kt @@ -98,6 +98,7 @@ internal class LinkShareViewHolder(itemView: View) : RecyclerView.ViewHolder(ite } } + @Suppress("ReturnCount") private fun setSubline(binding: FileDetailsShareLinkShareItemBinding?, context: Context?, publicShare: OCShare) { if (binding == null || context == null) { return diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt index cbbb40d1cd01..72e619f869b0 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListDelegate.kt @@ -344,6 +344,7 @@ class OCFileListDelegate( fileUploadHelper.isUploading(file.remotePath, user.accountName) } + @Suppress("ComplexCondition") private fun showLocalFileIndicator(file: OCFile, holder: ListViewHolder) { var isFolderDown = false if (file.isFolder && !file.isEncrypted && file.fileLength != 0L && file.etag.isNotBlank()) { diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaActivity.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaActivity.kt index 6ed9b4297b0f..abc808e6f1eb 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaActivity.kt @@ -59,9 +59,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.MoreExecutors import com.nextcloud.client.account.User -import com.nextcloud.client.account.UserAccountManager import com.nextcloud.client.di.Injectable -import com.nextcloud.client.jobs.BackgroundJobManager import com.nextcloud.client.jobs.download.FileDownloadHelper import com.nextcloud.client.media.BackgroundPlayerService import com.nextcloud.client.media.ErrorFormat @@ -69,6 +67,7 @@ import com.nextcloud.client.media.ExoplayerListener import com.nextcloud.client.media.NextcloudExoPlayer.createNextcloudExoplayer import com.nextcloud.client.network.ClientFactory import com.nextcloud.client.network.ClientFactory.CreationException +import com.nextcloud.common.NextcloudClient import com.nextcloud.ui.fileactions.FileAction import com.nextcloud.ui.fileactions.FileActionsBottomSheet.Companion.newInstance import com.nextcloud.ui.fileactions.FileActionsBottomSheet.ResultListener @@ -101,7 +100,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.lang.ref.WeakReference -import javax.inject.Inject /** * This activity shows a preview of a downloaded media file (audio or video). @@ -126,15 +124,7 @@ class PreviewMediaActivity : private var savedPlaybackPosition: Long = 0 private var autoplay = true private var streamUri: Uri? = null - - @Inject - lateinit var clientFactory: ClientFactory - - @Inject - lateinit var accountManager: UserAccountManager - - @Inject - lateinit var backgroundJobManager: BackgroundJobManager + private var nextcloudClient: NextcloudClient? = null private lateinit var binding: ActivityPreviewMediaBinding private var emptyListView: ViewGroup? = null @@ -332,6 +322,7 @@ class PreviewMediaActivity : val client = clientRepository.getNextcloudClient() ?: return@launch withContext(Dispatchers.Main) { + nextcloudClient = client videoPlayer = createNextcloudExoplayer(this@PreviewMediaActivity, client) val uniqueSessionId = "preview_session_" + System.currentTimeMillis() videoMediaSession = MediaSession.Builder(this@PreviewMediaActivity, videoPlayer as Player) @@ -491,17 +482,36 @@ class PreviewMediaActivity : PlayerView.ControllerVisibilityListener { visibility -> if (visibility == View.VISIBLE) { windowInsetsController.show(type) - supportActionBar!!.show() + supportActionBar?.show() } else if (visibility == View.GONE) { windowInsetsController.hide(type) - supportActionBar!!.hide() + supportActionBar?.hide() } } ) it.player = videoPlayer + it.setFullscreenButtonClickListener { startFullScreenVideo() } } } + private fun startFullScreenVideo() { + val client = nextcloudClient ?: return + val player = videoPlayer ?: return + val dialog = PreviewVideoFullscreenDialog( + this, + client, + player, + binding.exoplayerView + ) + .apply { + setOnDismissListener { + setupVideoView() + } + } + + dialog.show() + } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.custom_menu_placeholder, menu) @@ -592,7 +602,7 @@ class PreviewMediaActivity : list, this, binding.root, - backgroundJobManager + this.backgroundJobManager ) } diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt index cfc9f506b8fe..5a19c90b77c3 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt @@ -27,11 +27,17 @@ import android.view.MotionEvent import android.view.View import android.view.View.OnTouchListener import android.view.ViewGroup +import android.widget.FrameLayout import androidx.annotation.OptIn import androidx.annotation.StringRes import androidx.core.net.toUri import androidx.core.view.MenuHost import androidx.core.view.MenuProvider +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.marginBottom +import androidx.core.view.updateLayoutParams +import androidx.core.view.updatePadding import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -40,6 +46,7 @@ import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.ExoPlayer import androidx.media3.session.MediaSession +import androidx.media3.ui.DefaultTimeBar import com.nextcloud.client.account.User import com.nextcloud.client.account.UserAccountManager import com.nextcloud.client.di.Injectable @@ -55,7 +62,6 @@ import com.nextcloud.ui.fileactions.FileAction import com.nextcloud.ui.fileactions.FileActionsBottomSheet.Companion.newInstance import com.nextcloud.utils.extensions.getParcelableArgument import com.nextcloud.utils.extensions.getTypedActivity -import com.nextcloud.utils.extensions.logFileSize import com.owncloud.android.R import com.owncloud.android.databinding.FragmentPreviewMediaBinding import com.owncloud.android.datamodel.OCFile @@ -89,7 +95,7 @@ import javax.inject.Inject * * DO NOT CALL IT: an [OCFile] and [User] must be provided for a successful construction */ -@Suppress("NestedBlockDepth", "ComplexMethod", "LongMethod", "TooManyFunctions") +@Suppress("NestedBlockDepth", "ComplexMethod", "LongMethod", "TooManyFunctions", "ReturnCount") class PreviewMediaFragment : FileFragment(), OnTouchListener, @@ -117,6 +123,7 @@ class PreviewMediaFragment : private var exoPlayer: ExoPlayer? = null private var mediaSession: MediaSession? = null private var nextcloudClient: NextcloudClient? = null + private var isFullscreenActive = false @OptIn(UnstableApi::class) override fun onCreate(savedInstanceState: Bundle?) { @@ -167,7 +174,6 @@ class PreviewMediaFragment : } private fun initArguments(bundle: Bundle) { - file.logFileSize(TAG) file = bundle.getParcelableArgument(FILE, OCFile::class.java) user = bundle.getParcelableArgument(USER, User::class.java) @@ -176,6 +182,36 @@ class PreviewMediaFragment : isLivePhoto = bundle.getBoolean(IS_LIVE_PHOTO) } + override fun onResume() { + super.onResume() + applyWindowInsets() + } + + @OptIn(UnstableApi::class) + private fun applyWindowInsets() { + binding.root.post { + val rootInsets = ViewCompat.getRootWindowInsets(binding.root) ?: return@post + val insets = rootInsets.getInsets( + WindowInsetsCompat.Type.systemBars() or + WindowInsetsCompat.Type.displayCutout() + ) + val playerView = binding.exoplayerView + val exoControls = playerView + .findViewById(androidx.media3.ui.R.id.exo_bottom_bar) + val exoProgress = playerView + .findViewById(androidx.media3.ui.R.id.exo_progress) + val progressOriginalMargin = exoProgress?.marginBottom ?: 0 + exoControls?.updateLayoutParams { + bottomMargin = insets.bottom + } + exoProgress?.updateLayoutParams { + bottomMargin = insets.bottom + progressOriginalMargin + } + exoControls?.updatePadding(left = insets.left, right = insets.right) + exoProgress?.updatePadding(left = insets.left, right = insets.right) + } + } + private fun setLoadingView() { binding.progress.visibility = View.VISIBLE binding.emptyView.emptyListView.visibility = View.GONE @@ -196,7 +232,6 @@ class PreviewMediaFragment : override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - file.logFileSize(TAG) toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_LOCKED_CLOSED) outState.run { @@ -431,7 +466,6 @@ class PreviewMediaFragment : } } - @Suppress("ReturnCount") private fun loadStreamUrl(user: User?, clientFactory: ClientFactory?, fileId: Long): Uri? { val client: OwnCloudClient? = try { clientFactory?.create(user) @@ -466,6 +500,9 @@ class PreviewMediaFragment : } override fun onStop() { + if (!isFullscreenActive) { + releaseVideoPlayer() + } releaseVideoPlayer() super.onStop() } @@ -483,13 +520,24 @@ class PreviewMediaFragment : } private fun startFullScreenVideo() { - activity?.let { activity -> - nextcloudClient?.let { client -> - exoPlayer?.let { player -> - PreviewVideoFullscreenDialog(activity, client, player, binding.exoplayerView).show() - } + val activity = activity ?: return + val client = nextcloudClient ?: return + val player = exoPlayer ?: return + + isFullscreenActive = true + val dialog = PreviewVideoFullscreenDialog( + activity, + client, + player, + binding.exoplayerView + ).apply { + setOnDismissListener { + isFullscreenActive = false + setupVideoView() } } + + dialog.show() } override fun onConfigurationChanged(newConfig: Configuration) { @@ -576,20 +624,14 @@ class PreviewMediaFragment : startPlaybackPosition: Long, autoplay: Boolean, isLivePhoto: Boolean - ): PreviewMediaFragment { - val previewMediaFragment = PreviewMediaFragment() - - val bundle = Bundle().apply { + ): PreviewMediaFragment = PreviewMediaFragment().apply { + arguments = Bundle().apply { putParcelable(FILE, fileToDetail) putParcelable(USER, user) putLong(PLAYBACK_POSITION, startPlaybackPosition) putBoolean(AUTOPLAY, autoplay) putBoolean(IS_LIVE_PHOTO, isLivePhoto) } - - previewMediaFragment.arguments = bundle - - return previewMediaFragment } /** diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt index dd1e6814eccc..98a81226d44d 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewVideoFullscreenDialog.kt @@ -131,6 +131,7 @@ class PreviewVideoFullscreenDialog( sourceView.showController() } dismiss() + isEnabled = false } }