mirror of
https://github.com/olegvodyanov/instalinks.git
synced 2025-12-20 07:57:04 +03:00
Compare commits
2 Commits
12b1d78b67
...
8720c08250
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8720c08250 | ||
|
|
79f8ca6ecf |
@ -20,6 +20,7 @@ def links_list(request):
|
|||||||
try:
|
try:
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
per_page = int(request.GET.get('per_page', 8))
|
per_page = int(request.GET.get('per_page', 8))
|
||||||
|
watched = bool(request.GET.get('watched', ""))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return JsonResponse({'error': 'Invalid page or per_page'}, status=400)
|
return JsonResponse({'error': 'Invalid page or per_page'}, status=400)
|
||||||
|
|
||||||
@ -28,7 +29,8 @@ def links_list(request):
|
|||||||
|
|
||||||
all_links = Link.objects.all().order_by('-id') # latest first
|
all_links = Link.objects.all().order_by('-id') # latest first
|
||||||
total = all_links.count()
|
total = all_links.count()
|
||||||
results = list(all_links[offset:limit].values('id', 'url', 'watched'))
|
limit_results = list(all_links[offset:limit].values('id', 'url', 'watched'))
|
||||||
|
results = filter(lambda row: row['watched'] == str(watched), limit_results)
|
||||||
|
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'results': results,
|
'results': results,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ const newLinksContainer = document.getElementById('newLinksContainer');
|
|||||||
const watchedLinksContainer = document.getElementById('watchedLinksContainer');
|
const watchedLinksContainer = document.getElementById('watchedLinksContainer');
|
||||||
|
|
||||||
const PER_PAGE = 8;
|
const PER_PAGE = 8;
|
||||||
|
const WATCHED = false;
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
let linksData = [];
|
let linksData = [];
|
||||||
|
|
||||||
@ -14,32 +15,50 @@ function extractReelId(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadLinks() {
|
function loadLinks() {
|
||||||
|
const cacheKeyWatched = `links_cache_page_${currentPage}_per_${PER_PAGE}&watched='true'`;
|
||||||
|
const cachedWatched = localStorage.getItem(cacheKeyWatched);
|
||||||
|
|
||||||
const cacheKey = `links_cache_page_${currentPage}_per_${PER_PAGE}`;
|
const cacheKey = `links_cache_page_${currentPage}_per_${PER_PAGE}`;
|
||||||
const cached = localStorage.getItem(cacheKey);
|
const cached = localStorage.getItem(cacheKey);
|
||||||
|
|
||||||
|
if (cachedWatched) {
|
||||||
|
const data = JSON.parse(cachedWatched);
|
||||||
|
linksData = data.results;
|
||||||
|
renderPaginatedList(
|
||||||
|
linksData,watchedLinksContainer,true,data.page,data.pages
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const data = JSON.parse(cached);
|
const data = JSON.parse(cached);
|
||||||
linksData = data.results;
|
linksData = data.results;
|
||||||
renderPaginatedList(
|
renderPaginatedList(
|
||||||
linksData.filter(l => !l.watched),newLinksContainer,false,data.page,data.pages
|
linksData,watchedLinksContainer,true,data.page,data.pages
|
||||||
);
|
|
||||||
renderPaginatedList(
|
|
||||||
linksData.filter(l => l.watched),watchedLinksContainer,true,data.page,data.pages
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always fetch fresh data in the background
|
// Always fetch fresh data in the background
|
||||||
|
fetch(`/api/links/?page=${currentPage}&per_page=${PER_PAGE}&watched='true'`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
localStorage.setItem(cacheKeyWatched, JSON.stringify(data));
|
||||||
|
if (!cachedWatched) {
|
||||||
|
linksData = data.results;
|
||||||
|
renderPaginatedList(
|
||||||
|
linksData,watchedLinksContainer,true,data.page,data.pages
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
|
||||||
fetch(`/api/links/?page=${currentPage}&per_page=${PER_PAGE}`)
|
fetch(`/api/links/?page=${currentPage}&per_page=${PER_PAGE}`)
|
||||||
.then(res => res.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
localStorage.setItem(cacheKey, JSON.stringify(data));
|
localStorage.setItem(cacheKey, JSON.stringify(data));
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
linksData = data.results;
|
linksData = data.results;
|
||||||
renderPaginatedList(
|
renderPaginatedList(
|
||||||
linksData.filter(l => !l.watched),newLinksContainer,false,data.page,data.pages
|
linksData,newLinksContainer,false,data.page,data.pages
|
||||||
);
|
|
||||||
renderPaginatedList(
|
|
||||||
linksData.filter(l => l.watched),watchedLinksContainer,true,data.page,data.pages
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -68,11 +87,11 @@ function renderPaginatedList(linkList, container, isWatched, page, totalPages) {
|
|||||||
const navigation = document.createElement('div');
|
const navigation = document.createElement('div');
|
||||||
navigation.className = 'd-flex justify-content-center mt-4 gap-2';
|
navigation.className = 'd-flex justify-content-center mt-4 gap-2';
|
||||||
|
|
||||||
const prevBtn = document.createElement('button');
|
const previousBtn = document.createElement('button');
|
||||||
prevBtn.innerText = '← Previous';
|
previousBtn.innerText = '← Previous';
|
||||||
prevBtn.className = 'btn btn-outline-primary';
|
previousBtn.className = 'btn btn-outline-primary';
|
||||||
prevBtn.disabled = page <= 1;
|
previousBtn.disabled = page <= 1;
|
||||||
prevBtn.onclick = () => {
|
previousBtn.onclick = () => {
|
||||||
currentPage--;
|
currentPage--;
|
||||||
loadLinks();
|
loadLinks();
|
||||||
};
|
};
|
||||||
@ -86,7 +105,7 @@ function renderPaginatedList(linkList, container, isWatched, page, totalPages) {
|
|||||||
loadLinks();
|
loadLinks();
|
||||||
};
|
};
|
||||||
|
|
||||||
navigation.appendChild(prevBtn);
|
navigation.appendChild(previousBtn);
|
||||||
navigation.appendChild(nextBtn);
|
navigation.appendChild(nextBtn);
|
||||||
container.appendChild(navigation);
|
container.appendChild(navigation);
|
||||||
}
|
}
|
||||||
@ -152,8 +171,8 @@ function deleteLink(linkId) {
|
|||||||
fetch(`/api/links/${linkId}/delete/`, {
|
fetch(`/api/links/${linkId}/delete/`, {
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(response => {
|
||||||
if (res.ok) {
|
if (response.ok) {
|
||||||
linksData = linksData.filter(link => link.id !== linkId);
|
linksData = linksData.filter(link => link.id !== linkId);
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
loadLinks();
|
loadLinks();
|
||||||
@ -175,10 +194,10 @@ function markLinkWatched(linkId) {
|
|||||||
fetch(`/api/links/${linkId}/watched/`, {
|
fetch(`/api/links/${linkId}/watched/`, {
|
||||||
method: 'PATCH'
|
method: 'PATCH'
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(response => response.json())
|
||||||
.then(updatedLink => {
|
.then(updatedLink => {
|
||||||
// Update the local array
|
// Update the local array
|
||||||
const idx = linksData.findIndex(l => l.id === updatedLink.id);
|
const idx = linksData.findIndex(link => link.id === updatedLink.id);
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
linksData[idx] = updatedLink;
|
linksData[idx] = updatedLink;
|
||||||
}
|
}
|
||||||
@ -198,7 +217,7 @@ addLinkBtn.addEventListener('click', () => {
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ url: newUrl })
|
body: JSON.stringify({ url: newUrl })
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(response => response.json())
|
||||||
.then(addedLink => {
|
.then(addedLink => {
|
||||||
// update local data
|
// update local data
|
||||||
linksData.push(addedLink);
|
linksData.push(addedLink);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user