fix: remove ContentLength from presigned URL, fix macOS multi-select

- ContentLength in PutObjectCommand causes XHR upload failures (browser
  does not send matching Content-Length header in presigned PUT requests)
- Change accept to audio/* so macOS Finder allows multi-file selection
- Add step prefix to errors ([URL]/[S3]/[DB]) for easier debugging

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Robin Choice
2026-04-13 18:30:50 +02:00
parent 9530add1ff
commit e63dc30a7f
2 changed files with 13 additions and 10 deletions

View File

@@ -62,35 +62,39 @@
}
async function uploadOne(file: File, idx: number) {
let step = 'URL';
try {
const mimeType = file.type || 'audio/wav';
const { uploadUrl, fileKey } = await api.post<{ uploadUrl: string; fileKey: string }>(
`/stems/track/${trackId}/upload-url`,
{ fileName: file.name, mimeType: file.type || 'audio/wav', fileSize: file.size },
{ fileName: file.name, mimeType, fileSize: file.size },
);
await uploadWithProgress(uploadUrl, file, (p) => {
step = 'S3';
await uploadWithProgress(uploadUrl, file, mimeType, (p) => {
files[idx] = { ...files[idx], progress: p };
});
step = 'DB';
await api.post(`/stems/track/${trackId}`, {
fileKey,
name: stemNameFromFile(file.name),
originalFileName: file.name,
mimeType: file.type || 'audio/wav',
mimeType,
fileSize: file.size,
});
files[idx] = { ...files[idx], progress: 100 };
} catch (err) {
files[idx] = { ...files[idx], error: err instanceof Error ? err.message : 'Fehler' };
files[idx] = { ...files[idx], error: `[${step}] ${err instanceof Error ? err.message : 'Fehler'}` };
}
}
function uploadWithProgress(url: string, file: File, onProgress: (p: number) => void): Promise<void> {
function uploadWithProgress(url: string, file: File, mimeType: string, onProgress: (p: number) => void): Promise<void> {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('PUT', url);
xhr.setRequestHeader('Content-Type', file.type || 'audio/wav');
xhr.setRequestHeader('Content-Type', mimeType);
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) onProgress(Math.round((e.loaded / e.total) * 100));
};
@@ -117,7 +121,7 @@
<input
id="stem-input-{trackId}"
type="file"
accept=".wav,.mp3,.flac,.aiff,.aif"
accept="audio/*"
multiple
onchange={handleFileSelect}
hidden
@@ -125,7 +129,7 @@
<div class="dropzone-content">
<span class="icon"><Icon name="upload" size={24} /></span>
<p>STEMs hier ablegen oder klicken</p>
<span class="hint">Mehrere Dateien gleichzeitig möglich · WAV, FLAC, AIFF · max 500 MB</span>
<span class="hint">Mehrere Dateien gleichzeitig möglich · WAV, MP3, FLAC, AIFF · max 500 MB</span>
</div>
</div>