Mercurial
diff mrjunejune/src/notes/editor.js @ 202:b9b184b3303c
[Notes] Images get processed and it is properly fetched. Thank you.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 15 Feb 2026 09:12:57 -0800 |
| parents | 6cdee35a7ba9 |
| children |
line wrap: on
line diff
--- a/mrjunejune/src/notes/editor.js Sun Feb 15 07:07:50 2026 -0800 +++ b/mrjunejune/src/notes/editor.js Sun Feb 15 09:12:57 2026 -0800 @@ -1,5 +1,3 @@ -console.log("june"); - let editor = null; let currentNoteId = 'index'; @@ -76,7 +74,7 @@ } // 1. Create media record - const createResp = await fetch('/api/media/create', { + const createResponse = await fetch('/api/media/create', { method: 'POST', headers: { 'Authorization': 'Bearer ' + token, @@ -88,60 +86,72 @@ }) }); - if (!createResp.ok) { - const error = await createResp.json(); + if (!createResponse.ok) { + const error = await createResponse.json().catch(() => ({})); throw new Error(error.error || 'Failed to create media record'); } - const { media_id, upload_url } = await createResp.json(); + const data = await createResponse.json(); - // 2. Upload to S3 - const uploadResp = await fetch(upload_url, { + // 2. Upload file directly to S3 + const uploadResponse = await fetch(data.upload_url, { method: 'PUT', - headers: { 'Content-Type': file.type }, + headers: { + 'Content-Type': file.type + }, body: file }); - if (!uploadResp.ok) { - throw new Error('S3 upload failed'); + if (!uploadResponse.ok) { + throw new Error('Failed to upload file to S3'); } - // 3. Mark uploaded - await fetch(`/api/media/${media_id}/uploaded`, { + // 3. Mark as uploaded (triggers processing for images) + await fetch(`/api/media/${data.media_id}/uploaded`, { method: 'POST', - headers: { 'Authorization': 'Bearer ' + token } + headers: { + 'Authorization': 'Bearer ' + token + } }); - // 4. Poll for images, immediate return for non-images + // 4. Poll for images, return immediately for non-images if (file.type.startsWith('image/')) { - return await pollForProcessedImage(media_id); + return await pollForProcessedImage(data.media_id, token); } else { - // For non-images, return the original S3 URL - const s3_url = upload_url.split('?')[0]; - return { url: s3_url }; + // For non-images, construct the public URL + const publicUrl = data.upload_url.split('?')[0]; // Remove query params + return { url: publicUrl }; } } -async function pollForProcessedImage(mediaId) { - const token = getAuthToken(); - const maxAttempts = 60; // 2 minutes max +async function pollForProcessedImage(mediaId, token) { + const maxAttempts = 60; // 2 minutes max (60 * 2 seconds) for (let i = 0; i < maxAttempts; i++) { - await new Promise(r => setTimeout(r, 2000)); // 2 sec interval + await new Promise(resolve => setTimeout(resolve, 2000)); // 2 second interval - const resp = await fetch(`/api/media/${mediaId}/status`, { - headers: { 'Authorization': 'Bearer ' + token } + const statusResponse = await fetch(`/api/media/${mediaId}/status`, { + headers: { + 'Authorization': 'Bearer ' + token + } }); - if (!resp.ok) continue; + if (!statusResponse.ok) { + console.warn('Status check failed, retrying...'); + continue; + } + + const statusData = await statusResponse.json(); - const { status, processed_url, error_message } = await resp.json(); - - if (status === 'finished') return { url: processed_url }; - if (status === 'error') throw new Error(error_message || 'Processing failed'); + if (statusData.status === 'finished') { + return { url: statusData.processed_url }; + } else if (statusData.status === 'error') { + throw new Error(statusData.error_message || 'Processing failed'); + } + // Status is 'uploaded' or 'processing', continue polling } - throw new Error('Processing timeout'); + throw new Error('Processing timeout after 2 minutes'); } async function saveContent(content) { @@ -202,3 +212,4 @@ loadNote(currentNoteId); }); +