/* 全局搜索页逻辑: 防抖搜索 + 项目/release/issue 三段结果. * renderProjectCard 由模板内联 module 注入. */ import { debounce, fetchJson, escapeHtml, truncate } from "../utils.js"; export function initSearchPage(renderProjectCard) { function renderResults(data) { const hint = document.getElementById("searchHint"); const results = document.getElementById("searchResults"); const total = data.projects.length + data.releases.length + data.issues.length; if (!total) { results.classList.add("d-none"); hint.classList.remove("d-none"); hint.textContent = "没有找到匹配结果"; return; } hint.classList.add("d-none"); results.classList.remove("d-none"); document.getElementById("projCount").textContent = data.projects.length; document.getElementById("relCount").textContent = data.releases.length; document.getElementById("issueCount").textContent = data.issues.length; document.getElementById("resultProjects").innerHTML = data.projects.length ? data.projects .map((p) => renderProjectCard(p, { showSubtitle: false, showForks: false }) ) .join("") : '
无匹配项目
'; document.getElementById("resultReleases").innerHTML = data.releases.length ? data.releases .map( (r) => `
  • ${escapeHtml(r.tag_name || "")} ${escapeHtml(truncate(r.name, 60))} 查看项目
  • ` ) .join("") : '
  • 无匹配 release
  • '; document.getElementById("resultIssues").innerHTML = data.issues.length ? data.issues .map( (i) => `
  • ${escapeHtml(i.state || "")} ${escapeHtml(truncate(i.title, 80))} 查看项目
  • ` ) .join("") : '
  • 无匹配 issue
  • '; } async function doSearch(keyword) { const hint = document.getElementById("searchHint"); const results = document.getElementById("searchResults"); if (!keyword) { results.classList.add("d-none"); hint.classList.remove("d-none"); hint.textContent = "输入关键词开始搜索"; return; } try { hint.classList.remove("empty-hint-error"); const data = await fetchJson(`/api/search?q=${encodeURIComponent(keyword)}`); renderResults(data); } catch (err) { console.error("搜索失败:", err); results.classList.add("d-none"); hint.classList.remove("d-none"); hint.classList.add("empty-hint-error"); hint.innerHTML = '加载失败, '; const retryBtn = document.getElementById("searchRetryBtn"); if (retryBtn) retryBtn.addEventListener("click", () => doSearch(keyword)); } } const debouncedSearch = debounce(doSearch, 300); document.addEventListener("DOMContentLoaded", () => { const input = document.getElementById("searchInput"); input.addEventListener("input", (e) => debouncedSearch(e.target.value.trim())); // Support ?q= from the navbar search box. const params = new URLSearchParams(window.location.search); const q = params.get("q"); if (q) { input.value = q; doSearch(q.trim()); } }); }