Skip to content

Commit 5ec534d

Browse files
committed
feat: add cache for image ribbon gallery to reduce API calls
1 parent eece4c0 commit 5ec534d

File tree

1 file changed

+108
-13
lines changed

1 file changed

+108
-13
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 108 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,6 +1911,16 @@ function RemoteFunctions(config = {}) {
19111911
}
19121912
};
19131913

1914+
// image ribbon gallery cache, to store the last query and its results
1915+
// then next time we can load it from cache itself instead of making a new API call
1916+
const _imageGalleryCache = {
1917+
currentQuery: null,
1918+
allImages: [],
1919+
totalPages: 1,
1920+
currentPage: 1,
1921+
maxImages: 50
1922+
};
1923+
19141924
/**
19151925
* when user clicks on an image we call this,
19161926
* this creates a image ribbon gallery at the bottom of the live preview
@@ -2274,6 +2284,23 @@ function RemoteFunctions(config = {}) {
22742284

22752285
_fetchImages: function(searchQuery, page = 1, append = false) {
22762286
this._currentSearchQuery = searchQuery;
2287+
2288+
if (!append && this._loadFromCache(searchQuery)) { // try cache first
2289+
return;
2290+
}
2291+
if (append && this._loadPageFromCache(searchQuery, page)) { // try to load new page from cache
2292+
return;
2293+
}
2294+
// if unable to load from cache, we make the API call
2295+
this._fetchFromAPI(searchQuery, page, append);
2296+
},
2297+
2298+
_fetchFromAPI: function(searchQuery, page, append) {
2299+
// when we fetch from API, we clear the cache and then store a fresh copy
2300+
if (searchQuery !== _imageGalleryCache.currentQuery) {
2301+
this._clearCache();
2302+
}
2303+
22772304
const apiUrl = `https://images.phcode.dev/api/images/search?q=${encodeURIComponent(searchQuery)}&per_page=10&page=${page}`;
22782305

22792306
if (!append) {
@@ -2299,6 +2326,8 @@ function RemoteFunctions(config = {}) {
22992326
this.totalPages = data.total_pages || 1;
23002327
this.currentPage = page;
23012328
this._updateNavButtons();
2329+
this._updateSearchInput(searchQuery);
2330+
this._updateCache(searchQuery, data, append);
23022331
} else if (!append) {
23032332
this._showError('No images found');
23042333
}
@@ -2319,6 +2348,79 @@ function RemoteFunctions(config = {}) {
23192348
});
23202349
},
23212350

2351+
_updateCache: function(searchQuery, data, append) {
2352+
// Update cache with new data for current query
2353+
_imageGalleryCache.currentQuery = searchQuery;
2354+
_imageGalleryCache.totalPages = data.total_pages || 1;
2355+
_imageGalleryCache.currentPage = this.currentPage;
2356+
2357+
if (append) {
2358+
// Append new results to existing cache
2359+
const newImages = _imageGalleryCache.allImages.concat(data.results);
2360+
2361+
if (newImages.length > _imageGalleryCache.maxImages) { // max = 50
2362+
_imageGalleryCache.allImages = newImages.slice(-_imageGalleryCache.maxImages);
2363+
} else {
2364+
_imageGalleryCache.allImages = newImages;
2365+
}
2366+
} else {
2367+
// new search replace cache
2368+
_imageGalleryCache.allImages = data.results;
2369+
}
2370+
},
2371+
2372+
_clearCache: function() {
2373+
// clear current cache when switching to new query
2374+
_imageGalleryCache.currentQuery = null;
2375+
_imageGalleryCache.allImages = [];
2376+
_imageGalleryCache.totalPages = 1;
2377+
_imageGalleryCache.currentPage = 1;
2378+
},
2379+
2380+
_updateSearchInput: function(searchQuery) {
2381+
// write the current query in the search input
2382+
const searchInput = this._shadow.querySelector('.phoenix-ribbon-search input');
2383+
if (searchInput && searchQuery) {
2384+
searchInput.value = searchQuery;
2385+
searchInput.placeholder = searchQuery;
2386+
}
2387+
},
2388+
2389+
_loadFromCache: function(searchQuery) {
2390+
// Check if we can load from cache for this query
2391+
if (searchQuery === _imageGalleryCache.currentQuery && _imageGalleryCache.allImages.length > 0) {
2392+
this.allImages = _imageGalleryCache.allImages;
2393+
this.totalPages = _imageGalleryCache.totalPages;
2394+
this.currentPage = _imageGalleryCache.currentPage;
2395+
2396+
this._renderImages(this.allImages, false);
2397+
this._updateNavButtons();
2398+
this._updateSearchInput(searchQuery);
2399+
return true; // Successfully loaded from cache
2400+
}
2401+
return false; // unable to load from cache
2402+
},
2403+
2404+
_loadPageFromCache: function(searchQuery, page) {
2405+
// check if this page is in cache
2406+
if (searchQuery === _imageGalleryCache.currentQuery && page <= Math.ceil(_imageGalleryCache.allImages.length / 10)) {
2407+
const startIdx = (page - 1) * 10;
2408+
const endIdx = startIdx + 10;
2409+
const pageImages = _imageGalleryCache.allImages.slice(startIdx, endIdx);
2410+
2411+
if (pageImages.length > 0) {
2412+
this.allImages = this.allImages.concat(pageImages);
2413+
this._renderImages(pageImages, true);
2414+
this.currentPage = page;
2415+
this._updateNavButtons();
2416+
this._isLoadingMore = false;
2417+
this._hideLoadingMore();
2418+
return true; // Successfully loaded page from cache
2419+
}
2420+
}
2421+
return false;
2422+
},
2423+
23222424
_handleNavLeft: function() {
23232425
const container = this._shadow.querySelector('.phoenix-ribbon-strip');
23242426
if (!container) { return; }
@@ -2698,7 +2800,9 @@ function RemoteFunctions(config = {}) {
26982800
this._style();
26992801
window.document.body.appendChild(this.body);
27002802
this._attachEventHandlers();
2701-
this._fetchImages(this._getDefaultQuery());
2803+
2804+
const queryToUse = _imageGalleryCache.currentQuery || this._getDefaultQuery();
2805+
this._fetchImages(queryToUse);
27022806
setTimeout(() => this._updateNavButtons(), 0);
27032807
},
27042808

@@ -3146,7 +3250,9 @@ function RemoteFunctions(config = {}) {
31463250

31473251
// if the selected element is an image, show the image ribbon gallery (make sure its enabled in preferences)
31483252
if(element && element.tagName.toLowerCase() === 'img' && shouldShowImageRibbon()) {
3149-
_imageRibbonGallery = new ImageRibbonGallery(element);
3253+
if (!_imageRibbonGallery) {
3254+
_imageRibbonGallery = new ImageRibbonGallery(element);
3255+
}
31503256
}
31513257

31523258
element._originalOutline = element.style.outline;
@@ -3184,17 +3290,6 @@ function RemoteFunctions(config = {}) {
31843290

31853291
_selectElement(element);
31863292
}
3187-
3188-
// if the image is an element we show the image ribbon gallery (if enabled in preferences)
3189-
if(element && element.tagName.toLowerCase() === 'img' && shouldShowImageRibbon()) {
3190-
event.preventDefault();
3191-
event.stopPropagation();
3192-
event.stopImmediatePropagation();
3193-
3194-
_imageRibbonGallery = new ImageRibbonGallery(element);
3195-
} else {
3196-
dismissImageRibbonGallery();
3197-
}
31983293
}
31993294

32003295
/**

0 commit comments

Comments
 (0)