Cleanup
This commit is contained in:
parent
d69ff79a67
commit
bedb515dc2
4 changed files with 198 additions and 174 deletions
|
@ -1,9 +1,24 @@
|
|||
export default function UploadSelectorInputs({
|
||||
type GetInputProps = () => React.HTMLAttributes<HTMLInputElement>;
|
||||
|
||||
interface UploadSelectorInputsProps {
|
||||
getDragAndDropInputProps: GetInputProps;
|
||||
getFileSelectorInputProps: GetInputProps;
|
||||
getFolderSelectorInputProps: GetInputProps;
|
||||
getZipFileSelectorInputProps?: GetInputProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a bunch of HTML inputs elements, one each for the given props.
|
||||
*
|
||||
* These hidden input element serve as the way for us to show various file /
|
||||
* folder Selector dialogs and handle drag and drop inputs.
|
||||
*/
|
||||
export const UploadSelectorInputs: React.FC<UploadSelectorInputsProps> = ({
|
||||
getDragAndDropInputProps,
|
||||
getFileSelectorInputProps,
|
||||
getFolderSelectorInputProps,
|
||||
getZipFileSelectorInputProps,
|
||||
}) {
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<input {...getDragAndDropInputProps()} />
|
||||
|
@ -14,4 +29,4 @@ export default function UploadSelectorInputs({
|
|||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,82 +1,36 @@
|
|||
import {
|
||||
SESSION_KEYS,
|
||||
clearKeys,
|
||||
getKey,
|
||||
} from "@ente/shared/storage/sessionStorage";
|
||||
import { Typography, styled } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import {
|
||||
constructEmailList,
|
||||
createAlbum,
|
||||
getAllLatestCollections,
|
||||
getAllLocalCollections,
|
||||
getCollectionSummaries,
|
||||
getFavItemIds,
|
||||
getHiddenItemsSummary,
|
||||
getSectionSummaries,
|
||||
} from "services/collectionService";
|
||||
import { getLocalFiles, syncFiles } from "services/fileService";
|
||||
|
||||
import { checkSubscriptionPurchase } from "utils/billing";
|
||||
|
||||
import log from "@/next/log";
|
||||
import { APPS } from "@ente/shared/apps/constants";
|
||||
import { CenteredFlex } from "@ente/shared/components/Container";
|
||||
import EnteSpinner from "@ente/shared/components/EnteSpinner";
|
||||
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
|
||||
import { CustomError } from "@ente/shared/error";
|
||||
import { useFileInput } from "@ente/shared/hooks/useFileInput";
|
||||
import useMemoSingleThreaded from "@ente/shared/hooks/useMemoSingleThreaded";
|
||||
import InMemoryStore, { MS_KEYS } from "@ente/shared/storage/InMemoryStore";
|
||||
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
|
||||
import {
|
||||
getToken,
|
||||
isFirstLogin,
|
||||
justSignedUp,
|
||||
setIsFirstLogin,
|
||||
setJustSignedUp,
|
||||
} from "@ente/shared/storage/localStorage/helpers";
|
||||
import CollectionSelector, {
|
||||
CollectionSelectorAttributes,
|
||||
} from "components/Collections/CollectionSelector";
|
||||
import FullScreenDropZone from "components/FullScreenDropZone";
|
||||
import { LoadingOverlay } from "components/LoadingOverlay";
|
||||
import PhotoFrame from "components/PhotoFrame";
|
||||
import Sidebar from "components/Sidebar";
|
||||
import SelectedFileOptions from "components/pages/gallery/SelectedFileOptions";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import {
|
||||
isTokenValid,
|
||||
syncMapEnabled,
|
||||
validateKey,
|
||||
} from "services/userService";
|
||||
import { preloadImage } from "utils/common";
|
||||
import {
|
||||
FILE_OPS_TYPE,
|
||||
constructFileToCollectionMap,
|
||||
getSelectedFiles,
|
||||
getUniqueFiles,
|
||||
handleFileOps,
|
||||
mergeMetadata,
|
||||
sortFiles,
|
||||
} from "utils/file";
|
||||
|
||||
import log from "@/next/log";
|
||||
import { APPS } from "@ente/shared/apps/constants";
|
||||
import { CenteredFlex } from "@ente/shared/components/Container";
|
||||
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
|
||||
import { CustomError } from "@ente/shared/error";
|
||||
import useFileInput from "@ente/shared/hooks/useFileInput";
|
||||
import useMemoSingleThreaded from "@ente/shared/hooks/useMemoSingleThreaded";
|
||||
import InMemoryStore, { MS_KEYS } from "@ente/shared/storage/InMemoryStore";
|
||||
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
|
||||
import { getToken } from "@ente/shared/storage/localStorage/helpers";
|
||||
SESSION_KEYS,
|
||||
clearKeys,
|
||||
getKey,
|
||||
} from "@ente/shared/storage/sessionStorage";
|
||||
import { User } from "@ente/shared/user/types";
|
||||
import { isPromise } from "@ente/shared/utils";
|
||||
import { Typography, styled } from "@mui/material";
|
||||
import AuthenticateUserModal from "components/AuthenticateUserModal";
|
||||
import Collections from "components/Collections";
|
||||
import CollectionNamer, {
|
||||
CollectionNamerAttributes,
|
||||
} from "components/Collections/CollectionNamer";
|
||||
import CollectionSelector, {
|
||||
CollectionSelectorAttributes,
|
||||
} from "components/Collections/CollectionSelector";
|
||||
import ExportModal from "components/ExportModal";
|
||||
import {
|
||||
FilesDownloadProgress,
|
||||
|
@ -85,13 +39,18 @@ import {
|
|||
import FixCreationTime, {
|
||||
FixCreationTimeAttributes,
|
||||
} from "components/FixCreationTime";
|
||||
import FullScreenDropZone from "components/FullScreenDropZone";
|
||||
import GalleryEmptyState from "components/GalleryEmptyState";
|
||||
import { LoadingOverlay } from "components/LoadingOverlay";
|
||||
import PhotoFrame from "components/PhotoFrame";
|
||||
import { ITEM_TYPE, TimeStampListItem } from "components/PhotoList";
|
||||
import SearchResultInfo from "components/Search/SearchResultInfo";
|
||||
import Sidebar from "components/Sidebar";
|
||||
import Uploader from "components/Upload/Uploader";
|
||||
import UploadInputs from "components/UploadSelectorInputs";
|
||||
import { UploadSelectorInputs } from "components/UploadSelectorInputs";
|
||||
import { GalleryNavbar } from "components/pages/gallery/Navbar";
|
||||
import PlanSelector from "components/pages/gallery/PlanSelector";
|
||||
import SelectedFileOptions from "components/pages/gallery/SelectedFileOptions";
|
||||
import {
|
||||
ALL_SECTION,
|
||||
ARCHIVE_SECTION,
|
||||
|
@ -100,15 +59,42 @@ import {
|
|||
TRASH_SECTION,
|
||||
} from "constants/collection";
|
||||
import { SYNC_INTERVAL_IN_MICROSECONDS } from "constants/gallery";
|
||||
import { t } from "i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { AppContext } from "pages/_app";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { clipService } from "services/clip-service";
|
||||
import { constructUserIDToEmailMap } from "services/collectionService";
|
||||
import {
|
||||
constructEmailList,
|
||||
constructUserIDToEmailMap,
|
||||
createAlbum,
|
||||
getAllLatestCollections,
|
||||
getAllLocalCollections,
|
||||
getCollectionSummaries,
|
||||
getFavItemIds,
|
||||
getHiddenItemsSummary,
|
||||
getSectionSummaries,
|
||||
} from "services/collectionService";
|
||||
import downloadManager from "services/download";
|
||||
import { syncEmbeddings, syncFileEmbeddings } from "services/embeddingService";
|
||||
import { syncEntities } from "services/entityService";
|
||||
import { getLocalFiles, syncFiles } from "services/fileService";
|
||||
import locationSearchService from "services/locationSearchService";
|
||||
import { getLocalTrashedFiles, syncTrash } from "services/trashService";
|
||||
import uploadManager from "services/upload/uploadManager";
|
||||
import {
|
||||
isTokenValid,
|
||||
syncMapEnabled,
|
||||
validateKey,
|
||||
} from "services/userService";
|
||||
import { Collection, CollectionSummaries } from "types/collection";
|
||||
import { EnteFile } from "types/file";
|
||||
import {
|
||||
|
@ -120,6 +106,7 @@ import {
|
|||
} from "types/gallery";
|
||||
import { Search, SearchResultSummary, UpdateSearch } from "types/search";
|
||||
import { FamilyData } from "types/user";
|
||||
import { checkSubscriptionPurchase } from "utils/billing";
|
||||
import {
|
||||
COLLECTION_OPS_TYPE,
|
||||
constructCollectionNameMap,
|
||||
|
@ -131,6 +118,16 @@ import {
|
|||
splitNormalAndHiddenCollections,
|
||||
} from "utils/collection";
|
||||
import ComlinkSearchWorker from "utils/comlink/ComlinkSearchWorker";
|
||||
import { preloadImage } from "utils/common";
|
||||
import {
|
||||
FILE_OPS_TYPE,
|
||||
constructFileToCollectionMap,
|
||||
getSelectedFiles,
|
||||
getUniqueFiles,
|
||||
handleFileOps,
|
||||
mergeMetadata,
|
||||
sortFiles,
|
||||
} from "utils/file";
|
||||
import { isArchivedFile } from "utils/magicMetadata";
|
||||
import { getSessionExpiredMessage } from "utils/ui";
|
||||
import { getLocalFamilyData } from "utils/user/family";
|
||||
|
@ -201,8 +198,11 @@ export default function Gallery() {
|
|||
const [isPhotoSwipeOpen, setIsPhotoSwipeOpen] = useState(false);
|
||||
|
||||
const {
|
||||
// A function to call to get the props we should apply to the container,
|
||||
getRootProps: getDragAndDropRootProps,
|
||||
// ... the props we should apply to the <input> element,
|
||||
getInputProps: getDragAndDropInputProps,
|
||||
// ... and the files that we got.
|
||||
acceptedFiles: dragAndDropFiles,
|
||||
} = useDropzone({
|
||||
noClick: true,
|
||||
|
@ -210,23 +210,23 @@ export default function Gallery() {
|
|||
disabled: shouldDisableDropzone,
|
||||
});
|
||||
const {
|
||||
selectedFiles: fileSelectorFiles,
|
||||
open: openFileSelector,
|
||||
getInputProps: getFileSelectorInputProps,
|
||||
openSelector: openFileSelector,
|
||||
selectedFiles: fileSelectorFiles,
|
||||
} = useFileInput({
|
||||
directory: false,
|
||||
});
|
||||
const {
|
||||
selectedFiles: folderSelectorFiles,
|
||||
open: openFolderSelector,
|
||||
getInputProps: getFolderSelectorInputProps,
|
||||
openSelector: openFolderSelector,
|
||||
selectedFiles: folderSelectorFiles,
|
||||
} = useFileInput({
|
||||
directory: true,
|
||||
});
|
||||
const {
|
||||
selectedFiles: fileSelectorZipFiles,
|
||||
open: openZipFileSelector,
|
||||
getInputProps: getZipFileSelectorInputProps,
|
||||
openSelector: openZipFileSelector,
|
||||
selectedFiles: fileSelectorZipFiles,
|
||||
} = useFileInput({
|
||||
directory: false,
|
||||
accept: ".zip",
|
||||
|
@ -1013,14 +1013,14 @@ export default function Gallery() {
|
|||
setSelectedFiles: setSelected,
|
||||
}}
|
||||
>
|
||||
<FullScreenDropZone
|
||||
getDragAndDropRootProps={getDragAndDropRootProps}
|
||||
>
|
||||
<UploadInputs
|
||||
getDragAndDropInputProps={getDragAndDropInputProps}
|
||||
getFileSelectorInputProps={getFileSelectorInputProps}
|
||||
getFolderSelectorInputProps={getFolderSelectorInputProps}
|
||||
getZipFileSelectorInputProps={getZipFileSelectorInputProps}
|
||||
<FullScreenDropZone {...{ getDragAndDropRootProps }}>
|
||||
<UploadSelectorInputs
|
||||
{...{
|
||||
getDragAndDropInputProps,
|
||||
getFileSelectorInputProps,
|
||||
getFolderSelectorInputProps,
|
||||
getZipFileSelectorInputProps,
|
||||
}}
|
||||
/>
|
||||
{blockingLoad && (
|
||||
<LoadingOverlay>
|
||||
|
|
|
@ -1,15 +1,51 @@
|
|||
import log from "@/next/log";
|
||||
import { logoutUser } from "@ente/accounts/services/user";
|
||||
import { APPS } from "@ente/shared/apps/constants";
|
||||
import {
|
||||
CenteredFlex,
|
||||
SpaceBetweenFlex,
|
||||
VerticallyCentered,
|
||||
} from "@ente/shared/components/Container";
|
||||
import EnteSpinner from "@ente/shared/components/EnteSpinner";
|
||||
import FormPaper from "@ente/shared/components/Form/FormPaper";
|
||||
import FormPaperTitle from "@ente/shared/components/Form/FormPaper/Title";
|
||||
import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
|
||||
import { OverflowMenuOption } from "@ente/shared/components/OverflowMenu/option";
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
|
||||
import { ENTE_WEBSITE_LINK } from "@ente/shared/constants/urls";
|
||||
import ComlinkCryptoWorker from "@ente/shared/crypto";
|
||||
import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
|
||||
import { useFileInput } from "@ente/shared/hooks/useFileInput";
|
||||
import AddPhotoAlternateOutlined from "@mui/icons-material/AddPhotoAlternateOutlined";
|
||||
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
|
||||
import MoreHoriz from "@mui/icons-material/MoreHoriz";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import bs58 from "bs58";
|
||||
import { CollectionInfo } from "components/Collections/CollectionInfo";
|
||||
import { CollectionInfoBarWrapper } from "components/Collections/styledComponents";
|
||||
import {
|
||||
FilesDownloadProgress,
|
||||
FilesDownloadProgressAttributes,
|
||||
} from "components/FilesDownloadProgress";
|
||||
import FullScreenDropZone from "components/FullScreenDropZone";
|
||||
import { LoadingOverlay } from "components/LoadingOverlay";
|
||||
import PhotoFrame from "components/PhotoFrame";
|
||||
import { ITEM_TYPE, TimeStampListItem } from "components/PhotoList";
|
||||
import UploadButton from "components/Upload/UploadButton";
|
||||
import Uploader from "components/Upload/Uploader";
|
||||
import { UploadSelectorInputs } from "components/UploadSelectorInputs";
|
||||
import SharedAlbumNavbar from "components/pages/sharedAlbum/Navbar";
|
||||
import SelectedFileOptions from "components/pages/sharedAlbum/SelectedFileOptions";
|
||||
import { ALL_SECTION } from "constants/collection";
|
||||
import { t } from "i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { AppContext } from "pages/_app";
|
||||
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import downloadManager from "services/download";
|
||||
import {
|
||||
getLocalPublicCollection,
|
||||
getLocalPublicCollectionPassword,
|
||||
|
@ -25,50 +61,6 @@ import {
|
|||
} from "services/publicCollectionService";
|
||||
import { Collection } from "types/collection";
|
||||
import { EnteFile } from "types/file";
|
||||
import {
|
||||
downloadSelectedFiles,
|
||||
getSelectedFiles,
|
||||
mergeMetadata,
|
||||
sortFiles,
|
||||
} from "utils/file";
|
||||
import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery";
|
||||
|
||||
import { logoutUser } from "@ente/accounts/services/user";
|
||||
import { APPS } from "@ente/shared/apps/constants";
|
||||
import EnteSpinner from "@ente/shared/components/EnteSpinner";
|
||||
import FormPaper from "@ente/shared/components/Form/FormPaper";
|
||||
import FormPaperTitle from "@ente/shared/components/Form/FormPaper/Title";
|
||||
import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
|
||||
import { OverflowMenuOption } from "@ente/shared/components/OverflowMenu/option";
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
|
||||
import { ENTE_WEBSITE_LINK } from "@ente/shared/constants/urls";
|
||||
import ComlinkCryptoWorker from "@ente/shared/crypto";
|
||||
import useFileInput from "@ente/shared/hooks/useFileInput";
|
||||
import AddPhotoAlternateOutlined from "@mui/icons-material/AddPhotoAlternateOutlined";
|
||||
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
|
||||
import MoreHoriz from "@mui/icons-material/MoreHoriz";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import bs58 from "bs58";
|
||||
import { CollectionInfo } from "components/Collections/CollectionInfo";
|
||||
import { CollectionInfoBarWrapper } from "components/Collections/styledComponents";
|
||||
import {
|
||||
FilesDownloadProgress,
|
||||
FilesDownloadProgressAttributes,
|
||||
} from "components/FilesDownloadProgress";
|
||||
import FullScreenDropZone from "components/FullScreenDropZone";
|
||||
import { LoadingOverlay } from "components/LoadingOverlay";
|
||||
import { ITEM_TYPE, TimeStampListItem } from "components/PhotoList";
|
||||
import UploadButton from "components/Upload/UploadButton";
|
||||
import Uploader from "components/Upload/Uploader";
|
||||
import UploadSelectorInputs from "components/UploadSelectorInputs";
|
||||
import SharedAlbumNavbar from "components/pages/sharedAlbum/Navbar";
|
||||
import SelectedFileOptions from "components/pages/sharedAlbum/SelectedFileOptions";
|
||||
import { useRouter } from "next/router";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import downloadManager from "services/download";
|
||||
import {
|
||||
SelectedState,
|
||||
SetFilesDownloadProgressAttributes,
|
||||
|
@ -76,6 +68,13 @@ import {
|
|||
UploadTypeSelectorIntent,
|
||||
} from "types/gallery";
|
||||
import { downloadCollectionFiles, isHiddenCollection } from "utils/collection";
|
||||
import {
|
||||
downloadSelectedFiles,
|
||||
getSelectedFiles,
|
||||
mergeMetadata,
|
||||
sortFiles,
|
||||
} from "utils/file";
|
||||
import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery";
|
||||
|
||||
export default function PublicCollectionGallery() {
|
||||
const token = useRef<string>(null);
|
||||
|
@ -118,16 +117,16 @@ export default function PublicCollectionGallery() {
|
|||
disabled: shouldDisableDropzone,
|
||||
});
|
||||
const {
|
||||
selectedFiles: fileSelectorFiles,
|
||||
open: openFileSelector,
|
||||
getInputProps: getFileSelectorInputProps,
|
||||
openSelector: openFileSelector,
|
||||
selectedFiles: fileSelectorFiles,
|
||||
} = useFileInput({
|
||||
directory: false,
|
||||
});
|
||||
const {
|
||||
selectedFiles: folderSelectorFiles,
|
||||
open: openFolderSelector,
|
||||
getInputProps: getFolderSelectorInputProps,
|
||||
openSelector: openFolderSelector,
|
||||
selectedFiles: folderSelectorFiles,
|
||||
} = useFileInput({
|
||||
directory: true,
|
||||
});
|
||||
|
@ -543,14 +542,13 @@ export default function PublicCollectionGallery() {
|
|||
photoListFooter,
|
||||
}}
|
||||
>
|
||||
<FullScreenDropZone
|
||||
getDragAndDropRootProps={getDragAndDropRootProps}
|
||||
>
|
||||
<FullScreenDropZone {...{ getDragAndDropRootProps }}>
|
||||
<UploadSelectorInputs
|
||||
getDragAndDropInputProps={getDragAndDropInputProps}
|
||||
getFileSelectorInputProps={getFileSelectorInputProps}
|
||||
getFolderSelectorInputProps={getFolderSelectorInputProps}
|
||||
getZipFileSelectorInputProps={undefined}
|
||||
{...{
|
||||
getDragAndDropInputProps,
|
||||
getFileSelectorInputProps,
|
||||
getFolderSelectorInputProps,
|
||||
}}
|
||||
/>
|
||||
<SharedAlbumNavbar
|
||||
showUploadButton={
|
||||
|
|
|
@ -1,56 +1,71 @@
|
|||
import { useCallback, useRef, useState } from "react";
|
||||
|
||||
interface UseFileInputParams {
|
||||
/**
|
||||
* If `true`, the file open dialog will ask the user to select directories.
|
||||
* Otherwise it'll ask the user to select files (default).
|
||||
*/
|
||||
directory?: boolean;
|
||||
/**
|
||||
* If specified, it'll restrict the type of files that the user can select
|
||||
* by setting the "accept" attribute of the underlying HTML input element we
|
||||
* use to surface the file selector dialog. For value of accept can be an
|
||||
* extension or a MIME type (See
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept).
|
||||
*/
|
||||
accept?: string;
|
||||
}
|
||||
|
||||
interface UseFileInputResult {
|
||||
/**
|
||||
* A function to call to get the properties that should be passed to a dummy
|
||||
* `input` element that needs to be created to anchor the select file
|
||||
* dialog. This input HTML element is not going to be visible, but it needs
|
||||
* to be part of the DOM for {@link openSelector} to have effect.
|
||||
*/
|
||||
getInputProps: () => React.HTMLAttributes<HTMLInputElement>;
|
||||
/**
|
||||
* A function that can be called to open the select file / directory dialog.
|
||||
*/
|
||||
openSelector: () => void;
|
||||
/**
|
||||
* The list of {@link File}s that the user selected.
|
||||
*
|
||||
* This will be a list even if the user selected directories - in that case,
|
||||
* it will be the recursive list of files within this directory.
|
||||
*/
|
||||
selectedFiles: File[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return three things:
|
||||
* Wrap a open file selector into an easy to use package.
|
||||
*
|
||||
* - A function that can be called to trigger the showing of the select file /
|
||||
* directory dialog.
|
||||
* Returns a {@link UseFileInputResult} which contains a function to get the
|
||||
* props for an input element, a function to open the file selector, and the
|
||||
* list of selected files.
|
||||
*
|
||||
* - The list of properties that should be passed to a dummy `input` element
|
||||
* that needs to be created to anchor the select file dialog. This input HTML
|
||||
* element is not going to be visible, but it needs to be part of the DOM fro
|
||||
* the open trigger to have effect.
|
||||
*
|
||||
* - The list of files that the user selected. This will be a list even if the
|
||||
* user selected directories - in that case, it will be the recursive list of
|
||||
* files within this directory.
|
||||
*
|
||||
* @param param0
|
||||
*
|
||||
* - If {@link directory} is true, the file open dialog will ask the user to
|
||||
* select directories. Otherwise it'll ask the user to select files.
|
||||
*
|
||||
* - If {@link accept} is specified, it'll restrict the type of files that the
|
||||
* user can select by setting the "accept" attribute of the underlying HTML
|
||||
* input element we use to surface the file selector dialog. For value of
|
||||
* accept can be an extension or a MIME type (See
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept).
|
||||
* See the documentation of {@link UseFileInputParams} and
|
||||
* {@link UseFileInputResult} for more details.
|
||||
*/
|
||||
export default function useFileInput({
|
||||
export const useFileInput = ({
|
||||
directory,
|
||||
accept,
|
||||
}: UseFileInputParams) {
|
||||
}: UseFileInputParams): UseFileInputResult => {
|
||||
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
|
||||
const inputRef = useRef<HTMLInputElement>();
|
||||
|
||||
const openSelectorDialog = useCallback(() => {
|
||||
const openSelector = useCallback(() => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.value = null;
|
||||
inputRef.current.click();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = async (
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (
|
||||
event,
|
||||
) => {
|
||||
if (!!event.target && !!event.target.files) {
|
||||
setSelectedFiles([...event.target.files]);
|
||||
}
|
||||
const files = event.target?.files;
|
||||
if (files) setSelectedFiles([...files]);
|
||||
};
|
||||
|
||||
// [Note: webkitRelativePath]
|
||||
|
@ -78,12 +93,8 @@ export default function useFileInput({
|
|||
onChange: handleChange,
|
||||
...(accept ? { accept } : {}),
|
||||
}),
|
||||
[],
|
||||
[directoryOpts, accept],
|
||||
);
|
||||
|
||||
return {
|
||||
getInputProps,
|
||||
open: openSelectorDialog,
|
||||
selectedFiles: selectedFiles,
|
||||
};
|
||||
}
|
||||
return { getInputProps, openSelector, selectedFiles };
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue