@@ -3349,9 +3349,9 @@ export class OptionsComponent implements OnInit {
33493349 }
33503350
33513351 /**
3352- * Start periodic cloud sync for tags.
3352+ * Start periodic cloud sync for tags and image metadata .
33533353 * This handles cross-browser and cross-device synchronization
3354- * by periodically fetching tags from the cloud.
3354+ * by periodically fetching updates from the cloud.
33553355 */
33563356 private startCloudTagSync ( ) : void {
33573357 // Clear any existing interval
@@ -3371,16 +3371,20 @@ export class OptionsComponent implements OnInit {
33713371 }
33723372
33733373 try {
3374+ // Sync tags from cloud
33743375 await this . mergeCloudTags ( ) ;
3376+ // Sync image metadata (tags, favorites) from cloud
3377+ await this . mergeCloudImages ( ) ;
33753378 await this . updateTagCounts ( ) ;
33763379 } catch ( error ) {
3377- console . error ( 'Periodic cloud tag sync failed:' , error ) ;
3380+ console . error ( 'Periodic cloud sync failed:' , error ) ;
33783381 }
33793382 } , this . cloudSyncIntervalMs ) ;
33803383 }
33813384
33823385 /**
3383- * Download and merge synced images from cloud into local storage
3386+ * Download and merge synced images from cloud into local storage.
3387+ * Also updates tags and favorite status on existing local images from cloud.
33843388 */
33853389 async mergeCloudImages ( ) : Promise < number > {
33863390 try {
@@ -3393,45 +3397,68 @@ export class OptionsComponent implements OnInit {
33933397
33943398 const db = await this . getDatabase ( ) ;
33953399 let imagesAdded = 0 ;
3400+ let imagesUpdated = 0 ;
33963401
3397- for ( const image of images ) {
3402+ for ( const cloudImage of images ) {
33983403 // Check if image already exists locally
3399- const exists = await new Promise < boolean > ( ( resolve ) => {
3404+ const localImage = await new Promise < MobiansImage | null > ( ( resolve ) => {
34003405 const transaction = db . transaction ( this . storeName , 'readonly' ) ;
34013406 const store = transaction . objectStore ( this . storeName ) ;
3402- const request = store . get ( image . UUID ) ;
3403- request . onsuccess = ( ) => resolve ( ! ! request . result ) ;
3404- request . onerror = ( ) => resolve ( false ) ;
3407+ const request = store . get ( cloudImage . UUID ) ;
3408+ request . onsuccess = ( ) => resolve ( request . result || null ) ;
3409+ request . onerror = ( ) => resolve ( null ) ;
34053410 } ) ;
34063411
3407- if ( ! exists ) {
3408- // Add image metadata to ImageStore
3412+ if ( ! localImage ) {
3413+ // Add new image from cloud
34093414 const transaction = db . transaction ( [ this . storeName , 'blobStore' ] , 'readwrite' ) ;
34103415 const imageStore = transaction . objectStore ( this . storeName ) ;
34113416 const blobStore = transaction . objectStore ( 'blobStore' ) ;
34123417
3413- imageStore . put ( image ) ;
3418+ imageStore . put ( cloudImage ) ;
34143419
34153420 // Add blob if available
3416- const blob = blobs . get ( image . UUID ) ;
3421+ const blob = blobs . get ( cloudImage . UUID ) ;
34173422 if ( blob ) {
3418- blobStore . put ( { UUID : image . UUID , blob } ) ;
3423+ blobStore . put ( { UUID : cloudImage . UUID , blob } ) ;
34193424 }
34203425
34213426 imagesAdded ++ ;
3427+ } else {
3428+ // Image exists - update tags and favorite status from cloud
3429+ const tagsChanged = JSON . stringify ( localImage . tags || [ ] ) !== JSON . stringify ( cloudImage . tags || [ ] ) ;
3430+ const favoriteChanged = localImage . favorite !== cloudImage . favorite ;
3431+
3432+ if ( tagsChanged || favoriteChanged ) {
3433+ const transaction = db . transaction ( this . storeName , 'readwrite' ) ;
3434+ const store = transaction . objectStore ( this . storeName ) ;
3435+
3436+ localImage . tags = cloudImage . tags || [ ] ;
3437+ localImage . favorite = cloudImage . favorite ;
3438+ store . put ( localImage ) ;
3439+
3440+ // Update local metadata cache
3441+ const cachedImg = this . imageHistoryMetadata . find ( i => i . UUID === cloudImage . UUID ) ;
3442+ if ( cachedImg ) {
3443+ cachedImg . tags = cloudImage . tags || [ ] ;
3444+ cachedImg . favorite = cloudImage . favorite ;
3445+ }
3446+
3447+ imagesUpdated ++ ;
3448+ }
34223449 }
34233450 }
34243451
3425- if ( imagesAdded > 0 ) {
3426- console . log ( `Merged ${ imagesAdded } cloud images to local storage ` ) ;
3452+ if ( imagesAdded > 0 || imagesUpdated > 0 ) {
3453+ console . log ( `Cloud sync: ${ imagesAdded } images added, ${ imagesUpdated } images updated ` ) ;
34273454 // Refresh image list
34283455 await this . searchImages ( ) ;
34293456 this . currentPageImages = await this . paginateImages ( this . currentPageNumber ) ;
34303457 this . updateFavoriteImages ( ) ;
34313458 await this . updateTagCounts ( ) ;
34323459 }
34333460
3434- return imagesAdded ;
3461+ return imagesAdded + imagesUpdated ;
34353462 } catch ( error ) {
34363463 console . error ( 'Failed to merge cloud images:' , error ) ;
34373464 return 0 ;
@@ -3572,6 +3599,8 @@ export class OptionsComponent implements OnInit {
35723599 const transaction = db . transaction ( this . storeName , 'readwrite' ) ;
35733600 const store = transaction . objectStore ( this . storeName ) ;
35743601
3602+ const updatedImages : { uuid : string ; tags : string [ ] } [ ] = [ ] ;
3603+
35753604 for ( const uuid of this . tagAssignImageUUIDs ) {
35763605 const request = store . get ( uuid ) ;
35773606 await new Promise < void > ( ( resolve ) => {
@@ -3582,6 +3611,7 @@ export class OptionsComponent implements OnInit {
35823611 if ( ! image . tags . includes ( tag . id ) ) {
35833612 image . tags . push ( tag . id ) ;
35843613 store . put ( image ) ;
3614+ updatedImages . push ( { uuid : image . UUID , tags : [ ...image . tags ] } ) ;
35853615
35863616 // Update local metadata
35873617 const localImg = this . imageHistoryMetadata . find ( i => i . UUID === uuid ) ;
@@ -3598,6 +3628,13 @@ export class OptionsComponent implements OnInit {
35983628 } ) ;
35993629 }
36003630
3631+ // Sync tag changes to cloud for synced images
3632+ if ( this . authService . isLoggedIn ( ) && updatedImages . length > 0 ) {
3633+ for ( const { uuid, tags } of updatedImages ) {
3634+ await this . imageSyncService . updateImageMetadata ( uuid , { tags } ) ;
3635+ }
3636+ }
3637+
36013638 // Update tag count
36023639 await this . updateTagCounts ( ) ;
36033640 this . notifyTagsUpdated ( 'assign' , tag . id ) ;
@@ -3619,6 +3656,8 @@ export class OptionsComponent implements OnInit {
36193656 const transaction = db . transaction ( this . storeName , 'readwrite' ) ;
36203657 const store = transaction . objectStore ( this . storeName ) ;
36213658
3659+ const updatedImages : { uuid : string ; tags : string [ ] } [ ] = [ ] ;
3660+
36223661 for ( const uuid of imageUUIDs ) {
36233662 const request = store . get ( uuid ) ;
36243663 await new Promise < void > ( ( resolve ) => {
@@ -3627,6 +3666,7 @@ export class OptionsComponent implements OnInit {
36273666 if ( image && image . tags ) {
36283667 image . tags = image . tags . filter ( t => t !== tag . id ) ;
36293668 store . put ( image ) ;
3669+ updatedImages . push ( { uuid : image . UUID , tags : [ ...image . tags ] } ) ;
36303670
36313671 // Update local metadata
36323672 const localImg = this . imageHistoryMetadata . find ( i => i . UUID === uuid ) ;
@@ -3639,6 +3679,13 @@ export class OptionsComponent implements OnInit {
36393679 } ) ;
36403680 }
36413681
3682+ // Sync tag changes to cloud for synced images
3683+ if ( this . authService . isLoggedIn ( ) && updatedImages . length > 0 ) {
3684+ for ( const { uuid, tags } of updatedImages ) {
3685+ await this . imageSyncService . updateImageMetadata ( uuid , { tags } ) ;
3686+ }
3687+ }
3688+
36423689 await this . updateTagCounts ( ) ;
36433690 this . notifyTagsUpdated ( 'unassign' , tag . id ) ;
36443691 } catch ( error ) {
0 commit comments