This commit is contained in:
2026-09-29 18:34:51 +02:00
parent 6c813143eb
commit 40ba687970
5 changed files with 260 additions and 63 deletions
+34 -22
View File
@@ -2916,8 +2916,9 @@ body.sidebar-right-hidden #sidebar-drag-zone::after {
overflow: visible !important;
}
/* Same track count as the open state so the sidebar toggle can animate the columns (f0ckm.js) */
body.layout-legacy.sidebar-right-hidden .item-layout-container {
grid-template-columns: 1fr;
grid-template-columns: minmax(0, 1fr) 0px;
}
body.layout-legacy .item-layout-container .item-main-content {
@@ -3473,6 +3474,7 @@ body.sidebar-right-hidden #sidebar-drag-zone::after {
width: 320px;
max-height: 80vh;
overflow-y: auto;
scrollbar-width: none;
background: rgba(18, 18, 22, 0.95);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
@@ -3495,19 +3497,17 @@ body.sidebar-right-hidden #sidebar-drag-zone::after {
flex: 1;
min-height: 0;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
scrollbar-width: none;
padding: 0;
touch-action: pan-y;
}
.sidebar-tuner-container::-webkit-scrollbar {
width: 5px;
}
.sidebar-tuner-container::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.15);
border-radius: 4px;
/* Tuner scrolls (floating panel or sidebar container) but without a visible scrollbar */
.sidebar-tuner-container::-webkit-scrollbar,
.f0ck-audio-tuner-panel::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
}
.sidebar-tuner-container.active {
@@ -4351,7 +4351,7 @@ html[theme='95'] .sidebar-video-title {
font-size: 1em;
border-bottom: 1px solid var(--nav-border-color);
contain: layout style;
margin: 0px;
margin-bottom: 5px;
}
.sidebar-activity .comment-content-inner {
@@ -4833,7 +4833,7 @@ body.layout-legacy .comment-input {
}
.admin-pin-btn:hover,
.admin-edit-btn:hover {^
.admin-edit-btn:hover {
color: var(--accent);
}
@@ -5418,6 +5418,14 @@ body.layout-legacy .blahlol {
border-top: 1px solid var(--nav-border-color);
}
/* Comments hidden ("c"): nothing below closes the box, so it gets its own bottom border.
comments-sliding = the comments are sliding up behind it or back down (comments.js); the border
stays for the whole slide in both directions */
body.layout-legacy.comments-hidden .blahlol,
body.layout-legacy.comments-sliding .blahlol {
border-bottom: 1px solid var(--nav-border-color);
}
body.layout-legacy .comments-list:not(:has(.comment)) {
border: none;
}
@@ -6540,9 +6548,9 @@ html[res="fullscreen"] span#favs {
}
/* Linux Firefox "thin" is often too small and hard to see. Use auto there. */
html.is-linux.is-firefox *:not(html):not(body) {
/* html.is-linux.is-firefox *:not(html):not(body) {
scrollbar-width: auto;
}
} */
/* Strictly hide root body and html scrollbar everywhere - eliminates gutter spacing */
html,
@@ -10623,12 +10631,15 @@ div.favs div.posts {
top: 0;
left: 0;
bottom: 0;
width: calc(100vw - var(--sidebar-w, 300px));
/* Always full width, shifted left by half the sidebar so it stays centred under the content. The size
never changes with the sidebar, so the drawing is never stretched or redrawn: the sidebar toggle only
moves it (transform, GPU), see toggleSidebarRight() in f0ckm.js */
width: 100vw;
height: 100%;
transform: translate3d(0, 0, 0) scale(var(--bg-canvas-zoom, 1.38));
transform: translate3d(calc(var(--sidebar-w, 300px) / -2), 0, 0) scale(var(--bg-canvas-zoom, 1.38));
transform-origin: center center;
z-index: -2;
transition: opacity 1.5s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s ease-in-out;
transition: opacity 1.5s cubic-bezier(0.4, 0, 0.2, 1), transform 0.6s cubic-bezier(0.45, 0, 0.2, 1);
opacity: var(--bg-canvas-opacity, 0.81);
filter: var(--bg-canvas-filter, none);
-webkit-filter: var(--bg-canvas-filter, none);
@@ -15526,7 +15537,6 @@ body.layout-modern .tag-ac-input {
min-height: 0;
overflow-y: auto;
overscroll-behavior: contain;
padding: 0 18px;
scrollbar-width: none;
}
@@ -15540,7 +15550,6 @@ body.layout-modern .tag-ac-input {
/* Above everything the form layers inside the panel (badges 5-100, tag input 9998, emoji picker 10000);
all of it lives in the panel's own stacking context, so these numbers don't leak outside */
z-index: 10001;
margin: 0 -18px 12px;
padding: 16px 62px 12px 18px;
background: var(--bg, #111);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
@@ -15672,12 +15681,15 @@ nav.navbar #nav-upload-link.is-active {
box-shadow: inset 0 -2px 0 var(--accent);
}
nav.navbar #nav-upload-link.is-active i {
nav.navbar #nav-upload-link i {
display: inline-block;
transform: rotate(180deg);
transition: transform 0.15s;
}
nav.navbar #nav-upload-link.is-active i {
transform: rotate(180deg);
}
/* Navbar entries (settings gear, user/anon menu "Settings") whose page is open in the page modal */
nav.navbar a[data-page-modal].is-active,
nav.navbar a[data-page-modal].is-active i {
@@ -21485,7 +21497,7 @@ body.onara-modal-open:not(.onara-modal-closing) #bg,
body.onara-modal-open:not(.onara-modal-closing) #bg.fader-in {
z-index: 51 !important;
cursor: pointer !important;
transition: width 0.3s ease-in-out !important;
transition: transform 0.6s cubic-bezier(0.45, 0, 0.2, 1) !important;
animation: none !important;
opacity: var(--bg-canvas-opacity, 1.0) !important;
}
+90
View File
@@ -47,6 +47,9 @@ class CommentSystem {
// inline script in header.html (prevents flash). Here we sync the
// container-level class and display state to match.
if (this.container) {
// A slide cut short by navigating away must not leave its border behind
this._legacySlide = null;
document.body.classList.remove('comments-sliding');
const isHidden = localStorage.getItem('comments_hidden') === 'true';
// Force show if hash is present
if (window.location.hash && window.location.hash.startsWith('#c')) {
@@ -4135,6 +4138,16 @@ class CommentSystem {
document.body.classList.contains('comments-hidden') ||
localStorage.getItem('comments_hidden') === 'true';
// Legacy layout: comments slide up behind the info box (and back down out of it)
const reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (document.body.classList.contains('layout-legacy') && typeof this.container.animate === 'function' && !reduceMotion) {
// A slide still running decides the direction, since the classes only flip when it ends
const running = this._legacySlide && this._legacySlide.el === this.container ? this._legacySlide : null;
const hiddenNow = running ? running.dir === 'hide' : isHidden;
this.slideLegacyComments(!hiddenNow, layout, sidebar, siblings);
return;
}
if (isHidden) {
// SHOW: expand grid first, then slide content in
if (layout) layout.classList.remove('sidebar-hidden');
@@ -4170,6 +4183,83 @@ class CommentSystem {
}
}
// Legacy layout slide: the container shrinks from the bottom up while its content moves up by the same
// amount, so the comments look like they retract behind the box above them (reverse on show).
// Pressing again mid-slide turns it around from where it is.
slideLegacyComments(hide, layout, sidebar, siblings) {
const el = this.container;
const kids = Array.from(el.children);
// Curtain feel: slow, soft start, gentle settle at the end
const DURATION = 900;
const EASING = 'cubic-bezier(0.45, 0, 0.2, 1)';
let startH = null;
if (this._legacySlide) {
// Only turn around from mid-slide on the same item; a slide left over from a previous item is dropped
if (this._legacySlide.el === el) startH = el.getBoundingClientRect().height;
this._legacySlide.anims.forEach(a => a.cancel());
this._legacySlide = null;
}
if (!hide) {
// Put it back in the flow first (collapsed), so its full height can be measured
if (layout) layout.classList.remove('sidebar-hidden');
document.body.classList.remove('sidebar-left-hidden', 'comments-hidden');
// Border stays until the comments are fully down again
document.body.classList.add('comments-sliding');
el.classList.remove('is-hidden', 'faded-out');
el.style.removeProperty('display');
if (sidebar) {
sidebar.classList.remove('is-hidden');
sidebar.style.removeProperty('display');
}
siblings.forEach(s => s.classList.remove('faded-out'));
localStorage.setItem('comments_hidden', 'false');
if (startH === null) startH = 0;
} else {
// Mark state immediately so quick navigations stay hidden
localStorage.setItem('comments_hidden', 'true');
document.body.classList.add('comments-sliding');
if (startH === null) startH = el.getBoundingClientRect().height;
}
el.style.height = 'auto';
const fullH = el.scrollHeight;
const endH = hide ? 0 : fullH;
el.style.overflow = 'hidden';
el.style.height = endH + 'px';
const frames = (h0, h1) => [{ transform: 'translateY(' + (h0 - fullH) + 'px)' }, { transform: 'translateY(' + (h1 - fullH) + 'px)' }];
// A turnaround covers only part of the distance, so it takes proportionally less time (same speed)
const share = fullH > 0 ? Math.abs(endH - startH) / fullH : 1;
const opts = { duration: Math.round(DURATION * Math.max(0.3, Math.min(1, share))), easing: EASING };
const anims = [el.animate([{ height: startH + 'px' }, { height: endH + 'px' }], opts)];
kids.forEach(k => anims.push(k.animate(frames(startH, endH), opts)));
const slide = { dir: hide ? 'hide' : 'show', anims, el };
this._legacySlide = slide;
anims[0].onfinish = () => {
if (this._legacySlide !== slide) return;
this._legacySlide = null;
el.style.removeProperty('overflow');
el.style.removeProperty('height');
if (!hide) {
document.body.classList.remove('comments-sliding');
return;
}
el.classList.add('faded-out', 'is-hidden');
el.style.setProperty('display', 'none', 'important');
siblings.forEach(s => s.classList.add('faded-out'));
if (sidebar) {
sidebar.classList.add('is-hidden');
sidebar.style.setProperty('display', 'none', 'important');
}
if (layout) layout.classList.add('sidebar-hidden');
document.body.classList.add('sidebar-left-hidden', 'comments-hidden');
document.body.classList.remove('comments-sliding');
};
}
escapeHtml(unsafe) {
+133 -38
View File
@@ -3745,6 +3745,7 @@ window.cancelAnimFrame = (function () {
const newYtSrc = ytId ? `https://www.youtube.com/embed/${ytId}?enablejsapi=1` : newSrc;
if (ytIframe.src !== newYtSrc) ytIframe.src = newYtSrc;
ytIframe.style.display = 'block';
if (window.stopVisualizer) window.stopVisualizer();
} else if (mime.startsWith('video/')) {
container.classList.remove('is-youtube-active');
container.classList.add('is-video-active');
@@ -3770,6 +3771,7 @@ window.cancelAnimFrame = (function () {
initAlbumVideoV0ck();
video = videoEl;
if (window.stopVisualizer) window.stopVisualizer();
if (window.initBackground) window.initBackground();
if (item.size && videoWrapper) {
@@ -3943,6 +3945,8 @@ window.cancelAnimFrame = (function () {
imgEl.classList.add('album-img-fade');
}
video = null;
if (window.stopVisualizer) window.stopVisualizer();
if (window.initBackground) window.initBackground();
}
if (linkEl && !mime.startsWith('video/')) {
@@ -5275,7 +5279,7 @@ window.cancelAnimFrame = (function () {
}
if (!elem) {
const albumAudio = document.getElementById('f0ck-album-audio');
if (albumAudio && albumAudio.src) {
if (albumAudio && albumAudio.src && !isInactiveAlbumAudio(albumAudio)) {
elem = albumAudio;
}
}
@@ -5528,6 +5532,16 @@ window.cancelAnimFrame = (function () {
const itemId = window.getCurrentItemId();
const isDrawable = elem && elem.tagName === 'IMG';
// Album image slides: the /t/ thumb belongs to the whole album, so draw the slide itself
if (isDrawable && elem.closest('.album-gallery-container')) {
if (elem.complete && elem.naturalWidth > 0) {
crossfadeToSource(elem);
} else {
elem.onload = () => crossfadeToSource(elem);
}
return;
}
if (itemId) {
if (document.body.classList.contains('onara-modal-open')) {
const onaraThumbImg = document.querySelector('.posts > a.thumb.onara-active img, .posts > a.thumb:focus img');
@@ -8825,6 +8839,20 @@ window.cancelAnimFrame = (function () {
}
};
// Stop the audio visualizer loop so it no longer paints into #bg
window.stopVisualizer = () => {
if (visualizerRafId) { window.cancelAnimFrame(visualizerRafId); visualizerRafId = null; }
const bgCanvas = document.getElementById('bg');
if (bgCanvas) bgCanvas.style.filter = '';
};
// The album template always contains a hidden <audio>; it only counts while an audio slide is shown
const isInactiveAlbumAudio = (el) => {
if (!el || el.id !== 'f0ck-album-audio') return false;
const albumContainer = el.closest('.album-gallery-container');
return !albumContainer || !albumContainer.classList.contains('is-audio-active');
};
window.initVisualizer = (targetAudio) => {
let audioElement = targetAudio;
if (!audioElement || !audioElement.isConnected) {
@@ -8847,6 +8875,11 @@ window.cancelAnimFrame = (function () {
}
}
}
if (isInactiveAlbumAudio(audioElement)) {
// Album is showing an image/video slide: the visualizer must not take over #bg
window.stopVisualizer();
return;
}
if (audioElement) {
if (!audioElement.crossOrigin) {
audioElement.crossOrigin = 'anonymous';
@@ -17426,41 +17459,77 @@ window.cancelAnimFrame = (function () {
// At ≤599px the sidebar is a pure overlay — never touch wrapper padding
const animateWrappers = window.innerWidth > 599;
// Smoothness: the sidebar and #bg canvas animate via CSS transitions (compositor, minimal layout).
// The content wrappers and Onara modal change width ONCE instead of every frame: before the slide
// when opening, after it when closing. The strip the sidebar travels through is therefore always
// empty background, so no thumbnails reflow behind it; the single reflow is masked with an opacity fade.
const DURATION = 320;
const EASING = 'cubic-bezier(0.32, 0.72, 0, 1)';
// Smoothness: the sidebar, #bg canvas, drag pill, right-anchored bars, the Onara modal and the item
// view's grid all move together, frame by frame, with one slow curtain-like easing (same feel as the
// legacy comment slide). Only the thumbnail-grid wrappers (index pages) still change width ONCE
// (before the slide when opening, after it when closing): their thumbnails would re-wrap into
// different rows mid-slide, so that single reflow is masked with an opacity fade instead.
const DURATION = 600;
const EASING = 'cubic-bezier(0.45, 0, 0.2, 1)';
const glide = DURATION + 'ms ' + EASING;
const wrappers = getSidebarWrappers();
const onaraModal = document.getElementById('onara-modal');
const bgCanvas = document.getElementById('bg');
const isEdgeWrapper = w => w.classList.contains('pagination-container-fluid') || w.classList.contains('admin-bar') || w.classList.contains('messages-convo-page');
// Elements positioned by `right`: glide to the new edge together with the sidebar (both directions)
const moveEdges = (open) => {
if (!animateWrappers) return;
const val = open ? sidebarWidth + 'px' : '0px';
const targets = wrappers ? Array.from(wrappers).filter(isEdgeWrapper) : [];
if (onaraModal) targets.push(onaraModal);
targets.forEach(el => {
// Pin the current value first so the transition has a defined start
el.style.setProperty('transition', 'none', 'important');
el.style.setProperty('right', getComputedStyle(el).right, 'important');
void el.offsetWidth;
el.style.setProperty('transition', 'right ' + glide, 'important');
el.style.setProperty('right', val, 'important');
});
};
// Padding-based wrappers (thumbnail grids): one-time reflow, softened
const applyLayout = (open) => {
// Let overlays that mirror the content area (page modal) resize at exactly the same moment
window.dispatchEvent(new CustomEvent('f0ck:sidebar-right-layout', { detail: { open, width: sidebarWidth, overlay: !animateWrappers } }));
if (!animateWrappers) return;
wrappers.forEach(w => {
const isRightEdge = w.classList.contains('pagination-container-fluid') || w.classList.contains('admin-bar');
const isMessages = w.classList.contains('messages-convo-page');
const prop = (isRightEdge || isMessages) ? 'right' : 'padding-right';
if (isEdgeWrapper(w)) return;
w.style.setProperty('transition', 'none', 'important');
w.style.setProperty(prop, open ? sidebarWidth + 'px' : '0px', 'important');
});
if (onaraModal) {
onaraModal.style.setProperty('transition', 'none', 'important');
onaraModal.style.setProperty('right', open ? sidebarWidth + 'px' : '0px', 'important');
}
// #bg canvas is handled separately below — it transitions smoothly alongside the sidebar
// Soften the one-time reflow
wrappers.forEach(w => {
if (w.classList.contains('pagination-container-fluid') || w.classList.contains('admin-bar')) return;
w.style.setProperty('padding-right', open ? sidebarWidth + 'px' : '0px', 'important');
if (typeof w.animate === 'function') w.animate([{ opacity: 0.55 }, { opacity: 1 }], { duration: 220, easing: 'ease-out' });
});
if (typeof window.redrawBgCanvas === 'function') requestAnimationFrame(() => window.redrawBgCanvas());
};
// Opening: make room first, then slide in over empty space
// Item view: animate the grid's sidebar track so media and comments glide with the sidebar instead
// of jumping when the class flips at the end. The target comes from the current track sizes
// (last track = sidebar column, the one before it = flexible content column) rather than from
// flipping the class early, which would kick off unrelated CSS transitions.
let gridAnim = null;
const itemLayout = animateWrappers && !document.body.classList.contains('onara-modal-open')
? document.querySelector('.item-layout-container') : null;
if (itemLayout && typeof itemLayout.animate === 'function') {
const from = getComputedStyle(itemLayout).gridTemplateColumns;
const tracks = from && from !== 'none' ? from.trim().split(/\s+/) : [];
const px = tracks.map(t => (/^-?[\d.]+px$/.test(t) ? parseFloat(t) : NaN));
if (tracks.length >= 2 && px.every(n => !isNaN(n))) {
const last = px.length - 1;
const newLast = isHidden ? sidebarWidth : 0;
if (Math.abs(px[last] - newLast) > 0.5) {
const to = px.slice();
to[last - 1] = Math.max(0, px[last - 1] + (px[last] - newLast));
to[last] = newLast;
itemLayout.style.setProperty('transition', 'none', 'important');
gridAnim = itemLayout.animate(
[{ gridTemplateColumns: px.map(n => n + 'px').join(' ') }, { gridTemplateColumns: to.map(n => n + 'px').join(' ') }],
{ duration: DURATION, easing: EASING, fill: 'forwards' }
);
}
}
}
moveEdges(isHidden);
// Opening: make room in thumbnail grids first, then slide in over empty space
if (isHidden) applyLayout(true);
// The drag-zone pill follows the sidebar edge (small fixed element: cheap to animate)
@@ -17477,22 +17546,17 @@ window.cancelAnimFrame = (function () {
edgeZone.style.pointerEvents = 'all';
}
// Commit the starting width for #bg so the transition has a defined origin
if (bgCanvas && animateWrappers) {
const bgStartWidth = isHidden ? '100vw' : `calc(100vw - ${sidebarWidth}px)`;
bgCanvas.style.setProperty('width', bgStartWidth, 'important');
}
sidebar.style.willChange = 'transform';
void sidebar.offsetWidth; // commit the start state before transitions begin
sidebar.style.setProperty('transition', `transform ${DURATION}ms ${EASING}`, 'important');
sidebar.style.transform = `translateX(${targetTranslate}px)`;
// #bg canvas width transitions in sync with the sidebar slide (position:fixed, no layout cost)
// #bg canvas: same size in both states, it only shifts to stay centred under the content. Moving it
// (transform, GPU) instead of resizing it means no stretched frame mid-slide and no redraw at the end.
if (bgCanvas && animateWrappers) {
const bgTargetWidth = isHidden ? `calc(100vw - ${sidebarWidth}px)` : '100vw';
bgCanvas.style.setProperty('transition', `width ${DURATION}ms ${EASING}`, 'important');
bgCanvas.style.setProperty('width', bgTargetWidth, 'important');
const bgShift = isHidden ? -sidebarWidth / 2 : 0;
bgCanvas.style.setProperty('transition', `transform ${DURATION}ms ${EASING}`, 'important');
bgCanvas.style.setProperty('transform', `translate3d(${bgShift}px, 0, 0) scale(var(--bg-canvas-zoom, 1.38))`, 'important');
}
let settled = false;
@@ -17522,16 +17586,16 @@ window.cancelAnimFrame = (function () {
}
if (bgCanvas) {
bgCanvas.style.removeProperty('transition');
bgCanvas.style.removeProperty('width');
bgCanvas.style.removeProperty('transform');
}
wrappers.forEach(w => {
w.style.removeProperty('transition');
w.style.removeProperty('padding-right');
w.style.removeProperty('right');
});
if (typeof window.redrawBgCanvas === 'function') {
window.redrawBgCanvas();
}
// The class now yields the columns the animation ended on: hand back to the stylesheet
if (gridAnim) gridAnim.cancel();
if (itemLayout) itemLayout.style.removeProperty('transition');
});
};
@@ -22685,6 +22749,12 @@ document.addEventListener('click', (e) => {
// Trackpad sideways swipes (deltaX dominant) are left to the browser.
(() => {
const WHEEL_X_SEL = '.f0ck-tuner-subtabs-nav, .f0ck-tuner-mode-bar, #settings-quicknav';
const WHEEL_X_SPEED = 0.45; // fraction of the wheel delta applied per notch
const WHEEL_X_EASE = 0.12; // share of the remaining distance covered per frame
const stopGlide = (bar) => {
if (bar._wheelRaf) cancelAnimationFrame(bar._wheelRaf);
bar._wheelRaf = null;
};
document.addEventListener('wheel', (e) => {
if (e.ctrlKey || e.defaultPrevented) return; // ctrl+wheel = zoom
if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return;
@@ -22695,7 +22765,9 @@ document.addEventListener('click', (e) => {
const dir = Math.sign(e.deltaY);
// The wheel stays with the bar while the pointer is on it (no page scroll)
e.preventDefault();
if ((dir < 0 && bar.scrollLeft <= 0) || (dir > 0 && bar.scrollLeft >= max - 1)) {
// While a glide is running, measure against where it is heading, not where it currently is
const pos = bar._wheelRaf ? bar._wheelTarget : bar.scrollLeft;
if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= max - 1)) {
// At the end: short rubber-band stretch past the edge, then ease back. A running stretch is not
// restarted, so a continuous wheel spin reads as one bounce instead of a jitter.
const items = Array.from(bar.children).filter(el => typeof el.animate === 'function' && el.offsetParent !== null);
@@ -22722,7 +22794,30 @@ document.addEventListener('click', (e) => {
}
// deltaMode 1 = lines (Firefox mouse wheels), 2 = pages
const amount = Math.abs(e.deltaMode === 1 ? e.deltaY * 16 : e.deltaMode === 2 ? e.deltaY * bar.clientWidth : e.deltaY);
bar.scrollLeft = Math.max(0, Math.min(max, bar.scrollLeft + dir * amount));
// Slower than a raw wheel step, and eased: each notch moves the target, the bar glides after it
bar._wheelTarget = Math.max(0, Math.min(max, pos + dir * amount * WHEEL_X_SPEED));
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
bar.scrollLeft = bar._wheelTarget;
return;
}
if (!bar._wheelRaf) {
if (!bar._wheelCancelBound) {
// Grabbing the bar (touch/pen/mouse) hands control back to the user
bar.addEventListener('pointerdown', () => stopGlide(bar), { passive: true });
bar._wheelCancelBound = true;
}
const step = () => {
const diff = bar._wheelTarget - bar.scrollLeft;
if (Math.abs(diff) < 0.5) {
bar.scrollLeft = bar._wheelTarget;
bar._wheelRaf = null;
return;
}
bar.scrollLeft += diff * WHEEL_X_EASE;
bar._wheelRaf = requestAnimationFrame(step);
};
bar._wheelRaf = requestAnimationFrame(step);
}
}, { passive: false });
})();
+2 -2
View File
@@ -144,7 +144,7 @@
@endif
<i class="iconset fa-solid fa-circle-info" id="a_info" data-item-id="{{ item.id }}" title="{{ t('info_modal.button_title') || 'Post & File Info' }}"></i>
@if(enable_comments)
<i class="iconset {{ isSubscribed ? 'fa-solid' : 'fa-regular' }} fa-bell" id="subscribe-btn" data-item-id="{{ item.id }}" title="{{ isSubscribed ? 'Subscribed' : 'Subscribe' }}"></i>
<i class="iconset {{ isSubscribed ? 'fa-solid active' : 'fa-regular' }} fa-bell" id="subscribe-btn" data-item-id="{{ item.id }}" title="{{ isSubscribed ? 'Subscribed' : 'Subscribe' }}"></i>
@endif
<i class="iconset fa-solid fa-triangle-exclamation report-item-btn" data-item-id="{{ item.id }}" title="Report this post"></i>
@if(halls_enabled)
@@ -212,7 +212,7 @@
@endif
<i class="iconset fa-solid fa-circle-info" id="a_info" data-item-id="{{ item.id }}" title="{{ t('info_modal.button_title') || 'Post & File Info' }}"></i>
@if(enable_comments)
<i class="iconset {{ isSubscribed ? 'fa-solid' : 'fa-regular' }} fa-bell" id="subscribe-btn" data-item-id="{{ item.id }}" title="{{ isSubscribed ? 'Subscribed' : 'Subscribe' }}"></i>
<i class="iconset {{ isSubscribed ? 'fa-solid active' : 'fa-regular' }} fa-bell" id="subscribe-btn" data-item-id="{{ item.id }}" title="{{ isSubscribed ? 'Subscribed' : 'Subscribe' }}"></i>
@endif
<i class="iconset fa-solid fa-triangle-exclamation report-item-btn" data-item-id="{{ item.id }}" title="Report this post"></i>
@if(halls_enabled)
+1 -1
View File
@@ -176,7 +176,7 @@
@if(session)
<i class="iconset fa-solid fa-circle-info" id="a_info" data-item-id="{{ item.id }}" title="{{ t('info_modal.button_title') || 'Post & File Info' }}"></i>
@if(enable_comments)
<i class="iconset {{ isSubscribed ? 'fa-solid' : 'fa-regular' }} fa-bell" id="subscribe-btn" data-item-id="{{ item.id }}" title="{{ isSubscribed ? 'Subscribed' : 'Subscribe' }}"></i>
<i class="iconset {{ isSubscribed ? 'fa-solid active' : 'fa-regular' }} fa-bell" id="subscribe-btn" data-item-id="{{ item.id }}" title="{{ isSubscribed ? 'Subscribed' : 'Subscribe' }}"></i>
@endif
<i class="iconset fa-solid fa-triangle-exclamation report-item-btn" data-item-id="{{ item.id }}" title="Report this post"></i>
@if(can_manage_item)