import { useSignal } from '@preact/signals'; import { Directory, DirectoryFile } from '/lib/types.ts'; import { ResponseBody as UploadResponseBody } from '/routes/api/files/upload.tsx'; import { RequestBody as CreateDirectoryRequestBody, ResponseBody as CreateDirectoryResponseBody, } from '/routes/api/files/create-directory.tsx'; import CreateDirectoryModal from '/components/files/CreateDirectoryModal.tsx'; import ListFiles from '/components/files/ListFiles.tsx'; import FilesBreadcrumb from '/components/files/FilesBreadcrumb.tsx'; import ListPhotos from '/components/photos/ListPhotos.tsx'; interface MainPhotosProps { initialDirectories: Directory[]; initialFiles: DirectoryFile[]; initialPath: string; } export default function MainPhotos({ initialDirectories, initialFiles, initialPath }: MainPhotosProps) { const isAdding = useSignal(false); const isUploading = useSignal(false); const directories = useSignal(initialDirectories); const files = useSignal(initialFiles); const path = useSignal(initialPath); const areNewOptionsOption = useSignal(false); const isNewDirectoryModalOpen = useSignal(false); function onClickUploadFile() { const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.multiple = true; fileInput.accept = 'image/*,video/*'; fileInput.click(); fileInput.onchange = async (event) => { const chosenFilesList = (event.target as HTMLInputElement)?.files!; const chosenFiles = Array.from(chosenFilesList); isUploading.value = true; for (const chosenFile of chosenFiles) { if (!chosenFile) { continue; } areNewOptionsOption.value = false; const requestBody = new FormData(); requestBody.set('parent_path', path.value); requestBody.set('path_in_view', path.value); requestBody.set('name', chosenFile.name); requestBody.set('contents', chosenFile); try { const response = await fetch(`/api/files/upload`, { method: 'POST', body: requestBody, }); if (!response.ok) { throw new Error(`Failed to upload photo. ${response.statusText} ${await response.text()}`); } const result = await response.json() as UploadResponseBody; if (!result.success) { throw new Error('Failed to upload photo!'); } files.value = [...result.newFiles]; } catch (error) { console.error(error); } } isUploading.value = false; }; } function onClickCreateDirectory() { if (isNewDirectoryModalOpen.value) { isNewDirectoryModalOpen.value = false; return; } isNewDirectoryModalOpen.value = true; } async function onClickSaveDirectory(newDirectoryName: string) { if (isAdding.value) { return; } if (!newDirectoryName) { return; } areNewOptionsOption.value = false; isAdding.value = true; try { const requestBody: CreateDirectoryRequestBody = { parentPath: path.value, name: newDirectoryName, }; const response = await fetch(`/api/files/create-directory`, { method: 'POST', body: JSON.stringify(requestBody), }); if (!response.ok) { throw new Error(`Failed to create directory. ${response.statusText} ${await response.text()}`); } const result = await response.json() as CreateDirectoryResponseBody; if (!result.success) { throw new Error('Failed to create directory!'); } directories.value = [...result.newDirectories]; isNewDirectoryModalOpen.value = false; } catch (error) { console.error(error); } isAdding.value = false; } function onCloseCreateDirectory() { isNewDirectoryModalOpen.value = false; } function toggleNewOptionsDropdown() { areNewOptionsOption.value = !areNewOptionsOption.value; } return ( <>
{isAdding.value ? ( <> Creating... ) : null} {isUploading.value ? ( <> Uploading... ) : null} {!isAdding.value && !isUploading.value ? <>  : null}
); }