1- import { useEffect , useRef , useState } from 'react'
1+ import { useCallback , useEffect , useRef , useState } from 'react'
22import { toast } from '@sim/emcn'
33import { getErrorMessage } from '@sim/utils/errors'
44import { useLimitUpgradeToast } from '@/lib/billing/client'
@@ -15,7 +15,7 @@ interface UploadProgress {
1515
1616/** Captures the upload destination for a batch and retires it when its owner view unmounts. */
1717export function useProjectFileUpload ( projectId : string , canWrite : boolean ) {
18- const mutation = useUploadProjectFile ( )
18+ const { mutateAsync } = useUploadProjectFile ( )
1919 const notifyLimit = useLimitUpgradeToast ( )
2020 const active = useRef < AbortController | null > ( null )
2121 const canWriteRef = useRef ( canWrite )
@@ -34,53 +34,56 @@ export function useProjectFileUpload(projectId: string, canWrite: boolean) {
3434 if ( ! canWrite ) active . current ?. abort ( )
3535 } , [ canWrite ] )
3636
37- async function uploadFiles ( files : File [ ] , folderId : string | null ) {
38- if ( ! canWriteRef . current || active . current || files . length === 0 ) return
39- const allowed : File [ ] = [ ]
40- for ( const file of files ) {
41- if ( file . size > MAX_WORKSPACE_FILE_SIZE ) {
42- toast . error ( `${ file . name } exceeds the 5 GiB upload limit` )
43- } else if ( ! isSupportedFileUpload ( file . name ) ) {
44- toast . error ( `Unsupported file type: ${ file . name } ` )
45- } else {
46- allowed . push ( file )
47- }
48- }
49- if ( allowed . length === 0 ) return
50- const controller = new AbortController ( )
51- active . current = controller
52- const updateProgress = ( completed : number , currentPercent : number ) => {
53- if ( active . current === controller && ! controller . signal . aborted ) {
54- setProgress ( { completed, currentPercent, total : allowed . length , folderId } )
37+ const uploadFiles = useCallback (
38+ async ( files : File [ ] , folderId : string | null ) => {
39+ if ( ! canWriteRef . current || active . current || files . length === 0 ) return
40+ const allowed : File [ ] = [ ]
41+ for ( const file of files ) {
42+ if ( file . size > MAX_WORKSPACE_FILE_SIZE ) {
43+ toast . error ( `${ file . name } exceeds the 5 GiB upload limit` )
44+ } else if ( ! isSupportedFileUpload ( file . name ) ) {
45+ toast . error ( `Unsupported file type: ${ file . name } ` )
46+ } else {
47+ allowed . push ( file )
48+ }
5549 }
56- }
57- updateProgress ( 0 , 0 )
58- try {
59- for ( const [ index , file ] of allowed . entries ( ) ) {
60- if ( controller . signal . aborted || ! canWriteRef . current ) break
61- try {
62- await mutation . mutateAsync ( {
63- projectId,
64- folderId,
65- file,
66- signal : controller . signal ,
67- onProgress : ( { percent } ) => updateProgress ( index , percent ) ,
68- } )
69- } catch ( error ) {
70- if ( controller . signal . aborted ) break
71- const message = getErrorMessage ( error , `Unable to upload ${ file . name } ` )
72- if ( / s t o r a g e l i m i t / i. test ( message ) ) notifyLimit ( 'storage' , message )
73- else toast . error ( message )
50+ if ( allowed . length === 0 ) return
51+ const controller = new AbortController ( )
52+ active . current = controller
53+ const updateProgress = ( completed : number , currentPercent : number ) => {
54+ if ( active . current === controller && ! controller . signal . aborted ) {
55+ setProgress ( { completed, currentPercent, total : allowed . length , folderId } )
7456 }
75- updateProgress ( index + 1 , 0 )
7657 }
77- } finally {
78- if ( active . current === controller ) {
79- active . current = null
80- setProgress ( null )
58+ updateProgress ( 0 , 0 )
59+ try {
60+ for ( const [ index , file ] of allowed . entries ( ) ) {
61+ if ( controller . signal . aborted || ! canWriteRef . current ) break
62+ try {
63+ await mutateAsync ( {
64+ projectId,
65+ folderId,
66+ file,
67+ signal : controller . signal ,
68+ onProgress : ( { percent } ) => updateProgress ( index , percent ) ,
69+ } )
70+ } catch ( error ) {
71+ if ( controller . signal . aborted ) break
72+ const message = getErrorMessage ( error , `Unable to upload ${ file . name } ` )
73+ if ( / s t o r a g e l i m i t / i. test ( message ) ) notifyLimit ( 'storage' , message )
74+ else toast . error ( message )
75+ }
76+ updateProgress ( index + 1 , 0 )
77+ }
78+ } finally {
79+ if ( active . current === controller ) {
80+ active . current = null
81+ setProgress ( null )
82+ }
8183 }
82- }
83- }
84+ } ,
85+ [ projectId , mutateAsync , notifyLimit ]
86+ )
8487
8588 const label = progress
8689 ? `${ progress . completed } /${ progress . total } ${ progress . currentPercent > 0 && progress . currentPercent < 100 ? ` · ${ progress . currentPercent } %` : '' } `
0 commit comments