import type { DARK_MODE, LIGHT_MODE, SYSTEM_MODE, WALLPAPER_BANNER, WALLPAPER_NONE, WALLPAPER_OVERLAY, } from "../constants/constants"; export type SiteConfig = { title: string; subtitle: string; site_url: string; description?: string; // 网站描述,用于生成 keywords?: string[]; // 站点关键词,用于生成 lang: "en" | "zh_CN" | "zh_TW" | "ja" | "ru"; themeColor: { hue: number; fixed: boolean; defaultMode?: LIGHT_DARK_MODE; // 默认模式:浅色、深色或跟随系统 }; // 卡片样式配置 card: { // 是否开启卡片边框和阴影立体效果 border: boolean; }; // 字体配置 font: FontConfig; // 站点开始日期,用于计算运行天数 siteStartDate?: string; // 格式: "YYYY-MM-DD" // 可选:站点时区,使用 IANA 时区标识,例如 "Asia/Shanghai"、"UTC" timezone?: string; // 提醒框配置 rehypeCallouts: { theme: "github" | "obsidian" | "vitepress"; }; // 添加bangumi配置 bangumi?: { userId?: string; // Bangumi用户ID }; generateOgImages: boolean; favicon: Array<{ src: string; theme?: "light" | "dark"; sizes?: string; }>; navbar: { /** 导航栏Logo图标,可选类型:icon库、本地图片、网络图片链接 */ logo?: { type: "icon" | "image" | "url"; value: string; // icon名、本地图片路径或网络图片url alt?: string; // 图片alt文本 }; title?: string; // 导航栏标题,如果不设置则使用 title widthFull?: boolean; // 导航栏是否占满屏幕宽度 followTheme?: boolean; // 导航栏图标和标题是否跟随主题色 }; showLastModified: boolean; // 控制"上次编辑"卡片显示的开关 outdatedThreshold?: number; // 文章过期阈值(天数),超过此天数才显示"上次编辑"卡片 sharePoster?: boolean; // 是否显示分享海报按钮 // 页面开关配置 pages: { sponsor: boolean; // 赞助页面开关 guestbook: boolean; // 留言板页面开关 bangumi: boolean; }; // 文章列表布局配置 postListLayout: { defaultMode: "list" | "grid"; // 默认布局模式:list=列表模式,grid=网格模式 allowSwitch: boolean; // 是否允许用户切换布局 grid: { // 网格布局配置,仅在 defaultMode 为 "grid" 或允许切换布局时生效 // 是否开启瀑布流布局 masonry: boolean; // 网格模式列数:2 或 3,默认为 2。注意:3列模式仅在单侧边栏(或无侧边栏)且屏幕宽度足够时生效 columns?: 2 | 3; }; }; // 分页配置 pagination: { postsPerPage: number; // 每页显示的文章数量 }; // 统计分析 analytics?: { googleAnalyticsId?: string; // Google Analytics ID microsoftClarityId?: string; // Microsoft Clarity ID }; // 图片优化配置 imageOptimization?: { /** * 输出图片格式 * - "avif": 仅输出 AVIF 格式(最小体积,兼容性较低) * - "webp": 仅输出 WebP 格式(体积适中,兼容性好) * - "both": 同时输出 AVIF 和 WebP(推荐,浏览器自动选择最佳格式) */ formats?: "avif" | "webp" | "both"; /** * 图片压缩质量 (1-100) * 值越低体积越小但质量越差,推荐 70-85 */ quality?: number; }; }; export type Favicon = { src: string; theme?: "light" | "dark"; sizes?: string; }; export enum LinkPreset { Home = 0, Archive = 1, About = 2, Friends = 3, Sponsor = 4, Guestbook = 5, Bangumi = 6, } export type NavBarLink = { name: string; url: string; external?: boolean; icon?: string; // 菜单项图标 children?: (NavBarLink | LinkPreset)[]; // 支持子菜单,可以是NavBarLink或LinkPreset }; export enum NavBarSearchMethod { PageFind = 0, } export type NavBarSearchConfig = { method: NavBarSearchMethod; }; export type NavBarConfig = { links: (NavBarLink | LinkPreset)[]; }; export type ProfileConfig = { avatar?: string; name: string; bio?: string; links: { name: string; url: string; icon: string; showName?: boolean; }[]; }; export type LicenseConfig = { enable: boolean; name: string; url: string; }; // 评论配置 export type CommentConfig = { /** * 当前启用的评论系统类型 * "none" | "twikoo" | "waline" | "giscus" | "disqus" | 'artalk' */ type: "none" | "twikoo" | "waline" | "giscus" | "disqus" | "artalk"; twikoo?: { envId: string; region?: string; lang?: string; visitorCount?: boolean; }; waline?: { serverURL: string; lang?: string; login?: "enable" | "force" | "disable"; visitorCount?: boolean; // 是否统计访问量,true 启用访问量,false 关闭 }; artalk?: { // 后端程序 API 地址 server: string; /** * 语言,支持语言如下: * - "en" (English) * - "zh-CN" (简体中文) * - "zh-TW" (繁体中文) * - "ja" (日本語) * - "ko" (한국어) * - "fr" (Français) * - "ru" (Русский) * */ locale: string | "auto"; // 是否统计访问量,true 启用访问量,false 关闭 visitorCount?: boolean; }; giscus?: { repo: string; repoId: string; category: string; categoryId: string; mapping: string; strict: string; reactionsEnabled: string; emitMetadata: string; inputPosition: string; lang: string; loading: string; }; disqus?: { shortname: string; }; }; export type LIGHT_DARK_MODE = | typeof LIGHT_MODE | typeof DARK_MODE | typeof SYSTEM_MODE; export type WALLPAPER_MODE = | typeof WALLPAPER_BANNER | typeof WALLPAPER_OVERLAY | typeof WALLPAPER_NONE; export type BlogPostData = { body: string; title: string; published: Date; description: string; tags: string[]; draft?: boolean; image?: string; category?: string; pinned?: boolean; prevTitle?: string; prevSlug?: string; nextTitle?: string; nextSlug?: string; }; export type ExpressiveCodeConfig = { /** @deprecated 使用 darkTheme 和 lightTheme 代替 */ theme?: string; /** 暗色主题名称(用于暗色模式) */ darkTheme: string; /** 亮色主题名称(用于亮色模式) */ lightTheme: string; /** 代码块折叠插件配置 */ pluginCollapsible?: PluginCollapsibleConfig; }; export type PluginCollapsibleConfig = { enable: boolean; // 是否启用代码块折叠功能 lineThreshold: number; // 触发折叠的行数阈值 previewLines: number; // 折叠时显示的预览行数 defaultCollapsed: boolean; // 默认是否折叠 }; export type AnnouncementConfig = { // enable属性已移除,现在通过sidebarLayoutConfig统一控制 title?: string; // 公告栏标题 content: string; // 公告栏内容 icon?: string; // 公告栏图标 type?: "info" | "warning" | "success" | "error"; // 公告类型 closable?: boolean; // 是否可关闭 link?: { enable: boolean; // 是否启用链接 text: string; // 链接文字 url: string; // 链接地址 external?: boolean; // 是否外部链接 }; }; // 单个字体配置 export type FontItem = { id: string; // 字体唯一标识符 name: string; // 字体显示名称 src: string; // 字体文件路径或URL链接 family: string; // CSS font-family 名称 weight?: string | number; // 字体粗细,如 "normal", "bold", 400, 700 等 style?: "normal" | "italic" | "oblique"; // 字体样式 display?: "auto" | "block" | "swap" | "fallback" | "optional"; // font-display 属性 unicodeRange?: string; // Unicode 范围,用于字体子集化 format?: | "woff" | "woff2" | "truetype" | "opentype" | "embedded-opentype" | "svg"; // 字体格式,仅当 src 为本地文件时需要 }; // 字体配置 export type FontConfig = { enable: boolean; // 是否启用自定义字体功能 selected: string | string[]; // 当前选择的字体ID,支持单个或多个字体组合 fonts: Record; // 字体库,以ID为键的对象 fallback?: string[]; // 全局字体回退列表 preload?: boolean; // 是否预加载字体文件以提高性能 }; export type FooterConfig = { enable: boolean; // 是否启用Footer HTML注入功能 customHtml?: string; // 自定义HTML内容,用于添加备案号等信息 }; export type CoverImageConfig = { enableInPost: boolean; // 是否在文章详情页显示封面图 randomCoverImage: { enable: boolean; // 是否启用随机图功能 apis: string[]; // 随机图API列表 fallback?: string; // API失败时的回退图片路径(相对于src目录) showLoading?: boolean; // 是否显示加载动画 }; }; // 组件配置类型定义 export type WidgetComponentType = | "profile" | "announcement" | "categories" | "tags" | "sidebarToc" | "advertisement" | "stats" | "calendar" | "music"; export type WidgetComponentConfig = { type: WidgetComponentType; // 组件类型 enable: boolean; // 是否启用该组件 position: "top" | "sticky"; // 组件位置:top=固定在顶部,sticky=粘性定位(可滚动) configId?: string; // 配置ID,用于广告组件指定使用哪个配置 showOnPostPage?: boolean; // 是否在文章详情页显示 showOnNonPostPage?: boolean; // 是否在非文章详情页显示 responsive?: { hidden?: ("mobile" | "tablet" | "desktop")[]; // 在指定设备上隐藏 collapseThreshold?: number; // 折叠阈值 }; customProps?: Record; // 自定义属性,用于扩展组件功能 }; export type MobileBottomComponentConfig = { type: WidgetComponentType; // 组件类型 enable: boolean; // 是否启用该组件 configId?: string; // 配置ID,用于广告组件指定使用哪个配置 showOnPostPage?: boolean; // 是否在文章详情页显示 showOnNonPostPage?: boolean; // 是否在非文章详情页显示 responsive?: { hidden?: ("mobile" | "tablet" | "desktop")[]; // 在指定设备上隐藏 collapseThreshold?: number; // 折叠阈值 }; customProps?: Record; // 自定义属性,用于扩展组件功能 }; export type SidebarLayoutConfig = { enable: boolean; // 是否启用侧边栏 position: "left" | "both"; // 侧边栏位置:左侧或双侧 showRightSidebarOnPostPage?: boolean; // 当position为left时,是否在文章详情页显示右侧边栏 leftComponents: WidgetComponentConfig[]; // 左侧边栏组件配置列表 rightComponents: WidgetComponentConfig[]; // 右侧边栏组件配置列表 mobileBottomComponents: MobileBottomComponentConfig[]; // 移动端底部组件配置列表(<768px显示) }; export type SakuraConfig = { enable: boolean; // 是否启用樱花特效 sakuraNum: number; // 樱花数量,默认21 limitTimes: number; // 樱花越界限制次数,-1为无限循环 size: { min: number; // 樱花最小尺寸倍数 max: number; // 樱花最大尺寸倍数 }; opacity: { min: number; // 樱花最小不透明度 max: number; // 樱花最大不透明度 }; speed: { horizontal: { min: number; // 水平移动速度最小值 max: number; // 水平移动速度最大值 }; vertical: { min: number; // 垂直移动速度最小值 max: number; // 垂直移动速度最大值 }; rotation: number; // 旋转速度 fadeSpeed: number; // 消失速度,不应大于最小不透明度 }; zIndex: number; // 层级,确保樱花在合适的层级显示 }; // Spine 看板娘配置 export type SpineModelConfig = { enable: boolean; // 是否启用 Spine 看板娘 model: { path: string; // 模型文件路径 (.json) scale?: number; // 模型缩放比例,默认1.0 x?: number; // X轴偏移,默认0 y?: number; // Y轴偏移,默认0 }; position: { corner: "bottom-left" | "bottom-right" | "top-left" | "top-right"; // 显示位置 offsetX?: number; // 水平偏移量,默认20px offsetY?: number; // 垂直偏移量,默认20px }; size: { width?: number; // 容器宽度,默认280px height?: number; // 容器高度,默认400px }; interactive?: { enabled?: boolean; // 是否启用交互功能,默认true clickAnimations?: string[]; // 点击时随机播放的动画列表 clickMessages?: string[]; // 点击时随机显示的文字消息 messageDisplayTime?: number; // 文字显示时间(毫秒),默认3000 idleAnimations?: string[]; // 待机动画列表 idleInterval?: number; // 待机动画切换间隔(毫秒),默认10000 }; responsive?: { hideOnMobile?: boolean; // 是否在移动端隐藏,默认false mobileBreakpoint?: number; // 移动端断点,默认768px }; zIndex?: number; // 层级,默认1000 opacity?: number; // 透明度,0-1,默认1.0 }; // Live2D 看板娘配置 export type Live2DModelConfig = { enable: boolean; // 是否启用 Live2D 看板娘 model: { path: string; // 模型文件夹路径或model3.json文件路径 }; position?: { corner?: "bottom-left" | "bottom-right" | "top-left" | "top-right"; // 显示位置,默认bottom-right offsetX?: number; // 水平偏移量,默认20px offsetY?: number; // 垂直偏移量,默认20px }; size?: { width?: number; // 容器宽度,默认280px height?: number; // 容器高度,默认250px }; interactive?: { enabled?: boolean; // 是否启用交互功能,默认true // motions 和 expressions 将从模型 JSON 文件中自动读取 clickMessages?: string[]; // 点击时随机显示的文字消息 messageDisplayTime?: number; // 文字显示时间(毫秒),默认3000 }; responsive?: { hideOnMobile?: boolean; // 是否在移动端隐藏,默认false mobileBreakpoint?: number; // 移动端断点,默认768px }; }; export type BackgroundWallpaperConfig = { mode: "banner" | "overlay" | "none"; // 壁纸模式:banner横幅模式、overlay全屏透明覆盖模式或none纯色背景 switchable?: boolean; // 是否允许用户通过导航栏切换壁纸模式,默认true src: | string | string[] | { desktop?: string | string[]; mobile?: string | string[]; }; // 支持单个图片、图片数组或分别设置桌面端和移动端图片 // Banner模式特有配置 banner?: { position?: | "top" | "center" | "bottom" | "top left" | "top center" | "top right" | "center left" | "center center" | "center right" | "bottom left" | "bottom center" | "bottom right" | "left top" | "left center" | "left bottom" | "right top" | "right center" | "right bottom" | string; // 壁纸位置,支持CSS object-position的所有值,包括百分比和像素值 homeText?: { enable: boolean; // 是否在首页显示自定义文字(全局开关) title?: string; // 主标题 subtitle?: string | string[]; // 副标题,支持单个字符串或字符串数组 titleSize?: string; // 主标题字体大小,如 "3.5rem" subtitleSize?: string; // 副标题字体大小,如 "1.5rem" typewriter?: { enable: boolean; // 是否启用打字机效果 speed: number; // 打字速度(毫秒) deleteSpeed: number; // 删除速度(毫秒) pauseTime: number; // 完整显示后的暂停时间(毫秒) }; }; credit?: { enable: | boolean | { desktop: boolean; // 桌面端是否显示横幅图片来源文本 mobile: boolean; // 移动端是否显示横幅图片来源文本 }; // 是否显示横幅图片来源文本,支持布尔值或分别设置桌面端和移动端 text: | string | { desktop: string; // 桌面端显示的来源文本 mobile: string; // 移动端显示的来源文本 }; // 横幅图片来源文本,支持字符串或分别设置桌面端和移动端 url?: | string | { desktop: string; // 桌面端原始艺术品或艺术家页面的 URL 链接 mobile: string; // 移动端原始艺术品或艺术家页面的 URL 链接 }; // 原始艺术品或艺术家页面的 URL 链接,支持字符串或分别设置桌面端和移动端 }; navbar?: { transparentMode?: "semi" | "full" | "semifull"; // 导航栏透明模式 enableBlur?: boolean; // 是否开启毛玻璃模糊效果 blur?: number; // 毛玻璃模糊度 }; waves?: { enable: | boolean | { desktop: boolean; // 桌面端是否启用波浪动画效果 mobile: boolean; // 移动端是否启用波浪动画效果 }; // 是否启用波浪动画效果,支持布尔值或分别设置桌面端和移动端 }; }; // 全屏透明覆盖模式特有配置 overlay?: { zIndex?: number; // 层级,确保壁纸在合适的层级显示 opacity?: number; // 壁纸透明度,0-1之间 blur?: number; // 背景模糊程度,单位px }; }; // 广告栏配置 export type AdConfig = { title?: string; // 广告栏标题 content?: string; // 广告栏文本内容 image?: { src: string; // 图片地址 alt?: string; // 图片描述 link?: string; // 图片点击链接 external?: boolean; // 是否外部链接 }; link?: { text: string; // 链接文本 url: string; // 链接地址 external?: boolean; // 是否外部链接 }; padding?: { top?: string; // 上边距,如 "0", "1rem", "16px" right?: string; // 右边距 bottom?: string; // 下边距 left?: string; // 左边距 all?: string; // 统一边距,会覆盖单独设置 }; closable?: boolean; // 是否可关闭 displayCount?: number; // 显示次数限制,-1为无限制 expireDate?: string; // 过期时间 (ISO 8601 格式) }; // 友链配置 export type FriendLink = { title: string; // 友链标题 imgurl: string; // 头像图片URL desc: string; // 友链描述 siteurl: string; // 友链地址 tags?: string[]; // 标签数组 weight: number; // 权重,数字越大排序越靠前 enabled: boolean; // 是否启用 }; export type FriendsPageConfig = { columns: 2 | 3; // 显示列数:2列或3列 }; // 音乐播放器配置 export type MusicPlayerConfig = { // 使用方式:'meting' 或 'local' mode?: "meting" | "local"; // "meting" 使用 Meting API,"local" 使用本地音乐列表 // 默认音量 (0-1) volume?: number; // 播放模式:'list'=列表循环, 'one'=单曲循环, 'random'=随机播放 playMode?: "list" | "one" | "random"; // 是否显示歌词 showLyrics?: boolean; // 是否在导航栏显示音乐播放器 showInNavbar?: boolean; // Meting API 配置 meting?: { // Meting API 地址 api?: string; // 音乐平台:netease=网易云音乐, tencent=QQ音乐, kugou=酷狗音乐, xiami=虾米音乐, baidu=百度音乐 server?: "netease" | "tencent" | "kugou" | "xiami" | "baidu"; // 类型:song=单曲, playlist=歌单, album=专辑, search=搜索, artist=艺术家 type?: "song" | "playlist" | "album" | "search" | "artist"; // 歌单/专辑/单曲 ID 或搜索关键词 id?: string; // 认证 token(可选) auth?: string; // 备用 API 配置(当主 API 失败时使用) fallbackApis?: string[]; }; // 本地音乐配置(当 mode 为 'local' 时使用) local?: { playlist?: Array<{ name: string; // 歌曲名称 artist: string; // 艺术家 url: string; // 音乐文件路径(相对于 public 目录) cover?: string; // 封面图片路径(相对于 public 目录) lrc?: string; // 歌词内容,支持 LRC 格式 }>; }; }; // 赞助方式类型 export type SponsorMethod = { name: string; // 赞助方式名称,如 "支付宝"、"微信"、"PayPal" icon?: string; // 图标名称(Iconify 格式),如 "fa7-brands:alipay" qrCode?: string; // 收款码图片路径(相对于 public 目录),可选 link?: string; // 赞助链接 URL,可选。如果提供,会显示跳转按钮 description?: string; // 描述文本 enabled: boolean; // 是否启用 }; // 赞助者列表项 export type SponsorItem = { name: string; // 赞助者名称,如果想显示匿名,可以直接设置为"匿名"或使用 i18n amount?: string; // 赞助金额(可选) date?: string; // 赞助日期(可选,ISO 格式) message?: string; // 留言(可选) }; // 赞助配置 export type SponsorConfig = { title?: string; // 页面标题,默认使用 i18n description?: string; // 页面描述文本 usage?: string; // 赞助用途说明 methods: SponsorMethod[]; // 赞助方式列表 sponsors?: SponsorItem[]; // 赞助者列表(可选) showSponsorsList?: boolean; // 是否显示赞助者列表,默认 true showButtonInPost?: boolean; // 是否在文章详情页底部显示赞助按钮,默认 true }; // 响应式图像布局类型 export type ResponsiveImageLayout = "constrained" | "full-width" | "none"; // 图像格式类型 export type ImageFormat = "avif" | "webp" | "png" | "jpg" | "jpeg" | "gif";