diff --git a/changelog.d/5463.bugfix b/changelog.d/5463.bugfix new file mode 100644 index 0000000000..3e06b96b8a --- /dev/null +++ b/changelog.d/5463.bugfix @@ -0,0 +1 @@ +Fix reactions summary crash diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 43fa9e0c2e..fb47fb5136 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -53,6 +53,7 @@ import im.vector.app.features.home.room.detail.timeline.item.DaySeparatorItem import im.vector.app.features.home.room.detail.timeline.item.DaySeparatorItem_ import im.vector.app.features.home.room.detail.timeline.item.ItemWithEvents import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData +import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryEvents import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptsItem import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever @@ -415,7 +416,12 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec partialState = partialState, lastSentEventIdWithoutReadReceipts = lastSentEventWithoutReadReceipts, callback = callback, - eventsGroup = timelineEventsGroup + eventsGroup = timelineEventsGroup, + reactionsSummaryEvents = ReactionsSummaryEvents( + onAddMoreClicked = { reactionListFactory.onAddMoreClicked(callback, event) }, + onShowLessClicked = { reactionListFactory.onShowLessClicked(event.eventId) }, + onShowMoreClicked = { reactionListFactory.onShowMoreClicked(event.eventId) } + ) ) modelCache[position] = buildCacheItem(params) numberOfEventsToBuild++ diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/CallItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/CallItemFactory.kt index 0161f0b55d..a5d6f75387 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/CallItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/CallItemFactory.kt @@ -26,6 +26,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttrib import im.vector.app.features.home.room.detail.timeline.item.CallTileTimelineItem import im.vector.app.features.home.room.detail.timeline.item.CallTileTimelineItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData +import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryEvents import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -61,7 +62,8 @@ class CallItemFactory @Inject constructor( highlight = params.isHighlighted, informationData = informationData, isStillActive = callEventGrouper.isInCall(), - formattedDuration = callEventGrouper.formattedDuration() + formattedDuration = callEventGrouper.formattedDuration(), + reactionsSummaryEvents = params.reactionsSummaryEvents ) } else { null @@ -78,7 +80,8 @@ class CallItemFactory @Inject constructor( highlight = params.isHighlighted, informationData = informationData, isStillActive = callEventGrouper.isRinging(), - formattedDuration = callEventGrouper.formattedDuration() + formattedDuration = callEventGrouper.formattedDuration(), + reactionsSummaryEvents = params.reactionsSummaryEvents ) } else { null @@ -94,7 +97,8 @@ class CallItemFactory @Inject constructor( highlight = params.isHighlighted, informationData = informationData, isStillActive = false, - formattedDuration = callEventGrouper.formattedDuration() + formattedDuration = callEventGrouper.formattedDuration(), + reactionsSummaryEvents = params.reactionsSummaryEvents ) } EventType.CALL_HANGUP -> { @@ -111,7 +115,8 @@ class CallItemFactory @Inject constructor( highlight = params.isHighlighted, informationData = informationData, isStillActive = false, - formattedDuration = callEventGrouper.formattedDuration() + formattedDuration = callEventGrouper.formattedDuration(), + reactionsSummaryEvents = params.reactionsSummaryEvents ) } else -> null @@ -133,10 +138,11 @@ class CallItemFactory @Inject constructor( highlight: Boolean, isStillActive: Boolean, formattedDuration: String, - callback: TimelineEventController.Callback? + callback: TimelineEventController.Callback?, + reactionsSummaryEvents: ReactionsSummaryEvents? ): CallTileTimelineItem? { val userOfInterest = roomSummary.toMatrixItem() - val attributes = messageItemAttributesFactory.create(null, informationData, callback).let { + val attributes = messageItemAttributesFactory.create(null, informationData, callback, reactionsSummaryEvents).let { CallTileTimelineItem.Attributes( callId = callId, callKind = callKind, @@ -151,7 +157,8 @@ class CallItemFactory @Inject constructor( readReceiptsCallback = it.readReceiptsCallback, userOfInterest = userOfInterest, callback = callback, - isStillActive = isStillActive + isStillActive = isStillActive, + reactionsSummaryEvents = reactionsSummaryEvents ) } return CallTileTimelineItem_() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt index bc2497392c..2b04600af2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt @@ -111,7 +111,9 @@ class EncryptedItemFactory @Inject constructor(private val messageInformationDat messageContent = event.root.content.toModel(), informationData = informationData, callback = params.callback, - threadDetails = threadDetails) + threadDetails = threadDetails, + reactionsSummaryEvents = params.reactionsSummaryEvents + ) return MessageTextItem_() .layout(informationData.messageLayout.layoutRes) .leftGuideline(avatarSizeProvider.leftGuideline) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt index 0ff786d504..0cb86a5c1c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt @@ -46,7 +46,7 @@ class EncryptionItemFactory @Inject constructor( } val algorithm = event.root.content.toModel()?.algorithm val informationData = informationDataFactory.create(params) - val attributes = messageItemAttributesFactory.create(null, informationData, params.callback) + val attributes = messageItemAttributesFactory.create(null, informationData, params.callback, params.reactionsSummaryEvents) val isSafeAlgorithm = algorithm == MXCRYPTO_ALGORITHM_MEGOLM val title: String @@ -80,7 +80,8 @@ class EncryptionItemFactory @Inject constructor( itemClickListener = attributes.itemClickListener, itemLongClickListener = attributes.itemLongClickListener, reactionPillCallback = attributes.reactionPillCallback, - readReceiptsCallback = attributes.readReceiptsCallback + readReceiptsCallback = attributes.readReceiptsCallback, + reactionsSummaryEvents = attributes.reactionsSummaryEvents ) ) .highlighted(params.isHighlighted) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index aa1758dd6c..2890e070ef 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -155,7 +155,7 @@ class MessageItemFactory @Inject constructor( if (event.root.isRedacted()) { // message is redacted - val attributes = messageItemAttributesFactory.create(null, informationData, callback, threadDetails) + val attributes = messageItemAttributesFactory.create(null, informationData, callback, params.reactionsSummaryEvents) return buildRedactedItem(attributes, highlight) } @@ -177,7 +177,7 @@ class MessageItemFactory @Inject constructor( } // always hide summary when we are on thread timeline - val attributes = messageItemAttributesFactory.create(messageContent, informationData, callback, threadDetails) + val attributes = messageItemAttributesFactory.create(messageContent, informationData, callback, params.reactionsSummaryEvents, threadDetails) // val all = event.root.toContent() // val ev = all.toModel() @@ -413,7 +413,8 @@ class MessageItemFactory @Inject constructor( itemClickListener = attributes.itemClickListener, reactionPillCallback = attributes.reactionPillCallback, readReceiptsCallback = attributes.readReceiptsCallback, - emojiTypeFace = attributes.emojiTypeFace + emojiTypeFace = attributes.emojiTypeFace, + reactionsSummaryEvents = attributes.reactionsSummaryEvents ) ) .callback(callback) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt index 46ae01a794..7c02b6f058 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt @@ -18,6 +18,7 @@ package im.vector.app.features.home.room.detail.timeline.factory import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventsGroup +import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryEvents import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent data class TimelineItemFactoryParams( @@ -29,6 +30,7 @@ data class TimelineItemFactoryParams( val partialState: TimelineEventController.PartialState = TimelineEventController.PartialState(), val lastSentEventIdWithoutReadReceipts: String? = null, val callback: TimelineEventController.Callback? = null, + val reactionsSummaryEvents: ReactionsSummaryEvents? = null, val eventsGroup: TimelineEventsGroup? = null ) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt index bdc6906593..16cf73cbb0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt @@ -71,10 +71,10 @@ class VerificationItemFactory @Inject constructor( // If it's not a request ignore this event // if (refEvent.root.getClearContent().toModel() == null) return ignoredConclusion(event, highlight, callback) - val referenceInformationData = messageInformationDataFactory.create(TimelineItemFactoryParams(refEvent)) + val referenceInformationData = messageInformationDataFactory.create(TimelineItemFactoryParams(event = refEvent)) val informationData = messageInformationDataFactory.create(params) - val attributes = messageItemAttributesFactory.create(null, informationData, params.callback) + val attributes = messageItemAttributesFactory.create(null, informationData, params.callback, params.reactionsSummaryEvents) when (event.root.getClearType()) { EventType.KEY_VERIFICATION_CANCEL -> { @@ -100,7 +100,8 @@ class VerificationItemFactory @Inject constructor( itemClickListener = attributes.itemClickListener, itemLongClickListener = attributes.itemLongClickListener, reactionPillCallback = attributes.reactionPillCallback, - readReceiptsCallback = attributes.readReceiptsCallback + readReceiptsCallback = attributes.readReceiptsCallback, + reactionsSummaryEvents = attributes.reactionsSummaryEvents ) ) .highlighted(params.isHighlighted) @@ -133,7 +134,8 @@ class VerificationItemFactory @Inject constructor( itemClickListener = attributes.itemClickListener, itemLongClickListener = attributes.itemLongClickListener, reactionPillCallback = attributes.reactionPillCallback, - readReceiptsCallback = attributes.readReceiptsCallback + readReceiptsCallback = attributes.readReceiptsCallback, + reactionsSummaryEvents = attributes.reactionsSummaryEvents ) ) .highlighted(params.isHighlighted) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/WidgetItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/WidgetItemFactory.kt index a08383315c..647b34c626 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/WidgetItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/WidgetItemFactory.kt @@ -88,7 +88,8 @@ class WidgetItemFactory @Inject constructor( userOfInterest = userOfInterest, callback = params.callback, isStillActive = isCallStillActive, - formattedDuration = "" + formattedDuration = "", + reactionsSummaryEvents = params.reactionsSummaryEvents ) return CallTileTimelineItem_() .attributes(attributes) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 59b39d17ef..97b3a8f445 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -93,7 +93,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses avatarUrl = event.senderInfo.avatarUrl, memberName = event.senderInfo.disambiguatedDisplayName, messageLayout = messageLayout, - reactionsSummary = reactionsSummaryFactory.create(event, params.callback), + reactionsSummary = reactionsSummaryFactory.create(event), pollResponseAggregatedSummary = event.annotations?.pollResponseSummary?.let { PollResponseData( myVote = it.aggregatedContent?.myVote, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt index 845b765101..426561054b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageItemAttributesFactory.kt @@ -24,6 +24,7 @@ import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData +import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryEvents import org.matrix.android.sdk.api.session.threads.ThreadDetails import javax.inject.Inject @@ -38,6 +39,7 @@ class MessageItemAttributesFactory @Inject constructor( fun create(messageContent: Any?, informationData: MessageInformationData, callback: TimelineEventController.Callback?, + reactionsSummaryEvents: ReactionsSummaryEvents?, threadDetails: ThreadDetails? = null): AbsMessageItem.Attributes { return AbsMessageItem.Attributes( avatarSize = avatarSizeProvider.avatarSize, @@ -60,6 +62,7 @@ class MessageItemAttributesFactory @Inject constructor( emojiTypeFace = emojiCompatFontProvider.typeface, decryptionErrorMessage = stringProvider.getString(R.string.encrypted_message), threadDetails = threadDetails, + reactionsSummaryEvents = reactionsSummaryEvents, areThreadMessagesEnabled = preferencesProvider.areThreadMessagesEnabled() ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt index fcc98ff729..3ba5997ee3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt @@ -34,7 +34,7 @@ class ReactionsSummaryFactory @Inject constructor() { return eventsRequestingBuild.remove(event.eventId) } - fun create(event: TimelineEvent, callback: TimelineEventController.Callback?): ReactionsSummaryData { + fun create(event: TimelineEvent): ReactionsSummaryData { val eventId = event.eventId val showAllStates = showAllReactionsByEvent.contains(eventId) val reactions = event.annotations?.reactionsSummary @@ -43,21 +43,24 @@ class ReactionsSummaryFactory @Inject constructor() { } return ReactionsSummaryData( reactions = reactions, - showAll = showAllStates, - onShowMoreClicked = { - showAllReactionsByEvent.add(eventId) - onRequestBuild(eventId) - }, - onShowLessClicked = { - showAllReactionsByEvent.remove(eventId) - onRequestBuild(eventId) - }, - onAddMoreClicked = { - callback?.onAddMoreReaction(event) - } + showAll = showAllStates ) } + fun onAddMoreClicked(callback: TimelineEventController.Callback?, event: TimelineEvent) { + callback?.onAddMoreReaction(event) + } + + fun onShowMoreClicked(eventId: String) { + showAllReactionsByEvent.add(eventId) + onRequestBuild(eventId) + } + + fun onShowLessClicked(eventId: String) { + showAllReactionsByEvent.remove(eventId) + onRequestBuild(eventId) + } + private fun onRequestBuild(eventId: String) { eventsRequestingBuild.add(eventId) onRequestBuild?.invoke() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 430e0970bb..4f08c9d05f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -121,18 +121,24 @@ abstract class AbsBaseMessageItem : BaseEventItem val showReactionsTextView = createReactionTextView(holder) if (reactionsSummary.showAll) { showReactionsTextView.setText(R.string.message_reaction_show_less) - showReactionsTextView.onClick { reactionsSummary.onShowLessClicked() } + showReactionsTextView.onClick { + baseAttributes.reactionsSummaryEvents?.onShowLessClicked?.invoke() + } } else { val moreCount = reactions.count() - MAX_REACTIONS_TO_SHOW showReactionsTextView.text = holder.view.resources.getQuantityString(R.plurals.message_reaction_show_more, moreCount, moreCount) - showReactionsTextView.onClick { reactionsSummary.onShowMoreClicked() } + showReactionsTextView.onClick { + baseAttributes.reactionsSummaryEvents?.onShowMoreClicked?.invoke() + } } holder.reactionsContainer.addView(showReactionsTextView) } val addMoreReactionsTextView = createReactionTextView(holder) addMoreReactionsTextView.text = holder.view.context.getDrawableAsSpannable(R.drawable.ic_add_reaction_small) - addMoreReactionsTextView.onClick { reactionsSummary.onAddMoreClicked() } + addMoreReactionsTextView.onClick { + baseAttributes.reactionsSummaryEvents?.onAddMoreClicked?.invoke() + } holder.reactionsContainer.addView(addMoreReactionsTextView) holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener) } @@ -180,6 +186,7 @@ abstract class AbsBaseMessageItem : BaseEventItem // val memberClickListener: ClickListener? val reactionPillCallback: TimelineEventController.ReactionPillCallback? + val reactionsSummaryEvents: ReactionsSummaryEvents? // val avatarCallback: TimelineEventController.AvatarCallback? val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt index 9e8f86c26e..e3ae91bf0b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -184,7 +184,8 @@ abstract class AbsMessageItem : AbsBaseMessageItem val emojiTypeFace: Typeface? = null, val decryptionErrorMessage: String? = null, val threadDetails: ThreadDetails? = null, - val areThreadMessagesEnabled: Boolean = false + val areThreadMessagesEnabled: Boolean = false, + override val reactionsSummaryEvents: ReactionsSummaryEvents? = null, ) : AbsBaseMessageItem.Attributes { // Have to override as it's used to diff epoxy items diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt index 6db0b0c380..ea130901b1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt @@ -263,7 +263,8 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem? = null, - val showAll: Boolean = false, + val showAll: Boolean = false +) : Parcelable + +data class ReactionsSummaryEvents( val onShowMoreClicked: () -> Unit, val onShowLessClicked: () -> Unit, val onAddMoreClicked: () -> Unit -) : Parcelable +) @Parcelize data class ReactionInfoData( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt index fdde087b44..2d9119f14c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/StatusTileTimelineItem.kt @@ -93,7 +93,8 @@ abstract class StatusTileTimelineItem : AbsBaseMessageItem