oleg.vodyanov91@gmail.com 8e9a052d34 fix
2025-04-23 10:42:00 +04:00

167 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 weve 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();