mirror of https://github.com/VERT-sh/VERT.git
feat: advanced settings dropdown
hide most conversion settings under a "advanced settings" dropdown
This commit is contained in:
parent
424ed6e5d6
commit
d5205666ff
|
|
@ -101,6 +101,7 @@
|
||||||
},
|
},
|
||||||
"conversion": {
|
"conversion": {
|
||||||
"title": "Conversion",
|
"title": "Conversion",
|
||||||
|
"advanced_settings": "Advanced settings",
|
||||||
"filename_format": "File name format",
|
"filename_format": "File name format",
|
||||||
"filename_description": "This will determine the name of the file on download, <b>not including the file extension.</b> You can put these following templates in the format, which will be replaced with the relevant information: <b>%name%</b> for the original file name, <b>%extension%</b> for the original file extension, and <b>%date%</b> for a date string of when the file was converted.",
|
"filename_description": "This will determine the name of the file on download, <b>not including the file extension.</b> You can put these following templates in the format, which will be replaced with the relevant information: <b>%name%</b> for the original file name, <b>%extension%</b> for the original file extension, and <b>%date%</b> for a date string of when the file was converted.",
|
||||||
"placeholder": "VERT_%name%",
|
"placeholder": "VERT_%name%",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import FancyTextInput from "$lib/components/functional/FancyInput.svelte";
|
import FancyTextInput from "$lib/components/functional/FancyInput.svelte";
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import { PauseIcon, PlayIcon, RefreshCwIcon } from "lucide-svelte";
|
import {
|
||||||
|
PauseIcon,
|
||||||
|
PlayIcon,
|
||||||
|
RefreshCwIcon,
|
||||||
|
ChevronDownIcon,
|
||||||
|
} from "lucide-svelte";
|
||||||
import type { ISettings } from "./index.svelte";
|
import type { ISettings } from "./index.svelte";
|
||||||
import {
|
import {
|
||||||
CONVERSION_BITRATES,
|
CONVERSION_BITRATES,
|
||||||
|
|
@ -15,8 +20,10 @@
|
||||||
import { effects } from "$lib/store/index.svelte";
|
import { effects } from "$lib/store/index.svelte";
|
||||||
import FormatDropdown from "$lib/components/functional/FormatDropdown.svelte";
|
import FormatDropdown from "$lib/components/functional/FormatDropdown.svelte";
|
||||||
import { categories } from "$lib/converters";
|
import { categories } from "$lib/converters";
|
||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
const { settings = $bindable() }: { settings: ISettings } = $props();
|
const { settings = $bindable() }: { settings: ISettings } = $props();
|
||||||
|
let showAdvanced = $state(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Panel class="flex flex-col gap-8 p-6">
|
<Panel class="flex flex-col gap-8 p-6">
|
||||||
|
|
@ -29,7 +36,7 @@
|
||||||
/>
|
/>
|
||||||
{m["settings.conversion.title"]()}
|
{m["settings.conversion.title"]()}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<p class="text-base font-bold">
|
<p class="text-base font-bold">
|
||||||
|
|
@ -47,198 +54,271 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<button
|
||||||
<p class="text-base font-bold">
|
onclick={() => (showAdvanced = !showAdvanced)}
|
||||||
{m["settings.conversion.default_format"]()}
|
class="bg-button flex items-center justify-between p-4 rounded-lg text-black dynadark:text-white w-full"
|
||||||
</p>
|
|
||||||
<p class="text-sm text-muted font-normal">
|
|
||||||
{m["settings.conversion.default_format_description"]()}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col gap-3 w-full">
|
|
||||||
<div class="flex gap-3 w-full">
|
|
||||||
<button
|
|
||||||
onclick={() => (settings.useDefaultFormat = true)}
|
|
||||||
class="btn {$effects
|
|
||||||
? ''
|
|
||||||
: '!scale-100'} {settings.useDefaultFormat
|
|
||||||
? 'selected'
|
|
||||||
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<PlayIcon size="24" class="inline-block mr-2" />
|
|
||||||
Enable
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onclick={() => (settings.useDefaultFormat = false)}
|
|
||||||
class="btn {$effects
|
|
||||||
? ''
|
|
||||||
: '!scale-100'} {settings.useDefaultFormat
|
|
||||||
? ''
|
|
||||||
: 'selected'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<PauseIcon size="24" class="inline-block mr-2" />
|
|
||||||
Disable
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid gap-3 grid-cols-2 md:grid-cols-4"
|
|
||||||
class:opacity-50={!settings.useDefaultFormat}
|
|
||||||
>
|
>
|
||||||
<div class="flex flex-col gap-2">
|
<span class="text-base font-bold"
|
||||||
<p class="text-sm font-bold">
|
>{m["settings.conversion.advanced_settings"]()}</span
|
||||||
{m["settings.conversion.default_format_image"]()}
|
>
|
||||||
</p>
|
<ChevronDownIcon
|
||||||
<FormatDropdown
|
size="20"
|
||||||
categories={{ image: categories.image }}
|
class={clsx("transition-transform duration-300", {
|
||||||
from={".png"}
|
"rotate-180": showAdvanced,
|
||||||
bind:selected={settings.defaultFormat.image}
|
})}
|
||||||
disabled={!settings.useDefaultFormat}
|
/>
|
||||||
/>
|
</button>
|
||||||
</div>
|
<div
|
||||||
<div class="flex flex-col gap-2">
|
class={clsx(
|
||||||
<p class="text-sm font-bold">
|
"flex flex-col gap-8 transition-all duration-300 ease-in-out",
|
||||||
{m["settings.conversion.default_format_audio"]()}
|
{"max-h-[2000px] opacity-100 overflow-visible": showAdvanced},
|
||||||
</p>
|
{"max-h-0 opacity-0 overflow-hidden -mb-4": !showAdvanced},
|
||||||
<FormatDropdown
|
)}
|
||||||
categories={{ audio: categories.audio }}
|
>
|
||||||
from={".mp3"}
|
<div class="flex flex-col gap-8">
|
||||||
bind:selected={settings.defaultFormat.audio}
|
<div class="flex flex-col gap-4">
|
||||||
disabled={!settings.useDefaultFormat}
|
<div class="flex flex-col gap-2">
|
||||||
/>
|
<p class="text-base font-bold">
|
||||||
</div>
|
{m["settings.conversion.default_format"]()}
|
||||||
<div class="flex flex-col gap-2">
|
</p>
|
||||||
<p class="text-sm font-bold">
|
<p class="text-sm text-muted font-normal">
|
||||||
{m["settings.conversion.default_format_video"]()}
|
{m[
|
||||||
</p>
|
"settings.conversion.default_format_description"
|
||||||
<FormatDropdown
|
]()}
|
||||||
categories={{ video: categories.video }}
|
</p>
|
||||||
from={".mp4"}
|
</div>
|
||||||
bind:selected={settings.defaultFormat.video}
|
<div class="flex flex-col gap-3 w-full">
|
||||||
disabled={!settings.useDefaultFormat}
|
<div class="flex gap-3 w-full">
|
||||||
/>
|
<button
|
||||||
</div>
|
onclick={() =>
|
||||||
<div class="flex flex-col gap-2">
|
(settings.useDefaultFormat = true)}
|
||||||
<p class="text-sm font-bold">
|
class="btn {$effects
|
||||||
{m["settings.conversion.default_format_document"]()}
|
? ''
|
||||||
</p>
|
: '!scale-100'} {settings.useDefaultFormat
|
||||||
<FormatDropdown
|
? 'selected'
|
||||||
categories={{ doc: categories.doc }}
|
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
from={".docx"}
|
>
|
||||||
bind:selected={settings.defaultFormat.document}
|
<PlayIcon
|
||||||
disabled={!settings.useDefaultFormat}
|
size="24"
|
||||||
/>
|
class="inline-block mr-2"
|
||||||
</div>
|
/>
|
||||||
</div>
|
Enable
|
||||||
</div>
|
</button>
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
<p class="text-base font-bold">
|
|
||||||
{m["settings.conversion.metadata"]()}
|
|
||||||
</p>
|
|
||||||
<p class="text-sm text-muted font-normal italic">
|
|
||||||
{m["settings.conversion.metadata_description"]()}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col gap-3 w-full">
|
|
||||||
<div class="flex gap-3 w-full">
|
|
||||||
<button
|
|
||||||
onclick={() => (settings.metadata = true)}
|
|
||||||
class="btn {$effects
|
|
||||||
? ''
|
|
||||||
: '!scale-100'} {settings.metadata
|
|
||||||
? 'selected'
|
|
||||||
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<PlayIcon size="24" class="inline-block mr-2" />
|
|
||||||
{m["settings.conversion.keep"]()}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onclick={() => (settings.metadata = false)}
|
onclick={() =>
|
||||||
class="btn {$effects
|
(settings.useDefaultFormat = false)}
|
||||||
? ''
|
class="btn {$effects
|
||||||
: '!scale-100'} {settings.metadata
|
? ''
|
||||||
? ''
|
: '!scale-100'} {settings.useDefaultFormat
|
||||||
: 'selected'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
? ''
|
||||||
>
|
: 'selected'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
<PauseIcon size="24" class="inline-block mr-2" />
|
>
|
||||||
{m["settings.conversion.remove"]()}
|
<PauseIcon
|
||||||
</button>
|
size="24"
|
||||||
</div>
|
class="inline-block mr-2"
|
||||||
</div>
|
/>
|
||||||
</div>
|
Disable
|
||||||
<div class="flex flex-col gap-4">
|
</button>
|
||||||
<div class="flex flex-col gap-2">
|
</div>
|
||||||
<p class="text-base font-bold">
|
</div>
|
||||||
{m["settings.conversion.quality"]()}
|
<div
|
||||||
</p>
|
class="grid gap-3 grid-cols-2 md:grid-cols-4"
|
||||||
<p class="text-sm text-muted font-normal">
|
class:opacity-50={!settings.useDefaultFormat}
|
||||||
{m["settings.conversion.quality_description"]()}
|
>
|
||||||
</p>
|
<div class="flex flex-col gap-2">
|
||||||
</div>
|
<p class="text-sm font-bold">
|
||||||
<div class="grid grid-cols-2 gap-3">
|
{m[
|
||||||
<div class="flex flex-col gap-2">
|
"settings.conversion.default_format_image"
|
||||||
<p class="text-sm font-bold">
|
]()}
|
||||||
{m["settings.conversion.quality_images"]()}
|
</p>
|
||||||
</p>
|
<FormatDropdown
|
||||||
<FancyInput
|
categories={{ image: categories.image }}
|
||||||
bind:value={
|
from={".png"}
|
||||||
settings.magickQuality as unknown as string
|
bind:selected={
|
||||||
}
|
settings.defaultFormat.image
|
||||||
type="number"
|
}
|
||||||
min={1}
|
disabled={!settings.useDefaultFormat}
|
||||||
max={100}
|
/>
|
||||||
placeholder={"100"}
|
</div>
|
||||||
extension={"%"}
|
<div class="flex flex-col gap-2">
|
||||||
/>
|
<p class="text-sm font-bold">
|
||||||
</div>
|
{m[
|
||||||
<div class="flex flex-col gap-2">
|
"settings.conversion.default_format_audio"
|
||||||
<p class="text-sm font-bold">
|
]()}
|
||||||
{m["settings.conversion.quality_audio"]()}
|
</p>
|
||||||
</p>
|
<FormatDropdown
|
||||||
<Dropdown
|
categories={{ audio: categories.audio }}
|
||||||
options={CONVERSION_BITRATES.map((b) =>
|
from={".mp3"}
|
||||||
b.toString(),
|
bind:selected={
|
||||||
)}
|
settings.defaultFormat.audio
|
||||||
selected={settings.ffmpegQuality.toString()}
|
}
|
||||||
onselect={(option: string) =>
|
disabled={!settings.useDefaultFormat}
|
||||||
(settings.ffmpegQuality =
|
/>
|
||||||
option as ConversionBitrate)}
|
</div>
|
||||||
settingsStyle
|
<div class="flex flex-col gap-2">
|
||||||
/>
|
<p class="text-sm font-bold">
|
||||||
</div>
|
{m[
|
||||||
</div>
|
"settings.conversion.default_format_video"
|
||||||
<div class="grid grid-cols-2 gap-3">
|
]()}
|
||||||
<div class="flex flex-col gap-2">
|
</p>
|
||||||
<p class="text-sm font-bold">
|
<FormatDropdown
|
||||||
{m["settings.conversion.rate"]()}
|
categories={{ video: categories.video }}
|
||||||
</p>
|
from={".mp4"}
|
||||||
<Dropdown
|
bind:selected={
|
||||||
options={SAMPLE_RATES.map((r) => r.toString())}
|
settings.defaultFormat.video
|
||||||
selected={settings.ffmpegSampleRate.toString()}
|
}
|
||||||
onselect={(option: string) => {
|
disabled={!settings.useDefaultFormat}
|
||||||
settings.ffmpegSampleRate =
|
/>
|
||||||
option as SampleRate;
|
</div>
|
||||||
}}
|
<div class="flex flex-col gap-2">
|
||||||
settingsStyle
|
<p class="text-sm font-bold">
|
||||||
/>
|
{m[
|
||||||
</div>
|
"settings.conversion.default_format_document"
|
||||||
<div class="flex flex-col gap-2">
|
]()}
|
||||||
<p class="text-sm font-bold select-none">
|
</p>
|
||||||
|
<FormatDropdown
|
||||||
</p>
|
categories={{ doc: categories.doc }}
|
||||||
<FancyInput
|
from={".docx"}
|
||||||
bind:value={
|
bind:selected={
|
||||||
settings.ffmpegCustomSampleRate as unknown as string
|
settings.defaultFormat.document
|
||||||
}
|
}
|
||||||
type="number"
|
disabled={!settings.useDefaultFormat}
|
||||||
min={1}
|
/>
|
||||||
placeholder={"44100"}
|
</div>
|
||||||
extension={"Hz"}
|
</div>
|
||||||
disabled={settings.ffmpegSampleRate !== "custom"}
|
</div>
|
||||||
/>
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.conversion.metadata"]()}
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="text-sm text-muted font-normal italic"
|
||||||
|
>
|
||||||
|
{m[
|
||||||
|
"settings.conversion.metadata_description"
|
||||||
|
]()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-3 w-full">
|
||||||
|
<div class="flex gap-3 w-full">
|
||||||
|
<button
|
||||||
|
onclick={() =>
|
||||||
|
(settings.metadata = true)}
|
||||||
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} {settings.metadata
|
||||||
|
? 'selected'
|
||||||
|
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<PlayIcon
|
||||||
|
size="24"
|
||||||
|
class="inline-block mr-2"
|
||||||
|
/>
|
||||||
|
{m["settings.conversion.keep"]()}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onclick={() =>
|
||||||
|
(settings.metadata = false)}
|
||||||
|
class="btn {$effects
|
||||||
|
? ''
|
||||||
|
: '!scale-100'} {settings.metadata
|
||||||
|
? ''
|
||||||
|
: 'selected'} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<PauseIcon
|
||||||
|
size="24"
|
||||||
|
class="inline-block mr-2"
|
||||||
|
/>
|
||||||
|
{m["settings.conversion.remove"]()}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-base font-bold">
|
||||||
|
{m["settings.conversion.quality"]()}
|
||||||
|
</p>
|
||||||
|
<p class="text-sm text-muted font-normal">
|
||||||
|
{m[
|
||||||
|
"settings.conversion.quality_description"
|
||||||
|
]()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold">
|
||||||
|
{m[
|
||||||
|
"settings.conversion.quality_images"
|
||||||
|
]()}
|
||||||
|
</p>
|
||||||
|
<FancyInput
|
||||||
|
bind:value={
|
||||||
|
settings.magickQuality as unknown as string
|
||||||
|
}
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={100}
|
||||||
|
placeholder={"100"}
|
||||||
|
extension={"%"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold">
|
||||||
|
{m[
|
||||||
|
"settings.conversion.quality_audio"
|
||||||
|
]()}
|
||||||
|
</p>
|
||||||
|
<Dropdown
|
||||||
|
options={CONVERSION_BITRATES.map((b) =>
|
||||||
|
b.toString(),
|
||||||
|
)}
|
||||||
|
selected={settings.ffmpegQuality.toString()}
|
||||||
|
onselect={(option: string) =>
|
||||||
|
(settings.ffmpegQuality =
|
||||||
|
option as ConversionBitrate)}
|
||||||
|
settingsStyle
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold">
|
||||||
|
{m["settings.conversion.rate"]()}
|
||||||
|
</p>
|
||||||
|
<Dropdown
|
||||||
|
options={SAMPLE_RATES.map((r) =>
|
||||||
|
r.toString(),
|
||||||
|
)}
|
||||||
|
selected={settings.ffmpegSampleRate.toString()}
|
||||||
|
onselect={(option: string) => {
|
||||||
|
settings.ffmpegSampleRate =
|
||||||
|
option as SampleRate;
|
||||||
|
}}
|
||||||
|
settingsStyle
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm font-bold select-none">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<FancyInput
|
||||||
|
bind:value={
|
||||||
|
settings.ffmpegCustomSampleRate as unknown as string
|
||||||
|
}
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
placeholder={"44100"}
|
||||||
|
extension={"Hz"}
|
||||||
|
disabled={settings.ffmpegSampleRate !==
|
||||||
|
"custom"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue