Skip to content

Commit e76af8e

Browse files
Copilotlstein
andauthored
Fix deleted bookmarked images remaining visible in grid view due to browser caching (#188)
* Initial plan * Fix deleted images not removed from grid view by reordering events Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add grid position preservation when deleting images Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix code review issues: handle edge case and remove duplicate property Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Make edge case handling more explicit for empty album Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add debug logging and concurrent reset guard to diagnose issue Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add more detailed debug logging for slide removal and loading Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add cache-busting to thumbnails after deletion to prevent stale images Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Remove debug logging now that issue is resolved Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
1 parent ef018ce commit e76af8e

4 files changed

Lines changed: 466 additions & 10 deletions

File tree

photomap/frontend/static/javascript/bookmarks.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,13 +533,20 @@ class BookmarkManager {
533533
}
534534
}
535535

536-
// Clear bookmarks after successful deletion
537-
this.clearBookmarks();
538-
539-
// Trigger album refresh
536+
// Trigger album refresh BEFORE clearing bookmarks
537+
// This ensures slideState.totalAlbumImages is updated before any grid refreshes
538+
// Pass deletedIndices to allow position preservation
540539
window.dispatchEvent(new CustomEvent("albumChanged", {
541-
detail: { album: state.album, totalImages: slideState.totalAlbumImages - indices.length }
540+
detail: {
541+
album: state.album,
542+
totalImages: slideState.totalAlbumImages - indices.length,
543+
changeType: 'deletion',
544+
deletedIndices: indices
545+
}
542546
}));
547+
548+
// Clear bookmarks after album refresh
549+
this.clearBookmarks();
543550

544551
} catch (error) {
545552
console.error("Delete failed:", error);

photomap/frontend/static/javascript/grid-view.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class GridViewManager {
3333
this.currentColumns = 0;
3434
this.suppressSlideChange = false;
3535
this.batchLoading = false;
36+
this.resetInProgress = false; // Guard against concurrent resets
37+
this.cacheBreaker = Date.now(); // Cache breaker for thumbnail URLs
3638
this.slideData = {};
3739
this.GRID_MAX_SCREENS = 6;
3840

@@ -219,7 +221,11 @@ class GridViewManager {
219221
}
220222
);
221223

222-
this.addEventListener(window, "albumChanged", async () => {
224+
this.addEventListener(window, "albumChanged", async (e) => {
225+
// Update cache breaker to force thumbnail reload, especially for deletions
226+
if (e.detail?.changeType === 'deletion') {
227+
this.cacheBreaker = Date.now();
228+
}
223229
await this.resetAllSlides();
224230
});
225231

@@ -361,6 +367,13 @@ class GridViewManager {
361367
if (!this.gridInitialized) return;
362368
if (!this.swiper) return;
363369
if (!this.isVisible()) return;
370+
371+
// Guard against concurrent resets
372+
if (this.resetInProgress) {
373+
return;
374+
}
375+
376+
this.resetInProgress = true;
364377

365378
showSpinner();
366379

@@ -393,6 +406,7 @@ class GridViewManager {
393406
}
394407

395408
hideSpinner();
409+
this.resetInProgress = false;
396410
}
397411

398412
async loadBatch(startIndex = null, append = true) {
@@ -617,7 +631,7 @@ class GridViewManager {
617631
}
618632

619633
makePlaceholderSlideHTML(globalIndex) {
620-
const thumbnail_url = `thumbnails/${state.album}/${globalIndex}?size=${this.slideHeight}`;
634+
const thumbnail_url = `thumbnails/${state.album}/${globalIndex}?size=${this.slideHeight}&t=${this.cacheBreaker}`;
621635
return `
622636
<div class="swiper-slide" style="width:${this.slideHeight}px; height:${
623637
this.slideHeight
@@ -643,7 +657,7 @@ class GridViewManager {
643657
data.searchIndex = slideState.globalToSearch(globalIndex);
644658
this.slideData[globalIndex] = data;
645659

646-
const thumbnail_url = `thumbnails/${state.album}/${globalIndex}?size=${this.slideHeight}`;
660+
const thumbnail_url = `thumbnails/${state.album}/${globalIndex}?size=${this.slideHeight}&t=${this.cacheBreaker}`;
647661
return `
648662
<div class="swiper-slide" style="width:${this.slideHeight}px; height:${
649663
this.slideHeight

photomap/frontend/static/javascript/slide-state.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,29 @@ class SlideStateManager {
243243
}
244244

245245
handleAlbumChanged(detail) {
246-
this.currentGlobalIndex = 0;
247-
this.currentSearchIndex = 0;
246+
// For deletions, try to preserve position by calculating how many images before current were deleted
247+
if (detail.changeType === 'deletion' && detail.deletedIndices && !this.isSearchMode) {
248+
const deletedIndices = detail.deletedIndices;
249+
const currentIndex = this.currentGlobalIndex;
250+
251+
// Count how many deleted images were before the current position
252+
const deletedBefore = deletedIndices.filter(idx => idx < currentIndex).length;
253+
254+
// Adjust current position by subtracting deleted images before it
255+
const newIndex = Math.max(0, currentIndex - deletedBefore);
256+
257+
// Clamp to new total, ensuring non-negative
258+
// Handle edge case where all images are deleted (totalImages = 0)
259+
this.currentGlobalIndex = detail.totalImages > 0
260+
? Math.max(0, Math.min(newIndex, detail.totalImages - 1))
261+
: 0;
262+
this.currentSearchIndex = 0;
263+
} else {
264+
// For other changes (album switch, move, etc.), reset to beginning
265+
this.currentGlobalIndex = 0;
266+
this.currentSearchIndex = 0;
267+
}
268+
248269
this.exitSearchMode();
249270
this.totalAlbumImages = detail.totalImages; // Update from state
250271
}

0 commit comments

Comments
 (0)