fix: Bug - Sending files and attachment issues
Hydrate playable media after disk receive, relay file-announce to sibling devices via account_sync, bind DM attachments to pre-allocated message ids, and improve gallery retry/cancel UX with bounded parallel auto-downloads. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -172,7 +172,7 @@ Browsers do not reliably fire WebSocket close events during page refresh or navi
|
||||
|
||||
Multi-device sessions keep **multiple** open connections for the same `oderId` (different `clientInstanceId` values per tab/device). Server broadcasts exclude only the sending **connection id**, not the whole identity, so chat/typing/voice-state updates reach every logged-in device. Presence `user_joined` / `user_left` broadcasts still exclude the whole identity so other users never see duplicate join/leave events.
|
||||
|
||||
Account-owned state (saved servers, friends, profile avatar/card text, custom emoji library, server icons, message edits/reactions, **chat message creates/revisions**) syncs through **`account_sync`** WebSocket messages. The client wraps relayable P2P broadcast events and the server forwards them to other connections for the same identity via `notifyOtherConnectionsForOderId`. When a new device identifies, existing connections receive `account_sync_peer_online` and push a full snapshot including chunked `chat-sync-batch` history for every saved room. Each `chat-sync-batch` carries its messages' attachment metadata (`attachments` map, local paths stripped) so sibling devices learn about synced attachments without holding the bytes.
|
||||
Account-owned state (saved servers, friends, profile avatar/card text, custom emoji library, server icons, message edits/reactions, **chat message creates/revisions**, **attachment `file-announce` metadata**) syncs through **`account_sync`** WebSocket messages. The client wraps relayable P2P broadcast events and the server forwards them to other connections for the same identity via `notifyOtherConnectionsForOderId`. Relayable types live in `account-sync/account-sync.rules.ts` (`RELAYABLE_ACCOUNT_SYNC_TYPES`); `file-announce` is included so sibling devices learn about new attachment metadata without requiring a cross-user mirror host first. When a new device identifies, existing connections receive `account_sync_peer_online` and push a full snapshot including chunked `chat-sync-batch` history for every saved room. Each `chat-sync-batch` carries its messages' attachment metadata (`attachments` map, local paths stripped) so sibling devices learn about synced attachments without holding the bytes.
|
||||
|
||||
RTC offers/answers/ICE are routed to the connection marked `voiceActive` for the target user (fallback: any open connection). Voice ownership is tracked per connection from `voice_state` payloads that include `clientInstanceId`.
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@ describe('account-sync.rules', () => {
|
||||
expect(isRelayableAccountSyncEvent({ type: 'chat-message', message: {} as never })).toBe(true);
|
||||
expect(isRelayableAccountSyncEvent({ type: 'message-revision', revision: {} as never })).toBe(true);
|
||||
expect(isRelayableAccountSyncEvent({ type: 'chat-sync-batch', roomId: 'r1', messages: [] })).toBe(true);
|
||||
expect(isRelayableAccountSyncEvent({
|
||||
type: 'file-announce',
|
||||
messageId: 'm1',
|
||||
file: {
|
||||
id: 'f1',
|
||||
filename: 'photo.png',
|
||||
size: 1,
|
||||
mime: 'image/png',
|
||||
isImage: true
|
||||
}
|
||||
})).toBe(true);
|
||||
|
||||
expect(isRelayableAccountSyncEvent({ type: 'voice-state', voiceState: {} as never })).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ const RELAYABLE_ACCOUNT_SYNC_TYPES = new Set([
|
||||
'chat-message',
|
||||
'message-revision',
|
||||
'chat-sync-batch',
|
||||
'file-announce',
|
||||
'user-avatar-summary',
|
||||
'user-avatar-request',
|
||||
'user-avatar-full',
|
||||
|
||||
Reference in New Issue
Block a user