Improve ts types in upload

This commit is contained in:
Kloon ImKloon 2023-09-14 12:57:39 +02:00
parent 065e11ff2b
commit 1ad7f4be5f
No known key found for this signature in database
GPG Key ID: CCF1C86A995C5B6A
4 changed files with 61 additions and 37 deletions

View File

@ -17,9 +17,9 @@ export const useUploadStore = defineStore("upload", {
// convert to a function
state: (): {
id: number;
sizes: any[];
progress: any[];
queue: any[];
sizes: number[];
progress: Progress[];
queue: UploadItem[];
uploads: Uploads;
error: Error | null;
} => ({
@ -39,7 +39,8 @@ export const useUploadStore = defineStore("upload", {
const totalSize = state.sizes.reduce((a, b) => a + b, 0);
const sum: number = state.progress.reduce((acc, val) => acc + val);
// TODO: this looks ugly but it works with ts now
const sum = state.progress.reduce((acc, val) => +acc + +val) as number;
return Math.ceil((sum / totalSize) * 100);
},
filesInUploadCount: (state) => {
@ -58,7 +59,7 @@ export const useUploadStore = defineStore("upload", {
const isDir = upload.file.isDir;
const progress = isDir
? 100
: Math.ceil((state.progress[id] / size) * 100);
: Math.ceil(((state.progress[id] as number) / size) * 100);
files.push({
id,
@ -74,9 +75,7 @@ export const useUploadStore = defineStore("upload", {
},
actions: {
// no context as first argument, use `this` instead
setProgress(obj: { id: number; loaded: boolean }) {
// Vue.set(this.progress, id, loaded);
const { id, loaded } = obj;
setProgress({ id, loaded }: { id: number; loaded: Progress }) {
this.progress[id] = loaded;
},
setError(error: Error) {
@ -95,11 +94,9 @@ export const useUploadStore = defineStore("upload", {
moveJob() {
const item = this.queue[0];
this.queue.shift();
// Vue.set(this.uploads, item.id, item);
this.uploads[item.id] = item;
},
removeJob(id: number) {
// Vue.delete(this.uploads, id);
delete this.uploads[id];
},
upload(item: UploadItem) {
@ -147,7 +144,7 @@ export const useUploadStore = defineStore("upload", {
await api.post(item.path).catch(this.setError);
} else {
const onUpload = throttle(
(event) =>
(event: ProgressEvent) =>
this.setProgress({
id: item.id,
loaded: event.loaded,
@ -157,7 +154,7 @@ export const useUploadStore = defineStore("upload", {
);
await api
.post(item.path, item.file, item.overwrite, onUpload)
.post(item.path, item.file.file as File, item.overwrite, onUpload)
.catch(this.setError);
}

View File

@ -9,7 +9,6 @@ interface ResourceBase {
isSymlink: boolean;
type: ResourceType;
url: string;
fullPath?: string;
}
interface Resource extends ResourceBase {

View File

@ -1,19 +1,31 @@
interface Uploads {
[key: string]: Upload;
[key: number]: Upload;
}
interface Upload {
id: number;
file: Resource;
type: string;
file: UploadEntry;
type?: ResourceType;
}
interface UploadItem {
id: number;
url?: string;
path: string;
file: Resource;
file: UploadEntry;
dir?: boolean;
overwrite?: boolean;
type?: ResourceType;
}
interface UploadEntry {
fullPath: string;
isDir: boolean;
name: string;
size: number;
file?: File;
}
type UploadList = UploadEntry[];
type Progress = number | boolean;

View File

@ -2,7 +2,7 @@ import { useUploadStore } from "@/stores/upload";
import url from "@/utils/url";
export function checkConflict(
files: ResourceItem[],
files: UploadList,
dest: ResourceItem[]
): boolean {
if (typeof dest === "undefined" || dest === null) {
@ -11,7 +11,7 @@ export function checkConflict(
const folder_upload = files[0].fullPath !== undefined;
const names: string[] = [];
const names = new Set<string>();
for (let i = 0; i < files.length; i++) {
const file = files[i];
let name = file.name;
@ -23,39 +23,48 @@ export function checkConflict(
}
}
names.push(name);
names.add(name);
}
return dest.some((d) => names.includes(d.name));
return dest.some((d) => names.has(d.name));
}
export function scanFiles(dt: { [key: string]: any; item: ResourceItem }) {
export function scanFiles(dt: DataTransfer) {
return new Promise((resolve) => {
let reading = 0;
const contents: any[] = [];
const contents: UploadList = [];
if (dt.items !== undefined) {
for (const item of dt.items) {
if (dt.items) {
// ts didnt 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();
readEntry(entry);
entry && readEntry(entry);
}
}
} else {
resolve(dt.files);
}
function readEntry(entry: any, directory = "") {
function readEntry(entry: FileSystemEntry, directory = ""): void {
if (entry.isFile) {
reading++;
entry.file((file: Resource) => {
(entry as FileSystemFileEntry).file((file) => {
reading--;
file.fullPath = `${directory}${file.name}`;
contents.push(file);
contents.push({
file,
name: file.name,
size: file.size,
isDir: false,
fullPath: `${directory}${file.name}`,
});
if (reading === 0) {
resolve(contents);
@ -71,14 +80,20 @@ export function scanFiles(dt: { [key: string]: any; item: ResourceItem }) {
contents.push(dir);
readReaderContent(entry.createReader(), `${directory}${entry.name}`);
readReaderContent(
(entry as FileSystemDirectoryEntry).createReader(),
`${directory}${entry.name}`
);
}
}
function readReaderContent(reader: any, directory: string) {
function readReaderContent(
reader: FileSystemDirectoryReader,
directory: string
): void {
reading++;
reader.readEntries(function (entries: any[]) {
reader.readEntries((entries) => {
reading--;
if (entries.length > 0) {
for (const entry of entries) {
@ -106,16 +121,15 @@ function detectType(mimetype: string): ResourceType {
}
export function handleFiles(
files: Resource[],
files: UploadList,
base: string,
overwrite = false
) {
const uploadStore = useUploadStore();
for (let i = 0; i < files.length; i++) {
for (const file of files) {
const id = uploadStore.id;
let path = base;
const file = files[i];
if (file.fullPath !== undefined) {
path += url.encodePath(file.fullPath);
@ -127,12 +141,14 @@ export function handleFiles(
path += "/";
}
console.log("File", file);
const item: UploadItem = {
id,
path,
file,
overwrite,
...(!file.isDir && { type: detectType(file.type) }),
...(!file.isDir && { type: detectType((file.file as File).type) }),
};
uploadStore.upload(item);