Skip to content

Commit 236c1b0

Browse files
committed
Fixes after rebase, review comments
1 parent dba7c64 commit 236c1b0

File tree

24 files changed

+93
-91
lines changed

24 files changed

+93
-91
lines changed

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import io.element.android.features.messages.impl.timeline.components.customreact
4343
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
4444
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState
4545
import io.element.android.features.messages.impl.timeline.model.TimelineItem
46+
import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
4647
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentWithAttachment
4748
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
4849
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
@@ -328,7 +329,10 @@ class MessagesPresenter(
328329
val displayThreads = featureFlagService.isFeatureEnabled(FeatureFlags.Threads)
329330
if (displayThreads) {
330331
// Get either the thread id this event is in, or the event id if it's not in a thread so we can start one
331-
val threadId = targetEvent.threadInfo.threadRootId ?: targetEvent.eventId!!.toThreadId()
332+
val threadId = when (targetEvent.threadInfo) {
333+
is TimelineItemThreadInfo.ThreadResponse -> targetEvent.threadInfo.threadRootId
334+
is TimelineItemThreadInfo.ThreadRoot, null -> targetEvent.eventId?.toThreadId()
335+
} ?: return@launch
332336
navigator.onOpenThread(threadId, null)
333337
} else {
334338
handleActionReply(targetEvent, composerState, timelineProtectionState)

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import io.element.android.features.messages.impl.actionlist.model.TimelineItemAc
2525
import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailure
2626
import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailureFactory
2727
import io.element.android.features.messages.impl.timeline.model.TimelineItem
28+
import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
2829
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
2930
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentWithAttachment
3031
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent
@@ -174,7 +175,7 @@ class DefaultActionListPresenter(
174175
add(TimelineItemAction.ReplyInThread)
175176
add(TimelineItemAction.Reply)
176177
} else {
177-
if (!isThreadsEnabled && timelineItem.threadInfo.threadRootId != null) {
178+
if (!isThreadsEnabled && timelineItem.threadInfo is TimelineItemThreadInfo.ThreadResponse) {
178179
// If threads are not enabled, we can reply in a thread if the item is already in the thread
179180
add(TimelineItemAction.ReplyInThread)
180181
} else {

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ internal fun aTimelineItemEvent(
146146
groupPosition: TimelineItemGroupPosition = TimelineItemGroupPosition.None,
147147
sendState: LocalEventSendState? = null,
148148
inReplyTo: InReplyToDetails? = null,
149-
threadInfo: TimelineItemThreadInfo = TimelineItemThreadInfo(threadRootId = null, latestEventText = null, threadSummary = null),
149+
threadInfo: TimelineItemThreadInfo? = null,
150150
debugInfo: TimelineItemDebugInfo = aTimelineItemDebugInfo(),
151151
timelineItemReactions: TimelineItemReactions = aTimelineItemReactions(),
152152
readReceiptState: TimelineItemReadReceipts = aTimelineItemReadReceipts(),

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ object MessageEventBubbleDefaults {
162162
}
163163
}
164164

165+
val threadInfoShape: Shape = RoundedCornerShape(BUBBLE_RADIUS)
166+
165167
// Design says: The maximum width of a bubble is still 3/4 of the screen width. But try with 78% now.
166168
const val BUBBLE_WIDTH_RATIO = 0.78f
167169
}

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,17 @@ import io.element.android.libraries.designsystem.text.toPx
9595
import io.element.android.libraries.designsystem.theme.components.Icon
9696
import io.element.android.libraries.designsystem.theme.components.Text
9797
import io.element.android.libraries.matrix.api.core.EventId
98-
import io.element.android.libraries.matrix.api.core.ThreadId
9998
import io.element.android.libraries.matrix.api.core.UserId
10099
import io.element.android.libraries.matrix.api.core.toThreadId
101100
import io.element.android.libraries.matrix.api.timeline.Timeline
102101
import io.element.android.libraries.matrix.api.timeline.item.EmbeddedEventInfo
103-
import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo
104102
import io.element.android.libraries.matrix.api.timeline.item.ThreadSummary
105103
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
106104
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
107105
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
108106
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
109107
import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl
108+
import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName
110109
import io.element.android.libraries.matrix.api.timeline.item.event.getDisplayName
111110
import io.element.android.libraries.matrix.api.user.MatrixUser
112111
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
@@ -266,24 +265,22 @@ fun TimelineItemEventRow(
266265
)
267266
}
268267

269-
if (displayThreadSummaries && timelineMode !is Timeline.Mode.Thread) {
270-
event.threadInfo.threadSummary?.let { threadSummary ->
271-
ThreadSummaryView(
272-
modifier = if (event.isMine) {
273-
Modifier.align(Alignment.End).padding(end = 16.dp)
274-
} else {
275-
if (timelineRoomInfo.isDm) Modifier else Modifier.padding(start = 16.dp)
276-
}.padding(top = 2.dp),
277-
threadSummary = threadSummary,
278-
latestEventText = event.threadInfo.latestEventText,
279-
isOutgoing = event.isMine,
280-
onClick = {
281-
event.eventId?.let {
282-
eventSink(TimelineEvents.OpenThread(it.toThreadId(), null))
283-
}
268+
if (displayThreadSummaries && timelineMode !is Timeline.Mode.Thread && event.threadInfo is TimelineItemThreadInfo.ThreadRoot) {
269+
ThreadSummaryView(
270+
modifier = if (event.isMine) {
271+
Modifier.align(Alignment.End).padding(end = 16.dp)
272+
} else {
273+
if (timelineRoomInfo.isDm) Modifier else Modifier.padding(start = 16.dp)
274+
}.padding(top = 2.dp),
275+
threadSummary = event.threadInfo.summary,
276+
latestEventText = event.threadInfo.latestEventText,
277+
isOutgoing = event.isMine,
278+
onClick = {
279+
event.eventId?.let {
280+
eventSink(TimelineEvents.OpenThread(it.toThreadId(), null))
284281
}
285-
)
286-
}
282+
}
283+
)
287284
}
288285

289286
// Read receipts / Send state
@@ -308,7 +305,7 @@ private fun ThreadSummaryView(
308305
onClick: () -> Unit,
309306
modifier: Modifier = Modifier,
310307
) {
311-
val bubbleShape = MessageEventBubbleDefaults.shape(false, TimelineItemGroupPosition.None, isOutgoing)
308+
val bubbleShape = MessageEventBubbleDefaults.threadInfoShape
312309
BoxWithConstraints(modifier = modifier) {
313310
Row(
314311
modifier = Modifier
@@ -340,7 +337,7 @@ private fun ThreadSummaryView(
340337
threadSummary.latestEvent.dataOrNull()?.let { latestEvent ->
341338
val avatarData = AvatarData(
342339
id = latestEvent.senderId.value,
343-
name = latestEvent.senderProfile.getDisplayName(),
340+
name = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId),
344341
url = latestEvent.senderProfile.getAvatarUrl(),
345342
size = AvatarSize.TimelineThreadLatestEventSender,
346343
)
@@ -779,7 +776,7 @@ private fun MessageEventBubbleContent(
779776
else -> ContentPadding.Textual
780777
}
781778
CommonLayout(
782-
showThreadDecoration = timelineMode !is Timeline.Mode.Thread && event.threadInfo.threadRootId != null,
779+
showThreadDecoration = timelineMode !is Timeline.Mode.Thread && event.threadInfo is TimelineItemThreadInfo.ThreadResponse,
783780
timestampPosition = timestampPosition,
784781
paddingBehaviour = paddingBehaviour,
785782
inReplyToDetails = event.inReplyTo,
@@ -831,17 +828,16 @@ internal fun TimelineItemEventRowWithThreadSummaryPreview() = ElementPreview {
831828
" hopefully can be manually adjusted to test different behaviors."
832829
),
833830
groupPosition = TimelineItemGroupPosition.First,
834-
threadInfo = TimelineItemThreadInfo(
835-
threadRootId = ThreadId("\$thread-root-id"),
831+
threadInfo = TimelineItemThreadInfo.ThreadRoot(
836832
latestEventText = "This is the latest message in the thread",
837-
threadSummary = ThreadSummary(AsyncData.Success(
833+
summary = ThreadSummary(AsyncData.Success(
838834
EmbeddedEventInfo(
839835
eventOrTransactionId = EventOrTransactionId.Event(EventId("\$event-id")),
840836
content = MessageContent(
841837
body = "This is the latest message in the thread",
842838
inReplyTo = null,
843839
isEdited = false,
844-
threadInfo = EventThreadInfo(null, null),
840+
threadInfo = null,
845841
type = TextMessageType("This is the latest message in the thread", null)
846842
),
847843
senderId = UserId("@user:id"),
@@ -874,7 +870,7 @@ internal fun ThreadSummaryViewPreview() {
874870
body = body,
875871
inReplyTo = null,
876872
isEdited = false,
877-
threadInfo = EventThreadInfo(null, null),
873+
threadInfo = null,
878874
type = TextMessageType(body, null)
879875
),
880876
senderId = UserId("@user:id"),

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowWithReplyPreview.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,7 @@ internal fun TimelineItemEventRowWithReplyContentToPreview(
5858
),
5959
inReplyTo = inReplyToDetails,
6060
displayNameAmbiguous = displayNameAmbiguous,
61-
threadInfo = TimelineItemThreadInfo(
62-
threadRootId = ThreadId("\$thread-root-id"),
63-
latestEventText = null,
64-
threadSummary = null,
65-
),
61+
threadInfo = TimelineItemThreadInfo.ThreadResponse(threadRootId = ThreadId("\$thread-root-id")),
6662
groupPosition = TimelineItemGroupPosition.Last,
6763
),
6864
)

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class TimelineItemContentFactory(
6464
sender: UserId,
6565
senderProfile: ProfileTimelineDetails,
6666
): TimelineItemEventContent {
67-
val isOutgoing = currentSessionIdHolder.isCurrentSession(sender)
67+
val isOutgoing = currentSessionIdHolder.current == sender
6868
return when (itemContent) {
6969
is FailedToParseMessageLikeContent -> failedToParseMessageFactory.create(itemContent)
7070
is FailedToParseStateContent -> failedToParseStateFactory.create(itemContent)

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemEventFactory.kt

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItemReac
2121
import io.element.android.features.messages.impl.timeline.model.TimelineItemReadReceipts
2222
import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
2323
import io.element.android.features.messages.impl.utils.messagesummary.MessageSummaryFormatter
24+
import io.element.android.libraries.architecture.map
2425
import io.element.android.libraries.core.bool.orTrue
2526
import io.element.android.libraries.dateformatter.api.DateFormatter
2627
import io.element.android.libraries.dateformatter.api.DateFormatterMode
@@ -30,6 +31,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
3031
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
3132
import io.element.android.libraries.matrix.api.room.RoomMember
3233
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
34+
import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo
3335
import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl
3436
import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName
3537
import io.element.android.libraries.matrix.ui.messages.reply.map
@@ -71,25 +73,27 @@ class TimelineItemEventFactory(
7173
url = senderProfile.getAvatarUrl(),
7274
size = AvatarSize.TimelineSender
7375
)
74-
75-
val threadInfo = currentTimelineItem.event.threadInfo()
76-
val threadSummaryText = threadInfo?.threadSummary?.let { (latestEvent, numberOfReplies) ->
77-
val latestEventData = latestEvent.dataOrNull() ?: return@let null
78-
val threadSummaryContent = contentFactory.create(
79-
itemContent = latestEventData.content,
80-
eventId = latestEventData.eventOrTransactionId.eventId,
81-
isEditable = false,
82-
sender = latestEventData.senderId,
83-
senderProfile = latestEventData.senderProfile,
84-
)
85-
summaryFormatter.format(threadSummaryContent)
86-
}
87-
val mappedThreadInfo = threadInfo?.let {
88-
TimelineItemThreadInfo(
89-
threadRootId = it.threadRootId,
90-
latestEventText = threadSummaryText,
91-
threadSummary = it.threadSummary,
92-
)
76+
val mappedThreadInfo = when (val threadInfo = currentTimelineItem.event.threadInfo()) {
77+
is EventThreadInfo.ThreadResponse -> {
78+
TimelineItemThreadInfo.ThreadResponse(threadInfo.threadRootId)
79+
}
80+
is EventThreadInfo.ThreadRoot -> {
81+
TimelineItemThreadInfo.ThreadRoot(
82+
summary = threadInfo.summary,
83+
latestEventText = threadInfo.summary.latestEvent.dataOrNull()
84+
?.let {
85+
contentFactory.create(
86+
itemContent = it.content,
87+
eventId = it.eventOrTransactionId.eventId,
88+
isEditable = false,
89+
sender = it.senderId,
90+
senderProfile = it.senderProfile,
91+
)
92+
}
93+
?.let(summaryFormatter::format)
94+
)
95+
}
96+
null -> null
9397
}
9498

9599
return TimelineItem.Event(
@@ -110,7 +114,7 @@ class TimelineItemEventFactory(
110114
readReceiptState = currentTimelineItem.computeReadReceiptState(roomMembers),
111115
localSendState = currentTimelineItem.event.localSendState,
112116
inReplyTo = currentTimelineItem.event.inReplyTo()?.map(permalinkParser = permalinkParser),
113-
threadInfo = mappedThreadInfo ?: TimelineItemThreadInfo(threadRootId = null, threadSummary = null, latestEventText = null),
117+
threadInfo = mappedThreadInfo,
114118
origin = currentTimelineItem.event.origin,
115119
timelineItemDebugInfoProvider = currentTimelineItem.event.timelineItemDebugInfoProvider,
116120
messageShieldProvider = currentTimelineItem.event.messageShieldProvider,

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ sealed interface TimelineItem {
8383
val readReceiptState: TimelineItemReadReceipts,
8484
val localSendState: LocalEventSendState?,
8585
val inReplyTo: InReplyToDetails?,
86-
val threadInfo: TimelineItemThreadInfo,
86+
val threadInfo: TimelineItemThreadInfo?,
8787
val origin: TimelineItemEventOrigin?,
8888
val timelineItemDebugInfoProvider: TimelineItemDebugInfoProvider,
8989
val messageShieldProvider: MessageShieldProvider,
@@ -132,8 +132,7 @@ sealed interface TimelineItem {
132132
) : TimelineItem
133133
}
134134

135-
data class TimelineItemThreadInfo(
136-
val threadRootId: ThreadId?,
137-
val latestEventText: String?,
138-
val threadSummary: ThreadSummary?,
139-
)
135+
sealed interface TimelineItemThreadInfo {
136+
data class ThreadRoot(val summary: ThreadSummary, val latestEventText: String?) : TimelineItemThreadInfo
137+
data class ThreadResponse(val threadRootId: ThreadId) : TimelineItemThreadInfo
138+
}

features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ class MessagesPresenterTest {
11811181
val initialState = awaitItem()
11821182
initialState.eventSink(MessagesEvents.HandleAction(
11831183
action = TimelineItemAction.ReplyInThread,
1184-
event = aMessageEvent(threadInfo = TimelineItemThreadInfo(A_THREAD_ID, null, null))
1184+
event = aMessageEvent(threadInfo = TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID))
11851185
))
11861186
awaitItem()
11871187
openThreadLambda.assertions().isCalledOnce().with(value(A_THREAD_ID), value(null))
@@ -1204,7 +1204,7 @@ class MessagesPresenterTest {
12041204
event = aMessageEvent(
12051205
// The event id will be used as the thread id instead
12061206
eventId = AN_EVENT_ID,
1207-
threadInfo = TimelineItemThreadInfo(null, null, null),
1207+
threadInfo = null,
12081208
)
12091209
))
12101210
awaitItem()

0 commit comments

Comments
 (0)