diff --git a/search-app/live-search.js b/search-app/live-search.js index fd9fb3c..a78a394 100644 --- a/search-app/live-search.js +++ b/search-app/live-search.js @@ -910,7 +910,38 @@ }[c])); } - function injectHeatmapBanner(container) { + // Get (or create) an Immich API key for the heatmap iframe so the user + // isn't prompted to paste one. Cached in this origin's localStorage. + async function getHeatmapApiKey() { + const cached = localStorage.getItem('ls-heatmap-api-key'); + if (cached) return cached; + try { + const r = await fetch('/api/api-keys', { + method: 'POST', + headers: getAuthHeaders(), + credentials: 'include', + body: JSON.stringify({ + name: 'Heatmap iframe (auto)', + permissions: ['asset.read', 'asset.view'] + }) + }); + if (!r.ok) { + console.warn('[live-search] api-key create failed', r.status); + return null; + } + const j = await r.json(); + const secret = j.secret || (j.apiKey && j.apiKey.secret); + if (secret) { + localStorage.setItem('ls-heatmap-api-key', secret); + return secret; + } + } catch (e) { + console.warn('[live-search] api-key create error', e); + } + return null; + } + + async function injectHeatmapBanner(container) { if (container.querySelector('.ls-heatmap-banner')) return; const banner = document.createElement('div'); banner.className = 'ls-heatmap-banner'; @@ -920,16 +951,22 @@ `; + const iframe = banner.querySelector('iframe'); const btn = banner.querySelector('button'); btn.addEventListener('click', () => { banner.classList.toggle('collapsed'); btn.textContent = banner.classList.contains('collapsed') ? 'Expand' : 'Collapse'; }); - container.insertBefore(banner, container.firstChild); + // Append at the END so it lands below People + Places sections. + container.appendChild(banner); + + // Resolve API key then set iframe src. The heatmap app reads ?apiKey + // and seeds its own localStorage, skipping the login prompt. + const key = await getHeatmapApiKey(); + iframe.src = HEATMAP_URL + (key ? '?apiKey=' + encodeURIComponent(key) : ''); } async function enhanceSection(section, kind) {