Voice Broadcast - Add timeline item listening state

This commit is contained in:
Florian Renaud 2022-10-17 22:58:12 +02:00
parent 2760781f0a
commit 215128c213
2 changed files with 47 additions and 7 deletions

View file

@ -15,8 +15,8 @@
*/ */
package im.vector.app.features.home.room.detail.timeline.factory package im.vector.app.features.home.room.detail.timeline.factory
import im.vector.app.core.extensions.getVectorLastMessageContent
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvider import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvider
import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventsGroup import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventsGroup
import im.vector.app.features.home.room.detail.timeline.helper.VoiceBroadcastEventsGroup import im.vector.app.features.home.room.detail.timeline.helper.VoiceBroadcastEventsGroup
@ -25,10 +25,14 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadca
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastItem_
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
import org.matrix.android.sdk.api.session.Session
import javax.inject.Inject import javax.inject.Inject
class VoiceBroadcastItemFactory @Inject constructor( class VoiceBroadcastItemFactory @Inject constructor(
private val session: Session,
private val avatarSizeProvider: AvatarSizeProvider, private val avatarSizeProvider: AvatarSizeProvider,
private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker,
) { ) {
fun create( fun create(
@ -42,11 +46,15 @@ class VoiceBroadcastItemFactory @Inject constructor(
if (messageContent.voiceBroadcastState != VoiceBroadcastState.STARTED) return null if (messageContent.voiceBroadcastState != VoiceBroadcastState.STARTED) return null
val voiceBroadcastEventsGroup = eventsGroup?.let { VoiceBroadcastEventsGroup(it) } ?: return null val voiceBroadcastEventsGroup = eventsGroup?.let { VoiceBroadcastEventsGroup(it) } ?: return null
val mostRecentTimelineEvent = voiceBroadcastEventsGroup.getLastDisplayableEvent() val mostRecentTimelineEvent = voiceBroadcastEventsGroup.getLastDisplayableEvent()
val mostRecentMessageContent = mostRecentTimelineEvent.root.asVoiceBroadcastEvent()?.content ?: return null val mostRecentEvent = mostRecentTimelineEvent.root.asVoiceBroadcastEvent()
val mostRecentMessageContent = mostRecentEvent?.content ?: return null
val isRecording = mostRecentMessageContent.voiceBroadcastState != VoiceBroadcastState.STOPPED && mostRecentEvent.root.stateKey == session.myUserId
return MessageVoiceBroadcastItem_() return MessageVoiceBroadcastItem_()
.attributes(attributes) .attributes(attributes)
.highlighted(highlight) .highlighted(highlight)
.voiceBroadcastState(mostRecentMessageContent.voiceBroadcastState) .voiceBroadcastState(mostRecentMessageContent.voiceBroadcastState)
.recording(isRecording)
.audioMessagePlaybackTracker(audioMessagePlaybackTracker)
.leftGuideline(avatarSizeProvider.leftGuideline) .leftGuideline(avatarSizeProvider.leftGuideline)
.callback(callback) .callback(callback)
} }

View file

@ -22,8 +22,10 @@ import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailAction.VoiceBroadcastAction
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker.Listener.State
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
@EpoxyModelClass @EpoxyModelClass
@ -35,6 +37,15 @@ abstract class MessageVoiceBroadcastItem : AbsMessageItem<MessageVoiceBroadcastI
@EpoxyAttribute @EpoxyAttribute
var voiceBroadcastState: VoiceBroadcastState? = null var voiceBroadcastState: VoiceBroadcastState? = null
@EpoxyAttribute
var recording: Boolean = false
@EpoxyAttribute
lateinit var audioMessagePlaybackTracker: AudioMessagePlaybackTracker
private val voiceBroadcastEventId
get() = attributes.informationData.eventId
override fun isCacheable(): Boolean = false override fun isCacheable(): Boolean = false
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
@ -44,16 +55,37 @@ abstract class MessageVoiceBroadcastItem : AbsMessageItem<MessageVoiceBroadcastI
@SuppressLint("SetTextI18n") // Temporary text @SuppressLint("SetTextI18n") // Temporary text
private fun bindVoiceBroadcastItem(holder: Holder) { private fun bindVoiceBroadcastItem(holder: Holder) {
holder.currentStateText.text = "Voice Broadcast state: ${voiceBroadcastState?.value ?: "None"}"
if (recording) {
renderRecording(holder)
} else {
renderListening(holder)
}
}
private fun renderListening(holder: Holder) {
audioMessagePlaybackTracker.track(attributes.informationData.eventId, object : AudioMessagePlaybackTracker.Listener {
override fun onUpdate(state: State) {
holder.playButton.isEnabled = state !is State.Playing
holder.pauseButton.isEnabled = state is State.Playing
holder.stopButton.isEnabled = state !is State.Idle
}
})
holder.playButton.setOnClickListener { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcastEventId)) }
holder.pauseButton.setOnClickListener { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.Pause) }
holder.stopButton.setOnClickListener { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.Stop) }
}
private fun renderRecording(holder: Holder) {
with(holder) { with(holder) {
currentStateText.text = "Voice Broadcast state: ${voiceBroadcastState?.value ?: "None"}"
playButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.PAUSED playButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.PAUSED
pauseButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.STARTED || voiceBroadcastState == VoiceBroadcastState.RESUMED pauseButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.STARTED || voiceBroadcastState == VoiceBroadcastState.RESUMED
stopButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.STARTED || stopButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.STARTED ||
voiceBroadcastState == VoiceBroadcastState.RESUMED || voiceBroadcastState == VoiceBroadcastState.RESUMED ||
voiceBroadcastState == VoiceBroadcastState.PAUSED voiceBroadcastState == VoiceBroadcastState.PAUSED
playButton.setOnClickListener { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Resume) } playButton.setOnClickListener { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Resume) }
pauseButton.setOnClickListener { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Pause) } pauseButton.setOnClickListener { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Pause) }
stopButton.setOnClickListener { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Stop) } stopButton.setOnClickListener { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Stop) }
} }
} }