minearm-website 0.0.3-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/astro.config.ts +33 -0
  4. package/minearm.ts +174 -0
  5. package/package.json +64 -0
  6. package/public/13.jpg +0 -0
  7. package/public/1937daxue.png +0 -0
  8. package/public/3.png +0 -0
  9. package/public/404.png +0 -0
  10. package/public/5.jpg +0 -0
  11. package/public/BC.png +0 -0
  12. package/public/Chinese.png +0 -0
  13. package/public/avatar.avif +0 -0
  14. package/public/avatar.jpg +0 -0
  15. package/public/c++1.png +0 -0
  16. package/public/docker-hub.png +0 -0
  17. package/public/favicon.png +0 -0
  18. package/public/help1.png +0 -0
  19. package/public/heroimg.jpg +0 -0
  20. package/public/logo.png +0 -0
  21. package/public/mail.png +0 -0
  22. package/public/nahida.png +0 -0
  23. package/public/pojipao.avif +0 -0
  24. package/public/rust1.png +0 -0
  25. package/public/scripts/mdata.json +4 -0
  26. package/public/scripts/utils.js +190 -0
  27. package/public/xmrig.jpg +0 -0
  28. package/src/components/BodyInject.astro +5 -0
  29. package/src/components/HeadInject.astro +16 -0
  30. package/src/components/Search.astro +30 -0
  31. package/src/components/animation/bubbles.astro +82 -0
  32. package/src/components/animation/wave.astro +81 -0
  33. package/src/components/aside/announcement.astro +25 -0
  34. package/src/components/aside/aside.astro +32 -0
  35. package/src/components/aside/asideComps.astro +26 -0
  36. package/src/components/aside/authorInfo.astro +54 -0
  37. package/src/components/aside/blogToc.astro +26 -0
  38. package/src/components/aside/countScript.astro +18 -0
  39. package/src/components/aside/customCard.astro +23 -0
  40. package/src/components/aside/siteInfo.astro +51 -0
  41. package/src/components/client/searchCore.vue +77 -0
  42. package/src/components/client/themeControl.vue +77 -0
  43. package/src/components/footer/Footer.astro +32 -0
  44. package/src/components/header/Header.astro +40 -0
  45. package/src/components/header/HeaderButton.astro +59 -0
  46. package/src/components/header/HeaderItem.astro +63 -0
  47. package/src/components/header/heroWave.astro +19 -0
  48. package/src/components/header/searchBar.astro +21 -0
  49. package/src/components/icons/bilibili.astro +10 -0
  50. package/src/components/icons/c.astro +10 -0
  51. package/src/components/icons/code.astro +37 -0
  52. package/src/components/icons/computer.astro +4 -0
  53. package/src/components/icons/cube.astro +10 -0
  54. package/src/components/icons/game.astro +10 -0
  55. package/src/components/icons/getIcon.astro +64 -0
  56. package/src/components/icons/github.astro +10 -0
  57. package/src/components/icons/hardDriver.astro +10 -0
  58. package/src/components/icons/home.astro +14 -0
  59. package/src/components/icons/icon.ts +33 -0
  60. package/src/components/icons/icons.json +91961 -0
  61. package/src/components/icons/link.astro +4 -0
  62. package/src/components/icons/mail.astro +10 -0
  63. package/src/components/icons/paperPlane.astro +4 -0
  64. package/src/components/icons/pen.astro +14 -0
  65. package/src/components/icons/person.astro +14 -0
  66. package/src/components/icons/searchicon.astro +23 -0
  67. package/src/components/icons/tags.astro +10 -0
  68. package/src/components/icons/toTop.astro +10 -0
  69. package/src/components/icons/tools.astro +1 -0
  70. package/src/components/loading/loading.vue +185 -0
  71. package/src/components/postComment.astro +62 -0
  72. package/src/components/postlist/pagination.astro +40 -0
  73. package/src/components/postlist/postsList.astro +57 -0
  74. package/src/content/blog/default/Extended Search.md +50 -0
  75. package/src/content/blog/default/Mail.md +15 -0
  76. package/src/content/blog/default/history//345/205/254/345/205/203/345/211/215//347/247/246/345/247/213/347/232/207/347/273/237/344/270/200/345/205/255/345/233/275.md +40 -0
  77. package/src/content/blog/default/history//350/277/221/344/273/243/347/257/207//344/270/255/345/233/275/345/205/261/344/272/247/345/205/232/345/205/232/345/217/262.md +2361 -0
  78. package/src/content/blog/default/it/Rust/345/237/272/346/234/254/350/257/255/346/263/225.md +298 -0
  79. package/src/content/config.ts +38 -0
  80. package/src/env.d.ts +148 -0
  81. package/src/layouts/BaseLayout.astro +67 -0
  82. package/src/layouts/DefaultMdLayout.astro +46 -0
  83. package/src/layouts/HomeLayout.astro +27 -0
  84. package/src/layouts/PostLayout.astro +60 -0
  85. package/src/layouts/TagsLayout.astro +44 -0
  86. package/src/layouts/c.astro +42 -0
  87. package/src/layouts/h.astro +60 -0
  88. package/src/pages/404.md +10 -0
  89. package/src/pages/[...page].astro +46 -0
  90. package/src/pages/about/index.md +90 -0
  91. package/src/pages/blog/[...slug].astro +68 -0
  92. package/src/pages/categories/[category]/[...page].astro +45 -0
  93. package/src/pages/categories/index.astro +20 -0
  94. package/src/pages/friends/index.md +24 -0
  95. package/src/pages/rss.xml.js +20 -0
  96. package/src/pages/tags/[tag]/[...page].astro +42 -0
  97. package/src/pages/tags/index.astro +19 -0
  98. package/src/site_config.ts +15 -0
  99. package/src/styles/animation.scss +94 -0
  100. package/src/styles/blog/blog.scss +124 -0
  101. package/src/styles/blog/code.scss +111 -0
  102. package/src/styles/blog/directives.scss +356 -0
  103. package/src/styles/blog/index.scss +4 -0
  104. package/src/styles/blog/post.scss +474 -0
  105. package/src/styles/components/aside.scss +178 -0
  106. package/src/styles/components/footer.scss +74 -0
  107. package/src/styles/components/header.scss +421 -0
  108. package/src/styles/components/heroWave.scss +24 -0
  109. package/src/styles/components/main.scss +275 -0
  110. package/src/styles/components/page-content.scss +147 -0
  111. package/src/styles/components/pagination.scss +121 -0
  112. package/src/styles/components/search.scss +349 -0
  113. package/src/styles/custom.scss +21 -0
  114. package/src/styles/global.scss +167 -0
  115. package/src/styles/mixin.scss +17 -0
  116. package/src/styles/tags/tags.scss +83 -0
  117. package/src/theme_config.ts +178 -0
  118. package/src/utils/generateSearchData.ts +30 -0
  119. package/src/utils/md.ts +114 -0
  120. package/src/utils/processMd.ts +278 -0
  121. package/src/utils/utils.ts +87 -0
  122. package/tsconfig.json +32 -0
  123. package/vercel.json +26 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 KraHsu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Minearm & Website
2
+ # 本主题是从HusBlog改进而来的
3
+ url: https://github.com/KraHsu/HsuBlog.git
4
+
5
+
6
+ # 文件结构
7
+
8
+ ```bash
9
+ root
10
+ ├─public
11
+ │ └─scripts
12
+ └─src
13
+ ├─components
14
+ │ ├─animation
15
+ │ ├─aside
16
+ │ ├─client
17
+ │ ├─footer
18
+ │ ├─header
19
+ │ ├─icons
20
+ │ ├─loading
21
+ │ └─postlist
22
+ ├─content
23
+ │ └─blog
24
+ │ └─default
25
+ ├─layouts
26
+ ├─pages
27
+ │ ├─about
28
+ │ ├─blog
29
+ │ ├─categories
30
+ │ │ └─[category]
31
+ │ ├─friends
32
+ │ └─tags
33
+ │ └─[tag]
34
+ ├─styles
35
+ │ ├─blog
36
+ │ │ └─dist
37
+ │ ├─components
38
+ │ │ └─dist
39
+ │ ├─dist
40
+ │ └─tags
41
+ └─utils
42
+ ```
43
+
44
+ ~~~
45
+ # 安装依赖
46
+ npm install
47
+ # 更新
48
+ npm update
49
+ ~~~
50
+
51
+ ~~~
52
+ # 启动开发预览
53
+ npm run dev
54
+ ~~~
55
+
56
+ ~~~
57
+ # 构建和预览
58
+ npm run build
59
+ npm run preview
60
+ ~~~
61
+
62
+ # 许可证
63
+ 本项目在MIT许可证下授权,版权所有©2024
64
+
65
+ 由Minearm-RPM构建的
66
+
67
+ # 转载时需标明出处!。
@@ -0,0 +1,33 @@
1
+ import { defineConfig } from "astro/config";
2
+ import sitemap from "@astrojs/sitemap";
3
+ import { markdownDirectives, remarkFrontmatter, rehypeFrontmatter, remarkRestyling, rehypeRestyling } from "./src/utils/md";
4
+ import remarkGfm from "remark-gfm";
5
+ import remarkMath from "remark-math";
6
+ import rehypeKatex from "rehype-katex";
7
+ import rehypeMathjax from "rehype-mathjax";
8
+ import remarkDirective from "remark-directive";
9
+ import vue from "@astrojs/vue";
10
+ import { SiteConfig } from "./src/site_config";
11
+ import { generateSearchData } from "./src/utils/generateSearchData.ts";
12
+ const remarkPlugins: any = [remarkFrontmatter, remarkGfm, SiteConfig.markdownMath !== false && remarkMath, remarkRestyling, remarkDirective, markdownDirectives, SiteConfig.localSearch && generateSearchData].filter(Boolean);
13
+ const rehypePlugins: any = [rehypeFrontmatter, rehypeRestyling, SiteConfig.markdownMath === "Katex" && rehypeKatex, SiteConfig.markdownMath === "Mathjax" && rehypeMathjax].filter(Boolean);
14
+ // https://astro.build/config
15
+ export default defineConfig({
16
+ site: SiteConfig.site,
17
+ integrations: [sitemap(), vue()],
18
+ output: "static",
19
+ build: {
20
+ format: "directory"
21
+ },
22
+ markdown: {
23
+ syntaxHighlight: "shiki",
24
+ shikiConfig: {
25
+ theme: "css-variables",
26
+ langs: [],
27
+ wrap: false
28
+ },
29
+ remarkPlugins: remarkPlugins,
30
+ rehypePlugins: rehypePlugins
31
+ },
32
+ trailingSlash: "ignore"
33
+ });
package/minearm.ts ADDED
@@ -0,0 +1,174 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import matter from "gray-matter";
4
+ import yargs from "yargs";
5
+ import { hideBin } from "yargs/helpers";
6
+ import { promisify } from "util";
7
+ import { glob } from "glob";
8
+ import { utils } from "./src/utils/utils.js";
9
+
10
+ interface Argv {
11
+ _: string[];
12
+ filename?: string;
13
+ $0: string;
14
+ }
15
+
16
+ const readFileAsync = promisify(fs.readFile);
17
+ const writeFileAsync = promisify(fs.writeFile);
18
+ const mkdirAsync = promisify(fs.mkdir);
19
+
20
+ const getDateString = () => {
21
+ const date = new Date();
22
+ const monthNames = [
23
+ "Jan",
24
+ "Feb",
25
+ "Mar",
26
+ "Apr",
27
+ "May",
28
+ "Jun",
29
+ "Jul",
30
+ "Aug",
31
+ "Sep",
32
+ "Oct",
33
+ "Nov",
34
+ "Dec",
35
+ ];
36
+ const month = monthNames[date.getMonth()];
37
+ const day = date.getDate().toString().padStart(2, "0");
38
+ const year = date.getFullYear();
39
+
40
+ return `${month} ${day} ${year}`;
41
+ };
42
+
43
+ const getHexTimestamp = () => {
44
+ const timestamp = Date.now();
45
+ const hexTimestamp = timestamp.toString(36);
46
+
47
+ return hexTimestamp;
48
+ };
49
+
50
+ const createFile = async (
51
+ filePath: string,
52
+ dirPath: string,
53
+ content: string
54
+ ) => {
55
+ // Get all directories from dirPath
56
+ const directories = dirPath.split(path.sep);
57
+
58
+ // Make sure all directories exist, create them if necessary
59
+ for (let i = 1; i <= directories.length; i++) {
60
+ const segment = directories.slice(0, i).join(path.sep);
61
+ if (!fs.existsSync(segment)) {
62
+ await mkdirAsync(segment);
63
+ }
64
+ }
65
+
66
+ if (fs.existsSync(filePath)) {
67
+ console.error(`File ${filePath} already exists.`);
68
+ process.exit(1);
69
+ }
70
+
71
+ await writeFileAsync(filePath, content);
72
+ console.log(`File created: ${filePath}`);
73
+ };
74
+
75
+ const createMdFile = async (filename: string) => {
76
+ const dateStr = getDateString();
77
+ const hexTimestamp = getHexTimestamp();
78
+
79
+ // split filename into path and actual filename
80
+ const filenameParts = filename.split("/");
81
+ const actualFilename = filenameParts.pop();
82
+
83
+ // create the full directory path
84
+ const dirPath = path.resolve(`./src/content/blog/`, ...filenameParts);
85
+ const filePath = path.resolve(dirPath, `${actualFilename}.md`);
86
+
87
+ const content = `---
88
+ title: ${actualFilename}
89
+ description: ''
90
+ pubDate: ${dateStr}
91
+ updatedDate: ${dateStr}
92
+ heroColor: ''
93
+ abbrlink: ${hexTimestamp}
94
+ tags:
95
+ - ''
96
+ category: ''
97
+ ---`;
98
+
99
+ await createFile(filePath, dirPath, content);
100
+ };
101
+
102
+ const createMdPage = async (filename: string) => {
103
+ const dirPath = path.resolve(`./src/pages/${filename}`);
104
+ const filePath = path.resolve(dirPath, "index.md");
105
+
106
+ const content = `---
107
+ layout: "../../layouts/DefaultMdLayout.astro"
108
+ title: ${filename}
109
+ description: ""
110
+ heroColor: "#007aff"
111
+ useComments: true
112
+ useToc: true
113
+ ---
114
+
115
+ ## ${filename}`;
116
+
117
+ await createFile(filePath, dirPath, content);
118
+ };
119
+
120
+ const addAbbrlinkToFile = async (filepath: string) => {
121
+ try {
122
+ const content = await readFileAsync(filepath, "utf8");
123
+ const parsedMatter = matter(content);
124
+
125
+ if (!parsedMatter.data.abbrlink) {
126
+ const pubDateStr = parsedMatter.data.pubDate;
127
+ const pubDate = new Date(pubDateStr);
128
+ const abbrlink = pubDate.getTime().toString(36);
129
+
130
+ parsedMatter.data.abbrlink = abbrlink;
131
+
132
+ const fileContent = matter.stringify(content, parsedMatter.data);
133
+ await writeFileAsync(filepath, fileContent);
134
+ console.log(`Permalink added: ${filepath}`);
135
+ }
136
+ } catch (error) {
137
+ console.error(`Unable to add link: ${filepath}`);
138
+ console.error(error);
139
+ }
140
+ };
141
+
142
+ const addAbbrlinkToFiles = async () => {
143
+ try {
144
+ const files = await glob("./src/content/blog/**/*.md");
145
+ for (const file of files) {
146
+ await addAbbrlinkToFile(file);
147
+ }
148
+ } catch (error) {
149
+ console.error(error);
150
+ }
151
+ };
152
+
153
+ const argv = yargs(hideBin(process.argv))
154
+ .command("new <filename>", "Create a new post with the title <filename>")
155
+ .command("abbr", "Add a permalink to markdown files")
156
+ .command("newPage <filename>", "Create a new page with the title <filename>")
157
+ .help()
158
+ .alias("help", "h").argv as Argv;
159
+
160
+ if (argv._[0] === "new") {
161
+ if (argv.filename) {
162
+ createMdFile(argv.filename);
163
+ } else {
164
+ console.error('Filename is required for the "new" command');
165
+ }
166
+ } else if (argv._[0] === "abbr") {
167
+ addAbbrlinkToFiles();
168
+ } else if (argv._[0] === "newPage") {
169
+ if (argv.filename) {
170
+ createMdPage(argv.filename);
171
+ } else {
172
+ console.error('Filename is required for the "newPage" command');
173
+ }
174
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "minearm-website",
3
+ "description": "Welcome to Minearm & Website.",
4
+ "version": "0.0.3-beta.2",
5
+ "homepage": "https://github.com/Minearm-RPM/minearm",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "scripts": {
9
+ "dev": "astro dev",
10
+ "start": "astro dev",
11
+ "build": "astro build",
12
+ "preview": "astro preview",
13
+ "astro": "astro",
14
+ "new": "ts-node ./minearm.ts new",
15
+ "abbr": "ts-node ./minearm.ts abbr",
16
+ "newpage": "ts-node ./minearm.ts newPage",
17
+ "help": "ts-node ./minearm.ts help",
18
+ "pu": "ts-node ./pu.ts"
19
+ },
20
+ "dependencies": {
21
+ "@astrojs/markdown-remark": "^5.3.0",
22
+ "@astrojs/mdx": "^3.1.9",
23
+ "@astrojs/rss": "^4.0.9",
24
+ "@duannx/vue-client-only": "^1.0.3",
25
+ "@fortawesome/fontawesome-svg-core": "^6.4.0",
26
+ "@fortawesome/free-solid-svg-icons": "^6.4.0",
27
+ "@iconify-json/tabler": "^1.2.8",
28
+ "astro": "^4.16.13",
29
+ "astro-i18next": "^1.0.0-beta.21",
30
+ "astro-icon": "^1.1.2",
31
+ "fuse.js": "^6.6.2",
32
+ "glob": "^10.3.3",
33
+ "hastscript": "^7.2.0",
34
+ "html-loader": "^0.5.5",
35
+ "markdown-loader": "^8.0.0",
36
+ "marked": "^15.0.0",
37
+ "mdast-util-to-string": "^4.0.0",
38
+ "pnpm": "^9.13.2",
39
+ "reading-time": "^1.5.0",
40
+ "rehype-katex": "7.0.1",
41
+ "rehype-mathjax": "6.0.0",
42
+ "remark-directive": "3.0.0",
43
+ "remark-gfm": "4.0.0",
44
+ "remark-math": "6.0.0",
45
+ "showdown": "^2.1.0",
46
+ "yargs": "^17.7.2"
47
+ },
48
+ "devDependencies": {
49
+ "@astrojs/sitemap": "^3.2.1",
50
+ "@astrojs/vue": "^4.5.2",
51
+ "@types/yargs": "^17.0.24",
52
+ "sass": "1.70.0",
53
+ "scss": "^0.2.4",
54
+ "ts-node": "10.9.2",
55
+ "vue": "3.5.0"
56
+ },
57
+ "keywords": [
58
+ "astro-component",
59
+ "withastro"
60
+ ],
61
+ "main": "index.js",
62
+ "author": "",
63
+ "license": "ISC"
64
+ }
package/public/13.jpg ADDED
Binary file
Binary file
package/public/3.png ADDED
Binary file
package/public/404.png ADDED
Binary file
package/public/5.jpg ADDED
Binary file
package/public/BC.png ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ {
2
+ "totalWordCounts": 116400,
3
+ "totalPostCounts": 11
4
+ }
@@ -0,0 +1,190 @@
1
+ const hsu = {
2
+ calculateScrollPercentage: () => {
3
+ // 获取当前页面滚动的高度
4
+ let scrollPosition = document.documentElement.scrollTop || window.scrollY;
5
+
6
+ // 获取页面的总高度
7
+ let totalHeight = Math.max(
8
+ document.body.scrollHeight,
9
+ document.documentElement.scrollHeight,
10
+ document.body.offsetHeight,
11
+ document.documentElement.offsetHeight,
12
+ document.body.clientHeight,
13
+ document.documentElement.clientHeight
14
+ ) - document.documentElement.clientHeight;
15
+
16
+ // 计算滚动百分比并四舍五入
17
+ let scrollPercentage = Math.round(scrollPosition / totalHeight * 100);
18
+
19
+ // 获取用于显示百分比的元素
20
+ let percentDisplayElement = document.getElementById("percent");
21
+
22
+ // 计算可见窗口的底部位置
23
+ var visibleWindowBottomPosition = window.scrollY + document.documentElement.clientHeight;
24
+
25
+ // 获取网站底部元素
26
+ let siteFooterElement = document.getElementById("site-footer");
27
+
28
+ // 判断页面是否滚动到了网站的底部,或者滚动百分比是否超过了95%
29
+ if (siteFooterElement.offsetTop + siteFooterElement.offsetHeight / 2 < visibleWindowBottomPosition || scrollPercentage > 95) {
30
+ document.getElementById("menu-totop").classList.add("tobottom");
31
+ } else {
32
+ document.getElementById("menu-totop").classList.remove("tobottom");
33
+
34
+ // 如果滚动百分比是有效的,更新显示的百分比
35
+ if (scrollPercentage >= 0) {
36
+ percentDisplayElement.innerHTML = scrollPercentage;
37
+ }
38
+ }
39
+
40
+ // 判断页面是否在顶部,更改 header 的 class
41
+ let header = document.getElementById("site-header");
42
+ scrollPercentage > 0 ? header.classList.add("not-top") : header.classList.remove("not-top");
43
+ },
44
+ scrollToDestination: (destination, duration) => {
45
+ // 初始值检查,如果e或t小于0,直接返回
46
+ if (destination < 0 || duration < 0) {
47
+ return;
48
+ }
49
+
50
+ // 获取当前窗口滚动的垂直位置
51
+ const currentPos = window.scrollY || window.screenTop;
52
+
53
+ // 让目标位置上方空出70px的位置
54
+ destination -= 70;
55
+
56
+ // 检查浏览器是否支持CSS的平滑滚动
57
+ if ("CSS" in window && CSS.supports("scroll-behavior", "smooth")) {
58
+ // 如果支持,使用CSS的平滑滚动
59
+ window.scrollTo({
60
+ top: destination,
61
+ behavior: "smooth"
62
+ });
63
+ return;
64
+ }
65
+
66
+ // 如果不支持CSS的平滑滚动,使用JavaScript实现
67
+ let startTime = null;
68
+ duration = duration || 500; // 默认持续时间为500ms
69
+
70
+ window.requestAnimationFrame(function scrollSmoothly(currentTime) {
71
+ startTime = startTime || currentTime;
72
+
73
+ if (currentPos < destination) {
74
+ const timeElapsed = currentTime - startTime;
75
+ window.scrollTo(0, (destination - currentPos) * timeElapsed / duration + currentPos);
76
+
77
+ // 检查是否已经滚动到目标位置,如果没有,继续请求动画帧
78
+ if (timeElapsed < duration) {
79
+ window.requestAnimationFrame(scrollSmoothly);
80
+ } else {
81
+ window.scrollTo(0, destination);
82
+ }
83
+ } else {
84
+ const timeElapsed = currentTime - startTime;
85
+ window.scrollTo(0, currentPos - (currentPos - destination) * timeElapsed / duration);
86
+
87
+ // 检查是否已经滚动到目标位置,如果没有,继续请求动画帧
88
+ if (timeElapsed < duration) {
89
+ window.requestAnimationFrame(scrollSmoothly);
90
+ } else {
91
+ window.scrollTo(0, destination);
92
+ }
93
+ }
94
+ });
95
+ },
96
+ goToUrl: (url) => {
97
+ window.location.href = url;
98
+ },
99
+ copyCode: function (event) {
100
+ // 使用事件对象找到被点击的code-copy元素的父code-block
101
+ const codeBlock = event.target.closest('.code-block');
102
+
103
+ // 获取该code-block内的code标签的文本内容
104
+ const codeContent = codeBlock.querySelector(".astro-code").textContent;
105
+
106
+ // 复制到剪贴板
107
+ navigator.clipboard.writeText(codeContent).then(function () {
108
+ // 成功复制后的操作
109
+ console.log("代码已成功复制到剪贴板!");
110
+ }).catch(function (err) {
111
+ // 如果出现错误,例如用户没有授予剪贴板权限
112
+ console.error("无法复制代码:", err);
113
+ });
114
+ },
115
+ anchorScroll: function (event) {
116
+ // 获取目标元素
117
+ var target = document.querySelector(this.getAttribute('href'));
118
+
119
+ if (target) {
120
+ event.preventDefault();
121
+
122
+ // 为 target 元素添加 'target-to' 类
123
+ if (target.classList.contains('target-to')) {
124
+ return
125
+ }
126
+ target.classList.add('target-to');
127
+
128
+ // 两秒后移除 'target-to' 类
129
+ setTimeout(function () {
130
+ target.classList.remove('target-to');
131
+ }, 1510);
132
+
133
+ // 计算距离,考虑额外的偏移量
134
+ // 4rem 需要转化为像素,这里假设 1rem = 16px,所以 4rem = 64px
135
+ var offsetTop = target.getBoundingClientRect().top + window.pageYOffset - 80;
136
+
137
+ window.scrollTo({
138
+ top: offsetTop,
139
+ behavior: "smooth"
140
+ });
141
+ }
142
+ },
143
+ formatNumber: function (num) {
144
+ if (num >= 1000000000) {
145
+ return (num / 1000000000).toFixed(1) + "B";
146
+ }
147
+ if (num >= 1000000) {
148
+ return (num / 1000000).toFixed(1) + "M";
149
+ }
150
+ if (num >= 1000) {
151
+ return (num / 1000).toFixed(1) + "K";
152
+ }
153
+ return num.toString();
154
+ },
155
+ getJson: async function (url) {
156
+ const response = await fetch(url);
157
+ if (!response.ok) {
158
+ throw new Error("HTTP error " + response.status);
159
+ }
160
+ return await response.json();
161
+ },
162
+ opensearch: function () {
163
+ const search = document.getElementById("search")
164
+ // document.dispatchEvent(new Event("opensearch"));
165
+
166
+ search?.classList.remove("hide")
167
+ document.body.style.overflow = "hidden";
168
+
169
+ },
170
+ closesearch: async function () {
171
+ const search = document.getElementById("search")
172
+ // document.dispatchEvent(new Event("closesearch"));
173
+
174
+ search?.classList.add("begin-to-hide");
175
+ await this.sleep(1000)
176
+ search?.classList.remove("begin-to-hide")
177
+ search?.classList.add("hide");
178
+
179
+ document.body.style.overflow = "";
180
+ },
181
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms))
182
+ }
183
+
184
+ document.addEventListener("DOMContentLoaded", function () {
185
+ var links = document.querySelectorAll('a[href^="#"]');
186
+
187
+ for (var i = 0; i < links.length; i++) {
188
+ links[i].addEventListener('click', hsu.anchorScroll)
189
+ }
190
+ });
Binary file
@@ -0,0 +1,5 @@
1
+ ---
2
+ import { ThemeConfig } from "@src/theme_config";
3
+ ---
4
+
5
+ <Fragment></Fragment>
@@ -0,0 +1,16 @@
1
+ ---
2
+ import { ThemeConfig as TC } from "@src/theme_config";
3
+ ---
4
+
5
+ <Fragment>
6
+ <script src="/scripts/utils.js" type="text/javascript"></script>
7
+ {TC.head.map((item) => <Fragment set:html={item} />)}
8
+ {
9
+ TC.aside.siteInfo.busuanzi && (
10
+ <script
11
+ async
12
+ src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"
13
+ />
14
+ )
15
+ }
16
+ </Fragment>
@@ -0,0 +1,30 @@
1
+ ---
2
+ import "@style/components/search.scss";
3
+ import SearchCore from "./client/searchCore.vue";
4
+ import { ThemeConfig } from "@src/theme_config";
5
+ import { utils } from "@src/utils/utils";
6
+
7
+ const hits = ThemeConfig.site.localSearch.hits.map((hit) =>
8
+ utils.replaceLink(hit, "search-hit")
9
+ );
10
+ const comment = utils.replaceLink(
11
+ utils.executeEmbeddedScripts(ThemeConfig.site.localSearch.comment)
12
+ );
13
+ ---
14
+
15
+ <div id="search" class="hide">
16
+ <div class="search-wrap">
17
+ <div class="search-header">
18
+ <div class="search-title">搜索</div>
19
+ <div class="search-close" onclick={"hsu.closesearch()"}>
20
+ <i class="fa-solid fa-xmark"></i>
21
+ </div>
22
+ </div>
23
+ <SearchCore client:only />
24
+ <div class="search-hits">
25
+ {hits.map((hit) => <Fragment set:html={hit} />)}
26
+ </div>
27
+ <div class="search-comment" set:html={comment} />
28
+ </div>
29
+ <div class="search-mask" onclick={"hsu.closesearch()"}></div>
30
+ </div>