50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useCallback } from 'react'
|
|
import type { FolderEntry } from '@/lib/client-types'
|
|
|
|
function revokeEntryUrls(entry: FolderEntry) {
|
|
const urls = new Set<string>()
|
|
if (entry.modelUrl) urls.add(entry.modelUrl)
|
|
Object.values(entry.assetUrls || {}).forEach((url) => urls.add(url))
|
|
urls.forEach((url) => URL.revokeObjectURL(url))
|
|
}
|
|
|
|
export function useFolderEntries() {
|
|
const [entries, setEntries] = useState<FolderEntry[]>([])
|
|
|
|
const updateEntry = useCallback((index: number, patch: Partial<FolderEntry>) => {
|
|
setEntries((prev) => prev.map((f, i) => (i === index ? { ...f, ...patch } : f)))
|
|
}, [])
|
|
|
|
const removeEntry = useCallback((index: number) => {
|
|
setEntries((prev) => {
|
|
const entry = prev[index]
|
|
if (entry) revokeEntryUrls(entry)
|
|
return prev.filter((_, i) => i !== index)
|
|
})
|
|
}, [])
|
|
|
|
const resetEntries = useCallback(() => {
|
|
setEntries((prev) => {
|
|
prev.forEach((f) => {
|
|
revokeEntryUrls(f)
|
|
})
|
|
return []
|
|
})
|
|
}, [])
|
|
|
|
const allDone = entries.length > 0 && entries.every((f) => f.status === 'success')
|
|
const hasErrors = entries.some((f) => f.status === 'error')
|
|
|
|
return {
|
|
entries,
|
|
setEntries,
|
|
updateEntry,
|
|
removeEntry,
|
|
resetEntries,
|
|
allDone,
|
|
hasErrors,
|
|
}
|
|
}
|