Skip to content

feat(chatlist): add mark-as-read to the multi-select toolbar - #70

Merged
trevarj merged 2 commits into
trevarj:mainfrom
TehPeGaSuS:feat/chatlist-mark-selected-read
Aug 26, 2026
Merged

feat(chatlist): add mark-as-read to the multi-select toolbar#70
trevarj merged 2 commits into
trevarj:mainfrom
TehPeGaSuS:feat/chatlist-mark-selected-read

Conversation

@TehPeGaSuS

Copy link
Copy Markdown
Contributor

Summary

  • unreadChatRows/mark-all deliberately skips muted rows (comment: "the whole point of muting is not to be told about activity ahead of time"), which means a muted chat's unread badge can only ever clear by opening it individually — it can grow indefinitely if you mute-and-forget.
  • Add an explicit "mark as read" action to the chat-list multi-select toolbar, between mute and archive, using Icons.Outlined.DoneAll — the same icon the drawer's existing "mark all read" action already uses, for visual consistency.
  • Unlike mark-all, this reaches every selected buffer regardless of mute state: hand-picking a row via long-press selection is an explicit opt-in, not an automatic sweep, so the muted exclusion doesn't apply here.
  • ChatListViewModel.markSelectedRead(bufferIds) delegates to the same markChatsRead entry point markCurrentScopeRead uses, just without the unreadBufferIds mute filter.

Test plan

  • ./gradlew ktlintCheck
  • ./gradlew :app:testDebugUnitTest --tests io.github.trevarj.motd.ui.chatlist.ChatListMarkSelectedReadTest (new: asserts a muted row — which unreadBufferIds itself skips — still gets marked read via the explicit selection path, plus a no-op-on-empty-selection case)
  • ./gradlew assembleDebug
  • Verified on-device: long-press select a muted chat, tap the new icon, its unread badge clears.

Mark-all deliberately skips muted rows, so a muted chat's unread
count can only ever clear by opening it individually. Add an explicit
per-selection "mark as read" action to the selection toolbar
(Icons.Outlined.DoneAll, matching the existing drawer mark-all-read
icon) that reaches every selected buffer, muted or not — hand-picking
a row is an explicit opt-in, unlike the automatic mark-all sweep.

ChatListViewModel.markSelectedRead delegates to the same
markChatsRead entry point mark-all uses, just without the mute filter.
"N selected" wrapped onto 3 lines once the toolbar carried 5 action
icons (pin/mute/mark-read/archive/delete), blowing out the bar's
height. Two changes, discussed with trev/PeGaSuS in #motd:

- The title now auto-shrinks its font (TextAutoSize.StepBased, 14-22sp)
  before ever wrapping, with maxLines=1 + ellipsis as the last-resort
  floor for pathological cases (huge selected counts on tiny screens).
- Collapse the action row to the 3 most-reached-for actions inline
  (mark as read, mute, delete/remove) plus an overflow "more" menu
  (Icons.Filled.MoreVert) holding pin and archive/unarchive. Existing
  testTags (chatlist_selection_pin/mute/archive) now live on
  DropdownMenuItems instead of top-level IconButtons.

@trevarj trevarj left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Selection action uses existing markChatsRead boundary, explicitly includes muted rows, clears transient selection, and has focused coverage. Exact head passed complete Required CI.

@trevarj
trevarj merged commit 8f6381c into trevarj:main Aug 26, 2026
6 checks passed
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.

2 participants