@@ -14,6 +14,47 @@ import { removeStaleLocalData } from '@/dataproxy/worker/data'
1414
1515const log = Minilog ( '👷♂️ [SharedWorkerProvider]' )
1616
17+ // Event payload received from cozy realtime for io.cozy.files
18+ type FilesRealtimeEvent = {
19+ dir_id : string
20+ class : string
21+ referenced_by ?: Array < { id ?: string } >
22+ }
23+
24+ function isFilesRealtimeEvent ( value : unknown ) : value is FilesRealtimeEvent {
25+ if ( ! value || typeof value !== 'object' ) return false
26+ const v = value as Record < string , unknown >
27+ return (
28+ typeof v . dir_id === 'string' &&
29+ typeof v . class === 'string' &&
30+ ( v . referenced_by === undefined || Array . isArray ( v . referenced_by ) )
31+ )
32+ }
33+
34+ interface Realtime {
35+ subscribe : (
36+ event : 'created' | 'deleted' | 'updated' ,
37+ doctype : string ,
38+ handler : ( event : unknown ) => void
39+ ) => void
40+ unsubscribe : (
41+ event : 'created' | 'deleted' | 'updated' ,
42+ doctype : string ,
43+ handler : ( event : unknown ) => void
44+ ) => void
45+ }
46+
47+ function hasRealtimePlugin (
48+ plugins : unknown
49+ ) : plugins is { realtime : Realtime } {
50+ return (
51+ ! ! plugins &&
52+ typeof plugins === 'object' &&
53+ 'realtime' in ( plugins as Record < string , unknown > ) &&
54+ typeof ( plugins as { realtime ?: unknown } ) . realtime === 'object'
55+ )
56+ }
57+
1758export const SharedWorkerContext = React . createContext <
1859 DataProxyWorkerContext | undefined
1960> ( undefined )
@@ -41,13 +82,71 @@ export const SharedWorkerProvider = React.memo(
4182 const [ tabCount , setTabCount ] = useState ( 0 )
4283 const client = useClient ( )
4384
85+ useEffect ( ( ) => {
86+ if ( ! client ) return
87+
88+ if ( ! hasRealtimePlugin ( client . plugins ) ) {
89+ throw new Error (
90+ 'You must include the realtime plugin to use RealTimeQueries'
91+ )
92+ }
93+ const realtime = client . plugins . realtime
94+
95+ if ( ! realtime ) {
96+ throw new Error (
97+ 'You must include the realtime plugin to use RealTimeQueries'
98+ )
99+ }
100+
101+ const handleFileCreated = ( event : unknown ) : void => {
102+ if ( ! isFilesRealtimeEvent ( event ) ) return
103+ if (
104+ event . dir_id === 'io.cozy.files.shared-drives-dir' &&
105+ event . class === 'shortcut'
106+ ) {
107+ const driveId = event ?. referenced_by ?. [ 0 ] ?. id
108+ if ( driveId ) {
109+ log . info ( `Shared drive ${ driveId } created` )
110+ worker ?. addSharedDrive ( driveId )
111+ }
112+ }
113+ }
114+ const handleFileDeleted = ( event : unknown ) : void => {
115+ if ( ! isFilesRealtimeEvent ( event ) ) return
116+ if (
117+ event . dir_id === 'io.cozy.files.shared-drives-dir' &&
118+ event . class === 'shortcut'
119+ ) {
120+ const driveId = event ?. referenced_by ?. [ 0 ] ?. id
121+ if ( driveId ) {
122+ log . info ( `Shared drive ${ driveId } deleted` )
123+ worker ?. removeSharedDrive ( driveId )
124+ }
125+ }
126+ }
127+ realtime . subscribe ( 'created' , 'io.cozy.files' , handleFileCreated )
128+ realtime . subscribe ( 'deleted' , 'io.cozy.files' , handleFileDeleted )
129+ return ( ) : void => {
130+ realtime . unsubscribe ( 'created' , 'io.cozy.files' , handleFileCreated )
131+ realtime . unsubscribe ( 'deleted' , 'io.cozy.files' , handleFileDeleted )
132+ }
133+ } , [ client , worker ] )
134+
44135 useEffect ( ( ) => {
45136 if ( ! client ) return
46137
47138 const doAsync = async ( ) : Promise < void > => {
48139 // Cleanup any remaining local data
49140 await removeStaleLocalData ( )
50141
142+ const { data : sharedDrives } = await client
143+ . collection ( 'io.cozy.sharings' )
144+ . fetchSharedDrives ( )
145+
146+ const sharedDriveIds : string [ ] = sharedDrives . map (
147+ ( drive : { id : string } ) => drive . id
148+ )
149+
51150 log . debug ( 'Init SharedWorker' )
52151
53152 let obj : Comlink . Remote < DataProxyWorker >
@@ -78,14 +177,17 @@ export const SharedWorkerProvider = React.memo(
78177 log . debug ( 'Provide CozyClient data to Worker' )
79178 const { uri, token } = client . getStackClient ( )
80179
81- await obj . setup ( {
82- uri,
83- token : token . token ,
84- instanceOptions : client . instanceOptions ,
85- capabilities : client . capabilities ,
86- useRemoteData
87- } )
88- setWorker ( ( ) => obj )
180+ await obj . setup (
181+ {
182+ uri,
183+ token : token . token ,
184+ instanceOptions : client . instanceOptions ,
185+ capabilities : client . capabilities ,
186+ useRemoteData
187+ } ,
188+ { sharedDriveIds } as { sharedDriveIds : string [ ] }
189+ )
190+ setWorker ( ( ) : Comlink . Remote < DataProxyWorker > => obj )
89191 }
90192
91193 doAsync ( )
0 commit comments