diff --git a/web/apps/photos/src/utils/upload/index.ts b/web/apps/photos/src/utils/upload/index.ts index 21531bd38..935400352 100644 --- a/web/apps/photos/src/utils/upload/index.ts +++ b/web/apps/photos/src/utils/upload/index.ts @@ -110,14 +110,59 @@ export function areFileWithCollectionsSame( return firstFile.localID === secondFile.localID; } -export function getImportSuggestion( +/** + * Return true if all the paths in the given list are items that belong to the + * same (arbitrary) directory. + */ +export const areInSameDirectory = ( uploadType: PICKED_UPLOAD_TYPE, - paths: string[], + toUploadFiles: File[] | ElectronFile[], ): ImportSuggestion { if (isElectron() && uploadType === PICKED_UPLOAD_TYPE.FILES) { return DEFAULT_IMPORT_SUGGESTION; } + const paths: string[] = toUploadFiles.map((file) => file["path"]); + const getCharCount = (str: string) => (str.match(/\//g) ?? []).length; + paths.sort((path1, path2) => getCharCount(path1) - getCharCount(path2)); + const firstPath = paths[0]; + const lastPath = paths[paths.length - 1]; + + const L = firstPath.length; + let i = 0; + const firstFileFolder = firstPath.substring(0, firstPath.lastIndexOf("/")); + const lastFileFolder = lastPath.substring(0, lastPath.lastIndexOf("/")); + + while (i < L && firstPath.charAt(i) === lastPath.charAt(i)) i++; + let commonPathPrefix = firstPath.substring(0, i); + + if (commonPathPrefix) { + commonPathPrefix = commonPathPrefix.substring( + 0, + commonPathPrefix.lastIndexOf("/"), + ); + if (commonPathPrefix) { + commonPathPrefix = commonPathPrefix.substring( + commonPathPrefix.lastIndexOf("/") + 1, + ); + } + } + return { + rootFolderName: commonPathPrefix || null, + hasNestedFolders: firstFileFolder !== lastFileFolder, + hasRootLevelFileWithFolder: firstFileFolder === "", + }; +} + +export function getImportSuggestion( + uploadType: PICKED_UPLOAD_TYPE, + toUploadFiles: File[] | ElectronFile[], +): ImportSuggestion { + if (isElectron() && uploadType === PICKED_UPLOAD_TYPE.FILES) { + return DEFAULT_IMPORT_SUGGESTION; + } + + const paths: string[] = toUploadFiles.map((file) => file["path"]); const getCharCount = (str: string) => (str.match(/\//g) ?? []).length; paths.sort((path1, path2) => getCharCount(path1) - getCharCount(path2)); const firstPath = paths[0]; diff --git a/web/packages/next/file.ts b/web/packages/next/file.ts index fae9a6d00..b213283b4 100644 --- a/web/packages/next/file.ts +++ b/web/packages/next/file.ts @@ -29,6 +29,23 @@ export const nameAndExtension = (fileName: string): FileNameComponents => { export const fileNameFromComponents = (components: FileNameComponents) => components.filter((x) => !!x).join("."); +/** + * Extract the fileName from the given path. + */ +export const fileNameFromPOSIXPath = (path: string) => { + const pathComponents = path.split("/"); + return pathComponents[pathComponents.length - 1] ?? path; +}; + +/** + * Extract the directory path (leading up to the item) from the given path. + */ +export const directoryNameFromPOSIXPath = (path: string) => { + const pathComponents = path.split("/"); + pathComponents.pop(); + return pathComponents.join("/"); +}; + export function getFileNameSize(file: File | ElectronFile) { return `${file.name}_${convertBytesToHumanReadable(file.size)}`; }