diff --git a/README.md b/README.md
index 0958b75..5bf181c 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
## 📌 项目地址 & 使用教程
🔗 **GitHub**:[lsy2246/newechoes](https://github.com/lsy2246/newechoes)
-📖 **使用教程**:[点击查看](https://blog.lsy22.com/articles/web/echoes%E5%8D%9A%E5%AE%A2%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E)
+📖 **使用教程**:[点击查看](https://blog.lsy22.com/articles/技术日志/web/echoes博客使用说明)
---
@@ -24,29 +24,3 @@
|----------|----------------|
| 🇨🇳 国内访问 | [blog.lsy22.com](https://blog.lsy22.com/) |
| 🌍 国外访问 | [vercel.blog.lsy22.com](https://vercel.blog.lsy22.com/) |
-
----
-
-## 📸 界面预览
-
-### 🔹 文章管理
-
-
-
-### 🔹 文章界面
-
-
-
-### 🔹 项目
-
-
-
-### 🔹 观影记录
-
-
-
-### 🔹 旅行足迹
-
-
-
----
diff --git a/astro.config.mjs b/astro.config.mjs
index dc39a29..c6307ec 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -13,9 +13,7 @@ import swup from "@swup/astro"
import { SITE_URL } from "./src/consts";
import pagefind from "astro-pagefind";
import compressor from "astro-compressor";
-
import vercel from "@astrojs/vercel";
-
import expressiveCode from "astro-expressive-code";
import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
import { pluginCollapsibleSections } from "@expressive-code/plugin-collapsible-sections";
@@ -69,6 +67,9 @@ export default defineConfig({
defaultProps: {
showLineNumbers: true,
collapseStyle: 'collapsible-auto',
+ wrap: true,
+ preserveIndent: true,
+ hangingIndent: 2,
},
frames: {
extractFileNameFromCode: true,
diff --git a/package-lock.json b/package-lock.json
index 314fe9f..a6a6a29 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,6 @@
"astro": "^5.7.4",
"astro-expressive-code": "^0.41.2",
"astro-pagefind": "^1.8.3",
- "astro-theme-toggle": "^0.6.0",
"cheerio": "^1.0.0",
"node-fetch": "^3.3.2",
"octokit": "^3.2.1",
@@ -5097,15 +5096,6 @@
"astro": "^2.0.4 || ^3 || ^4 || ^5"
}
},
- "node_modules/astro-theme-toggle": {
- "version": "0.6.0",
- "resolved": "https://registry.npmmirror.com/astro-theme-toggle/-/astro-theme-toggle-0.6.0.tgz",
- "integrity": "sha512-Pe2DTeckxJaspMXNWbHzhn3fQq6K4JTEZ/Gutehgty6qzfLWehsGPFtsKOhsS0r2EOK18MaUnONliE5+sDBLYw==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ocavue"
- }
- },
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmmirror.com/async/-/async-3.2.6.tgz",
@@ -6040,6 +6030,15 @@
"node": ">=10"
}
},
+ "node_modules/cosmiconfig/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/cross-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/cross-fetch/-/cross-fetch-3.2.0.tgz",
@@ -6249,6 +6248,15 @@
"postcss": "^8.2.15"
}
},
+ "node_modules/cssnano/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/csso": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/csso/-/csso-4.2.0.tgz",
@@ -11904,6 +11912,15 @@
}
}
},
+ "node_modules/postcss-load-config/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/postcss-merge-longhand": {
"version": "5.1.7",
"resolved": "https://registry.npmmirror.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz",
@@ -15575,12 +15592,17 @@
"license": "ISC"
},
"node_modules/yaml": {
- "version": "1.10.2",
- "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "version": "2.7.1",
+ "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.7.1.tgz",
+ "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==",
"license": "ISC",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/yargs": {
diff --git a/package.json b/package.json
index 6fabcb2..520b53d 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,6 @@
"astro": "^5.7.4",
"astro-expressive-code": "^0.41.2",
"astro-pagefind": "^1.8.3",
- "astro-theme-toggle": "^0.6.0",
"cheerio": "^1.0.0",
"node-fetch": "^3.3.2",
"octokit": "^3.2.1",
diff --git a/src/components/Header.astro b/src/components/Header.astro
index 92113d6..192c7ec 100644
--- a/src/components/Header.astro
+++ b/src/components/Header.astro
@@ -1,7 +1,7 @@
---
import { SITE_NAME, NAV_LINKS } from "@/consts.ts";
-import { Toggle } from "astro-theme-toggle";
import Search from "astro-pagefind/components/Search";
+import ThemeToggle from "@/components/ThemeToggle.astro";
// 获取当前路径
const currentPath = Astro.url.pathname;
@@ -76,39 +76,9 @@ const normalizedPath =
))
}
-
-
-
-
-
-
-
-
-
+
+
+
@@ -245,36 +215,11 @@ const normalizedPath =
-
-
-
-
-
-
-
-
+
@@ -439,23 +384,29 @@ const normalizedPath =
// 清空桌面搜索框的函数
function clearDesktopSearch(): void {
// 获取关键元素
- const searchInput = document.querySelector('.pagefind-ui__search-input');
- const clearButton = document.querySelector('.pagefind-ui__search-clear');
- const resultsContainer = document.querySelector('.pagefind-ui__results');
-
+ const searchInput = document.querySelector(
+ ".pagefind-ui__search-input",
+ );
+ const clearButton = document.querySelector(
+ ".pagefind-ui__search-clear",
+ );
+ const resultsContainer = document.querySelector(
+ ".pagefind-ui__results",
+ );
+
// 隐藏搜索结果面板
if (resultsContainer) {
// 直接隐藏结果容器
- resultsContainer.setAttribute('style', 'display: none !important');
+ resultsContainer.setAttribute("style", "display: none !important");
}
-
+
// 如果有清除按钮,点击它清空输入框
if (clearButton) {
(clearButton as HTMLElement).click();
} else if (searchInput) {
// 备选方案,设置输入框为空
- (searchInput as HTMLInputElement).value = '';
- searchInput.dispatchEvent(new Event('input', { bubbles: true }));
+ (searchInput as HTMLInputElement).value = "";
+ searchInput.dispatchEvent(new Event("input", { bubbles: true }));
}
}
@@ -508,7 +459,7 @@ const normalizedPath =
if (isSearchResult && isSearchResult.tagName === "A") {
// 不做任何处理,避免干扰导航
// 让路由变化后的处理函数来隐藏搜索面板
-
+
// 只关闭移动端搜索面板,因为它不影响导航
closeMobileSearch();
}
@@ -653,70 +604,46 @@ const normalizedPath =
// 初始化搜索功能
initSearch();
- // 处理移动端主题切换容器
- const themeToggleContainer = document.getElementById(
- "theme-toggle-container",
- );
- if (themeToggleContainer) {
- (themeToggleContainer as HTMLElement).style.pointerEvents = "auto";
- addListener(
- themeToggleContainer,
- "click",
- (e: Event) => {
- const target = e.target as HTMLElement;
- if (
- target.tagName !== "ASTRO-THEME-TOGGLE" &&
- !target.closest("astro-theme-toggle")
- ) {
- e.stopPropagation();
- const toggleButton =
- themeToggleContainer.querySelector("astro-theme-toggle");
- if (toggleButton) {
- (toggleButton as HTMLElement).click();
- }
- }
- },
- { capture: true },
- );
- }
-
// 路由变化时处理
const routeEvents = [
- "astro:page-load", // Astro路由导航完成
- "astro:after-swap" // Astro视图变化后
+ "astro:page-load", // Astro路由导航完成
+ "astro:after-swap", // Astro视图变化后
];
-
- routeEvents.forEach(eventName => {
+
+ routeEvents.forEach((eventName) => {
addListener(document, eventName, () => {
// 页面加载后清空搜索框和隐藏结果面板
clearDesktopSearch();
closeMobileSearch();
});
});
-
+
// 直接监听popstate和pushstate事件
addListener(window, "popstate", () => {
clearDesktopSearch();
closeMobileSearch();
});
-
+
// 添加自定义监听处理history API
const originalPushState = history.pushState;
- history.pushState = function(...args) {
+ history.pushState = function (...args) {
// 调用原始方法
- const result = originalPushState.apply(this, args as [any, string, string | URL | null]);
-
+ const result = originalPushState.apply(
+ this,
+ args as [any, string, string | URL | null],
+ );
+
// 触发自定义事件
const event = new Event("pushstate");
window.dispatchEvent(event);
-
+
// 在pushstate时清空搜索面板
clearDesktopSearch();
closeMobileSearch();
-
+
return result;
};
-
+
addListener(window, "pushstate", () => {
clearDesktopSearch();
closeMobileSearch();
diff --git a/src/components/Layout.astro b/src/components/Layout.astro
index 9feff2b..0d7ec2a 100644
--- a/src/components/Layout.astro
+++ b/src/components/Layout.astro
@@ -2,105 +2,190 @@
import "@/styles/global.css";
import Header from "@/components/Header.astro";
import Footer from "@/components/Footer.astro";
-import { ICP, PSB_ICP, PSB_ICP_URL, SITE_NAME, SITE_DESCRIPTION } from "@/consts";
-import { ThemeScript } from 'astro-theme-toggle';
-import { AstroSeo } from '@astrolib/seo';
+import {
+ ICP,
+ PSB_ICP,
+ PSB_ICP_URL,
+ SITE_NAME,
+ SITE_DESCRIPTION,
+} from "@/consts";
+import { AstroSeo } from "@astrolib/seo";
// 定义Props接口
interface Props {
- title?: string;
- description?: string;
- date?: Date;
- tags?: string[];
+ title?: string;
+ description?: string;
+ date?: Date;
+ tags?: string[];
}
// 获取完整的 URL
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
// 从props中获取页面特定信息
-const { title = SITE_NAME, description = SITE_DESCRIPTION, date, tags } = Astro.props;
+const {
+ title = SITE_NAME,
+ description = SITE_DESCRIPTION,
+ date,
+ tags,
+} = Astro.props;
---
+
-
-
-
-
-
-
-
-
-
- ({
- property: 'article:tag',
- content: tag,
- })) || []),
- ]}
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+ ({
+ property: "article:tag",
+ content: tag,
+ })) || []),
+ ]}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro
new file mode 100644
index 0000000..9822ebb
--- /dev/null
+++ b/src/components/ThemeToggle.astro
@@ -0,0 +1,949 @@
+---
+interface Props {
+ height?: number;
+ width?: number;
+ fill?: string;
+ className?: string;
+ // 更新主题过渡动画模式配置
+ transitionMode?: "expand" | "shrink" | "auto" | "reverse-auto";
+}
+
+const {
+ height = 16,
+ width = 16,
+ fill = "currentColor",
+ className = "",
+ transitionMode = "auto", // 默认为自动模式
+} = Astro.props;
+
+---
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/content/理解计算机/Web/MDX使用教程.mdx b/src/content/理解计算机/Web/MDX使用教程.mdx
index a996c2d..b500ab2 100644
--- a/src/content/理解计算机/Web/MDX使用教程.mdx
+++ b/src/content/理解计算机/Web/MDX使用教程.mdx
@@ -131,6 +131,8 @@ function greet(user: User): string {
```
````
+
+
```typescript
interface User {
id: number;
@@ -199,6 +201,8 @@ function greet(user: User): string {
---
```
+
+
---
### 1.9 表情符号
diff --git a/src/pages/404.astro b/src/pages/404.astro
index 9bfc081..2687175 100644
--- a/src/pages/404.astro
+++ b/src/pages/404.astro
@@ -7,7 +7,7 @@ export const prerender = true;
---
-
+
diff --git a/src/pages/articles/index.astro b/src/pages/articles/index.astro
index 76235f2..7738cdd 100644
--- a/src/pages/articles/index.astro
+++ b/src/pages/articles/index.astro
@@ -69,7 +69,7 @@ const pageTitle = currentPath ? currentPath : '文章列表';
---
-
+
diff --git a/src/pages/books.astro b/src/pages/books.astro
index e22f637..8763fc6 100644
--- a/src/pages/books.astro
+++ b/src/pages/books.astro
@@ -1,14 +1,15 @@
---
-import Layout from '@/components/Layout.astro';
-import MediaGrid from '@/components/MediaGrid.tsx';
-import { SITE_NAME, DOUBAN_ID } from '@/consts';
+import Layout from "@/components/Layout.astro";
+import MediaGrid from "@/components/MediaGrid.tsx";
+import { DOUBAN_ID } from "@/consts";
---
-
-
+
-
\ No newline at end of file
+
+
diff --git a/src/pages/filtered/index.astro b/src/pages/filtered/index.astro
index 5033629..12819cb 100644
--- a/src/pages/filtered/index.astro
+++ b/src/pages/filtered/index.astro
@@ -28,7 +28,7 @@ function getArticleUrl(articleId: string) {
}
---
-
+
@@ -66,7 +66,7 @@ function getArticleUrl(articleId: string) {
-
+