Improve ts types in upload
This commit is contained in:
parent
065e11ff2b
commit
1ad7f4be5f
@ -17,9 +17,9 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
// convert to a function
|
// convert to a function
|
||||||
state: (): {
|
state: (): {
|
||||||
id: number;
|
id: number;
|
||||||
sizes: any[];
|
sizes: number[];
|
||||||
progress: any[];
|
progress: Progress[];
|
||||||
queue: any[];
|
queue: UploadItem[];
|
||||||
uploads: Uploads;
|
uploads: Uploads;
|
||||||
error: Error | null;
|
error: Error | null;
|
||||||
} => ({
|
} => ({
|
||||||
@ -39,7 +39,8 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
|
|
||||||
const totalSize = state.sizes.reduce((a, b) => a + b, 0);
|
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);
|
return Math.ceil((sum / totalSize) * 100);
|
||||||
},
|
},
|
||||||
filesInUploadCount: (state) => {
|
filesInUploadCount: (state) => {
|
||||||
@ -58,7 +59,7 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
const isDir = upload.file.isDir;
|
const isDir = upload.file.isDir;
|
||||||
const progress = isDir
|
const progress = isDir
|
||||||
? 100
|
? 100
|
||||||
: Math.ceil((state.progress[id] / size) * 100);
|
: Math.ceil(((state.progress[id] as number) / size) * 100);
|
||||||
|
|
||||||
files.push({
|
files.push({
|
||||||
id,
|
id,
|
||||||
@ -74,9 +75,7 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// no context as first argument, use `this` instead
|
// no context as first argument, use `this` instead
|
||||||
setProgress(obj: { id: number; loaded: boolean }) {
|
setProgress({ id, loaded }: { id: number; loaded: Progress }) {
|
||||||
// Vue.set(this.progress, id, loaded);
|
|
||||||
const { id, loaded } = obj;
|
|
||||||
this.progress[id] = loaded;
|
this.progress[id] = loaded;
|
||||||
},
|
},
|
||||||
setError(error: Error) {
|
setError(error: Error) {
|
||||||
@ -95,11 +94,9 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
moveJob() {
|
moveJob() {
|
||||||
const item = this.queue[0];
|
const item = this.queue[0];
|
||||||
this.queue.shift();
|
this.queue.shift();
|
||||||
// Vue.set(this.uploads, item.id, item);
|
|
||||||
this.uploads[item.id] = item;
|
this.uploads[item.id] = item;
|
||||||
},
|
},
|
||||||
removeJob(id: number) {
|
removeJob(id: number) {
|
||||||
// Vue.delete(this.uploads, id);
|
|
||||||
delete this.uploads[id];
|
delete this.uploads[id];
|
||||||
},
|
},
|
||||||
upload(item: UploadItem) {
|
upload(item: UploadItem) {
|
||||||
@ -147,7 +144,7 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
await api.post(item.path).catch(this.setError);
|
await api.post(item.path).catch(this.setError);
|
||||||
} else {
|
} else {
|
||||||
const onUpload = throttle(
|
const onUpload = throttle(
|
||||||
(event) =>
|
(event: ProgressEvent) =>
|
||||||
this.setProgress({
|
this.setProgress({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
loaded: event.loaded,
|
loaded: event.loaded,
|
||||||
@ -157,7 +154,7 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await api
|
await api
|
||||||
.post(item.path, item.file, item.overwrite, onUpload)
|
.post(item.path, item.file.file as File, item.overwrite, onUpload)
|
||||||
.catch(this.setError);
|
.catch(this.setError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
frontend/src/types/file.d.ts
vendored
1
frontend/src/types/file.d.ts
vendored
@ -9,7 +9,6 @@ interface ResourceBase {
|
|||||||
isSymlink: boolean;
|
isSymlink: boolean;
|
||||||
type: ResourceType;
|
type: ResourceType;
|
||||||
url: string;
|
url: string;
|
||||||
fullPath?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Resource extends ResourceBase {
|
interface Resource extends ResourceBase {
|
||||||
|
|||||||
20
frontend/src/types/upload.d.ts
vendored
20
frontend/src/types/upload.d.ts
vendored
@ -1,19 +1,31 @@
|
|||||||
interface Uploads {
|
interface Uploads {
|
||||||
[key: string]: Upload;
|
[key: number]: Upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Upload {
|
interface Upload {
|
||||||
id: number;
|
id: number;
|
||||||
file: Resource;
|
file: UploadEntry;
|
||||||
type: string;
|
type?: ResourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UploadItem {
|
interface UploadItem {
|
||||||
id: number;
|
id: number;
|
||||||
url?: string;
|
url?: string;
|
||||||
path: string;
|
path: string;
|
||||||
file: Resource;
|
file: UploadEntry;
|
||||||
dir?: boolean;
|
dir?: boolean;
|
||||||
overwrite?: boolean;
|
overwrite?: boolean;
|
||||||
type?: ResourceType;
|
type?: ResourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UploadEntry {
|
||||||
|
fullPath: string;
|
||||||
|
isDir: boolean;
|
||||||
|
name: string;
|
||||||
|
size: number;
|
||||||
|
file?: File;
|
||||||
|
}
|
||||||
|
|
||||||
|
type UploadList = UploadEntry[];
|
||||||
|
|
||||||
|
type Progress = number | boolean;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useUploadStore } from "@/stores/upload";
|
|||||||
import url from "@/utils/url";
|
import url from "@/utils/url";
|
||||||
|
|
||||||
export function checkConflict(
|
export function checkConflict(
|
||||||
files: ResourceItem[],
|
files: UploadList,
|
||||||
dest: ResourceItem[]
|
dest: ResourceItem[]
|
||||||
): boolean {
|
): boolean {
|
||||||
if (typeof dest === "undefined" || dest === null) {
|
if (typeof dest === "undefined" || dest === null) {
|
||||||
@ -11,7 +11,7 @@ export function checkConflict(
|
|||||||
|
|
||||||
const folder_upload = files[0].fullPath !== undefined;
|
const folder_upload = files[0].fullPath !== undefined;
|
||||||
|
|
||||||
const names: string[] = [];
|
const names = new Set<string>();
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
const file = files[i];
|
const file = files[i];
|
||||||
let name = file.name;
|
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) => {
|
return new Promise((resolve) => {
|
||||||
let reading = 0;
|
let reading = 0;
|
||||||
const contents: any[] = [];
|
const contents: UploadList = [];
|
||||||
|
|
||||||
if (dt.items !== undefined) {
|
if (dt.items) {
|
||||||
for (const item of 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 (
|
if (
|
||||||
item.kind === "file" &&
|
item.kind === "file" &&
|
||||||
typeof item.webkitGetAsEntry === "function"
|
typeof item.webkitGetAsEntry === "function"
|
||||||
) {
|
) {
|
||||||
const entry = item.webkitGetAsEntry();
|
const entry = item.webkitGetAsEntry();
|
||||||
readEntry(entry);
|
entry && readEntry(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resolve(dt.files);
|
resolve(dt.files);
|
||||||
}
|
}
|
||||||
|
|
||||||
function readEntry(entry: any, directory = "") {
|
function readEntry(entry: FileSystemEntry, directory = ""): void {
|
||||||
if (entry.isFile) {
|
if (entry.isFile) {
|
||||||
reading++;
|
reading++;
|
||||||
entry.file((file: Resource) => {
|
(entry as FileSystemFileEntry).file((file) => {
|
||||||
reading--;
|
reading--;
|
||||||
|
|
||||||
file.fullPath = `${directory}${file.name}`;
|
contents.push({
|
||||||
contents.push(file);
|
file,
|
||||||
|
name: file.name,
|
||||||
|
size: file.size,
|
||||||
|
isDir: false,
|
||||||
|
fullPath: `${directory}${file.name}`,
|
||||||
|
});
|
||||||
|
|
||||||
if (reading === 0) {
|
if (reading === 0) {
|
||||||
resolve(contents);
|
resolve(contents);
|
||||||
@ -71,14 +80,20 @@ export function scanFiles(dt: { [key: string]: any; item: ResourceItem }) {
|
|||||||
|
|
||||||
contents.push(dir);
|
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++;
|
reading++;
|
||||||
|
|
||||||
reader.readEntries(function (entries: any[]) {
|
reader.readEntries((entries) => {
|
||||||
reading--;
|
reading--;
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
@ -106,16 +121,15 @@ function detectType(mimetype: string): ResourceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handleFiles(
|
export function handleFiles(
|
||||||
files: Resource[],
|
files: UploadList,
|
||||||
base: string,
|
base: string,
|
||||||
overwrite = false
|
overwrite = false
|
||||||
) {
|
) {
|
||||||
const uploadStore = useUploadStore();
|
const uploadStore = useUploadStore();
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (const file of files) {
|
||||||
const id = uploadStore.id;
|
const id = uploadStore.id;
|
||||||
let path = base;
|
let path = base;
|
||||||
const file = files[i];
|
|
||||||
|
|
||||||
if (file.fullPath !== undefined) {
|
if (file.fullPath !== undefined) {
|
||||||
path += url.encodePath(file.fullPath);
|
path += url.encodePath(file.fullPath);
|
||||||
@ -127,12 +141,14 @@ export function handleFiles(
|
|||||||
path += "/";
|
path += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("File", file);
|
||||||
|
|
||||||
const item: UploadItem = {
|
const item: UploadItem = {
|
||||||
id,
|
id,
|
||||||
path,
|
path,
|
||||||
file,
|
file,
|
||||||
overwrite,
|
overwrite,
|
||||||
...(!file.isDir && { type: detectType(file.type) }),
|
...(!file.isDir && { type: detectType((file.file as File).type) }),
|
||||||
};
|
};
|
||||||
|
|
||||||
uploadStore.upload(item);
|
uploadStore.upload(item);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user