b1f37752d6
Audit of write-actions revealed that send (and edit via realtime UPDATE) are already optimistic via local state insertion in `useConversationMessages`, and friend nicknames are pure-local localStorage. Five user-write actions were waiting on the ~100-200 ms server roundtrip + realtime echo: * Toggle mute (`setConversationMutedUntil`) * Toggle mentions-only (`setConversationMentionsOnly`) * Toggle archive (`setConversationArchived`) * Pin / unpin message (`pinMessage` / `unpinMessage`) * Revoke device (`revokeDevice` RPC) All five now flip local state synchronously and roll back on failure. The existing realtime subscriptions reconcile canonically (no-op when the optimistic patch already matches the server row), so this is purely a UX latency improvement — no protocol or persistence changes. Reactions (`toggleReaction` / `voteExclusive`) were intentionally skipped this round: rollback semantics for the exclusive-vote path with multiple sequential awaits are messy enough to warrant a dedicated pass.
@chat-app/desktop
Tauri v2 + React + Vite + Tailwind desktop client (macOS / Windows / Linux).
Prerequisites
- Node 22+, pnpm 9+
- Rust + Cargo (install via https://rustup.rs)
- Platform build deps:
- macOS: Xcode Command Line Tools
- Linux:
libwebkit2gtk-4.1-dev,build-essential,libssl-dev(Debian/Ubuntu) - Windows: Microsoft C++ Build Tools + WebView2
Dev
# from repo root
pnpm install
pnpm desktop:dev # tauri dev — launches Vite + native window
pnpm desktop:build # production bundle per platform
Layout
src/— React app (Vite bundles intodist/).src-tauri/— Rust backend.main.rswires Tauri plugins.vite.config.ts— port1420, HMR on1421, aliases to shared packages.
Secure Storage
Session tokens + user private keys live in Stronghold (tauri-plugin-stronghold).
Local message history lives in SQLite (tauri-plugin-sql), DB file encrypted at rest.