Skip to content

feat: preview the newest message in the chats section - #1672

Open
Chessing234 wants to merge 3 commits into
permissionlesstech:mainfrom
Chessing234:feat/recent-chat-preview
Open

feat: preview the newest message in the chats section#1672
Chessing234 wants to merge 3 commits into
permissionlesstech:mainfrom
Chessing234:feat/recent-chat-preview

Conversation

@Chessing234

Copy link
Copy Markdown
Contributor

The two follow-ups you named as worth keeping on #1576, ported onto main's RecentChatList rather than reopening that PR.

What the rows show now

Each chats row gains a second line with the newest message in the thread.

Media messages are the reason this needs any logic at all. Their content is "[image] 9F2A7C41-B0E3.jpg" — the marker is part of the message, not decoration the view adds (MimeType.Category.messagePrefix, BitchatMessage.mediaAttachment). Rendering that verbatim would put an opaque on-disk filename in front of the reader. RecentChatPreview keeps the marker and drops the filename, which is both what you asked for and what the thread itself shows.

It matches against MimeType.Category's own messagePrefix rather than three string literals, so adding a category cannot leave a path here still printing a filename. .file is included even though mediaAttachment does not resolve it to an attachment — it still arrives as prefixed content and would otherwise fall through to the text path.

Text is collapsed to one line and bounded at 80 characters, cutting on a word boundary when one is near the limit.

Hiding the open thread

The other half: a row pointing at the conversation already on screen is the sheet offering to open what is open. Suppressed by the same identity keys the section already uses for roster overlap, so a thread opened under the stable Noise ID also suppresses the row keyed by its ephemeral alias.

This needed a binding that was missing, and I would have shipped the bug without the test. selectedPeer was not among the publishers PeerListModel observes, so the suppression only took effect whenever something else triggered a refresh. The integration test spent 30.07s waiting for that to happen; with privateChatManager.$selectedPeer bound it takes 0.074s. Closing the thread restores the row, so the suppression is a view of the current selection rather than a durable removal.

Localization

No catalog changes. The markers are already the literal [image] / [voice] / [file] tokens the message content carries, so the preview reuses them rather than introducing keys that would need 30 translations.

The preview is threaded into the accessibility label too — the row uses .accessibilityElement(children: .ignore), so a line left out there is one sighted users can read and VoiceOver cannot.

Verification

  • Full SwiftPM suite green, 2018 → 2029. The delta is exactly the 11 tests added (10 unit, 1 integration).
  • RecentChatPreview is framework-free, so every rule above is exercised directly rather than through a view.
  • The integration test covers both halves against a real PeerListModel: newest-message-wins, multi-line flattening, the media marker, suppression on open, and restoration on close.
  • No local SwiftLint, so I checked the --strict rules by hand against .swiftlint.yml.

What I did not verify

No device or simulator run — the row layout is verified by reading, not by looking at it. Specifically, the second line changes each row from one line to two where a preview exists, and I have not seen how that lands against the surrounding sections at the narrowest sheet width. Worth a glance from someone with the app open before this merges.

Media messages carry their payload as "[image] <filename>" — the marker is
part of the message content, not decoration the view adds. Rendering that
verbatim in a list row would put an opaque on-disk filename in front of
the reader, which says nothing about the conversation.

Keep the marker, drop the filename, collapse text to one line and bound
its length. Matching against MimeType.Category's own messagePrefix rather
than three literals means adding a category cannot leave a path here
still printing a filename.

No caller yet; this commit is the rules and their tests.
Two follow-ups jack asked for on permissionlesstech#1576, on top of what landed.

Each chats row gains a second line with the newest message: the marker
alone for media, one collapsed line for text. Rows are also suppressed
for the conversation currently on screen, which the sheet was otherwise
offering to open.

Suppression needs its own binding. `selectedPeer` was not among the
publishers PeerListModel observes, so without it the row would linger
until some unrelated change triggered a refresh. The integration test
took 30s waiting for that before the binding existed and 0.07s after.

Preview is threaded into the accessibility label too — the row ignores
its children, so a line left out there is one sighted users can read and
VoiceOver cannot.
Periphery runs as a build gate and flags an unused import as an issue.
RecentChatPreview names only app-target types.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant