mirror of
https://github.com/saicaca/fuwari.git
synced 2025-03-13 23:24:42 +08:00
313 lines
9.0 KiB
Plaintext
313 lines
9.0 KiB
Plaintext
---
|
|
import GlobalStyles from "@components/GlobalStyles.astro";
|
|
import '@fontsource/roboto/400.css';
|
|
import '@fontsource/roboto/500.css';
|
|
import '@fontsource/roboto/700.css';
|
|
import ImageWrapper from "@components/misc/ImageWrapper.astro";
|
|
|
|
import {pathsEqual} from "@utils/url-utils";
|
|
import ConfigCarrier from "@components/ConfigCarrier.astro";
|
|
import {profileConfig, siteConfig} from "@/config";
|
|
|
|
interface Props {
|
|
title: string;
|
|
banner: string;
|
|
}
|
|
|
|
let { title, banner } = Astro.props;
|
|
|
|
const isHomePage = pathsEqual(Astro.url.pathname, '/');
|
|
|
|
const testPathName = Astro.url.pathname;
|
|
|
|
const anim = {
|
|
old: {
|
|
name: 'fadeIn',
|
|
duration: '4s',
|
|
easing: 'linear',
|
|
fillMode: 'forwards',
|
|
mixBlendMode: 'normal',
|
|
},
|
|
new: {
|
|
name: 'fadeOut',
|
|
duration: '4s',
|
|
easing: 'linear',
|
|
fillMode: 'backwards',
|
|
mixBlendMode: 'normal',
|
|
}
|
|
};
|
|
|
|
const myFade = {
|
|
forwards: anim,
|
|
backwards: anim,
|
|
};
|
|
|
|
// defines global css variables
|
|
// why doing this in Layout instead of GlobalStyles: https://github.com/withastro/astro/issues/6728#issuecomment-1502203757
|
|
const configHue = siteConfig.themeHue;
|
|
if (!banner || typeof banner !== 'string' || banner.trim() === '') {
|
|
banner = siteConfig.banner.src;
|
|
}
|
|
|
|
// TODO don't use post cover as banner for now
|
|
banner = siteConfig.banner.src;
|
|
|
|
const enableBanner = siteConfig.banner.enable;
|
|
|
|
let pageTitle;
|
|
if (title) {
|
|
pageTitle = `${title} - ${siteConfig.title}`;
|
|
} else {
|
|
pageTitle = `${siteConfig.title} - ${siteConfig.subtitle}`;
|
|
}
|
|
|
|
---
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="en" isHome={isHomePage} pathname={testPathName} class="bg-[var(--page-bg)] transition text-[14px] md:text-[16px]">
|
|
<head>
|
|
|
|
<title>{pageTitle}</title>
|
|
|
|
<meta charset="UTF-8" />
|
|
<meta name="description" content="Astro description">
|
|
<meta name="viewport" content="width=device-width" />
|
|
<meta name="generator" content={Astro.generator} />
|
|
<link rel="icon" media="(prefers-color-scheme: light)" href="/favicon/favicon-light-32.png" sizes="32x32">
|
|
<link rel="icon" media="(prefers-color-scheme: light)" href="/favicon/favicon-light-128.png" sizes="128x128">
|
|
<link rel="icon" media="(prefers-color-scheme: light)" href="/favicon/favicon-light-180.png" sizes="180x180">
|
|
<link rel="icon" media="(prefers-color-scheme: light)" href="/favicon/favicon-light-192.png" sizes="192x192">
|
|
<link rel="icon" media="(prefers-color-scheme: dark)" href="/favicon/favicon-dark-32.png" sizes="32x32">
|
|
<link rel="icon" media="(prefers-color-scheme: dark)" href="/favicon/favicon-dark-128.png" sizes="128x128">
|
|
<link rel="icon" media="(prefers-color-scheme: dark)" href="/favicon/favicon-dark-180.png" sizes="180x180">
|
|
<link rel="icon" media="(prefers-color-scheme: dark)" href="/favicon/favicon-dark-192.png" sizes="192x192">
|
|
|
|
<link rel="stylesheet" href="https://cdn.staticfile.org/KaTeX/0.16.9/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
|
|
|
|
<link rel="alternate" type="application/rss+xml" title={profileConfig.name} href={`${Astro.site}rss.xml`}/>
|
|
|
|
<style define:vars={{ configHue }}></style> <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->
|
|
|
|
</head>
|
|
<body class=" min-h-screen transition " class:list={[{"is-home": isHomePage, "enable-banner": enableBanner}]}>
|
|
<ConfigCarrier></ConfigCarrier>
|
|
<GlobalStyles>
|
|
<div id="banner-wrapper" class="absolute w-full">
|
|
<ImageWrapper id="boxtest" alt="Banner image of the blog" class:list={["object-center object-cover h-full", {"hidden": !siteConfig.banner.enable}]}
|
|
src={siteConfig.banner.src}
|
|
>
|
|
</ImageWrapper>
|
|
</div>
|
|
<slot />
|
|
</GlobalStyles>
|
|
</body>
|
|
</html>
|
|
<style is:global>
|
|
:root {
|
|
--hue: var(--configHue);
|
|
--page-width: 75rem;
|
|
}
|
|
</style>
|
|
<style is:global>
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
@layer components {
|
|
/* TODO: temporarily make banner height same for all pages since I cannot make the transition feel good
|
|
I want to make the height transition parallel with the content transition instead of blocking it
|
|
*/
|
|
|
|
/*
|
|
.enable-banner.is-home #banner-wrapper {
|
|
@apply h-[var(--banner-height)] md:h-[var(--banner-height-home)]
|
|
}
|
|
*/
|
|
.enable-banner #banner-wrapper {
|
|
@apply h-[var(--banner-height)]
|
|
}
|
|
|
|
/*
|
|
.enable-banner.is-home #top-row {
|
|
@apply h-[calc(var(--banner-height)_-_4.5rem)] md:h-[calc(var(--banner-height-home)_-_4.5rem)]
|
|
}
|
|
*/
|
|
.enable-banner #top-row {
|
|
@apply h-[calc(var(--banner-height)_-_4.5rem)]
|
|
}
|
|
}
|
|
</style>
|
|
<script>
|
|
import 'overlayscrollbars/overlayscrollbars.css';
|
|
import {
|
|
OverlayScrollbars,
|
|
ScrollbarsHidingPlugin,
|
|
SizeObserverPlugin,
|
|
ClickScrollPlugin
|
|
} from 'overlayscrollbars';
|
|
import {getHue, setHue} from "../utils/setting-utils";
|
|
|
|
/* Preload fonts */
|
|
// (async function() {
|
|
// try {
|
|
// await Promise.all([
|
|
// document.fonts.load("400 1em Roboto"),
|
|
// document.fonts.load("700 1em Roboto"),
|
|
// ]);
|
|
// document.body.classList.remove("hidden");
|
|
// } catch (error) {
|
|
// console.log("Failed to load fonts:", error);
|
|
// }
|
|
// })();
|
|
|
|
/* TODO This is a temporary solution for style flicker issue when the transition is activated */
|
|
/* issue link: https://github.com/withastro/astro/issues/8711, the solution get from here too */
|
|
/* update: fixed in Astro 3.2.4 */
|
|
function disableAnimation() {
|
|
const css = document.createElement('style')
|
|
css.appendChild(
|
|
document.createTextNode(
|
|
`*{
|
|
-webkit-transition:none!important;
|
|
-moz-transition:none!important;
|
|
-o-transition:none!important;
|
|
-ms-transition:none!important;
|
|
transition:none!important
|
|
}`
|
|
)
|
|
)
|
|
document.head.appendChild(css)
|
|
|
|
return () => {
|
|
// Force restyle
|
|
;(() => window.getComputedStyle(document.body))()
|
|
|
|
// Wait for next tick before removing
|
|
setTimeout(() => {
|
|
document.head.removeChild(css)
|
|
}, 1)
|
|
}
|
|
}
|
|
|
|
function setClickOutsideToClose(panel: string, ignores: string[]) {
|
|
document.addEventListener("click", event => {
|
|
let panelDom = document.getElementById(panel);
|
|
let tDom = event.target;
|
|
for (let ig of ignores) {
|
|
let ie = document.getElementById(ig)
|
|
if (ie == tDom || (ie?.contains(tDom))) {
|
|
return;
|
|
}
|
|
}
|
|
panelDom.classList.add("closed");
|
|
});
|
|
}
|
|
setClickOutsideToClose("display-setting", ["display-setting", "display-settings-switch"])
|
|
setClickOutsideToClose("nav-menu-panel", ["nav-menu-panel", "nav-menu-switch"])
|
|
setClickOutsideToClose("search-panel", ["search-panel", "search-bar", "search-switch"])
|
|
|
|
|
|
function loadTheme() {
|
|
if (localStorage.theme === 'dark' || (!('theme' in localStorage) &&
|
|
window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
document.documentElement.classList.add('dark');
|
|
localStorage.theme = 'dark';
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
localStorage.theme = 'light';
|
|
}
|
|
}
|
|
|
|
function loadHue() {
|
|
setHue(getHue())
|
|
}
|
|
|
|
function setBannerHeight() {
|
|
const banner = document.getElementById('banner-wrapper');
|
|
if (document.documentElement.hasAttribute('isHome')) {
|
|
banner.classList.remove('banner-else');
|
|
banner.classList.add('banner-home');
|
|
} else {
|
|
banner.classList.remove('banner-home');
|
|
banner.classList.add('banner-else');
|
|
}
|
|
}
|
|
|
|
function initCustomScrollbar() {
|
|
OverlayScrollbars(
|
|
// docs say that a initialization to the body element would affect native functionality like window.scrollTo
|
|
// but just leave it here for now
|
|
{
|
|
target: document.querySelector('body'),
|
|
cancel: {
|
|
nativeScrollbarsOverlaid: true, // don't initialize the overlay scrollbar if there is a native one
|
|
}
|
|
}, {
|
|
scrollbars: {
|
|
theme: 'scrollbar-base scrollbar-auto py-1',
|
|
autoHide: 'move',
|
|
autoHideDelay: 500,
|
|
autoHideSuspend: false,
|
|
},
|
|
});
|
|
document.querySelectorAll('pre').forEach((ele) => {
|
|
OverlayScrollbars(ele, {
|
|
scrollbars: {
|
|
theme: 'scrollbar-base scrollbar-dark px-2',
|
|
autoHide: 'leave',
|
|
autoHideDelay: 500,
|
|
autoHideSuspend: false
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function init() {
|
|
// disableAnimation()() // TODO
|
|
setBannerHeight();
|
|
loadTheme();
|
|
loadHue();
|
|
initCustomScrollbar();
|
|
}
|
|
|
|
/* Load settings when entering the site */
|
|
init();
|
|
|
|
/* Load settings before swapping */
|
|
/* astro:after-swap event happened before swap animation */
|
|
document.addEventListener('astro:after-swap', init);
|
|
|
|
const setup = () => {
|
|
// TODO: temp solution to change the height of the banner
|
|
/*
|
|
window.swup.hooks.on('animation:out:start', () => {
|
|
const path = window.location.pathname
|
|
const body = document.querySelector('body')
|
|
if (path[path.length - 1] === '/' && !body.classList.contains('is-home')) {
|
|
body.classList.add('is-home')
|
|
} else if (path[path.length - 1] !== '/' && body.classList.contains('is-home')) {
|
|
body.classList.remove('is-home')
|
|
}
|
|
})
|
|
*/
|
|
// Remove the delay for the first time page load
|
|
window.swup.hooks.on('link:click', () => {
|
|
document.documentElement.style.setProperty('--content-delay', '0ms')
|
|
})
|
|
}
|
|
if (window.swup.hooks) {
|
|
setup()
|
|
} else {
|
|
document.addEventListener('swup:enable', setup)
|
|
}
|
|
|
|
</script>
|
|
|
|
<style is:global lang="stylus">
|
|
#banner-wrapper
|
|
top: 0
|
|
opacity: 1
|
|
.banner-closed
|
|
#banner-wrapper
|
|
top: -120px
|
|
opacity: 0
|
|
</style> |