Skip to content

Commit 88690dd

Browse files
author
NellowTCS
committed
more fixes
1 parent 838ffec commit 88690dd

3 files changed

Lines changed: 101 additions & 66 deletions

File tree

Build/src/helpers/filePickerHelper.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,8 @@ export async function extractAudioMetadata(file: File): Promise<AudioMetadata> {
502502
// Process album art if available
503503
let albumArt: string | undefined = undefined;
504504
if (cover && cover.data && cover.data.length > 0) {
505-
const blob = new Blob([cover.data], { type: cover.mime_type });
505+
const uint8Array = new Uint8Array(cover.data);
506+
const blob = new Blob([uint8Array], { type: cover.mime_type });
506507
albumArt = await new Promise<string>((resolve, reject) => {
507508
const reader = new FileReader();
508509
reader.onloadend = () => resolve(reader.result as string);
@@ -569,14 +570,14 @@ export async function extractAudioMetadata(file: File): Promise<AudioMetadata> {
569570
}
570571
}
571572
// Fallback to original (music-metadata) for all other formats
572-
let MetadataWorkerType: typeof Worker;
573+
let MetadataWorkerType: new () => Worker;
573574
if (typeof __IS_SINGLE_FILE__ !== "undefined" && __IS_SINGLE_FILE__) {
574575
MetadataWorkerType = (
575576
await import("../workers/metadataWorker.ts?worker&inline")
576-
).default;
577+
).default as new () => Worker;
577578
} else {
578-
MetadataWorkerType = (await import("../workers/metadataWorker.ts?worker"))
579-
.default;
579+
MetadataWorkerType = ((await import("../workers/metadataWorker.ts?worker"))
580+
.default as new () => Worker);
580581
}
581582
const worker = new MetadataWorkerType();
582583

Build/src/helpers/importAudioFiles.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ export async function importAudioFiles(
4646
// Safari: Pre-decode to WAV for compatibility
4747
const { decodeFloToWav } = await import("./refloWavHelper");
4848
const wavBytes = await decodeFloToWav(arrayBuffer);
49-
const wavBlob = new Blob([wavBytes], { type: "audio/wav" });
49+
const wavArray = new Uint8Array(wavBytes);
50+
const wavBlob = new Blob([wavArray], { type: "audio/wav" });
5051
processedFile = new File(
5152
[wavBlob],
5253
file.name.replace(/\.flo$/i, ".wav"),

Build/tests/__mocks__/browser.ts

Lines changed: 93 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,100 @@
1-
class MockGainNode {
2-
gain = { value: 1 };
3-
disconnect() {}
4-
connect() {
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
3+
declare const global: any;
4+
5+
const MockGainNode: any = {
6+
gain: { value: 1 },
7+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8+
connect(..._args: any[]): any {
59
return this;
6-
}
7-
}
10+
},
11+
disconnect(): void {},
12+
};
813

9-
class MockAudioContext {
10-
sampleRate = 44100;
11-
baseLatency = 0;
12-
close() {
13-
return Promise.resolve();
14-
}
15-
createGain() {
16-
return new MockGainNode();
17-
}
18-
createBufferSource() {
19-
return {
20-
buffer: null,
21-
connect: () => {},
22-
start: () => {},
23-
stop: () => {},
24-
onended: null,
25-
disconnect: () => {},
26-
};
27-
}
28-
createBuffer(channels: number, length: number, sampleRate: number) {
29-
return {
30-
numberOfChannels: channels,
31-
length,
32-
sampleRate,
33-
duration: length / sampleRate,
34-
getChannelData: () => new Float32Array(length),
35-
};
36-
}
37-
decodeAudioData(buffer: ArrayBuffer) {
38-
return Promise.resolve(this.createBuffer(2, 44100, 44100));
39-
}
40-
destination = {};
14+
function MockAudioContext(this: any): void {
15+
this.sampleRate = 44100;
16+
this.baseLatency = 0;
17+
this.destination = {};
4118
}
4219

43-
class MockAudio {
44-
src = "";
45-
currentTime = 0;
46-
duration = 0;
47-
paused = true;
48-
volume = 1;
49-
playbackRate = 1;
50-
readyState = 4;
51-
HAVE_ENOUGH_DATA = 4;
20+
MockAudioContext.prototype.close = function(): Promise<void> {
21+
return Promise.resolve();
22+
};
23+
24+
MockAudioContext.prototype.createGain = function(): any {
25+
return MockGainNode;
26+
};
27+
28+
MockAudioContext.prototype.createBuffer = function(
29+
channels: number,
30+
length: number,
31+
sampleRate: number
32+
): any {
33+
return {
34+
numberOfChannels: channels,
35+
length,
36+
sampleRate,
37+
duration: length / sampleRate,
38+
getChannelData: () => new Float32Array(length),
39+
};
40+
};
41+
42+
MockAudioContext.prototype.createBufferSource = function(): any {
43+
return {
44+
buffer: null,
45+
connect: () => {},
46+
disconnect: () => {},
47+
start: () => {},
48+
stop: () => {},
49+
};
50+
};
5251

53-
play() {
54-
return Promise.resolve();
55-
}
56-
pause() {}
57-
load() {}
58-
addEventListener(_event: string, _callback: () => void) {}
59-
removeEventListener(_event: string, _callback: () => void) {}
60-
dispatchEvent(_event: unknown) {
61-
return true;
62-
}
52+
MockAudioContext.prototype.decodeAudioData = function(
53+
buffer: ArrayBuffer,
54+
successCallback?: (decoded: any) => void,
55+
errorCallback?: (error: any) => void
56+
): Promise<any> {
57+
const decoded = this.createBuffer(2, 44100, 44100);
58+
successCallback?.(decoded);
59+
return Promise.resolve(decoded).catch((err) => {
60+
errorCallback?.(err);
61+
throw err;
62+
});
63+
};
64+
65+
const listeners = new Map<string, Set<any>>();
66+
67+
function MockAudio(this: any): void {
68+
this.src = "";
69+
this.currentTime = 0;
70+
this.duration = 0;
71+
this.paused = true;
72+
this.volume = 1;
73+
this.playbackRate = 1;
74+
this.readyState = 4;
75+
this.HAVE_ENOUGH_DATA = 4;
6376
}
6477

65-
(global as unknown as { AudioContext: typeof AudioContext }).AudioContext = MockAudioContext as unknown as typeof AudioContext;
66-
(global as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext = MockAudioContext as unknown as typeof AudioContext;
67-
(global as unknown as { Audio: typeof Audio }).Audio = MockAudio as unknown as typeof Audio;
78+
MockAudio.prototype.play = function(): Promise<void> {
79+
return Promise.resolve();
80+
};
81+
MockAudio.prototype.pause = function(): void {};
82+
MockAudio.prototype.load = function(): void {};
83+
84+
MockAudio.prototype.addEventListener = function(event: string, callback: any): void {
85+
if (!listeners.has(event)) listeners.set(event, new Set());
86+
listeners.get(event)!.add(callback);
87+
};
88+
89+
MockAudio.prototype.removeEventListener = function(event: string, callback: any): void {
90+
listeners.get(event)?.delete(callback);
91+
};
92+
93+
MockAudio.prototype.dispatchEvent = function(event: any): boolean {
94+
listeners.get(event.type)?.forEach((listener) => listener());
95+
return true;
96+
};
97+
98+
(global as any).AudioContext = MockAudioContext;
99+
(global as any).webkitAudioContext = MockAudioContext;
100+
(global as any).Audio = MockAudio;

0 commit comments

Comments
 (0)