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_no": "Don't submit",
|
||||
"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",
|
||||
"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.",
|
||||
|
|
|
|||
|
|
@ -3,19 +3,13 @@
|
|||
import { removeDialog } from "$lib/store/DialogProvider";
|
||||
import { BanIcon, CheckIcon, InfoIcon, TriangleAlert } from "lucide-svelte";
|
||||
import { quintOut } from "svelte/easing";
|
||||
import type { Dialog as DialogType } from "$lib/store/DialogProvider";
|
||||
|
||||
type Props = {
|
||||
id: number;
|
||||
title: string;
|
||||
message: string;
|
||||
buttons: {
|
||||
text: string;
|
||||
action: () => void;
|
||||
}[];
|
||||
type: "success" | "error" | "info" | "warning";
|
||||
};
|
||||
type Props = DialogType;
|
||||
|
||||
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 = {
|
||||
success: "purple",
|
||||
|
|
@ -59,7 +53,14 @@
|
|||
</div>
|
||||
</div>
|
||||
<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 class="flex flex-row items-center gap-4 w-full">
|
||||
{#each buttons as { text, action }, i}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
export interface VertdErrorProps {
|
||||
jobId: string;
|
||||
auth: string;
|
||||
from?: string;
|
||||
to?: string;
|
||||
errorMessage?: string;
|
||||
fileName?: string;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -10,6 +14,8 @@
|
|||
|
||||
import { m } from "$lib/paraglide/messages";
|
||||
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();
|
||||
|
||||
|
|
@ -52,22 +58,50 @@
|
|||
|
||||
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>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<p class="text-black">{m["convert.errors.vertd_generic_body"]()}</p>
|
||||
<div class="flex gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<button
|
||||
onclick={submit}
|
||||
class="btn rounded-lg h-fit py-2 w-full bg-accent-red-alt text-white"
|
||||
onclick={showDetails}
|
||||
class="btn rounded-lg h-fit py-2 w-full bg-accent-blue text-black"
|
||||
disabled={submitting}
|
||||
>{m["convert.errors.vertd_generic_yes"]()}</button
|
||||
>
|
||||
<button
|
||||
onclick={remove}
|
||||
class="btn rounded-lg h-fit py-2 w-full"
|
||||
disabled={submitting}
|
||||
>{m["convert.errors.vertd_generic_no"]()}</button
|
||||
>View Details Submitted</button
|
||||
>
|
||||
<div class="flex gap-4">
|
||||
<button
|
||||
onclick={submit}
|
||||
class="btn rounded-lg h-fit py-2 w-full bg-accent-red-alt text-white"
|
||||
disabled={submitting}
|
||||
>{m["convert.errors.vertd_generic_yes"]()}</button
|
||||
>
|
||||
<button
|
||||
onclick={remove}
|
||||
class="btn rounded-lg h-fit py-2 w-full"
|
||||
disabled={submitting}
|
||||
>{m["convert.errors.vertd_generic_no"]()}</button
|
||||
>
|
||||
</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,
|
||||
}}
|
||||
>
|
||||
{#each dialogList as { id, title, message, buttons, type }, i}
|
||||
{#each dialogList as dialog, i}
|
||||
{#if i === 0}
|
||||
<Dialog {id} {title} {message} {buttons} {type} />
|
||||
<Dialog {...dialog} />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -377,6 +377,9 @@ export class VertdConverter extends Converter {
|
|||
additional: {
|
||||
jobId: uploadRes.id,
|
||||
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";
|
||||
|
||||
type DialogType = "success" | "error" | "info" | "warning";
|
||||
|
||||
export interface Dialog {
|
||||
type BaseDialog = {
|
||||
id: number;
|
||||
title: string;
|
||||
message: string;
|
||||
buttons: {
|
||||
text: string;
|
||||
action: () => void;
|
||||
}[];
|
||||
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[]>([]);
|
||||
|
||||
|
|
@ -19,20 +41,33 @@ let dialogId = 0;
|
|||
|
||||
function addDialog(
|
||||
title: string,
|
||||
message: string,
|
||||
buttons: Dialog["buttons"],
|
||||
message: string | Component<DialogProps>,
|
||||
buttons: BaseDialog["buttons"],
|
||||
type: DialogType,
|
||||
) {
|
||||
additional?: unknown,
|
||||
): number {
|
||||
const id = dialogId++;
|
||||
|
||||
const newDialog: Dialog = {
|
||||
id,
|
||||
title,
|
||||
message,
|
||||
buttons,
|
||||
type,
|
||||
};
|
||||
dialogs.update((currentDialogs) => [...currentDialogs, newDialog]);
|
||||
if (typeof message === "string") {
|
||||
const newDialog: StringDialog = {
|
||||
id,
|
||||
title,
|
||||
message,
|
||||
buttons,
|
||||
type,
|
||||
};
|
||||
dialogs.update((currentDialogs) => [...currentDialogs, newDialog]);
|
||||
} else {
|
||||
const newDialog: ComponentDialog = {
|
||||
id,
|
||||
title,
|
||||
message,
|
||||
buttons,
|
||||
type,
|
||||
additional,
|
||||
};
|
||||
dialogs.update((currentDialogs) => [...currentDialogs, newDialog]);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue