diff --git a/public/app.js b/public/app.js index a774e90..faa87f9 100644 --- a/public/app.js +++ b/public/app.js @@ -246,6 +246,7 @@ function viewHome() { const t = typeof cur === 'function' ? cur() : null; $('#view').innerHTML = `
${esc(e)}
`).join(''); - res.innerHTML = card + sec('Tasks', taskHtml) + sec('Events', eventHtml) + sec('Libraries', libHtml) + sec('Files', fileHtml) + sec('Music', musicHtml) + notes; - if (!taskHtml && !eventHtml && !libHtml && !fileHtml && !musicHtml && !card) res.innerHTML = 'No results. The line above shows what was searched.
' + notes; + const linkHtml = allowed('links') ? linkList().filter(l => (l.title + ' ' + l.url + ' ' + (l.group || '')).toLowerCase().includes(lower)).slice(0, 8).map(l => `${icon('link')}${esc(l.title || l.url)}${esc(new URL(safeUrl(l.url)).host)}${l.group ? ' · ' + esc(l.group) : ''}`).join('') : ''; + res.innerHTML = card + sec('Tasks', taskHtml) + sec('Links', linkHtml) + sec('Events', eventHtml) + sec('Libraries', libHtml) + sec('Files', fileHtml) + sec('Music', musicHtml) + notes; + if (!taskHtml && !linkHtml && !eventHtml && !libHtml && !fileHtml && !musicHtml && !card) res.innerHTML = 'No results. The line above shows what was searched.
' + notes; res.querySelectorAll('button[data-f]').forEach(b => b.onclick = () => { const [r, p, n, dd] = JSON.parse(b.dataset.f); openFile(r, p, n, dd); }); res.querySelectorAll('button[data-t]').forEach(b => b.onclick = () => playQueue([JSON.parse(b.dataset.t)], 0)); res.querySelectorAll('button[data-tl]').forEach(b => b.onclick = () => { store.set('task_list', b.dataset.tl); location.hash = '#/tasks'; }); @@ -642,48 +646,6 @@ const dueInfo = d => { if (!d) return null; const t = ymd(new Date()); const lab return d < t ? { text: 'Overdue · ' + label, color: 'var(--danger)' } : d === t ? { text: 'Today', color: 'var(--accent)' } : { text: label, color: 'var(--muted)' }; }; const taskStore = []; // tasks on screen, so a tap can open the right one -// ---- Links: your own bookmarks, grouped, saved with your other settings (private to you, every device) -const safeUrl = s => { let t = String(s || '').trim(); if (!t) return ''; if (!/^[a-z][a-z0-9+.-]*:/i.test(t)) t = 'https://' + t; try { const u = new URL(t); return /^https?:$/.test(u.protocol) ? u.href : ''; } catch { return ''; } }; -const linkList = () => { const l = store.get('links', []); return Array.isArray(l) ? l.filter(x => x && safeUrl(x.url)) : []; }; -const LINK_COLORS = ['#4f7cff', '#2f9e6e', '#e0742b', '#d9453a', '#8a5cf0', '#e5a00d', '#0f9d9a', '#c2417a']; -const linkColor = l => LINK_COLORS[[...String(l.title || l.url)].reduce((n, c) => n + c.charCodeAt(0), 0) % LINK_COLORS.length]; -let linkQuery = ''; -function viewLinks() { - const all = linkList(), q = linkQuery.trim().toLowerCase(); - const shown = q ? all.filter(l => (l.title + ' ' + l.url + ' ' + (l.group || '')).toLowerCase().includes(q)) : all; - const groups = [...new Set(shown.map(l => l.group || ''))].sort((a, b) => (a === '') - (b === '') || a.localeCompare(b)); - $('#view').innerHTML = `No links yet. Add the sites you use most; they are saved on your server and show up on every device.
'} - ${all.length && !shown.length ? 'Nothing matches.
' : ''} - ${groups.map(g => `${g ? `Loading…