Designs by Duhart All work
Rank
13 of 28
Tier
Tier B 70 of 120

17 — GlobalChat: Messaging UI (iOS + Web)

UI project 4 of 5 · IOS/TheOne/Main/GlobalChat, app/web-platform/app/globalchat Stack: SwiftUI + Combine + Core Data; React/Next.js with a transport/store/runtime split Scope: iOS module 75 Swift files ≈ 9,400 lines · web tier with composer, media, search, webrtc, transport, store

Where this sits. The client half of GlobalChat. Two independent implementations of one realtime protocol — which is exactly the situation where client/server contract discipline stops being theoretical.


One protocol, two independent clientsinteractive
# engineeringsocket open
  1. did the relay ever catch up after the restart?
  2. yeah, lag was the outbox, not Kafka. 40s to drain.✓ acked
  3. so the consumer groups were fine the whole time

The client half of project 2. The web tier splits transport, store and runtime so the socket can drop and reconnect without the UI knowing. The message above goes optimistic first, then reconciles against the server ack.

The web tier's structure

app/web-platform/app/globalchat/
  transport/    wire layer — WebSocket, reconnect, framing
  store/        client state, ordering, dedupe
  runtime/      lifecycle and orchestration
  composer/     message composition, attachments, voice
  components/   render layer
  media/        attachment handling
  search/       message search
  webrtc/       callController.ts — the media plane

Separating transport / store / runtime / render is the right decomposition for a realtime client. The transport dies constantly; the store must survive it; the render layer should never know a socket exists.

The iOS module — and the correction worth reading

docs/GLOBALCHAT-MODULE-WIRING.md is a wiring record that opens by retracting three of its own earlier conclusions. That document is a hiring artifact in its own right:

"I got these wrong first time and they change the picture materially."

  1. "The module was never orphaned — it is load-bearing." GlobalChatServer.swift declares 13 publishers typed with GlobalChatMessage, GlobalChatReceiptEvent, GlobalChatCallLogEntry and 14 other types — every one declared only inside this module. There is no second copy. The module owns model, persistence and view; GlobalChatServer owns transport.

  2. "The module has been attached in production all along." TheOneApp.swift:112 applies .attachGlobalChat(...) — committed, not added by this work. GlobalChatStore.attach had been subscribed to all 13 publishers and mirroring live traffic into Core Data on every install. The data layer was wired; only the view layer was never rendered.

  3. "The attach modifier never had a crash." The earlier claim that nothing injected GlobalChatServer was wrong — "my grep looked for a variable named server, and it is named chat."

The real gap, once the false ones were cleared, was narrow and specific: the outbound path, where GlobalChatStore held a private weak var attachedServer.

Publicly correcting your own analysis, naming the grep that misled you, and then landing a smaller and correct fix is the single most senior-coded behavior in this entire repository.

Feature surface

Attachments (typed), voice messaging, reactions, edits and deletes, view-once media, live location, typing indicators, read receipts, search, call log, and an avatar hexagon treatment migrated across the component set. The dating variant wraps 18 Dating* components in a DatingChatView facade over the same GlobalChat engine.

WEB_CHAT_RUNBOOK_AND_GAPS.md carries a WhatsApp feature-parity comparison (present / partial / missing), and WEB_CHAT_FEATURE_IMPLEMENTATION_PLAN.md turns the gaps into a phased plan with code-verified backend status, exact file/wire/store changes, effort sizing, acceptance criteria, and iOS-parity notes.

Interview surface this opens