From cc6a08eda9ecbc34654df7616abbefebc8e5f3e6 Mon Sep 17 00:00:00 2001 From: JovannMC Date: Wed, 28 May 2025 14:15:29 +0300 Subject: [PATCH] feat: functional dropdown just gotta do searching --- .../functional/ConversionPanel.svelte | 9 +- src/lib/components/functional/Dropdown.svelte | 49 +--- .../functional/FormatDropdown.svelte | 237 ++++++++++++++++++ src/lib/converters/index.ts | 38 +++ src/lib/types/dropdown.ts | 5 - src/lib/types/file.svelte.ts | 7 + src/lib/types/index.ts | 3 +- src/routes/convert/+page.svelte | 33 ++- 8 files changed, 320 insertions(+), 61 deletions(-) create mode 100644 src/lib/components/functional/FormatDropdown.svelte delete mode 100644 src/lib/types/dropdown.ts diff --git a/src/lib/components/functional/ConversionPanel.svelte b/src/lib/components/functional/ConversionPanel.svelte index 9ae95f6..572af77 100644 --- a/src/lib/components/functional/ConversionPanel.svelte +++ b/src/lib/components/functional/ConversionPanel.svelte @@ -5,6 +5,8 @@ import Dropdown from "./Dropdown.svelte"; import Tooltip from "../visual/Tooltip.svelte"; import ProgressBar from "../visual/ProgressBar.svelte"; + import FormatDropdown from "./FormatDropdown.svelte"; + import { categories } from "$lib/converters"; const length = $derived(files.files.length); const progress = $derived(files.files.filter((f) => f.result).length); @@ -66,10 +68,7 @@

Set all to

{#if files.requiredConverters.length === 1} - {@const supported = files.files[0]?.converters.flatMap((c) => - c.formatStrings((f) => f.toSupported), - )} - files.files.forEach((f) => { if (f.from !== r) { @@ -77,7 +76,7 @@ f.result = null; } })} - options={supported || []} + {categories} /> {:else} diff --git a/src/lib/components/functional/Dropdown.svelte b/src/lib/components/functional/Dropdown.svelte index 40d36d7..102b14d 100644 --- a/src/lib/components/functional/Dropdown.svelte +++ b/src/lib/components/functional/Dropdown.svelte @@ -1,13 +1,11 @@
{#if open} -
- -
-
-
- -
- -
-
- - -
- {#each options as option} - - {/each} -
+ {#each options as option} + + {/each}
{/if}
diff --git a/src/lib/components/functional/FormatDropdown.svelte b/src/lib/components/functional/FormatDropdown.svelte new file mode 100644 index 0000000..163384f --- /dev/null +++ b/src/lib/components/functional/FormatDropdown.svelte @@ -0,0 +1,237 @@ + + +
+ + {#if open} + +
+ +
+
+ + + + +
+
+ + +
+ {#each shownCategories as category} + + {/each} +
+ +
+ {#if currentCategory} + {#each categories[currentCategory].formats as option} + + {/each} + {/if} +
+
+ {/if} +
diff --git a/src/lib/converters/index.ts b/src/lib/converters/index.ts index dd43695..b93f1e3 100644 --- a/src/lib/converters/index.ts +++ b/src/lib/converters/index.ts @@ -1,3 +1,4 @@ +import type { Categories } from "$lib/types"; import { FFmpegConverter } from "./ffmpeg.svelte"; import { PandocConverter } from "./pandoc.svelte"; import { VertdConverter } from "./vertd.svelte"; @@ -9,3 +10,40 @@ export const converters = [ new VertdConverter(), new PandocConverter(), ]; + +export function getConverterByFormat(format: string) { + for (const converter of converters) { + if (converter.supportedFormats.some((f) => f.name === format)) { + return converter; + } + } + return null; +} + +export const categories: Categories = { + image: { formats: [""], canConvertTo: [] }, + video: { formats: [""], canConvertTo: [] }, // add "audio" when "nullptr/experimental-audio-to-video" is implemented + audio: { formats: [""], canConvertTo: [] }, // add "video" when "nullptr/experimental-audio-to-video" is implemented + docs: { formats: [""], canConvertTo: [] }, +}; + +categories.audio.formats = + converters + .find((c) => c.name === "ffmpeg") + ?.formatStrings((f) => f.toSupported) + .filter((f) => f !== "mp3") || []; +categories.video.formats = + converters + .find((c) => c.name === "vertd") + ?.formatStrings((f) => f.toSupported) + .filter((f) => f !== "mp4") || []; +categories.image.formats = + converters + .find((c) => c.name === "libvips") + ?.formatStrings((f) => f.toSupported) + .filter((f) => f !== ".webp" && f !== ".gif") || []; +categories.docs.formats = + converters + .find((c) => c.name === "pandoc") + ?.formatStrings((f) => f.toSupported) + .filter((f) => f !== ".pdf") || []; diff --git a/src/lib/types/dropdown.ts b/src/lib/types/dropdown.ts deleted file mode 100644 index 1dd4b8b..0000000 --- a/src/lib/types/dropdown.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Categories { - [key: string]: { - formats: string[]; - } -} \ No newline at end of file diff --git a/src/lib/types/file.svelte.ts b/src/lib/types/file.svelte.ts index f77156c..8fc0d61 100644 --- a/src/lib/types/file.svelte.ts +++ b/src/lib/types/file.svelte.ts @@ -119,3 +119,10 @@ export class VertFile { a.remove(); } } + +export interface Categories { + [key: string]: { + formats: string[]; + canConvertTo?: string[]; + }; +} diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index 7d0d8f7..dc857ca 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -1,4 +1,3 @@ export * from "./file.svelte"; export * from "./util"; -export * from "./conversion-worker"; -export * from "./dropdown"; \ No newline at end of file +export * from "./conversion-worker"; \ No newline at end of file diff --git a/src/routes/convert/+page.svelte b/src/routes/convert/+page.svelte index c284cea..58fc205 100644 --- a/src/routes/convert/+page.svelte +++ b/src/routes/convert/+page.svelte @@ -1,11 +1,11 @@ @@ -224,13 +242,8 @@
- - - c.formatStrings((f) => f.toSupported), - ) - .filter((format) => format !== file.from) || []} + handleSelect(option, file)} />