55 lines
2.7 KiB
JavaScript
55 lines
2.7 KiB
JavaScript
(() => {
|
|
const badges = document.querySelectorAll('[data-share-unread-count]');
|
|
if (!badges.length) return;
|
|
const workspace = document.querySelector('[data-share-read-url]');
|
|
const scroller = workspace?.querySelector('[data-conversation]');
|
|
const countUrl = badges[0].dataset.countUrl;
|
|
let running = false;
|
|
const cookie = name => document.cookie.split('; ').find(row => row.startsWith(`${name}=`))?.split('=').slice(1).join('=') || '';
|
|
const refresh = async () => {
|
|
if (running || document.visibilityState !== 'visible') return;
|
|
running = true;
|
|
try {
|
|
const ids = [];
|
|
if (scroller) {
|
|
const bounds = scroller.getBoundingClientRect();
|
|
scroller.querySelectorAll('[data-message-id]').forEach(message => {
|
|
const box = message.getBoundingClientRect();
|
|
if (box.bottom > Math.max(bounds.top, 0) && box.top < Math.min(bounds.bottom, innerHeight)) ids.push(message.dataset.messageId);
|
|
});
|
|
}
|
|
const body = new URLSearchParams();
|
|
ids.forEach(id => body.append('message_ids', id));
|
|
const response = await fetch(workspace?.dataset.shareReadUrl || countUrl, workspace ? {
|
|
method: 'POST', body, headers: {'X-CSRFToken': cookie('csrftoken')}, cache: 'no-store', credentials: 'same-origin'
|
|
} : {cache: 'no-store', credentials: 'same-origin'});
|
|
if (response.status === 403 && workspace) {
|
|
scroller.querySelectorAll('[data-message], .date-divider, .conversation-empty').forEach(item => item.remove());
|
|
const notice = document.createElement('p');
|
|
notice.className = 'conversation-empty';
|
|
notice.textContent = 'دسترسی به این اشتراک لغو شده است.';
|
|
scroller.append(notice);
|
|
workspace.removeAttribute('data-poll-url');
|
|
const counts = await fetch(countUrl, {cache: 'no-store', credentials: 'same-origin'});
|
|
if (counts.ok) {
|
|
const data = await counts.json();
|
|
badges.forEach(badge => {badge.textContent = data.unread_shares; badge.hidden = !data.unread_shares;});
|
|
}
|
|
return;
|
|
}
|
|
if (!response.ok) return;
|
|
const data = await response.json();
|
|
badges.forEach(badge => {badge.textContent = data.unread_shares; badge.hidden = !data.unread_shares;});
|
|
} catch (_) {
|
|
// A failed request leaves the count and read status available for retry.
|
|
} finally { running = false; }
|
|
};
|
|
scroller?.addEventListener('scroll', refresh, {passive: true});
|
|
document.addEventListener('visibilitychange', refresh);
|
|
window.addEventListener('pageshow', refresh);
|
|
window.addEventListener('focus', refresh);
|
|
document.body.addEventListener('htmx:afterSwap', refresh);
|
|
setInterval(refresh, workspace ? 3000 : 15000);
|
|
refresh();
|
|
})();
|