fix: proper dropdown option labelling

This commit is contained in:
Maya 2026-02-19 18:45:41 +03:00
parent 1c65d37963
commit e9db7a9568
No known key found for this signature in database
8 changed files with 108 additions and 44 deletions

View File

@ -128,8 +128,8 @@
},
"common": {
"metadata": "Metadata",
"auto": "auto",
"custom": "custom"
"auto": "Auto",
"custom": "Custom"
}
},
"tooltips": {

View File

@ -5,7 +5,7 @@
import { quintOut } from "svelte/easing";
type Props = {
options: string[];
options: string[] | { value: string; label: string }[];
selected?: string;
onselect?: (option: string) => void;
disabled?: boolean;
@ -14,7 +14,9 @@
let {
options,
selected = $bindable(options[0]),
selected = $bindable(
typeof options[0] === "string" ? options[0] : options[0].value,
),
onselect,
disabled,
settingsStyle,
@ -29,12 +31,21 @@
open = !open;
};
const select = (option: string) => {
const oldIndex = options.indexOf(selected || "");
const newIndex = options.indexOf(option);
const getValue = (option: string | { value: string; label: string }) =>
typeof option === "string" ? option : option.value;
const getLabel = (option: string | { value: string; label: string }) =>
typeof option === "string" ? option : option.label;
const select = (option: string | { value: string; label: string }) => {
const selectedValue = getValue(option);
const oldIndex = options.findIndex((opt) => getValue(opt) === selected);
const newIndex = options.findIndex(
(opt) => getValue(opt) === selectedValue,
);
isUp = oldIndex > newIndex;
selected = option;
onselect?.(option);
selected = selectedValue;
onselect?.(selectedValue);
toggle();
};
@ -89,14 +100,17 @@
? 'font-normal'
: 'font-medium'}"
>
{selected}
{getLabel(
options.find((opt) => getValue(opt) === selected) ||
selected,
)}
</p>
{/key}
{#each options as option}
<p
class="col-start-1 row-start-1 invisible pointer-events-none"
>
{option}
{getLabel(option)}
</p>
{/each}
</div>
@ -121,7 +135,7 @@
class="w-full p-2 px-4 text-left hover:bg-panel"
onclick={() => select(option)}
>
{option}
{getLabel(option)}
</button>
{/each}
</div>

View File

@ -104,7 +104,13 @@
{#if setting.type === "select"}
<Dropdown
options={setting.options?.map(
(opt) => opt.value,
(opt) =>
typeof opt === "string"
? {
value: opt,
label: opt,
}
: opt,
) || []}
selected={settings[setting.key] ??
file.conversionSettings[

View File

@ -121,7 +121,10 @@ export class FFmpegConverter extends Converter {
default: global.ffmpegQuality,
options: CONVERSION_BITRATES.map((b) => ({
value: b,
label: b,
label:
b === "auto" || b === "custom"
? m[`convert.settings.common.${b}`]()
: `${b} kbps`,
})),
hasCustomInput: true,
customInputKey: "customBitrate",
@ -138,7 +141,10 @@ export class FFmpegConverter extends Converter {
: global.ffmpegSampleRate,
options: SAMPLE_RATES.map((r) => ({
value: r,
label: r,
label:
r === "auto" || r === "custom"
? m[`convert.settings.common.${r}`]()
: `${r} Hz`,
})),
hasCustomInput: true,
customInputKey: "customSampleRate",
@ -179,11 +185,9 @@ export class FFmpegConverter extends Converter {
return [bitrate, sampleRate, tracks, channels, metadata];
}
public async getDefaultSettings(
input: VertFile,
): Promise<ConversionSettings> {
public async getDefaultSettings(): Promise<ConversionSettings> {
const defaults: ConversionSettings = {};
const settings = await this.getAvailableSettings(input);
const settings = await this.getAvailableSettings();
settings.forEach((setting) => {
defaults[setting.key] = setting.default;
});
@ -200,7 +204,7 @@ export class FFmpegConverter extends Converter {
const conversionSettings =
Object.keys(settings).length > 0
? settings
: await this.getDefaultSettings(input); // use defaults if not provided
: await this.getDefaultSettings(); // use defaults if not provided
const isAlac = to === ".alac";
if (isAlac) to = ".m4a";

View File

@ -136,13 +136,12 @@ export class MagickConverter extends Converter {
label: m["convert.settings.image.depth"](),
type: "select",
default: "auto",
// somehow implement custom option
options: [
{ value: "auto", label: "Auto" },
{ value: "custom", label: "Custom" },
{ value: "8", label: "8-bit" },
{ value: "16", label: "16-bit" },
{ value: "32", label: "32-bit" },
{ value: "custom", label: "Custom" },
],
};
@ -166,8 +165,12 @@ export class MagickConverter extends Converter {
};
// TODO: check other formats for transparency support
const fromJpeg = input.from === ".jpg" || input.from === ".jpeg" || input.from === ".jfif";
const toJpeg = input.to === ".jpg" || input.to === ".jpeg" || input.to === ".jfif";
const fromJpeg =
input.from === ".jpg" ||
input.from === ".jpeg" ||
input.from === ".jfif";
const toJpeg =
input.to === ".jpg" || input.to === ".jpeg" || input.to === ".jfif";
const transparency: SettingDefinition = {
key: "transparency",
label: m["convert.settings.image.transparency"](),
@ -188,9 +191,11 @@ export class MagickConverter extends Converter {
return [quality, depth, colorSpace, transparency, metadata];
}
public async getDefaultSettings(): Promise<ConversionSettings> {
public async getDefaultSettings(
input: VertFile,
): Promise<ConversionSettings> {
const defaults: ConversionSettings = {};
const settings = await this.getAvailableSettings();
const settings = await this.getAvailableSettings(input);
settings.forEach((setting) => {
defaults[setting.key] = setting.default;
});
@ -272,7 +277,7 @@ export class MagickConverter extends Converter {
const conversionSettings = JSON.stringify(
Object.keys(settings).length > 0
? settings // user-provided settings
: await this.getDefaultSettings(), // use defaults if not provided
: await this.getDefaultSettings(input), // use defaults if not provided
);
const convertMsg: WorkerMessage = {
type: "convert",

View File

@ -61,8 +61,8 @@ export class PandocConverter extends Converter {
from: file.from,
to,
},
compression: null,
id: file.id,
conversionSettings: "", // no settings for pandoc yet
};
worker.postMessage(convertMsg);
const result = await waitForMessage(worker);

View File

@ -483,7 +483,12 @@ export class VertdConverter extends Converter {
default: "auto",
options: CONVERSION_BITRATES.map((b) => ({
value: b,
label: b,
label:
b === "auto"
? m["convert.settings.common.auto"]()
: b === "custom"
? m["convert.settings.common.custom"]()
: `${b} kbps`,
})),
hasCustomInput: true,
customInputKey: "customBitrate",
@ -497,7 +502,12 @@ export class VertdConverter extends Converter {
default: "auto",
options: SAMPLE_RATES.map((r) => ({
value: r,
label: r,
label:
r === "auto"
? m["convert.settings.common.auto"]()
: r === "custom"
? m["convert.settings.common.custom"]()
: `${r} Hz`,
})),
hasCustomInput: true,
customInputKey: "customSampleRate",

View File

@ -43,7 +43,9 @@
{m["settings.conversion.filename_format"]()}
</p>
<p class="text-sm text-muted font-normal">
{@html sanitize(m["settings.conversion.filename_description"]())}
{@html sanitize(
m["settings.conversion.filename_description"](),
)}
</p>
</div>
<FancyTextInput
@ -71,8 +73,14 @@
<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},
{
"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">
@ -102,7 +110,9 @@
size="24"
class="inline-block mr-2"
/>
{m["settings.conversion.default_format_enable"]()}
{m[
"settings.conversion.default_format_enable"
]()}
</button>
<button
@ -118,7 +128,9 @@
size="24"
class="inline-block mr-2"
/>
{m["settings.conversion.default_format_disable"]()}
{m[
"settings.conversion.default_format_disable"
]()}
</button>
</div>
</div>
@ -193,9 +205,7 @@
<p class="text-base font-bold">
{m["settings.conversion.metadata"]()}
</p>
<p
class="text-sm text-muted font-normal"
>
<p class="text-sm text-muted font-normal">
{m[
"settings.conversion.metadata_description"
]()}
@ -273,8 +283,17 @@
]()}
</p>
<Dropdown
options={CONVERSION_BITRATES.map((b) =>
b.toString(),
options={CONVERSION_BITRATES.map(
(b) => ({
value: b.toString(),
label:
b === "auto" ||
b === "custom"
? m[
`convert.settings.common.${b}`
]()
: `${b} kbps`,
}),
)}
selected={settings.ffmpegQuality.toString()}
onselect={(option: string) =>
@ -290,13 +309,19 @@
{m["settings.conversion.rate"]()}
</p>
<Dropdown
options={SAMPLE_RATES.map((r) =>
r.toString(),
)}
options={SAMPLE_RATES.map((r) => ({
value: r.toString(),
label:
r === "auto" || r === "custom"
? m[
`convert.settings.common.${r}`
]()
: `${r} Hz`,
}))}
selected={settings.ffmpegSampleRate.toString()}
onselect={(option: string) => {
settings.ffmpegSampleRate =
option as SampleRate;
option as SampleRate as string;
}}
settingsStyle
/>