Pagination for known spam works well enough
This commit is contained in:
parent
efe46f5c0e
commit
dd651d5cac
|
@ -8,7 +8,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>Hello World</h1>
|
<h1>Spam Noticer</h1>
|
||||||
<div class="info-container"></div>
|
<div class="info-container"></div>
|
||||||
</header>
|
</header>
|
||||||
<main></main>
|
<main></main>
|
||||||
|
|
225
script.js
225
script.js
|
@ -108,7 +108,7 @@ function resolvePath(routes, path, query_params) {
|
||||||
|
|
||||||
function resolve(path_data, route_part) {
|
function resolve(path_data, route_part) {
|
||||||
console.log('calling content');
|
console.log('calling content');
|
||||||
console.log(path_data, route_part);
|
console.log(path_data, route_part, query_params);
|
||||||
route_part.content(path_data, query_params);
|
route_part.content(path_data, query_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +140,165 @@ var ROUTES = RoutePart(
|
||||||
, handlePageRoot
|
, handlePageRoot
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pagination
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createPagination(start_page_num, url, name, page_size, renderContent) {
|
||||||
|
const numDisplayedPages = 5; // Specify the number of numbered links to display
|
||||||
|
|
||||||
|
// Helper function to update the URL with the new page number
|
||||||
|
function updatePageNumberInURL(pageNum) {
|
||||||
|
let params;
|
||||||
|
|
||||||
|
if (window.location.search == "") {
|
||||||
|
params = {}
|
||||||
|
} else {
|
||||||
|
console.log("calling parseQueryParams. window.location.search:", window.location.search);
|
||||||
|
params = parseQueryParams(window.location.search.substring(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("updatePageNumberInURL", params);
|
||||||
|
params[name.replaceAll(' ', '_')] = pageNum;
|
||||||
|
changeUrl("/", params, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPaginationControls(page_num, dataset_size) {
|
||||||
|
const container = div();
|
||||||
|
container.classList.add('pagination');
|
||||||
|
|
||||||
|
// Calculate the total number of pages
|
||||||
|
const total_pages = Math.ceil(dataset_size / page_size);
|
||||||
|
console.log('page_num:', page_num, 'page_size:', page_size, 'dataset_size:', dataset_size, 'total_pages:', total_pages);
|
||||||
|
|
||||||
|
function createNumberedLink(pageNum) {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
|
||||||
|
link.addEventListener('click', function(e) {
|
||||||
|
//loadNthPage(url, pageNum - 1, page_size)
|
||||||
|
e.preventDefault();
|
||||||
|
updatePageNumberInURL(pageNum - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
link.appendChild(text(pageNum));
|
||||||
|
|
||||||
|
if (pageNum - 1 === page_num) {
|
||||||
|
link.classList.add('active'); // Apply CSS class for active page
|
||||||
|
} else {
|
||||||
|
link.setAttribute('href', '#');
|
||||||
|
}
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Previous link if applicable
|
||||||
|
if (page_num > 0) {
|
||||||
|
const prev_link = document.createElement('a');
|
||||||
|
prev_link.setAttribute('href', '#');
|
||||||
|
|
||||||
|
prev_link.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
//loadNthPage(url, page_num - 1, page_size)
|
||||||
|
updatePageNumberInURL(page_num - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
prev_link.appendChild(text('Previous'));
|
||||||
|
container.appendChild(prev_link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add numbered links
|
||||||
|
const firstDisplayedPage = Math.max(1, page_num - Math.floor(numDisplayedPages / 2));
|
||||||
|
const lastDisplayedPage = Math.min(total_pages, firstDisplayedPage + numDisplayedPages - 1);
|
||||||
|
|
||||||
|
if (firstDisplayedPage > 1) {
|
||||||
|
container.appendChild(createNumberedLink(1));
|
||||||
|
|
||||||
|
if (firstDisplayedPage > 2) {
|
||||||
|
container.appendChild(text('...'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = firstDisplayedPage; i <= lastDisplayedPage; i++) {
|
||||||
|
container.appendChild(createNumberedLink(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastDisplayedPage < total_pages) {
|
||||||
|
if (lastDisplayedPage < total_pages - 1) {
|
||||||
|
container.appendChild(text('...'));
|
||||||
|
}
|
||||||
|
|
||||||
|
container.appendChild(createNumberedLink(total_pages));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Next link if applicable
|
||||||
|
if (page_num < total_pages - 1) {
|
||||||
|
const next_link = document.createElement('a');
|
||||||
|
next_link.setAttribute('href', '#');
|
||||||
|
|
||||||
|
next_link.addEventListener('click', function(e) {
|
||||||
|
//loadNthPage(url, page_num + 1, page_size)
|
||||||
|
e.preventDefault();
|
||||||
|
updatePageNumberInURL(page_num + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
next_link.appendChild(text('Next'));
|
||||||
|
container.appendChild(next_link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNthPage(url, page_num) {
|
||||||
|
// Calculate the range of results based on the current page
|
||||||
|
const start = page_num * page_size;
|
||||||
|
const end = start + page_size - 1;
|
||||||
|
|
||||||
|
var headers = {
|
||||||
|
'Authorization': 'Bearer ' + GlobalVars.settings.jwt,
|
||||||
|
//'Prefer': 'count=estimated',
|
||||||
|
'Prefer': 'count=exact',
|
||||||
|
'Range-Unit': 'items',
|
||||||
|
'Range': `${start}-${end}`
|
||||||
|
};
|
||||||
|
|
||||||
|
pageInfoText.innerText = `Loading page ${page_num} of ${name}`;
|
||||||
|
cancelGlobalEvts();
|
||||||
|
|
||||||
|
if (page_num > 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return get(url, cancel, headers)
|
||||||
|
.then(function(response) {
|
||||||
|
// Retrieve the range and total number of results from the HTTP headers
|
||||||
|
const rangeHeader = response.getResponseHeader('Content-Range');
|
||||||
|
const [start, end, total_results] = parseRangeHeader(rangeHeader);
|
||||||
|
const json = JSON.parse(response.responseText);
|
||||||
|
const controlsA = createPaginationControls(page_num, total_results);
|
||||||
|
const controlsB = createPaginationControls(page_num, total_results);
|
||||||
|
renderContent(json, controlsA, controlsB);
|
||||||
|
pageInfoText.innerText = `${name} ${page_num + 1}/${Math.ceil(total_results / page_size)}`;
|
||||||
|
})
|
||||||
|
.catch(caught.bind(this, `Failed to load ${url} page ${page_num}. Reason:`));
|
||||||
|
}
|
||||||
|
|
||||||
|
loadNthPage(url, start_page_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to parse the Content-Range header
|
||||||
|
function parseRangeHeader(rangeHeader) {
|
||||||
|
const match = rangeHeader.match(/(\d+)-(\d+)\/(\d+)/);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
const start = parseInt(match[1]);
|
||||||
|
const end = parseInt(match[2]);
|
||||||
|
const totalResults = parseInt(match[3]);
|
||||||
|
return [start, end, totalResults];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [0, 0, 0]; // Default values if the header is not available or not in the expected format
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions
|
* Functions
|
||||||
*/
|
*/
|
||||||
|
@ -156,7 +315,7 @@ function resolveResponse(resolve, reject) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (e.target.status >= 200 && e.target.status < 300) {
|
if (e.target.status >= 200 && e.target.status < 300) {
|
||||||
return resolve(e.target.responseText);
|
return resolve(e.target);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error('API responded with ' + e.target.status));
|
reject(new Error('API responded with ' + e.target.status));
|
||||||
}
|
}
|
||||||
|
@ -361,10 +520,6 @@ function keepElements(elem_selectors) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadJwt() {
|
|
||||||
cancelGlobalEvts();
|
|
||||||
}
|
|
||||||
|
|
||||||
function caught(m, e) {
|
function caught(m, e) {
|
||||||
console.error(m);
|
console.error(m);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -402,7 +557,8 @@ function mkSpamImgElement(img_description) {
|
||||||
function renderNav() {
|
function renderNav() {
|
||||||
var nav = document.createElement('nav');
|
var nav = document.createElement('nav');
|
||||||
var a_elem = _mkelem('a', text('All Known Spam Posts'));
|
var a_elem = _mkelem('a', text('All Known Spam Posts'));
|
||||||
a_elem.addEventListener('click', function() {
|
a_elem.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
changeUrl('/', null, true);
|
changeUrl('/', null, true);
|
||||||
});
|
});
|
||||||
a_elem.setAttribute('href', '#');
|
a_elem.setAttribute('href', '#');
|
||||||
|
@ -476,7 +632,6 @@ function renderAttachmentReason(attachment, known_spam_post_attachments) {
|
||||||
'match': `${Math.round(distance * 100 * 10) / 10}%`
|
'match': `${Math.round(distance * 100 * 10) / 10}%`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
container.appendChild(renderThings(things));
|
container.appendChild(renderThings(things));
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
@ -556,34 +711,36 @@ function renderOverviewPost(post) {
|
||||||
return postContainer;
|
return postContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadKnownSpamPosts() {
|
function loadKnownSpamPosts(params) {
|
||||||
pageInfoText.innerText = 'Loading all known spam posts...';
|
if (params == null) {
|
||||||
cancelGlobalEvts();
|
params = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageName = "known spam posts";
|
||||||
var url = GlobalVars.settings.postgrest_url + '/known_spam_post?select=*,known_spam_post_attachment(*,phash::text)'
|
var url = GlobalVars.settings.postgrest_url + '/known_spam_post?select=*,known_spam_post_attachment(*,phash::text)'
|
||||||
var headers = {
|
|
||||||
'Authorization': 'Bearer ' + GlobalVars.settings.jwt
|
|
||||||
};
|
|
||||||
|
|
||||||
get(url, cancel, headers)
|
const pageNum = Number(params[pageName.replaceAll(' ', '_')] || 0);
|
||||||
.then(function(response) {
|
|
||||||
var json = JSON.parse(response);
|
|
||||||
console.log("results for", url, response);
|
|
||||||
pageInfoText.innerText = 'Have these known spam posts:';
|
|
||||||
var mainElem = document.querySelector('main');
|
|
||||||
mainElem.innerHTML = '';
|
|
||||||
|
|
||||||
json.forEach(function (post) {
|
function renderContent(json, controlsA, controlsB) {
|
||||||
var postElem = renderOverviewPost(post);
|
pageInfoText.innerText = 'Have these known spam posts:';
|
||||||
|
var mainElem = document.querySelector('main');
|
||||||
|
mainElem.innerHTML = '';
|
||||||
|
mainElem.appendChild(controlsA);
|
||||||
|
|
||||||
postElem.addEventListener('click', function() {
|
json.forEach(function (post) {
|
||||||
changeUrl('/spam_post/' + post.text_post_id, null, true);
|
var postElem = renderOverviewPost(post);
|
||||||
});
|
|
||||||
|
|
||||||
mainElem.appendChild(postElem);
|
postElem.addEventListener('click', function() {
|
||||||
|
changeUrl('/spam_post/' + post.text_post_id, null, true);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.catch(caught.bind(this, "Failed to load known spam posts. Reason:"));
|
mainElem.appendChild(postElem);
|
||||||
|
});
|
||||||
|
|
||||||
|
mainElem.appendChild(controlsB);
|
||||||
|
}
|
||||||
|
|
||||||
|
createPagination(pageNum, url, pageName, 25, renderContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeUrl(path, search_query, push_state) {
|
function changeUrl(path, search_query, push_state) {
|
||||||
|
@ -602,7 +759,7 @@ function changeUrl(path, search_query, push_state) {
|
||||||
|
|
||||||
function handlePageRoot(_, query_params) {
|
function handlePageRoot(_, query_params) {
|
||||||
console.log("handlePageRoot", JSON.stringify(query_params));
|
console.log("handlePageRoot", JSON.stringify(query_params));
|
||||||
return loadKnownSpamPosts();
|
return loadKnownSpamPosts(query_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSpamPost(path_data, _) {
|
function showSpamPost(path_data, _) {
|
||||||
|
@ -638,7 +795,7 @@ function showSpamPost(path_data, _) {
|
||||||
|
|
||||||
get(url, cancel, headers)
|
get(url, cancel, headers)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
var json = JSON.parse(response);
|
var json = JSON.parse(response.responseText);
|
||||||
console.log(json);
|
console.log(json);
|
||||||
pageInfoText.innerText = 'Known Spam Post';
|
pageInfoText.innerText = 'Known Spam Post';
|
||||||
|
|
||||||
|
@ -657,7 +814,7 @@ function showSpamPost(path_data, _) {
|
||||||
|
|
||||||
get(url, cancel, headers)
|
get(url, cancel, headers)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
var json = JSON.parse(response);
|
var json = JSON.parse(response.responseText);
|
||||||
console.log("known spam attachments:", json);
|
console.log("known spam attachments:", json);
|
||||||
knownSpamAttachmentsSectionElem
|
knownSpamAttachmentsSectionElem
|
||||||
.appendChild(renderKnownSpamAttachments(json));
|
.appendChild(renderKnownSpamAttachments(json));
|
||||||
|
@ -706,8 +863,10 @@ function gatherElements() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseQueryParams(querystring) {
|
function parseQueryParams(querystring) {
|
||||||
|
console.log('parseQueryParams', querystring, querystring.split('&'));
|
||||||
return querystring.split('&')
|
return querystring.split('&')
|
||||||
.map(function(part) {
|
.map(function(part) {
|
||||||
|
console.log(part);
|
||||||
return part.split('=').map(decodeURIComponent);
|
return part.split('=').map(decodeURIComponent);
|
||||||
})
|
})
|
||||||
.reduce(function(acc, pair) { return { [pair[0]]: pair[1] } }, {});
|
.reduce(function(acc, pair) { return { [pair[0]]: pair[1] } }, {});
|
||||||
|
@ -739,7 +898,7 @@ function getSettings() {
|
||||||
pageInfoText.innerText = 'Loading settings';
|
pageInfoText.innerText = 'Loading settings';
|
||||||
return get('/static/settings.json', cancel)
|
return get('/static/settings.json', cancel)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
var result = JSON.parse(response);
|
var result = JSON.parse(response.responseText);
|
||||||
console.log("settings response:", result);
|
console.log("settings response:", result);
|
||||||
GlobalVars.settings = result;
|
GlobalVars.settings = result;
|
||||||
pageInfoText.innerText = 'Have settings.';
|
pageInfoText.innerText = 'Have settings.';
|
||||||
|
|
Loading…
Reference in New Issue