Simple play/pause overlay

This commit is contained in:
Valere 2020-07-08 22:58:27 +02:00
parent e9778d6feb
commit e24d5b3ca4
7 changed files with 53 additions and 10 deletions

View File

@ -21,6 +21,10 @@ sealed class AttachmentEvents {
} }
interface AttachmentEventListener { interface AttachmentEventListener {
fun onEvent(event: AttachmentEvents) fun onEvent(event: AttachmentEvents)
} }
sealed class AttachmentCommands {
object PauseVideo : AttachmentCommands()
object StartVideo : AttachmentCommands()
}

View File

@ -152,6 +152,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
super.onResume() super.onResume()
attachmentsAdapter.onResume(currentPosition) attachmentsAdapter.onResume(currentPosition)
} }
override fun dispatchTouchEvent(ev: MotionEvent): Boolean { override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
// The zoomable view is configured to disallow interception when image is zoomed // The zoomable view is configured to disallow interception when image is zoomed
@ -302,6 +303,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
finish() finish()
} }
public fun handle(commands: AttachmentCommands) {
(attachmentsAdapter.recyclerView?.findViewHolderForAdapterPosition(currentPosition) as? BaseViewHolder)?.let {
it.handleCommand(commands)
}
}
private fun hideSystemUI() { private fun hideSystemUI() {
systemUiVisibility = false systemUiVisibility = false
// Enables regular immersive mode. // Enables regular immersive mode.

View File

@ -31,6 +31,8 @@ abstract class BaseViewHolder constructor(itemView: View) :
open fun entersBackground() {} open fun entersBackground() {}
open fun entersForeground() {} open fun entersForeground() {}
open fun onSelected(selected: Boolean) {} open fun onSelected(selected: Boolean) {}
open fun handleCommand(commands: AttachmentCommands) {}
} }
class AttachmentViewHolder constructor(itemView: View) : class AttachmentViewHolder constructor(itemView: View) :
@ -123,7 +125,6 @@ class AttachmentsAdapter() : RecyclerView.Adapter<BaseViewHolder>() {
return false return false
} }
fun onPause(position: Int) { fun onPause(position: Int) {
val holder = recyclerView?.findViewHolderForAdapterPosition(position) as? BaseViewHolder val holder = recyclerView?.findViewHolderForAdapterPosition(position) as? BaseViewHolder
holder?.entersBackground() holder?.entersBackground()
@ -132,7 +133,6 @@ class AttachmentsAdapter() : RecyclerView.Adapter<BaseViewHolder>() {
fun onResume(position: Int) { fun onResume(position: Int) {
val holder = recyclerView?.findViewHolderForAdapterPosition(position) as? BaseViewHolder val holder = recyclerView?.findViewHolderForAdapterPosition(position) as? BaseViewHolder
holder?.entersForeground() holder?.entersForeground()
} }
// override fun getItemCount(): Int { // override fun getItemCount(): Int {
// return 8 // return 8

View File

@ -26,7 +26,6 @@ import androidx.core.view.isVisible
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import kotlinx.coroutines.selects.select
import java.io.File import java.io.File
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -41,6 +40,7 @@ class VideoViewHolder constructor(itemView: View) :
private var mVideoPath: String? = null private var mVideoPath: String? = null
private var progressDisposable: Disposable? = null private var progressDisposable: Disposable? = null
private var progress: Int = 0 private var progress: Int = 0
private var wasPaused = false
var eventListener: WeakReference<AttachmentEventListener>? = null var eventListener: WeakReference<AttachmentEventListener>? = null
@ -99,7 +99,6 @@ class VideoViewHolder constructor(itemView: View) :
videoView.stopPlayback() videoView.stopPlayback()
videoView.pause() videoView.pause()
} }
} }
override fun entersForeground() { override fun entersForeground() {
@ -111,11 +110,11 @@ class VideoViewHolder constructor(itemView: View) :
if (videoView.isPlaying) { if (videoView.isPlaying) {
progress = videoView.currentPosition progress = videoView.currentPosition
videoView.stopPlayback() videoView.stopPlayback()
progressDisposable?.dispose()
progressDisposable = null
} else { } else {
progress = 0 progress = 0
} }
progressDisposable?.dispose()
progressDisposable = null
} else { } else {
if (mVideoPath != null) { if (mVideoPath != null) {
startPlaying() startPlaying()
@ -144,13 +143,30 @@ class VideoViewHolder constructor(itemView: View) :
} }
videoView.setVideoPath(mVideoPath) videoView.setVideoPath(mVideoPath)
videoView.start() if (!wasPaused) {
if (progress > 0) { videoView.start()
videoView.seekTo(progress) if (progress > 0) {
videoView.seekTo(progress)
}
}
}
override fun handleCommand(commands: AttachmentCommands) {
if (!isSelected) return
when (commands) {
AttachmentCommands.StartVideo -> {
wasPaused = false
videoView.start()
}
AttachmentCommands.PauseVideo -> {
wasPaused = true
videoView.pause()
}
} }
} }
override fun bind(attachmentInfo: AttachmentInfo) { override fun bind(attachmentInfo: AttachmentInfo) {
progress = 0 progress = 0
wasPaused = false
} }
} }

View File

@ -35,6 +35,7 @@ class AttachmentOverlayView @JvmOverloads constructor(
var onShareCallback: (() -> Unit)? = null var onShareCallback: (() -> Unit)? = null
var onBack: (() -> Unit)? = null var onBack: (() -> Unit)? = null
var onPlayPause: ((play: Boolean) -> Unit)? = null
private val counterTextView: TextView private val counterTextView: TextView
private val infoTextView: TextView private val infoTextView: TextView
@ -42,6 +43,8 @@ class AttachmentOverlayView @JvmOverloads constructor(
private val overlayPlayPauseButton: ImageView private val overlayPlayPauseButton: ImageView
private val overlaySeekBar: SeekBar private val overlaySeekBar: SeekBar
var isPlaying = false
val videoControlsGroup: Group val videoControlsGroup: Group
init { init {
@ -61,6 +64,9 @@ class AttachmentOverlayView @JvmOverloads constructor(
findViewById<ImageView>(R.id.overlayShareButton).setOnClickListener { findViewById<ImageView>(R.id.overlayShareButton).setOnClickListener {
onShareCallback?.invoke() onShareCallback?.invoke()
} }
findViewById<ImageView>(R.id.overlayPlayPauseButton).setOnClickListener {
onPlayPause?.invoke(!isPlaying)
}
} }
fun updateWith(counter: String, senderInfo: String) { fun updateWith(counter: String, senderInfo: String) {
@ -74,6 +80,7 @@ class AttachmentOverlayView @JvmOverloads constructor(
overlayPlayPauseButton.setImageResource(if (!event.isPlaying) R.drawable.ic_play_arrow else R.drawable.ic_pause) overlayPlayPauseButton.setImageResource(if (!event.isPlaying) R.drawable.ic_play_arrow else R.drawable.ic_pause)
val safeDuration = (if (event.duration == 0) 100 else event.duration).toFloat() val safeDuration = (if (event.duration == 0) 100 else event.duration).toFloat()
val percent = ((event.progress / safeDuration) * 100f).toInt().coerceAtMost(100) val percent = ((event.progress / safeDuration) * 100f).toInt().coerceAtMost(100)
isPlaying = event.isPlaying
overlaySeekBar.progress = percent overlaySeekBar.progress = percent
} }
} }

View File

@ -57,6 +57,7 @@ class RoomAttachmentProvider(
interface InteractionListener { interface InteractionListener {
fun onDismissTapped() fun onDismissTapped()
fun onShareTapped() fun onShareTapped()
fun onPlayPause(play: Boolean)
} }
var interactionListener: InteractionListener? = null var interactionListener: InteractionListener? = null
@ -197,6 +198,9 @@ class RoomAttachmentProvider(
overlayView?.onShareCallback = { overlayView?.onShareCallback = {
interactionListener?.onShareTapped() interactionListener?.onShareTapped()
} }
overlayView?.onPlayPause = { play ->
interactionListener?.onPlayPause(play)
}
} }
val item = attachments[position] val item = attachments[position]
val dateString = item.root.localDateTime().let { val dateString = item.root.localDateTime().let {

View File

@ -39,6 +39,7 @@ import im.vector.matrix.android.api.session.room.model.message.getFileUrl
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.attachmentviewer.AttachmentCommands
import im.vector.riotx.attachmentviewer.AttachmentViewerActivity import im.vector.riotx.attachmentviewer.AttachmentViewerActivity
import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.di.DaggerScreenComponent import im.vector.riotx.core.di.DaggerScreenComponent
@ -242,6 +243,10 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), RoomAttachmen
animateClose() animateClose()
} }
override fun onPlayPause(play: Boolean) {
handle(if (play) AttachmentCommands.StartVideo else AttachmentCommands.PauseVideo)
}
override fun onShareTapped() { override fun onShareTapped() {
// Share // Share
eventList?.get(currentPosition)?.let { timelineEvent -> eventList?.get(currentPosition)?.let { timelineEvent ->