fdsa
This commit is contained in:
@@ -3164,6 +3164,18 @@ body.sidebar-right-hidden #sidebar-drag-zone {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.thumb > .sidebar-media-placeholder {
|
||||
z-index: 1;
|
||||
font-size: 2.8em;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.thumb:has(.sidebar-media-placeholder),
|
||||
.thumb.thumb-fallback:has(.sidebar-media-placeholder) {
|
||||
opacity: 1 !important;
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
.sidebar-video-details {
|
||||
display: flex;
|
||||
margin-top: 8px;
|
||||
|
||||
+193
-55
@@ -297,7 +297,7 @@ window.cancelAnimFrame = (function () {
|
||||
* Forcefully refreshes all thumbnail occurrences for a specific item in the DOM.
|
||||
* Handles grid items (data-bg), images (src), and the background canvas.
|
||||
*/
|
||||
window.refreshItemThumbnails = (itemId, timestamp = Date.now()) => {
|
||||
window.refreshItemThumbnails = (itemId, timestamp = Date.now(), hasCoverart = undefined) => {
|
||||
if (!itemId) return;
|
||||
const idStr = String(itemId);
|
||||
|
||||
@@ -340,15 +340,28 @@ window.cancelAnimFrame = (function () {
|
||||
// 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);
|
||||
if (hasCoverart === true || (hasCoverart === undefined && audioCover.src && audioCover.src.includes('/ca/'))) {
|
||||
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);
|
||||
}
|
||||
} else if (hasCoverart === false) {
|
||||
const fallbackUrl = '/s/img/audio.webp';
|
||||
audioCover.src = fallbackUrl;
|
||||
const parent = audioCover.parentElement;
|
||||
if (parent) {
|
||||
parent.style.background = `url('${fallbackUrl}') no-repeat center / contain black`;
|
||||
}
|
||||
const audioEl = document.querySelector('audio#my-video');
|
||||
if (audioEl) {
|
||||
audioEl.setAttribute('poster', fallbackUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +447,19 @@ window.cancelAnimFrame = (function () {
|
||||
applyThumb(thumb, finalBg);
|
||||
} else {
|
||||
img.onload = () => applyThumb(thumb, finalBg);
|
||||
img.onerror = () => thumb.classList.remove('lazy-thumb');
|
||||
img.onerror = () => {
|
||||
const mime = thumb.dataset.mime || '';
|
||||
if (mime.startsWith('audio/')) {
|
||||
if (!thumb.querySelector('.sidebar-media-placeholder.audio')) {
|
||||
const ph = document.createElement('div');
|
||||
ph.className = 'sidebar-media-placeholder audio';
|
||||
ph.innerHTML = '<i class="fa-solid fa-music"></i>';
|
||||
thumb.prepend(ph);
|
||||
}
|
||||
thumb.classList.add('thumb-fallback');
|
||||
}
|
||||
thumb.classList.remove('lazy-thumb');
|
||||
};
|
||||
}
|
||||
thumb.dataset.lazyObserved = 'true';
|
||||
}
|
||||
@@ -463,7 +488,12 @@ window.cancelAnimFrame = (function () {
|
||||
} else {
|
||||
const mime = thumb.dataset.mime || '';
|
||||
if (mime.startsWith('audio/')) {
|
||||
thumb.style.setProperty('--thumb-bg', `url('/s/img/audio.webp')`);
|
||||
if (!thumb.querySelector('.sidebar-media-placeholder.audio')) {
|
||||
const ph = document.createElement('div');
|
||||
ph.className = 'sidebar-media-placeholder audio';
|
||||
ph.innerHTML = '<i class="fa-solid fa-music"></i>';
|
||||
thumb.prepend(ph);
|
||||
}
|
||||
thumb.classList.add('thumb-fallback');
|
||||
}
|
||||
thumb.classList.remove('lazy-thumb');
|
||||
@@ -1346,8 +1376,8 @@ window.cancelAnimFrame = (function () {
|
||||
};
|
||||
window.openOnaraModal = openOnaraModal;
|
||||
|
||||
const updateOnaraActiveItem = (itemid, url) => {
|
||||
if (!isOnaraActive()) return;
|
||||
const updateOnaraActiveItem = (itemid, url, forceScroll = false, slug = null) => {
|
||||
if (!isOnaraActive()) return null;
|
||||
// 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'));
|
||||
|
||||
@@ -1358,6 +1388,9 @@ window.cancelAnimFrame = (function () {
|
||||
targetThumb = document.querySelector(`.posts > a.thumb[href="${parsedPath}"], .posts > a.thumb[href="${url}"]`);
|
||||
} catch {}
|
||||
}
|
||||
if (!targetThumb && slug) {
|
||||
targetThumb = document.querySelector(`.posts > a.thumb[href$="/${slug}"]`);
|
||||
}
|
||||
if (!targetThumb && itemid) {
|
||||
targetThumb = document.querySelector(`.posts > a.thumb[href$="/${itemid}"], .posts > a.thumb[data-bg*="/${itemid}."]`);
|
||||
}
|
||||
@@ -1374,13 +1407,140 @@ window.cancelAnimFrame = (function () {
|
||||
const vh = window.innerHeight || document.documentElement.clientHeight;
|
||||
// If any part of the thumbnail is already visible in the viewport, do not scroll
|
||||
const isVisible = rect.bottom > navbarH && rect.top < vh;
|
||||
if (!isVisible) {
|
||||
targetThumb.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'instant' });
|
||||
if (!isVisible || forceScroll) {
|
||||
targetThumb.scrollIntoView({ block: 'center', inline: 'nearest', behavior: 'instant' });
|
||||
}
|
||||
}
|
||||
return targetThumb;
|
||||
};
|
||||
window.updateOnaraActiveItem = updateOnaraActiveItem;
|
||||
|
||||
let _onaraSyncSeq = 0;
|
||||
const syncOnaraBackgroundGrid = async (itemid, url, knownPage = null, slug = null) => {
|
||||
if (!isOnaraActive()) return;
|
||||
|
||||
// Fast path: if target item is already in current background DOM, just highlight and ensure visibility
|
||||
const existingThumb = updateOnaraActiveItem(itemid, url, false, slug);
|
||||
if (existingThumb) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentSeq = ++_onaraSyncSeq;
|
||||
const urlObj = new URL(url || window.location.href, window.location.origin);
|
||||
const feedBasePath = urlObj.pathname.replace(/\/+$/, '').replace(/\/(?:\d+|[a-zA-Z0-9_-]{11})$/, '') || '/';
|
||||
|
||||
let targetPage = (typeof knownPage === 'number' && knownPage >= 1) ? knownPage : null;
|
||||
|
||||
if (!targetPage) {
|
||||
try {
|
||||
const pageParams = new URLSearchParams();
|
||||
pageParams.set('id', itemid);
|
||||
if (feedBasePath.startsWith('/tag/')) {
|
||||
pageParams.set('tag', decodeURIComponent(feedBasePath.replace(/^\/tag\//, '')));
|
||||
} else if (feedBasePath.startsWith('/h/')) {
|
||||
pageParams.set('hall', decodeURIComponent(feedBasePath.replace(/^\/h\//, '')));
|
||||
} else if (feedBasePath.match(/^\/user\/([^/]+)\/hall\/([^/]+)/)) {
|
||||
const m = feedBasePath.match(/^\/user\/([^/]+)\/hall\/([^/]+)/);
|
||||
pageParams.set('userHallOwner', decodeURIComponent(m[1]));
|
||||
pageParams.set('userHall', decodeURIComponent(m[2]));
|
||||
} else if (feedBasePath.match(/^\/user\/([^/]+)\/favs/)) {
|
||||
const m = feedBasePath.match(/^\/user\/([^/]+)\/favs/);
|
||||
pageParams.set('user', decodeURIComponent(m[1]));
|
||||
pageParams.set('fav', 'true');
|
||||
} else if (feedBasePath.match(/^\/user\/([^/]+)/)) {
|
||||
const m = feedBasePath.match(/^\/user\/([^/]+)/);
|
||||
pageParams.set('user', decodeURIComponent(m[1]));
|
||||
} else if (feedBasePath === '/favs') {
|
||||
pageParams.set('fav', 'true');
|
||||
}
|
||||
if (typeof window.activeMode !== 'undefined') {
|
||||
pageParams.set('mode', window.activeMode);
|
||||
}
|
||||
const isStrict = window.f0ckSession?.strict_mode || (localStorage.getItem('search_strict') === 'true') || urlObj.searchParams.get('strict') === '1';
|
||||
if (isStrict) {
|
||||
pageParams.set('strict', '1');
|
||||
}
|
||||
const resp = await fetch(`/api/v2/item-page?${pageParams.toString()}`);
|
||||
if (resp.ok) {
|
||||
const pageData = await resp.json();
|
||||
if (pageData && pageData.success && pageData.page) {
|
||||
targetPage = pageData.page;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[ONARA] Failed to fetch item-page:', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSeq !== _onaraSyncSeq) return;
|
||||
if (!targetPage || targetPage < 1) targetPage = 1;
|
||||
|
||||
const pagePath = targetPage === 1 ? feedBasePath : (feedBasePath === '/' ? `/p/${targetPage}` : `${feedBasePath}/p/${targetPage}`);
|
||||
const searchParams = new URLSearchParams(urlObj.search);
|
||||
const searchStr = searchParams.toString() ? `?${searchParams.toString()}` : '';
|
||||
const pageUrl = pagePath + searchStr;
|
||||
|
||||
try {
|
||||
const pageRes = await fetch(pageUrl, {
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
});
|
||||
if (currentSeq !== _onaraSyncSeq) return;
|
||||
if (!pageRes.ok) return;
|
||||
|
||||
const html = await pageRes.text();
|
||||
if (currentSeq !== _onaraSyncSeq) return;
|
||||
|
||||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||||
const newPosts = doc.querySelector('.posts');
|
||||
const oldPosts = document.querySelector('.posts');
|
||||
|
||||
if (newPosts && oldPosts) {
|
||||
oldPosts.innerHTML = newPosts.innerHTML;
|
||||
oldPosts.dataset.currentPage = targetPage;
|
||||
if (newPosts.dataset.hasMore) {
|
||||
oldPosts.dataset.hasMore = newPosts.dataset.hasMore;
|
||||
}
|
||||
if (typeof window.initLazyLoading === 'function') {
|
||||
window.initLazyLoading();
|
||||
}
|
||||
}
|
||||
|
||||
const newPag = doc.querySelector('.pagination-wrapper');
|
||||
const oldPag = document.querySelector('.pagination-wrapper');
|
||||
if (newPag && oldPag) {
|
||||
oldPag.innerHTML = newPag.innerHTML;
|
||||
}
|
||||
|
||||
const newTitle = doc.querySelector('.page-title-wrap, .page-title, .user-profile-header, .hall-header');
|
||||
const oldTitle = document.querySelector('.page-title-wrap, .page-title, .user-profile-header, .hall-header');
|
||||
if (newTitle && oldTitle) {
|
||||
oldTitle.replaceWith(newTitle);
|
||||
}
|
||||
|
||||
window._onaraCurrentGridUrl = pageUrl;
|
||||
window._onaraReturnUrl = pageUrl;
|
||||
if (doc.title) {
|
||||
window._onaraReturnTitle = doc.title;
|
||||
}
|
||||
|
||||
const thumb = updateOnaraActiveItem(itemid, url, true, slug);
|
||||
if (!thumb && oldPosts) {
|
||||
const synthThumb = document.createElement('a');
|
||||
synthThumb.href = url;
|
||||
synthThumb.className = 'thumb lazy-thumb onara-active';
|
||||
synthThumb.dataset.bg = `/t/${itemid}.webp`;
|
||||
synthThumb.dataset.size = '1';
|
||||
synthThumb.innerHTML = '<div class="thumb-indicators"></div><p></p>';
|
||||
oldPosts.prepend(synthThumb);
|
||||
if (typeof window.initLazyLoading === 'function') window.initLazyLoading();
|
||||
synthThumb.scrollIntoView({ block: 'center', inline: 'nearest', behavior: 'instant' });
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[ONARA] Failed to sync background grid:', err);
|
||||
}
|
||||
};
|
||||
window.syncOnaraBackgroundGrid = syncOnaraBackgroundGrid;
|
||||
|
||||
const isItemPath = (pathOrUrl) => {
|
||||
try {
|
||||
const p = new URL(pathOrUrl, window.location.origin).pathname;
|
||||
@@ -4436,6 +4596,10 @@ window.cancelAnimFrame = (function () {
|
||||
});
|
||||
}
|
||||
|
||||
if (useOnara) {
|
||||
params.append('onara', '1');
|
||||
}
|
||||
|
||||
if (params.toString() !== '') {
|
||||
ajaxUrl += (ajaxUrl.includes('?') ? '&' : '?') + params.toString();
|
||||
}
|
||||
@@ -4466,7 +4630,8 @@ window.cancelAnimFrame = (function () {
|
||||
onaraMount.innerHTML = '';
|
||||
}
|
||||
_container = onaraMount;
|
||||
updateOnaraActiveItem(itemid, url);
|
||||
updateOnaraActiveItem(itemid, url, false, _cachedItem.slug);
|
||||
syncOnaraBackgroundGrid(itemid, url, _cachedItem.page, _cachedItem.slug);
|
||||
} else {
|
||||
_container = document.querySelector('#main .container') || (document.getElementById('main')?.classList.contains('item-view') ? document.getElementById('main') : null);
|
||||
const _isStructuralPage = !!document.querySelector('.pagewrapper');
|
||||
@@ -4597,12 +4762,14 @@ window.cancelAnimFrame = (function () {
|
||||
if (!freshText) return;
|
||||
let freshHtml = freshText;
|
||||
let freshSlug = null;
|
||||
let freshPage = null;
|
||||
try {
|
||||
const d = JSON.parse(freshText);
|
||||
if (d && typeof d.html === 'string') freshHtml = d.html;
|
||||
if (d && (d.slug || d.item?.slug)) freshSlug = d.slug || d.item?.slug;
|
||||
if (d && d.page) freshPage = d.page;
|
||||
} catch(_) {}
|
||||
itemCacheMap.set(_itemCacheKey, { html: freshHtml, slug: freshSlug, ts: Date.now() });
|
||||
itemCacheMap.set(_itemCacheKey, { html: freshHtml, slug: freshSlug, page: freshPage, ts: Date.now() });
|
||||
window.f0ckDebug('[itemCache] Background revalidation complete for', _itemCacheKey);
|
||||
})
|
||||
.catch(() => {});
|
||||
@@ -4629,7 +4796,7 @@ window.cancelAnimFrame = (function () {
|
||||
- Total Network: ${(tBody - tStart).toFixed(2)}ms
|
||||
- Content Size: ${(rawText.length / 1024).toFixed(2)} KB`);
|
||||
|
||||
let html, paginationHtml, responseSlug = null;
|
||||
let html, paginationHtml, responseSlug = null, responsePage = null;
|
||||
|
||||
try {
|
||||
// Optimistically try to parse as JSON first
|
||||
@@ -4643,6 +4810,7 @@ window.cancelAnimFrame = (function () {
|
||||
html = data.html;
|
||||
paginationHtml = data.pagination;
|
||||
responseSlug = data.slug || data.item?.slug || null;
|
||||
responsePage = data.page || null;
|
||||
} else {
|
||||
html = rawText;
|
||||
}
|
||||
@@ -4653,7 +4821,7 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
// ── Store in item cache (stale-while-revalidate) ───────────────────────
|
||||
if (html && !options.noCacheStore) {
|
||||
itemCacheMap.set(_itemCacheKey, { html, slug: responseSlug, ts: Date.now() });
|
||||
itemCacheMap.set(_itemCacheKey, { html, slug: responseSlug, page: responsePage, ts: Date.now() });
|
||||
if (itemCacheMap.size > ITEM_CACHE_MAX) {
|
||||
// Evict oldest entry
|
||||
itemCacheMap.delete(itemCacheMap.keys().next().value);
|
||||
@@ -4673,7 +4841,8 @@ window.cancelAnimFrame = (function () {
|
||||
onaraMount.innerHTML = '';
|
||||
}
|
||||
container = onaraMount;
|
||||
updateOnaraActiveItem(itemid, url);
|
||||
updateOnaraActiveItem(itemid, url, false, responseSlug);
|
||||
syncOnaraBackgroundGrid(itemid, url, responsePage, responseSlug);
|
||||
} 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');
|
||||
@@ -5121,38 +5290,7 @@ window.cancelAnimFrame = (function () {
|
||||
|
||||
// Background grid sync — page number already in response, no extra fetch needed
|
||||
if (isOnaraActive() && targetId) {
|
||||
const postsEl = document.querySelector('.posts[data-current-page]');
|
||||
const currentPage = postsEl ? parseInt(postsEl.dataset.currentPage, 10) : 1;
|
||||
|
||||
if (targetPage !== currentPage) {
|
||||
// Build page URL from current grid base
|
||||
let gridBase = window._onaraCurrentGridUrl
|
||||
? window._onaraCurrentGridUrl.replace(/\/p\/\d+/, '').replace(/\/$/, '')
|
||||
: window.location.pathname
|
||||
.replace(/\/[a-zA-Z0-9_-]{11}$/, '')
|
||||
.replace(/\/\d+$/, '')
|
||||
.replace(/\/p\/\d+/, '')
|
||||
.replace(/\/$/, '');
|
||||
const pageUrl = targetPage === 1 ? (gridBase || '/') : `${gridBase}/p/${targetPage}`;
|
||||
|
||||
fetch(pageUrl)
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||||
const newPosts = doc.querySelector('.posts');
|
||||
const oldPosts = document.querySelector('.posts');
|
||||
if (newPosts && oldPosts) {
|
||||
oldPosts.innerHTML = newPosts.innerHTML;
|
||||
oldPosts.dataset.currentPage = targetPage;
|
||||
if (typeof window.initLazyLoading === 'function') window.initLazyLoading();
|
||||
}
|
||||
window._onaraCurrentGridUrl = pageUrl;
|
||||
if (typeof updateOnaraActiveItem === 'function') {
|
||||
updateOnaraActiveItem(targetId, `/${targetKey}`);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
syncOnaraBackgroundGrid(targetId, `/${targetKey}`, targetPage, targetKey);
|
||||
}
|
||||
} else if (params.has('tag') || params.has('hall') || params.has('user') || params.has('userHall')) {
|
||||
// Context had no matching items with the active MIME filter — try global random with the same filter
|
||||
@@ -9110,7 +9248,7 @@ class NotificationSystem {
|
||||
} else if (data.type === 'rethumb') {
|
||||
window.f0ckDebug(`[SSE] Rethumb update received for item ${data.data?.item_id}`);
|
||||
if (data.data && data.data.item_id && window.refreshItemThumbnails) {
|
||||
window.refreshItemThumbnails(data.data.item_id);
|
||||
window.refreshItemThumbnails(data.data.item_id, Date.now(), data.data.has_coverart);
|
||||
}
|
||||
} else if (data.type === 'new_item') {
|
||||
window.f0ckDebug(`[SSE] New item received:`, data.data);
|
||||
@@ -13838,7 +13976,7 @@ document.addEventListener('click', (e) => {
|
||||
// Cache-bust thumbnails and player media on page
|
||||
const timestamp = Date.now();
|
||||
if (typeof window.refreshItemThumbnails === 'function') {
|
||||
window.refreshItemThumbnails(itemId, timestamp);
|
||||
window.refreshItemThumbnails(itemId, timestamp, data.has_coverart);
|
||||
} else {
|
||||
document.querySelectorAll(`img[src*="/t/${itemId}.webp"]`).forEach(img => {
|
||||
const url = new URL(img.src, window.location.origin);
|
||||
|
||||
Reference in New Issue
Block a user