@@ -63,6 +63,15 @@ const arraysEqual = (a: Uint8Array, b: Uint8Array) => {
6363const FMComponent : React . FC < FMProps & JSX . IntrinsicElements [ "div" ] > = ( { wsUrl, ...props } ) => {
6464 const { t } = useTranslation ( ) ;
6565 const fmRef = useRef < HTMLDivElement > ( null ) ;
66+ const wsRef = useRef < WebSocket | null > ( null ) ;
67+
68+ useEffect ( ( ) => {
69+ return ( ) => {
70+ if ( wsRef . current ) {
71+ wsRef . current . close ( ) ;
72+ }
73+ } ;
74+ } , [ ] ) ;
6675
6776 const [ dOpen , setdOpen ] = useState ( false ) ;
6877 const [ uOpen , setuOpen ] = useState ( false ) ;
@@ -146,99 +155,104 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
146155
147156 worker . onmessage = async ( event : MessageEvent < FMWorkerData > ) => {
148157 switch ( event . data . type ) {
149- case FMWorkerOpcode . Error : {
150- console . error ( 'Error from worker' , event . data . error ) ;
151- break ;
152- }
153- case FMWorkerOpcode . Progress : {
154- handleReady . current = true ;
155- break ;
156- }
157- case FMWorkerOpcode . Result : {
158- handleReady . current = false ;
159-
160- if ( event . data . blob && event . data . fileName ) {
161- const url = URL . createObjectURL ( event . data . blob ) ;
162- const anchor = document . createElement ( 'a' ) ;
163- anchor . href = url ;
164- anchor . download = event . data . fileName ;
165- anchor . click ( ) ;
166- URL . revokeObjectURL ( url ) ;
158+ case FMWorkerOpcode . Error : {
159+ console . error ( 'Error from worker' , event . data . error ) ;
160+ break ;
161+ }
162+ case FMWorkerOpcode . Progress : {
163+ handleReady . current = true ;
164+ break ;
167165 }
166+ case FMWorkerOpcode . Result : {
167+ handleReady . current = false ;
168+
169+ if ( event . data . blob && event . data . fileName ) {
170+ const url = URL . createObjectURL ( event . data . blob ) ;
171+ const anchor = document . createElement ( 'a' ) ;
172+ anchor . href = url ;
173+ anchor . download = event . data . fileName ;
174+ anchor . click ( ) ;
175+ URL . revokeObjectURL ( url ) ;
176+ }
168177
169- firstChunk . current = true ;
170- if ( dOpen ) setdOpen ( false ) ;
171- break ;
172- }
178+ firstChunk . current = true ;
179+ if ( dOpen ) setdOpen ( false ) ;
180+ break ;
181+ }
173182 }
174183 }
175184
176185 const [ currentPath , setPath ] = useState ( '' ) ;
177186 useEffect ( ( ) => {
178- listFile ( ) ;
179- } , [ currentPath ] )
187+ if ( wsRef . current && wsRef . current . readyState === WebSocket . OPEN ) {
188+ listFile ( ) ;
189+ }
190+ } , [ wsRef . current , currentPath ] )
180191
181- const ws = new WebSocket ( wsUrl ) ;
182- ws . binaryType = 'arraybuffer' ;
183- ws . onopen = ( ) => {
184- listFile ( ) ;
185- }
186- ws . onclose = ( e ) => {
187- console . log ( 'WebSocket connection closed:' , e ) ;
188- }
189- ws . onerror = ( e ) => {
190- console . error ( e ) ;
191- toast ( "Websocket" + " " + t ( "Error" ) , {
192- description : t ( "Results.UnExpectedError" ) ,
193- } )
194- }
195- ws . onmessage = async ( e ) => {
196- try {
197- const buf : ArrayBufferLike = e . data ;
198-
199- if ( firstChunk . current ) {
200- const identifier = new Uint8Array ( buf , 0 , 4 ) ;
201- if ( arraysEqual ( identifier , FMIdentifier . file ) ) {
202- worker . postMessage ( { operation : 1 , arrayBuffer : buf , fileName : currentBasename . current } ) ;
203- firstChunk . current = false ;
204- } else if ( arraysEqual ( identifier , FMIdentifier . fileName ) ) {
205- const { path, fmList } = await fm . parseFMList ( buf ) ;
206- setPath ( path ) ;
207- setFMEntries ( fmList ) ;
208- } else if ( arraysEqual ( identifier , FMIdentifier . error ) ) {
209- const errBytes = buf . slice ( 4 ) ;
210- const errMsg = new TextDecoder ( 'utf-8' ) . decode ( errBytes ) ;
211- throw new Error ( errMsg ) ;
212- } else if ( arraysEqual ( identifier , FMIdentifier . complete ) ) {
213- // Upload completed
214- if ( uOpen ) setuOpen ( false ) ;
215- listFile ( ) ;
192+ useEffect ( ( ) => {
193+ const ws = new WebSocket ( wsUrl ) ;
194+ wsRef . current = ws ;
195+ ws . binaryType = 'arraybuffer' ;
196+ ws . onopen = ( ) => {
197+ listFile ( ) ;
198+ }
199+ ws . onclose = ( e ) => {
200+ console . log ( 'WebSocket connection closed:' , e ) ;
201+ }
202+ ws . onerror = ( e ) => {
203+ console . error ( e ) ;
204+ toast ( "Websocket" + " " + t ( "Error" ) , {
205+ description : t ( "Results.UnExpectedError" ) ,
206+ } )
207+ }
208+ ws . onmessage = async ( e ) => {
209+ try {
210+ const buf : ArrayBufferLike = e . data ;
211+
212+ if ( firstChunk . current ) {
213+ const identifier = new Uint8Array ( buf , 0 , 4 ) ;
214+ if ( arraysEqual ( identifier , FMIdentifier . file ) ) {
215+ worker . postMessage ( { operation : 1 , arrayBuffer : buf , fileName : currentBasename . current } ) ;
216+ firstChunk . current = false ;
217+ } else if ( arraysEqual ( identifier , FMIdentifier . fileName ) ) {
218+ const { path, fmList } = await fm . parseFMList ( buf ) ;
219+ setPath ( path ) ;
220+ setFMEntries ( fmList ) ;
221+ } else if ( arraysEqual ( identifier , FMIdentifier . error ) ) {
222+ const errBytes = buf . slice ( 4 ) ;
223+ const errMsg = new TextDecoder ( 'utf-8' ) . decode ( errBytes ) ;
224+ throw new Error ( errMsg ) ;
225+ } else if ( arraysEqual ( identifier , FMIdentifier . complete ) ) {
226+ // Upload completed
227+ if ( uOpen ) setuOpen ( false ) ;
228+ listFile ( ) ;
229+ } else {
230+ throw new Error ( t ( "Results.UnknownIdentifier" ) ) ;
231+ }
216232 } else {
217- throw new Error ( t ( "Results.UnknownIdentifier" ) ) ;
233+ await waitForHandleReady ( ) ;
234+ worker . postMessage ( { operation : 2 , arrayBuffer : buf , fileName : currentBasename . current } ) ;
218235 }
219- } else {
220- await waitForHandleReady ( ) ;
221- worker . postMessage ( { operation : 2 , arrayBuffer : buf , fileName : currentBasename . current } ) ;
236+ } catch ( error ) {
237+ console . error ( 'Error processing received data:' , error ) ;
238+ toast ( "FM" + " " + t ( "Error" ) , {
239+ description : t ( "Results.UnExpectedError" ) ,
240+ } )
241+ if ( dOpen ) setdOpen ( false ) ;
242+ if ( uOpen ) setuOpen ( false ) ;
222243 }
223- } catch ( error ) {
224- console . error ( 'Error processing received data:' , error ) ;
225- toast ( "FM" + " " + t ( "Error" ) , {
226- description : t ( "Results.UnExpectedError" ) ,
227- } )
228- if ( dOpen ) setdOpen ( false ) ;
229- if ( uOpen ) setuOpen ( false ) ;
230244 }
231- }
245+ } , [ wsUrl ] )
232246
233- const listFile = ( ) => {
247+ let listFile = ( ) => {
234248 const prefix = new Int8Array ( [ FMOpcode . List ] ) ;
235249 const pathMsg = new TextEncoder ( ) . encode ( currentPath ) ;
236250
237251 const msg = new Int8Array ( prefix . length + pathMsg . length ) ;
238252 msg . set ( prefix ) ;
239253 msg . set ( pathMsg , prefix . length ) ;
240254
241- ws . send ( msg ) ;
255+ wsRef . current ? .send ( msg ) ;
242256 }
243257
244258 const downloadFile = ( basename : string ) => {
@@ -250,7 +264,7 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
250264 msg . set ( prefix ) ;
251265 msg . set ( filePathMessage , prefix . length ) ;
252266
253- ws . send ( msg ) ;
267+ wsRef . current ? .send ( msg ) ;
254268 }
255269
256270 const uploadFile = async ( file : File ) => {
@@ -259,13 +273,13 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
259273
260274 // Send header
261275 const header = fm . buildUploadHeader ( { path : currentPath , file : file } ) ;
262- ws . send ( header ) ;
276+ wsRef . current ? .send ( header ) ;
263277
264278 // Send data chunks
265279 while ( offset < file . size ) {
266280 const chunk = file . slice ( offset , offset + chunkSize ) ;
267281 const arrayBuffer = await fm . readFileAsArrayBuffer ( chunk ) ;
268- if ( arrayBuffer ) ws . send ( arrayBuffer ) ;
282+ if ( arrayBuffer ) wsRef . current ? .send ( arrayBuffer ) ;
269283 offset += chunkSize ;
270284 }
271285 }
0 commit comments