Update web/templates/search.html

This commit is contained in:
Joshua Laymon 2025-09-09 01:51:14 +00:00
parent fc82767666
commit 0ffecb9100

View File

@ -23,9 +23,7 @@
<!-- Mobile dropdown filters -->
<div class="filter-row mobile-filters">
<button type="button" id="filterDropdownBtn" class="btn btn-secondary dropdown-toggle" aria-expanded="false">
Filters ▾
</button>
<button type="button" id="filterDropdownBtn" class="btn btn-secondary" aria-expanded="false">Filters ▾</button>
<div id="filterDropdownPanel" class="dropdown-panel">
{% for f in field_options %}
<label class="check-pill" style="display:block; margin:6px 0;">
@ -125,7 +123,7 @@
return url + sep + 't=' + Date.now();
}
// Search history
// Search history (keeps selected-fields subtitle)
function renderHistory(items){
const list = document.getElementById('searchHistoryList');
const empty = document.getElementById('searchHistoryEmpty');
@ -213,7 +211,7 @@
});
});
// Dropdown toggle for mobile filters
// Mobile filter dropdown toggle
(function(){
const btn = document.getElementById('filterDropdownBtn');
const panel = document.getElementById('filterDropdownPanel');
@ -248,6 +246,99 @@
el.textContent = pick;
})();
/* ===============================
Illustration of the Day (client-only, deterministic)
=============================== */
(function illustrationOfTheDay(){
const total = {{ total|default:0 }};
const iotdTextEl = document.getElementById('iotd-text');
const iotdOpenEl = document.getElementById('iotd-open');
if (!iotdTextEl || !iotdOpenEl) return;
if (!total || total < 1){
iotdTextEl.textContent = 'No illustrations available yet.';
iotdOpenEl.style.display = 'none';
return;
}
// Seed from local date (YYYYMMDD) so its the same for everyone that day
const today = new Date();
const ymd = today.getFullYear()*10000 + (today.getMonth()+1)*100 + today.getDate();
// 32-bit xorshift PRNG for a good daily seed
function xorshift32(seed){
let x = seed | 0;
x ^= x << 13; x ^= x >>> 17; x ^= x << 5;
return (x >>> 0);
}
const seed = xorshift32(ymd ^ 0x9E3779B9);
const maxGuess = Math.max(100, Math.floor(total * 4));
const maxAttempts = Math.min(600, maxGuess);
function idAt(i){
const v = (Math.imul(i + 1, 1103515245) + 12345 + seed) >>> 0;
return 1 + (v % maxGuess);
}
async function fetchEntryHtml(id){
const url = entryUrlFor(id);
try{
const r = await fetch(url, { credentials: 'same-origin' });
if (r.ok) return await r.text();
}catch(_){}
return null;
}
function ensurePunct(str){
const s = (str || '').trim();
if (!s) return '';
return /[.!?…]$/.test(s) ? s : (s + '.');
}
function extractSectionText(doc, label){
const labels = doc.querySelectorAll('.section-label, .meta-label, h3, h4, strong');
for (const el of labels){
const t = (el.textContent || '').trim().toLowerCase();
if (t === label){
const section = el.closest('.section') || el.parentElement;
if (section){
const body = section.querySelector('.lead-text') ||
section.querySelector('.section-body') ||
section.querySelector('p');
if (body) return (body.textContent || '').trim();
}
}
}
const alt = doc.querySelector('.lead-text, .section-body');
return alt ? (alt.textContent || '').trim() : '';
}
function renderIotd(id, html){
const dom = new DOMParser().parseFromString(html, 'text/html');
const illustration = extractSectionText(dom, 'illustration');
const application = extractSectionText(dom, 'application');
const merged = (ensurePunct(illustration) + (application ? ' ' + application : '')).trim();
iotdTextEl.textContent = merged || 'Open to view todays illustration.';
iotdOpenEl.href = entryUrlFor(id);
iotdOpenEl.style.display = 'inline-block';
}
(async function findAndRender(){
for (let i = 0; i < maxAttempts; i++){
const id = idAt(i);
const html = await fetchEntryHtml(id);
if (html){
renderIotd(id, html);
return;
}
}
iotdTextEl.textContent = 'Unable to load todays illustration.';
iotdOpenEl.style.display = 'none';
})();
})();
})();
</script>
@ -289,12 +380,34 @@
margin-top:6px;
padding:10px;
}
#filterDropdownBtn {
width:100%;
text-align:left;
}
#filterDropdownBtn { width:100%; text-align:left; }
}
</style>
<!-- Save q + selected fields exactly as submitted -->
<script>
(function(){
const form = document.querySelector('form.search-form') || document.querySelector('form[method="get"]');
if (!form) return;
const qInput = form.querySelector('input[name="q"]');
form.addEventListener('submit', () => {
const fd = new FormData(form);
const fields = [];
for (const [k, v] of fd.entries()) {
if (k.startsWith('sel[') && k.endsWith(']') && (v === 'on' || v === 'true' || v === '1')) {
fields.push(k.slice(4, -1));
}
}
const q = (qInput && qInput.value || '').trim();
try {
localStorage.setItem('lastSearchQ', q);
localStorage.setItem('lastSearchFields', JSON.stringify(fields));
} catch (_) {}
});
})();
</script>
{% include "partials/announcement_modal.html" %}
{% endblock %}