You've already forked AstralRinth
forked from didirus/AstralRinth
Files UX Sprint (#3019)
* chore: dedupe lockfile Signed-off-by: Evan Song <theevansong@gmail.com> * fix: incorrect spacing between editing and browsing state Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve files image viewer toolbar Signed-off-by: Evan Song <theevansong@gmail.com> * chore: image viewer cursor affordance Signed-off-by: Evan Song <theevansong@gmail.com> * chore: clean imports Signed-off-by: Evan Song <theevansong@gmail.com> * chore: add tooltips Signed-off-by: Evan Song <theevansong@gmail.com> * chore: use black background Signed-off-by: Evan Song <theevansong@gmail.com> * feat: show scale factor, handle large images, consolidate state Signed-off-by: Evan Song <theevansong@gmail.com> * chore: add types to fs operations Signed-off-by: Evan Song <theevansong@gmail.com> * feat: add date create sorting option Signed-off-by: Evan Song <theevansong@gmail.com> * fix: match name of folder creation modal Signed-off-by: Evan Song <theevansong@gmail.com> * fix: add it here too Signed-off-by: Evan Song <theevansong@gmail.com> * feat: add creation date to file item, file manager header Signed-off-by: Evan Song <theevansong@gmail.com> * chore: a11y Signed-off-by: Evan Song <theevansong@gmail.com> * fix: ensure move item modal always has leading slash Signed-off-by: Evan Song <theevansong@gmail.com> * fix: correct move input placeholder Signed-off-by: Evan Song <theevansong@gmail.com> * chore: correct design disparity Signed-off-by: Evan Song <theevansong@gmail.com> * chore: add better affordance on active file item state Signed-off-by: Evan Song <theevansong@gmail.com> * fix: correct instances where we dont sentence case Signed-off-by: Evan Song <theevansong@gmail.com> * chore: clean Signed-off-by: Evan Song <theevansong@gmail.com> * chore: notify that server restarted on saveandrestart Signed-off-by: Evan Song <theevansong@gmail.com> * fix: consolidate error state in file manager Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust sizing Signed-off-by: Evan Song <theevansong@gmail.com> * feat: drag and drop file items to move them Signed-off-by: Evan Song <theevansong@gmail.com> * feat: enable ability to drag folders too Signed-off-by: Evan Song <theevansong@gmail.com> * feat: better file movement toasts Signed-off-by: Evan Song <theevansong@gmail.com> * just say u hate me Signed-off-by: Evan Song <theevansong@gmail.com> * feat: uploading indicator for file uploads Signed-off-by: Evan Song <theevansong@gmail.com> * chore: cleaner file item ghost when dragging Signed-off-by: Evan Song <theevansong@gmail.com> * fix: enforce max length and truncate on ghost Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve item rename toast Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve item create toast Signed-off-by: Evan Song <theevansong@gmail.com> * feat: undo and redo stack Signed-off-by: Evan Song <theevansong@gmail.com> * fix: confusing behavior where folders were not sorted alphabetically Signed-off-by: Evan Song <theevansong@gmail.com> * feat: find and replace in file editor Signed-off-by: Evan Song <theevansong@gmail.com> * feat: correctly set language mode of file editor Signed-off-by: Evan Song <theevansong@gmail.com> * chore: slop Signed-off-by: Evan Song <theevansong@gmail.com> * chore: actually handle case with multiple dots in file name before setting language Signed-off-by: Evan Song <theevansong@gmail.com> * fix: match move icons in file context/threedot Signed-off-by: Evan Song <theevansong@gmail.com> * feat: upload indicator Signed-off-by: Evan Song <theevansong@gmail.com> * chore: dedupe lockfile again Signed-off-by: Evan Song <theevansong@gmail.com> * lockfile Signed-off-by: Evan Song <theevansong@gmail.com> * fix: file undefinedness Signed-off-by: Evan Song <theevansong@gmail.com> * checkpoint Signed-off-by: Evan Song <theevansong@gmail.com> * checkpoint Signed-off-by: Evan Song <theevansong@gmail.com> * checkpoint Signed-off-by: Evan Song <theevansong@gmail.com> * remove shitty animation logic Signed-off-by: Evan Song <theevansong@gmail.com> * feat: file upload queuer Signed-off-by: Evan Song <theevansong@gmail.com> * chore: only allow editable files to have active affordance Signed-off-by: Evan Song <theevansong@gmail.com> * fix: properly throw pyrofetcherror when rename fails Signed-off-by: Evan Song <theevansong@gmail.com> * feat: cancel file uploads Signed-off-by: Evan Song <theevansong@gmail.com> * chore: clean Signed-off-by: Evan Song <theevansong@gmail.com> --------- Signed-off-by: Evan Song <theevansong@gmail.com>
This commit is contained in:
@@ -226,6 +226,21 @@ interface JWTAuth {
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface DirectoryItem {
|
||||
name: string;
|
||||
type: "directory" | "file";
|
||||
count?: number;
|
||||
modified: number;
|
||||
created: number;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface DirectoryResponse {
|
||||
items: DirectoryItem[];
|
||||
total: number;
|
||||
current?: number;
|
||||
}
|
||||
|
||||
type ContentType = "Mod" | "Plugin";
|
||||
|
||||
const constructServerProperties = (properties: any): string => {
|
||||
@@ -738,6 +753,8 @@ const retryWithAuth = async (requestFn: () => Promise<any>) => {
|
||||
await internalServerRefrence.value.refresh(["fs"]);
|
||||
return await requestFn();
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -763,21 +780,74 @@ const createFileOrFolder = (path: string, type: "file" | "directory") => {
|
||||
};
|
||||
|
||||
const uploadFile = (path: string, file: File) => {
|
||||
// eslint-disable-next-line require-await
|
||||
return retryWithAuth(async () => {
|
||||
const encodedPath = encodeURIComponent(path);
|
||||
return await PyroFetch(`/create?path=${encodedPath}&type=file`, {
|
||||
method: "POST",
|
||||
contentType: "application/octet-stream",
|
||||
body: file,
|
||||
override: internalServerRefrence.value.fs.auth,
|
||||
const progressSubject = new EventTarget();
|
||||
const abortController = new AbortController();
|
||||
|
||||
const uploadPromise = new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.upload.addEventListener("progress", (e) => {
|
||||
if (e.lengthComputable) {
|
||||
const progress = (e.loaded / e.total) * 100;
|
||||
progressSubject.dispatchEvent(
|
||||
new CustomEvent("progress", {
|
||||
detail: {
|
||||
loaded: e.loaded,
|
||||
total: e.total,
|
||||
progress,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
xhr.onload = () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
resolve(xhr.response);
|
||||
} else {
|
||||
reject(new Error(`Upload failed with status ${xhr.status}`));
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = () => reject(new Error("Upload failed"));
|
||||
xhr.onabort = () => reject(new Error("Upload cancelled"));
|
||||
|
||||
xhr.open(
|
||||
"POST",
|
||||
`https://${internalServerRefrence.value.fs.auth.url}/create?path=${encodedPath}&type=file`,
|
||||
);
|
||||
xhr.setRequestHeader("Authorization", `Bearer ${internalServerRefrence.value.fs.auth.token}`);
|
||||
xhr.setRequestHeader("Content-Type", "application/octet-stream");
|
||||
xhr.send(file);
|
||||
|
||||
abortController.signal.addEventListener("abort", () => {
|
||||
xhr.abort();
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
promise: uploadPromise,
|
||||
onProgress: (
|
||||
callback: (progress: { loaded: number; total: number; progress: number }) => void,
|
||||
) => {
|
||||
progressSubject.addEventListener("progress", ((e: CustomEvent) => {
|
||||
callback(e.detail);
|
||||
}) as EventListener);
|
||||
},
|
||||
cancel: () => {
|
||||
abortController.abort();
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const renameFileOrFolder = (path: string, name: string) => {
|
||||
const pathName = path.split("/").slice(0, -1).join("/") + "/" + name;
|
||||
return retryWithAuth(async () => {
|
||||
return await PyroFetch(`/move`, {
|
||||
await PyroFetch(`/move`, {
|
||||
method: "POST",
|
||||
override: internalServerRefrence.value.fs.auth,
|
||||
body: {
|
||||
@@ -785,6 +855,7 @@ const renameFileOrFolder = (path: string, name: string) => {
|
||||
destination: pathName,
|
||||
},
|
||||
});
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1235,7 +1306,7 @@ type FSFunctions = {
|
||||
* @param pageSize - The page size to list.
|
||||
* @returns
|
||||
*/
|
||||
listDirContents: (path: string, page: number, pageSize: number) => Promise<any>;
|
||||
listDirContents: (path: string, page: number, pageSize: number) => Promise<DirectoryResponse>;
|
||||
|
||||
/**
|
||||
* @param path - The path to create the file or folder at.
|
||||
|
||||
Reference in New Issue
Block a user