"use strict"; // ── state ────────────────────────────────────────────────────────────────── let images = []; let current_idx = 0; let current_query = ""; let current_page = 0; let is_loading = false; let is_fetching_more = false; // ── elements ─────────────────────────────────────────────────────────────── const search_screen = document.getElementById("search_screen"); const gallery_screen = document.getElementById("gallery_screen"); const search_input = document.getElementById("search_input"); const search_btn = document.getElementById("search_btn"); const recents_section= document.getElementById("recents_section"); const recents_list = document.getElementById("recents_list"); const img_track = document.getElementById("img_track"); const img_counter = document.getElementById("img_counter"); const back_btn = document.getElementById("back_btn"); const arrow_left = document.getElementById("arrow_left"); const arrow_right = document.getElementById("arrow_right"); const loading_bar = document.getElementById("loading_bar"); const toast_el = document.getElementById("toast"); // ── recents ──────────────────────────────────────────────────────────────── function load_recents() { return JSON.parse(localStorage.getItem("diashow_recents") || "[]"); } function save_recent(q) { let recents = load_recents().filter(r => r !== q); recents.unshift(q); recents = recents.slice(0, 8); localStorage.setItem("diashow_recents", JSON.stringify(recents)); } function render_recents() { const recents = load_recents(); if (!recents.length) { recents_section.style.display = "none"; return; } recents_section.style.display = "block"; recents_list.innerHTML = recents .map(r => ``) .join(""); } function escape_html(s) { return s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); } // ── loading bar ──────────────────────────────────────────────────────────── let bar_timer = null; function show_loading() { loading_bar.style.width = "0%"; loading_bar.classList.add("active"); loading_bar.style.transition = "none"; requestAnimationFrame(() => { loading_bar.style.transition = "width 1.5s ease-out"; loading_bar.style.width = "75%"; }); } function hide_loading() { loading_bar.style.transition = "width 0.2s ease"; loading_bar.style.width = "100%"; clearTimeout(bar_timer); bar_timer = setTimeout(() => { loading_bar.classList.remove("active"); loading_bar.style.width = "0%"; }, 250); } // ── toast ────────────────────────────────────────────────────────────────── let toast_timer = null; function show_toast(msg) { toast_el.textContent = msg; toast_el.classList.add("show"); clearTimeout(toast_timer); toast_timer = setTimeout(() => toast_el.classList.remove("show"), 3000); } // ── API ──────────────────────────────────────────────────────────────────── async function fetch_images(query, page = 0) { const res = await fetch(`/api/search?q=${encodeURIComponent(query)}&page=${page}`); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); if (data.error) throw new Error(data.error); return data.images || []; } // ── search ───────────────────────────────────────────────────────────────── async function do_search(q) { if (!q.trim() || is_loading) return; q = q.trim(); is_loading = true; show_loading(); search_btn.disabled = true; try { const results = await fetch_images(q); if (!results.length) { show_toast("no images found :/"); return; } save_recent(q); current_query = q; current_page = 0; images = results; current_idx = 0; open_gallery(); } catch (e) { show_toast("fetch failed — " + e.message); } finally { is_loading = false; hide_loading(); search_btn.disabled = false; } } // ── gallery ──────────────────────────────────────────────────────────────── function make_slide(img_data, idx) { const slide = document.createElement("div"); slide.className = "img_slide"; slide.dataset.idx = idx; const el = document.createElement("img"); el.alt = ""; el.loading = "lazy"; el.src = img_data.url; el.onerror = () => { slide.innerHTML = `