27th October 2026
🍂🍁🍂
Loading app...
Add to your home screen
Quick access without scanning each time
📸
Uploading your photos
Please keep this screen open
Starting upload...
Keep the app open — we'll let you know when it's done
Connecting...
Quality:
Photos uploaded! They're now live in the gallery 🍂

Please enter your name before uploading

🔐

Admin access

Enter your password to manage photos

Edit photo

Choose a ratio then drag on the image · drag inside box to move it

const eQuality = QUALITY[SIGNAL].compress ? QUALITY[SIGNAL].quality : 0.98; const eExt = QUALITY[SIGNAL].compress ? '.webp' : '.jpg'; const hasEdits = editorRotation!==0 || editorFlipped || (editorFilter && editorFilter!=='none') || cropRect; if (!hasEdits) { const origFile=new File([editorFile],(editorFile.name||'photo.jpg').replace(/\.[^.]+$/,eExt),{type:editorFile.type||eType}); if (editorFileIndex===-1) selectedFiles.push(origFile); else selectedFiles[editorFileIndex]=origFile; renderPreviews(); checkReady(); document.getElementById('editor-overlay').classList.remove('open'); document.body.style.overflow=''; return; } const fc=document.createElement('canvas'); const isRot=editorRotation%180!==0; fc.width=isRot?editorImg.naturalHeight:editorImg.naturalWidth; fc.height=isRot?editorImg.naturalWidth:editorImg.naturalHeight; const fCtx=fc.getContext('2d'); fCtx.save(); fCtx.translate(fc.width/2,fc.height/2); fCtx.rotate(editorRotation*Math.PI/180); if (editorFlipped) fCtx.scale(-1,1); if (editorFilter && editorFilter!=='none') { const f=FILTERS.find(f=>f.id===editorFilter); if(f) fCtx.filter=f.css; } fCtx.drawImage(editorImg,-editorImg.naturalWidth/2,-editorImg.naturalHeight/2); fCtx.restore(); fc.toBlob(async blob => { if (!blob) return; const name=(editorFile.name||'photo'+eExt).replace(/\.[^.]+$/,eExt); const editedFile=new File([blob],name,{type:eType}); if (editorFileIndex && typeof editorFileIndex==='object' && editorFileIndex.adminId) { try { const ts=Date.now(); const uniqueName=name.replace(eExt,`-edited-${ts}${eExt}`); const storagePath=`guest-uploads/${uniqueName}`; const { error: uploadErr } = await supabase.storage .from(SUBDOMAIN) .upload(storagePath, new File([blob],uniqueName,{type:eType}), { upsert:false }); if (uploadErr) throw new Error(uploadErr.message); const { error: updateErr } = await supabase .from('photos') .update({ storage_path: storagePath, file_name: uniqueName }) .eq('id', editorFileIndex.adminId); if (updateErr) throw new Error(updateErr.message); const old=editorFileIndex.adminPhoto; if (old?.storage_path) await supabase.storage.from(SUBDOMAIN).remove([old.storage_path]); setAdminStatus('Photo updated! ✓'); await loadPhotos(); loadAdminPhotos(); } catch(e) { setAdminStatus('Save failed: '+e.message); } } else { if (editorFileIndex===-1) selectedFiles.push(editedFile); else selectedFiles[editorFileIndex]=editedFile; renderPreviews(); checkReady(); } }, eType, eQuality); document.getElementById('editor-overlay').classList.remove('open'); document.body.style.overflow=''; };