Understand, document and fix
This commit is contained in:
parent
ac67566f45
commit
e92bbdb8c6
2 changed files with 52 additions and 4 deletions
|
@ -1,6 +1,8 @@
|
|||
import { basename } from "@/next/file";
|
||||
import log from "@/next/log";
|
||||
import type { CollectionMapping, Electron, ZipItem } from "@/next/types/ipc";
|
||||
import { firstNonEmpty } from "@/utils/array";
|
||||
import { ensure } from "@/utils/ensure";
|
||||
import { CustomError } from "@ente/shared/error";
|
||||
import { isPromise } from "@ente/shared/utils";
|
||||
import DiscFullIcon from "@mui/icons-material/DiscFull";
|
||||
|
@ -324,17 +326,17 @@ export default function Uploader({
|
|||
|
||||
// Trigger an upload when any of the dependencies change.
|
||||
useEffect(() => {
|
||||
// Re the paths:
|
||||
// About the paths:
|
||||
//
|
||||
// - These are not necessarily the full paths. In particular, when
|
||||
// running on the browser they'll be the relative paths (at best) or
|
||||
// just the file-name otherwise.
|
||||
//
|
||||
// - All the paths use POSIX separators. See inline comments.
|
||||
//
|
||||
const allItemAndPaths = [
|
||||
// See: [Note: webkitRelativePath]. In particular, they use POSIX
|
||||
// separators.
|
||||
webFiles.map((f) => [f, f.webkitRelativePath ?? f.name]),
|
||||
// Relative path (using POSIX separators) or the file's name.
|
||||
webFiles.map((f) => [f, pathLikeForWebFile(f)]),
|
||||
// The paths we get from the desktop app all eventually come either
|
||||
// from electron.selectDirectory or electron.pathForFile, both of
|
||||
// which return POSIX paths.
|
||||
|
@ -822,6 +824,37 @@ const desktopFilesAndZipItems = async (electron: Electron, files: File[]) => {
|
|||
return { fileAndPaths, zipItems };
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the relative path or name of a File object selected or
|
||||
* drag-and-dropped on the web.
|
||||
*
|
||||
* There are three cases here:
|
||||
*
|
||||
* 1. If the user selects individual file(s), then the returned File objects
|
||||
* will only have a `name`.
|
||||
*
|
||||
* 2. If the user selects directory(ies), then the returned File objects will
|
||||
* have a `webkitRelativePath`. For more details, see [Note:
|
||||
* webkitRelativePath]. In particular, these will POSIX separators.
|
||||
*
|
||||
* 3. If the user drags-and-drops, then the react-dropzone library that we use
|
||||
* will internally convert `webkitRelativePath` to `path`, but otherwise it
|
||||
* behaves same as case 2.
|
||||
* https://github.com/react-dropzone/file-selector/blob/master/src/file.ts#L1214
|
||||
*/
|
||||
const pathLikeForWebFile = (file: File): string =>
|
||||
ensure(
|
||||
firstNonEmpty([
|
||||
// We need to check first, since path is not a property of
|
||||
// the standard File objects.
|
||||
"path" in file && typeof file.path == "string"
|
||||
? file.path
|
||||
: undefined,
|
||||
file.webkitRelativePath,
|
||||
file.name,
|
||||
]),
|
||||
);
|
||||
|
||||
// This is used to prompt the user the make upload strategy choice
|
||||
interface ImportSuggestion {
|
||||
rootFolderName: string;
|
||||
|
|
|
@ -13,3 +13,18 @@ export const shuffled = <T>(xs: T[]) =>
|
|||
.map((x) => [Math.random(), x])
|
||||
.sort()
|
||||
.map(([, x]) => x) as T[];
|
||||
|
||||
/**
|
||||
* Return the first non-empty string from the given list of strings.
|
||||
*
|
||||
* This function is needed because the `a ?? b` idiom doesn't do what you'd
|
||||
* expect when a is "". Perhaps the behaviour is wrong, perhaps the expecation
|
||||
* is wrong; this function papers over the differences.
|
||||
*
|
||||
* If none of the strings are non-empty, or if there are no strings in the given
|
||||
* array, return undefined.
|
||||
*/
|
||||
export const firstNonEmpty = (ss: (string | undefined)[]) => {
|
||||
for (const s of ss) if (s && s.length > 0) return s;
|
||||
return undefined;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue