({ logger = appLogger }: UseUrlLoaderDeps = {})
| 31 | * Hook for loading COLMAP reconstructions from URLs |
| 32 | */ |
| 33 | export function useUrlLoader({ logger = appLogger }: UseUrlLoaderDeps = {}) { |
| 34 | const { processFiles } = useFileDropzone(); |
| 35 | const logError = logger.error; |
| 36 | const logInfo = logger.info; |
| 37 | const setError = useReconstructionStore((s) => s.setError); |
| 38 | const setSourceInfo = useReconstructionStore((s) => s.setSourceInfo); |
| 39 | const mergeRemoteSplatCatalog = useReconstructionStore((s) => s.mergeRemoteSplatCatalog); |
| 40 | |
| 41 | // Use store state for URL loading (shared across components) |
| 42 | const urlLoading = useReconstructionStore((s) => s.urlLoading); |
| 43 | const urlProgress = useReconstructionStore((s) => s.urlProgress); |
| 44 | const urlError = useReconstructionStore((s) => s.urlError); |
| 45 | const setUrlLoading = useReconstructionStore((s) => s.setUrlLoading); |
| 46 | const setUrlProgress = useReconstructionStore((s) => s.setUrlProgress); |
| 47 | const setUrlError = useReconstructionStore((s) => s.setUrlError); |
| 48 | const tryStartUrlLoad = useReconstructionStore((s) => s.tryStartUrlLoad); |
| 49 | const finishUrlLoad = useReconstructionStore((s) => s.finishUrlLoad); |
| 50 | const shouldKeepUrlLoadingForSplatRenderer = useCallback(() => { |
| 51 | const state = useReconstructionStore.getState(); |
| 52 | return isSplatLoadingProgressForFile(state.urlProgress, state.loadedFiles?.splatFile); |
| 53 | }, []); |
| 54 | |
| 55 | /** |
| 56 | * Fetch and validate the manifest file |
| 57 | */ |
| 58 | const fetchManifest = useCallback(async (manifestUrl: string): Promise<ColmapManifest> => { |
| 59 | return fetchUrlManifest(manifestUrl, { setUrlProgress }); |
| 60 | }, [setUrlProgress]); |
| 61 | |
| 62 | /** |
| 63 | * Load reconstruction from a ZIP URL. |
| 64 | * Downloads the ZIP, extracts COLMAP files, and sets up lazy image extraction. |
| 65 | * Note: Caller (loadFromUrl) is responsible for clearing caches before calling this. |
| 66 | */ |
| 67 | const loadFromZipUrl = useCallback(async (url: string): Promise<boolean> => { |
| 68 | return loadZipUrlSource(url, { |
| 69 | log: logInfo, |
| 70 | processFiles, |
| 71 | setSourceInfo, |
| 72 | setUrlProgress, |
| 73 | }); |
| 74 | }, [logInfo, processFiles, setSourceInfo, setUrlProgress]); |
| 75 | |
| 76 | const loadFromSplatUrl = useCallback(async ( |
| 77 | url: string, |
| 78 | options: { onSplatFileFetched?: (file: File) => void } = {} |
| 79 | ): Promise<boolean> => { |
| 80 | return loadSplatUrlSource(url, { |
| 81 | log: logInfo, |
| 82 | onSplatFileFetched: options.onSplatFileFetched, |
| 83 | processFiles, |
| 84 | setSourceInfo, |
| 85 | setUrlProgress, |
| 86 | }); |
| 87 | }, [logInfo, processFiles, setSourceInfo, setUrlProgress]); |
| 88 | |
| 89 | /** |
| 90 | * Main entry point: load reconstruction from URL |
no test coverage detected