hexo-theme-shokax 0.2.3 → 0.2.5-beta1
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/README.md +8 -2
- package/README_en.MD +44 -13
- package/_config.yml +13 -2
- package/layout/_mixin/postmeta.pug +0 -1
- package/layout/_partials/post/post.pug +13 -0
- package/package.json +14 -15
- package/scripts/generaters/config.js +3 -3
- package/scripts/generaters/images.js +4 -7
- package/scripts/generaters/index.js +7 -7
- package/scripts/generaters/script.js +10 -10
- package/scripts/helpers/list_categories.js +2 -5
- package/scripts/helpers/summary_ai.js +96 -0
- package/source/css/_common/components/tags/tabs.styl +10 -3
- package/source/css/_mixins.styl +1 -1
- package/source/js/_app/fireworks.js +14 -14
- package/source/js/_app/library.js +15 -11
- package/source/js/_app/page.js +3 -3
- package/source/js/_app/player.js +5 -5
- package/source/js/_app/vue.js +2 -0
package/README.md
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|

|
6
6
|

|
7
7
|

|
8
|
+

|
8
9
|
|
9
10
|
语言(language): 简体中文 | [English](./README_en.md) \
|
10
11
|
此项目是shoka的一个二次开发版(算精神续作),致力于提高性能和优化魔改体验 \
|
@@ -24,15 +25,17 @@ shokaX的社区资源导航和插件仓库为[awesome-shokaX](https://github.com
|
|
24
25
|
| PWA支持 | ✅ | JSD拆分 | ✅ |
|
25
26
|
| 注入API | ✅ | 社区插件系统 | ✅ |
|
26
27
|
| 自定义字体 | ✅* | 自定义样式 | ✅* |
|
27
|
-
| 多种评论系统支持 | ✅ |
|
28
|
+
| 多种评论系统支持 | ✅ | AI生成文章概括 | 🔬 |
|
28
29
|
| 底部备案号 | ✅ | 自定义页尾 | ✅* |
|
29
30
|
| CSS渐变封面 | ✅ | typescript支持 | ✅ |
|
30
31
|
|
31
32
|
备注:
|
32
33
|
- *: 需要使用注入API实现
|
34
|
+
- 🔬: 实验中,可能存在问题
|
33
35
|
|
34
36
|
|
35
37
|
## 🔧 如何安装?
|
38
|
+
注意: 本项目需要 node.js 18.x 或更高版本才能运行 \
|
36
39
|
建议使用[ShokaX-CLI](https://github.com/zkz098/shokaX-CLI) ,执行下列命令即可:
|
37
40
|
```bash
|
38
41
|
npm i shokax-cli --location=global
|
@@ -57,7 +60,7 @@ github仓库建议通过右边的 releases 下载,步骤为:
|
|
57
60
|
- [Easy hexo](https://easyhexo.com/)
|
58
61
|
|
59
62
|
# 许可证
|
60
|
-
许可证: GPL 3 \
|
63
|
+
许可证: GPL 3 or later \
|
61
64
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fzkz098%2Fhexo-theme-shokaX?ref=badge_large)
|
62
65
|
|
63
66
|
## 特别说明
|
@@ -76,3 +79,6 @@ GPL许可证主要目的是限制修改后的分发行为,避免未经许可
|
|
76
79
|
|
77
80
|
## 特别鸣谢
|
78
81
|
[<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" width="25%">](https://jb.gg/OpenSourceSupport)
|
82
|
+
|
83
|
+
## 其他信息
|
84
|
+

|
package/README_en.MD
CHANGED
@@ -1,25 +1,56 @@
|
|
1
|
+
If the repository address you are visiting is zkz098/hexo-theme-shokaX, please switch to the latest address: theme-shoka-x/hexo-theme-shokaX.
|
2
|
+
|
1
3
|
# hexo-theme-shokaX
|
2
4
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fzkz098%2Fhexo-theme-shokaX?ref=badge_shield)
|
3
|
-

|
6
|
+

|
5
7
|

|
8
|
+

|
9
|
+
|
10
|
+
Language: [简体中文](./README.md) | English \
|
11
|
+
This project is a secondary development version of shoka (spiritual sequel), dedicated to improving performance and optimizing modding experience.
|
12
|
+
The reason for its birth is that shoka has not been updated for two years, with a large backlog of bugs and feature requests.
|
13
|
+
|
14
|
+
The community resource navigation and plugin repository for shokaX is awesome-shokaX.
|
15
|
+
|
16
|
+
## 💬 Differences with shoka
|
17
|
+
The original shoka used javascript+Native+nunjucks technology, while shokaX uses typescript+Vue 3+Pug technology and has changed a lot of hard-to-access CDN links.
|
18
|
+
|
19
|
+
## ✨ Feature List
|
20
|
+
| Feature Name | Implementation Status | Feature Name | Implementation Status |
|
21
|
+
|:-------------------------------:|:---------------------:|:------------------------------:|:---------------------:|
|
22
|
+
| PWA Support | ✅ | JSD Splitting | ✅ |
|
23
|
+
| Injection API | ✅ | Community Plugin System | ✅ |
|
24
|
+
| Custom Fonts | ✅* | Custom Styles | ✅* |
|
25
|
+
| Multiple Comment System Support | ✅ | User Behavior Analysis Support | ✅ |
|
26
|
+
| Record Number at the Bottom | ✅ | Custom Footer | ✅* |
|
27
|
+
| CSS Gradient Cover | ✅ | Typescript Support | ✅ |
|
6
28
|
|
7
|
-
|
8
|
-
|
9
|
-
This project is in a period of intensive development, but the github repository version is basically available. \
|
10
|
-
Please refer to the wiki for secondary development and common problems.
|
11
|
-
Starting with `0.0.2-alpha2`, `lantern` and `qweather` have been migrated as plugins.
|
12
|
-
The plugin system is complete, see [awesome-shokaX](https://github.com/zkz098/awesome-shokaX) for how to use it.
|
29
|
+
Remarks:
|
30
|
+
- *: Requires implementation using Injection API.
|
13
31
|
|
14
|
-
## How to
|
15
|
-
[ShokaX-CLI](https://github.com/zkz098/shokaX-CLI)
|
32
|
+
## 🔧 How to Install?
|
33
|
+
It is recommended to use [ShokaX-CLI](https://github.com/zkz098/shokaX-CLI) and execute the following command:
|
16
34
|
```bash
|
17
35
|
npm i shokax-cli --location=global
|
18
|
-
# hexo init
|
19
|
-
SXC install
|
36
|
+
# hexo init initializes the environment
|
37
|
+
SXC install shokaX
|
20
38
|
```
|
39
|
+
[Click here](https://docs.kaitaku.xyz/guide/#%E9%85%8D%E7%BD%AE%E4%B8%BB%E9%A2%98) for the next configuration steps.
|
40
|
+
|
41
|
+
It is recommended to download the GitHub repository from the Releases on the right-hand side, as follows:
|
42
|
+
|
43
|
+
- Click on the Latest version in Releases
|
44
|
+
- Download the Source code(zip) in Assets
|
45
|
+
- Unzip to use as the theme
|
21
46
|
|
22
47
|
# License
|
23
|
-
|
48
|
+
license: GPL 3 or later
|
24
49
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fzkz098%2Fhexo-theme-shokaX?ref=badge_large)
|
25
50
|
|
51
|
+
## Contributors
|
52
|
+
|
53
|
+
[](https://github.com/zkz098/hexo-theme-shokaX/graphs/contributors)
|
54
|
+
|
55
|
+
## Special thanks
|
56
|
+
[<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" width="25%">](https://jb.gg/OpenSourceSupport)
|
package/_config.yml
CHANGED
@@ -198,6 +198,17 @@ giscus:
|
|
198
198
|
commentTheme:
|
199
199
|
lang:
|
200
200
|
|
201
|
+
summary:
|
202
|
+
enable: false
|
203
|
+
introduce: "我是基于ChatGPT-turbo-3.5实现的AI助手,在此网站上负责整理和概括文章" # AI自我介绍
|
204
|
+
mode: openai # openai/custom
|
205
|
+
openai:
|
206
|
+
remote: "https://api.openai.com"
|
207
|
+
apikey: "key"
|
208
|
+
custom:
|
209
|
+
remote: "http://localhost:8000"
|
210
|
+
|
211
|
+
|
201
212
|
# Social Links
|
202
213
|
# Usage: `Key: permalink || icon || color`
|
203
214
|
# Key is the link label showing to end users.
|
@@ -344,7 +355,7 @@ advVendors:
|
|
344
355
|
fetch:
|
345
356
|
src: npm:whatwg-fetch@3.4.0/dist/fetch.umd.js
|
346
357
|
anime:
|
347
|
-
src:
|
358
|
+
src: npm:theme-shokax-anime@latest/anime.shokax.min.js
|
348
359
|
algolia:
|
349
360
|
src: bytedance:algoliasearch/4.12.1/algoliasearch-lite.umd.min.js
|
350
361
|
instantsearch:
|
@@ -394,7 +405,7 @@ vendors:
|
|
394
405
|
pace: npm/pace-js@1.0.2/pace.min.js # ok
|
395
406
|
pjax: npm/pjax@0.2.8/pjax.min.js # ok
|
396
407
|
fetch: npm/whatwg-fetch@3.4.0/dist/fetch.umd.min.js # ok
|
397
|
-
anime: npm/
|
408
|
+
anime: npm/theme-shokax-anime@latest/anime.shokax.min.js
|
398
409
|
algolia: npm/algoliasearch@4/dist/algoliasearch-lite.umd.js # ok
|
399
410
|
instantsearch: npm/instantsearch.js@4/dist/instantsearch.production.min.js # ok
|
400
411
|
lazyload: npm/lozad@1/dist/lozad.min.js # ok
|
@@ -12,6 +12,19 @@ article(itemscope itemtype="http://schema.org/Article" class="post block" lang=t
|
|
12
12
|
div(class="gallery" itemscope itemtype="http://schema.org/ImageGallery")
|
13
13
|
each photo in post.photos
|
14
14
|
img(data-src=_image_url(photo, post.path) itemprop="contentUrl")
|
15
|
+
if theme.summary.enable && page.layout === 'post'
|
16
|
+
div(class='tabs' id='summary')
|
17
|
+
div(class="show-btn")
|
18
|
+
div(class="nav")
|
19
|
+
ul(class="special")
|
20
|
+
div(class="tab" data-id="summary" data-title="自我介绍")
|
21
|
+
p
|
22
|
+
!= get_introduce()
|
23
|
+
div(class="tab active" data-id="summary" data-title="文章概括")
|
24
|
+
p
|
25
|
+
!= get_summary(page)
|
26
|
+
|
27
|
+
|
15
28
|
!= post.content
|
16
29
|
if post.tags && post.tags.length
|
17
30
|
div(class="tags")
|
package/package.json
CHANGED
@@ -1,49 +1,48 @@
|
|
1
1
|
{
|
2
2
|
"name": "hexo-theme-shokax",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.5-beta1",
|
4
4
|
"description": "a hexo theme based on shoka",
|
5
5
|
"main": "index.js",
|
6
6
|
"repository": "https://github.com/zkz098/hexo-theme-shokaX",
|
7
7
|
"author": "Chou kaitaku",
|
8
8
|
"license": "GPL-3.0-or-later",
|
9
9
|
"scripts": {
|
10
|
-
"test": "
|
10
|
+
"test": "tsc",
|
11
11
|
"build": "pnpm install && tsc",
|
12
12
|
"docs:dev": "vuepress dev docs",
|
13
13
|
"docs:build": "vuepress build docs"
|
14
14
|
},
|
15
15
|
"devDependencies": {
|
16
16
|
"@algolia/client-search": "^4",
|
17
|
-
"@types/animejs": "^3.1.7",
|
18
17
|
"@types/fancybox": "^3.5.3",
|
19
18
|
"@types/hexo": "^3.8.8",
|
20
19
|
"@types/jquery": "^3.5.16",
|
21
20
|
"@types/js-yaml": "^4.0.5",
|
22
21
|
"@types/lozad": "^1.16.1",
|
23
|
-
"@types/node": "^18.15.
|
24
|
-
"@
|
25
|
-
"@typescript-eslint/
|
26
|
-
"@typescript-eslint/parser": "^5.56.0",
|
22
|
+
"@types/node": "^18.15.13",
|
23
|
+
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
24
|
+
"@typescript-eslint/parser": "^5.59.0",
|
27
25
|
"@vuepress/client": "2.0.0-beta.61",
|
28
26
|
"@vuepress/plugin-docsearch": "2.0.0-beta.61",
|
29
|
-
"algoliasearch": "^4.
|
30
|
-
"eslint": "^8.
|
27
|
+
"algoliasearch": "^4.17.0",
|
28
|
+
"eslint": "^8.39.0",
|
31
29
|
"eslint-config-standard": "^17.0.0",
|
32
30
|
"eslint-plugin-import": "^2.27.5",
|
33
|
-
"eslint-plugin-n": "^15.
|
31
|
+
"eslint-plugin-n": "^15.7.0",
|
34
32
|
"eslint-plugin-promise": "^6.1.1",
|
35
|
-
"eslint-plugin-vue": "^9.
|
33
|
+
"eslint-plugin-vue": "^9.11.0",
|
36
34
|
"hexo-fs": "^4.1.1",
|
37
35
|
"hexo-util": "^3.0.1",
|
38
|
-
"instantsearch.js": "^4.
|
36
|
+
"instantsearch.js": "^4.54.1",
|
39
37
|
"pjax": "^0.2.8",
|
40
|
-
"
|
38
|
+
"theme-shokax-anime": "^0.0.4",
|
39
|
+
"typescript": "^5.0.4",
|
41
40
|
"vue": "^3.2.47",
|
42
41
|
"vuepress": "2.0.0-beta.61",
|
43
|
-
"vuepress-plugin-sitemap2": "2.0.0-beta.
|
42
|
+
"vuepress-plugin-sitemap2": "2.0.0-beta.206"
|
44
43
|
},
|
45
44
|
"dependencies": {
|
46
45
|
"js-yaml": "^4.1.0",
|
47
|
-
"sass": "^1.
|
46
|
+
"sass": "^1.62.0"
|
48
47
|
}
|
49
48
|
}
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
const hexo_util_1 = __importDefault(require("hexo-util"));
|
7
|
-
const
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
8
8
|
const path_1 = __importDefault(require("path"));
|
9
9
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
10
10
|
hexo.extend.filter.register('before_generate', () => {
|
@@ -26,7 +26,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|
26
26
|
hexo.theme.config.style = {};
|
27
27
|
for (const style of ['iconfont', 'colors', 'custom']) {
|
28
28
|
const custom_file = 'source/_data/' + style + '.styl';
|
29
|
-
if (
|
29
|
+
if (node_fs_1.default.existsSync(custom_file)) {
|
30
30
|
hexo.theme.config.style[style] = path_1.default.resolve(hexo.base_dir, custom_file);
|
31
31
|
}
|
32
32
|
}
|
@@ -34,6 +34,6 @@ hexo.extend.filter.register('before_generate', () => {
|
|
34
34
|
hexo.theme.config.image_list = data.images;
|
35
35
|
}
|
36
36
|
else {
|
37
|
-
hexo.theme.config.image_list = js_yaml_1.default.load(
|
37
|
+
hexo.theme.config.image_list = js_yaml_1.default.load(node_fs_1.default.readFileSync(path_1.default.join(__dirname, '../../_images.yml')));
|
38
38
|
}
|
39
39
|
});
|
@@ -1,22 +1,19 @@
|
|
1
1
|
'use strict';
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
const
|
3
|
+
const fs = require("hexo-fs");
|
7
4
|
hexo.extend.generator.register('images', function (locals) {
|
8
5
|
const theme = hexo.theme.config;
|
9
6
|
const dir = 'source/_data/' + theme.assets + '/';
|
10
|
-
if (!
|
7
|
+
if (!fs.existsSync(dir)) {
|
11
8
|
return;
|
12
9
|
}
|
13
10
|
const result = [];
|
14
|
-
const files =
|
11
|
+
const files = fs.listDirSync(dir);
|
15
12
|
files.forEach((file) => {
|
16
13
|
result.push({
|
17
14
|
path: theme.assets + '/' + file,
|
18
15
|
data: function () {
|
19
|
-
return
|
16
|
+
return fs.createReadStream(dir + file);
|
20
17
|
}
|
21
18
|
});
|
22
19
|
});
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
const
|
6
|
+
const fs = require("hexo-fs");
|
7
7
|
const hexo_pagination_1 = __importDefault(require("hexo-pagination"));
|
8
8
|
hexo.config.index_generator = Object.assign({
|
9
9
|
per_page: typeof hexo.config.per_page === 'undefined' ? 10 : hexo.config.per_page,
|
@@ -31,27 +31,27 @@ hexo.extend.generator.register('index', function (locals) {
|
|
31
31
|
if (categories && categories.length) {
|
32
32
|
categories.forEach((cat) => {
|
33
33
|
const cover = `source/_posts/${cat.slug}`;
|
34
|
-
if (
|
34
|
+
if (fs.existsSync(cover + '/cover.avif')) {
|
35
35
|
covers.push({
|
36
36
|
path: cat.slug + '/cover.avif',
|
37
37
|
data: function () {
|
38
|
-
return
|
38
|
+
return fs.createReadStream(cover + '/cover.avif');
|
39
39
|
}
|
40
40
|
});
|
41
41
|
}
|
42
|
-
else if (
|
42
|
+
else if (fs.existsSync(cover + '/cover.webp')) {
|
43
43
|
covers.push({
|
44
44
|
path: cat.slug + '/cover.webp',
|
45
45
|
data: function () {
|
46
|
-
return
|
46
|
+
return fs.createReadStream(cover + '/cover.webp');
|
47
47
|
}
|
48
48
|
});
|
49
49
|
}
|
50
|
-
else if (
|
50
|
+
else if (fs.existsSync(cover + '/cover.jpg')) {
|
51
51
|
covers.push({
|
52
52
|
path: cat.slug + '/cover.jpg',
|
53
53
|
data: function () {
|
54
|
-
return
|
54
|
+
return fs.createReadStream(cover + '/cover.jpg');
|
55
55
|
}
|
56
56
|
});
|
57
57
|
const topcat = getTopcat(cat);
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
const package_json_1 = __importDefault(require("../../package.json"));
|
7
|
-
const
|
7
|
+
const fs = require("hexo-fs");
|
8
8
|
hexo.extend.generator.register('script', function (locals) {
|
9
9
|
const log = hexo.log || console.log;
|
10
10
|
const config = hexo.config;
|
@@ -61,27 +61,27 @@ hexo.extend.generator.register('script', function (locals) {
|
|
61
61
|
}
|
62
62
|
let text = '';
|
63
63
|
['library', 'global', 'page', 'vue', 'components'].forEach(function (item) {
|
64
|
-
if (
|
65
|
-
text +=
|
64
|
+
if (fs.existsSync(`themes/shokaX/source/js/_app/${item}.js`)) {
|
65
|
+
text += fs.readFileSync(`themes/shokaX/source/js/_app/${item}.js`).toString();
|
66
66
|
}
|
67
67
|
else {
|
68
|
-
text +=
|
68
|
+
text += fs.readFileSync(`node_modules/hexo-theme-shokax/source/js/_app/${item}.js`).toString();
|
69
69
|
}
|
70
70
|
});
|
71
71
|
if (!theme.experiments?.noPlayer) {
|
72
|
-
if (
|
73
|
-
text +=
|
72
|
+
if (fs.existsSync('themes/shokaX/source/js/_app/player.js')) {
|
73
|
+
text += fs.readFileSync('themes/shokaX/source/js/_app/player.js').toString();
|
74
74
|
}
|
75
75
|
else {
|
76
|
-
text +=
|
76
|
+
text += fs.readFileSync('node_modules/hexo-theme-shokax/source/js/_app/player.js').toString();
|
77
77
|
}
|
78
78
|
}
|
79
79
|
if (theme.fireworks && theme.fireworks.enable) {
|
80
|
-
if (
|
81
|
-
text +=
|
80
|
+
if (fs.existsSync('themes/shokaX/source/js/_app/fireworks.js')) {
|
81
|
+
text += fs.readFileSync('themes/shokaX/source/js/_app/fireworks.js').toString();
|
82
82
|
}
|
83
83
|
else {
|
84
|
-
text +=
|
84
|
+
text += fs.readFileSync('node_modules/hexo-theme-shokax/source/js/_app/fireworks.js').toString();
|
85
85
|
}
|
86
86
|
siteConfig.fireworks = theme.fireworks.color || ['rgba(255,182,185,.9)', 'rgba(250,227,217,.9)', 'rgba(187,222,214,.9)', 'rgba(138,198,209,.9)'];
|
87
87
|
}
|
@@ -1,9 +1,6 @@
|
|
1
1
|
'use strict';
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
const
|
3
|
+
const fs = require("hexo-fs");
|
7
4
|
const prepareQuery = (categories, parent) => {
|
8
5
|
const query = {
|
9
6
|
parent: undefined
|
@@ -63,7 +60,7 @@ hexo.extend.helper.register('_categories', function () {
|
|
63
60
|
categories.forEach((cat, i) => {
|
64
61
|
const child = prepareQuery(categories, cat._id);
|
65
62
|
const cover = 'source/_posts' + cat.path.replace(this.config.category_dir, '') + 'cover.jpg';
|
66
|
-
if (
|
63
|
+
if (fs.existsSync(cover)) {
|
67
64
|
const className = cat.slug.split('/');
|
68
65
|
className.pop();
|
69
66
|
cat.class = className.join(' ');
|
@@ -0,0 +1,96 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
7
|
+
function getContent(post) {
|
8
|
+
return post?.raw ?? post?._content ?? post.content;
|
9
|
+
}
|
10
|
+
let db;
|
11
|
+
function postMessage(path, content, dbPath, startMessage) {
|
12
|
+
if (node_fs_1.default.existsSync('summary.json')) {
|
13
|
+
db = JSON.parse(node_fs_1.default.readFileSync('summary.json'));
|
14
|
+
}
|
15
|
+
else {
|
16
|
+
db = {};
|
17
|
+
}
|
18
|
+
const config = hexo.theme.config.summary;
|
19
|
+
if (config.enable) {
|
20
|
+
if (typeof db?.[path] !== 'undefined' && typeof db?.[path]?.[dbPath] !== 'undefined') {
|
21
|
+
return db[path][dbPath];
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
if (typeof db?.[path] === 'undefined') {
|
25
|
+
db[path] = {};
|
26
|
+
}
|
27
|
+
else {
|
28
|
+
db[path][dbPath] = '';
|
29
|
+
}
|
30
|
+
}
|
31
|
+
if (config.mode === 'openai') {
|
32
|
+
const request = () => {
|
33
|
+
fetch(`${config.openai.remote}/v1/chat/completions`, {
|
34
|
+
method: 'POST',
|
35
|
+
headers: requestHeaders,
|
36
|
+
body: JSON.stringify(requestBody)
|
37
|
+
}).then((response) => {
|
38
|
+
if (!response.ok) {
|
39
|
+
throw Error('ERROR: Failed to get summary from Openai API');
|
40
|
+
}
|
41
|
+
response.json().then((data) => {
|
42
|
+
const summary = data.choices[0].message.content;
|
43
|
+
try {
|
44
|
+
db[path][dbPath] = summary;
|
45
|
+
}
|
46
|
+
catch (e) {
|
47
|
+
db ??= {};
|
48
|
+
db[path] ??= {};
|
49
|
+
db[path][dbPath] ??= '';
|
50
|
+
console.log(db[path]);
|
51
|
+
db[path][dbPath] = summary;
|
52
|
+
}
|
53
|
+
node_fs_1.default.writeFileSync('summary.json', JSON.stringify(db));
|
54
|
+
if (node_fs_1.default.existsSync('requested.lock')) {
|
55
|
+
node_fs_1.default.unlinkSync('requested.lock');
|
56
|
+
}
|
57
|
+
return summary;
|
58
|
+
});
|
59
|
+
});
|
60
|
+
};
|
61
|
+
const checkTime = () => {
|
62
|
+
if (node_fs_1.default.existsSync('request.lock')) {
|
63
|
+
if (node_fs_1.default.existsSync('requested.lock')) {
|
64
|
+
setTimeout(checkTime, 1000 * 10);
|
65
|
+
return;
|
66
|
+
}
|
67
|
+
node_fs_1.default.writeFileSync('requested.lock', '');
|
68
|
+
setTimeout(request, 1000 * 20);
|
69
|
+
node_fs_1.default.unlinkSync('request.lock');
|
70
|
+
}
|
71
|
+
else {
|
72
|
+
node_fs_1.default.writeFileSync('request.lock', '');
|
73
|
+
request();
|
74
|
+
}
|
75
|
+
};
|
76
|
+
const requestHeaders = {
|
77
|
+
'Content-Type': 'application/json',
|
78
|
+
Authorization: `Bearer ${config.openai.apikey}`
|
79
|
+
};
|
80
|
+
const requestBody = {
|
81
|
+
model: 'gpt-3.5-turbo',
|
82
|
+
messages: [{ role: 'user', content: `${startMessage} ${content}` }],
|
83
|
+
temperature: 0.7
|
84
|
+
};
|
85
|
+
checkTime();
|
86
|
+
}
|
87
|
+
else {
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
hexo.extend.helper.register('get_summary', (post) => {
|
92
|
+
return postMessage(post.path, getContent(post), 'summary', '请为下述文章提供一份200字以内的概括,使用中文回答且尽可能简洁: ');
|
93
|
+
});
|
94
|
+
hexo.extend.helper.register('get_introduce', () => {
|
95
|
+
return hexo.theme.config.summary.introduce;
|
96
|
+
});
|
@@ -14,6 +14,13 @@
|
|
14
14
|
overflow-x: auto;
|
15
15
|
}
|
16
16
|
|
17
|
+
ul.special::before {
|
18
|
+
font-family: ic;
|
19
|
+
content: "\e652";
|
20
|
+
font-size: x-large;
|
21
|
+
padding-left: 1em;
|
22
|
+
}
|
23
|
+
|
17
24
|
li {
|
18
25
|
position: relative;
|
19
26
|
cursor: pointer;
|
@@ -27,20 +34,20 @@
|
|
27
34
|
position: absolute;
|
28
35
|
left: 50%;
|
29
36
|
right: 50%;
|
30
|
-
top:
|
37
|
+
top: 2em;
|
31
38
|
bottom: 0;
|
32
39
|
transition: all .2s ease-in-out;
|
33
40
|
width: auto;
|
34
41
|
height: auto;
|
35
42
|
background: none;
|
36
|
-
border-radius:
|
43
|
+
border-radius: 10px;
|
37
44
|
border-bottom: .125rem solid transparent;
|
38
45
|
}
|
39
46
|
|
40
47
|
&.active::before {
|
41
48
|
left: 0;
|
42
49
|
right: 0;
|
43
|
-
border-bottom-color: var(--
|
50
|
+
border-bottom-color: var(--primary-color);
|
44
51
|
}
|
45
52
|
}
|
46
53
|
}
|
package/source/css/_mixins.styl
CHANGED
@@ -77,9 +77,9 @@ function createCircle(x, y) {
|
|
77
77
|
};
|
78
78
|
return p;
|
79
79
|
}
|
80
|
-
function renderParticule(
|
81
|
-
for (
|
82
|
-
|
80
|
+
function renderParticule(targets) {
|
81
|
+
for (const target of targets) {
|
82
|
+
target.draw();
|
83
83
|
}
|
84
84
|
}
|
85
85
|
function animateParticules(x, y) {
|
@@ -88,31 +88,31 @@ function animateParticules(x, y) {
|
|
88
88
|
for (let i = 0; i < numberOfParticules; i++) {
|
89
89
|
particules.push(createParticule(x, y));
|
90
90
|
}
|
91
|
-
anime.timeline().add({
|
91
|
+
anime().timeline().add({
|
92
92
|
targets: particules,
|
93
|
+
duration: anime.random(1200, 1800),
|
94
|
+
easing: 'easeOutExpo',
|
95
|
+
update: renderParticule,
|
93
96
|
x: function (p) {
|
94
97
|
return p.endPos.x;
|
95
98
|
},
|
96
99
|
y: function (p) {
|
97
100
|
return p.endPos.y;
|
98
101
|
},
|
99
|
-
radius: 0.1
|
100
|
-
duration: anime.random(1200, 1800),
|
101
|
-
easing: 'easeOutExpo',
|
102
|
-
update: renderParticule
|
102
|
+
radius: 0.1
|
103
103
|
}).add({
|
104
104
|
targets: circle,
|
105
|
+
duration: anime.random(1200, 1800),
|
106
|
+
easing: 'easeOutExpo',
|
107
|
+
update: renderParticule,
|
105
108
|
radius: anime.random(80, 160),
|
106
109
|
lineWidth: 0,
|
107
110
|
alpha: {
|
108
111
|
value: 0,
|
109
112
|
easing: 'linear',
|
110
113
|
duration: anime.random(600, 800)
|
111
|
-
}
|
112
|
-
|
113
|
-
easing: 'easeOutExpo',
|
114
|
-
update: renderParticule
|
115
|
-
}, 0);
|
114
|
+
}
|
115
|
+
}).play();
|
116
116
|
}
|
117
117
|
const render = anime({
|
118
118
|
duration: Infinity,
|
@@ -127,7 +127,7 @@ const hasAncestor = function (node, name) {
|
|
127
127
|
break;
|
128
128
|
if (node.nodeName === name)
|
129
129
|
return true;
|
130
|
-
} while (node = node.parentNode);
|
130
|
+
} while ((node = node.parentNode) !== null);
|
131
131
|
return false;
|
132
132
|
};
|
133
133
|
document.addEventListener(tap, function (e) {
|
@@ -61,7 +61,7 @@ Object.assign(HTMLElement.prototype, {
|
|
61
61
|
}
|
62
62
|
return this.getBoundingClientRect().width;
|
63
63
|
},
|
64
|
-
|
64
|
+
getTop: function () {
|
65
65
|
return this.getBoundingClientRect().top;
|
66
66
|
},
|
67
67
|
left: function () {
|
@@ -192,7 +192,7 @@ const vendorCss = function (type, condition) {
|
|
192
192
|
window['css' + type] = true;
|
193
193
|
}
|
194
194
|
};
|
195
|
-
const transition = (target, type, complete) => {
|
195
|
+
const transition = (target, type, complete, begin) => {
|
196
196
|
let animation;
|
197
197
|
let display = 'none';
|
198
198
|
switch (type) {
|
@@ -236,14 +236,14 @@ const transition = (target, type, complete) => {
|
|
236
236
|
begin: function (anim) {
|
237
237
|
target.display('block');
|
238
238
|
},
|
239
|
-
translateX: [100, 0],
|
239
|
+
translateX: ['100%', '0%'],
|
240
240
|
opacity: [0, 1]
|
241
241
|
};
|
242
242
|
display = 'block';
|
243
243
|
break;
|
244
244
|
case 'slideRightOut':
|
245
245
|
animation = {
|
246
|
-
translateX: [0, 100],
|
246
|
+
translateX: ['0%', '100%'],
|
247
247
|
opacity: [1, 0]
|
248
248
|
};
|
249
249
|
break;
|
@@ -255,11 +255,15 @@ const transition = (target, type, complete) => {
|
|
255
255
|
anime(Object.assign({
|
256
256
|
targets: target,
|
257
257
|
duration: 200,
|
258
|
-
easing: 'linear'
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
258
|
+
easing: 'linear',
|
259
|
+
begin: function () {
|
260
|
+
begin && begin();
|
261
|
+
},
|
262
|
+
complete: function () {
|
263
|
+
target.display(display);
|
264
|
+
complete && complete();
|
265
|
+
}
|
266
|
+
}, animation)).play();
|
263
267
|
};
|
264
268
|
const pjaxScript = function (element) {
|
265
269
|
const { text, parentNode, id, className, type, src, dataset } = element;
|
@@ -292,10 +296,10 @@ const pageScroll = function (target, offset, complete) {
|
|
292
296
|
targets: typeof offset === 'number' ? target.parentNode : document.scrollingElement,
|
293
297
|
duration: 500,
|
294
298
|
easing: 'easeInOutQuad',
|
295
|
-
scrollTop: offset || (typeof target === 'number' ? target : (target ? target.
|
299
|
+
scrollTop: offset || (typeof target === 'number' ? target : (target ? target.getTop() + document.documentElement.scrollTop - siteNavHeight : 0)),
|
296
300
|
complete: function () {
|
297
301
|
complete && complete();
|
298
302
|
}
|
299
303
|
};
|
300
|
-
anime(opt);
|
304
|
+
anime(opt).play();
|
301
305
|
};
|
package/source/js/_app/page.js
CHANGED
@@ -72,7 +72,7 @@ const postFancybox = function (p) {
|
|
72
72
|
$dom.each(p + ' p.gallery', function (element) {
|
73
73
|
const box = document.createElement('div');
|
74
74
|
box.className = 'gallery';
|
75
|
-
box.attr('data-height', element.attr('data-height') || 220);
|
75
|
+
box.attr('data-height', String(element.attr('data-height') || 220));
|
76
76
|
box.innerHTML = element.innerHTML.replace(/<br>/g, '');
|
77
77
|
element.parentNode.insertBefore(box, element);
|
78
78
|
element.remove();
|
@@ -405,7 +405,7 @@ const tabFormat = function () {
|
|
405
405
|
target.addClass('active');
|
406
406
|
});
|
407
407
|
box.appendChild(element);
|
408
|
-
element.attr('data-ready', true);
|
408
|
+
element.attr('data-ready', String(true));
|
409
409
|
});
|
410
410
|
};
|
411
411
|
const loadComments = function () {
|
@@ -616,7 +616,7 @@ const domInit = function () {
|
|
616
616
|
const pjaxReload = function () {
|
617
617
|
pagePosition();
|
618
618
|
if (sideBar.hasClass('on')) {
|
619
|
-
transition(sideBar, function () {
|
619
|
+
transition(sideBar, 0, function () {
|
620
620
|
sideBar.removeClass('on');
|
621
621
|
menuToggle.removeClass('close');
|
622
622
|
});
|
package/source/js/_app/player.js
CHANGED
@@ -425,7 +425,7 @@ const mediaPlayer = function (t, config) {
|
|
425
425
|
t.player = {
|
426
426
|
_id: utils.random(999999),
|
427
427
|
group: true,
|
428
|
-
load:
|
428
|
+
load: (newList) => {
|
429
429
|
let d = '';
|
430
430
|
if (newList && newList.length > 0) {
|
431
431
|
if (this.options.rawList !== newList) {
|
@@ -483,7 +483,7 @@ const mediaPlayer = function (t, config) {
|
|
483
483
|
}
|
484
484
|
});
|
485
485
|
},
|
486
|
-
mode:
|
486
|
+
mode: () => {
|
487
487
|
const total = playlist.data.length;
|
488
488
|
if (!total || playlist.errnum === total) {
|
489
489
|
return;
|
@@ -496,7 +496,7 @@ const mediaPlayer = function (t, config) {
|
|
496
496
|
}
|
497
497
|
playlist.index = index;
|
498
498
|
};
|
499
|
-
const random =
|
499
|
+
const random = () => {
|
500
500
|
const p = utils.random(total);
|
501
501
|
if (playlist.index !== p) {
|
502
502
|
playlist.index = p;
|
@@ -523,7 +523,7 @@ const mediaPlayer = function (t, config) {
|
|
523
523
|
}
|
524
524
|
this.init();
|
525
525
|
},
|
526
|
-
switch:
|
526
|
+
switch: (index) => {
|
527
527
|
if (typeof index === 'number' &&
|
528
528
|
index !== playlist.index &&
|
529
529
|
playlist.current() &&
|
@@ -555,7 +555,7 @@ const mediaPlayer = function (t, config) {
|
|
555
555
|
this.play();
|
556
556
|
}
|
557
557
|
},
|
558
|
-
play:
|
558
|
+
play: () => {
|
559
559
|
NOWPLAYING && NOWPLAYING.player.pause();
|
560
560
|
if (playlist.current().error) {
|
561
561
|
this.mode();
|