// Links tab: your own bookmarks, grouped. Saved with the other per-person settings (see app.js: store).
// ---- 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 = `
Links
${all.length ? '' : '
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 ? `
${esc(g)}
` : (groups.length > 1 ? '
Other
' : '')}
${shown.filter(l => (l.group || '') === g).map(l => `
`).join('')}
`).join('')}
`;
$('#lq').oninput = e => { linkQuery = e.target.value; const p = e.target.selectionStart; viewLinks(); const n = $('#lq'); n.focus(); n.setSelectionRange(p, p); };
$('#ladd').onclick = () => linkSheet();
document.querySelectorAll('[data-edit]').forEach(b => b.onclick = () => linkSheet(all.find(l => l.id === b.dataset.edit)));
}
function linkSheet(link) {
const groups = [...new Set(linkList().map(l => l.group).filter(Boolean))];
const el = openSheet(link ? 'Edit link' : 'Add a link', '', ``);
if (el.querySelector('#sx')) el.querySelector('#sx').onclick = closeSheet;
if (link) el.querySelector('#ld').onclick = () => confirmSheet('Delete link?', link.title, 'Delete', () => { store.set('links', linkList().filter(l => l.id !== link.id)); viewLinks(); });
el.querySelector('#lf').onsubmit = e => {
e.preventDefault();
const url = safeUrl(el.querySelector('#lu').value);
if (!url) { el.querySelector('#le').textContent = 'That is not a web address (it must be http or https).'; return; }
const next = { id: link ? link.id : 'l' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6), title: el.querySelector('#lt').value.trim().slice(0, 60), url, group: el.querySelector('#lg').value.trim().slice(0, 40) };
const rest = linkList();
store.set('links', link ? rest.map(l => l.id === link.id ? next : l) : [...rest, next]);
closeSheet(); viewLinks();
};
}