Skip to content

refactor(chat-list): move the chat list into a KMP module and wire it into the desktop graph - #1950

Merged
bmc08gt merged 3 commits into
code/cashfrom
refactor/chat-list-kmp
Nov 3, 2026
Merged

bmc08gt merged 3 commits into
code/cashfrom
refactor/chat-list-kmp

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

The chat list lived in features/tipping, which is Android-only, so desktop could not resolve ChatsViewModel. This moves it into a new KMP module, apps/flipcash/features/chat-list, and adds it and RealChatCoordinator to the desktop graph. Android behavior is unchanged. The desktop sidebar UI is not touched (that lands in #1920).

Module

  • ChatsViewModel and ArchivedChatsViewModel are open classes with @Inject constructors in commonMain. HiltChatsViewModel and HiltArchivedChatsViewModel in androidMain are the @HiltViewModel subclasses, as with WalletViewModel.
  • ChatsScreen and ArchivedChatsScreen stay in androidMain (hiltViewModel, title bar, toast host); ChatsScreenContent, ArchivedChatsContent, TipChatRow, ChipReveal and ConversationMapping are commonMain.
  • Strings and plurals use com.flipcash.core.resources.Res. Packages are unchanged (com.flipcash.app.tipping), so callers only gain a dependency.
  • Tipping keeps New Chat, groups and requests, and depends on chat-list.

Desktop

  • ChatModule and RecentReactionsOwnerModule join the graph, with desktop bindings for AppForeground, ChatNotifications, InviteCipher, HostInvites and RecentReactionsStore.
  • RealChatCoordinator is now in StartupContract.sharedSessionListeners rather than the Android-only list. DesktopWiringTest resolves ChatsViewModel and checks the coordinator is in the listener set.
  • Metro treats a defaulted constructor parameter as optional and leaves it out of the initialization order, so RealChatCoordinator_Factory was handed a null HostInvites provider at startup. The desktop build sets optionalBindingBehavior = REQUIRE_OPTIONAL_BINDING and binds the four T? = null parameters (HostInvites, PaymentRequests, GroupKeyEnvelopeStore, IncomingMessageOpener) explicitly.

Tests

No test is lost: tipping testDebugUnitTest went from 84 to 45, and chat-list testAndroidHostTest runs 39. Five of the VM and row tests are in commonTest and also run on jvm (jvmTest: 22 cases).

…features/chat-list

New KMP module with the chat list, archived list, their view models and
row/reveal helpers, still all in androidMain. Strings and the empty-state
drawable move from R to the Compose resources core already generates.
hostedRequests stays in tipping, its only caller.
…classes

ChatsViewModel and ArchivedChatsViewModel become open classes with an
@Inject constructor; HiltChatsViewModel and HiltArchivedChatsViewModel in
androidMain carry @hiltviewmodel, as balance does for the wallet. The
screens split into ChatsScreenContent / ArchivedChatsContent in commonMain
and thin Android entries that own hiltViewModel, the navigator, the toast
host and the title bar (TitleBar and the toast host are still androidMain
in ui/components, so the bar is a slot).

chatterName moves from an androidMain file in common-ui to commonMain; it
is a pure string function. Tests that need no Android move to commonTest
with kotlin.test and run on jvm too.
@bmc08gt bmc08gt self-assigned this Nov 3, 2026
@github-actions github-actions Bot added type: refactor Code restructuring, no behavior change area: build-system Gradle, convention plugins, build-logic labels Nov 3, 2026
@bmc08gt
bmc08gt merged commit a7bde40 into code/cash Nov 3, 2026
5 checks passed
bmc08gt added a commit that referenced this pull request Nov 3, 2026
…ee-pane

* origin/code/cash: (44 commits)
  refactor(chat-list): move the chat list into a KMP module and wire it into the desktop graph (#1950)
  build(deps): bump dev.zacsweers.metro from 1.4.5 to 1.5.1 (#1901)
  feat(flipcash): add return-payment contract scaffolding (#1949)
  refactor(chat-ui): make shared/chat-ui a KMP module (#1934)
  build(deps): bump com.google.firebase:firebase-bom from 34.19.0 to 35.1.0 (#1900)
  build(deps): bump io.ktor:ktor-network from 3.4.1 to 3.6.0 (#1909)
  build(deps): bump rinku from 1.6.0 to 1.9.0 (#1907)
  build(deps): bump androidx.webkit:webkit from 1.17.0 to 1.18.0 (#1906)
  build(deps): bump agp from 9.4.1 to 9.5.0 (#1905)
  build(deps): bump androidx-datastore from 1.2.1 to 1.3.0 (#1904)
  build(deps): bump compose-multiplatform from 1.12.1 to 1.12.2 (#1903)
  build(deps): bump com.google.android.gms:play-services-base (#1902)
  build(deps): bump okhttp from 5.5.0 to 5.5.1 (#1899)
  refactor(messenger): split ChatViewModel's reducer into per-area files (#1933)
  refactor(amount-entry): make shared/amount-entry a KMP module (#1932)
  fix(build): stop KMP host tests building release variants and debug manifests changing per commit (#1948)
  refactor(theme): collapse Avenir into one family with a real Medium face (#1947)
  perf: run independent hot-path calls concurrently (#1945)
  docs(claude): test gestures with device input and keep mode state at screen level (#1943)
  build: bump Flipcash to 2026.11.2
  ...

# Conflicts:
#	CLAUDE.md
bmc08gt added a commit that referenced this pull request Nov 3, 2026
The sidebar now runs the shared ChatsScreenContent on desktop's ChatsViewModel
(#1950) in place of the placeholder card. Picking a chat records it in
DesktopNavState and names it in the main pane. The conversation itself stays a
placeholder: it runs on ChatViewModel, which is still Android-only.

Archived chats, mute and new chat have no desktop screen yet, so those
actions do nothing. AppBarWithTitle is Android-only, so the list title is a
plain Text.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: build-system Gradle, convention plugins, build-logic type: refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant