fix: better requiredConverters handling

should fix some people having issues with being unable to convert (even though they should be able to do certain connversions - e.g. ffmpeg failed to load, should still allow video-video conversion)

perks of having an old ass iphone 11 pro max on ios 16.1.1 lmfao
This commit is contained in:
Maya 2026-03-11 11:02:38 +03:00
parent 1573bda61e
commit 8360970e25
No known key found for this signature in database
5 changed files with 81 additions and 13 deletions

View File

@ -25,7 +25,7 @@
class="btn {$effects
? ''
: '!scale-100'} highlight flex gap-3 max-md:w-full md:max-w-[15.5rem]"
disabled={!files.ready}
disabled={!files.allReady}
>
<RefreshCw size="24" />
<p>{m["convert.panel.convert_all"]()}</p>
@ -34,7 +34,7 @@
class="btn {$effects
? ''
: '!scale-100'} flex gap-3 max-md:w-full md:max-w-[15.5rem]"
disabled={!files.ready || !files.results}
disabled={!files.allReady || !files.results}
onclick={() => files.downloadAll()}
>
<FolderArchiveIcon size="24" />

View File

@ -226,7 +226,7 @@ export class MediabunnyConverter extends Converter {
// currently the official ones -- maybe add our own in the future
this.initializeCodecs();
// don't know how to check if mediabunny is ready rn, maybe test smol conversion or run some other method? shrug
// TODO: don't know how to check if mediabunny is ready/actually supported rn, maybe test smol conversion or run some other method? shrug
if (typeof Conversion === "undefined") {
this.status = "not-ready";
this.error("Mediabunny failed to load");

View File

@ -1,5 +1,6 @@
import { browser } from "$app/environment";
import { byNative, converterCategories, converters } from "$lib/converters";
import type { Converter } from "$lib/converters/converter.svelte";
import { error, log } from "$lib/util/logger";
import { VertFile } from "$lib/types";
import { parseBlob, selectCover } from "music-metadata";
@ -14,16 +15,62 @@ import { GB } from "$lib/util/consts";
class Files {
public files = $state<VertFile[]>([]);
private getRequiredConverters(file: VertFile): Converter[] {
if (file.isZip()) return file.converters;
const compatibleConverters = file.findConverters([file.from, file.to]);
const selectedConverterName = file.conversionSettings.converter;
if (!selectedConverterName) return compatibleConverters;
const selectedConverter = compatibleConverters.find(
(converter) => converter.name === selectedConverterName,
);
return selectedConverter ? [selectedConverter] : compatibleConverters;
}
private isConverterReady(converter: Converter): boolean {
return (
converter.status === "ready" ||
converter.status === "partially-ready" // no idea where this could be used actually in a real converter
);
}
public isReady(file: VertFile): boolean {
const requiredConverters = this.getRequiredConverters(file);
if (requiredConverters.length === 0) return false;
return (
!file.processing &&
requiredConverters.some((converter) =>
this.isConverterReady(converter),
)
);
}
public requiredConverters = $derived(
Array.from(new Set(files.files.map((f) => f.converters).flat())),
Array.from(
new Set(
this.files.flatMap((file) =>
this.getRequiredConverters(file),
),
),
),
);
public ready = $derived(
this.files.length === 0
? false
: this.requiredConverters.every((f) => f?.status === "ready") &&
this.files.every((f) => !f.processing),
: this.files.some((file) => this.isReady(file)),
);
public allReady = $derived(
this.files.length === 0
? false
: this.files.every((file) => this.isReady(file)),
);
public results = $derived(
this.files.length === 0 ? false : this.files.every((f) => f.result),
);
@ -289,7 +336,10 @@ class Files {
this._addThumbnail(vf);
const convName = converter.name;
if (file.size > MAX_ARRAY_BUFFER_SIZE && (converterCategories.video.includes(convName))) {
if (
file.size > MAX_ARRAY_BUFFER_SIZE &&
converterCategories.video.includes(convName)
) {
ToastManager.add({
type: "warning",
message: m["convert.large_file_warning"]({
@ -363,9 +413,10 @@ class Files {
if (!result) continue;
let filename = filenames[i];
// check if this filename appears more than once
const isDuplicate = filenames.filter((name) => name === filename).length > 1;
const isDuplicate =
filenames.filter((name) => name === filename).length > 1;
if (isDuplicate) {
const nameParts = filename.lastIndexOf(".");
const nameWithoutExt = filename.substring(0, nameParts);

View File

@ -139,6 +139,14 @@ export class VertFile {
.map((c) => c.name)
.join(", ")}`,
);
setInterval(() => {
log(["file", "effect"], `from: ${this.from}, to: ${this.to}`);
log(
["file", "effect"],
`converter status: ${this.converters.map((c) => `${c.name}: ${c.status}`).join(", ")}`,
);
}, 1000);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -159,14 +167,23 @@ export class VertFile {
]);
if (compatibleConverters.length) {
converter = compatibleConverters[0];
log(["file", "convert"], `found compatible converter: ${converter.name}`);
log(
["file", "convert"],
`found compatible converter: ${converter.name}`,
);
} else {
log(["file", "convert"], `no compatible converter found for ${this.from} to ${this.to}`);
log(
["file", "convert"],
`no compatible converter found for ${this.from} to ${this.to}`,
);
// TODO: handle zip converter fallback explicitly if needed
// TODO: provide a clearer error path for unsupported from/to pairs
}
} else {
log(["file", "convert"], `using custom converter from settings: ${converter.name}`);
log(
["file", "convert"],
`using custom converter from settings: ${converter.name}`,
);
}
if (!converter) throw new Error("No converter found");

View File

@ -401,7 +401,7 @@
: isDocument
? 'bg-accent-green'
: 'bg-accent-blue'}"
disabled={!files.ready}
disabled={!files.isReady(file)}
onclick={() => file.convert()}
>
<RotateCwIcon size="24" />