filebrowser/frontend/src/utils/upload.ts

155 lines
3.5 KiB
TypeScript

import { useUploadStore } from "@/stores/upload";
import url from "@/utils/url";
export function checkConflict(
files: UploadList,
dest: ResourceItem[]
): boolean {
if (typeof dest === "undefined" || dest === null) {
dest = [];
}
const folder_upload = files[0].fullPath !== undefined;
const names = new Set<string>();
for (let i = 0; i < files.length; i++) {
const file = files[i];
let name = file.name;
if (folder_upload) {
const dirs = file.fullPath?.split("/");
if (dirs && dirs.length > 1) {
name = dirs[0];
}
}
names.add(name);
}
return dest.some((d) => names.has(d.name));
}
export function scanFiles(dt: DataTransfer): Promise<UploadList | FileList> {
return new Promise((resolve) => {
let reading = 0;
const contents: UploadList = [];
if (dt.items) {
// ts didn't like the for of loop even tho
// it is the official example on MDN
// for (const item of dt.items) {
for (let i = 0; i < dt.items.length; i++) {
const item = dt.items[i];
if (
item.kind === "file" &&
typeof item.webkitGetAsEntry === "function"
) {
const entry = item.webkitGetAsEntry();
entry && readEntry(entry);
}
}
} else {
resolve(dt.files);
}
function readEntry(entry: FileSystemEntry, directory = ""): void {
if (entry.isFile) {
reading++;
(entry as FileSystemFileEntry).file((file) => {
reading--;
contents.push({
file,
name: file.name,
size: file.size,
isDir: false,
fullPath: `${directory}${file.name}`,
});
if (reading === 0) {
resolve(contents);
}
});
} else if (entry.isDirectory) {
const dir = {
isDir: true,
size: 0,
fullPath: `${directory}${entry.name}`,
name: entry.name,
};
contents.push(dir);
readReaderContent(
(entry as FileSystemDirectoryEntry).createReader(),
`${directory}${entry.name}`
);
}
}
function readReaderContent(
reader: FileSystemDirectoryReader,
directory: string
): void {
reading++;
reader.readEntries((entries) => {
reading--;
if (entries.length > 0) {
for (const entry of entries) {
readEntry(entry, `${directory}/`);
}
readReaderContent(reader, `${directory}/`);
}
if (reading === 0) {
resolve(contents);
}
});
}
});
}
function detectType(mimetype: string): ResourceType {
if (mimetype.startsWith("video")) return "video";
if (mimetype.startsWith("audio")) return "audio";
if (mimetype.startsWith("image")) return "image";
if (mimetype.startsWith("pdf")) return "pdf";
if (mimetype.startsWith("text")) return "text";
return "blob";
}
export function handleFiles(
files: UploadList,
base: string,
overwrite = false
) {
const uploadStore = useUploadStore();
for (const file of files) {
const id = uploadStore.id;
let path = base;
if (file.fullPath !== undefined) {
path += url.encodePath(file.fullPath);
} else {
path += url.encodeRFC5987ValueChars(file.name);
}
if (file.isDir) {
path += "/";
}
const item: UploadItem = {
id,
path,
file,
overwrite,
...(!file.isDir && { type: detectType((file.file as File).type) }),
};
uploadStore.upload(item);
}
}