From 11582fc32ce1fc4032b199323fe91650a8e929ab Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Sun, 12 Jan 2025 14:10:22 +0100 Subject: [PATCH] feat: Trigger PouchDB replication when realtime event is received --- src/App.js | 2 + .../hooks/useOfflineReplicationOnRealtime.ts | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/app/domain/offline/hooks/useOfflineReplicationOnRealtime.ts diff --git a/src/App.js b/src/App.js index 3efb859cb..238325336 100644 --- a/src/App.js +++ b/src/App.js @@ -71,6 +71,7 @@ import { } from '/screens/home/hooks/useLauncherContext' import LauncherView from '/screens/konnectors/LauncherView' import { makeImportantFilesAvailableOfflineInBackground } from '/app/domain/io.cozy.files/importantFiles' +import { useOfflineReplicationOnRealtime } from '/app/domain/offline/hooks/useOfflineReplicationOnRealtime' import { useShareFiles } from '/app/domain/osReceive/services/shareFilesService' import { ClouderyOffer } from '/app/view/IAP/ClouderyOffer' import { useDimensions } from '/libs/dimensions' @@ -130,6 +131,7 @@ const App = ({ setClient }) => { useNotifications() useGeolocationTracking() useCozyEnvironmentOverride() + useOfflineReplicationOnRealtime() useOfflineDebugUniversalLinks(client) usePerformancesUniversalLinks(client) diff --git a/src/app/domain/offline/hooks/useOfflineReplicationOnRealtime.ts b/src/app/domain/offline/hooks/useOfflineReplicationOnRealtime.ts new file mode 100644 index 000000000..3bb49ebde --- /dev/null +++ b/src/app/domain/offline/hooks/useOfflineReplicationOnRealtime.ts @@ -0,0 +1,54 @@ +import { useEffect } from 'react' + +import { useClient } from 'cozy-client' +import type { CozyClientDocument } from 'cozy-client/types/types' +import Minilog from 'cozy-minilog' + +import { triggerPouchReplication } from '/app/domain/offline/utils' +import { offlineDoctypes } from '/pouchdb/getLinks' + +const log = Minilog('📶 useOfflineReplicationOnRealtime') + +export const useOfflineReplicationOnRealtime = (): void => { + const client = useClient() + + useEffect(() => { + if (!client) return + + // @ts-expect-error client.plugins is not typed + const realtime = client.plugins.realtime as CozyRealtime + + const triggerReplication = + (verb: string) => + (doc: CozyClientDocument): void => { + const docInfo = `${verb} ${doc._type ?? ''} ${doc._id ?? ''}` + log.debug(`Trigger replication from realtime event (${docInfo})`) + triggerPouchReplication(client) + } + + const triggerReplicationCreated = triggerReplication('created') + const triggerReplicationUpdated = triggerReplication('updated') + const triggerReplicationDeleted = triggerReplication('deleted') + + offlineDoctypes.forEach(doctype => { + realtime.subscribe('created', doctype, triggerReplicationCreated) + realtime.subscribe('updated', doctype, triggerReplicationUpdated) + realtime.subscribe('deleted', doctype, triggerReplicationDeleted) + }) + + return () => { + offlineDoctypes.forEach(doctype => { + realtime.unsubscribe('created', doctype, triggerReplicationCreated) + realtime.unsubscribe('updated', doctype, triggerReplicationUpdated) + realtime.unsubscribe('deleted', doctype, triggerReplicationDeleted) + }) + } + }) +} + +interface CozyRealtime { + subscribe: (event: string, type: string, handler: Subscription) => void + unsubscribe: (event: string, type: string, handler: Subscription) => void +} + +type Subscription = (doc: CozyClientDocument) => void