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": {
|
||||
"title": "Conversion",
|
||||
"advanced_settings": "Advanced settings",
|
||||
"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.",
|
||||
"placeholder": "VERT_%name%",
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
<script lang="ts">
|
||||
import FancyTextInput from "$lib/components/functional/FancyInput.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 {
|
||||
CONVERSION_BITRATES,
|
||||
|
@ -15,8 +20,10 @@
|
|||
import { effects } from "$lib/store/index.svelte";
|
||||
import FormatDropdown from "$lib/components/functional/FormatDropdown.svelte";
|
||||
import { categories } from "$lib/converters";
|
||||
import clsx from "clsx";
|
||||
|
||||
const { settings = $bindable() }: { settings: ISettings } = $props();
|
||||
let showAdvanced = $state(false);
|
||||
</script>
|
||||
|
||||
<Panel class="flex flex-col gap-8 p-6">
|
||||
|
@ -29,7 +36,7 @@
|
|||
/>
|
||||
{m["settings.conversion.title"]()}
|
||||
</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-2">
|
||||
<p class="text-base font-bold">
|
||||
|
@ -47,198 +54,271 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-base font-bold">
|
||||
{m["settings.conversion.default_format"]()}
|
||||
</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}
|
||||
<button
|
||||
onclick={() => (showAdvanced = !showAdvanced)}
|
||||
class="bg-button flex items-center justify-between p-4 rounded-lg text-black dynadark:text-white w-full"
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m["settings.conversion.default_format_image"]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ image: categories.image }}
|
||||
from={".png"}
|
||||
bind:selected={settings.defaultFormat.image}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m["settings.conversion.default_format_audio"]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ audio: categories.audio }}
|
||||
from={".mp3"}
|
||||
bind:selected={settings.defaultFormat.audio}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m["settings.conversion.default_format_video"]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ video: categories.video }}
|
||||
from={".mp4"}
|
||||
bind:selected={settings.defaultFormat.video}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m["settings.conversion.default_format_document"]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ doc: categories.doc }}
|
||||
from={".docx"}
|
||||
bind:selected={settings.defaultFormat.document}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</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.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>
|
||||
<span class="text-base font-bold"
|
||||
>{m["settings.conversion.advanced_settings"]()}</span
|
||||
>
|
||||
<ChevronDownIcon
|
||||
size="20"
|
||||
class={clsx("transition-transform duration-300", {
|
||||
"rotate-180": showAdvanced,
|
||||
})}
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class={clsx(
|
||||
"flex flex-col gap-8 transition-all duration-300 ease-in-out",
|
||||
{"max-h-[2000px] opacity-100 overflow-visible": showAdvanced},
|
||||
{"max-h-0 opacity-0 overflow-hidden -mb-4": !showAdvanced},
|
||||
)}
|
||||
>
|
||||
<div class="flex flex-col gap-8">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-base font-bold">
|
||||
{m["settings.conversion.default_format"]()}
|
||||
</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.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"}
|
||||
/>
|
||||
<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">
|
||||
<p class="text-sm font-bold">
|
||||
{m[
|
||||
"settings.conversion.default_format_image"
|
||||
]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ image: categories.image }}
|
||||
from={".png"}
|
||||
bind:selected={
|
||||
settings.defaultFormat.image
|
||||
}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m[
|
||||
"settings.conversion.default_format_audio"
|
||||
]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ audio: categories.audio }}
|
||||
from={".mp3"}
|
||||
bind:selected={
|
||||
settings.defaultFormat.audio
|
||||
}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m[
|
||||
"settings.conversion.default_format_video"
|
||||
]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ video: categories.video }}
|
||||
from={".mp4"}
|
||||
bind:selected={
|
||||
settings.defaultFormat.video
|
||||
}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-sm font-bold">
|
||||
{m[
|
||||
"settings.conversion.default_format_document"
|
||||
]()}
|
||||
</p>
|
||||
<FormatDropdown
|
||||
categories={{ doc: categories.doc }}
|
||||
from={".docx"}
|
||||
bind:selected={
|
||||
settings.defaultFormat.document
|
||||
}
|
||||
disabled={!settings.useDefaultFormat}
|
||||
/>
|
||||
</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.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>
|
||||
|
|
Loading…
Reference in New Issue