Skip to content

Commit 6f3ed97

Browse files
committed
Revert "Deduplication"
This reverts commit 00ecba7.
1 parent 00ecba7 commit 6f3ed97

File tree

3 files changed

+57
-101
lines changed

3 files changed

+57
-101
lines changed

Build/src/helpers/filePickerHelper.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -834,9 +834,10 @@ export function handleShareTarget(): ShareTargetResult | null {
834834
return null; // Will be handled in useShareTarget
835835
}
836836

837-
export function useShareTarget(onShareReceived: (result: ShareTargetResult) => void) {
837+
export function useShareTarget(
838+
onShareReceived: (result: ShareTargetResult) => void
839+
) {
838840
const hasProcessedRef = useRef(false);
839-
const processedFilesRef = useRef<Set<string>>(new Set()); // Track processed file IDs
840841

841842
useEffect(() => {
842843
if (hasProcessedRef.current) return;
@@ -854,14 +855,9 @@ export function useShareTarget(onShareReceived: (result: ShareTargetResult) => v
854855
if (key.url.includes("/shared-file-")) {
855856
const response = await cache.match(key);
856857
const blob = await response?.blob();
857-
const fileName = response?.headers.get("x-file-name") || "unknown-file";
858-
859-
// Generate a unique ID for each file (name + size + lastModified)
860-
const id = `${fileName}-${blob?.size}`;
861-
if (!processedFilesRef.current.has(id)) {
862-
processedFilesRef.current.add(id); // Mark as processed
863-
files.push(new File([blob!], fileName, { type: blob?.type }));
864-
}
858+
const fileName =
859+
response?.headers.get("x-file-name") || "unknown-file";
860+
files.push(new File([blob!], fileName, { type: blob?.type }));
865861
}
866862
}
867863

@@ -884,6 +880,7 @@ export function useShareTarget(onShareReceived: (result: ShareTargetResult) => v
884880
}
885881
}
886882

883+
// Fallback to text sharing (e.g., query parameters)
887884
const shareResult = handleShareTarget();
888885
if (shareResult) {
889886
hasProcessedRef.current = true;

Build/src/helpers/importAudioFiles.tsx

Lines changed: 20 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,24 @@ import { setAlbumArtInCache } from "../hooks/useAlbumArt";
66
export async function importAudioFiles(
77
audioFiles: Array<{ file: File } | File>,
88
addSong: (song: Song, file: File) => Promise<void>,
9-
t: any
9+
t: any,
1010
) {
1111
if (!audioFiles || audioFiles.length === 0) return;
1212

1313
const BATCH_SIZE = 10;
1414
let successCount = 0;
1515
let errorCount = 0;
16-
let skippedCount = 0; // Count skipped duplicates
1716
let currentBatch = 1;
1817
const totalBatches = Math.ceil(audioFiles.length / BATCH_SIZE);
1918

20-
// Track unique files to avoid duplicate imports in this session
21-
const processedFileIds = new Set<string>();
22-
2319
for (let i = 0; i < audioFiles.length; i += BATCH_SIZE) {
2420
const batch = audioFiles.slice(i, i + BATCH_SIZE);
25-
toast.loading(
26-
t("batch.processing", { currentBatch, totalBatches, successCount })
27-
);
21+
toast.loading(t("batch.processing", { currentBatch, totalBatches }));
2822

2923
// Process sequentially to reduce memory pressure
3024
for (const audioFile of batch) {
3125
try {
3226
const file: File = (audioFile as any).file || (audioFile as File);
33-
34-
// Unique ID based on file metadata (name, size, lastModified)
35-
const fileId = `${file.name}-${file.size}-${file.lastModified}`;
36-
if (processedFileIds.has(fileId)) {
37-
// Skip duplicates detected via unique ID
38-
console.log(`Skipping duplicate file: ${file.name}`);
39-
skippedCount++;
40-
continue;
41-
}
42-
processedFileIds.add(fileId); // Mark the file as processed
43-
4427
const metadata = await extractAudioMetadata(file);
4528
const songId = generateUniqueId();
4629

@@ -49,36 +32,31 @@ export async function importAudioFiles(
4932
let processedMimeType = file.type;
5033

5134
const isFlo =
52-
file.name.toLowerCase().endsWith(".flo") ||
53-
metadata.encoding?.codec === "flo";
35+
file.name.toLowerCase().endsWith('.flo') ||
36+
metadata.encoding?.codec === 'flo';
5437

5538
if (isFlo) {
5639
try {
5740
const arrayBuffer = await file.arrayBuffer();
58-
const isSafari = /^((?!chrome|android).)*safari/i.test(
59-
navigator.userAgent
60-
);
41+
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
6142

6243
if (isSafari) {
6344
// Safari: Pre-decode to WAV for compatibility
6445
const { decodeFloToWav } = await import("./refloWavHelper");
6546
const wavBytes = await decodeFloToWav(arrayBuffer);
66-
const wavBlob = new Blob([wavBytes], { type: "audio/wav" });
47+
const wavBlob = new Blob([wavBytes], { type: 'audio/wav' });
6748
processedFile = new File(
6849
[wavBlob],
69-
file.name.replace(/\.flo$/i, ".wav"),
70-
{ type: "audio/wav" }
50+
file.name.replace(/\.flo$/i, '.wav'),
51+
{ type: 'audio/wav' }
7152
);
72-
processedMimeType = "audio/wav";
53+
processedMimeType = 'audio/wav';
7354
console.log(`Pre-decoded flo to WAV for Safari: ${file.name}`);
7455
} else {
7556
// Non-Safari: Pre-decode to PCM for Web Audio API
7657
const { decodeFloToAudioBuffer } = await import("./floProcessor");
7758
const audioContext = new AudioContext();
78-
const audioBuffer = await decodeFloToAudioBuffer(
79-
arrayBuffer,
80-
audioContext
81-
);
59+
const audioBuffer = await decodeFloToAudioBuffer(arrayBuffer, audioContext);
8260

8361
// Store as interleaved Float32Array PCM
8462
const frameCount = audioBuffer.length;
@@ -88,27 +66,25 @@ export async function importAudioFiles(
8866
// Interleave channels
8967
for (let i = 0; i < frameCount; i++) {
9068
for (let ch = 0; ch < channels; ch++) {
91-
pcmData[i * channels + ch] = audioBuffer.getChannelData(ch)[
92-
i
93-
];
69+
pcmData[i * channels + ch] = audioBuffer.getChannelData(ch)[i];
9470
}
9571
}
9672

97-
const pcmBlob = new Blob([pcmData.buffer], { type: "audio/pcm" });
73+
const pcmBlob = new Blob([pcmData.buffer], { type: 'audio/pcm' });
9874
processedFile = new File(
9975
[pcmBlob],
100-
file.name.replace(/\.flo$/i, ".pcm"),
101-
{ type: "audio/pcm" }
76+
file.name.replace(/\.flo$/i, '.pcm'),
77+
{ type: 'audio/pcm' }
10278
);
103-
processedMimeType = "audio/pcm";
79+
processedMimeType = 'audio/pcm';
10480

10581
// Store AudioBuffer properties for reconstruction
10682
metadata.encoding = {
10783
...metadata.encoding,
10884
sampleRate: audioBuffer.sampleRate,
10985
channels: audioBuffer.numberOfChannels,
11086
bitsPerSample: 32, // Float32
111-
codec: "pcm-float32",
87+
codec: 'pcm-float32',
11288
};
11389

11490
// Close the temporary AudioContext
@@ -119,27 +95,22 @@ export async function importAudioFiles(
11995
} catch (error) {
12096
console.warn("Failed to pre-decode flo file, storing original:", error);
12197
// Keep original file if pre-decoding fails
122-
processedMimeType = "audio/x-flo";
98+
processedMimeType = 'audio/x-flo';
12399
}
124100
}
125101

126102
// Save album art separately if present
127103
const hasAlbumArt = !!metadata.albumArt;
128104
if (hasAlbumArt && metadata.albumArt) {
129-
await musicIndexedDbHelper.saveAlbumArt(
130-
songId,
131-
metadata.albumArt
132-
);
105+
await musicIndexedDbHelper.saveAlbumArt(songId, metadata.albumArt);
133106
setAlbumArtInCache(songId, metadata.albumArt);
134107
}
135108

136109
const song: Song = {
137110
id: songId,
138111
title: metadata.title,
139112
artist: metadata.artist,
140-
album:
141-
metadata.album ||
142-
t("songInfo.album", { title: t("common.unknownAlbum") }),
113+
album: metadata.album || t("songInfo.album", { title: t("common.unknownAlbum") }),
143114
duration: metadata.duration,
144115
url: "", // Will be set by addSong
145116
albumArt: metadata.albumArt, // Keep for immediate display
@@ -171,14 +142,8 @@ export async function importAudioFiles(
171142
}
172143

173144
toast.dismiss();
174-
// Show accurate results with skipped files count
175145
if (successCount > 0) {
176-
toast.success(
177-
t("filePicker.successImport", {
178-
count: successCount,
179-
skipped: skippedCount,
180-
})
181-
);
146+
toast.success(t("filePicker.successImport", { count: successCount }));
182147
}
183148
if (errorCount > 0) {
184149
toast.error(t("filePicker.failedImport", { count: errorCount }));

Build/src/workers/sw.ts

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,41 @@ precacheAndRoute(self.__WB_MANIFEST);
77
// Handle SPA navigation requests
88
const handler = createHandlerBoundToURL("index.html");
99
const navigationRoute = new NavigationRoute(handler, {
10-
allowlist: [/^\/beta\/HTMLPlayer\//],
10+
allowlist: [/^\/beta\/HTMLPlayer\//],
1111
});
1212
registerRoute(navigationRoute);
1313

1414
// Handle POST requests for file sharing
1515
registerRoute(
16-
({ url, request }) => {
17-
return url.pathname === "/beta/HTMLPlayer/" && request.method === "POST";
18-
},
19-
async ({ event }) => {
20-
try {
21-
const formData = await event.request.formData();
22-
const cache = await caches.open("incoming-shares");
16+
({ url, request }) => {
17+
return url.pathname === "/beta/HTMLPlayer/" && request.method === "POST";
18+
},
19+
async ({ event }) => {
20+
try {
21+
const formData = await event.request.formData();
22+
const cache = await caches.open("incoming-shares");
2323

24-
// Keep track of already cached files during this session
25-
const existingKeys = new Set(
26-
(await cache.keys()).map((key) => key.url.split("/").pop())
27-
);
28-
29-
const files = [];
30-
for (const [value] of formData.entries()) {
31-
if (value instanceof File) {
32-
const uniqueKey = `shared-file-${value.name}`;
33-
if (!existingKeys.has(uniqueKey)) {
34-
// Only cache if it's not already cached
35-
await cache.put(uniqueKey, new Response(value, {
36-
headers: { "x-file-name": value.name },
37-
}));
38-
files.push(uniqueKey);
39-
}
40-
}
41-
}
42-
43-
const redirectUrl = new URL(
44-
`/beta/HTMLPlayer/?share-received=true&files=${files.length}`,
45-
self.location.origin
46-
);
47-
return Response.redirect(redirectUrl.href, 303);
48-
} catch (e) {
49-
return new Response("Failed to process file share", { status: 400 });
24+
// Process all files in the form data
25+
const files = [];
26+
for (const [key, value] of formData.entries()) {
27+
if (value instanceof File) {
28+
files.push({ file: value, key });
29+
await cache.put(`/shared-file-${value.name}`, new Response(value, {
30+
headers: { "x-file-name": value.name, "content-type": value.type },
31+
}));
5032
}
51-
},
52-
"POST"
33+
}
34+
35+
// Redirect to the app with an indicator for file sharing
36+
const redirectUrl = new URL(
37+
`/beta/HTMLPlayer/?share-received=true&files=${files.length}`,
38+
self.location.origin
39+
);
40+
return Response.redirect(redirectUrl.href, 303);
41+
} catch (e) {
42+
// Always return a response even on error
43+
return new Response("Failed to process file share", { status: 400 });
44+
}
45+
},
46+
"POST"
5347
);

0 commit comments

Comments
 (0)