forked from GitHub-Mirror/riotX-android
Refactoring (duplication in Message Item Factory) + cleaning
This commit is contained in:
parent
297f202005
commit
e22b555b58
@ -46,7 +46,7 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
||||
private val backgroundHandler: Handler = TimelineAsyncHelper.getBackgroundHandler()
|
||||
) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
|
||||
|
||||
interface Callback : ReactionPillCallback {
|
||||
interface Callback : ReactionPillCallback, AvatarCallback {
|
||||
fun onEventVisible(event: TimelineEvent)
|
||||
fun onUrlClicked(url: String)
|
||||
fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View)
|
||||
@ -55,8 +55,6 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
||||
fun onAudioMessageClicked(messageAudioContent: MessageAudioContent)
|
||||
fun onEventCellClicked(informationData: MessageInformationData, messageContent: MessageContent, view: View)
|
||||
fun onEventLongClicked(informationData: MessageInformationData, messageContent: MessageContent, view: View): Boolean
|
||||
fun onAvatarClicked(informationData: MessageInformationData)
|
||||
fun onMemberNameClicked(informationData: MessageInformationData)
|
||||
fun onEditedDecorationClicked(informationData: MessageInformationData, editAggregatedSummary: EditAggregatedSummary?)
|
||||
}
|
||||
|
||||
@ -65,6 +63,11 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
||||
fun onLongClickOnReactionPill(informationData: MessageInformationData, reaction: String)
|
||||
}
|
||||
|
||||
interface AvatarCallback {
|
||||
fun onAvatarClicked(informationData: MessageInformationData)
|
||||
fun onMemberNameClicked(informationData: MessageInformationData)
|
||||
}
|
||||
|
||||
private val collapsedEventIds = linkedSetOf<String>()
|
||||
private val mergeItemCollapseStates = HashMap<String, Boolean>()
|
||||
private val modelCache = arrayListOf<CacheItemData?>()
|
||||
|
@ -1,16 +1,12 @@
|
||||
package im.vector.riotredesign.features.home.room.detail.timeline.action
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import com.airbnb.mvrx.*
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||
import im.vector.riotredesign.core.extensions.localDateTime
|
||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.android.ext.android.get
|
||||
|
||||
|
||||
@ -33,53 +29,41 @@ data class ReactionInfo(
|
||||
*/
|
||||
class ViewReactionViewModel(private val session: Session,
|
||||
private val timelineDateFormatter: TimelineDateFormatter,
|
||||
lifecycleOwner: LifecycleOwner?,
|
||||
liveSummary: LiveData<List<EventAnnotationsSummary>>?,
|
||||
initialState: DisplayReactionsViewState) : VectorViewModel<DisplayReactionsViewState>(initialState) {
|
||||
|
||||
init {
|
||||
loadReaction()
|
||||
if (lifecycleOwner != null) {
|
||||
liveSummary?.observe(lifecycleOwner, Observer {
|
||||
it?.firstOrNull()?.let {
|
||||
loadReaction()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun loadReaction() = withState { state ->
|
||||
fun loadReaction() = withState { state ->
|
||||
|
||||
GlobalScope.launch {
|
||||
try {
|
||||
val room = session.getRoom(state.roomId)
|
||||
val event = room?.getTimeLineEvent(state.eventId)
|
||||
if (event == null) {
|
||||
setState { copy(mapReactionKeyToMemberList = Fail(Throwable())) }
|
||||
return@launch
|
||||
}
|
||||
var results = ArrayList<ReactionInfo>()
|
||||
event.annotations?.reactionsSummary?.forEach { sum ->
|
||||
try {
|
||||
val room = session.getRoom(state.roomId)
|
||||
val event = room?.getTimeLineEvent(state.eventId)
|
||||
if (event == null) {
|
||||
setState { copy(mapReactionKeyToMemberList = Fail(Throwable())) }
|
||||
return@withState
|
||||
}
|
||||
var results = ArrayList<ReactionInfo>()
|
||||
event.annotations?.reactionsSummary?.forEach { sum ->
|
||||
|
||||
sum.sourceEvents.mapNotNull { room.getTimeLineEvent(it) }.forEach {
|
||||
val localDate = it.root.localDateTime()
|
||||
results.add(ReactionInfo(it.root.eventId!!, sum.key, it.root.sender
|
||||
?: "", it.senderName, timelineDateFormatter.formatMessageHour(localDate)))
|
||||
}
|
||||
}
|
||||
setState {
|
||||
copy(
|
||||
mapReactionKeyToMemberList = Success(results.sortedBy { it.timestamp })
|
||||
)
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
mapReactionKeyToMemberList = Fail(t)
|
||||
)
|
||||
sum.sourceEvents.mapNotNull { room.getTimeLineEvent(it) }.forEach {
|
||||
val localDate = it.root.localDateTime()
|
||||
results.add(ReactionInfo(it.root.eventId!!, sum.key, it.root.sender
|
||||
?: "", it.senderName, timelineDateFormatter.formatMessageHour(localDate)))
|
||||
}
|
||||
}
|
||||
setState {
|
||||
copy(
|
||||
mapReactionKeyToMemberList = Success(results.sortedBy { it.timestamp })
|
||||
)
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
mapReactionKeyToMemberList = Fail(t)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +82,18 @@ class ViewReactionViewModel(private val session: Session,
|
||||
override fun create(viewModelContext: ViewModelContext, state: DisplayReactionsViewState): ViewReactionViewModel? {
|
||||
val session = viewModelContext.activity.get<Session>()
|
||||
val eventId = (viewModelContext.args as TimelineEventFragmentArgs).eventId
|
||||
return ViewReactionViewModel(session, viewModelContext.activity.get(), viewModelContext.activity, session.getRoom(state.roomId)?.getEventSummaryLive(eventId), state)
|
||||
val lifecycleOwner = (viewModelContext as FragmentViewModelContext).fragment<Fragment>()
|
||||
val liveSummary = session.getRoom(state.roomId)?.getEventSummaryLive(eventId)
|
||||
val viewReactionViewModel = ViewReactionViewModel(session, viewModelContext.activity.get(), state)
|
||||
// This states observes the live summary
|
||||
// When fragment context will be destroyed the observer will automatically removed
|
||||
liveSummary?.observe(lifecycleOwner, Observer {
|
||||
it?.firstOrNull()?.let {
|
||||
viewReactionViewModel.loadReaction()
|
||||
}
|
||||
})
|
||||
|
||||
return viewReactionViewModel
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,18 +143,11 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
callback: TimelineEventController.Callback?): MessageFileItem? {
|
||||
return MessageFileItem_()
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.filename(messageContent.body)
|
||||
.iconRes(R.drawable.filetype_audio)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener {
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener {
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
.cellClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view: View ->
|
||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||
@ -174,18 +167,11 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
callback: TimelineEventController.Callback?): MessageFileItem? {
|
||||
return MessageFileItem_()
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.filename(messageContent.body)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.iconRes(R.drawable.filetype_attachment)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
.cellClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||
@ -223,17 +209,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
return MessageImageVideoItem_()
|
||||
.playable(messageContent.info?.mimeType == "image/gif")
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.mediaData(data)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
.clickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onImageMessageClicked(messageContent, data, view)
|
||||
@ -271,17 +250,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
return MessageImageVideoItem_()
|
||||
.playable(true)
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.mediaData(thumbnailData)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
.cellClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||
@ -316,16 +288,9 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
}
|
||||
}
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
//click on the text
|
||||
.clickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
@ -390,12 +355,9 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
return MessageTextItem_()
|
||||
.message(message)
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
@ -430,16 +392,9 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
}
|
||||
}
|
||||
.informationData(informationData)
|
||||
.avatarCallback(callback)
|
||||
.reactionPillCallback(callback)
|
||||
.emojiTypeFace(emojiCompatFontProvider.typeface)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
.cellClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onEventCellClicked(informationData, messageContent, view)
|
||||
@ -454,14 +409,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
callback: TimelineEventController.Callback?): RedactedMessageItem? {
|
||||
return RedactedMessageItem_()
|
||||
.informationData(informationData)
|
||||
.avatarClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onAvatarClicked(informationData)
|
||||
}))
|
||||
.memberClickListener(
|
||||
DebouncedClickListener(View.OnClickListener { view ->
|
||||
callback?.onMemberNameClicked(informationData)
|
||||
}))
|
||||
.avatarCallback(callback)
|
||||
}
|
||||
|
||||
private fun linkifyBody(body: CharSequence, callback: TimelineEventController.Callback?): CharSequence {
|
||||
|
@ -29,6 +29,7 @@ import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.utils.DebouncedClickListener
|
||||
import im.vector.riotredesign.core.utils.DimensionUtils.dpToPx
|
||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||
@ -45,9 +46,6 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
@EpoxyAttribute
|
||||
var cellClickListener: View.OnClickListener? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var avatarClickListener: View.OnClickListener? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var memberClickListener: View.OnClickListener? = null
|
||||
|
||||
@ -57,6 +55,17 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
@EpoxyAttribute
|
||||
var reactionPillCallback: TimelineEventController.ReactionPillCallback? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var avatarCallback: TimelineEventController.AvatarCallback?= null
|
||||
|
||||
private val _avatarClickListener = DebouncedClickListener(View.OnClickListener {
|
||||
avatarCallback?.onAvatarClicked(informationData)
|
||||
})
|
||||
private val _memberNameClickListener = DebouncedClickListener(View.OnClickListener {
|
||||
avatarCallback?.onMemberNameClicked(informationData)
|
||||
})
|
||||
|
||||
|
||||
var reactionClickListener: ReactionButton.ReactedListener = object : ReactionButton.ReactedListener {
|
||||
override fun onReacted(reactionButton: ReactionButton) {
|
||||
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString, true)
|
||||
@ -81,9 +90,9 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
width = size
|
||||
}
|
||||
holder.avatarImageView.visibility = View.VISIBLE
|
||||
holder.avatarImageView.setOnClickListener(avatarClickListener)
|
||||
holder.avatarImageView.setOnClickListener(_avatarClickListener)
|
||||
holder.memberNameView.visibility = View.VISIBLE
|
||||
holder.memberNameView.setOnClickListener(memberClickListener)
|
||||
holder.memberNameView.setOnClickListener(_memberNameClickListener)
|
||||
holder.timeView.visibility = View.VISIBLE
|
||||
holder.timeView.text = informationData.time
|
||||
holder.memberNameView.text = informationData.memberName
|
||||
|
@ -11,8 +11,10 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemSimpleReactionInfoKey"
|
||||
android:layout_width="44dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
|
Loading…
Reference in New Issue
Block a user