mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-18 04:06:05 +02:00
feat: integrate PhotoSwipe lightbox, enhance scrollbar functionality, and update layout components
- Added a new PhotoSwipe component for image lightbox functionality in the layout. - Enhanced scrollbar component with an auto-hide delay feature. - Updated global styles to improve scrollbar appearance and added styles for PhotoSwipe. - Included new Head layout component for better SEO and meta tag management. - Added images to existing posts for improved visual content. This commit improves user experience with enhanced image viewing and layout consistency.
This commit is contained in:
parent
ac9e839a75
commit
1af92d92c8
10 changed files with 131 additions and 51 deletions
|
@ -1,144 +0,0 @@
|
|||
---
|
||||
import themeConfig from '@/config'
|
||||
|
||||
interface Props {
|
||||
postTitle?: string
|
||||
postDescription?: string
|
||||
postImage?: string
|
||||
}
|
||||
|
||||
const { postTitle, postDescription, postImage } = Astro.props
|
||||
const { title, subtitle, description, author, url, favicon } = themeConfig.site
|
||||
const { light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
||||
const { locale, moreLocale } = themeConfig.global
|
||||
const { verification = {}, twitterID = '', facebookID = '', facebookLink = '', googleAnalyticsID = '', umamiAnalyticsID = '', siteScreenshot = '' } = themeConfig.seo ?? {}
|
||||
const { google = '', bing = '', yandex = '', baidu = '' } = verification
|
||||
const { cdn, commentURL = '', imageHostURL = '', customGoogleAnalyticsURL = '', customUmamiAnalyticsURL = '', customUmamiAnalyticsJS = '' } = themeConfig.preload
|
||||
---
|
||||
<!-- Basic -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
{favicon.toLowerCase().endsWith('.webp') && <link rel="icon" type="image/webp" href={favicon} />}
|
||||
{favicon.toLowerCase().endsWith('.svg') && <link rel="icon" type="image/svg+xml" href={favicon} />}
|
||||
{favicon.toLowerCase().endsWith('.png') && <link rel="icon" type="image/png" href={favicon} />}
|
||||
|
||||
<title>{postTitle ? `${postTitle} | ${title}` : `${title} - ${subtitle}`}</title>
|
||||
<meta name="description" content={postDescription || description} />
|
||||
<meta name="author" content={author} />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="theme-color" content={lightMode} media="(prefers-color-scheme: light)" />
|
||||
<meta name="theme-color" content={darkMode} media="(prefers-color-scheme: dark)" />
|
||||
<meta itemprop="name" content={postTitle || title} />
|
||||
<meta itemprop="image" content={postImage || siteScreenshot} />
|
||||
<meta itemprop="description" content={postDescription || subtitle} />
|
||||
|
||||
<!-- Preload -->
|
||||
<link rel="preconnect" href={cdn} />
|
||||
<link rel="preload" href={`${cdn}/gh/radishzzz/retypeset-font/font.css`} as="style" />
|
||||
{commentURL && <link rel="dns-prefetch" href={commentURL} />}
|
||||
{imageHostURL && <link rel="dns-prefetch" href={imageHostURL} />}
|
||||
{customGoogleAnalyticsURL && <link rel="dns-prefetch" href={customGoogleAnalyticsURL} />}
|
||||
{customUmamiAnalyticsURL && <link rel="dns-prefetch" href={customUmamiAnalyticsURL} />}
|
||||
<link rel="stylesheet" href={`${cdn}/gh/radishzzz/retypeset-font/font.css`} />
|
||||
|
||||
<!-- Link -->
|
||||
<link rel="author" href={url} />
|
||||
<link rel="publisher" href={author} />
|
||||
<link rel="canonical" href={Astro.url} />
|
||||
<link rel="alternate" href="/rss.xml" type="application/rss+xml" title="RSS" />
|
||||
<link rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/" />
|
||||
|
||||
<!-- i18n hreflang generate -->
|
||||
{[locale, ...moreLocale].map(lang => (
|
||||
<link
|
||||
rel="alternate"
|
||||
href={`${url}${lang === locale ? '' : lang}`}
|
||||
hreflang={lang === 'zh-tw' ? 'zh-TW' : lang}
|
||||
/>
|
||||
))}
|
||||
|
||||
<!-- Facebook Open Graph -->
|
||||
<meta property="fb:app_id" content={facebookID} />
|
||||
<meta property="og:url" content={Astro.url} />
|
||||
<meta property="og:type" content={postTitle ? 'article' : 'website'} />
|
||||
<meta property="og:title" content={postTitle || title} />
|
||||
<meta property="og:image" content={postImage || siteScreenshot} />
|
||||
<meta property="og:image:alt" content={postTitle || title} />
|
||||
<meta property="og:description" content={postDescription || subtitle} />
|
||||
<meta property="og:site_name" content={title} />
|
||||
<meta property="og:locale" content={Astro.currentLocale?.replace('-', '_') || 'en_US'} />
|
||||
<meta property="article:author" content={facebookLink} />
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:url" content={Astro.url} />
|
||||
<meta name="twitter:title" content={postTitle || title} />
|
||||
<meta name="twitter:description" content={postDescription || subtitle} />
|
||||
<meta name="twitter:image" content={postImage || siteScreenshot} />
|
||||
<meta name="twitter:image:alt" content={postTitle || title} />
|
||||
{twitterID && (
|
||||
<>
|
||||
<meta name="twitter:site" content={twitterID} />
|
||||
<meta name="twitter:creator" content={twitterID} />
|
||||
</>
|
||||
)}
|
||||
<meta name="twitter:dnt" content="on" />
|
||||
|
||||
<!-- Site Verification -->
|
||||
{google && <meta name="google-site-verification" content={google} />}
|
||||
{bing && <meta name="msvalidate.01" content={bing} />}
|
||||
{yandex && <meta name="yandex-verification" content={yandex} />}
|
||||
{baidu && <meta name="baidu-site-verification" content={baidu} />}
|
||||
|
||||
<!-- Theme Toggle -->
|
||||
<script is:inline>
|
||||
const theme = localStorage.getItem('theme')
|
||||
?? (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
|
||||
document.documentElement.classList.toggle('dark', theme === 'dark')
|
||||
</script>
|
||||
|
||||
<!-- Google Analytics -->
|
||||
{
|
||||
googleAnalyticsID && (
|
||||
<>
|
||||
<script
|
||||
type="text/partytown"
|
||||
crossorigin="anonymous"
|
||||
src={`${customGoogleAnalyticsURL || 'https://www.googletagmanager.com'}/gtag/js?id=${googleAnalyticsID}`}
|
||||
/>
|
||||
<script
|
||||
type="text/partytown"
|
||||
define:vars={{ googleAnalyticsID, customGoogleAnalyticsURL }}
|
||||
>
|
||||
window.dataLayer = window.dataLayer || []
|
||||
function gtag(...args) {
|
||||
dataLayer.push(args)
|
||||
}
|
||||
gtag('js', new Date())
|
||||
if (customGoogleAnalyticsURL) {
|
||||
gtag('config', googleAnalyticsID, {
|
||||
transport_url: customGoogleAnalyticsURL,
|
||||
})
|
||||
}
|
||||
else {
|
||||
gtag('config', googleAnalyticsID)
|
||||
}
|
||||
</script>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
<!-- Umami Analytics -->
|
||||
{
|
||||
umamiAnalyticsID && (
|
||||
<script
|
||||
type="text/partytown"
|
||||
crossorigin="anonymous"
|
||||
data-website-id={umamiAnalyticsID}
|
||||
src={customUmamiAnalyticsJS || 'https://analytics.umami.is/script.js'}
|
||||
data-cache="true"
|
||||
/>
|
||||
)
|
||||
}
|
52
src/components/PhotoSwipe.astro
Normal file
52
src/components/PhotoSwipe.astro
Normal file
|
@ -0,0 +1,52 @@
|
|||
<script>
|
||||
import PhotoSwipeLightbox from 'photoswipe/lightbox'
|
||||
import 'photoswipe/style.css'
|
||||
|
||||
// Store lightbox instance for later use
|
||||
let lightbox: PhotoSwipeLightbox | null = null
|
||||
const pswp = import('photoswipe')
|
||||
|
||||
// Initialize PhotoSwipe lightbox with custom configuration
|
||||
function createPhotoSwipe() {
|
||||
lightbox = new PhotoSwipeLightbox({
|
||||
gallery: 'article img',
|
||||
pswpModule: () => pswp,
|
||||
closeSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="2.4rem" viewBox="0 -960 960 960" width="3.8rem" fill="#A0A09F"><path d="M480-424 284-228q-11 11-28 11t-28-11q-11-11-11-28t11-28l196-196-196-196q-11-11-11-28t11-28q11-11 28-11t28 11l196 196 196-196q11-11 28-11t28 11q11 11 11 28t-11 28L536-480l196 196q11 11 11 28t-11 28q-11 11-28 11t-28-11L480-424Z"/></svg>',
|
||||
zoomSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="2.4rem" viewBox="0 -960 960 960" width="3.8rem" fill="#A0A09F"><path d="M340-540h-40q-17 0-28.5-11.5T260-580q0-17 11.5-28.5T300-620h40v-40q0-17 11.5-28.5T380-700q17 0 28.5 11.5T420-660v40h40q17 0 28.5 11.5T500-580q0 17-11.5 28.5T460-540h-40v40q0 17-11.5 28.5T380-460q-17 0-28.5-11.5T340-500v-40Zm40 220q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l224 224q11 11 11 28t-11 28q-11 11-28 11t-28-11L532-372q-30 24-69 38t-83 14Zm0-80q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>',
|
||||
wheelToZoom: true,
|
||||
arrowPrev: false,
|
||||
arrowNext: false,
|
||||
imageClickAction: 'close',
|
||||
tapAction: 'close',
|
||||
doubleTapAction: 'zoom',
|
||||
})
|
||||
|
||||
// Add custom filter to handle image data and dimensions
|
||||
lightbox.addFilter('domItemData', (itemData: any, element: Element) => {
|
||||
if (element instanceof HTMLImageElement) {
|
||||
itemData.src = element.src
|
||||
itemData.w = Number(element.naturalWidth || window.innerWidth)
|
||||
itemData.h = Number(element.naturalHeight || window.innerHeight)
|
||||
itemData.msrc = element.src
|
||||
}
|
||||
return itemData
|
||||
})
|
||||
|
||||
lightbox.init()
|
||||
}
|
||||
|
||||
// Cleanup function to destroy lightbox instance
|
||||
function cleanup() {
|
||||
if (lightbox) {
|
||||
lightbox.destroy()
|
||||
lightbox = null
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize PhotoSwipe when DOM is ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
createPhotoSwipe()
|
||||
})
|
||||
|
||||
document.addEventListener('astro:before-swap', cleanup)
|
||||
</script>
|
|
@ -14,6 +14,7 @@ function initScrollbar() {
|
|||
scrollbars: {
|
||||
theme: document.documentElement.classList.contains('dark') ? 'scrollbar-dark' : 'scrollbar-light',
|
||||
autoHide: 'scroll',
|
||||
autoHideDelay: 800,
|
||||
},
|
||||
overflow: {
|
||||
x: 'hidden',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue