mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 07:28:26 +00:00
Also mark selection
This commit is contained in:
parent
957c333cf3
commit
77d16e275d
@ -228,35 +228,61 @@ export const Upload: React.FC<UploadProps> = ({
|
||||
const uploaderNameRef = useRef<string>(null);
|
||||
const isDragAndDrop = useRef(false);
|
||||
|
||||
/**
|
||||
* `true` if we've activated one hidden {@link Inputs} that allow the user
|
||||
* to select items, and haven't heard back from the browser as to the
|
||||
* selection (or cancellation).
|
||||
*
|
||||
* [Note: Showing an activity indicator during upload item selection]
|
||||
*
|
||||
* When selecting a large number of items (100K+), the browser can take
|
||||
* significant time (10s+) before it hands back control to us. The
|
||||
* {@link isInputPending} state tracks this intermediate state, and we use
|
||||
* it to show an activity indicator to let that the user know that their
|
||||
* selection is still being processed.
|
||||
*/
|
||||
const [isInputPending, setIsInputPending] = useState(false);
|
||||
|
||||
/**
|
||||
* Files that were selected by the user in the last activation of one of the
|
||||
* hidden {@link Inputs}.
|
||||
*/
|
||||
const [selectedInputFiles, setSelectedInputFiles] = useState<File[]>([]);
|
||||
|
||||
const handleInputSelect = useCallback((files: File[]) => {
|
||||
setIsInputPending(false);
|
||||
setSelectedInputFiles(files);
|
||||
}, []);
|
||||
|
||||
const handleInputCancel = useCallback(() => {
|
||||
console.log("cancel");
|
||||
setIsInputPending(false);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
getInputProps: getFileSelectorInputProps,
|
||||
openSelector: openFileSelector,
|
||||
selectedFiles: fileSelectorFiles,
|
||||
} = useFileInput({
|
||||
directory: false,
|
||||
onSelect: handleInputSelect,
|
||||
onCancel: handleInputCancel,
|
||||
});
|
||||
|
||||
const {
|
||||
getInputProps: getFolderSelectorInputProps,
|
||||
openSelector: openFolderSelector,
|
||||
selectedFiles: folderSelectorFiles,
|
||||
} = useFileInput({
|
||||
directory: true,
|
||||
onSelect: handleInputSelect,
|
||||
onCancel: handleInputCancel,
|
||||
});
|
||||
|
||||
const {
|
||||
getInputProps: getZipFileSelectorInputProps,
|
||||
openSelector: openZipFileSelector,
|
||||
selectedFiles: fileSelectorZipFiles,
|
||||
} = useFileInput({
|
||||
directory: false,
|
||||
accept: ".zip",
|
||||
onSelect: handleInputSelect,
|
||||
onCancel: handleInputCancel,
|
||||
});
|
||||
|
||||
@ -346,15 +372,9 @@ export const Upload: React.FC<UploadProps> = ({
|
||||
|
||||
switch (selectedUploadType.current) {
|
||||
case "files":
|
||||
files = fileSelectorFiles;
|
||||
break;
|
||||
|
||||
case "folders":
|
||||
files = folderSelectorFiles;
|
||||
break;
|
||||
|
||||
case "zips":
|
||||
files = fileSelectorZipFiles;
|
||||
files = selectedInputFiles;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -373,12 +393,7 @@ export const Upload: React.FC<UploadProps> = ({
|
||||
} else {
|
||||
setWebFiles(files);
|
||||
}
|
||||
}, [
|
||||
dragAndDropFiles,
|
||||
fileSelectorFiles,
|
||||
folderSelectorFiles,
|
||||
fileSelectorZipFiles,
|
||||
]);
|
||||
}, [selectedInputFiles, dragAndDropFiles]);
|
||||
|
||||
// Trigger an upload when any of the dependencies change.
|
||||
useEffect(() => {
|
||||
@ -739,6 +754,7 @@ export const Upload: React.FC<UploadProps> = ({
|
||||
|
||||
const handleUploadTypeSelect = (type: UploadType) => {
|
||||
selectedUploadType.current = type;
|
||||
setIsInputPending(true);
|
||||
switch (type) {
|
||||
case "files":
|
||||
openFileSelector();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
|
||||
interface UseFileInputParams {
|
||||
/**
|
||||
@ -14,6 +14,17 @@ interface UseFileInputParams {
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept).
|
||||
*/
|
||||
accept?: string;
|
||||
/**
|
||||
* A callback that is invoked when the user selects files.
|
||||
*
|
||||
* It will be passed 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.
|
||||
*
|
||||
* If the user selected no items, then {@link onCancel} will be invoked.
|
||||
*/
|
||||
onSelect: (selectedFiles: File[]) => void;
|
||||
/**
|
||||
* A callback that is invoked when the user cancels on the file / directory
|
||||
* dialog.
|
||||
@ -33,13 +44,6 @@ interface UseFileInputResult {
|
||||
* 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[];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,9 +59,9 @@ interface UseFileInputResult {
|
||||
export const useFileInput = ({
|
||||
directory,
|
||||
accept,
|
||||
onSelect,
|
||||
onCancel,
|
||||
}: UseFileInputParams): UseFileInputResult => {
|
||||
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
|
||||
const inputRef = useRef<HTMLInputElement | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
@ -80,7 +84,11 @@ export const useFileInput = ({
|
||||
event,
|
||||
) => {
|
||||
const files = event.target.files;
|
||||
if (files) setSelectedFiles([...files]);
|
||||
if (files?.length) {
|
||||
onSelect([...files]);
|
||||
} else {
|
||||
onCancel();
|
||||
}
|
||||
};
|
||||
|
||||
// [Note: webkitRelativePath]
|
||||
@ -111,5 +119,5 @@ export const useFileInput = ({
|
||||
[directoryOpts, accept, handleChange],
|
||||
);
|
||||
|
||||
return { getInputProps, openSelector, selectedFiles };
|
||||
return { getInputProps, openSelector };
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user