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.
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/astro.config.ts +33 -0
- package/minearm.ts +174 -0
- package/package.json +64 -0
- package/public/13.jpg +0 -0
- package/public/1937daxue.png +0 -0
- package/public/3.png +0 -0
- package/public/404.png +0 -0
- package/public/5.jpg +0 -0
- package/public/BC.png +0 -0
- package/public/Chinese.png +0 -0
- package/public/avatar.avif +0 -0
- package/public/avatar.jpg +0 -0
- package/public/c++1.png +0 -0
- package/public/docker-hub.png +0 -0
- package/public/favicon.png +0 -0
- package/public/help1.png +0 -0
- package/public/heroimg.jpg +0 -0
- package/public/logo.png +0 -0
- package/public/mail.png +0 -0
- package/public/nahida.png +0 -0
- package/public/pojipao.avif +0 -0
- package/public/rust1.png +0 -0
- package/public/scripts/mdata.json +4 -0
- package/public/scripts/utils.js +190 -0
- package/public/xmrig.jpg +0 -0
- package/src/components/BodyInject.astro +5 -0
- package/src/components/HeadInject.astro +16 -0
- package/src/components/Search.astro +30 -0
- package/src/components/animation/bubbles.astro +82 -0
- package/src/components/animation/wave.astro +81 -0
- package/src/components/aside/announcement.astro +25 -0
- package/src/components/aside/aside.astro +32 -0
- package/src/components/aside/asideComps.astro +26 -0
- package/src/components/aside/authorInfo.astro +54 -0
- package/src/components/aside/blogToc.astro +26 -0
- package/src/components/aside/countScript.astro +18 -0
- package/src/components/aside/customCard.astro +23 -0
- package/src/components/aside/siteInfo.astro +51 -0
- package/src/components/client/searchCore.vue +77 -0
- package/src/components/client/themeControl.vue +77 -0
- package/src/components/footer/Footer.astro +32 -0
- package/src/components/header/Header.astro +40 -0
- package/src/components/header/HeaderButton.astro +59 -0
- package/src/components/header/HeaderItem.astro +63 -0
- package/src/components/header/heroWave.astro +19 -0
- package/src/components/header/searchBar.astro +21 -0
- package/src/components/icons/bilibili.astro +10 -0
- package/src/components/icons/c.astro +10 -0
- package/src/components/icons/code.astro +37 -0
- package/src/components/icons/computer.astro +4 -0
- package/src/components/icons/cube.astro +10 -0
- package/src/components/icons/game.astro +10 -0
- package/src/components/icons/getIcon.astro +64 -0
- package/src/components/icons/github.astro +10 -0
- package/src/components/icons/hardDriver.astro +10 -0
- package/src/components/icons/home.astro +14 -0
- package/src/components/icons/icon.ts +33 -0
- package/src/components/icons/icons.json +91961 -0
- package/src/components/icons/link.astro +4 -0
- package/src/components/icons/mail.astro +10 -0
- package/src/components/icons/paperPlane.astro +4 -0
- package/src/components/icons/pen.astro +14 -0
- package/src/components/icons/person.astro +14 -0
- package/src/components/icons/searchicon.astro +23 -0
- package/src/components/icons/tags.astro +10 -0
- package/src/components/icons/toTop.astro +10 -0
- package/src/components/icons/tools.astro +1 -0
- package/src/components/loading/loading.vue +185 -0
- package/src/components/postComment.astro +62 -0
- package/src/components/postlist/pagination.astro +40 -0
- package/src/components/postlist/postsList.astro +57 -0
- package/src/content/blog/default/Extended Search.md +50 -0
- package/src/content/blog/default/Mail.md +15 -0
- 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
- 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
- package/src/content/blog/default/it/Rust/345/237/272/346/234/254/350/257/255/346/263/225.md +298 -0
- package/src/content/config.ts +38 -0
- package/src/env.d.ts +148 -0
- package/src/layouts/BaseLayout.astro +67 -0
- package/src/layouts/DefaultMdLayout.astro +46 -0
- package/src/layouts/HomeLayout.astro +27 -0
- package/src/layouts/PostLayout.astro +60 -0
- package/src/layouts/TagsLayout.astro +44 -0
- package/src/layouts/c.astro +42 -0
- package/src/layouts/h.astro +60 -0
- package/src/pages/404.md +10 -0
- package/src/pages/[...page].astro +46 -0
- package/src/pages/about/index.md +90 -0
- package/src/pages/blog/[...slug].astro +68 -0
- package/src/pages/categories/[category]/[...page].astro +45 -0
- package/src/pages/categories/index.astro +20 -0
- package/src/pages/friends/index.md +24 -0
- package/src/pages/rss.xml.js +20 -0
- package/src/pages/tags/[tag]/[...page].astro +42 -0
- package/src/pages/tags/index.astro +19 -0
- package/src/site_config.ts +15 -0
- package/src/styles/animation.scss +94 -0
- package/src/styles/blog/blog.scss +124 -0
- package/src/styles/blog/code.scss +111 -0
- package/src/styles/blog/directives.scss +356 -0
- package/src/styles/blog/index.scss +4 -0
- package/src/styles/blog/post.scss +474 -0
- package/src/styles/components/aside.scss +178 -0
- package/src/styles/components/footer.scss +74 -0
- package/src/styles/components/header.scss +421 -0
- package/src/styles/components/heroWave.scss +24 -0
- package/src/styles/components/main.scss +275 -0
- package/src/styles/components/page-content.scss +147 -0
- package/src/styles/components/pagination.scss +121 -0
- package/src/styles/components/search.scss +349 -0
- package/src/styles/custom.scss +21 -0
- package/src/styles/global.scss +167 -0
- package/src/styles/mixin.scss +17 -0
- package/src/styles/tags/tags.scss +83 -0
- package/src/theme_config.ts +178 -0
- package/src/utils/generateSearchData.ts +30 -0
- package/src/utils/md.ts +114 -0
- package/src/utils/processMd.ts +278 -0
- package/src/utils/utils.ts +87 -0
- package/tsconfig.json +32 -0
- 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
|
+
# 转载时需标明出处!。
|
package/astro.config.ts
ADDED
@@ -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
|
package/public/c++1.png
ADDED
Binary file
|
Binary file
|
Binary file
|
package/public/help1.png
ADDED
Binary file
|
Binary file
|
package/public/logo.png
ADDED
Binary file
|
package/public/mail.png
ADDED
Binary file
|
Binary file
|
Binary file
|
package/public/rust1.png
ADDED
Binary file
|
@@ -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
|
+
});
|
package/public/xmrig.jpg
ADDED
Binary file
|
@@ -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>
|