sunshine daisy
This commit is contained in:
@@ -2119,8 +2119,100 @@ body.layout-modern .global-sidebar-right {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
/* Mobile Stacking for Legacy Mode (max-width: 999px) */
|
||||
/* Mobile sidebar (max-width: 999px): sidebar fixed, capped to viewport width */
|
||||
@media (max-width: 999px) {
|
||||
/* Sidebar itself: cap width to viewport, always right-anchored */
|
||||
.item-sidebar-right,
|
||||
.index-sidebar-right,
|
||||
.global-sidebar-right {
|
||||
width: min(280px, 80vw) !important;
|
||||
right: 0 !important;
|
||||
}
|
||||
|
||||
body.sidebar-right-hidden .item-sidebar-right,
|
||||
body.sidebar-right-hidden .index-sidebar-right,
|
||||
body.sidebar-right-hidden .global-sidebar-right {
|
||||
right: calc(-1 * min(280px, 80vw)) !important;
|
||||
}
|
||||
|
||||
/* Mobile: pagination centered in available space (left of sidebar) */
|
||||
.pagination-container-fluid {
|
||||
right: min(280px, 80vw) !important;
|
||||
transition: right 0.3s ease-in-out !important;
|
||||
}
|
||||
|
||||
/* Sidebar hidden: pagination expands to full viewport width */
|
||||
body.sidebar-right-hidden .pagination-container-fluid {
|
||||
right: 0 !important;
|
||||
}
|
||||
|
||||
#sidebar-right-toggle {
|
||||
top: 80% !important;
|
||||
transform: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 600–999px: sidebar is attached to the grid, same as desktop but with mobile width.
|
||||
Grid reserves space for the sidebar so content is never hidden behind it. */
|
||||
@media (min-width: 600px) and (max-width: 999px) {
|
||||
.index-layout-wrapper {
|
||||
padding-right: min(280px, 80vw);
|
||||
}
|
||||
|
||||
body.sidebar-right-hidden .index-layout-wrapper {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Generic pagewrapper (non-index, non-item pages) also reserves space */
|
||||
.pagewrapper:not(:has(.index-layout-wrapper)):not(:has(.item-layout-container)) {
|
||||
padding-right: min(280px, 80vw);
|
||||
}
|
||||
|
||||
body.sidebar-right-hidden
|
||||
.pagewrapper:not(:has(.index-layout-wrapper)):not(:has(.item-layout-container)) {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Item page: extend the desktop grid layout to 600px so the fixed sidebar
|
||||
aligns naturally — col3 width = sidebar width, so content never overlaps. */
|
||||
body.layout-modern .item-layout-container {
|
||||
display: grid;
|
||||
grid-template-columns: min(260px, 26vw) minmax(0, 1fr) min(280px, 80vw);
|
||||
height: calc(100vh - var(--navbar-h, 50px));
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body.layout-modern.sidebar-right-hidden .item-layout-container {
|
||||
grid-template-columns: min(260px, 26vw) minmax(0, 1fr) 0px;
|
||||
}
|
||||
|
||||
body.layout-modern .item-layout-container .item-main-content {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
body.layout-modern .item-sidebar-left {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
/* Legacy layout: 2-column grid at this range */
|
||||
body.layout-legacy .item-layout-container {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) min(280px, 80vw);
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
body.layout-legacy.sidebar-right-hidden .item-layout-container {
|
||||
grid-template-columns: minmax(0, 1fr) 0px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Very small screens (≤599px): sidebar is always a pure overlay — never reserve space for it.
|
||||
Wrappers stay at full width regardless of sidebar state; no transitions needed here.
|
||||
Item view also switches to stacked layout here (not at 999px). */
|
||||
@media (max-width: 599px) {
|
||||
/* Item view: stack content above comments/sidebar-left */
|
||||
.item-layout-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -2130,39 +2222,34 @@ body.layout-modern .global-sidebar-right {
|
||||
|
||||
.item-layout-container .item-main-content {
|
||||
order: 1;
|
||||
/* Main content (video) on top */
|
||||
/* padding: 10px; */
|
||||
}
|
||||
|
||||
.item-sidebar-left {
|
||||
order: 2;
|
||||
/* Comments/Tags on bottom */
|
||||
/* padding: 10px; */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Mobile Overrides if necessary — most styles now universal */
|
||||
.item-sidebar-right,
|
||||
.index-sidebar-right,
|
||||
.global-sidebar-right {
|
||||
width: 280px !important;
|
||||
.index-layout-wrapper,
|
||||
.item-layout-container,
|
||||
.pagewrapper,
|
||||
body.sidebar-right-hidden .index-layout-wrapper,
|
||||
body.sidebar-right-hidden .item-layout-container,
|
||||
body.sidebar-right-hidden .pagewrapper {
|
||||
padding-right: 5px !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
body.sidebar-right-hidden .item-sidebar-right,
|
||||
body.sidebar-right-hidden .index-sidebar-right,
|
||||
body.sidebar-right-hidden .global-sidebar-right {
|
||||
right: -280px !important;
|
||||
}
|
||||
|
||||
/* Mobile: sidebar is an overlay, so pagination always spans full viewport */
|
||||
.pagination-container-fluid,
|
||||
body.sidebar-right-hidden .pagination-container-fluid {
|
||||
right: 0 !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
#sidebar-right-toggle {
|
||||
top: 80% !important;
|
||||
transform: none !important;
|
||||
/* All sidebars hide/show instantly at this breakpoint — no slide animation */
|
||||
.item-sidebar-right,
|
||||
.index-sidebar-right,
|
||||
.global-sidebar-right {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2958,7 +3045,8 @@ body.layout-legacy .scroll-nav-wrapper {
|
||||
right: -45px;
|
||||
width: 40px;
|
||||
pointer-events: none;
|
||||
z-index: 1000;
|
||||
z-index: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.layout-legacy .scroll-to-bottom {
|
||||
@@ -4720,11 +4808,12 @@ body.layout-modern .pagination-container-fluid {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
@media (min-width: 1000px) {
|
||||
|
||||
/* Reserve space for the fixed sidebar so content doesn't flow behind it */
|
||||
.index-layout-wrapper {
|
||||
padding-right: 300px;
|
||||
transition: padding-right 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
/* Modern layout: wider sidebar */
|
||||
@@ -7703,6 +7792,7 @@ div.posts>a.thumb > p {
|
||||
bottom: 5px;
|
||||
left: 5px;
|
||||
gap: 2px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Make individual item entry subtler and faster for infinite scroll */
|
||||
@@ -9748,6 +9838,20 @@ html[theme="f0ck95d"] .badge-dark {
|
||||
}
|
||||
}
|
||||
|
||||
/* At 600–999px: center the button in the free space left of the sidebar.
|
||||
Shift left by half the sidebar width so transform:translateX(-50%) lands
|
||||
at the center of the available area rather than the full viewport. */
|
||||
@media (min-width: 600px) and (max-width: 999px) {
|
||||
.mobile-scroll-to-top {
|
||||
left: calc(50% - min(140px, 40vw));
|
||||
transition: left 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
body.sidebar-right-hidden .mobile-scroll-to-top {
|
||||
left: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.steuerung.steuerung-icon .fa-solid {
|
||||
font-size: 0.85em;
|
||||
}
|
||||
@@ -9924,9 +10028,10 @@ html[theme="f0ck95"] .embed-responsive.embed-responsive-16by9 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
@media (min-width: 1000px) {
|
||||
.pagewrapper {
|
||||
padding-right: 300px;
|
||||
transition: padding-right 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
body.layout-modern .pagewrapper {
|
||||
@@ -9942,7 +10047,7 @@ html[theme="f0ck95"] .embed-responsive.embed-responsive-16by9 {
|
||||
Since Index and Item pages have their own layout wrappers that handle space reservation,
|
||||
we disable the generic pagewrapper padding on those pages to avoid "double padding" or broken expansion.
|
||||
*/
|
||||
@media (min-width: 1200px) {
|
||||
@media (min-width: 1000px) {
|
||||
|
||||
.pagewrapper:has(.index-layout-wrapper),
|
||||
.pagewrapper:has(.item-layout-container),
|
||||
@@ -11071,8 +11176,7 @@ div.posts>a::after {
|
||||
|
||||
|
||||
.pin-indicator {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
position: relative;
|
||||
left: 5px;
|
||||
font-size: 13px;
|
||||
fill: var(--accent);
|
||||
|
||||
@@ -2307,9 +2307,49 @@ window.cancelAnimFrame = (function () {
|
||||
hidden = hiddenValue === 'true';
|
||||
}
|
||||
document.body.classList.toggle('sidebar-right-hidden', hidden);
|
||||
|
||||
// Always force-hide on very small screens regardless of saved preference
|
||||
if (window.innerWidth <= 599) {
|
||||
document.body.classList.add('sidebar-right-hidden');
|
||||
}
|
||||
};
|
||||
window.initSidebarRightToggle();
|
||||
|
||||
// Auto-hide sidebar on very small screens (≤599px), restore on wider
|
||||
(() => {
|
||||
const mq = window.matchMedia('(max-width: 599px)');
|
||||
const applyBreakpoint = (e) => {
|
||||
// Freeze transitions so the class change is instant (no sliding during resize)
|
||||
const sidebar = document.querySelector('.global-sidebar-right, .item-sidebar-right, .index-sidebar-right');
|
||||
const wrappers = document.querySelectorAll('.index-layout-wrapper, .item-layout-container, .pagination-container-fluid, .pagewrapper');
|
||||
if (sidebar) sidebar.style.setProperty('transition', 'none', 'important');
|
||||
wrappers.forEach(w => w.style.setProperty('transition', 'none', 'important'));
|
||||
|
||||
if (e.matches) {
|
||||
// Entering narrow: force-hide without touching localStorage
|
||||
document.body.classList.add('sidebar-right-hidden');
|
||||
} else {
|
||||
// Leaving narrow: restore from saved preference
|
||||
const saved = localStorage.getItem('sidebarRightHidden');
|
||||
const hidden = saved === 'true';
|
||||
document.body.classList.toggle('sidebar-right-hidden', hidden);
|
||||
}
|
||||
|
||||
// Force reflow then restore transitions
|
||||
if (sidebar) void sidebar.offsetWidth;
|
||||
requestAnimationFrame(() => {
|
||||
if (sidebar) sidebar.style.removeProperty('transition');
|
||||
wrappers.forEach(w => {
|
||||
w.style.removeProperty('transition');
|
||||
w.style.removeProperty('padding-right');
|
||||
w.style.removeProperty('right');
|
||||
});
|
||||
});
|
||||
};
|
||||
mq.addEventListener('change', applyBreakpoint);
|
||||
applyBreakpoint(mq); // run once on init
|
||||
})();
|
||||
|
||||
const loadPageAjax = async (url, replace = true, options = {}) => {
|
||||
if (isNavigating) return;
|
||||
|
||||
@@ -6281,8 +6321,10 @@ window.cancelAnimFrame = (function () {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
|
||||
// Freeze all transitions (override CSS !important) so the class toggle
|
||||
// doesn't trigger an additional right-property animation.
|
||||
// Freeze sidebar AND wrapper transitions so the class toggle
|
||||
// doesn't trigger a second padding-right animation.
|
||||
const wrappers = getSidebarWrappers();
|
||||
wrappers.forEach(w => w.style.setProperty('transition', 'none', 'important'));
|
||||
sidebar.style.setProperty('transition', 'none', 'important');
|
||||
|
||||
if (stateChanging) {
|
||||
@@ -6300,6 +6342,11 @@ window.cancelAnimFrame = (function () {
|
||||
// Restore CSS-controlled transitions on the next frame
|
||||
requestAnimationFrame(() => {
|
||||
sidebar.style.removeProperty('transition');
|
||||
wrappers.forEach(w => {
|
||||
w.style.removeProperty('transition');
|
||||
w.style.removeProperty('padding-right');
|
||||
w.style.removeProperty('right');
|
||||
});
|
||||
swipeRT.isDraggingSidebar = false;
|
||||
});
|
||||
};
|
||||
@@ -6537,6 +6584,10 @@ window.cancelAnimFrame = (function () {
|
||||
const settle = () => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
// Freeze sidebar AND wrapper transitions so the class toggle
|
||||
// doesn't trigger a second padding-right animation.
|
||||
const wrappers = getSidebarWrappers();
|
||||
wrappers.forEach(w => w.style.setProperty('transition', 'none', 'important'));
|
||||
sidebar.style.setProperty('transition', 'none', 'important');
|
||||
|
||||
if (stateChanging) {
|
||||
@@ -6549,6 +6600,11 @@ window.cancelAnimFrame = (function () {
|
||||
sidebar.style.transform = '';
|
||||
requestAnimationFrame(() => {
|
||||
sidebar.style.removeProperty('transition');
|
||||
wrappers.forEach(w => {
|
||||
w.style.removeProperty('transition');
|
||||
w.style.removeProperty('padding-right');
|
||||
w.style.removeProperty('right');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6616,15 +6672,53 @@ window.cancelAnimFrame = (function () {
|
||||
});
|
||||
window.addEventListener('resize', syncEdgeZone, { passive: true });
|
||||
|
||||
// Touchend on edgeZone: instant tap-to-toggle (no 300ms synthetic click delay)
|
||||
// Returns true if (clientX, clientY) is within the pill's hit area.
|
||||
// The pill is #sidebar-drag-zone::after — 4×40px, centered on pointer:fine,
|
||||
// right-aligned with padding-right:6px on pointer:coarse.
|
||||
const isWithinPillArea = (clientX, clientY) => {
|
||||
const rect = edgeZone.getBoundingClientRect();
|
||||
const pillH = 40;
|
||||
const hitPad = 12; // generous padding so it's easy to hit
|
||||
// Vertical: pill is always centered in the drag zone
|
||||
const pillCenterY = rect.top + rect.height / 2;
|
||||
if (clientY < pillCenterY - pillH / 2 - hitPad || clientY > pillCenterY + pillH / 2 + hitPad) return false;
|
||||
// Horizontal: right-aligned on touch, centered on mouse
|
||||
const isCoarse = window.matchMedia('(pointer: coarse)').matches;
|
||||
const pillCenterX = isCoarse ? rect.right - 6 - 2 : rect.left + rect.width / 2;
|
||||
return clientX >= pillCenterX - 2 - hitPad && clientX <= pillCenterX + 2 + hitPad;
|
||||
};
|
||||
|
||||
// Touchend: tap on the pill toggles sidebar; rest of drag zone only responds to swipe
|
||||
edgeZone.addEventListener('touchend', e => {
|
||||
// Only if it was a clean tap (no significant swipe movement)
|
||||
if (Math.abs(swipeRT.xDiff || 0) < 15 && Math.abs(swipeRT.yDiff || 0) < 15) {
|
||||
e.preventDefault();
|
||||
edgeZone.dispatchEvent(new Event('click'));
|
||||
e.preventDefault(); // always prevent 300ms synthetic click
|
||||
const touch = e.changedTouches[0];
|
||||
if (touch && isWithinPillArea(touch.clientX, touch.clientY)) {
|
||||
window.toggleSidebarRight();
|
||||
}
|
||||
}
|
||||
}, { passive: false });
|
||||
|
||||
// Helper: all layout wrappers that have padding-right animated by sidebar state
|
||||
const getSidebarWrappers = () => {
|
||||
// At ≤999px: sidebar is a pure overlay — only pagination tracks it.
|
||||
if (window.innerWidth <= 599) {
|
||||
return document.querySelectorAll('.pagination-container-fluid');
|
||||
}
|
||||
// At ≥600px: exclude pagewrapper when a dedicated layout wrapper is present.
|
||||
// CSS already zeroes pagewrapper.padding-right via :has on those pages,
|
||||
// so including it here causes double-padding (pagewrapper + index-layout-wrapper both
|
||||
// get 300px snapped, making the grid 600px too narrow, then jumping back on settle).
|
||||
const hasDedicatedWrapper = !!(
|
||||
document.querySelector('.index-layout-wrapper') ||
|
||||
document.querySelector('.item-layout-container')
|
||||
);
|
||||
const sel = hasDedicatedWrapper
|
||||
? '.index-layout-wrapper, .pagination-container-fluid'
|
||||
: '.pagination-container-fluid, .pagewrapper';
|
||||
return document.querySelectorAll(sel);
|
||||
};
|
||||
|
||||
// Smoothly toggle sidebar open/closed
|
||||
window.toggleSidebarRight = () => {
|
||||
const sidebar = document.querySelector('.global-sidebar-right, .item-sidebar-right, .index-sidebar-right');
|
||||
@@ -6634,6 +6728,23 @@ window.cancelAnimFrame = (function () {
|
||||
const sidebarWidth = sidebar.offsetWidth || 300;
|
||||
const targetTranslate = isHidden ? -sidebarWidth : sidebarWidth;
|
||||
|
||||
// At ≤599px the sidebar is a pure overlay — never animate wrapper padding
|
||||
const animateWrappers = window.innerWidth > 599;
|
||||
|
||||
// Grid/pagewrapper: snap instantly in both directions (no animated reflow).
|
||||
// Pagination always animates — it tracks sidebar position with no reflow cost.
|
||||
const wrappers = getSidebarWrappers();
|
||||
if (animateWrappers) {
|
||||
wrappers.forEach(w => {
|
||||
const isPagination = w.classList.contains('pagination-container-fluid');
|
||||
const prop = isPagination ? 'right' : 'padding-right';
|
||||
const targetVal = isHidden ? sidebarWidth + 'px' : '0px';
|
||||
w.style.setProperty('transition', isPagination ? `${prop} 0.3s ease-in-out` : 'none', 'important');
|
||||
w.style.setProperty(prop, targetVal, 'important');
|
||||
});
|
||||
void sidebar.offsetWidth; // settle layout before sidebar transform begins
|
||||
}
|
||||
|
||||
sidebar.style.setProperty('transition', 'transform 0.3s ease-in-out', 'important');
|
||||
sidebar.style.transform = `translateX(${targetTranslate}px)`;
|
||||
|
||||
@@ -6641,13 +6752,22 @@ window.cancelAnimFrame = (function () {
|
||||
const settle = () => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
// Freeze wrapper transitions so the class commit doesn't re-trigger them
|
||||
wrappers.forEach(w => w.style.setProperty('transition', 'none', 'important'));
|
||||
sidebar.style.setProperty('transition', 'none', 'important');
|
||||
const toHidden = !isHidden;
|
||||
document.body.classList.toggle('sidebar-right-hidden', toHidden);
|
||||
localStorage.setItem('sidebarRightHidden', toHidden);
|
||||
void sidebar.offsetWidth;
|
||||
sidebar.style.transform = '';
|
||||
requestAnimationFrame(() => sidebar.style.removeProperty('transition'));
|
||||
requestAnimationFrame(() => {
|
||||
sidebar.style.removeProperty('transition');
|
||||
wrappers.forEach(w => {
|
||||
w.style.removeProperty('transition');
|
||||
w.style.removeProperty('padding-right');
|
||||
w.style.removeProperty('right');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onEnd = ev => {
|
||||
@@ -6659,9 +6779,11 @@ window.cancelAnimFrame = (function () {
|
||||
setTimeout(settle, 350);
|
||||
};
|
||||
|
||||
// Click on edgeZone: smoothly toggle sidebar open/closed
|
||||
edgeZone.addEventListener('click', () => {
|
||||
window.toggleSidebarRight();
|
||||
// Click on edgeZone: only toggle when the click lands on the pill
|
||||
edgeZone.addEventListener('click', (e) => {
|
||||
if (isWithinPillArea(e.clientX, e.clientY)) {
|
||||
window.toggleSidebarRight();
|
||||
}
|
||||
});
|
||||
// </mouse-sidebar-drag>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user