mirror of
https://github.com/olegvodyanov/instalinks.git
synced 2025-12-20 09:07:04 +03:00
153 lines
4.2 KiB
JavaScript
153 lines
4.2 KiB
JavaScript
const newLinkInput = document.getElementById('newLinkInput');
|
||
const addLinkBtn = document.getElementById('addLinkBtn');
|
||
const newLinksContainer = document.getElementById('newLinksContainer');
|
||
const watchedLinksContainer = document.getElementById('watchedLinksContainer');
|
||
|
||
let linksData = [];
|
||
|
||
// Fetch all links from the server
|
||
function loadLinks() {
|
||
fetch('/api/links/')
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
linksData = data; // store in a global variable
|
||
renderLinks();
|
||
})
|
||
.catch(err => console.error(err));
|
||
}
|
||
|
||
// Render the links into the two tabs
|
||
function renderLinks() {
|
||
// separate them
|
||
const newLinks = linksData.filter(link => !link.watched);
|
||
const watchedLinks = linksData.filter(link => link.watched);
|
||
|
||
const newRow = document.createElement('div');
|
||
newRow.className = 'row gy-4';
|
||
|
||
// Render "New" links
|
||
newLinksContainer.innerHTML = '';
|
||
newLinks.forEach(link => {
|
||
const col = document.createElement('div');
|
||
col.className = 'col-12 col-sm-6 col-md-4 col-lg-3'; // responsive columns
|
||
col.appendChild(createLinkElement(link, false));
|
||
newRow.appendChild(col);
|
||
});
|
||
|
||
newLinksContainer.appendChild(newRow);
|
||
|
||
const watchedRow = document.createElement('div');
|
||
watchedRow.className = 'row gy-4';
|
||
|
||
// Render "Watched" links
|
||
watchedLinksContainer.innerHTML = '';
|
||
watchedLinks.forEach(link => {
|
||
const col = document.createElement('div');
|
||
col.className = 'col-12 col-sm-6 col-md-4 col-lg-3';
|
||
col.appendChild(createLinkElement(link, true));
|
||
watchedRow.appendChild(col);
|
||
});
|
||
|
||
watchedLinksContainer.appendChild(watchedRow);
|
||
|
||
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);
|
||
renderLinks();
|
||
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;
|
||
}
|
||
renderLinks();
|
||
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 = '';
|
||
renderLinks();
|
||
reinitializeInstagramEmbeds();
|
||
})
|
||
.catch(err => console.error(err));
|
||
});
|
||
|
||
// On page load
|
||
loadLinks();
|