Commit Graph

15 Commits

Author SHA1 Message Date
90c2c1e3e0 feat(realtime): replace polling with a Rust-owned WebSocket connection
MessageList polled every three seconds and ChatPage bumped a refreshKey after
each send. Both are gone; messages now arrive over a socket.

The connection lives in the Tauri Rust layer rather than in the WebView. Two
reasons: the handshake can carry a real Authorization header, which is the only
channel that nginx, Apache and Caddy do not write to their access logs by
default, and tungstenite surfaces the full HTTP response on a rejected
handshake. The browser API is required by spec to collapse every failure into
close code 1006, so "token expired" and "server down" would be
indistinguishable — which matters once the client holds connections to several
servers and has to show a meaningful state for each.

The socket only carries {conversation, seq}. Rust does the backfill over REST
and hands resolved entities to the frontend, so the UI keeps no cursor logic:
it replaces by id and sorts by seq.

The client now supplies the message id. Without it an optimistically rendered
message cannot be matched against the copy that arrives over the realtime
channel and shows up twice; it also makes a retry after an unclear network
error a no-op instead of a duplicate.

icons/icon.ico is generated from the existing icon.png — tauri-build requires
it on Windows, and without it the crate does not build there at all.

Not yet done, marked as TODO in the code: token refresh (the connection ends
at expiry with 4001), the server list replacing BASE_URL, optimistic rendering,
and the DM-versus-channel rule for background fetching.
2026-08-14 18:26:28 +02:00
b93ca7dcb6 ci: add Gitea workflow for Linux and Android release builds
Some checks failed
release / build (push) Failing after 2m6s
v0.0.1
2026-08-14 12:04:34 +02:00
fb3bc6e93a docs: add README 2026-08-13 13:10:55 +02:00
dc7678d184 chore: add app icon 2026-08-12 18:11:43 +02:00
ee19de5f94 fix: reset scroll ref on conversation change
prevLengthRef.current was never zeroed when conversationId changed,
so the first batch of messages in a new (shorter) conversation would
not trigger scrollIntoView. Reset it in the polling useEffect cleanup.
2026-08-12 18:03:19 +02:00
455d304885 fix: address final review findings
- Finding 1: add AppState::authed_get/authed_post helpers that attach
  Bearer token when present; all 4 commands now use them
- Finding 2: MessageInput accepts onSent callback, calls it after
  successful send; ChatPage passes refreshKey bump as onSent
- Finding 3: MessageList useEffect uses cancellation flag so stale
  in-flight responses cannot overwrite a newly selected conversation
- Finding 4: scrollIntoView moved to separate effect keyed on
  messages.length so scroll only fires when new messages arrive
2026-08-12 17:58:02 +02:00
91260c8e30 feat: implement chat page with conversation list, message view, and polling 2026-08-12 17:51:00 +02:00
68c5024334 feat: implement workspace list page 2026-08-12 17:47:50 +02:00
b4e9d25b9f feat: implement login page 2026-08-12 17:44:21 +02:00
a432ac976b feat: add React app shell with routing 2026-08-12 17:27:40 +02:00
3109ac4c22 feat: add message Tauri commands 2026-08-12 17:21:44 +02:00
7c2e5ca9a9 feat: add workspace and conversation Tauri commands
Implement list_workspaces and list_conversations commands to enable
frontend access to workspace and conversation data via Tauri IPC.

- Add workspace.rs with list_workspaces command (GET /workspaces)
- Add conversation.rs with list_conversations command (GET /conversations?workspace_id=)
- Register both commands in lib.rs invoke_handler
- Update commands/mod.rs to expose new modules
2026-08-12 17:04:35 +02:00
d384465f2e feat: add login Tauri command 2026-08-12 16:59:55 +02:00
55133751cb feat: add AppState and domain models
- Introduce state.rs with AppState (HTTP client + token/user_id state)
- Define core models in models.rs (User, Workspace, Conversation, Message, AuthTokenResponse)
- Integrate state management into lib.rs via .manage(AppState::new())
2026-08-12 16:56:03 +02:00
a1032ddf11 chore: scaffold Tauri v2 + Vite + React project structure 2026-08-12 16:48:27 +02:00