mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 15:30:40 +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 uploaderNameRef = useRef<string>(null);
|
||||||
const isDragAndDrop = useRef(false);
|
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(() => {
|
const handleInputCancel = useCallback(() => {
|
||||||
console.log("cancel");
|
setIsInputPending(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getInputProps: getFileSelectorInputProps,
|
getInputProps: getFileSelectorInputProps,
|
||||||
openSelector: openFileSelector,
|
openSelector: openFileSelector,
|
||||||
selectedFiles: fileSelectorFiles,
|
|
||||||
} = useFileInput({
|
} = useFileInput({
|
||||||
directory: false,
|
directory: false,
|
||||||
|
onSelect: handleInputSelect,
|
||||||
onCancel: handleInputCancel,
|
onCancel: handleInputCancel,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getInputProps: getFolderSelectorInputProps,
|
getInputProps: getFolderSelectorInputProps,
|
||||||
openSelector: openFolderSelector,
|
openSelector: openFolderSelector,
|
||||||
selectedFiles: folderSelectorFiles,
|
|
||||||
} = useFileInput({
|
} = useFileInput({
|
||||||
directory: true,
|
directory: true,
|
||||||
|
onSelect: handleInputSelect,
|
||||||
onCancel: handleInputCancel,
|
onCancel: handleInputCancel,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getInputProps: getZipFileSelectorInputProps,
|
getInputProps: getZipFileSelectorInputProps,
|
||||||
openSelector: openZipFileSelector,
|
openSelector: openZipFileSelector,
|
||||||
selectedFiles: fileSelectorZipFiles,
|
|
||||||
} = useFileInput({
|
} = useFileInput({
|
||||||
directory: false,
|
directory: false,
|
||||||
accept: ".zip",
|
accept: ".zip",
|
||||||
|
onSelect: handleInputSelect,
|
||||||
onCancel: handleInputCancel,
|
onCancel: handleInputCancel,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -346,15 +372,9 @@ export const Upload: React.FC<UploadProps> = ({
|
|||||||
|
|
||||||
switch (selectedUploadType.current) {
|
switch (selectedUploadType.current) {
|
||||||
case "files":
|
case "files":
|
||||||
files = fileSelectorFiles;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "folders":
|
case "folders":
|
||||||
files = folderSelectorFiles;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "zips":
|
case "zips":
|
||||||
files = fileSelectorZipFiles;
|
files = selectedInputFiles;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -373,12 +393,7 @@ export const Upload: React.FC<UploadProps> = ({
|
|||||||
} else {
|
} else {
|
||||||
setWebFiles(files);
|
setWebFiles(files);
|
||||||
}
|
}
|
||||||
}, [
|
}, [selectedInputFiles, dragAndDropFiles]);
|
||||||
dragAndDropFiles,
|
|
||||||
fileSelectorFiles,
|
|
||||||
folderSelectorFiles,
|
|
||||||
fileSelectorZipFiles,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Trigger an upload when any of the dependencies change.
|
// Trigger an upload when any of the dependencies change.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -739,6 +754,7 @@ export const Upload: React.FC<UploadProps> = ({
|
|||||||
|
|
||||||
const handleUploadTypeSelect = (type: UploadType) => {
|
const handleUploadTypeSelect = (type: UploadType) => {
|
||||||
selectedUploadType.current = type;
|
selectedUploadType.current = type;
|
||||||
|
setIsInputPending(true);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "files":
|
case "files":
|
||||||
openFileSelector();
|
openFileSelector();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
|
|
||||||
interface UseFileInputParams {
|
interface UseFileInputParams {
|
||||||
/**
|
/**
|
||||||
@ -14,6 +14,17 @@ interface UseFileInputParams {
|
|||||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept).
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept).
|
||||||
*/
|
*/
|
||||||
accept?: string;
|
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
|
* A callback that is invoked when the user cancels on the file / directory
|
||||||
* dialog.
|
* dialog.
|
||||||
@ -33,13 +44,6 @@ interface UseFileInputResult {
|
|||||||
* A function that can be called to open the select file / directory dialog.
|
* A function that can be called to open the select file / directory dialog.
|
||||||
*/
|
*/
|
||||||
openSelector: () => void;
|
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 = ({
|
export const useFileInput = ({
|
||||||
directory,
|
directory,
|
||||||
accept,
|
accept,
|
||||||
|
onSelect,
|
||||||
onCancel,
|
onCancel,
|
||||||
}: UseFileInputParams): UseFileInputResult => {
|
}: UseFileInputParams): UseFileInputResult => {
|
||||||
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
|
|
||||||
const inputRef = useRef<HTMLInputElement | undefined>(undefined);
|
const inputRef = useRef<HTMLInputElement | undefined>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -80,7 +84,11 @@ export const useFileInput = ({
|
|||||||
event,
|
event,
|
||||||
) => {
|
) => {
|
||||||
const files = event.target.files;
|
const files = event.target.files;
|
||||||
if (files) setSelectedFiles([...files]);
|
if (files?.length) {
|
||||||
|
onSelect([...files]);
|
||||||
|
} else {
|
||||||
|
onCancel();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// [Note: webkitRelativePath]
|
// [Note: webkitRelativePath]
|
||||||
@ -111,5 +119,5 @@ export const useFileInput = ({
|
|||||||
[directoryOpts, accept, handleChange],
|
[directoryOpts, accept, handleChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { getInputProps, openSelector, selectedFiles };
|
return { getInputProps, openSelector };
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user