mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 11:41:17 +02:00
fix: back button error and view transition on ios, move scripts from layout to components
This commit is contained in:
parent
783fb958d5
commit
d2ebe60778
4 changed files with 90 additions and 85 deletions
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import { moreLocales } from '@/config'
|
import { moreLocales, themeConfig } from '@/config'
|
||||||
import { getNextGlobalLangPath, getNextSupportedLangPath } from '@/i18n/path'
|
import { getNextGlobalLangPath, getNextSupportedLangPath } from '@/i18n/path'
|
||||||
import { isPostPage, isTagPage } from '@/utils/page'
|
import { isPostPage, isTagPage } from '@/utils/page'
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ interface Props {
|
||||||
supportedLangs: string[]
|
supportedLangs: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
||||||
|
|
||||||
const { supportedLangs } = Astro.props
|
const { supportedLangs } = Astro.props
|
||||||
const currentPath = Astro.url.pathname
|
const currentPath = Astro.url.pathname
|
||||||
const isPost = isPostPage(currentPath)
|
const isPost = isPostPage(currentPath)
|
||||||
|
@ -25,10 +27,10 @@ const nextUrl = useSupportedLangs
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class:list={[
|
class:list={[
|
||||||
'absolute flex gap-6 top-14.6 right-7.25vw min-[823px]:max-[1024px]:right-[calc(50vw-22rem)]',
|
'absolute flex gap-6 top-14.6 right-7.25vw min-[823px]:max-[1024px]:right-[calc(50vw-22rem)]',
|
||||||
'[@supports(-webkit-touch-callout:none)]:top-13.6', // fix position issue on ios
|
'[@supports(-webkit-touch-callout:none)]:top-13.6', // fix position issue on ios
|
||||||
'lg:(fixed w-14rem top-auto bottom-47 right-[max(5.625rem,calc(50vw-34.375rem))])'
|
'lg:(fixed w-14rem top-auto bottom-47 right-[max(5.625rem,calc(50vw-34.375rem))])',
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<!-- Language switcher -->
|
<!-- Language switcher -->
|
||||||
|
@ -65,3 +67,56 @@ class:list={[
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Theme toggle >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||||
|
<script is:inline 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>
|
||||||
|
|
|
@ -39,13 +39,19 @@ const SubtitleTag = isPost ? 'div' : 'h2'
|
||||||
'font-bold font-title',
|
'font-bold font-title',
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<a
|
<!-- Fix text cropping issues during view transition on ios by adding a div tag -->
|
||||||
href={getLocalizedPath('/')}
|
<div
|
||||||
|
class="box-content inline-block pr-1"
|
||||||
transition:name={`site-title-${currentLang}`}
|
transition:name={`site-title-${currentLang}`}
|
||||||
data-disable-transition-on-theme
|
data-disable-transition-on-theme
|
||||||
>
|
>
|
||||||
{headerTitle}
|
<a
|
||||||
|
id="site-title-link"
|
||||||
|
href={getLocalizedPath('/')}
|
||||||
|
>
|
||||||
|
{headerTitle}
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</TitleTag>
|
</TitleTag>
|
||||||
|
|
||||||
{headerSubtitle && (
|
{headerSubtitle && (
|
||||||
|
|
|
@ -13,3 +13,22 @@
|
||||||
<path d="M16.6 1.9 4.3 12l12.3 10.1.3 1.6h.8l-.5-5.5h-.8l.1 2.5L6.6 12l9.9-8.7-.1 2.5h.8l.5-5.5h-.8z"></path>
|
<path d="M16.6 1.9 4.3 12l12.3 10.1.3 1.6h.8l-.5-5.5h-.8l.1 2.5L6.6 12l9.9-8.7-.1 2.5h.8l.5-5.5h-.8z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function setupBackButton() {
|
||||||
|
document.getElementById('back-button')?.addEventListener('click', () => {
|
||||||
|
if (document.referrer && document.referrer.includes(window.location.hostname)) {
|
||||||
|
window.history.back()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const titleLink = document.getElementById('site-title-link') as HTMLAnchorElement
|
||||||
|
if (titleLink) {
|
||||||
|
titleLink.click()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setupBackButton()
|
||||||
|
document.addEventListener('astro:after-swap', setupBackButton)
|
||||||
|
</script>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
|
import Button from '@/components/Button.astro'
|
||||||
import Footer from '@/components/Footer.astro'
|
import Footer from '@/components/Footer.astro'
|
||||||
import Header from '@/components/Header.astro'
|
import Header from '@/components/Header.astro'
|
||||||
import Navbar from '@/components/Navbar.astro'
|
import Navbar from '@/components/Navbar.astro'
|
||||||
import Button from '@/components/Button.astro'
|
|
||||||
import themeConfig from '@/config'
|
import themeConfig from '@/config'
|
||||||
import Head from '@/layouts/Head.astro'
|
import Head from '@/layouts/Head.astro'
|
||||||
import { getPageInfo } from '@/utils/page'
|
import { getPageInfo } from '@/utils/page'
|
||||||
|
@ -18,9 +18,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.props
|
const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.props
|
||||||
const { getLocalizedPath, isPost } = getPageInfo(Astro.url.pathname)
|
const { isPost } = getPageInfo(Astro.url.pathname)
|
||||||
const localizedHome = getLocalizedPath('/')
|
|
||||||
const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
|
||||||
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
||||||
const MarginBottom = isPost && themeConfig.comment?.enabled
|
const MarginBottom = isPost && themeConfig.comment?.enabled
|
||||||
? 'mb-10' // Post page with comment system
|
? 'mb-10' // Post page with comment system
|
||||||
|
@ -45,81 +43,8 @@ const MarginBottom = isPost && themeConfig.comment?.enabled
|
||||||
<main class={MarginBottom}>
|
<main class={MarginBottom}>
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
<Button supportedLangs={supportedLangs} />
|
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
<Button supportedLangs={supportedLangs} />
|
||||||
<!-- Theme toggle >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
||||||
<script is:inline 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>
|
|
||||||
|
|
||||||
<!-- Back home >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
||||||
<script is:inline define:vars={{ localizedHome }}>
|
|
||||||
function setupBackButton() {
|
|
||||||
document.getElementById('back-button')?.addEventListener('click', () => {
|
|
||||||
if (document.referrer) {
|
|
||||||
window.history.back()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const siteTitle = document.querySelector(`h1 a[href="${localizedHome}"]`)
|
|
||||||
if (siteTitle) {
|
|
||||||
siteTitle.click()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
setupBackButton()
|
|
||||||
document.addEventListener('astro:after-swap', setupBackButton)
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue