Merge branch 'main' into develop

This commit is contained in:
Adam Brown 2022-03-09 16:13:15 +00:00
commit ecb49b3b27
47 changed files with 142 additions and 70 deletions

View file

@ -1,3 +1,49 @@
Changes in Element v1.4.4 (2022-03-09)
======================================
Features ✨
----------
- Adds animated typing indicator to the bottom of the timeline ([#3296](https://github.com/vector-im/element-android/issues/3296))
- Removes the topic and typing information from the room's top bar ([#4642](https://github.com/vector-im/element-android/issues/4642))
- Add possibility to save media from Gallery + reorder choices in message context menu ([#5005](https://github.com/vector-im/element-android/issues/5005))
- Improves settings error dialog messaging when changing avatar or display name fails ([#5418](https://github.com/vector-im/element-android/issues/5418))
Bugfixes 🐛
----------
- Open direct message screen when clicking on DM button in the space members list ([#4319](https://github.com/vector-im/element-android/issues/4319))
- Fix incorrect media cache size in settings ([#5394](https://github.com/vector-im/element-android/issues/5394))
- Setting an avatar when creating a room had no effect ([#5402](https://github.com/vector-im/element-android/issues/5402))
- Fix reactions summary crash when reopening a room ([#5463](https://github.com/vector-im/element-android/issues/5463))
- Fixing room titles overlapping the room image in the room toolbar ([#5468](https://github.com/vector-im/element-android/issues/5468))
In development 🚧
----------------
- Starts the FTUE account personalisation flow by adding an account created screen behind a feature flag ([#5158](https://github.com/vector-im/element-android/issues/5158))
SDK API changes ⚠️
------------------
- Change name of getTimeLineEvent and getTimeLineEventLive methods to getTimelineEvent and getTimelineEventLive. ([#5330](https://github.com/vector-im/element-android/issues/5330))
Other changes
-------------
- Improve Bubble layouts rendering ([#5303](https://github.com/vector-im/element-android/issues/5303))
- Continue improving realm usage (potentially helping with storage and RAM usage) ([#5330](https://github.com/vector-im/element-android/issues/5330))
- Update reaction button layout. ([#5313](https://github.com/vector-im/element-android/issues/5313))
- Adds forceLoginFallback feature flag and usages to FTUE login and registration ([#5325](https://github.com/vector-im/element-android/issues/5325))
- Override task affinity to prevent unknown activities running in our app tasks. ([#4498](https://github.com/vector-im/element-android/issues/4498))
- Tentatively fixing the UI sanity test being unable to click on the space menu items ([#5269](https://github.com/vector-im/element-android/issues/5269))
- Moves attachment-viewer, diff-match-patch, and multipicker modules to subfolders under library ([#5309](https://github.com/vector-im/element-android/issues/5309))
- Log the `since` token used and `next_batch` token returned when doing an incremental sync. ([#5312](https://github.com/vector-im/element-android/issues/5312), [#5318](https://github.com/vector-im/element-android/issues/5318))
- Upgrades material dependency version from 1.4.0 to 1.5.0 ([#5392](https://github.com/vector-im/element-android/issues/5392))
- Using app name instead of hardcoded "Element" for exported keys filename ([#5326](https://github.com/vector-im/element-android/issues/5326))
- Upgrade the plugin which generate strings with template from 1.2.2 to 2.0.0 ([#5348](https://github.com/vector-im/element-android/issues/5348))
- Remove about 700 unused strings and their translations ([#5352](https://github.com/vector-im/element-android/issues/5352))
- Creates dedicated VectorOverrides for forcing behaviour for local testing/development ([#5361](https://github.com/vector-im/element-android/issues/5361))
- Cleanup unused threads build configurations ([#5379](https://github.com/vector-im/element-android/issues/5379))
- Notify element-android channel each time a nightly build completes. ([#5314](https://github.com/vector-im/element-android/issues/5314))
- Iterate on badge / unread indicator color ([#5456](https://github.com/vector-im/element-android/issues/5456))
Changes in Element v1.4.2 (2022-02-22 Palindrome Day!) Changes in Element v1.4.2 (2022-02-22 Palindrome Day!)
====================================================== ======================================================

View file

@ -1 +0,0 @@
Typing notifications moved from the header to the bottom of the timeline.

View file

@ -1 +0,0 @@
Open direct message screen when clicking on DM button in the space members list

View file

@ -1 +0,0 @@
Override task affinity to prevent unknown activities running in our app tasks.

View file

@ -1 +0,0 @@
Update the top bar in a room: remove topic and typing information

View file

@ -1 +0,0 @@
Add possibility to save media from Gallery + reorder choices in message context menu

View file

@ -1 +0,0 @@
Starts the FTUE account personalisation flow by adding an account created screen behind a feature flag

View file

@ -1 +0,0 @@
Tentatively fixing the UI sanity test being unable to click on the space menu items

View file

@ -1 +0,0 @@
Improve Bubble layouts rendering.

View file

@ -1 +0,0 @@
Moves attachment-viewer, diff-match-patch, and multipicker modules to subfolders under library

View file

@ -1 +0,0 @@
Log the `since` token used and `next_batch` token returned when doing an incremental sync.

View file

@ -1 +0,0 @@
Update reaction button layout.

View file

@ -1 +0,0 @@
Notify element-android channel each time a nightly build completes.

View file

@ -1 +0,0 @@
Log the `since` token used and `next_batch` token returned when doing an incremental sync.

View file

@ -1 +0,0 @@
Adds forceLoginFallback feature flag and usages to FTUE login and registration

View file

@ -1 +0,0 @@
[Export e2ee keys] use appName instead of element

View file

@ -1 +0,0 @@
Continue improving realm usage.

View file

@ -1 +0,0 @@
Change name of getTimeLineEvent and getTimeLineEventLive methods to getTimelineEvent and getTimelineEventLive.

View file

@ -1 +0,0 @@
Upgrade the plugin which generate strings with template from 1.2.2 to 2.0.0

View file

@ -1 +0,0 @@
Remove about 700 unused strings and their translations

View file

@ -1 +0,0 @@
Creates dedicated VectorOverrides for forcing behaviour for local testing/development

View file

@ -1 +0,0 @@
Cleanup unused threads build configurations

View file

@ -1 +0,0 @@
Upgrades material dependency version from 1.4.0 to 1.5.0

View file

@ -1 +0,0 @@
Fix incorrect media cache size in settings

View file

@ -1 +0,0 @@
[Create room] Setting an avatar when creating a room had no effect

View file

@ -1 +0,0 @@
Improves settings error dialog messaging when changing avatar or display name fails

View file

@ -1 +0,0 @@
Iterate on badge / unread indicator color

View file

@ -0,0 +1,2 @@
Main changes in this version: typing indicator UI updates. Various bug fixes and stability improvements.
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.4.4

View file

@ -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.DaySeparatorItem_
import im.vector.app.features.home.room.detail.timeline.item.ItemWithEvents 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.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.ReadReceiptData
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptsItem import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptsItem
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever 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, partialState = partialState,
lastSentEventIdWithoutReadReceipts = lastSentEventWithoutReadReceipts, lastSentEventIdWithoutReadReceipts = lastSentEventWithoutReadReceipts,
callback = callback, 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) modelCache[position] = buildCacheItem(params)
numberOfEventsToBuild++ numberOfEventsToBuild++

View file

@ -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.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.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.Session
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
@ -61,7 +62,8 @@ class CallItemFactory @Inject constructor(
highlight = params.isHighlighted, highlight = params.isHighlighted,
informationData = informationData, informationData = informationData,
isStillActive = callEventGrouper.isInCall(), isStillActive = callEventGrouper.isInCall(),
formattedDuration = callEventGrouper.formattedDuration() formattedDuration = callEventGrouper.formattedDuration(),
reactionsSummaryEvents = params.reactionsSummaryEvents
) )
} else { } else {
null null
@ -78,7 +80,8 @@ class CallItemFactory @Inject constructor(
highlight = params.isHighlighted, highlight = params.isHighlighted,
informationData = informationData, informationData = informationData,
isStillActive = callEventGrouper.isRinging(), isStillActive = callEventGrouper.isRinging(),
formattedDuration = callEventGrouper.formattedDuration() formattedDuration = callEventGrouper.formattedDuration(),
reactionsSummaryEvents = params.reactionsSummaryEvents
) )
} else { } else {
null null
@ -94,7 +97,8 @@ class CallItemFactory @Inject constructor(
highlight = params.isHighlighted, highlight = params.isHighlighted,
informationData = informationData, informationData = informationData,
isStillActive = false, isStillActive = false,
formattedDuration = callEventGrouper.formattedDuration() formattedDuration = callEventGrouper.formattedDuration(),
reactionsSummaryEvents = params.reactionsSummaryEvents
) )
} }
EventType.CALL_HANGUP -> { EventType.CALL_HANGUP -> {
@ -111,7 +115,8 @@ class CallItemFactory @Inject constructor(
highlight = params.isHighlighted, highlight = params.isHighlighted,
informationData = informationData, informationData = informationData,
isStillActive = false, isStillActive = false,
formattedDuration = callEventGrouper.formattedDuration() formattedDuration = callEventGrouper.formattedDuration(),
reactionsSummaryEvents = params.reactionsSummaryEvents
) )
} }
else -> null else -> null
@ -133,10 +138,11 @@ class CallItemFactory @Inject constructor(
highlight: Boolean, highlight: Boolean,
isStillActive: Boolean, isStillActive: Boolean,
formattedDuration: String, formattedDuration: String,
callback: TimelineEventController.Callback? callback: TimelineEventController.Callback?,
reactionsSummaryEvents: ReactionsSummaryEvents?
): CallTileTimelineItem? { ): CallTileTimelineItem? {
val userOfInterest = roomSummary.toMatrixItem() val userOfInterest = roomSummary.toMatrixItem()
val attributes = messageItemAttributesFactory.create(null, informationData, callback).let { val attributes = messageItemAttributesFactory.create(null, informationData, callback, reactionsSummaryEvents).let {
CallTileTimelineItem.Attributes( CallTileTimelineItem.Attributes(
callId = callId, callId = callId,
callKind = callKind, callKind = callKind,
@ -151,7 +157,8 @@ class CallItemFactory @Inject constructor(
readReceiptsCallback = it.readReceiptsCallback, readReceiptsCallback = it.readReceiptsCallback,
userOfInterest = userOfInterest, userOfInterest = userOfInterest,
callback = callback, callback = callback,
isStillActive = isStillActive isStillActive = isStillActive,
reactionsSummaryEvents = reactionsSummaryEvents
) )
} }
return CallTileTimelineItem_() return CallTileTimelineItem_()

View file

@ -111,7 +111,9 @@ class EncryptedItemFactory @Inject constructor(private val messageInformationDat
messageContent = event.root.content.toModel<EncryptedEventContent>(), messageContent = event.root.content.toModel<EncryptedEventContent>(),
informationData = informationData, informationData = informationData,
callback = params.callback, callback = params.callback,
threadDetails = threadDetails) threadDetails = threadDetails,
reactionsSummaryEvents = params.reactionsSummaryEvents
)
return MessageTextItem_() return MessageTextItem_()
.layout(informationData.messageLayout.layoutRes) .layout(informationData.messageLayout.layoutRes)
.leftGuideline(avatarSizeProvider.leftGuideline) .leftGuideline(avatarSizeProvider.leftGuideline)

View file

@ -46,7 +46,7 @@ class EncryptionItemFactory @Inject constructor(
} }
val algorithm = event.root.content.toModel<EncryptionEventContent>()?.algorithm val algorithm = event.root.content.toModel<EncryptionEventContent>()?.algorithm
val informationData = informationDataFactory.create(params) 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 isSafeAlgorithm = algorithm == MXCRYPTO_ALGORITHM_MEGOLM
val title: String val title: String
@ -80,7 +80,8 @@ class EncryptionItemFactory @Inject constructor(
itemClickListener = attributes.itemClickListener, itemClickListener = attributes.itemClickListener,
itemLongClickListener = attributes.itemLongClickListener, itemLongClickListener = attributes.itemLongClickListener,
reactionPillCallback = attributes.reactionPillCallback, reactionPillCallback = attributes.reactionPillCallback,
readReceiptsCallback = attributes.readReceiptsCallback readReceiptsCallback = attributes.readReceiptsCallback,
reactionsSummaryEvents = attributes.reactionsSummaryEvents
) )
) )
.highlighted(params.isHighlighted) .highlighted(params.isHighlighted)

View file

@ -155,7 +155,7 @@ class MessageItemFactory @Inject constructor(
if (event.root.isRedacted()) { if (event.root.isRedacted()) {
// message is redacted // message is redacted
val attributes = messageItemAttributesFactory.create(null, informationData, callback, threadDetails) val attributes = messageItemAttributesFactory.create(null, informationData, callback, params.reactionsSummaryEvents)
return buildRedactedItem(attributes, highlight) return buildRedactedItem(attributes, highlight)
} }
@ -177,7 +177,7 @@ class MessageItemFactory @Inject constructor(
} }
// always hide summary when we are on thread timeline // 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 all = event.root.toContent()
// val ev = all.toModel<Event>() // val ev = all.toModel<Event>()
@ -413,7 +413,8 @@ class MessageItemFactory @Inject constructor(
itemClickListener = attributes.itemClickListener, itemClickListener = attributes.itemClickListener,
reactionPillCallback = attributes.reactionPillCallback, reactionPillCallback = attributes.reactionPillCallback,
readReceiptsCallback = attributes.readReceiptsCallback, readReceiptsCallback = attributes.readReceiptsCallback,
emojiTypeFace = attributes.emojiTypeFace emojiTypeFace = attributes.emojiTypeFace,
reactionsSummaryEvents = attributes.reactionsSummaryEvents
) )
) )
.callback(callback) .callback(callback)

View file

@ -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.TimelineEventController
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.item.ReactionsSummaryEvents
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
data class TimelineItemFactoryParams( data class TimelineItemFactoryParams(
@ -29,6 +30,7 @@ data class TimelineItemFactoryParams(
val partialState: TimelineEventController.PartialState = TimelineEventController.PartialState(), val partialState: TimelineEventController.PartialState = TimelineEventController.PartialState(),
val lastSentEventIdWithoutReadReceipts: String? = null, val lastSentEventIdWithoutReadReceipts: String? = null,
val callback: TimelineEventController.Callback? = null, val callback: TimelineEventController.Callback? = null,
val reactionsSummaryEvents: ReactionsSummaryEvents? = null,
val eventsGroup: TimelineEventsGroup? = null val eventsGroup: TimelineEventsGroup? = null
) { ) {

View file

@ -71,10 +71,10 @@ class VerificationItemFactory @Inject constructor(
// If it's not a request ignore this event // If it's not a request ignore this event
// if (refEvent.root.getClearContent().toModel<MessageVerificationRequestContent>() == null) return ignoredConclusion(event, highlight, callback) // if (refEvent.root.getClearContent().toModel<MessageVerificationRequestContent>() == 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 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()) { when (event.root.getClearType()) {
EventType.KEY_VERIFICATION_CANCEL -> { EventType.KEY_VERIFICATION_CANCEL -> {
@ -100,7 +100,8 @@ class VerificationItemFactory @Inject constructor(
itemClickListener = attributes.itemClickListener, itemClickListener = attributes.itemClickListener,
itemLongClickListener = attributes.itemLongClickListener, itemLongClickListener = attributes.itemLongClickListener,
reactionPillCallback = attributes.reactionPillCallback, reactionPillCallback = attributes.reactionPillCallback,
readReceiptsCallback = attributes.readReceiptsCallback readReceiptsCallback = attributes.readReceiptsCallback,
reactionsSummaryEvents = attributes.reactionsSummaryEvents
) )
) )
.highlighted(params.isHighlighted) .highlighted(params.isHighlighted)
@ -133,7 +134,8 @@ class VerificationItemFactory @Inject constructor(
itemClickListener = attributes.itemClickListener, itemClickListener = attributes.itemClickListener,
itemLongClickListener = attributes.itemLongClickListener, itemLongClickListener = attributes.itemLongClickListener,
reactionPillCallback = attributes.reactionPillCallback, reactionPillCallback = attributes.reactionPillCallback,
readReceiptsCallback = attributes.readReceiptsCallback readReceiptsCallback = attributes.readReceiptsCallback,
reactionsSummaryEvents = attributes.reactionsSummaryEvents
) )
) )
.highlighted(params.isHighlighted) .highlighted(params.isHighlighted)

View file

@ -88,7 +88,8 @@ class WidgetItemFactory @Inject constructor(
userOfInterest = userOfInterest, userOfInterest = userOfInterest,
callback = params.callback, callback = params.callback,
isStillActive = isCallStillActive, isStillActive = isCallStillActive,
formattedDuration = "" formattedDuration = "",
reactionsSummaryEvents = params.reactionsSummaryEvents
) )
return CallTileTimelineItem_() return CallTileTimelineItem_()
.attributes(attributes) .attributes(attributes)

View file

@ -93,7 +93,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
avatarUrl = event.senderInfo.avatarUrl, avatarUrl = event.senderInfo.avatarUrl,
memberName = event.senderInfo.disambiguatedDisplayName, memberName = event.senderInfo.disambiguatedDisplayName,
messageLayout = messageLayout, messageLayout = messageLayout,
reactionsSummary = reactionsSummaryFactory.create(event, params.callback), reactionsSummary = reactionsSummaryFactory.create(event),
pollResponseAggregatedSummary = event.annotations?.pollResponseSummary?.let { pollResponseAggregatedSummary = event.annotations?.pollResponseSummary?.let {
PollResponseData( PollResponseData(
myVote = it.aggregatedContent?.myVote, myVote = it.aggregatedContent?.myVote,

View file

@ -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.TimelineEventController
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem 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.MessageInformationData
import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryEvents
import org.matrix.android.sdk.api.session.threads.ThreadDetails import org.matrix.android.sdk.api.session.threads.ThreadDetails
import javax.inject.Inject import javax.inject.Inject
@ -38,6 +39,7 @@ class MessageItemAttributesFactory @Inject constructor(
fun create(messageContent: Any?, fun create(messageContent: Any?,
informationData: MessageInformationData, informationData: MessageInformationData,
callback: TimelineEventController.Callback?, callback: TimelineEventController.Callback?,
reactionsSummaryEvents: ReactionsSummaryEvents?,
threadDetails: ThreadDetails? = null): AbsMessageItem.Attributes { threadDetails: ThreadDetails? = null): AbsMessageItem.Attributes {
return AbsMessageItem.Attributes( return AbsMessageItem.Attributes(
avatarSize = avatarSizeProvider.avatarSize, avatarSize = avatarSizeProvider.avatarSize,
@ -60,6 +62,7 @@ class MessageItemAttributesFactory @Inject constructor(
emojiTypeFace = emojiCompatFontProvider.typeface, emojiTypeFace = emojiCompatFontProvider.typeface,
decryptionErrorMessage = stringProvider.getString(R.string.encrypted_message), decryptionErrorMessage = stringProvider.getString(R.string.encrypted_message),
threadDetails = threadDetails, threadDetails = threadDetails,
reactionsSummaryEvents = reactionsSummaryEvents,
areThreadMessagesEnabled = preferencesProvider.areThreadMessagesEnabled() areThreadMessagesEnabled = preferencesProvider.areThreadMessagesEnabled()
) )
} }

View file

@ -34,7 +34,7 @@ class ReactionsSummaryFactory @Inject constructor() {
return eventsRequestingBuild.remove(event.eventId) return eventsRequestingBuild.remove(event.eventId)
} }
fun create(event: TimelineEvent, callback: TimelineEventController.Callback?): ReactionsSummaryData { fun create(event: TimelineEvent): ReactionsSummaryData {
val eventId = event.eventId val eventId = event.eventId
val showAllStates = showAllReactionsByEvent.contains(eventId) val showAllStates = showAllReactionsByEvent.contains(eventId)
val reactions = event.annotations?.reactionsSummary val reactions = event.annotations?.reactionsSummary
@ -43,21 +43,24 @@ class ReactionsSummaryFactory @Inject constructor() {
} }
return ReactionsSummaryData( return ReactionsSummaryData(
reactions = reactions, reactions = reactions,
showAll = showAllStates, showAll = showAllStates
onShowMoreClicked = {
showAllReactionsByEvent.add(eventId)
onRequestBuild(eventId)
},
onShowLessClicked = {
showAllReactionsByEvent.remove(eventId)
onRequestBuild(eventId)
},
onAddMoreClicked = {
callback?.onAddMoreReaction(event)
}
) )
} }
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) { private fun onRequestBuild(eventId: String) {
eventsRequestingBuild.add(eventId) eventsRequestingBuild.add(eventId)
onRequestBuild?.invoke() onRequestBuild?.invoke()

View file

@ -121,18 +121,24 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
val showReactionsTextView = createReactionTextView(holder) val showReactionsTextView = createReactionTextView(holder)
if (reactionsSummary.showAll) { if (reactionsSummary.showAll) {
showReactionsTextView.setText(R.string.message_reaction_show_less) showReactionsTextView.setText(R.string.message_reaction_show_less)
showReactionsTextView.onClick { reactionsSummary.onShowLessClicked() } showReactionsTextView.onClick {
baseAttributes.reactionsSummaryEvents?.onShowLessClicked?.invoke()
}
} else { } else {
val moreCount = reactions.count() - MAX_REACTIONS_TO_SHOW val moreCount = reactions.count() - MAX_REACTIONS_TO_SHOW
showReactionsTextView.text = holder.view.resources.getQuantityString(R.plurals.message_reaction_show_more, moreCount, moreCount) 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) holder.reactionsContainer.addView(showReactionsTextView)
} }
val addMoreReactionsTextView = createReactionTextView(holder) val addMoreReactionsTextView = createReactionTextView(holder)
addMoreReactionsTextView.text = holder.view.context.getDrawableAsSpannable(R.drawable.ic_add_reaction_small) 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.addView(addMoreReactionsTextView)
holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener) holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener)
} }
@ -180,6 +186,7 @@ abstract class AbsBaseMessageItem<H : AbsBaseMessageItem.Holder> : BaseEventItem
// val memberClickListener: ClickListener? // val memberClickListener: ClickListener?
val reactionPillCallback: TimelineEventController.ReactionPillCallback? val reactionPillCallback: TimelineEventController.ReactionPillCallback?
val reactionsSummaryEvents: ReactionsSummaryEvents?
// val avatarCallback: TimelineEventController.AvatarCallback? // val avatarCallback: TimelineEventController.AvatarCallback?
val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback?

View file

@ -184,7 +184,8 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : AbsBaseMessageItem<H>
val emojiTypeFace: Typeface? = null, val emojiTypeFace: Typeface? = null,
val decryptionErrorMessage: String? = null, val decryptionErrorMessage: String? = null,
val threadDetails: ThreadDetails? = null, val threadDetails: ThreadDetails? = null,
val areThreadMessagesEnabled: Boolean = false val areThreadMessagesEnabled: Boolean = false,
override val reactionsSummaryEvents: ReactionsSummaryEvents? = null,
) : AbsBaseMessageItem.Attributes { ) : AbsBaseMessageItem.Attributes {
// Have to override as it's used to diff epoxy items // Have to override as it's used to diff epoxy items

View file

@ -263,7 +263,8 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem<CallTileTimelineItem.Ho
override val itemLongClickListener: View.OnLongClickListener? = null, override val itemLongClickListener: View.OnLongClickListener? = null,
override val itemClickListener: ClickListener? = null, override val itemClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
override val reactionsSummaryEvents: ReactionsSummaryEvents? = null
) : AbsBaseMessageItem.Attributes ) : AbsBaseMessageItem.Attributes
enum class CallKind(@DrawableRes val icon: Int, @StringRes val title: Int) { enum class CallKind(@DrawableRes val icon: Int, @StringRes val title: Int) {

View file

@ -58,11 +58,14 @@ data class ReferencesInfoData(
data class ReactionsSummaryData( data class ReactionsSummaryData(
/*List of reactions (emoji,count,isSelected)*/ /*List of reactions (emoji,count,isSelected)*/
val reactions: List<ReactionInfoData>? = null, val reactions: List<ReactionInfoData>? = null,
val showAll: Boolean = false, val showAll: Boolean = false
) : Parcelable
data class ReactionsSummaryEvents(
val onShowMoreClicked: () -> Unit, val onShowMoreClicked: () -> Unit,
val onShowLessClicked: () -> Unit, val onShowLessClicked: () -> Unit,
val onAddMoreClicked: () -> Unit val onAddMoreClicked: () -> Unit
) : Parcelable )
@Parcelize @Parcelize
data class ReactionInfoData( data class ReactionInfoData(

View file

@ -93,7 +93,8 @@ abstract class StatusTileTimelineItem : AbsBaseMessageItem<StatusTileTimelineIte
override val itemClickListener: ClickListener? = null, override val itemClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
val emojiTypeFace: Typeface? = null val emojiTypeFace: Typeface? = null,
override val reactionsSummaryEvents: ReactionsSummaryEvents? = null
) : AbsBaseMessageItem.Attributes ) : AbsBaseMessageItem.Attributes
enum class ShieldUIState { enum class ShieldUIState {

View file

@ -154,6 +154,7 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
// val avatarCallback: TimelineEventController.AvatarCallback? = null, // val avatarCallback: TimelineEventController.AvatarCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
val emojiTypeFace: Typeface? = null override val reactionsSummaryEvents: ReactionsSummaryEvents? = null,
val emojiTypeFace: Typeface? = null,
) : AbsBaseMessageItem.Attributes ) : AbsBaseMessageItem.Attributes
} }

View file

@ -83,6 +83,7 @@ abstract class WidgetTileTimelineItem : AbsBaseMessageItem<WidgetTileTimelineIte
override val itemClickListener: ClickListener? = null, override val itemClickListener: ClickListener? = null,
override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null, override val reactionPillCallback: TimelineEventController.ReactionPillCallback? = null,
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null, override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
val emojiTypeFace: Typeface? = null val emojiTypeFace: Typeface? = null,
override val reactionsSummaryEvents: ReactionsSummaryEvents? = null
) : AbsBaseMessageItem.Attributes ) : AbsBaseMessageItem.Attributes
} }

View file

@ -59,6 +59,13 @@
tools:ignore="MissingConstraints" tools:ignore="MissingConstraints"
tools:visibility="invisible" /> tools:visibility="invisible" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/imageGroupBarrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="roomToolbarDecorationImageView,roomToolbarAvatarImageView,roomToolbarPresenceImageView,roomToolbarPublicImageView" />
<TextView <TextView
android:id="@+id/roomToolbarTitleView" android:id="@+id/roomToolbarTitleView"
android:layout_width="0dp" android:layout_width="0dp"
@ -72,7 +79,7 @@
app:layout_constraintBottom_toBottomOf="@id/roomToolbarAvatarImageView" app:layout_constraintBottom_toBottomOf="@id/roomToolbarAvatarImageView"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/roomToolbarDecorationImageView" app:layout_constraintStart_toEndOf="@id/imageGroupBarrier"
app:layout_constraintTop_toTopOf="@id/roomToolbarAvatarImageView" app:layout_constraintTop_toTopOf="@id/roomToolbarAvatarImageView"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
app:layout_goneMarginStart="7dp" app:layout_goneMarginStart="7dp"