60 Commits
Author SHA1 Message Date
justmeandClaude Sonnet 5.5 4d2a0c089a feat(files): store files on the host when a channel has no file domain
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image-api Pipeline was successful
Chat stays usable when the file service is off or down. Files up to 256 MB are hosted like chat; downloads try the host first and fall back to file-service tickets.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> [CI]
2026-10-19 14:25:25 +08:00
justmeandClaude Sonnet 5.5 4b4ab4ee4d feat(files): store files on the host when a channel has no file domain
Chat stays usable when the file service is off or down. Files up to 256 MB are hosted like chat; downloads try the host first and fall back to file-service tickets.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> [CI]
2026-10-19 14:24:41 +08:00
justmeandClaude Sonnet 5.5 7e6ef5e587 chore(contract): regenerate API contract after AccountProfile comment change
ci/woodpecker/push/web-build Pipeline failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image-api unknown status
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> [CI]
2026-10-19 14:19:30 +08:00
justmeandClaude Sonnet 5.5 7274390aa1 perf(host): store avatars as content-addressed files and serve them from disk
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/web-build Pipeline failed
ci/woodpecker/push/dev-image-api unknown status
Space info now carries avatar_version instead of the inlined thumbnail; the worker fetches the thumbnail once per version. Legacy base64 rows are migrated to files on startup, and the daily backup uploads avatar files.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> [CI]
2026-10-19 14:16:50 +08:00
justme 5489407241 refactor(web): restructure into api/domain/services/worker; capabilities, file domains, video covers
- dissolve core-bridge into api (wire contract), domain (models), services (what the UI
  calls) and worker (everything that runs in the Web Worker, grouped by account, crypto,
  space, files, shares, runtime); regroup features, lib and store by responsibility and
  delete unused components
- the UI only reads backend capabilities (domain/capabilities); one tokenRole picks the
  token, hasCode/isRetryable handle errors; pre-checks that decided permissions on the
  client are gone; tests fail if those rules are reimplemented
- files go straight to the file domain (create, upload, download, delete, commit, cancel);
  the host sees one registration per file; creating a channel allocates a file domain and
  works even when the file service is down
- file panel shows which channel the files belong to and its space usage; unlimited files
  preview in chat; videos get a stored cover; the file service status is shown
- fix: console flooded by Retry-After reads on every upload frame
2026-10-19 13:38:51 +08:00
justme d3da3597cc Merge master into feat/file-api 2026-10-19 09:56:30 +08:00
justme d048fedc5e feat: keep every frame in animated avatar thumbnails and raise the thumbnail limit to 800k chars [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-17 21:37:35 +08:00
justme ea7895d85c feat(web): upload large avatars in two steps so the thumbnail applies immediately 2026-10-17 21:37:30 +08:00
justme a27534b2dd chore: regenerate api contract [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-17 21:31:15 +08:00
justme d1ff8bab7d feat(web): role groups, last seen and unread markers in members, channels and spaces; lock channels without keys 2026-10-17 21:31:15 +08:00
justme 72a5e5b839 feat(server): split file storage into a separate file service with tickets, receipts and WebDAV backup
- new projects WebDrop.FileApi (file service), WebDrop.FileProtocol (shared tickets and receipts) and WebDrop.Sync (WebDAV)
- file content of any size goes to the file service; chat, avatars and space structure stay on the main backend
- tickets issued by the main backend, receipts by the file service, deletion queue and daily reconciliation
- daily database snapshot and file sync to external storage (OpenList/WebDAV) with a 30 day retention
- reorganize Core, Storage and Api into feature folders (namespaces unchanged)
- web client uploads file frames to the file service and reads them with tickets
2026-10-17 15:25:16 +08:00
justme d66c93fe98 feat(web): avatar thumbnails with original preview, registration avatar, pure-JS crypto fallback for http [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-17 14:35:42 +08:00
justme 283196938e feat(web): stream video and audio while decrypting, paste images, 16px inputs on touch 2026-10-17 14:35:41 +08:00
justme 31ae3bc39e feat(server): lossy avatar thumbnails, gzip upload and separate avatar endpoints 2026-10-17 14:35:41 +08:00
justme ba0b6c258a feat(web): space avatars with GIF support and live space list sync [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-17 13:44:16 +08:00
justme 96f92c2ba9 feat(web): inline previews in chat and per-upload download limit choice 2026-10-17 13:44:16 +08:00
justme 1a4069576b feat(server): space avatars and full member profiles in the structure response 2026-10-17 13:44:16 +08:00
justme 77c9017129 chore: regenerate API contract after role color doc changes [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-17 13:26:38 +08:00
justme a08aa7568f feat(web): animated GIF avatars that refresh across chat and member list [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/dev-image unknown status
2026-10-17 13:25:14 +08:00
justme 3b062687cd feat(web): role colors with picker, Material 3 draw, effects and inline markdown 2026-10-17 13:25:14 +08:00
justme bef8898cd8 feat(server): owner role group, custom role colors with effects and animated avatars 2026-10-17 13:25:13 +08:00
justme 7ef298f587 fix(web): make cancel, delete and chat work while a file is uploading [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-16 19:51:45 +08:00
justme a574583943 feat(web): space roles, upload queue with pipelined frames, background resume and faster sending 2026-10-16 19:42:33 +08:00
justme 1dd54243ae feat(api): add space roles with delegated member removal and structure management 2026-10-16 19:42:31 +08:00
justme 059a29a8d5 feat(web): ask for a display name when creating an account [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-16 18:30:59 +08:00
justme 915992776d feat(web): show the space validity period in the top bar 2026-10-16 18:30:59 +08:00
justme 6d6490055e feat(web): tidy the channel sidebar and let owners delete groups 2026-10-16 18:30:58 +08:00
justme 6310f93469 fix(web): verify deletions against the signer and read crypto state afresh 2026-10-16 18:30:58 +08:00
justme fc1dc08ebe feat(api): delete workspace groups and record who signed a content event 2026-10-16 18:30:58 +08:00
justme 55f1b70d89 feat(web): crop avatars in the browser with a live message preview [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
2026-10-16 17:54:32 +08:00
justme 18c871ec85 feat(web): use the Material settings gear and add rotate icons 2026-10-16 17:54:32 +08:00
justme 18185c5bd9 refactor(web): drop the settings entry from the space header 2026-10-16 17:54:32 +08:00
justme b847916a5b feat(web): group space settings into basic, content and join tabs 2026-10-16 17:54:31 +08:00
justme 79bfd560cb feat(web): call the login name the account ID and list sign-up requirements 2026-10-16 17:54:31 +08:00
justme fb5800f81d fix(web): show the author of incoming messages right away [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/dev-image unknown status
Messages from other members or devices used to render as an unknown member
until the space structure refreshed. Use the author account the server
records for the object, together with the loaded profiles, when the item
arrives.
2026-10-16 07:04:31 +08:00
justme 8233369cd4 feat(web)!: sign in before joining a space and drop the stranger option
Opening a space link while signed out shows the sign-in page first and keeps
the link in memory. The channel settings no longer offer the stranger switch,
and the client supports API contract major 8.
2026-10-16 06:46:15 +08:00
justme c858bd2a09 feat(server)!: require a logged-in account for every channel request
Drop unauthenticated guests from channels: the allow_guests setting, the
/guests endpoints and the guest seat table are gone, and requests without an
account session get 401 account_required. Share links are unaffected.
Contract version is now 8.0.0.
2026-10-16 06:46:15 +08:00
justme b1ac11e1d7 perf(web): shorten the cold start when opening a saved space
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
Activate the account with parallel requests, run the full vault sync in the
background, skip the duplicate space list request, and send the rejoin
together with the first screen of data. [CI]
2026-10-16 06:00:17 +08:00
justme d77ca1f113 perf(web): reuse cached crypto state and structure when decrypting and sending
Decrypting each history item no longer refetches the whole crypto state, and
sending a message only needs the object and frame requests.
2026-10-16 06:00:16 +08:00
justme 22f272e361 feat(web): show a skeleton while a space loads
Draw the page frame instead of a blank screen, fade it in only after 300ms,
and surface load errors with retry and back-to-home actions.
2026-10-16 05:44:58 +08:00
justme 1db3795d6a feat(web): open spaces as a plain chat on phones with a side drawer
Spaces, channels, files, members and the account move into a left drawer,
the top bar keeps only the essentials, and touch devices get a tap menu
instead of always-visible delete buttons. Also fixes the history checkboxes
in the channel settings sheet.
2026-10-16 05:34:38 +08:00
justme 06fe077ef1 perf(web): shorten the first open of a space for new members
Accepting an invitation no longer waits for the vault sync, the redundant
join right after joining is skipped, and the crypto state, first log page and
channel metadata are requested in parallel.
2026-10-16 05:34:38 +08:00
justme d0aefb3d6e feat(web): split the home page into quick share and spaces zones
Two side-by-side zones (stacked on narrow screens) with an icon and a
one-line positioning each: quick share is temporary, read-only and needs
no account; spaces are long-lived, multi-user and need a login. Shorter
copy, my shares listed under the share input, and an empty state for
spaces.
2026-10-14 22:42:06 +08:00
justme 0d31e3d058 feat(web): redesign account settings and the sign-in page
- account settings: sidebar sections (profile, devices, security,
  invitations, sync and sign-in) instead of one long scroll; inline device
  rename, confirmations for destructive actions and toast feedback
- sign-in/register: split layout with a quiet brand column, text tabs and
  underlined inputs; registering asks for the password twice and explains
  that it cannot be recovered
- move invitation accept/label helpers into store/invitations so the
  toast and the settings inbox share them
- add the home page zone styles used by the next commit
2026-10-14 22:42:06 +08:00
justme 4b8d0b5a5f feat(web): discord-style chat, members pane, invitations and optimistic send [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
- chat: left-aligned discord-style messages with grouped senders, hover
  actions, an auto-growing composer and file cards
- send: render messages and files locally first and replace the
  placeholder when the worker publishes the real item; failures keep the
  text with a retry action
- navigation: space rail plus a flatter channel list with the space name
  header and collapsible groups
- members: right pane tabs (files / members) grouped by online, offline
  and pending users, with a prominent invite action and a top bar shortcut
- notifications: toast host for invite results; invitees get a toast with
  an accept action, and the invitation payload now carries the space name
  and inviter inside the encrypted grant
- users over devices: drop device names, the device list and device
  rename/release; senders show the account (guests show as guest) and the
  share panel only keeps links
- follow contract 7.0.0 (max_members, members_used, members_full, /join)
- docs: ui-design and frontend updated for the new layout and concepts
2026-10-14 22:19:25 +08:00
justme d946fc5e8a feat(api)!: fold devices into users and report member presence
Contract 7.0.0 (breaking). Devices become an attribute of the account;
members are managed per user, and only unauthenticated guests keep a
per-terminal registration.

- rename seats -> max_members, seats_used -> members_used,
  seats_full -> members_full, SeatJoined -> JoinResult, the `seats`
  stream control message -> `members`, and POST /channels/{id}/seats ->
  POST /channels/{id}/join (stored channel settings are migrated on start)
- drop per-terminal encrypted device labels and the seat list/release
  endpoints; add GET/DELETE /channels/{id}/guests for guest terminals
- authenticate account members by account session only: the terminal key
  is optional for logged-in accounts, no seat row is written for them,
  and gated-download grants are counted per user (per terminal for guests)
- GET /channels/{id}/members now returns online, devices and
  online_devices per account; presence is tracked in memory from active
  WebSocket/SSE subscriptions and is not pushed over the stream
- owner invitation list no longer returns accounts that already joined
2026-10-14 22:18:59 +08:00
justme a6f078d009 feat(files): add per-channel storage quota [CI]
ci/woodpecker/pr/web-build Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-10-14 20:42:08 +08:00
justme b5cf3d5958 feat(web): add account workspaces and signed content flows 2026-10-14 04:06:03 +08:00
justme 7b8d61d1ba feat(api): add account workspaces and signed content events 2026-10-14 04:05:30 +08:00
justme b65e32885f feat(auth): remember encrypted local login credentials 2026-10-13 01:39:24 +08:00