const feedEl = document.getElementById('feed'); const sortSelect = document.getElementById('sort-select'); const userFilter = document.getElementById('user-filter'); const cookieName = 'linklog-feed-preferences'; function readPreferences() { const cookie = document.cookie .split('; ') .find((row) => row.startsWith(`${cookieName}=`)); if (!cookie) { return { sort: 'newest', user: '' }; } try { return JSON.parse(decodeURIComponent(cookie.split('=')[1])); } catch (error) { return { sort: 'newest', user: '' }; } } function writePreferences(pref) { const value = encodeURIComponent(JSON.stringify(pref)); document.cookie = `${cookieName}=${value}; path=/; max-age=31536000`; } function renderFeed(items) { feedEl.innerHTML = ''; if (!items.length) { feedEl.innerHTML = ''; return; } items.forEach((item) => { const article = document.createElement('article'); article.className = 'link-item'; const header = document.createElement('div'); header.className = 'link-header'; const avatar = document.createElement('div'); avatar.className = 'avatar'; avatar.textContent = (item.user?.username || 'U').slice(0, 1).toUpperCase(); const userName = document.createElement('div'); userName.className = 'user-name'; userName.textContent = item.user?.username || 'unknown'; header.appendChild(avatar); header.appendChild(userName); const title = document.createElement('h2'); const link = document.createElement('a'); link.href = item.url; link.target = '_blank'; link.rel = 'noopener noreferrer'; link.textContent = item.title || item.url; title.appendChild(link); const comment = document.createElement('div'); comment.className = 'comment'; comment.textContent = item.comment || 'No comment provided'; const meta = document.createElement('div'); meta.className = 'meta'; meta.textContent = item.created_at || 'updated recently'; article.appendChild(header); article.appendChild(title); article.appendChild(comment); article.appendChild(meta); feedEl.appendChild(article); }); } async function loadFeed() { const routeUser = document.body.dataset.userFilter; const endpoint = routeUser ? `/api/public/feed/${encodeURIComponent(routeUser)}` : '/api/public/feed'; const response = await fetch(endpoint); const data = await response.json(); let items = data || []; const pref = readPreferences(); if (pref.user && !routeUser) { items = items.filter((item) => (item.user?.username || '').toLowerCase() === pref.user.toLowerCase()); } if (pref.sort === 'oldest') { items = [...items].reverse(); } renderFeed(items); } function syncPreferences() { const pref = readPreferences(); sortSelect.value = pref.sort; userFilter.value = pref.user; sortSelect.addEventListener('change', (event) => { const next = { ...readPreferences(), sort: event.target.value }; writePreferences(next); loadFeed(); }); userFilter.addEventListener('input', (event) => { const next = { ...readPreferences(), user: event.target.value.trim() }; writePreferences(next); loadFeed(); }); } syncPreferences(); loadFeed();