show a lightning icon on recent searches that will load instantly

This commit is contained in:
Jonathan Sykes
2026-09-30 00:18:22 +08:00
parent 6ff9f86bd8
commit 74777ef87f
2 changed files with 12 additions and 4 deletions

View File

@@ -145,6 +145,9 @@ const RecentSearches = (() => {
const hit = loadResults()[norm(q)]; const hit = loadResults()[norm(q)];
return hit && Array.isArray(hit.results) && hit.results.length ? hit : null; return hit && Array.isArray(hit.results) && hit.results.length ? hit : null;
}, },
// Normalized queries that have a cached result set — one localStorage
// read for the whole dropdown, rather than one per row.
cachedQueries() { return new Set(Object.keys(loadResults())); },
}; };
})(); })();
@@ -8622,11 +8625,15 @@ function wireUI() {
function renderRecentSearches() { function renderRecentSearches() {
const list = RecentSearches.list(); const list = RecentSearches.list();
if (!list.length) { els.searchRecent.innerHTML = ''; return; } if (!list.length) { els.searchRecent.innerHTML = ''; return; }
els.searchRecent.innerHTML = list.map((q) => ` const cachedQueries = RecentSearches.cachedQueries();
<div class="search-recent-row" data-q="${escapeHtml(q)}" role="option"> els.searchRecent.innerHTML = list.map((q) => {
<span class="sr-icon">🕐</span><span class="sr-text">${escapeHtml(q)}</span> const isCached = cachedQueries.has(q.trim().toLowerCase());
return `
<div class="search-recent-row${isCached ? ' is-cached' : ''}" data-q="${escapeHtml(q)}" role="option">
<span class="sr-icon" title="${isCached ? 'Loads instantly, then refreshes' : 'Recent search'}">${isCached ? '⚡' : '🕐'}</span><span class="sr-text">${escapeHtml(q)}</span>
<button type="button" class="sr-remove" data-remove="${escapeHtml(q)}" aria-label="Remove ‘${escapeHtml(q)}’ from recent searches">✕</button> <button type="button" class="sr-remove" data-remove="${escapeHtml(q)}" aria-label="Remove ‘${escapeHtml(q)}’ from recent searches">✕</button>
</div>`).join('') + '<button type="button" class="search-recent-clear" data-clear-all>Clear recent searches</button>'; </div>`;
}).join('') + '<button type="button" class="search-recent-clear" data-clear-all>Clear recent searches</button>';
} }
function showRecentSearches() { function showRecentSearches() {
renderRecentSearches(); renderRecentSearches();

View File

@@ -304,6 +304,7 @@ body::after {
} }
.search-recent-row:hover, .search-recent-row:focus-visible { background: var(--bg-3); color: var(--text); } .search-recent-row:hover, .search-recent-row:focus-visible { background: var(--bg-3); color: var(--text); }
.search-recent-row .sr-icon { flex-shrink: 0; opacity: 0.55; font-size: 12px; } .search-recent-row .sr-icon { flex-shrink: 0; opacity: 0.55; font-size: 12px; }
.search-recent-row.is-cached .sr-icon { opacity: 0.85; color: var(--accent); }
.search-recent-row .sr-text { .search-recent-row .sr-text {
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;