make thread roots more distinguishable, and always show them even when redacted

This commit is contained in:
Henry Hiles 2026-11-06 09:46:59 -05:00
commit 5eed03c10e
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
3 changed files with 15 additions and 1 deletions

View file

@ -64,6 +64,10 @@ class const EventRenderer(
/// If set, shows who in this chat has read up to this event, e.g. in the /// If set, shows who in this chat has read up to this event, e.g. in the
/// timeline. /// timeline.
final ChatParams? readReceiptsChat, final ChatParams? readReceiptsChat,
/// The root of the thread this is shown in, if any, to set it apart from the
/// replies.
final String? threadRoot,
super.key, super.key,
}) extends HookConsumerWidget { }) extends HookConsumerWidget {
@override @override
@ -121,7 +125,9 @@ class const EventRenderer(
if (isHidden && !textOnly) return SizedBox.shrink(); if (isHidden && !textOnly) return SizedBox.shrink();
final isThreadRoot = threadRoot != null && event.eventId == threadRoot;
final isGrouped = final isGrouped =
(threadRoot == null || previousEvent?.eventId != threadRoot) &&
(previousEvent?.isShownAsMessage ?? false) && (previousEvent?.isShownAsMessage ?? false) &&
event.sender == previousEvent?.sender && event.sender == previousEvent?.sender &&
event.pmp?.id == previousEvent?.pmp?.id; event.pmp?.id == previousEvent?.pmp?.id;
@ -166,7 +172,8 @@ class const EventRenderer(
), ),
); );
final child = event.isShownAsMessage final child =
event.isShownAsMessage || (isThreadRoot && event.redactedBy != null)
? MessageRenderer( ? MessageRenderer(
event, event,
onTapReply: jumpToEvent == null onTapReply: jumpToEvent == null
@ -560,6 +567,8 @@ class const EventRenderer(
) )
else if (threadSummary != null) else if (threadSummary != null)
Padding(padding: .only(left: 4), child: threadSummary), Padding(padding: .only(left: 4), child: threadSummary),
if (isThreadRoot && !textOnly) Divider(height: 16),
], ],
); );
} }

View file

@ -55,6 +55,10 @@ class const MessageRenderer(
); );
final rendered = switch (event.content) { final rendered = switch (event.content) {
_ when event.redactedBy != null => Text(
"Redacted event",
style: errorStyle,
),
EncryptedContent() => Text("Unable to decrypt event", style: errorStyle), EncryptedContent() => Text("Unable to decrypt event", style: errorStyle),
StickerContent(:final body, :final url, :final info) => StickerContent(:final body, :final url, :final info) =>
textOnly textOnly

View file

@ -34,6 +34,7 @@ class const ChatTimeline({
getEventOptions: getEventOptions, getEventOptions: getEventOptions,
onSwipe: onSwipe == null ? null : () => onSwipe!(eventRowId), onSwipe: onSwipe == null ? null : () => onSwipe!(eventRowId),
readReceiptsChat: chat, readReceiptsChat: chat,
threadRoot: chat.threadRoot,
), ),
key: key, key: key,
isHighlighted: scroll.highlightedEvent == eventRowId, isHighlighted: scroll.highlightedEvent == eventRowId,