diff --git a/src/components/ArchivePanel.astro b/src/components/ArchivePanel.astro index 243bd30..c82dbf5 100644 --- a/src/components/ArchivePanel.astro +++ b/src/components/ArchivePanel.astro @@ -6,9 +6,9 @@ import I18nKey from "../i18n/i18nKey"; import {UNCATEGORIZED} from "@constants/constants"; interface Props { - keyword: string; - tags: string[]; - categories: string[]; + keyword?: string; + tags?: string[]; + categories?: string[]; } const { keyword, tags, categories} = Astro.props; @@ -27,8 +27,8 @@ if (Array.isArray(categories) && categories.length > 0) { ); } -const groups = function () { - const groupedPosts = posts.reduce((grouped, post) => { +const groups: {year: number, posts: typeof posts}[] = function () { + const groupedPosts = posts.reduce((grouped: {[year: number]: typeof posts}, post) => { const year = post.data.published.getFullYear() if (!grouped[year]) { grouped[year] = [] @@ -39,8 +39,8 @@ const groups = function () { // convert the object to an array const groupedPostsArray = Object.keys(groupedPosts).map(key => ({ - year: key, - posts: groupedPosts[key] + year: parseInt(key), + posts: groupedPosts[parseInt(key)] })) // sort years by latest first diff --git a/src/components/Navbar.astro b/src/components/Navbar.astro index 5b7a78c..90f70d7 100644 --- a/src/components/Navbar.astro +++ b/src/components/Navbar.astro @@ -1,7 +1,7 @@ --- import { Icon } from 'astro-icon/components'; import DisplaySettings from "./widget/DisplaySettings.svelte"; -import {LinkPreset, NavBarLink} from "../types/config"; +import {LinkPreset, type NavBarLink} from "../types/config"; import {navBarConfig, siteConfig} from "../config"; import NavMenuPanel from "./widget/NavMenuPanel.astro"; import Search from "./Search.svelte"; @@ -34,7 +34,7 @@ let links: NavBarLink[] = navBarConfig.links.map((item: NavBarLink | LinkPreset) >
{l.name} - {l.external && } + {l.external && }
; })} @@ -80,22 +80,20 @@ function switchTheme() { function loadButtonScript() { let switchBtn = document.getElementById("scheme-switch"); - switchBtn.addEventListener("click", function () { + switchBtn!.addEventListener("click", function () { switchTheme() }); let settingBtn = document.getElementById("display-settings-switch"); - if (settingBtn) { - settingBtn.addEventListener("click", function () { - let settingPanel = document.getElementById("display-setting"); - settingPanel.classList.toggle("float-panel-closed"); - }); - } + settingBtn!.addEventListener("click", function () { + let settingPanel = document.getElementById("display-setting"); + settingPanel!.classList.toggle("float-panel-closed"); + }); let menuBtn = document.getElementById("nav-menu-switch"); - menuBtn.addEventListener("click", function () { + menuBtn!.addEventListener("click", function () { let menuPanel = document.getElementById("nav-menu-panel"); - menuPanel.classList.toggle("float-panel-closed"); + menuPanel!.classList.toggle("float-panel-closed"); }); } diff --git a/src/components/PostCard.astro b/src/components/PostCard.astro index f1d4769..44ab3c8 100644 --- a/src/components/PostCard.astro +++ b/src/components/PostCard.astro @@ -8,7 +8,7 @@ import I18nKey from "../i18n/i18nKey"; import {getDir} from "../utils/url-utils"; interface Props { - class: string; + class?: string; entry: any; title: string; url: string; @@ -17,11 +17,10 @@ interface Props { category: string; image: string; description: string; - words: number; draft: boolean; style: string; } -const { entry, title, url, published, tags, category, image, description, words, style } = Astro.props; +const { entry, title, url, published, tags, category, image, description, style } = Astro.props; const className = Astro.props.class; const hasCover = image !== undefined && image !== null && image !== ''; diff --git a/src/components/PostMeta.astro b/src/components/PostMeta.astro index 34ec1d0..3a0c7f2 100644 --- a/src/components/PostMeta.astro +++ b/src/components/PostMeta.astro @@ -10,9 +10,9 @@ interface Props { published: Date; tags: string[]; category: string; - hideTagsForMobile: boolean; + hideTagsForMobile?: boolean; } -const {published, tags, category, hideTagsForMobile} = Astro.props; +const {published, tags, category, hideTagsForMobile = false} = Astro.props; const className = Astro.props.class; --- diff --git a/src/components/control/ButtonLink.astro b/src/components/control/ButtonLink.astro index b58d920..154306e 100644 --- a/src/components/control/ButtonLink.astro +++ b/src/components/control/ButtonLink.astro @@ -4,9 +4,9 @@ interface Props { url?: string label?: string } -const { badge, url, name } = Astro.props +const { badge, url, label } = Astro.props --- - + } @@ -48,15 +48,15 @@ const className = Astro.props.class constructor() { super(); - if (this.dataset.isCollapsed === undefined || this.dataset.isCollapsed === false) + if (this.dataset.isCollapsed !== "true") return; const id = this.dataset.id; const btn = this.querySelector('.expand-btn'); const wrapper = this.querySelector(`#${id}`) - btn.addEventListener('click', () => { - wrapper.classList.remove('collapsed'); - btn.classList.add('hidden'); + btn!.addEventListener('click', () => { + wrapper!.classList.remove('collapsed'); + btn!.classList.add('hidden'); }) } } diff --git a/src/content/config.ts b/src/content/config.ts index 5066aaa..b448dd9 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -4,11 +4,17 @@ const postsCollection = defineCollection({ schema: z.object({ title: z.string(), published: z.date(), - draft: z.boolean().optional(), - description: z.string().optional(), - image: z.string().optional(), - tags: z.array(z.string()).optional(), - category: z.string().optional(), + draft: z.boolean().optional().default(false), + description: z.string().optional().default(""), + image: z.string().optional().default(""), + tags: z.array(z.string()).optional().default([]), + category: z.string().optional().default(""), + + /* For internal use */ + prevTitle: z.string().default(""), + prevSlug: z.string().default(""), + nextTitle: z.string().default(""), + nextSlug: z.string().default(""), }), }) export const collections = { diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index f1837a4..70bdf3c 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -8,14 +8,14 @@ import ImageWrapper from "@components/misc/ImageWrapper.astro"; import {pathsEqual} from "@utils/url-utils"; import ConfigCarrier from "@components/ConfigCarrier.astro"; import {profileConfig, siteConfig} from "@/config"; -import {Favicon} from "../types/config"; +import {type Favicon} from "../types/config"; import {defaultFavicons} from "../constants/icon"; import {LIGHT_MODE, DARK_MODE, AUTO_MODE, DEFAULT_THEME} from "../constants/constants"; import {url} from "../utils/url-utils"; interface Props { - title: string; - banner: string; + title?: string; + banner?: string; description?: string; } @@ -23,8 +23,6 @@ let { title, banner, description } = Astro.props; const isHomePage = pathsEqual(Astro.url.pathname, '/'); -const testPathName = Astro.url.pathname; - const anim = { old: { name: 'fadeIn', @@ -73,7 +71,7 @@ const siteLang = siteConfig.lang.replace('_', '-') --- - + {pageTitle} @@ -232,13 +230,14 @@ function setClickOutsideToClose(panel: string, ignores: string[]) { document.addEventListener("click", event => { let panelDom = document.getElementById(panel); let tDom = event.target; + if (!(tDom instanceof Node)) return; // Ensure the event target is an HTML Node for (let ig of ignores) { let ie = document.getElementById(ig) if (ie == tDom || (ie?.contains(tDom))) { return; } } - panelDom.classList.add("float-panel-closed"); + panelDom!.classList.add("float-panel-closed"); }); } setClickOutsideToClose("display-setting", ["display-setting", "display-settings-switch"]) @@ -257,7 +256,8 @@ function loadHue() { function setBannerHeight() { const banner = document.getElementById('banner-wrapper'); - if (document.documentElement.hasAttribute('isHome')) { + if (!banner) return + if (document.documentElement.dataset.isHome === "true") { banner.classList.remove('banner-else'); banner.classList.add('banner-home'); } else { @@ -267,11 +267,13 @@ function setBannerHeight() { } function initCustomScrollbar() { + const bodyElement = document.querySelector('body'); + if (!bodyElement) return; 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'), + target: bodyElement, cancel: { nativeScrollbarsOverlaid: true, // don't initialize the overlay scrollbar if there is a native one } diff --git a/src/layouts/MainGridLayout.astro b/src/layouts/MainGridLayout.astro index e687d79..18301ab 100644 --- a/src/layouts/MainGridLayout.astro +++ b/src/layouts/MainGridLayout.astro @@ -8,7 +8,7 @@ import BackToTop from "@components/control/BackToTop.astro"; import {siteConfig} from "@/config"; interface Props { - title: string; + title?: string; banner?: string; description?: string; } diff --git a/src/pages/archive/category/[category].astro b/src/pages/archive/category/[category].astro index 88aa0d3..33af063 100644 --- a/src/pages/archive/category/[category].astro +++ b/src/pages/archive/category/[category].astro @@ -16,7 +16,7 @@ export async function getStaticPaths() { }); } -const { category } = Astro.params; +const category = Astro.params.category as string; --- diff --git a/src/pages/archive/tag/[tag].astro b/src/pages/archive/tag/[tag].astro index ce132a4..0e68b65 100644 --- a/src/pages/archive/tag/[tag].astro +++ b/src/pages/archive/tag/[tag].astro @@ -5,7 +5,6 @@ import ArchivePanel from "@components/ArchivePanel.astro"; import {i18n} from "@i18n/translation"; import I18nKey from "@i18n/i18nKey"; - export async function getStaticPaths() { let posts = await getSortedPosts() @@ -25,7 +24,7 @@ export async function getStaticPaths() { }); } -const { tag } = Astro.params; +const tag= Astro.params.tag as string; --- diff --git a/src/pages/posts/[...slug].astro b/src/pages/posts/[...slug].astro index 20bbe8c..7191bdc 100644 --- a/src/pages/posts/[...slug].astro +++ b/src/pages/posts/[...slug].astro @@ -108,21 +108,23 @@ const jsonLd = {
- + {entry.data.nextSlug &&
- +
{entry.data.nextTitle}
}
- + {entry.data.prevSlug &&
{entry.data.prevTitle}
- +
}
diff --git a/src/utils/setting-utils.ts b/src/utils/setting-utils.ts index 6471901..dc5d1da 100644 --- a/src/utils/setting-utils.ts +++ b/src/utils/setting-utils.ts @@ -14,11 +14,11 @@ export function getHue(): number { export function setHue(hue: number): void { localStorage.setItem('hue', String(hue)) - const r = document.querySelector(':root') + const r = document.querySelector(':root') as HTMLElement if (!r) { return } - r.style.setProperty('--hue', hue) + r.style.setProperty('--hue', String(hue)) } diff --git a/src/utils/url-utils.ts b/src/utils/url-utils.ts index 6b8e545..f2829ee 100644 --- a/src/utils/url-utils.ts +++ b/src/utils/url-utils.ts @@ -12,13 +12,11 @@ function joinUrl(...parts: string[]): string { return joined.replace(/\/+/g, '/'); } -export function getPostUrlBySlug(slug: string): string | null { - if (!slug) return null +export function getPostUrlBySlug(slug: string): string { return url(`/posts/${slug}/`) } -export function getCategoryUrl(category: string): string | null { - if (!category) return null +export function getCategoryUrl(category: string): string { if (category === i18n(i18nKey.uncategorized)) return url('/archive/category/uncategorized/') return url(`/archive/category/${category}/`)