mirror of https://github.com/VERT-sh/VERT.git
feat: view info submitted
for transparency, see the exact details that is sent automatically to the owner of the instance: - job id - convert from - convert to - ffmpeg stderr - actual video file (if submitted)
This commit is contained in:
parent
91a061a2ef
commit
e5ff309d83
|
|
@ -85,6 +85,13 @@
|
||||||
"vertd_generic_yes": "Submit video",
|
"vertd_generic_yes": "Submit video",
|
||||||
"vertd_generic_no": "Don't submit",
|
"vertd_generic_no": "Don't submit",
|
||||||
"vertd_failed_to_keep": "Failed to keep the video on the server: {error}",
|
"vertd_failed_to_keep": "Failed to keep the video on the server: {error}",
|
||||||
|
"vertd_details": "View error details",
|
||||||
|
"vertd_details_body": "If you submit your file, <b>your video will also be attached</b> alongside the error log being sent to us for review. The following information is the log that we automatically receive:",
|
||||||
|
"vertd_details_job_id": "<b>Job ID:</b> {jobId}",
|
||||||
|
"vertd_details_from": "<b>From format:</b> {from}",
|
||||||
|
"vertd_details_to": "<b>To format:</b> {to}",
|
||||||
|
"vertd_details_error_message": "<b>Error message:</b> [view_link]View error logs[/view_link]",
|
||||||
|
"vertd_details_close": "Close",
|
||||||
"unsupported_format": "Only image, video, audio, and document files are supported",
|
"unsupported_format": "Only image, video, audio, and document files are supported",
|
||||||
"vertd_not_found": "Could not find the vertd instance to start video conversion. Are you sure the instance URL is set correctly?",
|
"vertd_not_found": "Could not find the vertd instance to start video conversion. Are you sure the instance URL is set correctly?",
|
||||||
"worker_downloading": "The {type} converter is currently being initialized, please wait a few moments.",
|
"worker_downloading": "The {type} converter is currently being initialized, please wait a few moments.",
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,13 @@
|
||||||
import { removeDialog } from "$lib/store/DialogProvider";
|
import { removeDialog } from "$lib/store/DialogProvider";
|
||||||
import { BanIcon, CheckIcon, InfoIcon, TriangleAlert } from "lucide-svelte";
|
import { BanIcon, CheckIcon, InfoIcon, TriangleAlert } from "lucide-svelte";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
|
import type { Dialog as DialogType } from "$lib/store/DialogProvider";
|
||||||
|
|
||||||
type Props = {
|
type Props = DialogType;
|
||||||
id: number;
|
|
||||||
title: string;
|
|
||||||
message: string;
|
|
||||||
buttons: {
|
|
||||||
text: string;
|
|
||||||
action: () => void;
|
|
||||||
}[];
|
|
||||||
type: "success" | "error" | "info" | "warning";
|
|
||||||
};
|
|
||||||
|
|
||||||
let { id, title, message, buttons, type }: Props = $props();
|
let props: Props = $props();
|
||||||
|
const { id, title, message, buttons, type } = props;
|
||||||
|
const additional = "additional" in props ? props.additional : undefined;
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
success: "purple",
|
success: "purple",
|
||||||
|
|
@ -59,7 +53,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-1 w-full">
|
<div class="flex flex-col gap-1 w-full">
|
||||||
<p class="text-sm font-normal text-muted">{message}</p>
|
{#if typeof message === "string"}
|
||||||
|
<p class="text-sm font-normal text-muted whitespace-pre-wrap">{message}</p>
|
||||||
|
{:else}
|
||||||
|
{@const MessageComponent = message}
|
||||||
|
<div class="text-sm font-normal text-muted">
|
||||||
|
<MessageComponent {id} {title} {type} {buttons} {additional} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center gap-4 w-full">
|
<div class="flex flex-row items-center gap-4 w-full">
|
||||||
{#each buttons as { text, action }, i}
|
{#each buttons as { text, action }, i}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@
|
||||||
export interface VertdErrorProps {
|
export interface VertdErrorProps {
|
||||||
jobId: string;
|
jobId: string;
|
||||||
auth: string;
|
auth: string;
|
||||||
|
from?: string;
|
||||||
|
to?: string;
|
||||||
|
errorMessage?: string;
|
||||||
|
fileName?: string;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -10,6 +14,8 @@
|
||||||
|
|
||||||
import { m } from "$lib/paraglide/messages";
|
import { m } from "$lib/paraglide/messages";
|
||||||
import { ToastManager, type ToastProps } from "$lib/toast/index.svelte";
|
import { ToastManager, type ToastProps } from "$lib/toast/index.svelte";
|
||||||
|
import { addDialog } from "$lib/store/DialogProvider";
|
||||||
|
import VertdErrorDetails from "./VertdErrorDetails.svelte";
|
||||||
|
|
||||||
const toast: ToastProps<VertdErrorProps> = $props();
|
const toast: ToastProps<VertdErrorProps> = $props();
|
||||||
|
|
||||||
|
|
@ -52,10 +58,37 @@
|
||||||
|
|
||||||
ToastManager.remove(toast.id);
|
ToastManager.remove(toast.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showDetails = () => {
|
||||||
|
addDialog(
|
||||||
|
m["convert.errors.vertd_details"](),
|
||||||
|
VertdErrorDetails as any,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: "Close",
|
||||||
|
action: () => {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"info",
|
||||||
|
{
|
||||||
|
jobId: toast.additional.jobId || "Unknown",
|
||||||
|
from: toast.additional.from || "Unknown",
|
||||||
|
to: toast.additional.to || "Unknown",
|
||||||
|
errorMessage: toast.additional.errorMessage || "Unknown error",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<p class="text-black">{m["convert.errors.vertd_generic_body"]()}</p>
|
<p class="text-black">{m["convert.errors.vertd_generic_body"]()}</p>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<button
|
||||||
|
onclick={showDetails}
|
||||||
|
class="btn rounded-lg h-fit py-2 w-full bg-accent-blue text-black"
|
||||||
|
disabled={submitting}
|
||||||
|
>View Details Submitted</button
|
||||||
|
>
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
<button
|
<button
|
||||||
onclick={submit}
|
onclick={submit}
|
||||||
|
|
@ -70,4 +103,5 @@
|
||||||
>{m["convert.errors.vertd_generic_no"]()}</button
|
>{m["convert.errors.vertd_generic_no"]()}</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { m } from "$lib/paraglide/messages";
|
||||||
|
import type { DialogProps } from "$lib/store/DialogProvider";
|
||||||
|
import { link } from "$lib/store/index.svelte";
|
||||||
|
|
||||||
|
interface VertdErrorDetailsProps {
|
||||||
|
jobId: string;
|
||||||
|
from: string;
|
||||||
|
to: string;
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = DialogProps<VertdErrorDetailsProps>;
|
||||||
|
|
||||||
|
let { additional }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p>{@html m["convert.errors.vertd_details_body"]()}</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-black dynadark:text-white">
|
||||||
|
{@html m["convert.errors.vertd_details_job_id"]({
|
||||||
|
jobId: additional.jobId,
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-black dynadark:text-white">
|
||||||
|
{@html m["convert.errors.vertd_details_from"]({ from: additional.from })}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-black dynadark:text-white">
|
||||||
|
{@html m["convert.errors.vertd_details_to"]({ to: additional.to })}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="text-black dynadark:text-white">
|
||||||
|
{@html link(
|
||||||
|
["view_link"],
|
||||||
|
m["convert.errors.vertd_details_error_message"](),
|
||||||
|
[
|
||||||
|
URL.createObjectURL(
|
||||||
|
new Blob([additional.errorMessage], { type: "text/plain" })
|
||||||
|
)
|
||||||
|
],
|
||||||
|
[true],
|
||||||
|
["text-blue-500 font-normal hover:underline"]
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
@ -26,9 +26,9 @@
|
||||||
easing: quintOut,
|
easing: quintOut,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{#each dialogList as { id, title, message, buttons, type }, i}
|
{#each dialogList as dialog, i}
|
||||||
{#if i === 0}
|
{#if i === 0}
|
||||||
<Dialog {id} {title} {message} {buttons} {type} />
|
<Dialog {...dialog} />
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,9 @@ export class VertdConverter extends Converter {
|
||||||
additional: {
|
additional: {
|
||||||
jobId: uploadRes.id,
|
jobId: uploadRes.id,
|
||||||
auth: uploadRes.auth,
|
auth: uploadRes.auth,
|
||||||
|
from: input.from,
|
||||||
|
to: to,
|
||||||
|
errorMessage: msg.data.message,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,39 @@
|
||||||
|
import type { Component } from "svelte";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
type DialogType = "success" | "error" | "info" | "warning";
|
type DialogType = "success" | "error" | "info" | "warning";
|
||||||
|
|
||||||
export interface Dialog {
|
type BaseDialog = {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
message: string;
|
|
||||||
buttons: {
|
buttons: {
|
||||||
text: string;
|
text: string;
|
||||||
action: () => void;
|
action: () => void;
|
||||||
}[];
|
}[];
|
||||||
type: DialogType;
|
type: DialogType;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export type StringDialog = BaseDialog & {
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ComponentDialog<T = unknown> = BaseDialog & {
|
||||||
|
message: Component<DialogProps<T>>;
|
||||||
|
additional: T;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Dialog<T = unknown> = StringDialog | ComponentDialog<T>;
|
||||||
|
|
||||||
|
export type DialogProps<T = unknown> = {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
type: DialogType;
|
||||||
|
buttons: {
|
||||||
|
text: string;
|
||||||
|
action: () => void;
|
||||||
|
}[];
|
||||||
|
additional: T;
|
||||||
|
};
|
||||||
|
|
||||||
const dialogs = writable<Dialog[]>([]);
|
const dialogs = writable<Dialog[]>([]);
|
||||||
|
|
||||||
|
|
@ -19,13 +41,15 @@ let dialogId = 0;
|
||||||
|
|
||||||
function addDialog(
|
function addDialog(
|
||||||
title: string,
|
title: string,
|
||||||
message: string,
|
message: string | Component<DialogProps>,
|
||||||
buttons: Dialog["buttons"],
|
buttons: BaseDialog["buttons"],
|
||||||
type: DialogType,
|
type: DialogType,
|
||||||
) {
|
additional?: unknown,
|
||||||
|
): number {
|
||||||
const id = dialogId++;
|
const id = dialogId++;
|
||||||
|
|
||||||
const newDialog: Dialog = {
|
if (typeof message === "string") {
|
||||||
|
const newDialog: StringDialog = {
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
|
|
@ -33,6 +57,17 @@ function addDialog(
|
||||||
type,
|
type,
|
||||||
};
|
};
|
||||||
dialogs.update((currentDialogs) => [...currentDialogs, newDialog]);
|
dialogs.update((currentDialogs) => [...currentDialogs, newDialog]);
|
||||||
|
} else {
|
||||||
|
const newDialog: ComponentDialog = {
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
buttons,
|
||||||
|
type,
|
||||||
|
additional,
|
||||||
|
};
|
||||||
|
dialogs.update((currentDialogs) => [...currentDialogs, newDialog]);
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue