Skip to content

feat(client): direct message UI on Android (beta blocker 4/5)#597

Merged
Detair merged 1 commit into
mainfrom
feature/android-dm-ui
Jun 13, 2026
Merged

feat(client): direct message UI on Android (beta blocker 4/5)#597
Detair merged 1 commit into
mainfrom
feature/android-dm-ui

Conversation

@Detair

@Detair Detair commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

Android beta blocker 4/5: direct messages are now reachable from the Android client.

The home screen gains an envelope action (Email icon, core material-icons set) that opens a conversation list showing each DM's avatar, title, last-message preview, and unread badge. Tapping a conversation opens it through the existing TextChannelScreen — a DM is a channel, so its messages already flow through the message API by channel id.

What's new

  • ModelsDmConversation / DmParticipant / LastMessagePreview matching the flattened GET /api/dm response. KaikuJson uses the SnakeCase naming strategy + ignoreUnknownKeys, so the unmodelled channel fields (guild_id, position, …) parse away cleanly.
  • DmApi (getDms + markAsRead) and DmModule @Binds, following the existing MessageApi/ChatModule pattern.
  • DmRepository (@Singleton) holding the conversation list, with pure, unit-tested companion helpers:
    • conversationTitle — other participant for 1:1, group name (or joined names) for group DMs
    • conversationAvatarUrl — other participant's avatar for 1:1, group icon otherwise
    • clearUnread
  • DmListScreen + DmListViewModel — loads on open, retry on error, empty state; opening a DM marks it read (optimistic local clear + server call).
  • Navigation — new composable("dms") route; entry point threaded as onNavigateToDms through HomeScreen (defaulted param, so no other caller breaks).

Title/avatar resolution

Conversation Title Avatar
1:1 DM other participant's display name other participant's avatar
group w/ name channel name group icon
group w/o name other participants joined by , group icon

Tests

DmConversationTest covers all title/avatar branches (1:1, group named, group unnamed, self-only fallback) and unread clearing — 9 cases.

Notes / known limitations (acceptable for beta)

  • The DM list refreshes on open; it does not yet update unread live from the WebSocket while the list is on screen.
  • Avatar URLs are passed to Coil as-is, matching the existing MessageItem avatar convention.

🤖 Generated with Claude Code

Add a direct-message conversation list to the Android client. The home
screen gains an envelope action that opens a list of DMs showing each
conversation's avatar, title, last-message preview, and unread badge.
Tapping a conversation opens it through the existing text channel screen
(a DM is just a channel, so its messages flow through the message API by
channel id).

New pieces:
- DmConversation/DmParticipant/LastMessagePreview models matching the
  flattened GET /api/dm response (SnakeCase JSON, unknown channel fields
  ignored)
- DmApi (getDms + markAsRead) + DmModule @BINDS, following the MessageApi
  pattern
- DmRepository with pure, unit-tested helpers for conversation title and
  avatar resolution (1:1 vs group) and unread clearing
- DmListScreen + DmListViewModel; opening a DM marks it read
- "dms" nav route + envelope entry point in the home top bar

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Detair Detair merged commit 853813c into main Jun 13, 2026
30 of 31 checks passed
@Detair Detair deleted the feature/android-dm-ui branch June 13, 2026 04:30
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