feat: advanced settings dropdown

hide most conversion settings under a "advanced settings" dropdown
This commit is contained in:
Maya 2025-09-22 15:35:15 +03:00
parent 424ed6e5d6
commit d5205666ff
No known key found for this signature in database
2 changed files with 273 additions and 192 deletions

View File

@ -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%",

View File

@ -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">
@ -46,38 +53,71 @@
type="text" type="text"
/> />
</div> </div>
<div class="flex flex-col gap-4">
<button
onclick={() => (showAdvanced = !showAdvanced)}
class="bg-button flex items-center justify-between p-4 rounded-lg text-black dynadark:text-white w-full"
>
<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-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">
{m["settings.conversion.default_format"]()} {m["settings.conversion.default_format"]()}
</p> </p>
<p class="text-sm text-muted font-normal"> <p class="text-sm text-muted font-normal">
{m["settings.conversion.default_format_description"]()} {m[
"settings.conversion.default_format_description"
]()}
</p> </p>
</div> </div>
<div class="flex flex-col gap-3 w-full"> <div class="flex flex-col gap-3 w-full">
<div class="flex gap-3 w-full"> <div class="flex gap-3 w-full">
<button <button
onclick={() => (settings.useDefaultFormat = true)} onclick={() =>
(settings.useDefaultFormat = true)}
class="btn {$effects class="btn {$effects
? '' ? ''
: '!scale-100'} {settings.useDefaultFormat : '!scale-100'} {settings.useDefaultFormat
? 'selected' ? 'selected'
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center" : ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
> >
<PlayIcon size="24" class="inline-block mr-2" /> <PlayIcon
size="24"
class="inline-block mr-2"
/>
Enable Enable
</button> </button>
<button <button
onclick={() => (settings.useDefaultFormat = false)} onclick={() =>
(settings.useDefaultFormat = false)}
class="btn {$effects class="btn {$effects
? '' ? ''
: '!scale-100'} {settings.useDefaultFormat : '!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" /> <PauseIcon
size="24"
class="inline-block mr-2"
/>
Disable Disable
</button> </button>
</div> </div>
@ -88,45 +128,61 @@
> >
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-sm font-bold"> <p class="text-sm font-bold">
{m["settings.conversion.default_format_image"]()} {m[
"settings.conversion.default_format_image"
]()}
</p> </p>
<FormatDropdown <FormatDropdown
categories={{ image: categories.image }} categories={{ image: categories.image }}
from={".png"} from={".png"}
bind:selected={settings.defaultFormat.image} bind:selected={
settings.defaultFormat.image
}
disabled={!settings.useDefaultFormat} disabled={!settings.useDefaultFormat}
/> />
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-sm font-bold"> <p class="text-sm font-bold">
{m["settings.conversion.default_format_audio"]()} {m[
"settings.conversion.default_format_audio"
]()}
</p> </p>
<FormatDropdown <FormatDropdown
categories={{ audio: categories.audio }} categories={{ audio: categories.audio }}
from={".mp3"} from={".mp3"}
bind:selected={settings.defaultFormat.audio} bind:selected={
settings.defaultFormat.audio
}
disabled={!settings.useDefaultFormat} disabled={!settings.useDefaultFormat}
/> />
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-sm font-bold"> <p class="text-sm font-bold">
{m["settings.conversion.default_format_video"]()} {m[
"settings.conversion.default_format_video"
]()}
</p> </p>
<FormatDropdown <FormatDropdown
categories={{ video: categories.video }} categories={{ video: categories.video }}
from={".mp4"} from={".mp4"}
bind:selected={settings.defaultFormat.video} bind:selected={
settings.defaultFormat.video
}
disabled={!settings.useDefaultFormat} disabled={!settings.useDefaultFormat}
/> />
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-sm font-bold"> <p class="text-sm font-bold">
{m["settings.conversion.default_format_document"]()} {m[
"settings.conversion.default_format_document"
]()}
</p> </p>
<FormatDropdown <FormatDropdown
categories={{ doc: categories.doc }} categories={{ doc: categories.doc }}
from={".docx"} from={".docx"}
bind:selected={settings.defaultFormat.document} bind:selected={
settings.defaultFormat.document
}
disabled={!settings.useDefaultFormat} disabled={!settings.useDefaultFormat}
/> />
</div> </div>
@ -137,33 +193,45 @@
<p class="text-base font-bold"> <p class="text-base font-bold">
{m["settings.conversion.metadata"]()} {m["settings.conversion.metadata"]()}
</p> </p>
<p class="text-sm text-muted font-normal italic"> <p
{m["settings.conversion.metadata_description"]()} class="text-sm text-muted font-normal italic"
>
{m[
"settings.conversion.metadata_description"
]()}
</p> </p>
</div> </div>
<div class="flex flex-col gap-3 w-full"> <div class="flex flex-col gap-3 w-full">
<div class="flex gap-3 w-full"> <div class="flex gap-3 w-full">
<button <button
onclick={() => (settings.metadata = true)} onclick={() =>
(settings.metadata = true)}
class="btn {$effects class="btn {$effects
? '' ? ''
: '!scale-100'} {settings.metadata : '!scale-100'} {settings.metadata
? 'selected' ? 'selected'
: ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center" : ''} flex-1 p-4 rounded-lg text-black dynadark:text-white flex items-center justify-center"
> >
<PlayIcon size="24" class="inline-block mr-2" /> <PlayIcon
size="24"
class="inline-block mr-2"
/>
{m["settings.conversion.keep"]()} {m["settings.conversion.keep"]()}
</button> </button>
<button <button
onclick={() => (settings.metadata = false)} onclick={() =>
(settings.metadata = false)}
class="btn {$effects class="btn {$effects
? '' ? ''
: '!scale-100'} {settings.metadata : '!scale-100'} {settings.metadata
? '' ? ''
: '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" /> <PauseIcon
size="24"
class="inline-block mr-2"
/>
{m["settings.conversion.remove"]()} {m["settings.conversion.remove"]()}
</button> </button>
</div> </div>
@ -175,13 +243,17 @@
{m["settings.conversion.quality"]()} {m["settings.conversion.quality"]()}
</p> </p>
<p class="text-sm text-muted font-normal"> <p class="text-sm text-muted font-normal">
{m["settings.conversion.quality_description"]()} {m[
"settings.conversion.quality_description"
]()}
</p> </p>
</div> </div>
<div class="grid grid-cols-2 gap-3"> <div class="grid grid-cols-2 gap-3">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-sm font-bold"> <p class="text-sm font-bold">
{m["settings.conversion.quality_images"]()} {m[
"settings.conversion.quality_images"
]()}
</p> </p>
<FancyInput <FancyInput
bind:value={ bind:value={
@ -196,7 +268,9 @@
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-sm font-bold"> <p class="text-sm font-bold">
{m["settings.conversion.quality_audio"]()} {m[
"settings.conversion.quality_audio"
]()}
</p> </p>
<Dropdown <Dropdown
options={CONVERSION_BITRATES.map((b) => options={CONVERSION_BITRATES.map((b) =>
@ -216,7 +290,9 @@
{m["settings.conversion.rate"]()} {m["settings.conversion.rate"]()}
</p> </p>
<Dropdown <Dropdown
options={SAMPLE_RATES.map((r) => r.toString())} options={SAMPLE_RATES.map((r) =>
r.toString(),
)}
selected={settings.ffmpegSampleRate.toString()} selected={settings.ffmpegSampleRate.toString()}
onselect={(option: string) => { onselect={(option: string) => {
settings.ffmpegSampleRate = settings.ffmpegSampleRate =
@ -237,11 +313,15 @@
min={1} min={1}
placeholder={"44100"} placeholder={"44100"}
extension={"Hz"} extension={"Hz"}
disabled={settings.ffmpegSampleRate !== "custom"} disabled={settings.ffmpegSampleRate !==
"custom"}
/> />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
</div></Panel </div></Panel
> >