Commit Graph
811 Commits
Author SHA1 Message Date
Jannis Braun 61dea725a3 fix(web): polish failed-upload row — pill-shaped, content-width, proper button affordance 2026-05-02 18:11:31 +02:00
Jannis Braun a58b7459fb fix(web): in-session pause/resume preserves File ref; aborted transfers flip bubble to failed 2026-05-02 18:03:12 +02:00
Jannis Braun 403c6e9075 fix(web): orchestrator dispatches eager-upload bubbles via pendingMessageStore subscribe 2026-05-02 17:52:05 +02:00
Jannis Braun 348800bfca feat(web): channel-header transfer indicator + global tray panel 2026-05-02 17:11:41 +02:00
Jannis Braun 0be69808e4 feat(web): right-click Save Video / Save Audio via transferStore 2026-05-02 17:07:39 +02:00
Jannis Braun aaa15cef88 feat(web): file-card download routes through transferStore 2026-05-02 17:06:26 +02:00
Jannis Braun d3f45dbda4 feat(web): saveImage routes through transferStore 2026-05-02 17:05:51 +02:00
Jannis Braun 2be243336b feat: all profile uploads through transferStore; delete legacy POST /api/uploads
Migrates the remaining 5 profile/space upload sites (CreateSpace, AccountPanel
avatar+banner, OverviewPanel icon+banner) to transferStore.startUpload with
tray:false. Space sites pass _instanceOrigin so uploads route to the space's
home instance.

Removes upload/uploadWithProgress from api.uploads (and their private
uploadFile/uploadFileWithProgress helpers); api.uploads.url is preserved for
GET-path URL building. Deletes the server-side POST /api/uploads handler and
the now-unused @fastify/multipart plugin registration. GET /api/uploads/:filename
remains intact.
2026-05-02 16:46:29 +02:00
Jannis Braun 727c51f659 feat(web): RegisterPage avatar uses transferStore + waitForTransfer helper
Replaces the legacy /api/uploads call in RegisterPage with the tus-based
transferStore path. Extends Transfer to persist the server-assigned
filename (not just attachmentId) since downstream consumers store
attachment.filename on the user/space record.

- transferStore: rename setAttachmentId -> setAttachmentRef(id, attachmentId, filename)
  and add attachmentFilename field to Transfer
- both startUpload + resumeUpload onSuccess paths now record filename
- new utils/waitForTransfer.ts: waitForTransferAttachment(transferId)
  returns {attachmentId, filename}, with immediate-terminal handling
- RegisterPage: silent (tray:false) upload via transferStore, awaits
  the helper, passes the server filename to api.users.update
2026-05-02 16:40:50 +02:00
Jannis Braun 48d199515a feat(web): chatStore dedups WS echo against pendingMessageStore (FIFO) 2026-05-02 16:37:22 +02:00
Jannis Braun e534644e57 feat(web): Message renders pending-bubble overlay + retry/discard chrome 2026-05-02 16:31:53 +02:00
Jannis Braun 7b6586110d feat(web): MessageList interleaves pending bubbles by createdAtLocal 2026-05-02 16:28:21 +02:00
Jannis Braun b97326ef18 feat(web): MessageInput uses composerStore + transferStore (eager upload, FS handles) 2026-05-02 16:17:49 +02:00
Jannis Braun 65d8a19c87 feat(web): AttachmentProgress overlay component 2026-05-02 16:02:47 +02:00
Jannis Braun 5128a625b8 feat(web): pending-message orchestrator (TTL discard, deferred send, online retry) 2026-05-02 16:00:30 +02:00
Jannis Braun b01ad4edb8 feat(web): pendingMessageStore with FIFO dedup matcher and TTL discard 2026-05-02 15:49:59 +02:00
Jannis Braun c986f734ee feat(web): composerStore (per-channel draft + staged transfer ids) 2026-05-02 15:41:55 +02:00
Jannis Braun 2864d84a0f feat(web): transferStore.startDownload + pause/resume/abort with FS-handle path 2026-04-30 02:16:38 +02:00
Jannis Braun bde00e2d9f feat(web): transferStore upload + resume via tus-js-client 2026-04-30 02:11:43 +02:00
Jannis Braun bdfe7b453a feat(web): transferStore skeleton with versioned persistence 2026-04-30 02:06:17 +02:00
Jannis Braun 054f063f1f feat(web): IDB persistence + capability detection for FileSystemFileHandle 2026-04-30 02:03:01 +02:00
Jannis Braun 097976538d deps(web): add tus-js-client, idb, fake-indexeddb 2026-04-30 02:00:43 +02:00
Jannis Braun f538f1d92e fix(desktop): enable PulseAudio loopback flag so screen share starts on Linux
Chromium gates the PulseAudio loopback path behind the
PulseaudioLoopbackForScreenShare feature flag. Without it, returning
audio: 'loopback' from setDisplayMediaRequestHandler rejects the whole
getDisplayMedia request, so screen share never starts when the user has
"Share system audio" enabled. Also surface a clear warning toast on
loopback failure (PipeWire-only without pulse compat, macOS without
Catap) instead of failing silently — no auto-retry, since the picker
selection is already consumed.
2026-04-29 23:43:44 +02:00
Jannis Braun e0861597bc fix(web): portal overlays into fullscreenElement so they render in voice fullscreen
requestFullscreen() on the voice container puts only its descendants in the
browser's top layer; overlays portaled to document.body were rendered outside
that layer and stayed invisible — most visibly the right-click context menu on
stream tiles and voice user panels.

Add usePortalContainer() hook returning document.fullscreenElement ?? document.body
and re-rendering on fullscreenchange. Migrate every overlay reachable during a
call: ContextMenuRenderer (desktop, submenu, mobile sheet), Tooltip,
ConfirmDialog, ConnectionInfoPopover, ScreenShareSettingsPopover, and
ScreenSharePicker (which previously rendered inline at App root).
2026-04-29 23:32:14 +02:00
Jannis Braun 1ed70a90b1 fix(dm): render system messages in sidebar preview instead of raw JSON
DmLastMessagePreview lacked a `type` field, so the sidebar rendered
`lastMessage.content` verbatim — surfacing JSON like
`{"event":"space_invite",...}` for space invites and member-add events.

Adds `type` to the preview payload (populated server-side from
`dm_messages.type`) and routes all sidebar call sites through a single
`formatDmSidebarPreview` helper that renders human-readable text for
each system event and skips the group `Sender:` prefix on system rows.
2026-04-29 23:13:09 +02:00
Jannis Braun 9aa97f4552 fix(web): joinByCode normalizes explicit home origin to local
When a caller passes the user's own instance origin (e.g. from an invite
snapshot's spaceInstanceOrigin), strip it to undefined before the remote
branch so the local api path is taken instead of erroneously failing with
NotConnectedError. Mirrors inviteParser's identical normalization.
2026-04-29 22:52:47 +02:00
Jannis Braun 85987a891c fix(web): SpaceInviteCard navigates to /channels/:spaceId (not the non-existent /spaces/:id) 2026-04-29 22:44:35 +02:00
Jannis Braun d8b08d8990 fix(web): SpaceInviteCard navigates to space on already-member instead of showing error 2026-04-29 22:41:49 +02:00
Jannis Braun 65ca54f556 feat(web): useDeepLinkHandler also subscribes to onOpenInternalRoute 2026-04-29 22:09:20 +02:00
Jannis Braun 7d98558816 feat(web): push connected-instance origins to Electron main process 2026-04-29 22:08:30 +02:00
Jannis Braun b00d21df0e feat(desktop): preload exposes setConnectedOrigins + onOpenInternalRoute 2026-04-29 22:07:26 +02:00
Jannis Braun a46d35f5f8 feat(web): InviteModal — friend picker + restyled share-link footer, drop deep link 2026-04-29 22:02:23 +02:00
Jannis Braun 1859f2963c feat(web): SystemMessage dispatches space_invite to SpaceInviteCard 2026-04-29 21:55:06 +02:00
Jannis Braun e351d53dd5 fix(web): SpaceInviteCard — real embed idiom and correct getApiForOrigin import path 2026-04-29 21:52:20 +02:00
Jannis Braun 82533c1434 feat(web): SpaceInviteCard component with snapshot/live/revoked render states
Renders space invite system messages in DMs as embed-style cards on the chat
surface. Three render states: snapshot-only on mount (Join enabled, loading
dot), live-confirmed (memberCount refreshed from preview), revoked (gray-out
+ glass-pill indicator). Join targets the space's home origin via
joinByCode(code, spaceInstanceOrigin || undefined) — the three-way
federation correctness rule. Re-exports getApiForOrigin from api/client to
expose the cross-store resolver under a natural import surface.
2026-04-29 21:50:01 +02:00
Jannis Braun 657cc0e1b9 feat(web): add dm.spaceInvite() api client method 2026-04-29 21:44:40 +02:00
Jannis Braun d31a9cf579 refactor(web): RegistrationPanel — glass-bubble modal buttons + clearer Revoke copy 2026-04-29 03:01:47 +02:00
Jannis Braun f0ac847d9e refactor(web): RegistrationPanel sibling parity — Edit/Reinstate redesign + Redemptions header 2026-04-29 02:51:44 +02:00
Jannis Braun a52bab4c16 refactor(web): CreateInviteModal — icon-badge header + uppercase section labels + dominant submit 2026-04-29 02:47:44 +02:00
Jannis Braun 526043a3b4 feat(web): RegistrationPanel sort + status filter via FilterDropdown 2026-04-29 02:44:32 +02:00
Jannis Braun b91bc89c58 refactor(web): RegistrationPanel InviteRow → collapsed/expanded model 2026-04-29 02:40:33 +02:00
Jannis Braun 3fdf501620 refactor(web): RegistrationPanel tab strip restyle + count badges 2026-04-29 02:36:52 +02:00
Jannis Braun a7c321a9d4 feat(web): show federated-registration warning banner in Connections add-instance form 2026-04-29 01:49:32 +02:00
Jannis Braun 641d4efcb9 fix(web): RegisterPage invite-fallback validation, IIFE preference, open-registration silence 2026-04-29 01:46:48 +02:00
Jannis Braun 0dae217787 feat(web): RegisterPage invite-token URL pickup + manual entry + closed-state UX 2026-04-29 01:38:52 +02:00
Jannis Braun 5b51980278 fix(web): make ConfirmDialog Escape capture-phase to prevent leaking to ancestor modals 2026-04-29 01:26:38 +02:00
Jannis Braun bde4d829ef feat(web): RegistrationPanel Edit/Revoke/Reinstate/Delete + Redemptions 2026-04-29 01:21:14 +02:00
Jannis Braun ba5c84fc6b fix(web): add Custom… expiry preset to CreateInviteModal per spec §4.2 2026-04-29 01:13:22 +02:00
Jannis Braun 234ec8e70d feat(web): RegistrationPanel Create-invite modal 2026-04-29 01:06:48 +02:00
Jannis Braun 42d1be54fa fix(web): guard RegistrationPanel invite-list against stale-fetch race 2026-04-29 00:57:57 +02:00