From e9db7a9568cfb73ca50b284a983a1d4cc87042f9 Mon Sep 17 00:00:00 2001
From: Maya
Date: Thu, 19 Feb 2026 18:45:41 +0300
Subject: [PATCH] fix: proper dropdown option labelling
---
messages/en.json | 4 +-
src/lib/components/functional/Dropdown.svelte | 34 ++++++++----
.../functional/SettingsModal.svelte | 8 ++-
src/lib/converters/ffmpeg.svelte.ts | 18 ++++---
src/lib/converters/magick.svelte.ts | 19 ++++---
src/lib/converters/pandoc.svelte.ts | 2 +-
src/lib/converters/vertd.svelte.ts | 14 ++++-
src/lib/sections/settings/Conversion.svelte | 53 ++++++++++++++-----
8 files changed, 108 insertions(+), 44 deletions(-)
diff --git a/messages/en.json b/messages/en.json
index 6009e9c..fc2e363 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -128,8 +128,8 @@
},
"common": {
"metadata": "Metadata",
- "auto": "auto",
- "custom": "custom"
+ "auto": "Auto",
+ "custom": "Custom"
}
},
"tooltips": {
diff --git a/src/lib/components/functional/Dropdown.svelte b/src/lib/components/functional/Dropdown.svelte
index 293a1f3..c6205df 100644
--- a/src/lib/components/functional/Dropdown.svelte
+++ b/src/lib/components/functional/Dropdown.svelte
@@ -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,
+ )}
{/key}
{#each options as option}
- {option}
+ {getLabel(option)}
{/each}
@@ -121,7 +135,7 @@
class="w-full p-2 px-4 text-left hover:bg-panel"
onclick={() => select(option)}
>
- {option}
+ {getLabel(option)}
{/each}
diff --git a/src/lib/components/functional/SettingsModal.svelte b/src/lib/components/functional/SettingsModal.svelte
index 6052d54..dfc32a6 100644
--- a/src/lib/components/functional/SettingsModal.svelte
+++ b/src/lib/components/functional/SettingsModal.svelte
@@ -104,7 +104,13 @@
{#if setting.type === "select"}
opt.value,
+ (opt) =>
+ typeof opt === "string"
+ ? {
+ value: opt,
+ label: opt,
+ }
+ : opt,
) || []}
selected={settings[setting.key] ??
file.conversionSettings[
diff --git a/src/lib/converters/ffmpeg.svelte.ts b/src/lib/converters/ffmpeg.svelte.ts
index 9d7baad..c7ea958 100644
--- a/src/lib/converters/ffmpeg.svelte.ts
+++ b/src/lib/converters/ffmpeg.svelte.ts
@@ -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 {
+ public async getDefaultSettings(): Promise {
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";
diff --git a/src/lib/converters/magick.svelte.ts b/src/lib/converters/magick.svelte.ts
index 3437774..17d4a57 100644
--- a/src/lib/converters/magick.svelte.ts
+++ b/src/lib/converters/magick.svelte.ts
@@ -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 {
+ public async getDefaultSettings(
+ input: VertFile,
+ ): Promise {
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",
diff --git a/src/lib/converters/pandoc.svelte.ts b/src/lib/converters/pandoc.svelte.ts
index 6dfe84d..e447088 100644
--- a/src/lib/converters/pandoc.svelte.ts
+++ b/src/lib/converters/pandoc.svelte.ts
@@ -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);
diff --git a/src/lib/converters/vertd.svelte.ts b/src/lib/converters/vertd.svelte.ts
index 5792f2f..8cad8d7 100644
--- a/src/lib/converters/vertd.svelte.ts
+++ b/src/lib/converters/vertd.svelte.ts
@@ -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",
diff --git a/src/lib/sections/settings/Conversion.svelte b/src/lib/sections/settings/Conversion.svelte
index e959839..1e00f86 100644
--- a/src/lib/sections/settings/Conversion.svelte
+++ b/src/lib/sections/settings/Conversion.svelte
@@ -43,7 +43,9 @@
{m["settings.conversion.filename_format"]()}
- {@html sanitize(m["settings.conversion.filename_description"]())}
+ {@html sanitize(
+ m["settings.conversion.filename_description"](),
+ )}
@@ -102,7 +110,9 @@
size="24"
class="inline-block mr-2"
/>
- {m["settings.conversion.default_format_enable"]()}
+ {m[
+ "settings.conversion.default_format_enable"
+ ]()}
- {m["settings.conversion.default_format_disable"]()}
+ {m[
+ "settings.conversion.default_format_disable"
+ ]()}
@@ -193,9 +205,7 @@
{m["settings.conversion.metadata"]()}
-
+
{m[
"settings.conversion.metadata_description"
]()}
@@ -273,8 +283,17 @@
]()}
- 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"]()}
- 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
/>