mattermost-mobile-upstream/app/actions/websocket/draft.ts
Guillermo Vayá 62c694adeb feat(drafts): Phase 5 — WebSocket + lifecycle triggers make sync live
Wires the DraftSyncManager's reconcile/WS entry points (previously defined
but never called in production) into the app's WebSocket and lifecycle flow.
Design choice: WS draft events are treated as CHANGE SIGNALS that trigger an
authoritative GET reconcile of the current team, not applied directly — this
reuses Phase 4's matrix/scope/absence/observation-fence, and the server's
silent empty-upsert delete (no event) forces GET-reconciliation regardless.
The current-team GET also returns the user's DM/GM drafts, so it converges
them too; other teams' channel drafts converge on team switch.

Triggers:
- draft_created / draft_deleted WS events -> enqueue -> reconcile current team
  (constants + app/actions/websocket/draft.ts handler + event dispatch cases).
- Reconnect/first-connect: requestReconcile in doReconnect after entry batches.
- Team switch: requestReconcile in handleTeamChange (before the tablet early
  return, so both paths fire).
- Foreground: WebsocketManager forwards app-active to DraftSyncManager.onForeground
  (covers a socket that stayed open, so no reconnect fired). No second AppState
  listener is added.
- Capability change: handleCapabilityChange after config (AllowSyncedDrafts) and
  after sync_drafts preference create/update/delete batches.

Also adds a central empty-team guard in requestReconcile (the GET is per-team).

Deferred (noted for a follow-up): Global Drafts stale-on-open reconcile (touches
a screen, needs on-device verification); direct-apply of buffered WS events (the
buffer is retained, reserved for that future optimization).

tsc + eslint clean; new/updated unit tests across manager, ws handler, event
dispatch, reconnect, team switch, config/preference capability. All affected
suites green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 16:50:19 +02:00

17 lines
905 B
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import DraftSyncManager from '@managers/draft_sync_manager';
/**
* handleDraftWebSocketEvent: route an inbound draft_created / draft_deleted event to the draft-sync
* coordinator. Phase 5 treats the event as a CHANGE SIGNAL that triggers an authoritative reconcile
* of the current team, rather than applying the event payload directly (an empty-message upsert
* deletes a draft with no event, so a GET reconciliation is required regardless). The manager ignores
* the event when draft sync is disabled/invalidated. The server scopes these events to the owning
* user's other sessions, so no per-user filtering is needed here.
*/
export function handleDraftWebSocketEvent(serverUrl: string, msg: WebSocketMessage): void {
DraftSyncManager.enqueueWebSocketEvent(serverUrl, msg);
}