diff --git a/src/app.scss b/src/app.scss index b5db1c6..b005752 100644 --- a/src/app.scss +++ b/src/app.scss @@ -317,6 +317,18 @@ body { @apply outline outline-accent outline-2; } + input[type="range"] { + @apply appearance-none bg-panel h-2 rounded-lg; + } + + input[type="range"]::-webkit-slider-thumb { + @apply appearance-none w-4 h-4 bg-accent rounded-full cursor-pointer; + } + + input[type="range"]::-moz-range-thumb { + @apply w-4 h-4 bg-accent rounded-full cursor-pointer; + } + hr { @apply border-separator; } diff --git a/src/lib/components/functional/Uploader.svelte b/src/lib/components/functional/Uploader.svelte index 7aec8c4..6bd1221 100644 --- a/src/lib/components/functional/Uploader.svelte +++ b/src/lib/components/functional/Uploader.svelte @@ -6,12 +6,14 @@ import { effects, files } from "$lib/store/index.svelte"; import { converters } from "$lib/converters"; import { goto } from "$app/navigation"; + import { page } from "$app/state"; type Props = { class?: string; + jpegify?: boolean; }; - const { class: classList }: Props = $props(); + const { class: classList, jpegify }: Props = $props(); let uploaderButton = $state(); let fileInput = $state(); @@ -40,10 +42,13 @@ const handleFileChange = (e: Event) => { if (!fileInput) return; - - const oldLength = files.files.length; - files.add(fileInput.files); - if (oldLength !== files.files.length) goto("/convert"); + if (page.url.pathname !== "/jpegify/") { + const oldLength = files.files.length; + files.add(fileInput.files); + if (oldLength !== files.files.length) goto("/convert"); + } else { + files.add(fileInput.files); + } }; onMount(() => { @@ -93,7 +98,7 @@

- Drop or click to convert + Drop or click to {jpegify ? "JPEGIFY" : "convert"}

diff --git a/src/lib/components/layout/Gradients.svelte b/src/lib/components/layout/Gradients.svelte index 804cd7f..40d1101 100644 --- a/src/lib/components/layout/Gradients.svelte +++ b/src/lib/components/layout/Gradients.svelte @@ -32,7 +32,7 @@ easing: quintOut, }} > -{:else if page.url.pathname === "/convert/" && $showGradient} +{:else if (page.url.pathname === "/convert/" || page.url.pathname === "/jpegify/") && $showGradient} {#key $gradientColor}
i.activeMatch(page.url.pathname)), ); + const isSecretPage = $derived(selectedIndex === -1); + beforeNavigate((e) => { const oldIndex = items.findIndex((i) => i.activeMatch(e.from?.url.pathname || ""), @@ -155,16 +157,16 @@
- {#if linkRects[selectedIndex]} + {@const linkRect = linkRects.at(selectedIndex) || linkRects[0]} + {#if linkRect}
{/if} diff --git a/src/lib/converters/converter.svelte.ts b/src/lib/converters/converter.svelte.ts index 9183c2b..5482bd8 100644 --- a/src/lib/converters/converter.svelte.ts +++ b/src/lib/converters/converter.svelte.ts @@ -25,6 +25,8 @@ export class Converter { input: VertFile, // eslint-disable-next-line @typescript-eslint/no-unused-vars to: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars + ...args: any[] ): Promise { throw new Error("Not implemented"); } diff --git a/src/lib/converters/vips.svelte.ts b/src/lib/converters/vips.svelte.ts index 6de4904..663ec01 100644 --- a/src/lib/converters/vips.svelte.ts +++ b/src/lib/converters/vips.svelte.ts @@ -61,7 +61,13 @@ export class VipsConverter extends Converter { }; } - public async convert(input: VertFile, to: string): Promise { + public async convert( + input: VertFile, + to: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ...args: any[] + ): Promise { + const compression: number | undefined = args.at(0); log(["converters", this.name], `converting ${input.name} to ${to}`); const msg = { type: "convert", @@ -72,6 +78,7 @@ export class VipsConverter extends Converter { from: input.from, }, to, + compression, } as WorkerMessage; const res = await this.sendMessage(msg); diff --git a/src/lib/sections/about/Credits.svelte b/src/lib/sections/about/Credits.svelte index 8f4a46c..2f76e3e 100644 --- a/src/lib/sections/about/Credits.svelte +++ b/src/lib/sections/about/Credits.svelte @@ -61,7 +61,11 @@

GitHub contributors

{#if ghContribs && ghContribs.length > 0}

- Big thanks to all these people for helping out! + Big thanks + to all these people for helping out! => { image = vips.Image.newFromBuffer(buffer, "[n=-1]"); } - const output = image.writeToBuffer(message.to); + const opts: { [key: string]: string } = {}; + if (typeof message.compression !== "undefined") { + opts["Q"] = Math.min(100, message.compression + 1).toString(); + } + + const output = image.writeToBuffer(message.to, opts); image.delete(); return { type: "finished", diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 7a217bb..31234ed 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -18,6 +18,7 @@ } from "$lib/store/index.svelte"; import "../app.scss"; import { browser } from "$app/environment"; + import { page } from "$app/state"; let { children, data } = $props(); let enablePlausible = $state(false); @@ -40,9 +41,13 @@ const dropFiles = (e: DragEvent) => { e.preventDefault(); dropping.set(false); - const oldLength = files.files.length; - files.add(e.dataTransfer?.files); - if (oldLength !== files.files.length) goto("/convert"); + if (page.url.pathname !== "/jpegify/") { + const oldLength = files.files.length; + files.add(e.dataTransfer?.files); + if (oldLength !== files.files.length) goto("/convert"); + } else { + files.add(e.dataTransfer?.files); + } }; const handleDrag = (e: DragEvent, drag: boolean) => { diff --git a/src/routes/convert/+page.svelte b/src/routes/convert/+page.svelte index 4f830b9..c13bad9 100644 --- a/src/routes/convert/+page.svelte +++ b/src/routes/convert/+page.svelte @@ -243,7 +243,7 @@ ? 'bg-accent-green' : 'bg-accent-blue'}" disabled={!files.ready} - onclick={file.convert} + onclick={() => file.convert()} > diff --git a/src/routes/jpegify/+page.svelte b/src/routes/jpegify/+page.svelte new file mode 100644 index 0000000..0937a81 --- /dev/null +++ b/src/routes/jpegify/+page.svelte @@ -0,0 +1,113 @@ + + +