mirror of
https://github.com/rommapp/romm.git
synced 2025-12-22 10:27:13 +00:00
Upload dialog hotfixed + clear button
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -19,6 +19,8 @@ coverage
|
||||
|
||||
# Editor directories and files
|
||||
.vscode
|
||||
.zed
|
||||
pyrightconfig.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
|
||||
@@ -50,7 +50,14 @@ async def add_rom(request: Request):
|
||||
detail="No platform ID or filename provided",
|
||||
) from None
|
||||
|
||||
platform_fs_slug = db_platform_handler.get_platform(int(platform_id)).fs_slug
|
||||
db_platform = db_platform_handler.get_platform(int(platform_id))
|
||||
if not db_platform:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Platform not found",
|
||||
) from None
|
||||
|
||||
platform_fs_slug = db_platform.fs_slug
|
||||
roms_path = fs_rom_handler.build_upload_file_path(platform_fs_slug)
|
||||
log.info(f"Uploading file to {platform_fs_slug}")
|
||||
|
||||
|
||||
@@ -52,9 +52,7 @@ emitter?.on("showUploadRomDialog", (platformWhereUpload) => {
|
||||
})
|
||||
.catch(({ response, message }) => {
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: `Unable to upload roms: ${
|
||||
response?.data?.detail || response?.statusText || message
|
||||
}`,
|
||||
msg: `Unable to upload roms: ${response?.data?.detail || response?.statusText || message}`,
|
||||
icon: "mdi-close-circle",
|
||||
color: "red",
|
||||
timeout: 4000,
|
||||
@@ -101,13 +99,15 @@ async function uploadRoms() {
|
||||
platformId: platformId,
|
||||
})
|
||||
.then((responses: PromiseSettledResult<unknown>[]) => {
|
||||
uploadStore.clear();
|
||||
|
||||
const successfulUploads = responses.filter(
|
||||
(d) => d.status == "fulfilled"
|
||||
(d) => d.status == "fulfilled",
|
||||
);
|
||||
const failedUploads = responses.filter((d) => d.status == "rejected");
|
||||
|
||||
if (failedUploads.length == 0) {
|
||||
uploadStore.clearAll();
|
||||
}
|
||||
|
||||
if (successfulUploads.length == 0) {
|
||||
return emitter?.emit("snackbarShow", {
|
||||
msg: `All files skipped, nothing to upload.`,
|
||||
@@ -137,9 +137,7 @@ async function uploadRoms() {
|
||||
})
|
||||
.catch(({ response, message }) => {
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: `Unable to upload roms: ${
|
||||
response?.data?.detail || response?.statusText || message
|
||||
}`,
|
||||
msg: `Unable to upload roms: ${response?.data?.detail || response?.statusText || message}`,
|
||||
icon: "mdi-close-circle",
|
||||
color: "red",
|
||||
timeout: 4000,
|
||||
@@ -156,7 +154,7 @@ function triggerFileInput() {
|
||||
|
||||
function removeRomFromList(romName: string) {
|
||||
filesToUpload.value = filesToUpload.value.filter(
|
||||
(rom) => rom.name !== romName
|
||||
(rom) => rom.name !== romName,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ const uploadStore = storeUpload();
|
||||
const { files } = storeToRefs(uploadStore);
|
||||
const show = ref(false);
|
||||
|
||||
function clearFinished() {
|
||||
uploadStore.clearFinished();
|
||||
}
|
||||
|
||||
watch(files, (newList) => {
|
||||
show.value = newList.length > 0;
|
||||
});
|
||||
@@ -30,41 +34,64 @@ watch(files, (newList) => {
|
||||
<v-list-item
|
||||
v-for="file in files"
|
||||
class="py-2 px-4"
|
||||
:disabled="file.finished"
|
||||
:disabled="file.finished && !file.failed"
|
||||
>
|
||||
<v-list-item-title class="d-flex justify-space-between">
|
||||
{{ file.filename }}
|
||||
<v-icon
|
||||
:icon="file.finished ? `mdi-check` : `mdi-loading mdi-spin`"
|
||||
:color="file.finished ? `green` : `white`"
|
||||
class="mx-2"
|
||||
/>
|
||||
</v-list-item-title>
|
||||
<template v-if="file.progress > 0 && !file.finished">
|
||||
<v-progress-linear
|
||||
v-model="file.progress"
|
||||
height="4"
|
||||
color="white"
|
||||
class="mt-1"
|
||||
/>
|
||||
<div class="upload-speeds d-flex justify-space-between mt-1">
|
||||
<div>{{ formatBytes(file.rate) }}/s</div>
|
||||
<div>
|
||||
{{ formatBytes(file.loaded) }} /
|
||||
{{ formatBytes(file.total) }}
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="file.failed">
|
||||
<v-list-item-title class="d-flex justify-space-between">
|
||||
{{ file.filename }}
|
||||
<v-icon :icon="`mdi-close`" :color="`red`" class="mx-2" />
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="text-red mt-1">
|
||||
{{ file.failureReason }}
|
||||
</v-list-item-subtitle>
|
||||
</template>
|
||||
<template v-if="file.finished">
|
||||
<div class="upload-speeds d-flex justify-space-between mt-1">
|
||||
<div />
|
||||
<div>
|
||||
{{ formatBytes(file.total) }}
|
||||
<template v-else>
|
||||
<v-list-item-title class="d-flex justify-space-between">
|
||||
{{ file.filename }}
|
||||
<v-icon
|
||||
:icon="file.finished ? `mdi-check` : `mdi-loading mdi-spin`"
|
||||
:color="file.finished ? `green` : `white`"
|
||||
class="mx-2"
|
||||
/>
|
||||
</v-list-item-title>
|
||||
<template v-if="file.progress > 0 && !file.finished">
|
||||
<v-progress-linear
|
||||
v-model="file.progress"
|
||||
height="4"
|
||||
color="white"
|
||||
class="mt-1"
|
||||
/>
|
||||
<div class="upload-speeds d-flex justify-space-between mt-1">
|
||||
<div>{{ formatBytes(file.rate) }}/s</div>
|
||||
<div>
|
||||
{{ formatBytes(file.loaded) }} /
|
||||
{{ formatBytes(file.total) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="file.finished">
|
||||
<div class="upload-speeds d-flex justify-space-between mt-1">
|
||||
<div />
|
||||
<div>
|
||||
{{ formatBytes(file.total) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<div class="text-center">
|
||||
<v-btn
|
||||
size="small"
|
||||
variant="tonal"
|
||||
class="my-2"
|
||||
color="romm-accent-1"
|
||||
:disabled="!files.some((f) => f.finished || f.failed)"
|
||||
@click="clearFinished"
|
||||
>
|
||||
Clear finished
|
||||
</v-btn>
|
||||
</div>
|
||||
</v-snackbar>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ async function uploadRoms({
|
||||
})
|
||||
.then(resolve)
|
||||
.catch((error) => {
|
||||
console.error("Failed to upload file", file.name, error);
|
||||
uploadStore.fail(file.name, error.response?.data?.detail);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,6 +8,8 @@ class UploadingFile {
|
||||
loaded: number;
|
||||
rate: number;
|
||||
finished: boolean;
|
||||
failed: boolean;
|
||||
failureReason: string;
|
||||
|
||||
constructor(filename: string) {
|
||||
this.filename = filename;
|
||||
@@ -16,6 +18,8 @@ class UploadingFile {
|
||||
this.loaded = 0;
|
||||
this.rate = 0;
|
||||
this.finished = false;
|
||||
this.failed = false;
|
||||
this.failureReason = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +43,17 @@ export default defineStore("upload", {
|
||||
file.rate = progressEvent.rate || file.rate;
|
||||
file.finished = progressEvent.loaded === progressEvent.total;
|
||||
},
|
||||
clear() {
|
||||
fail(filename: string, reason: string) {
|
||||
const file = this.files.find((f) => f.filename === filename);
|
||||
if (!file) return;
|
||||
|
||||
file.failed = true;
|
||||
file.failureReason = reason;
|
||||
},
|
||||
clearFinished() {
|
||||
this.files = this.files.filter((f) => !f.finished && !f.failed);
|
||||
},
|
||||
clearAll() {
|
||||
this.files = [];
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user