Move voice broadcast item attributes to dedicated class

This commit is contained in:
Florian Renaud 2022-10-25 16:29:42 +02:00
parent f31429cf25
commit 649747bbb8
5 changed files with 57 additions and 87 deletions

View file

@ -201,7 +201,7 @@ class MessageItemFactory @Inject constructor(
is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes) is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes)
is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes) is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes)
is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes) is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes)
is MessageVoiceBroadcastInfoContent -> voiceBroadcastItemFactory.create(params, messageContent, highlight, callback, attributes) is MessageVoiceBroadcastInfoContent -> voiceBroadcastItemFactory.create(params, messageContent, highlight, attributes)
else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes) else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes)
} }
return messageItem?.apply { return messageItem?.apply {

View file

@ -18,7 +18,6 @@ package im.vector.app.features.home.room.detail.timeline.factory
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.DrawableProvider import im.vector.app.core.resources.DrawableProvider
import im.vector.app.features.displayname.getBestName import im.vector.app.features.displayname.getBestName
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
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.VoiceBroadcastEventsGroup import im.vector.app.features.home.room.detail.timeline.helper.VoiceBroadcastEventsGroup
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
@ -51,7 +50,6 @@ class VoiceBroadcastItemFactory @Inject constructor(
params: TimelineItemFactoryParams, params: TimelineItemFactoryParams,
messageContent: MessageVoiceBroadcastInfoContent, messageContent: MessageVoiceBroadcastInfoContent,
highlight: Boolean, highlight: Boolean,
callback: TimelineEventController.Callback?,
attributes: AbsMessageItem.Attributes, attributes: AbsMessageItem.Attributes,
): AbsMessageVoiceBroadcastItem<*>? { ): AbsMessageVoiceBroadcastItem<*>? {
// Only display item of the initial event with updated data // Only display item of the initial event with updated data
@ -64,72 +62,47 @@ class VoiceBroadcastItemFactory @Inject constructor(
val isRecording = voiceBroadcastContent.voiceBroadcastState != VoiceBroadcastState.STOPPED && voiceBroadcastEvent.root.stateKey == session.myUserId val isRecording = voiceBroadcastContent.voiceBroadcastState != VoiceBroadcastState.STOPPED && voiceBroadcastEvent.root.stateKey == session.myUserId
val voiceBroadcastAttributes = AbsMessageVoiceBroadcastItem.Attributes(
voiceBroadcastId = voiceBroadcastId,
voiceBroadcastState = voiceBroadcastContent.voiceBroadcastState,
recorderName = params.event.root.stateKey?.let { session.getUserOrDefault(it) }?.toMatrixItem()?.getBestName().orEmpty(),
recorder = voiceBroadcastRecorder,
player = voiceBroadcastPlayer,
roomItem = session.getRoom(params.event.roomId)?.roomSummary()?.toMatrixItem(),
colorProvider = colorProvider,
drawableProvider = drawableProvider,
)
return if (isRecording) { return if (isRecording) {
createRecordingItem( createRecordingItem(highlight, attributes, voiceBroadcastAttributes)
params,
voiceBroadcastId,
voiceBroadcastContent.voiceBroadcastState,
highlight,
callback,
attributes
)
} else { } else {
createListeningItem( createListeningItem(highlight, attributes, voiceBroadcastAttributes)
params,
voiceBroadcastId,
voiceBroadcastContent.voiceBroadcastState,
highlight,
callback,
attributes
)
} }
} }
private fun createRecordingItem( private fun createRecordingItem(
params: TimelineItemFactoryParams,
voiceBroadcastId: String,
voiceBroadcastState: VoiceBroadcastState?,
highlight: Boolean, highlight: Boolean,
callback: TimelineEventController.Callback?,
attributes: AbsMessageItem.Attributes, attributes: AbsMessageItem.Attributes,
voiceBroadcastAttributes: AbsMessageVoiceBroadcastItem.Attributes,
): MessageVoiceBroadcastRecordingItem { ): MessageVoiceBroadcastRecordingItem {
val roomSummary = session.getRoom(params.event.roomId)?.roomSummary()
return MessageVoiceBroadcastRecordingItem_() return MessageVoiceBroadcastRecordingItem_()
.id("voice_broadcast_$voiceBroadcastId") .id("voice_broadcast_${voiceBroadcastAttributes.voiceBroadcastId}")
.attributes(attributes) .attributes(attributes)
.voiceBroadcastAttributes(voiceBroadcastAttributes)
.highlighted(highlight) .highlighted(highlight)
.roomItem(roomSummary?.toMatrixItem())
.colorProvider(colorProvider)
.drawableProvider(drawableProvider)
.voiceBroadcastRecorder(voiceBroadcastRecorder)
.voiceBroadcastId(voiceBroadcastId)
.voiceBroadcastState(voiceBroadcastState)
.leftGuideline(avatarSizeProvider.leftGuideline) .leftGuideline(avatarSizeProvider.leftGuideline)
.callback(callback)
} }
private fun createListeningItem( private fun createListeningItem(
params: TimelineItemFactoryParams,
voiceBroadcastId: String,
voiceBroadcastState: VoiceBroadcastState?,
highlight: Boolean, highlight: Boolean,
callback: TimelineEventController.Callback?,
attributes: AbsMessageItem.Attributes, attributes: AbsMessageItem.Attributes,
voiceBroadcastAttributes: AbsMessageVoiceBroadcastItem.Attributes,
): MessageVoiceBroadcastListeningItem { ): MessageVoiceBroadcastListeningItem {
val roomSummary = session.getRoom(params.event.roomId)?.roomSummary()
val recorderName = params.event.root.stateKey?.let { session.getUserOrDefault(it) }?.toMatrixItem()?.getBestName()
return MessageVoiceBroadcastListeningItem_() return MessageVoiceBroadcastListeningItem_()
.id("voice_broadcast_$voiceBroadcastId") .id("voice_broadcast_${voiceBroadcastAttributes.voiceBroadcastId}")
.attributes(attributes) .attributes(attributes)
.voiceBroadcastAttributes(voiceBroadcastAttributes)
.highlighted(highlight) .highlighted(highlight)
.roomItem(roomSummary?.toMatrixItem())
.colorProvider(colorProvider)
.drawableProvider(drawableProvider)
.voiceBroadcastPlayer(voiceBroadcastPlayer)
.voiceBroadcastId(voiceBroadcastId)
.voiceBroadcastState(voiceBroadcastState)
.broadcasterName(recorderName)
.leftGuideline(avatarSizeProvider.leftGuideline) .leftGuideline(avatarSizeProvider.leftGuideline)
.callback(callback)
} }
} }

View file

@ -25,29 +25,26 @@ import im.vector.app.R
import im.vector.app.core.extensions.tintBackground import im.vector.app.core.extensions.tintBackground
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.DrawableProvider import im.vector.app.core.resources.DrawableProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.voicebroadcast.VoiceBroadcastPlayer
import im.vector.app.features.voicebroadcast.VoiceBroadcastRecorder
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
abstract class AbsMessageVoiceBroadcastItem<H : AbsMessageVoiceBroadcastItem.Holder> : AbsMessageItem<H>() { abstract class AbsMessageVoiceBroadcastItem<H : AbsMessageVoiceBroadcastItem.Holder> : AbsMessageItem<H>() {
@EpoxyAttribute @EpoxyAttribute
var callback: TimelineEventController.Callback? = null lateinit var voiceBroadcastAttributes: Attributes
@EpoxyAttribute protected val voiceBroadcastId get() = voiceBroadcastAttributes.voiceBroadcastId
lateinit var colorProvider: ColorProvider protected val voiceBroadcastState get() = voiceBroadcastAttributes.voiceBroadcastState
protected val recorderName get() = voiceBroadcastAttributes.recorderName
@EpoxyAttribute protected val recorder get() = voiceBroadcastAttributes.recorder
lateinit var drawableProvider: DrawableProvider protected val player get() = voiceBroadcastAttributes.player
protected val roomItem get() = voiceBroadcastAttributes.roomItem
@EpoxyAttribute protected val colorProvider get() = voiceBroadcastAttributes.colorProvider
lateinit var voiceBroadcastId: String protected val drawableProvider get() = voiceBroadcastAttributes.drawableProvider
protected val avatarRenderer get() = attributes.avatarRenderer
@EpoxyAttribute protected val callback get() = attributes.callback
var voiceBroadcastState: VoiceBroadcastState? = null
@EpoxyAttribute
var roomItem: MatrixItem? = null
override fun isCacheable(): Boolean = false override fun isCacheable(): Boolean = false
@ -59,7 +56,7 @@ abstract class AbsMessageVoiceBroadcastItem<H : AbsMessageVoiceBroadcastItem.Hol
private fun renderHeader(holder: H) { private fun renderHeader(holder: H) {
with(holder) { with(holder) {
roomItem?.let { roomItem?.let {
attributes.avatarRenderer.render(it, roomAvatarImageView) avatarRenderer.render(it, roomAvatarImageView)
titleText.text = it.displayName titleText.text = it.displayName
} }
} }
@ -93,4 +90,15 @@ abstract class AbsMessageVoiceBroadcastItem<H : AbsMessageVoiceBroadcastItem.Hol
val roomAvatarImageView by bind<ImageView>(R.id.roomAvatarImageView) val roomAvatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
val titleText by bind<TextView>(R.id.titleText) val titleText by bind<TextView>(R.id.titleText)
} }
data class Attributes(
val voiceBroadcastId: String,
val voiceBroadcastState: VoiceBroadcastState?,
val recorderName: String,
val recorder: VoiceBroadcastRecorder?,
val player: VoiceBroadcastPlayer,
val roomItem: MatrixItem?,
val colorProvider: ColorProvider,
val drawableProvider: DrawableProvider,
)
} }

View file

@ -19,7 +19,6 @@ package im.vector.app.features.home.room.detail.timeline.item
import android.view.View import android.view.View
import android.widget.ImageButton import android.widget.ImageButton
import androidx.core.view.isVisible import androidx.core.view.isVisible
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.core.epoxy.onClick import im.vector.app.core.epoxy.onClick
@ -30,12 +29,6 @@ import im.vector.app.features.voicebroadcast.views.VoiceBroadcastMetadataView
@EpoxyModelClass @EpoxyModelClass
abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem<MessageVoiceBroadcastListeningItem.Holder>() { abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem<MessageVoiceBroadcastListeningItem.Holder>() {
@EpoxyAttribute
var voiceBroadcastPlayer: VoiceBroadcastPlayer? = null
@EpoxyAttribute
var broadcasterName: String? = null
private lateinit var playerListener: VoiceBroadcastPlayer.Listener private lateinit var playerListener: VoiceBroadcastPlayer.Listener
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
@ -47,12 +40,12 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
playerListener = VoiceBroadcastPlayer.Listener { state -> playerListener = VoiceBroadcastPlayer.Listener { state ->
renderPlayingState(holder, state) renderPlayingState(holder, state)
} }
voiceBroadcastPlayer?.addListener(voiceBroadcastId, playerListener) player.addListener(voiceBroadcastId, playerListener)
} }
override fun renderMetadata(holder: Holder) { override fun renderMetadata(holder: Holder) {
with(holder) { with(holder) {
broadcasterNameMetadata.value = broadcasterName.orEmpty() broadcasterNameMetadata.value = recorderName
voiceBroadcastMetadata.isVisible = true voiceBroadcastMetadata.isVisible = true
listenersCountMetadata.isVisible = false listenersCountMetadata.isVisible = false
} }
@ -67,14 +60,14 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
VoiceBroadcastPlayer.State.PLAYING -> { VoiceBroadcastPlayer.State.PLAYING -> {
playPauseButton.setImageResource(R.drawable.ic_play_pause_pause) playPauseButton.setImageResource(R.drawable.ic_play_pause_pause)
playPauseButton.contentDescription = view.resources.getString(R.string.a11y_play_voice_broadcast) playPauseButton.contentDescription = view.resources.getString(R.string.a11y_play_voice_broadcast)
playPauseButton.onClick { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Listening.Pause) } playPauseButton.onClick { callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Listening.Pause) }
} }
VoiceBroadcastPlayer.State.IDLE, VoiceBroadcastPlayer.State.IDLE,
VoiceBroadcastPlayer.State.PAUSED -> { VoiceBroadcastPlayer.State.PAUSED -> {
playPauseButton.setImageResource(R.drawable.ic_play_pause_play) playPauseButton.setImageResource(R.drawable.ic_play_pause_play)
playPauseButton.contentDescription = view.resources.getString(R.string.a11y_pause_voice_broadcast) playPauseButton.contentDescription = view.resources.getString(R.string.a11y_pause_voice_broadcast)
playPauseButton.onClick { playPauseButton.onClick {
attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcastId)) callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcastId))
} }
} }
VoiceBroadcastPlayer.State.BUFFERING -> Unit VoiceBroadcastPlayer.State.BUFFERING -> Unit
@ -84,7 +77,7 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
override fun unbind(holder: Holder) { override fun unbind(holder: Holder) {
super.unbind(holder) super.unbind(holder)
voiceBroadcastPlayer?.removeListener(voiceBroadcastId, playerListener) player.removeListener(voiceBroadcastId, playerListener)
} }
override fun getViewStubId() = STUB_ID override fun getViewStubId() = STUB_ID

View file

@ -18,7 +18,6 @@ package im.vector.app.features.home.room.detail.timeline.item
import android.widget.ImageButton import android.widget.ImageButton
import androidx.core.view.isVisible import androidx.core.view.isVisible
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.core.epoxy.onClick import im.vector.app.core.epoxy.onClick
@ -30,9 +29,6 @@ import im.vector.app.features.voicebroadcast.views.VoiceBroadcastMetadataView
@EpoxyModelClass @EpoxyModelClass
abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem<MessageVoiceBroadcastRecordingItem.Holder>() { abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem<MessageVoiceBroadcastRecordingItem.Holder>() {
@EpoxyAttribute
var voiceBroadcastRecorder: VoiceBroadcastRecorder? = null
private var recorderListener: VoiceBroadcastRecorder.Listener? = null private var recorderListener: VoiceBroadcastRecorder.Listener? = null
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
@ -41,12 +37,12 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
} }
private fun bindVoiceBroadcastItem(holder: Holder) { private fun bindVoiceBroadcastItem(holder: Holder) {
if (voiceBroadcastRecorder != null && voiceBroadcastRecorder?.state != VoiceBroadcastRecorder.State.Idle) { if (recorder != null && recorder?.state != VoiceBroadcastRecorder.State.Idle) {
recorderListener = object : VoiceBroadcastRecorder.Listener { recorderListener = object : VoiceBroadcastRecorder.Listener {
override fun onStateUpdated(state: VoiceBroadcastRecorder.State) { override fun onStateUpdated(state: VoiceBroadcastRecorder.State) {
renderRecordingState(holder, state) renderRecordingState(holder, state)
} }
}.also { voiceBroadcastRecorder?.addListener(it) } }.also { recorder?.addListener(it) }
} else { } else {
renderVoiceBroadcastState(holder) renderVoiceBroadcastState(holder)
} }
@ -85,8 +81,8 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
val drawable = drawableProvider.getDrawable(R.drawable.ic_play_pause_pause, drawableColor) val drawable = drawableProvider.getDrawable(R.drawable.ic_play_pause_pause, drawableColor)
recordButton.setImageDrawable(drawable) recordButton.setImageDrawable(drawable)
recordButton.contentDescription = holder.view.resources.getString(R.string.a11y_pause_voice_broadcast_record) recordButton.contentDescription = holder.view.resources.getString(R.string.a11y_pause_voice_broadcast_record)
recordButton.onClick { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Pause) } recordButton.onClick { callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Pause) }
stopRecordButton.onClick { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Stop) } stopRecordButton.onClick { callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Stop) }
} }
private fun renderPausedState(holder: Holder) = with(holder) { private fun renderPausedState(holder: Holder) = with(holder) {
@ -95,8 +91,8 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
recordButton.setImageResource(R.drawable.ic_recording_dot) recordButton.setImageResource(R.drawable.ic_recording_dot)
recordButton.contentDescription = holder.view.resources.getString(R.string.a11y_resume_voice_broadcast_record) recordButton.contentDescription = holder.view.resources.getString(R.string.a11y_resume_voice_broadcast_record)
recordButton.onClick { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Resume) } recordButton.onClick { callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Resume) }
stopRecordButton.onClick { attributes.callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Stop) } stopRecordButton.onClick { callback?.onTimelineItemAction(VoiceBroadcastAction.Recording.Stop) }
} }
private fun renderStoppedState(holder: Holder) = with(holder) { private fun renderStoppedState(holder: Holder) = with(holder) {
@ -106,7 +102,7 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
override fun unbind(holder: Holder) { override fun unbind(holder: Holder) {
super.unbind(holder) super.unbind(holder)
recorderListener?.let { voiceBroadcastRecorder?.removeListener(it) } recorderListener?.let { recorder?.removeListener(it) }
recorderListener = null recorderListener = null
} }