onara
This commit is contained in:
+487
-117
@@ -117,6 +117,17 @@ window.cancelAnimFrame = (function () {
|
||||
} catch(e) { console.error('Visit tracking error:', e); }
|
||||
};
|
||||
|
||||
const ensureLayoutClass = () => {
|
||||
if (window.f0ckSession && window.f0ckSession.use_new_layout === false) {
|
||||
document.body.classList.remove('layout-modern');
|
||||
document.body.classList.add('layout-legacy');
|
||||
} else if (!document.body.classList.contains('layout-legacy')) {
|
||||
document.body.classList.add('layout-modern');
|
||||
}
|
||||
};
|
||||
window.ensureLayoutClass = ensureLayoutClass;
|
||||
ensureLayoutClass();
|
||||
|
||||
window.applyThumbCacheBust = (bgUrlStr) => {
|
||||
if (!bgUrlStr) return bgUrlStr;
|
||||
try {
|
||||
@@ -178,8 +189,24 @@ window.cancelAnimFrame = (function () {
|
||||
} catch(e) {}
|
||||
});
|
||||
|
||||
const currentId = typeof window.getCurrentItemId === 'function' ? window.getCurrentItemId() : null;
|
||||
|
||||
// Update audio cover in player if viewing this audio item
|
||||
const audioCover = document.getElementById('f0ck-audio-cover');
|
||||
if (audioCover && currentId === idStr) {
|
||||
const coverUrl = `/ca/${idStr}.webp?t=${timestamp}`;
|
||||
audioCover.src = coverUrl;
|
||||
const parent = audioCover.parentElement;
|
||||
if (parent) {
|
||||
parent.style.background = `url('${coverUrl}') no-repeat center / contain black`;
|
||||
}
|
||||
const audioEl = document.querySelector('audio#my-video');
|
||||
if (audioEl) {
|
||||
audioEl.setAttribute('poster', coverUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh background canvas if it matches the current item
|
||||
const currentId = window.getCurrentItemId();
|
||||
if (currentId === idStr && window.initBackground) {
|
||||
window.initBackground();
|
||||
}
|
||||
@@ -732,10 +759,16 @@ window.cancelAnimFrame = (function () {
|
||||
if (data.success) {
|
||||
window.flashMessage('ALL MODE ACTIVATED');
|
||||
gridCacheMap.clear();
|
||||
const isOnaraOpen = document.body.classList.contains('onara-modal-open');
|
||||
const isGridView = document.querySelector('.posts, .tags-grid');
|
||||
const isItemView = document.getElementById('prev') || document.getElementById('next') || /^\/\d+/.test(window.location.pathname);
|
||||
let reloadPromise = null;
|
||||
if (isGridView) {
|
||||
if (isOnaraOpen) {
|
||||
const bgUrl = window._onaraReturnUrl || getOnaraBaseUrl();
|
||||
const urlObj = new URL(bgUrl, window.location.origin);
|
||||
urlObj.searchParams.delete('mode');
|
||||
reloadPromise = window.loadPageAjax ? window.loadPageAjax(urlObj.toString(), true, { skipCache: true, skipPush: true }) : null;
|
||||
} else if (isGridView) {
|
||||
const currentUrl = new URL(window.location.href);
|
||||
currentUrl.searchParams.delete('mode');
|
||||
reloadPromise = window.loadPageAjax ? window.loadPageAjax(currentUrl.toString(), true, { skipCache: true }) : null;
|
||||
@@ -790,10 +823,16 @@ window.cancelAnimFrame = (function () {
|
||||
: 'ALL MODE ACTIVATED';
|
||||
window.flashMessage(label);
|
||||
gridCacheMap.clear();
|
||||
const isOnaraOpen = document.body.classList.contains('onara-modal-open');
|
||||
const isGridView = document.querySelector('.posts, .tags-grid');
|
||||
const isItemView = document.getElementById('prev') || document.getElementById('next') || /^\/\d+/.test(window.location.pathname);
|
||||
let reloadPromise = null;
|
||||
if (isGridView) {
|
||||
if (isOnaraOpen) {
|
||||
const bgUrl = window._onaraReturnUrl || getOnaraBaseUrl();
|
||||
const urlObj = new URL(bgUrl, window.location.origin);
|
||||
urlObj.searchParams.delete('mode');
|
||||
reloadPromise = window.loadPageAjax ? window.loadPageAjax(urlObj.toString(), true, { skipCache: true, skipPush: true }) : null;
|
||||
} else if (isGridView) {
|
||||
const currentUrl = new URL(window.location.href);
|
||||
currentUrl.searchParams.delete('mode');
|
||||
reloadPromise = window.loadPageAjax ? window.loadPageAjax(currentUrl.toString(), true, { skipCache: true }) : null;
|
||||
@@ -1014,6 +1053,159 @@ window.cancelAnimFrame = (function () {
|
||||
});
|
||||
};
|
||||
|
||||
// ── Onara Alternative Flavor: Fullscreen Modal Wrapper ─────────────────────
|
||||
const isOnaraActive = () => !!(window.f0ckSession?.onara || window.onara);
|
||||
|
||||
const getOrCreateOnaraModal = () => {
|
||||
let modal = document.getElementById('onara-modal');
|
||||
if (!modal) {
|
||||
modal = document.createElement('div');
|
||||
modal.id = 'onara-modal';
|
||||
modal.className = 'onara-modal-wrapper';
|
||||
modal.style.display = 'none';
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
modal.innerHTML = `
|
||||
<div class="onara-backdrop" id="onara-backdrop"></div>
|
||||
<div class="onara-modal-content" id="onara-modal-content">
|
||||
<div id="onara-item-mount" class="item-view"></div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(modal);
|
||||
}
|
||||
return modal;
|
||||
};
|
||||
|
||||
const updateOnaraActiveItem = (itemid, url) => {
|
||||
if (!isOnaraActive()) return;
|
||||
// Clear onara-active from any and all elements to guarantee only 1 item is selected
|
||||
document.querySelectorAll('.onara-active').forEach(el => el.classList.remove('onara-active'));
|
||||
|
||||
let targetThumb = null;
|
||||
if (url) {
|
||||
try {
|
||||
const parsedPath = new URL(url, window.location.origin).pathname;
|
||||
targetThumb = document.querySelector(`.posts > a.thumb[href="${parsedPath}"], .posts > a.thumb[href="${url}"]`);
|
||||
} catch {}
|
||||
}
|
||||
if (!targetThumb && itemid) {
|
||||
targetThumb = document.querySelector(`.posts > a.thumb[href$="/${itemid}"], .posts > a.thumb[data-bg*="/${itemid}."]`);
|
||||
}
|
||||
|
||||
// Blur any other active element so browser native focus cannot highlight a second thumbnail
|
||||
if (document.activeElement && document.activeElement !== targetThumb && typeof document.activeElement.blur === 'function') {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
if (targetThumb) {
|
||||
targetThumb.classList.add('onara-active');
|
||||
targetThumb.scrollIntoView({ block: 'center', inline: 'nearest', behavior: 'instant' });
|
||||
}
|
||||
};
|
||||
window.updateOnaraActiveItem = updateOnaraActiveItem;
|
||||
|
||||
const getOnaraBaseUrl = (itemUrl = window.location.href) => {
|
||||
try {
|
||||
const urlObj = new URL(itemUrl, window.location.origin);
|
||||
let path = urlObj.pathname.replace(/\/+$/, '');
|
||||
path = path.replace(/\/(?:\d+|[a-zA-Z0-9_-]{11})$/, '');
|
||||
const postsEl = document.querySelector('.posts[data-current-page]');
|
||||
const currentPage = postsEl ? parseInt(postsEl.dataset.currentPage, 10) : 1;
|
||||
if (currentPage > 1 && !path.includes('/p/')) {
|
||||
path = (path ? path : '') + '/p/' + currentPage;
|
||||
}
|
||||
if (!path) path = '/';
|
||||
return path + (urlObj.search || '') + (urlObj.hash || '');
|
||||
} catch {
|
||||
return '/';
|
||||
}
|
||||
};
|
||||
window.getOnaraBaseUrl = getOnaraBaseUrl;
|
||||
|
||||
const promoteOnaraModals = () => {
|
||||
const mount = document.getElementById('onara-item-mount');
|
||||
if (!mount) return;
|
||||
const modals = mount.querySelectorAll('#info-modal, #visibility-modal, .modal-overlay');
|
||||
modals.forEach(m => {
|
||||
const existing = document.body.querySelector(`:scope > #${m.id}`);
|
||||
if (existing && existing !== m) {
|
||||
existing.remove();
|
||||
}
|
||||
document.body.appendChild(m);
|
||||
});
|
||||
};
|
||||
window.promoteOnaraModals = promoteOnaraModals;
|
||||
|
||||
const closeOnaraModal = (options = {}) => {
|
||||
const modal = document.getElementById('onara-modal');
|
||||
if (!modal || modal.style.display === 'none') return;
|
||||
|
||||
// Close any auxiliary modals that may be open
|
||||
const infoModal = document.getElementById('info-modal');
|
||||
if (infoModal) infoModal.style.display = 'none';
|
||||
const visModal = document.getElementById('visibility-modal');
|
||||
if (visModal) visModal.style.display = 'none';
|
||||
const reportModal = document.getElementById('report-modal');
|
||||
if (reportModal) reportModal.style.display = 'none';
|
||||
const hallsModal = document.getElementById('halls-modal');
|
||||
if (hallsModal) hallsModal.style.display = 'none';
|
||||
if (typeof window.closeImageModal === 'function') window.closeImageModal();
|
||||
document.body.classList.remove('modal-open');
|
||||
|
||||
stopMedia();
|
||||
const mount = document.getElementById('onara-item-mount');
|
||||
if (mount) mount.innerHTML = '';
|
||||
modal.style.display = 'none';
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
document.body.classList.remove('onara-modal-open');
|
||||
|
||||
// Restore background canvas if needed
|
||||
const canvas = document.getElementById('bg');
|
||||
if (canvas) {
|
||||
canvas.classList.remove('fader-out', 'fast-fade');
|
||||
if (window.initBackground) window.initBackground();
|
||||
}
|
||||
|
||||
if (!options.skipHistory) {
|
||||
const returnUrl = window._onaraReturnUrl || getOnaraBaseUrl();
|
||||
history.pushState({}, '', returnUrl);
|
||||
if (window._onaraReturnTitle) {
|
||||
document.title = window._onaraReturnTitle;
|
||||
} else if (window.f0ckDomain) {
|
||||
document.title = window.f0ckDomain;
|
||||
}
|
||||
}
|
||||
window._onaraReturnUrl = null;
|
||||
window._onaraReturnTitle = null;
|
||||
|
||||
// Maintain focus on active item so user TAB navigation seamlessly resumes from current progress
|
||||
const activeThumb = document.querySelector('.posts > a.thumb.onara-active');
|
||||
document.querySelectorAll('.onara-active').forEach(el => el.classList.remove('onara-active'));
|
||||
if (activeThumb) {
|
||||
try {
|
||||
activeThumb.focus({ preventScroll: true });
|
||||
} catch {}
|
||||
}
|
||||
};
|
||||
window.closeOnaraModal = closeOnaraModal;
|
||||
window.isOnaraActive = isOnaraActive;
|
||||
|
||||
// Onara modal close click delegation: clicking outside .item-main-content closes modal
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!document.body.classList.contains('onara-modal-open')) return;
|
||||
// Do not close if clicking inside the item content
|
||||
if (e.target.closest('.item-main-content')) return;
|
||||
// Do not close if clicking auxiliary modals, dropdowns, or notifications
|
||||
if (e.target.closest('.modal-overlay:not(#onara-modal), .modal-content, .swal2-container, .tippy-box, #comments-container .emoji-picker')) return;
|
||||
// Do not close if clicking the global sidebar right or navbar (as modal respects them)
|
||||
if (e.target.closest('.global-sidebar-right, nav.navbar, #sidebar-drag-zone')) return;
|
||||
|
||||
// Any click outside .item-main-content (e.g. left side, right side, backdrop, modal background) closes
|
||||
if (e.target.closest('#onara-modal') || e.target.id === 'onara-backdrop') {
|
||||
e.preventDefault();
|
||||
closeOnaraModal();
|
||||
}
|
||||
});
|
||||
|
||||
if (loginModal) {
|
||||
if (loginBtn) {
|
||||
loginBtn.addEventListener('click', (e) => {
|
||||
@@ -1372,8 +1564,49 @@ window.cancelAnimFrame = (function () {
|
||||
closeModal(loginModal);
|
||||
closeModal(registerModal);
|
||||
closeModal(shortcutsModal);
|
||||
const imageModal = document.getElementById('image-modal');
|
||||
if (imageModal && (imageModal.classList.contains('visible') || imageModal.style.display === 'flex' || imageModal.style.display === 'block')) {
|
||||
if (typeof window.closeImageModal === 'function') window.closeImageModal();
|
||||
else {
|
||||
imageModal.classList.remove('visible');
|
||||
imageModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
return;
|
||||
}
|
||||
const infoModal = document.getElementById('info-modal');
|
||||
if (infoModal) closeModal(infoModal);
|
||||
if (infoModal && infoModal.style.display !== 'none') {
|
||||
infoModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
return;
|
||||
}
|
||||
const visModal = document.getElementById('visibility-modal');
|
||||
if (visModal && visModal.style.display !== 'none') {
|
||||
visModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
return;
|
||||
}
|
||||
const reportModal = document.getElementById('report-modal');
|
||||
if (reportModal && reportModal.style.display !== 'none') {
|
||||
reportModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
return;
|
||||
}
|
||||
const hallsModal = document.getElementById('halls-modal');
|
||||
if (hallsModal && hallsModal.style.display !== 'none') {
|
||||
hallsModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
return;
|
||||
}
|
||||
const anyOtherModal = document.querySelector('.modal-overlay:not(#onara-modal):not([style*="display: none"]), .modal.show, .swal2-container');
|
||||
if (anyOtherModal && window.getComputedStyle(anyOtherModal).display !== 'none') {
|
||||
anyOtherModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
return;
|
||||
}
|
||||
if (document.body.classList.contains('onara-modal-open')) {
|
||||
closeOnaraModal();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1519,15 +1752,42 @@ window.cancelAnimFrame = (function () {
|
||||
}
|
||||
};
|
||||
|
||||
const initOnaraInitialState = () => {
|
||||
if (!isOnaraActive()) return;
|
||||
promoteOnaraModals();
|
||||
if (document.body.classList.contains('onara-modal-open')) {
|
||||
const modal = document.getElementById('onara-modal');
|
||||
if (modal) {
|
||||
modal.style.display = 'flex';
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
}
|
||||
if (!window._onaraReturnUrl) {
|
||||
window._onaraReturnUrl = getOnaraBaseUrl();
|
||||
window._onaraReturnTitle = window.f0ckDomain || 'f0ck';
|
||||
}
|
||||
const pathSegments = window.location.pathname.split('/');
|
||||
const keySegments = pathSegments.filter(s => /^\d+$/.test(s) || /^[a-zA-Z0-9_-]{11}$/.test(s));
|
||||
const activeKey = keySegments.length ? keySegments[keySegments.length - 1] : null;
|
||||
if (activeKey) {
|
||||
updateOnaraActiveItem(activeKey, window.location.href);
|
||||
if (typeof window.trackVisit === 'function') {
|
||||
window.trackVisit(activeKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Initial Load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setupMedia();
|
||||
initOnaraInitialState();
|
||||
if (typeof requestIdleCallback === 'function') {
|
||||
requestIdleCallback(() => prefetchNextPrevItems());
|
||||
} else {
|
||||
setTimeout(prefetchNextPrevItems, 500);
|
||||
}
|
||||
});
|
||||
initOnaraInitialState();
|
||||
|
||||
// Export init function for dynamic calls
|
||||
window.initBackground = () => {
|
||||
@@ -2380,6 +2640,7 @@ window.cancelAnimFrame = (function () {
|
||||
// Immediately restore scrollability and hide modals
|
||||
if (window.resetGlobalScrollState) window.resetGlobalScrollState();
|
||||
if (window.hideAllModals) window.hideAllModals();
|
||||
if (window.closeOnaraModal) window.closeOnaraModal({ skipHistory: true });
|
||||
|
||||
isNavigating = true;
|
||||
|
||||
@@ -2493,7 +2754,7 @@ window.cancelAnimFrame = (function () {
|
||||
// Keep cache alive — cleared on mode/filter changes via gridCacheMap.clear()
|
||||
|
||||
if (navbar) navbar.classList.add('pbwork');
|
||||
stopMedia();
|
||||
if (!document.body.classList.contains('onara-modal-open')) stopMedia();
|
||||
|
||||
// Fade out background canvas (item view blur)
|
||||
const canvas = document.getElementById('bg');
|
||||
@@ -2514,9 +2775,12 @@ window.cancelAnimFrame = (function () {
|
||||
cache.node.style.display = '';
|
||||
cache.node.classList.remove('cached-grid');
|
||||
main.className = '';
|
||||
document.body.classList.remove('legacy-view', 'layout-modern', 'layout-legacy');
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.height = '';
|
||||
document.body.classList.remove('legacy-view');
|
||||
ensureLayoutClass();
|
||||
if (!document.body.classList.contains('onara-modal-open')) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.height = '';
|
||||
}
|
||||
const paginationWrapper = document.querySelector('.pagination-wrapper');
|
||||
if (paginationWrapper && cache.pagination) paginationWrapper.innerHTML = cache.pagination;
|
||||
const restoredPosts = cache.node.querySelector('.posts');
|
||||
@@ -2527,7 +2791,7 @@ window.cancelAnimFrame = (function () {
|
||||
}
|
||||
|
||||
// Update URL bar (only for explicit clicks, not browser back/forward which already did it)
|
||||
if (!options.skipPush) history.pushState({}, '', url);
|
||||
if (!options.skipPush && !document.body.classList.contains('onara-modal-open')) history.pushState({}, '', url);
|
||||
|
||||
// Restore scroll position
|
||||
requestAnimationFrame(() => window.scrollTo(0, cache.scroll));
|
||||
@@ -2576,11 +2840,13 @@ window.cancelAnimFrame = (function () {
|
||||
main.className = ''; // Reset class
|
||||
|
||||
// Clear legacy-view state (layout-lock) now that we are swapping to a list view
|
||||
document.body.classList.remove('legacy-view', 'layout-modern', 'layout-legacy');
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.height = '';
|
||||
// Toggle button lives permanently in body via header.html — no removal needed
|
||||
stopMedia(); // Ensure media stops when leaving item view
|
||||
document.body.classList.remove('legacy-view');
|
||||
ensureLayoutClass();
|
||||
if (!document.body.classList.contains('onara-modal-open')) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.height = '';
|
||||
stopMedia(); // Ensure media stops when leaving item view
|
||||
}
|
||||
|
||||
// Fade out background canvas for smooth transition to black
|
||||
const canvas = document.getElementById('bg');
|
||||
@@ -2737,6 +3003,7 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
// Ensure we keep a layout class but reset others
|
||||
document.body.classList.remove('item-layout-active', 'meme-layout-active'); // Kill known breakers
|
||||
ensureLayoutClass();
|
||||
}
|
||||
|
||||
// Reset navbar to clean state
|
||||
@@ -2745,9 +3012,11 @@ window.cancelAnimFrame = (function () {
|
||||
navbar.classList.remove('scrolled', 'pbwork');
|
||||
}
|
||||
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.height = '';
|
||||
document.body.style.minHeight = '';
|
||||
if (!document.body.classList.contains('onara-modal-open')) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.height = '';
|
||||
document.body.style.minHeight = '';
|
||||
}
|
||||
|
||||
window.f0ckDebug("[loadPageAjax] State synced for " + (isFullPage ? "full page" : "partial"));
|
||||
if (window.updateMimeLabel) window.updateMimeLabel();
|
||||
@@ -2949,7 +3218,7 @@ window.cancelAnimFrame = (function () {
|
||||
}
|
||||
|
||||
// UPDATE HISTORY BEFORE INITIALIZING SCRIPTS
|
||||
if (!options.skipPush) {
|
||||
if (!options.skipPush && !document.body.classList.contains('onara-modal-open')) {
|
||||
history.pushState({}, '', url);
|
||||
}
|
||||
|
||||
@@ -3319,6 +3588,15 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
isNavigating = true;
|
||||
|
||||
const isGridPage = !!document.querySelector('.index-layout-wrapper, .index-container, .posts');
|
||||
const isModalOpen = document.body.classList.contains('onara-modal-open');
|
||||
const useOnara = isOnaraActive() && (isGridPage || isModalOpen);
|
||||
|
||||
if (useOnara && !isModalOpen) {
|
||||
window._onaraReturnUrl = window.location.href;
|
||||
window._onaraReturnTitle = document.title;
|
||||
}
|
||||
|
||||
// ── Scroller-active cleanup (same as loadPageAjax) ───────────────────
|
||||
if (document.body.classList.contains('scroller-active')) {
|
||||
document.head.querySelectorAll('[data-pjax-abyss]').forEach(el => el.remove());
|
||||
@@ -3349,7 +3627,7 @@ window.cancelAnimFrame = (function () {
|
||||
const currentScroll = window.scrollY;
|
||||
|
||||
// Save scroll position for current page (only for new navigations)
|
||||
if (!options.skipPush && !options.keepMedia) {
|
||||
if (!options.skipPush && !options.keepMedia && !useOnara) {
|
||||
const currentState = history.state || {};
|
||||
history.replaceState({ ...currentState, scroll: currentScroll }, document.title, window.location.href);
|
||||
}
|
||||
@@ -3521,39 +3799,54 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
// ── Render cached HTML (same DOM setup as the normal path below) ──
|
||||
const _html = _cachedItem.html;
|
||||
let _container = document.querySelector('#main .container') || (document.getElementById('main')?.classList.contains('item-view') ? document.getElementById('main') : null);
|
||||
const _isStructuralPage = !!document.querySelector('.pagewrapper');
|
||||
const _isModeratorPage = !!document.querySelector('.approval-grid, .audit-log-container, .mod-reports-page');
|
||||
const _isNotificationsPage = !!document.querySelector('.notifications-page, .notif-history-container');
|
||||
const _isIndexPage = !!document.querySelector('.index-container, .posts');
|
||||
const _isStaticPage = !!document.querySelector('.static-page, .about-container, .upload-container');
|
||||
let _container;
|
||||
|
||||
if (!options.keepMedia && (!_container || _isModeratorPage || _isNotificationsPage || _isIndexPage || _isStaticPage || _isStructuralPage)) {
|
||||
if (main) {
|
||||
const _iw = main.querySelector('.index-layout-wrapper');
|
||||
const _ic = main.querySelector('.index-container');
|
||||
const _ntc = _iw || _ic;
|
||||
if (_ntc && _isIndexPage) {
|
||||
const _ck = window.location.pathname + window.location.search;
|
||||
const _pw = document.querySelector('.pagination-wrapper');
|
||||
gridCacheMap.set(_ck, { node: _ntc, scroll: currentScroll, pagination: _pw ? _pw.innerHTML : '' });
|
||||
_ntc.remove();
|
||||
if (useOnara) {
|
||||
const onaraModal = getOrCreateOnaraModal();
|
||||
const onaraMount = document.getElementById('onara-item-mount');
|
||||
document.body.classList.add('onara-modal-open');
|
||||
onaraModal.style.display = 'flex';
|
||||
onaraModal.setAttribute('aria-hidden', 'false');
|
||||
if (!options.keepMedia) {
|
||||
onaraMount.innerHTML = '';
|
||||
}
|
||||
_container = onaraMount;
|
||||
updateOnaraActiveItem(itemid, url);
|
||||
} else {
|
||||
_container = document.querySelector('#main .container') || (document.getElementById('main')?.classList.contains('item-view') ? document.getElementById('main') : null);
|
||||
const _isStructuralPage = !!document.querySelector('.pagewrapper');
|
||||
const _isModeratorPage = !!document.querySelector('.approval-grid, .audit-log-container, .mod-reports-page');
|
||||
const _isNotificationsPage = !!document.querySelector('.notifications-page, .notif-history-container');
|
||||
const _isIndexPage = !!document.querySelector('.index-container, .posts');
|
||||
const _isStaticPage = !!document.querySelector('.static-page, .about-container, .upload-container');
|
||||
|
||||
if (!options.keepMedia && (!_container || _isModeratorPage || _isNotificationsPage || _isIndexPage || _isStaticPage || _isStructuralPage)) {
|
||||
if (main) {
|
||||
const _iw = main.querySelector('.index-layout-wrapper');
|
||||
const _ic = main.querySelector('.index-container');
|
||||
const _ntc = _iw || _ic;
|
||||
if (_ntc && _isIndexPage) {
|
||||
const _ck = window.location.pathname + window.location.search;
|
||||
const _pw = document.querySelector('.pagination-wrapper');
|
||||
gridCacheMap.set(_ck, { node: _ntc, scroll: currentScroll, pagination: _pw ? _pw.innerHTML : '' });
|
||||
_ntc.remove();
|
||||
}
|
||||
main.className = 'item-view';
|
||||
document.body.classList.remove('legacy-view', 'layout-modern', 'layout-legacy');
|
||||
if (window.f0ckSession && !window.f0ckSession.use_new_layout) {
|
||||
document.body.classList.add('layout-legacy');
|
||||
} else {
|
||||
document.body.classList.add('layout-modern');
|
||||
}
|
||||
if (window.syncNavbarHeight) window.syncNavbarHeight();
|
||||
main.innerHTML = '';
|
||||
_container = main;
|
||||
}
|
||||
main.className = 'item-view';
|
||||
document.body.classList.remove('legacy-view', 'layout-modern', 'layout-legacy');
|
||||
if (window.f0ckSession && !window.f0ckSession.use_new_layout) {
|
||||
document.body.classList.add('layout-legacy');
|
||||
} else {
|
||||
document.body.classList.add('layout-modern');
|
||||
}
|
||||
if (window.syncNavbarHeight) window.syncNavbarHeight();
|
||||
main.innerHTML = '';
|
||||
_container = main;
|
||||
} else if (_container && !options.keepMedia) {
|
||||
_container.innerHTML = '';
|
||||
_container.removeAttribute('style');
|
||||
if (main) main.className = 'item-view';
|
||||
}
|
||||
} else if (_container && !options.keepMedia) {
|
||||
_container.innerHTML = '';
|
||||
_container.removeAttribute('style');
|
||||
if (main) main.className = 'item-view';
|
||||
}
|
||||
|
||||
if (options.keepMedia) {
|
||||
@@ -3568,14 +3861,18 @@ window.cancelAnimFrame = (function () {
|
||||
_container.insertAdjacentHTML('beforeend', _html);
|
||||
}
|
||||
|
||||
if (options.skipPush && history.state?.scroll !== undefined) {
|
||||
if (useOnara) {
|
||||
promoteOnaraModals();
|
||||
const onaraModal = document.getElementById('onara-modal');
|
||||
if (onaraModal) onaraModal.scrollTo(0, 0);
|
||||
} else if (options.skipPush && history.state?.scroll !== undefined) {
|
||||
requestAnimationFrame(() => window.scrollTo(0, history.state.scroll));
|
||||
} else if (!options.keepMedia) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
const _hash = new URL(url, window.location.origin).hash;
|
||||
const itemKey = _cachedItem.slug || itemid;
|
||||
const itemKey = (window.f0ckSession?.enable_item_slugs !== false && _cachedItem.slug) ? _cachedItem.slug : (_cachedItem.slug || itemid);
|
||||
let _pushUrl = `/${itemKey}`;
|
||||
if (userHall && userHallOwner) _pushUrl = `/user/${encodeURIComponent(userHallOwner)}/hall/${encodeURIComponent(userHall)}/${itemKey}`;
|
||||
else if (user) { _pushUrl = `/user/${encodeURIComponent(user)}/${itemKey}`; if (isFavs) _pushUrl = `/user/${encodeURIComponent(user)}/favs/${itemKey}`; }
|
||||
@@ -3585,7 +3882,7 @@ window.cancelAnimFrame = (function () {
|
||||
if (mime) _pushUrl = _pushUrl.replace(new RegExp(`/${itemKey}$`), `/${mime}/${itemKey}`);
|
||||
if (_hash) _pushUrl += _hash;
|
||||
|
||||
if (!options.keepMedia && !options.skipPush) history.pushState({}, '', _pushUrl);
|
||||
if (!options.keepMedia && !options.skipPush) history.pushState({ onara: useOnara }, '', _pushUrl);
|
||||
|
||||
document.title = `${window.f0ckDomain} - ${itemKey}`;
|
||||
if (navbar) navbar.classList.remove('pbwork');
|
||||
@@ -3678,55 +3975,69 @@ window.cancelAnimFrame = (function () {
|
||||
// Track visit for guests
|
||||
window.trackVisit(itemid);
|
||||
|
||||
let container = document.querySelector('#main .container') || (document.getElementById('main') && document.getElementById('main').classList.contains('item-view') ? document.getElementById('main') : null);
|
||||
const isStructuralPage = !!document.querySelector('.pagewrapper');
|
||||
const isModeratorPage = !!document.querySelector('.approval-grid, .audit-log-container, .mod-reports-page');
|
||||
const isNotificationsPage = !!document.querySelector('.notifications-page, .notif-history-container');
|
||||
const isIndexPage = !!document.querySelector('.index-container, .posts');
|
||||
const isStaticPage = !!document.querySelector('.static-page, .about-container, .upload-container');
|
||||
let container;
|
||||
|
||||
if (useOnara) {
|
||||
const onaraModal = getOrCreateOnaraModal();
|
||||
const onaraMount = document.getElementById('onara-item-mount');
|
||||
document.body.classList.add('onara-modal-open');
|
||||
onaraModal.style.display = 'flex';
|
||||
onaraModal.setAttribute('aria-hidden', 'false');
|
||||
if (!options.keepMedia) {
|
||||
onaraMount.innerHTML = '';
|
||||
}
|
||||
container = onaraMount;
|
||||
updateOnaraActiveItem(itemid, url);
|
||||
} else {
|
||||
container = document.querySelector('#main .container') || (document.getElementById('main') && document.getElementById('main').classList.contains('item-view') ? document.getElementById('main') : null);
|
||||
const isStructuralPage = !!document.querySelector('.pagewrapper');
|
||||
const isModeratorPage = !!document.querySelector('.approval-grid, .audit-log-container, .mod-reports-page');
|
||||
const isNotificationsPage = !!document.querySelector('.notifications-page, .notif-history-container');
|
||||
const isIndexPage = !!document.querySelector('.index-container, .posts');
|
||||
const isStaticPage = !!document.querySelector('.static-page, .about-container, .upload-container');
|
||||
|
||||
if (!options.keepMedia && (!container || isModeratorPage || isNotificationsPage || isIndexPage || isStaticPage || isStructuralPage)) {
|
||||
// Transition to Item View
|
||||
if (main) {
|
||||
// Check if we can cache the existing grid (Index Page only)
|
||||
const indexWrapper = main.querySelector('.index-layout-wrapper');
|
||||
const indexContainer = main.querySelector('.index-container');
|
||||
const nodeToCache = indexWrapper || indexContainer;
|
||||
if (!options.keepMedia && (!container || isModeratorPage || isNotificationsPage || isIndexPage || isStaticPage || isStructuralPage)) {
|
||||
// Transition to Item View
|
||||
if (main) {
|
||||
// Check if we can cache the existing grid (Index Page only)
|
||||
const indexWrapper = main.querySelector('.index-layout-wrapper');
|
||||
const indexContainer = main.querySelector('.index-container');
|
||||
const nodeToCache = indexWrapper || indexContainer;
|
||||
|
||||
if (nodeToCache && isIndexPage) {
|
||||
const cacheKey = window.location.pathname + window.location.search;
|
||||
const paginationWrapper = document.querySelector('.pagination-wrapper');
|
||||
gridCacheMap.set(cacheKey, {
|
||||
node: nodeToCache,
|
||||
scroll: currentScroll,
|
||||
pagination: paginationWrapper ? paginationWrapper.innerHTML : ''
|
||||
});
|
||||
nodeToCache.remove();
|
||||
}
|
||||
|
||||
main.className = 'item-view';
|
||||
if (nodeToCache && isIndexPage) {
|
||||
const cacheKey = window.location.pathname + window.location.search;
|
||||
const paginationWrapper = document.querySelector('.pagination-wrapper');
|
||||
gridCacheMap.set(cacheKey, {
|
||||
node: nodeToCache,
|
||||
scroll: currentScroll,
|
||||
pagination: paginationWrapper ? paginationWrapper.innerHTML : ''
|
||||
});
|
||||
nodeToCache.remove();
|
||||
}
|
||||
|
||||
main.className = 'item-view';
|
||||
|
||||
// Correctly handle body classes for the current layout mode
|
||||
document.body.classList.remove('legacy-view', 'layout-modern', 'layout-legacy');
|
||||
if (window.f0ckSession && !window.f0ckSession.use_new_layout) {
|
||||
document.body.classList.add('layout-legacy');
|
||||
} else {
|
||||
document.body.classList.add('layout-modern');
|
||||
}
|
||||
if (window.syncNavbarHeight) window.syncNavbarHeight();
|
||||
// Correctly handle body classes for the current layout mode
|
||||
document.body.classList.remove('legacy-view', 'layout-modern', 'layout-legacy');
|
||||
if (window.f0ckSession && !window.f0ckSession.use_new_layout) {
|
||||
document.body.classList.add('layout-legacy');
|
||||
} else {
|
||||
document.body.classList.add('layout-modern');
|
||||
}
|
||||
if (window.syncNavbarHeight) window.syncNavbarHeight();
|
||||
|
||||
// Toggle button lives permanently in body via header.html — no creation needed
|
||||
// Toggle button lives permanently in body via header.html — no creation needed
|
||||
|
||||
// HTML goes directly into #main without outdated .container wrapper for New Layout
|
||||
main.innerHTML = '';
|
||||
container = main; // HTML goes directly into #main
|
||||
// HTML goes directly into #main without outdated .container wrapper for New Layout
|
||||
main.innerHTML = '';
|
||||
container = main; // HTML goes directly into #main
|
||||
}
|
||||
} else if (container && !options.keepMedia) {
|
||||
// Already in some kind of item view or compatible layout, just clear it
|
||||
container.innerHTML = '';
|
||||
container.removeAttribute('style'); // Ensure no carry-over styles
|
||||
if (main) main.className = 'item-view';
|
||||
}
|
||||
} else if (container && !options.keepMedia) {
|
||||
// Already in some kind of item view or compatible layout, just clear it
|
||||
container.innerHTML = '';
|
||||
container.removeAttribute('style'); // Ensure no carry-over styles
|
||||
if (main) main.className = 'item-view';
|
||||
}
|
||||
|
||||
if (options.keepMedia) {
|
||||
@@ -3763,7 +4074,11 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
|
||||
// Handle Scroll Position (Restore or Reset)
|
||||
if (options.skipPush && history.state && history.state.scroll !== undefined) {
|
||||
if (useOnara) {
|
||||
promoteOnaraModals();
|
||||
const onaraModal = document.getElementById('onara-modal');
|
||||
if (onaraModal) onaraModal.scrollTo(0, 0);
|
||||
} else if (options.skipPush && history.state && history.state.scroll !== undefined) {
|
||||
requestAnimationFrame(() => window.scrollTo(0, history.state.scroll));
|
||||
} else if (!options.keepMedia) {
|
||||
window.scrollTo(0, 0);
|
||||
@@ -3775,7 +4090,7 @@ window.cancelAnimFrame = (function () {
|
||||
// Construct proper History URL (Context Aware)
|
||||
// If we inherited context, we should reflect it in the URL
|
||||
const hash = new URL(url, window.location.origin).hash;
|
||||
const itemKey = responseSlug || itemid;
|
||||
const itemKey = (window.f0ckSession?.enable_item_slugs !== false && responseSlug) ? responseSlug : (responseSlug || itemid);
|
||||
let pushUrl = `/${itemKey}`;
|
||||
// Logic from ajax.mjs context reconstruction:
|
||||
if (userHall && userHallOwner) {
|
||||
@@ -3799,7 +4114,7 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
if (!options.keepMedia && !options.skipPush) {
|
||||
// We overwrite proper URL even if the link clicked was "naked"
|
||||
history.pushState({}, '', pushUrl);
|
||||
history.pushState({ onara: useOnara }, '', pushUrl);
|
||||
}
|
||||
|
||||
if (!options.keepMedia) {
|
||||
@@ -3900,11 +4215,17 @@ window.cancelAnimFrame = (function () {
|
||||
gridCacheMap.clear();
|
||||
|
||||
// Refresh content
|
||||
const isOnaraOpen = document.body.classList.contains('onara-modal-open');
|
||||
const isGridView = document.querySelector('.posts, .tags-grid');
|
||||
const isItemView = document.getElementById('prev') || document.getElementById('next');
|
||||
|
||||
let reloadPromise = null;
|
||||
if (isGridView) {
|
||||
if (isOnaraOpen) {
|
||||
const bgUrl = window._onaraReturnUrl || getOnaraBaseUrl();
|
||||
const urlObj = new URL(bgUrl, window.location.origin);
|
||||
urlObj.searchParams.delete('mode');
|
||||
reloadPromise = loadPageAjax(urlObj.toString(), true, { skipCache: true, skipPush: true });
|
||||
} else if (isGridView) {
|
||||
// Reload current page without ?mode= in the URL — server picks up mode from session/cookie
|
||||
const currentUrl = new URL(window.location.href);
|
||||
currentUrl.searchParams.delete('mode');
|
||||
@@ -3935,6 +4256,13 @@ window.cancelAnimFrame = (function () {
|
||||
const thumbnail = target.closest('.posts > a:not(.notif-item)');
|
||||
if (thumbnail && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
|
||||
e.preventDefault();
|
||||
if (isOnaraActive()) {
|
||||
document.querySelectorAll('.onara-active').forEach(el => el.classList.remove('onara-active'));
|
||||
thumbnail.classList.add('onara-active');
|
||||
if (document.activeElement && document.activeElement !== thumbnail && typeof document.activeElement.blur === 'function') {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
// Thumbnails inherit context (e.g. from Tag Index)
|
||||
loadItemAjax(thumbnail.href, true);
|
||||
return;
|
||||
@@ -3945,6 +4273,25 @@ window.cancelAnimFrame = (function () {
|
||||
// Special check for random
|
||||
if (link.id === 'random' || link.id === 'nav-random') {
|
||||
e.preventDefault();
|
||||
|
||||
// In Onara mode with a background grid, pick a random item from the grid so it reflects on the main page
|
||||
if (isOnaraActive()) {
|
||||
const gridThumbs = Array.from(document.querySelectorAll('.posts > a:not(.notif-item)'));
|
||||
if (gridThumbs.length > 0) {
|
||||
const pool = gridThumbs.filter(t => !t.classList.contains('onara-active'));
|
||||
const chosen = (pool.length > 0 ? pool : gridThumbs)[Math.floor(Math.random() * (pool.length > 0 ? pool : gridThumbs).length)];
|
||||
if (chosen) {
|
||||
document.querySelectorAll('.onara-active').forEach(el => el.classList.remove('onara-active'));
|
||||
chosen.classList.add('onara-active');
|
||||
if (document.activeElement && document.activeElement !== chosen && typeof document.activeElement.blur === 'function') {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
loadItemAjax(chosen.href, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopMedia(); // Abort media BEFORE fetching random item
|
||||
|
||||
// Fade out background canvas for smooth transition
|
||||
@@ -4590,6 +4937,11 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
window.f0ckDebug("[popstate] Navigation to:", url, { isItem, isSpecial, isGridLike });
|
||||
|
||||
if (document.body.classList.contains('onara-modal-open') && !isItem) {
|
||||
closeOnaraModal({ skipHistory: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (isItem) {
|
||||
loadItemAjax(url, true, { skipPush: true });
|
||||
} else if (isSpecial || isGridLike) {
|
||||
@@ -4872,7 +5224,9 @@ window.cancelAnimFrame = (function () {
|
||||
if (infiniteState.currentPage !== p) {
|
||||
infiniteState.currentPage = p;
|
||||
infiniteState.firstPage = p;
|
||||
history.replaceState({}, '', buildUrl(p));
|
||||
if (!document.body.classList.contains('onara-modal-open')) {
|
||||
history.replaceState({}, '', buildUrl(p));
|
||||
}
|
||||
}
|
||||
|
||||
delete postsContainer.dataset.currentPage; // Clear after reading
|
||||
@@ -4948,6 +5302,11 @@ window.cancelAnimFrame = (function () {
|
||||
return;
|
||||
}
|
||||
|
||||
// Never overwrite item URL with /p/N when Onara modal is open!
|
||||
if (document.body.classList.contains('onara-modal-open')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update URL
|
||||
infiniteState.visiblePage = newPage;
|
||||
history.replaceState({}, '', buildUrl(newPage));
|
||||
@@ -9328,8 +9687,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
if (newPath === '') newPath = '/';
|
||||
url.pathname = newPath;
|
||||
|
||||
// Update the browser URL without reloading
|
||||
history.replaceState({}, '', url.toString());
|
||||
const isOnaraOpen = document.body.classList.contains('onara-modal-open');
|
||||
|
||||
// Update the browser URL without reloading (only when not in onara modal)
|
||||
if (!isOnaraOpen) {
|
||||
history.replaceState({}, '', url.toString());
|
||||
}
|
||||
|
||||
// Sync UI immediately (Before AJAX)
|
||||
if (window.updateMimeLabel) window.updateMimeLabel();
|
||||
@@ -9342,7 +9705,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
// Set flag so hideAllModals (called inside loadPageAjax) skips the filter overlay
|
||||
if (fromModal) window._keepFilterModal = true;
|
||||
|
||||
if (postsEl) {
|
||||
if (isOnaraOpen) {
|
||||
const bgUrl = window._onaraReturnUrl || getOnaraBaseUrl();
|
||||
reloadPromise = window.loadPageAjax ? window.loadPageAjax(bgUrl, { skipPush: true, skipCache: true }) : null;
|
||||
} else if (postsEl) {
|
||||
reloadPromise = window.loadPageAjax ? window.loadPageAjax(url.toString(), { skipPush: true }) : null;
|
||||
} else if (document.getElementById('main')?.classList.contains('item-view') || document.querySelector('.item-layout-container, .item-main-content')) {
|
||||
// On item view, refresh the context but KEEP media playing
|
||||
@@ -10191,7 +10557,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
// Close logic
|
||||
if (e.target.matches('#report-cancel')) {
|
||||
if (e.target.matches('#report-cancel') || e.target.id === 'report-modal') {
|
||||
reportModal.style.display = 'none';
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
@@ -11486,7 +11852,7 @@ document.addEventListener('click', (e) => {
|
||||
}
|
||||
|
||||
const closeBtn = e.target.closest('#info-modal-close, #info-modal-close-icon');
|
||||
if (closeBtn) {
|
||||
if (closeBtn || e.target.id === 'info-modal') {
|
||||
e.preventDefault();
|
||||
const modal = document.getElementById('info-modal');
|
||||
if (modal) {
|
||||
@@ -11683,21 +12049,25 @@ document.addEventListener('click', (e) => {
|
||||
if (data.success) {
|
||||
if (window.flashMessage) window.flashMessage('THUMBNAIL REGENERATED');
|
||||
else if (window.showFlash) window.showFlash('Thumbnail regenerated');
|
||||
// Cache-bust thumbnails on page
|
||||
// Cache-bust thumbnails and player media on page
|
||||
const timestamp = Date.now();
|
||||
document.querySelectorAll(`img[src*="/t/${itemId}.webp"]`).forEach(img => {
|
||||
const url = new URL(img.src, window.location.origin);
|
||||
url.searchParams.set('t', timestamp);
|
||||
img.src = url.toString();
|
||||
});
|
||||
document.querySelectorAll(`.thumb[data-bg*="/t/${itemId}.webp"]`).forEach(thumb => {
|
||||
const bg = thumb.dataset.bg;
|
||||
if (bg) {
|
||||
const url = new URL(bg, window.location.origin);
|
||||
if (typeof window.refreshItemThumbnails === 'function') {
|
||||
window.refreshItemThumbnails(itemId, timestamp);
|
||||
} else {
|
||||
document.querySelectorAll(`img[src*="/t/${itemId}.webp"]`).forEach(img => {
|
||||
const url = new URL(img.src, window.location.origin);
|
||||
url.searchParams.set('t', timestamp);
|
||||
thumb.style.setProperty('--thumb-bg', `url('${url.toString()}')`);
|
||||
}
|
||||
});
|
||||
img.src = url.toString();
|
||||
});
|
||||
document.querySelectorAll(`.thumb[data-bg*="/t/${itemId}.webp"]`).forEach(thumb => {
|
||||
const bg = thumb.dataset.bg;
|
||||
if (bg) {
|
||||
const url = new URL(bg, window.location.origin);
|
||||
url.searchParams.set('t', timestamp);
|
||||
thumb.style.setProperty('--thumb-bg', `url('${url.toString()}')`);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (window.flashError) window.flashError(data.msg || 'Regeneration failed');
|
||||
else alert(data.msg || 'Regeneration failed');
|
||||
|
||||
Reference in New Issue
Block a user