Skip to content

Commit f1b0bee

Browse files
committed
sync content
1 parent 94c1e45 commit f1b0bee

File tree

3 files changed

+98
-25
lines changed

3 files changed

+98
-25
lines changed

astro.config.mjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ export default defineConfig({
4040
// when the Tailwind class `transition-all` is used
4141
containers: ["main", "#toc"],
4242
smoothScrolling: true,
43-
cache: true,
43+
// Swup cache + client:only islands can get out of sync and break hydration.
44+
cache: false,
4445
preload: true,
4546
accessibility: true,
4647
updateHead: true,
@@ -102,7 +103,7 @@ export default defineConfig({
102103
}),
103104
svelte(),
104105
sitemap(),
105-
],
106+
].filter(Boolean),
106107
markdown: {
107108
remarkPlugins: [
108109
remarkMath,

src/layouts/Layout.astro

Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ function scheduleSwupRecovery() {
347347
}
348348

349349
function setClickOutsideToClose(panel: string, ignores: string[]) {
350+
const registry = (window as unknown as { __clickOutsideRegistry?: Set<string> }).__clickOutsideRegistry
351+
?? ((window as unknown as { __clickOutsideRegistry: Set<string> }).__clickOutsideRegistry = new Set<string>());
352+
if (registry.has(panel)) return;
353+
registry.add(panel);
354+
350355
document.addEventListener("click", event => {
351356
const panelDom = document.getElementById(panel);
352357
if (!panelDom) {
@@ -377,6 +382,8 @@ function loadHue() {
377382
}
378383

379384
let bodyScrollbarInitialized = false;
385+
let bodyScrollbarScheduled = false;
386+
const enableBodyScrollbar = false;
380387
let katexObserver: IntersectionObserver | undefined;
381388
const katexObserverOptions = {
382389
root: null,
@@ -419,28 +426,69 @@ function ensureKatexObserver() {
419426
}, katexObserverOptions);
420427
}
421428

422-
function initCustomScrollbar() {
429+
function initBodyScrollbar() {
430+
if (!enableBodyScrollbar) return;
423431
const bodyElement = document.body;
424-
if (!bodyElement) return;
425-
if (!bodyScrollbarInitialized) {
426-
OverlayScrollbars(
427-
// docs say that a initialization to the body element would affect native functionality like window.scrollTo
428-
// but just leave it here for now
429-
{
430-
target: bodyElement,
431-
cancel: {
432-
nativeScrollbarsOverlaid: true, // don't initialize the overlay scrollbar if there is a native one
433-
}
434-
}, {
432+
if (!bodyElement || bodyScrollbarInitialized) return;
433+
434+
OverlayScrollbars(
435+
{
436+
target: bodyElement,
437+
cancel: {
438+
// Avoid replacing native overlay scrollbars (macOS, etc.)
439+
nativeScrollbarsOverlaid: true,
440+
},
441+
},
442+
{
435443
scrollbars: {
436444
theme: 'scrollbar-base scrollbar-auto py-1',
437445
autoHide: 'move',
438446
autoHideDelay: 500,
439447
autoHideSuspend: false,
440448
},
441-
});
442-
bodyScrollbarInitialized = true;
449+
}
450+
);
451+
452+
bodyScrollbarInitialized = true;
453+
}
454+
455+
function scheduleBodyScrollbarInit() {
456+
if (bodyScrollbarInitialized || bodyScrollbarScheduled) return;
457+
bodyScrollbarScheduled = true;
458+
459+
const run = () => {
460+
bodyScrollbarScheduled = false;
461+
initBodyScrollbar();
462+
};
463+
464+
// Defer body-level DOM mutation until after the initial hydration window.
465+
if (document.readyState === 'complete') {
466+
requestAnimationFrame(run);
467+
return;
468+
}
469+
470+
window.addEventListener(
471+
'load',
472+
() => {
473+
run();
474+
},
475+
{ once: true }
476+
);
477+
478+
const requestIdle = (window as Window & {
479+
requestIdleCallback?: (cb: () => void, opts?: { timeout: number }) => void;
480+
}).requestIdleCallback;
481+
if (requestIdle) {
482+
requestIdle(run, { timeout: 1500 });
483+
return;
443484
}
485+
setTimeout(run, 0);
486+
}
487+
488+
function initCustomScrollbar() {
489+
const bodyElement = document.body;
490+
if (!bodyElement) return;
491+
scheduleBodyScrollbarInit();
444492

445493
ensureKatexObserver();
446494
const katexElements = document.querySelectorAll('.katex-display') as NodeListOf<HTMLElement>;
@@ -472,9 +520,31 @@ function init() {
472520
}
473521

474522
/* Load settings when entering the site */
475-
init();
523+
if (document.readyState === 'loading') {
524+
document.addEventListener('DOMContentLoaded', init, { once: true });
525+
} else {
526+
init();
527+
}
528+
529+
function syncNavbarForRoute(isHome: boolean) {
530+
const navbar = document.getElementById('navbar');
531+
if (!navbar) return;
532+
navbar.setAttribute('data-is-home', String(isHome));
533+
if (navbar.getAttribute('data-transparent-mode') === 'semifull') {
534+
// Non-home pages should always render the blurred state immediately.
535+
navbar.classList.toggle('scrolled', !isHome || window.scrollY > 8);
536+
}
537+
}
476538

477539
const setup = () => {
540+
// In dev, swup's cached HTML can get out of sync with hot-updated JS and break islands.
541+
if (import.meta.env.DEV) {
542+
try {
543+
window.swup?.cache?.empty?.();
544+
} catch (error) {
545+
console.warn('Failed to clear swup cache in dev:', error);
546+
}
547+
}
478548
// TODO: temp solution to change the height of the banner
479549
/*
480550
window.swup.hooks.on('animation:out:start', () => {
@@ -511,19 +581,20 @@ const setup = () => {
511581
updateScrollThresholds();
512582
requestScrollUpdate();
513583
});
514-
window.swup.hooks.on('visit:error', (visit: {to: {url: string}}) => {
515-
clearAnimationFlags();
516-
window.location.href = visit.to.url;
517-
});
518584
window.swup.hooks.on('visit:start', (visit: {to: {url: string}}) => {
585+
if (import.meta.env.DEV) {
586+
window.swup?.cache?.empty?.();
587+
}
519588
scheduleSwupRecovery();
520589
// change banner height immediately when a link is clicked
521590
const bodyElement = document.querySelector('body')
522-
if (pathsEqual(visit.to.url, url('/'))) {
591+
const isHomeTarget = pathsEqual(visit.to.url, url('/'));
592+
if (isHomeTarget) {
523593
bodyElement!.classList.add('lg:is-home');
524594
} else {
525595
bodyElement!.classList.remove('lg:is-home');
526596
}
597+
syncNavbarForRoute(isHomeTarget);
527598
updateScrollThresholds();
528599
requestScrollUpdate();
529600

@@ -545,6 +616,7 @@ const setup = () => {
545616
if (heightExtend) {
546617
heightExtend.classList.remove('hidden')
547618
}
619+
syncNavbarForRoute(document.body.classList.contains('lg:is-home'));
548620
refreshScrollTargets();
549621
updateScrollThresholds();
550622
requestScrollUpdate();

src/layouts/MainGridLayout.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const mainPanelTop = isBannerMode
9595
<!-- Navbar -->
9696
<slot slot="head" name="head"></slot>
9797
{isFullscreenMode && <FullscreenWallpaper config={siteConfig.wallpaper}></FullscreenWallpaper>}
98-
<div id="top-row" class="z-50 pointer-events-none relative transition-all duration-700 max-w-[var(--page-width)] px-0 md:pl-6 md:pr-2 mx-auto lg:ml-auto lg:mr-6" class:list={[""]}>
98+
<div id="top-row" class="z-50 pointer-events-none relative transition-all duration-700 max-w-[var(--page-width)] px-0 md:pl-6 md:pr-2 2xl:pl-12 2xl:pr-0 mx-auto" class:list={[""]}>
9999
<div id="navbar-wrapper" class="pointer-events-auto sticky top-0 transition-all">
100100
<Navbar></Navbar>
101101
</div>
@@ -117,9 +117,9 @@ const mainPanelTop = isBannerMode
117117
class:list={[{"mobile-main-no-banner": !isHomePage && isBannerMode, "no-banner-layout": !isBannerMode}]}
118118
style={`top: ${mainPanelTop}`}>
119119
<!-- The pointer-events-none here prevent blocking the click event of the TOC -->
120-
<div class="relative max-w-[var(--page-width)] mx-auto lg:ml-auto lg:mr-6 pointer-events-auto">
120+
<div class="relative max-w-[var(--page-width)] mx-auto 2xl:pl-12 2xl:pr-0 pointer-events-auto">
121121
<div id="main-grid" class="transition duration-700 w-full left-0 right-0 grid grid-cols-1 lg:grid-cols-[16rem_minmax(0,max(0px,calc(var(--page-width)_-_16rem_-_0.75rem)))] 2xl:grid-cols-[16rem_minmax(0,max(0px,calc(var(--page-width)_-_16rem_-_12.5rem_-_1.5rem)))_12.5rem] grid-rows-[auto_1fr_auto] lg:grid-rows-[auto]
122-
mx-auto gap-2 lg:gap-3 px-0 md:pl-6 md:pr-2"
122+
mx-auto gap-2 lg:gap-3 px-0 md:pl-6 md:pr-2 2xl:pl-12 2xl:pr-0"
123123
>
124124
<!-- Banner image credit -->
125125
{hasBannerCredit && <a href={siteConfig.wallpaper.banner?.credit?.url || "#"} id="banner-credit" target={hasBannerLink ? "_blank" : undefined} rel={hasBannerLink ? "noopener" : undefined} aria-label="Visit image source"

0 commit comments

Comments
 (0)