@@ -598,93 +598,9 @@ async function init() {
598598 } , 500 ) ;
599599 // Proactive tile caching — start after a short delay so it doesn't compete with initial load
600600 setTimeout ( ( ) => cacheMapTiles ( ) , 10000 ) ;
601- // One-time migration: convert PNG thumbnails to JPEG (remove once both machines have run this)
602- setTimeout ( ( ) => _migrateThumbsToWebP ( ) , 2000 ) ;
603- // One-time migration: move full-size base64 images from IndexedDB to disk
604- // After this, IndexedDB holds only metadata + thumbnails (~50KB per photo vs ~4MB)
605- setTimeout ( ( ) => _migrateImagesToDisk ( ) , 3000 ) ;
606601}
607602
608603
609- // ═══════════════════════════════════════
610- // ONE-TIME MIGRATION: PNG → JPEG thumbnails
611- // Remove this function and its setTimeout call in init() once both machines have run it.
612- // ═══════════════════════════════════════
613- async function _migrateThumbsToWebP ( ) {
614- let migrated = 0 ;
615- for ( const p of photos ) {
616- if ( ! p . thumbUrl || p . thumbUrl . startsWith ( 'data:image/jpeg' ) ) continue ;
617- try {
618- const img = new Image ( ) ;
619- await new Promise ( ( res , rej ) => { img . onload = res ; img . onerror = rej ; img . src = p . thumbUrl ; } ) ;
620- const canvas = document . createElement ( 'canvas' ) ;
621- canvas . width = img . naturalWidth ;
622- canvas . height = img . naturalHeight ;
623- canvas . getContext ( '2d' ) . drawImage ( img , 0 , 0 ) ;
624- p . thumbUrl = canvas . toDataURL ( 'image/jpeg' , 0.7 ) ;
625- await dbPut ( 'photos' , p ) ;
626- // Upload the new WebP thumbnail to disk (bypasses _savedPhotoDisk guard)
627- if ( _autoSaveAvailable ) {
628- await fetch ( `/api/photos/${ p . id } /thumb` , {
629- method : 'POST' ,
630- headers : { 'Content-Type' : 'application/json' } ,
631- body : JSON . stringify ( { dataUrl : p . thumbUrl } )
632- } ) ;
633- }
634- migrated ++ ;
635- } catch ( _ ) { /* skip failures */ }
636- }
637- if ( migrated ) {
638- rebuildPhotoList ( ) ;
639- buildTimeline ( ) ;
640- scheduleAutoSave ( ) ;
641- }
642- }
643-
644- // ═══════════════════════════════════════
645- // ONE-TIME MIGRATION: Move base64 images from IndexedDB to disk
646- // After this migration, IndexedDB holds metadata + thumbnails only (~50KB/photo vs ~4MB).
647- // Full-size images live in matrix-photos/ and are loaded on-demand by the lightbox.
648- // ═══════════════════════════════════════
649- async function _migrateImagesToDisk ( ) {
650- if ( ! _autoSaveAvailable ) return ; // serve.py must be running to save files
651- // Find photos still storing base64 full-size images in IndexedDB
652- const needMigration = photos . filter ( p => p . dataUrl && p . dataUrl . startsWith ( 'data:' ) ) ;
653- if ( ! needMigration . length ) return ;
654-
655- showToast ( `Migrating ${ needMigration . length } photo${ needMigration . length !== 1 ? 's' : '' } to disk…` , 'info' ) ;
656- let migrated = 0 ;
657-
658- for ( const p of needMigration ) {
659- try {
660- const ext = ( p . dataUrl . match ( / d a t a : i m a g e \/ ( \w + ) / ) || [ ] ) [ 1 ] === 'png' ? 'png' : 'jpg' ;
661- const filePath = `matrix-photos/${ p . id } .${ ext } ` ;
662- // Check if the image already exists on disk (from prior auto-save)
663- const exists = await fetch ( `/${ filePath } ` , { method : 'HEAD' } ) . then ( r => r . ok ) . catch ( ( ) => false ) ;
664- if ( ! exists ) {
665- // Image not on disk yet — save it now from the base64 in IndexedDB
666- await fetch ( `/api/photos/${ p . id } ` , {
667- method : 'POST' ,
668- headers : { 'Content-Type' : 'application/json' } ,
669- body : JSON . stringify ( { dataUrl : p . dataUrl } )
670- } ) ;
671- }
672- // Replace base64 with the file path reference in memory + IndexedDB
673- p . dataUrl = filePath ;
674- await dbPut ( 'photos' , p ) ;
675- migrated ++ ;
676- } catch ( err ) {
677- // Skip failures — photo retains its base64 and can retry next load
678- console . warn ( `Migration failed for ${ p . id } :` , err . message ) ;
679- }
680- }
681-
682- if ( migrated ) {
683- scheduleAutoSave ( ) ;
684- showToast ( `Migrated ${ migrated } photo${ migrated !== 1 ? 's' : '' } to disk ✓` , 'success' ) ;
685- }
686- }
687-
688604// ═══════════════════════════════════════
689605// OFFLINE SUPPORT
690606// ═══════════════════════════════════════
0 commit comments