mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-15 19:22:52 +02:00
140 lines
6 KiB
Text
140 lines
6 KiB
Text
---
|
||
// import BackToTop from '@/components/BackToTop.astro'
|
||
import Footer from '@/components/Footer.astro'
|
||
import MainHeader from '@/components/MainHeader.astro'
|
||
import MobileHeader from '@/components/MobileHeader.astro'
|
||
import Navigation from '@/components/Navbar.astro'
|
||
import LanguageSwitcher from '@/components/Widgets/LanguageSwitcher.astro'
|
||
// import PhotoSwipe from '@/components/PhotoSwipe.astro'
|
||
// import Scrollbar from '@/components/Scrollbar.astro'
|
||
import ThemeToggle from '@/components/Widgets/ThemeToggle.astro'
|
||
import themeConfig from '@/config'
|
||
import Head from '@/layouts/Head.astro'
|
||
import { getPageInfo } from '@/utils/page'
|
||
|
||
import '@/styles/font.css'
|
||
import '@/styles/global.css'
|
||
import '@/styles/heti.css'
|
||
|
||
interface Props {
|
||
postTitle?: string
|
||
postDescription?: string
|
||
postSlug?: string
|
||
supportedLangs?: string[]
|
||
}
|
||
|
||
const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.props
|
||
const { isHome, isPost } = getPageInfo(Astro.url.pathname)
|
||
const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
||
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
||
const footerMarginClass = isPost && themeConfig.comment?.waline?.serverURL
|
||
? 'mt-8'
|
||
: 'mt-12'
|
||
---
|
||
|
||
<html
|
||
lang={Astro.currentLocale || 'en-US'}
|
||
class={fontStyle}
|
||
data-overlayscrollbars-initialize
|
||
>
|
||
<Head {postTitle} {postDescription} {postSlug} />
|
||
<body data-overlayscrollbars-initialize>
|
||
<!-- mobile -->
|
||
<!-- mobile width: 393px / suitable words number: 21 / content width: 21*16px=336px / padding: (393px-336px)/2=28.5px=(28.5px/393px)=7.25vw -->
|
||
<!-- max mobile width: 1024px / max word number: 42+2=44 / max content width: 44*16px=704px / max div width: 704px/(100vw-7.25vw*2)=823.3918px/4=205.848 / max padding: 823.3918px-704px=119.3918px/2=59.6959px/16=3.731rem -->
|
||
<!-- desktop -->
|
||
<!-- desktop min div width: 1024px-90px*2=844px / min words number: 32 / min content width: 32*16px=512px/16=32rem / title width: 14*16px=224px/16=14rem / min-gap: 844px-512px-224px=108px -->
|
||
<!-- desktop max div width: 1100px+90px*2=1280px/4=320 / max words number: 42+2=44 / max content width: 44*16px=704px / title width: 14*16px=224px / max-gap: 1100px-704px-224px=172px/16=10.75rem -->
|
||
<!-- content width: calc(32rem+(100vw-1024px)*(44rem-32rem)/(1280-1024))=calc(75vw-16rem) / gap width: calc(6.75rem+(100vw-1024px)*(10.75rem-6.75rem)/(1280-1024))=calc(25vw-9.25rem) -->
|
||
<div
|
||
class="mx-auto max-w-205.848 min-h-vh w-full min-h-dvh"
|
||
p="x-[min(7.25vw,3.731rem)] y-8 lg:(x-22.5 y-20)"
|
||
lg="max-w-320 grid cols-[min(calc(75vw-16rem),44rem)_14rem] gap-[min(calc(25vw-9.25rem),10.75rem)]"
|
||
>
|
||
<!-- hide header and navigation on mobile for post pages -->
|
||
<div class={!isHome && isPost ? 'hidden lg:block' : ''}>
|
||
<MainHeader />
|
||
<Navigation />
|
||
<!-- only show footer on desktop-->
|
||
<Footer class="fixed hidden lg:block" supportedLangs={supportedLangs} />
|
||
</div>
|
||
|
||
<!-- show simple header on mobile for post pages -->
|
||
{!isHome && isPost && <MobileHeader />}
|
||
|
||
<!-- main content area -->
|
||
<main class="col-start-1 row-start-1">
|
||
<slot />
|
||
</main>
|
||
|
||
<!-- show footer on mobile -->
|
||
<Footer class={`block lg:hidden ${footerMarginClass}`} supportedLangs={supportedLangs} />
|
||
</div>
|
||
<!-- <Scrollbar /> -->
|
||
<!-- <BackToTop /> -->
|
||
<!-- <PhotoSwipe /> -->
|
||
|
||
<!-- only show on mobile (fix position issue on ios / fix right distance)-->
|
||
<div class="absolute right-7.25vw top-13.5 flex gap-6 [@supports(-webkit-touch-callout:none)]:top-12.5 min-[823px]:right-[calc(50vw-22rem)] lg:hidden">
|
||
<LanguageSwitcher supportedLangs={supportedLangs} />
|
||
<ThemeToggle />
|
||
</div>
|
||
|
||
<!-- Theme toggle >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||
<script define:vars={{ lightMode, darkMode }}>
|
||
// Update theme
|
||
function updateTheme() {
|
||
// Toggle website theme
|
||
document.documentElement.classList.toggle('dark')
|
||
|
||
// Get current theme
|
||
const isDark = document.documentElement.classList.contains('dark')
|
||
|
||
// Update meta theme color
|
||
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
|
||
if (metaThemeColor) {
|
||
metaThemeColor.setAttribute('content', isDark ? darkMode : lightMode)
|
||
}
|
||
|
||
// Update theme configuration in local storage
|
||
localStorage.setItem('theme', isDark ? 'dark' : 'light')
|
||
document.dispatchEvent(new Event('theme-changed'))
|
||
}
|
||
|
||
// Bind click event to the button
|
||
function setupThemeToggle() {
|
||
// Locate theme toggle button
|
||
const themeToggleButtons = document.querySelectorAll('.button-theme-toggle')
|
||
|
||
// Add click listener to each button
|
||
themeToggleButtons.forEach((button) => {
|
||
button.addEventListener('click', () => {
|
||
// If browser doesn't support View Transitions API, update theme directly
|
||
if (!document.startViewTransition) {
|
||
updateTheme()
|
||
return
|
||
}
|
||
|
||
// Temporarily add markers during animation to implement view transition and disable CSS transitions
|
||
document.documentElement.style.setProperty('view-transition-name', 'theme-transition')
|
||
document.documentElement.setAttribute('data-theme-transition', '')
|
||
|
||
// If browser supports View Transitions API, use it to update theme
|
||
const themeTransition = document.startViewTransition(updateTheme)
|
||
|
||
// Remove markers after animation
|
||
themeTransition.finished.then(() => {
|
||
document.documentElement.style.removeProperty('view-transition-name')
|
||
document.documentElement.removeAttribute('data-theme-transition')
|
||
})
|
||
})
|
||
})
|
||
}
|
||
|
||
// Initialize click event (on first load or page transition)
|
||
setupThemeToggle()
|
||
document.addEventListener('astro:after-swap', setupThemeToggle)
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|