Creating dedicated attachment interaction listener

This commit is contained in:
Maxime Naturel 2022-02-23 11:32:57 +01:00
parent 3384a0caa0
commit 6899b5b637
4 changed files with 105 additions and 60 deletions

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.media
interface AttachmentInteractionListener {
fun onDismissTapped()
fun onShareTapped()
fun onPlayPause(play: Boolean)
fun videoSeekTo(percent: Int)
}

View File

@ -30,35 +30,38 @@ class AttachmentOverlayView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), AttachmentEventListener {
var onShareCallback: (() -> Unit)? = null
var onBack: (() -> Unit)? = null
var onPlayPause: ((play: Boolean) -> Unit)? = null
var videoSeekTo: ((progress: Int) -> Unit)? = null
/* ==========================================================================================
* Fields
* ========================================================================================== */
var interactionListener: AttachmentInteractionListener? = null
val views: MergeImageAttachmentOverlayBinding
var isPlaying = false
private var isPlaying = false
private var suspendSeekBarUpdate = false
var suspendSeekBarUpdate = false
/* ==========================================================================================
* Init
* ========================================================================================== */
init {
inflate(context, R.layout.merge_image_attachment_overlay, this)
views = MergeImageAttachmentOverlayBinding.bind(this)
setBackgroundColor(Color.TRANSPARENT)
views.overlayBackButton.setOnClickListener {
onBack?.invoke()
interactionListener?.onDismissTapped()
}
views.overlayShareButton.setOnClickListener {
onShareCallback?.invoke()
interactionListener?.onShareTapped()
}
views.overlayPlayPauseButton.setOnClickListener {
onPlayPause?.invoke(!isPlaying)
interactionListener?.onPlayPause(!isPlaying)
}
views.overlaySeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
videoSeekTo?.invoke(progress)
interactionListener?.videoSeekTo(progress)
}
}
@ -72,11 +75,19 @@ class AttachmentOverlayView @JvmOverloads constructor(
})
}
/* ==========================================================================================
* Public API
* ========================================================================================== */
fun updateWith(counter: String, senderInfo: String) {
views.overlayCounterText.text = counter
views.overlayInfoText.text = senderInfo
}
/* ==========================================================================================
* Specialization
* ========================================================================================== */
override fun onEvent(event: AttachmentEvents) {
when (event) {
is AttachmentEvents.VideoEvent -> {

View File

@ -49,14 +49,7 @@ abstract class BaseAttachmentProvider<Type>(
private val stringProvider: StringProvider
) : AttachmentSourceProvider {
interface InteractionListener {
fun onDismissTapped()
fun onShareTapped()
fun onPlayPause(play: Boolean)
fun videoSeekTo(percent: Int)
}
var interactionListener: InteractionListener? = null
var interactionListener: AttachmentInteractionListener? = null
private var overlayView: AttachmentOverlayView? = null
@ -68,18 +61,7 @@ abstract class BaseAttachmentProvider<Type>(
if (position == -1) return null
if (overlayView == null) {
overlayView = AttachmentOverlayView(context)
overlayView?.onBack = {
interactionListener?.onDismissTapped()
}
overlayView?.onShareCallback = {
interactionListener?.onShareTapped()
}
overlayView?.onPlayPause = { play ->
interactionListener?.onPlayPause(play)
}
overlayView?.videoSeekTo = { percent ->
interactionListener?.videoSeekTo(percent)
}
overlayView?.interactionListener = interactionListener
}
val timelineEvent = getTimelineEventAtPosition(position)

View File

@ -47,7 +47,11 @@ import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmentProvider.InteractionListener {
class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInteractionListener {
/* ==========================================================================================
* Arguments
* ========================================================================================== */
@Parcelize
data class Args(
@ -56,6 +60,10 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
val sharedTransitionName: String?
) : Parcelable
/* ==========================================================================================
* Dependencies
* ========================================================================================== */
@Inject
lateinit var sessionHolder: ActiveSessionHolder
@Inject
@ -63,11 +71,18 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
@Inject
lateinit var imageContentRenderer: ImageContentRenderer
/* ==========================================================================================
* Fields
* ========================================================================================== */
private var initialIndex = 0
private var isAnimatingOut = false
private var currentSourceProvider: BaseAttachmentProvider<*>? = null
/* ==========================================================================================
* Lifecycle
* ========================================================================================== */
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Timber.i("onCreate Activity ${javaClass.simpleName}")
@ -140,12 +155,6 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
Timber.i("onPause Activity ${javaClass.simpleName}")
}
private fun getOtherThemes() = ActivityOtherThemes.VectorAttachmentsPreview
override fun shouldAnimateDismiss(): Boolean {
return currentPosition != initialIndex
}
override fun onBackPressed() {
if (currentPosition == initialIndex) {
// show back the transition view
@ -156,6 +165,14 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
super.onBackPressed()
}
/* ==========================================================================================
* Specialization
* ========================================================================================== */
override fun shouldAnimateDismiss(): Boolean {
return currentPosition != initialIndex
}
override fun animateClose() {
if (currentPosition == initialIndex) {
// show back the transition view
@ -166,9 +183,11 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
ActivityCompat.finishAfterTransition(this)
}
// ==========================================================================================
// PRIVATE METHODS
// ==========================================================================================
/* ==========================================================================================
* Private methods
* ========================================================================================== */
private fun getOtherThemes() = ActivityOtherThemes.VectorAttachmentsPreview
/**
* Try and add a [Transition.TransitionListener] to the entering shared element
@ -218,24 +237,9 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
})
}
companion object {
const val EXTRA_ARGS = "EXTRA_ARGS"
const val EXTRA_IMAGE_DATA = "EXTRA_IMAGE_DATA"
const val EXTRA_IN_MEMORY_DATA = "EXTRA_IN_MEMORY_DATA"
fun newIntent(context: Context,
mediaData: AttachmentData,
roomId: String?,
eventId: String,
inMemoryData: List<AttachmentData>,
sharedTransitionName: String?) = Intent(context, VectorAttachmentViewerActivity::class.java).also {
it.putExtra(EXTRA_ARGS, Args(roomId, eventId, sharedTransitionName))
it.putExtra(EXTRA_IMAGE_DATA, mediaData)
if (inMemoryData.isNotEmpty()) {
it.putParcelableArrayListExtra(EXTRA_IN_MEMORY_DATA, ArrayList(inMemoryData))
}
}
}
/* ==========================================================================================
* Specialization AttachmentInteractionListener
* ========================================================================================== */
override fun onDismissTapped() {
animateClose()
@ -252,7 +256,8 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
// TODO add save feature for image => check it works for video as well,
// check if it is already possible to save from menu with long press on video
override fun onShareTapped() {
// TODO move the retrieve of the file into ViewModel and use a ViewEvent to call shareMedia
// TODO the opening of share bottom sheet is extremely slow
// move the retrieve of the file into ViewModel and use a ViewEvent to call shareMedia
lifecycleScope.launch(Dispatchers.IO) {
val file = currentSourceProvider?.getFileForSharing(currentPosition) ?: return@launch
@ -265,4 +270,27 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen
}
}
}
/* ==========================================================================================
* COMPANION
* ========================================================================================== */
companion object {
private const val EXTRA_ARGS = "EXTRA_ARGS"
private const val EXTRA_IMAGE_DATA = "EXTRA_IMAGE_DATA"
private const val EXTRA_IN_MEMORY_DATA = "EXTRA_IN_MEMORY_DATA"
fun newIntent(context: Context,
mediaData: AttachmentData,
roomId: String?,
eventId: String,
inMemoryData: List<AttachmentData>,
sharedTransitionName: String?) = Intent(context, VectorAttachmentViewerActivity::class.java).also {
it.putExtra(EXTRA_ARGS, Args(roomId, eventId, sharedTransitionName))
it.putExtra(EXTRA_IMAGE_DATA, mediaData)
if (inMemoryData.isNotEmpty()) {
it.putParcelableArrayListExtra(EXTRA_IN_MEMORY_DATA, ArrayList(inMemoryData))
}
}
}
}