mirror of
https://github.com/mattermost/mattermost-mobile.git
synced 2026-11-07 03:10:12 +00:00
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>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import DraftSyncManager from '@managers/draft_sync_manager';
|
|
|
|
import {handleDraftWebSocketEvent} from './draft';
|
|
|
|
jest.mock('@managers/draft_sync_manager', () => ({
|
|
__esModule: true,
|
|
default: {enqueueWebSocketEvent: jest.fn()},
|
|
}));
|
|
|
|
describe('handleDraftWebSocketEvent', () => {
|
|
const serverUrl = 'https://server.test';
|
|
|
|
const draftEvent = (event: string): WebSocketMessage => ({
|
|
event,
|
|
data: {draft: '{"channel_id":"c","root_id":"","message":"hi"}'},
|
|
broadcast: {} as WebsocketBroadcast,
|
|
seq: 1,
|
|
});
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('routes a draft_created event to DraftSyncManager.enqueueWebSocketEvent', () => {
|
|
const msg = draftEvent('draft_created');
|
|
handleDraftWebSocketEvent(serverUrl, msg);
|
|
expect(DraftSyncManager.enqueueWebSocketEvent).toHaveBeenCalledWith(serverUrl, msg);
|
|
});
|
|
|
|
it('routes a draft_deleted event to DraftSyncManager.enqueueWebSocketEvent', () => {
|
|
const msg = draftEvent('draft_deleted');
|
|
handleDraftWebSocketEvent(serverUrl, msg);
|
|
expect(DraftSyncManager.enqueueWebSocketEvent).toHaveBeenCalledWith(serverUrl, msg);
|
|
});
|
|
});
|