forked from GitHub-Mirror/riotX-android
Create MessageInformationDataFactory for reusability
This commit is contained in:
parent
273c8a19b8
commit
a53e40e1ee
@ -29,6 +29,7 @@ import im.vector.riotredesign.features.home.room.detail.timeline.factory.*
|
|||||||
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.util.MessageInformationDataFactory
|
||||||
import im.vector.riotredesign.features.home.room.list.RoomSummaryController
|
import im.vector.riotredesign.features.home.room.list.RoomSummaryController
|
||||||
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
@ -69,15 +70,22 @@ class HomeModule {
|
|||||||
val eventHtmlRenderer = EventHtmlRenderer(GlideApp.with(fragment), fragment.requireContext(), get())
|
val eventHtmlRenderer = EventHtmlRenderer(GlideApp.with(fragment), fragment.requireContext(), get())
|
||||||
val noticeEventFormatter = get<NoticeEventFormatter>(parameters = { parametersOf(fragment) })
|
val noticeEventFormatter = get<NoticeEventFormatter>(parameters = { parametersOf(fragment) })
|
||||||
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
val timelineMediaSizeProvider = TimelineMediaSizeProvider()
|
||||||
val messageItemFactory = MessageItemFactory(colorProvider, timelineMediaSizeProvider,
|
val messageInformationDataFactory = MessageInformationDataFactory(timelineDateFormatter, colorProvider)
|
||||||
timelineDateFormatter, eventHtmlRenderer, get(), get())
|
val messageItemFactory = MessageItemFactory(colorProvider,
|
||||||
|
timelineMediaSizeProvider,
|
||||||
|
eventHtmlRenderer,
|
||||||
|
get(),
|
||||||
|
messageInformationDataFactory,
|
||||||
|
get())
|
||||||
|
|
||||||
|
val encryptedItemFactory = EncryptedItemFactory(messageInformationDataFactory, colorProvider, get())
|
||||||
|
|
||||||
val timelineItemFactory = TimelineItemFactory(
|
val timelineItemFactory = TimelineItemFactory(
|
||||||
messageItemFactory = messageItemFactory,
|
messageItemFactory = messageItemFactory,
|
||||||
noticeItemFactory = NoticeItemFactory(noticeEventFormatter),
|
noticeItemFactory = NoticeItemFactory(noticeEventFormatter),
|
||||||
defaultItemFactory = DefaultItemFactory(),
|
defaultItemFactory = DefaultItemFactory(),
|
||||||
encryptionItemFactory = EncryptionItemFactory(get()),
|
encryptionItemFactory = EncryptionItemFactory(get()),
|
||||||
encryptedItemFactory = EncryptedItemFactory(get())
|
encryptedItemFactory = encryptedItemFactory
|
||||||
)
|
)
|
||||||
TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider)
|
TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider)
|
||||||
}
|
}
|
||||||
|
@ -16,28 +16,28 @@
|
|||||||
|
|
||||||
package im.vector.riotredesign.features.home.room.detail.timeline.factory
|
package im.vector.riotredesign.features.home.room.detail.timeline.factory
|
||||||
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.text.Spannable
|
|
||||||
import android.text.SpannableString
|
|
||||||
import android.text.style.StyleSpan
|
|
||||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||||
|
import im.vector.riotredesign.core.resources.ColorProvider
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
|
import im.vector.riotredesign.features.home.room.detail.timeline.util.MessageInformationDataFactory
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
import me.gujun.android.span.span
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
|
|
||||||
|
|
||||||
// This class handles timeline event who haven't been successfully decrypted
|
// This class handles timeline events who haven't been successfully decrypted
|
||||||
class EncryptedItemFactory(private val stringProvider: StringProvider) {
|
class EncryptedItemFactory(private val messageInformationDataFactory: MessageInformationDataFactory,
|
||||||
|
private val colorProvider: ColorProvider,
|
||||||
|
private val stringProvider: StringProvider) {
|
||||||
|
|
||||||
|
fun create(event: TimelineEvent, nextEvent: TimelineEvent?): VectorEpoxyModel<*>? {
|
||||||
|
event.root.eventId ?: return null
|
||||||
|
|
||||||
fun create(timelineEvent: TimelineEvent): VectorEpoxyModel<*>? {
|
|
||||||
return when {
|
return when {
|
||||||
EventType.ENCRYPTED == timelineEvent.root.getClearType() -> {
|
EventType.ENCRYPTED == event.root.getClearType() -> {
|
||||||
val cryptoError = timelineEvent.root.mCryptoError
|
val cryptoError = event.root.mCryptoError
|
||||||
val errorDescription =
|
val errorDescription =
|
||||||
if (cryptoError?.code == MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE) {
|
if (cryptoError?.code == MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_ERROR_CODE) {
|
||||||
stringProvider.getString(R.string.notice_crypto_error_unkwown_inbound_session_id)
|
stringProvider.getString(R.string.notice_crypto_error_unkwown_inbound_session_id)
|
||||||
@ -46,20 +46,19 @@ class EncryptedItemFactory(private val stringProvider: StringProvider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val message = stringProvider.getString(R.string.notice_crypto_unable_to_decrypt, errorDescription)
|
val message = stringProvider.getString(R.string.notice_crypto_unable_to_decrypt, errorDescription)
|
||||||
val spannableStr = SpannableString(message)
|
val spannableStr = span(message) {
|
||||||
spannableStr.setSpan(StyleSpan(Typeface.ITALIC), 0, message.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
textStyle = "italic"
|
||||||
|
textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO This is not correct format for error, change it
|
// TODO This is not correct format for error, change it
|
||||||
val informationData = MessageInformationData(
|
val informationData = messageInformationDataFactory.create(event, nextEvent)
|
||||||
eventId = timelineEvent.root.eventId ?: "?",
|
|
||||||
senderId = timelineEvent.root.sender ?: "",
|
return MessageTextItem_()
|
||||||
sendState = timelineEvent.sendState,
|
.message(spannableStr)
|
||||||
avatarUrl = timelineEvent.senderAvatar(),
|
|
||||||
memberName = timelineEvent.senderName(),
|
|
||||||
showInformation = false
|
|
||||||
)
|
|
||||||
return NoticeItem_()
|
|
||||||
.noticeText(spannableStr)
|
|
||||||
.informationData(informationData)
|
.informationData(informationData)
|
||||||
|
|
||||||
|
// TODO Handle click on this event
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import android.text.style.RelativeSizeSpan
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import im.vector.matrix.android.api.permalinks.MatrixLinkify
|
import im.vector.matrix.android.api.permalinks.MatrixLinkify
|
||||||
import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
|
import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
|
||||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
import im.vector.matrix.android.api.session.events.model.RelationType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
||||||
@ -35,16 +34,14 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
|||||||
import im.vector.riotredesign.EmojiCompatFontProvider
|
import im.vector.riotredesign.EmojiCompatFontProvider
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
|
||||||
import im.vector.riotredesign.core.linkify.VectorLinkify
|
import im.vector.riotredesign.core.linkify.VectorLinkify
|
||||||
import im.vector.riotredesign.core.resources.ColorProvider
|
import im.vector.riotredesign.core.resources.ColorProvider
|
||||||
import im.vector.riotredesign.core.resources.StringProvider
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
import im.vector.riotredesign.core.utils.DebouncedClickListener
|
import im.vector.riotredesign.core.utils.DebouncedClickListener
|
||||||
import im.vector.riotredesign.features.home.getColorFromUserId
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.*
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.*
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.util.MessageInformationDataFactory
|
||||||
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
||||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||||
@ -52,50 +49,18 @@ import me.gujun.android.span.span
|
|||||||
|
|
||||||
class MessageItemFactory(private val colorProvider: ColorProvider,
|
class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||||
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
||||||
private val timelineDateFormatter: TimelineDateFormatter,
|
|
||||||
private val htmlRenderer: EventHtmlRenderer,
|
private val htmlRenderer: EventHtmlRenderer,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
|
private val messageInformationDataFactory: MessageInformationDataFactory,
|
||||||
private val emojiCompatFontProvider: EmojiCompatFontProvider) {
|
private val emojiCompatFontProvider: EmojiCompatFontProvider) {
|
||||||
|
|
||||||
fun create(event: TimelineEvent,
|
fun create(event: TimelineEvent,
|
||||||
nextEvent: TimelineEvent?,
|
nextEvent: TimelineEvent?,
|
||||||
callback: TimelineEventController.Callback?
|
callback: TimelineEventController.Callback?
|
||||||
): VectorEpoxyModel<*>? {
|
): VectorEpoxyModel<*>? {
|
||||||
|
event.root.eventId ?: return null
|
||||||
|
|
||||||
val eventId = event.root.eventId ?: return null
|
val informationData = messageInformationDataFactory.create(event, nextEvent)
|
||||||
|
|
||||||
val date = event.root.localDateTime()
|
|
||||||
val nextDate = nextEvent?.root?.localDateTime()
|
|
||||||
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
|
||||||
val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60))
|
|
||||||
?: false
|
|
||||||
|
|
||||||
val showInformation = addDaySeparator
|
|
||||||
|| event.senderAvatar != nextEvent?.senderAvatar
|
|
||||||
|| event.senderName != nextEvent?.senderName
|
|
||||||
|| nextEvent?.root?.getClearType() != EventType.MESSAGE
|
|
||||||
|| isNextMessageReceivedMoreThanOneHourAgo
|
|
||||||
|
|
||||||
val time = timelineDateFormatter.formatMessageHour(date)
|
|
||||||
val avatarUrl = event.senderAvatar
|
|
||||||
val memberName = event.senderName ?: event.root.sender ?: ""
|
|
||||||
val formattedMemberName = span(memberName) {
|
|
||||||
textColor = colorProvider.getColor(getColorFromUserId(event.root.sender
|
|
||||||
?: ""))
|
|
||||||
}
|
|
||||||
val hasBeenEdited = event.annotations?.editSummary != null
|
|
||||||
val informationData = MessageInformationData(eventId = eventId,
|
|
||||||
senderId = event.root.sender ?: "",
|
|
||||||
sendState = event.sendState,
|
|
||||||
time = time,
|
|
||||||
avatarUrl = avatarUrl,
|
|
||||||
memberName = formattedMemberName,
|
|
||||||
showInformation = showInformation,
|
|
||||||
orderedReactionList = event.annotations?.reactionsSummary?.map {
|
|
||||||
ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty())
|
|
||||||
},
|
|
||||||
hasBeenEdited = hasBeenEdited
|
|
||||||
)
|
|
||||||
|
|
||||||
if (event.root.unsignedData?.redactedEvent != null) {
|
if (event.root.unsignedData?.redactedEvent != null) {
|
||||||
//message is redacted
|
//message is redacted
|
||||||
@ -117,13 +82,11 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
return when (messageContent) {
|
return when (messageContent) {
|
||||||
is MessageEmoteContent -> buildEmoteMessageItem(messageContent,
|
is MessageEmoteContent -> buildEmoteMessageItem(messageContent,
|
||||||
informationData,
|
informationData,
|
||||||
hasBeenEdited,
|
|
||||||
event.annotations?.editSummary,
|
event.annotations?.editSummary,
|
||||||
callback)
|
callback)
|
||||||
is MessageTextContent -> buildTextMessageItem(event.sendState,
|
is MessageTextContent -> buildTextMessageItem(event.sendState,
|
||||||
messageContent,
|
messageContent,
|
||||||
informationData,
|
informationData,
|
||||||
hasBeenEdited,
|
|
||||||
event.annotations?.editSummary,
|
event.annotations?.editSummary,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
@ -266,7 +229,6 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
private fun buildTextMessageItem(sendState: SendState,
|
private fun buildTextMessageItem(sendState: SendState,
|
||||||
messageContent: MessageTextContent,
|
messageContent: MessageTextContent,
|
||||||
informationData: MessageInformationData,
|
informationData: MessageInformationData,
|
||||||
hasBeenEdited: Boolean,
|
|
||||||
editSummary: EditAggregatedSummary?,
|
editSummary: EditAggregatedSummary?,
|
||||||
callback: TimelineEventController.Callback?): MessageTextItem? {
|
callback: TimelineEventController.Callback?): MessageTextItem? {
|
||||||
|
|
||||||
@ -278,7 +240,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
|
|
||||||
return MessageTextItem_()
|
return MessageTextItem_()
|
||||||
.apply {
|
.apply {
|
||||||
if (hasBeenEdited) {
|
if (informationData.hasBeenEdited) {
|
||||||
val spannable = annotateWithEdited(linkifiedBody, callback, informationData, editSummary)
|
val spannable = annotateWithEdited(linkifiedBody, callback, informationData, editSummary)
|
||||||
message(spannable)
|
message(spannable)
|
||||||
} else {
|
} else {
|
||||||
@ -368,7 +330,6 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
|
|
||||||
private fun buildEmoteMessageItem(messageContent: MessageEmoteContent,
|
private fun buildEmoteMessageItem(messageContent: MessageEmoteContent,
|
||||||
informationData: MessageInformationData,
|
informationData: MessageInformationData,
|
||||||
hasBeenEdited: Boolean,
|
|
||||||
editSummary: EditAggregatedSummary?,
|
editSummary: EditAggregatedSummary?,
|
||||||
callback: TimelineEventController.Callback?): MessageTextItem? {
|
callback: TimelineEventController.Callback?): MessageTextItem? {
|
||||||
|
|
||||||
@ -378,7 +339,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||||||
}
|
}
|
||||||
return MessageTextItem_()
|
return MessageTextItem_()
|
||||||
.apply {
|
.apply {
|
||||||
if (hasBeenEdited) {
|
if (informationData.hasBeenEdited) {
|
||||||
val spannable = annotateWithEdited(message, callback, informationData, editSummary)
|
val spannable = annotateWithEdited(message, callback, informationData, editSummary)
|
||||||
message(spannable)
|
message(spannable)
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,7 +53,7 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
|
|||||||
|
|
||||||
// Crypto
|
// Crypto
|
||||||
EventType.ENCRYPTION -> encryptionItemFactory.create(event)
|
EventType.ENCRYPTION -> encryptionItemFactory.create(event)
|
||||||
EventType.ENCRYPTED -> encryptedItemFactory.create(event)
|
EventType.ENCRYPTED -> encryptedItemFactory.create(event, nextEvent)
|
||||||
|
|
||||||
// Unhandled event types (yet)
|
// Unhandled event types (yet)
|
||||||
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.riotredesign.features.home.room.detail.timeline.util
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
|
import im.vector.riotredesign.core.resources.ColorProvider
|
||||||
|
import im.vector.riotredesign.features.home.getColorFromUserId
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
|
||||||
|
import im.vector.riotredesign.features.home.room.detail.timeline.item.ReactionInfoData
|
||||||
|
import me.gujun.android.span.span
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class compute if data of an event (such has avatar, display name, ...) should be displayed, depending on the previous event in the timeline
|
||||||
|
*/
|
||||||
|
class MessageInformationDataFactory(private val timelineDateFormatter: TimelineDateFormatter,
|
||||||
|
private val colorProvider: ColorProvider) {
|
||||||
|
|
||||||
|
fun create(event: TimelineEvent, nextEvent: TimelineEvent?): MessageInformationData {
|
||||||
|
// Non nullability has been tested before
|
||||||
|
val eventId = event.root.eventId!!
|
||||||
|
|
||||||
|
val date = event.root.localDateTime()
|
||||||
|
|
||||||
|
val nextDate = nextEvent?.root?.localDateTime()
|
||||||
|
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
||||||
|
val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60))
|
||||||
|
?: false
|
||||||
|
val showInformation =
|
||||||
|
addDaySeparator
|
||||||
|
|| event.senderAvatar != nextEvent?.senderAvatar
|
||||||
|
|| event.senderName != nextEvent?.senderName
|
||||||
|
|| (nextEvent?.root?.getClearType() != EventType.MESSAGE && nextEvent?.root?.getClearType() != EventType.ENCRYPTED)
|
||||||
|
|| isNextMessageReceivedMoreThanOneHourAgo
|
||||||
|
|
||||||
|
val time = timelineDateFormatter.formatMessageHour(date)
|
||||||
|
val avatarUrl = event.senderAvatar()
|
||||||
|
val memberName = event.senderName ?: event.root.sender ?: ""
|
||||||
|
val formattedMemberName = span(memberName) {
|
||||||
|
textColor = colorProvider.getColor(getColorFromUserId(event.root.sender
|
||||||
|
?: ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
val hasBeenEdited = event.annotations?.editSummary != null
|
||||||
|
|
||||||
|
return MessageInformationData(
|
||||||
|
eventId = eventId,
|
||||||
|
senderId = event.root.sender ?: "",
|
||||||
|
sendState = event.sendState,
|
||||||
|
time = time,
|
||||||
|
avatarUrl = avatarUrl,
|
||||||
|
memberName = formattedMemberName,
|
||||||
|
showInformation = showInformation,
|
||||||
|
orderedReactionList = event.annotations?.reactionsSummary?.map {
|
||||||
|
ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty())
|
||||||
|
},
|
||||||
|
hasBeenEdited = hasBeenEdited
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user