1
1
import * as Comlink from 'comlink'
2
- import React , { useContext , useState , useEffect } from 'react'
2
+ import React , { useContext , useState , useEffect , useCallback } from 'react'
3
3
4
4
import { useClient } from 'cozy-client'
5
5
import { isFlagshipApp } from 'cozy-device-helper'
@@ -19,11 +19,12 @@ export const useDataProxy = () => {
19
19
return context
20
20
}
21
21
22
- export const DataProxyProvider = React . memo ( ( { children, options = { } } ) => {
22
+ export const DataProxyProvider = React . memo ( ( { children } ) => {
23
23
const client = useClient ( )
24
24
const webviewIntent = useWebviewIntent ( )
25
25
const [ iframeUrl , setIframeUrl ] = useState ( )
26
26
const [ dataProxy , setDataProxy ] = useState ( )
27
+ const [ value , setValue ] = useState ( )
27
28
const [ dataProxyServicesAvailable , setDataProxyServicesAvailable ] =
28
29
useState ( undefined )
29
30
@@ -111,27 +112,68 @@ export const DataProxyProvider = React.memo(({ children, options = {} }) => {
111
112
}
112
113
} , [ client , webviewIntent ] )
113
114
114
- const onIframeLoaded = ( ) => {
115
+ const onIframeLoaded = useCallback ( ( ) => {
115
116
const ifr = document . getElementById ( 'DataProxy' )
116
117
const remote = Comlink . wrap ( Comlink . windowEndpoint ( ifr . contentWindow ) )
117
118
setDataProxy ( ( ) => remote )
118
- }
119
+ } , [ setDataProxy ] )
119
120
120
- const search = async search => {
121
- log . log ( 'Send search query to DataProxy' )
122
- const result = await dataProxy . search ( search , options )
121
+ const onReceiveMessage = useCallback (
122
+ event => {
123
+ if ( ! event . origin . includes ( 'dataproxy' ) ) {
124
+ return
125
+ }
126
+ const eventData = event ?. data
127
+ if ( eventData && typeof eventData === 'object' ) {
128
+ if (
129
+ eventData . type === 'DATAPROXYMESSAGE' &&
130
+ eventData . payload === 'READY'
131
+ ) {
132
+ onIframeLoaded ( )
133
+ }
134
+ }
135
+ } ,
136
+ [ onIframeLoaded ]
137
+ )
123
138
124
- return result
125
- }
139
+ useEffect ( function ( ) {
140
+ window . addEventListener ( 'message' , onReceiveMessage )
141
+ return function ( ) {
142
+ window . removeEventListener ( 'message' , onReceiveMessage )
143
+ }
144
+ } )
126
145
127
- const value = {
128
- dataProxyServicesAvailable,
129
- search
130
- }
146
+ useEffect ( ( ) => {
147
+ const doAsync = async ( ) => {
148
+ // Make a global search
149
+ const search = async ( search , options ) => {
150
+ log . log ( 'Send search query to DataProxy' )
151
+ const result = await dataProxy . search ( search , options )
152
+ return result
153
+ }
154
+
155
+ const newValue = {
156
+ dataProxyServicesAvailable,
157
+ search
158
+ }
159
+
160
+ client . links . forEach ( link => {
161
+ if ( link . registerDataProxy ) {
162
+ // This is required as the DataProxy is not ready when the DataProxyLink is created
163
+ link . registerDataProxy ( newValue )
164
+ }
165
+ } )
166
+
167
+ setValue ( newValue )
168
+ }
169
+ if ( dataProxy && client ?. links ) {
170
+ doAsync ( )
171
+ }
172
+ } , [ dataProxy , client , dataProxyServicesAvailable ] )
131
173
132
174
return (
133
175
< DataProxyContext . Provider value = { value } >
134
- { children }
176
+ { value && children }
135
177
{ iframeUrl ? (
136
178
< iframe
137
179
id = "DataProxy"
@@ -143,7 +185,6 @@ export const DataProxyProvider = React.memo(({ children, options = {} }) => {
143
185
height : 0
144
186
} }
145
187
sandbox = "allow-same-origin allow-scripts"
146
- onLoad = { onIframeLoaded }
147
188
> </ iframe >
148
189
) : undefined }
149
190
</ DataProxyContext . Provider >
0 commit comments