const newLinkInput = document.getElementById('newLinkInput'); const addLinkBtn = document.getElementById('addLinkBtn'); const newLinksContainer = document.getElementById('newLinksContainer'); const watchedLinksContainer = document.getElementById('watchedLinksContainer'); const PER_PAGE = 8; let currentPage = 1; function loadLinks() { fetch('/api/links/?page=${currentPage}&per_page=${PER_PAGE}') .then(res => res.json()) .then(data => { linksData = data.results; renderPaginatedList(linksData, newLinksContainer, false, data.page, data.pages); renderPaginatedList(linksData.filter(l => l.watched), watchedLinksContainer, true, data.page, data.pages); }) .catch(err => console.error(err)); } function renderPaginatedList(linkList, container, isWatched, page, totalPages) { container.innerHTML = ''; const row = document.createElement('div'); row.className = 'row gy-4'; linkList .filter(link => link.watched === isWatched) .forEach(link => { const col = document.createElement('div'); col.className = 'col-12 col-sm-6 col-md-4 col-lg-3'; col.appendChild(createLinkElement(link, isWatched)); row.appendChild(col); }); container.appendChild(row); // Pagination controls if (totalPages > 1) { const nav = document.createElement('div'); nav.className = 'd-flex justify-content-center mt-4 gap-2'; const prevBtn = document.createElement('button'); prevBtn.innerText = '← Previous'; prevBtn.className = 'btn btn-outline-primary'; prevBtn.disabled = page <= 1; prevBtn.onclick = () => { currentPage--; loadLinks(); }; const nextBtn = document.createElement('button'); nextBtn.innerText = 'Next →'; nextBtn.className = 'btn btn-outline-primary'; nextBtn.disabled = page >= totalPages; nextBtn.onclick = () => { currentPage++; loadLinks(); }; nav.appendChild(prevBtn); nav.appendChild(nextBtn); container.appendChild(nav); } reinitializeInstagramEmbeds(); } // Create a DOM element for a single link function createLinkElement(link, isWatched) { const wrapper = document.createElement('div'); wrapper.className = 'mb-3'; // Instagram embed blockquote const blockquote = document.createElement('blockquote'); blockquote.className = 'instagram-media'; blockquote.setAttribute('data-instgrm-permalink', link.url); blockquote.style.background = '#FFF'; const p = document.createElement('p'); p.innerText = 'Loading Instagram...'; blockquote.appendChild(p); wrapper.appendChild(blockquote); // Button to mark watched if it's not watched if (!isWatched) { const watchButton = document.createElement('button'); watchButton.className = 'btn btn-sm btn-secondary'; watchButton.innerText = 'Mark Watched'; watchButton.onclick = () => markLinkWatched(link.id); wrapper.appendChild(watchButton); } // Delete button const deleteButton = document.createElement('button'); deleteButton.innerText = 'Delete'; deleteButton.className = 'btn btn-sm btn-danger'; deleteButton.onclick = () => deleteLink(link.id); wrapper.appendChild(deleteButton); return wrapper; } function deleteLink(linkId) { fetch(`/api/links/${linkId}/delete/`, { method: 'DELETE' }) .then(res => { if (res.ok) { linksData = linksData.filter(link => link.id !== linkId); currentPage = 1; renderPaginatedList(); reinitializeInstagramEmbeds(); } }) .catch(err => console.error(err)); } // Re-run the Instagram embed script after we’ve injected new blockquotes function reinitializeInstagramEmbeds() { if (window.instgrm) { window.instgrm.Embeds.process(); } } // Mark a link as watched function markLinkWatched(linkId) { fetch(`/api/links/${linkId}/watched/`, { method: 'PATCH' }) .then(res => res.json()) .then(updatedLink => { // Update the local array const idx = linksData.findIndex(l => l.id === updatedLink.id); if (idx !== -1) { linksData[idx] = updatedLink; } renderPaginatedList(); reinitializeInstagramEmbeds(); }) .catch(err => console.error(err)); } // Add new link addLinkBtn.addEventListener('click', () => { const newUrl = newLinkInput.value.trim(); if (!newUrl) return; fetch('/api/links/add/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: newUrl }) }) .then(res => res.json()) .then(addedLink => { // update local data linksData.push(addedLink); newLinkInput.value = ''; currentPage = 1; renderPaginatedList(); reinitializeInstagramEmbeds(); }) .catch(err => console.error(err)); }); // On page load loadLinks();