@bbki.ng/site 5.4.19 → 5.4.21
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/CHANGELOG.md +16 -0
- package/package.json +9 -21
- package/src/blog/app.tsx +0 -5
- package/src/blog/components/index.tsx +12 -16
- package/src/blog/pages/extensions/txt/article.tsx +13 -33
- package/src/blog/pages/extensions/txt/index.tsx +11 -15
- package/vite.config.js +51 -84
- package/jest.config.js +0 -15
- package/src/blog/__test__/utils/index.test.ts +0 -56
- package/src/blog/articles/index.ts +0 -46
- package/src/blog/components/img_list/index.tsx +0 -43
- package/src/blog/components/stickers/index.tsx +0 -46
- package/src/blog/components/table_skeleton/index.tsx +0 -40
- package/src/blog/pages/extensions/txt/consts.ts +0 -8
- package/src/blog/pages/tags/index.tsx +0 -28
- package/src/blog/pages/tags/tag_result.tsx +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @bbki.ng/site
|
|
2
2
|
|
|
3
|
+
## 5.4.21
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 625ea77: remove mdx articles
|
|
8
|
+
- Updated dependencies [625ea77]
|
|
9
|
+
- @bbki.ng/components@5.2.12
|
|
10
|
+
|
|
11
|
+
## 5.4.20
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- c06c91f: bug fix
|
|
16
|
+
- Updated dependencies [c06c91f]
|
|
17
|
+
- @bbki.ng/components@5.2.11
|
|
18
|
+
|
|
3
19
|
## 5.4.19
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbki.ng/site",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.21",
|
|
4
4
|
"description": "code behind bbki.ng",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -13,26 +13,22 @@
|
|
|
13
13
|
"@tailwindcss/vite": "4.1.17",
|
|
14
14
|
"classnames": "2.3.1",
|
|
15
15
|
"react": "^18.0.0",
|
|
16
|
-
"react-cusdis": "^2.1.3",
|
|
17
16
|
"react-dom": "^18.0.0",
|
|
18
17
|
"react-hotkeys-hook": "^3.4.3",
|
|
19
18
|
"react-router-dom": "6",
|
|
20
19
|
"sonner": "1.4.0",
|
|
21
20
|
"swr": "^2.2.5",
|
|
22
|
-
"
|
|
23
|
-
"@bbki.ng/components": "5.2.10",
|
|
24
|
-
"@bbki.ng/stylebase": "3.1.3"
|
|
21
|
+
"@bbki.ng/components": "5.2.12"
|
|
25
22
|
},
|
|
26
23
|
"devDependencies": {
|
|
27
24
|
"@eslint/compat": "^1.0.0",
|
|
28
25
|
"@eslint/js": "^8.57.0",
|
|
29
|
-
"@mdx-js/mdx": "
|
|
30
|
-
"@mdx-js/react": "^
|
|
31
|
-
"@mdx-js/rollup": "3.0.0",
|
|
26
|
+
"@mdx-js/mdx": "^3.0.0",
|
|
27
|
+
"@mdx-js/react": "^3.0.0",
|
|
28
|
+
"@mdx-js/rollup": "^3.0.0",
|
|
32
29
|
"@tailwindcss/postcss": "4.1.17",
|
|
33
30
|
"@tailwindcss/typography": "^0.5.0",
|
|
34
|
-
"@types/
|
|
35
|
-
"@types/node": "^16.11.1",
|
|
31
|
+
"@types/node": "^20.0.0",
|
|
36
32
|
"@types/react": "^18.0.15",
|
|
37
33
|
"@types/react-dom": "^18.0.6",
|
|
38
34
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
@@ -45,12 +41,8 @@
|
|
|
45
41
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
46
42
|
"eslint-plugin-unicorn": "^51.0.0",
|
|
47
43
|
"globals": "^14.0.0",
|
|
48
|
-
"husky": "^7.0.0",
|
|
49
|
-
"jest": "^27.4.5",
|
|
50
|
-
"lint-staged": "^11.2.1",
|
|
51
44
|
"postcss": "^8.3.9",
|
|
52
45
|
"prettier": "^3.2.0",
|
|
53
|
-
"pretty-quick": "^3.1.1",
|
|
54
46
|
"rehype-autolink-headings": "^6.1.1",
|
|
55
47
|
"rehype-highlight": "^5.0.0",
|
|
56
48
|
"rehype-slug": "^5.0.1",
|
|
@@ -60,18 +52,16 @@
|
|
|
60
52
|
"remark-parse": "^10.0.0",
|
|
61
53
|
"remark-toc": "^8.0.1",
|
|
62
54
|
"rollup-plugin-visualizer": "6.0.5",
|
|
63
|
-
"sass": "^1.42.1",
|
|
64
55
|
"tailwindcss": "^4.1.17",
|
|
65
|
-
"
|
|
66
|
-
"typescript": "^4.5.4",
|
|
56
|
+
"typescript": "^5.3.0",
|
|
67
57
|
"vite": "5.0.0",
|
|
68
58
|
"vite-plugin-cross-origin-isolation": "0.1.6",
|
|
69
59
|
"vite-plugin-glsl": "1.2.1",
|
|
70
60
|
"vite-plugin-mdx": "^3.5.8",
|
|
71
61
|
"vite-plugin-pwa": "0.19",
|
|
72
62
|
"workbox-window": "^6.3.0",
|
|
73
|
-
"@bbki.ng/config": "1.0.
|
|
74
|
-
"@bbki.ng/stylebase": "3.1.
|
|
63
|
+
"@bbki.ng/config": "1.0.4",
|
|
64
|
+
"@bbki.ng/stylebase": "3.1.5"
|
|
75
65
|
},
|
|
76
66
|
"author": "bbbottle",
|
|
77
67
|
"license": "MIT",
|
|
@@ -81,8 +71,6 @@
|
|
|
81
71
|
"prettier": "@bbki.ng/config/prettier",
|
|
82
72
|
"homepage": "https://github.com/bbbottle/bbki.ng#readme",
|
|
83
73
|
"scripts": {
|
|
84
|
-
"test": "jest",
|
|
85
|
-
"test:cov": "jest --coverage",
|
|
86
74
|
"dev": "NODE_ENV=development && vite --host",
|
|
87
75
|
"build": "tsc && vite build",
|
|
88
76
|
"serve": "vite preview"
|
package/src/blog/app.tsx
CHANGED
|
@@ -5,8 +5,6 @@ import { HotKeyNav } from './components';
|
|
|
5
5
|
import { Cover, Streaming } from './pages';
|
|
6
6
|
|
|
7
7
|
import ArticlePage from '@/pages/extensions/txt/article';
|
|
8
|
-
import Tags from '@/pages/tags';
|
|
9
|
-
import TagsResult from '@/pages/tags/tag_result';
|
|
10
8
|
import Txt from '@/pages/extensions/txt';
|
|
11
9
|
|
|
12
10
|
import { usePaths } from '@/hooks';
|
|
@@ -69,9 +67,6 @@ export const App = () => {
|
|
|
69
67
|
<Route path=":title" element={<ArticlePage />} />
|
|
70
68
|
</Route>
|
|
71
69
|
|
|
72
|
-
<Route path="tags" element={<Tags />} />
|
|
73
|
-
<Route path="tags/:tag" element={<TagsResult />} />
|
|
74
|
-
|
|
75
70
|
<Route path="bot" element={<BotRedirect />} />
|
|
76
71
|
<Route path="login" element={<Login />} />
|
|
77
72
|
<Route path="now" element={<Streaming />} />
|
|
@@ -1,32 +1,28 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { LinkList } from
|
|
3
|
-
import { BlurCover } from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LinkList } from '@bbki.ng/components';
|
|
3
|
+
import { BlurCover } from '@bbki.ng/components';
|
|
4
4
|
|
|
5
|
-
export {
|
|
5
|
+
export { withArticleWrapper } from './with_wrapper';
|
|
6
6
|
|
|
7
|
-
export {
|
|
7
|
+
export { HotKeyNav } from './hotkey_nav';
|
|
8
8
|
|
|
9
|
-
export {
|
|
9
|
+
export { VideoPlayer } from './video_player';
|
|
10
10
|
|
|
11
|
-
export {
|
|
11
|
+
export { ProgressBar } from './progress_bar';
|
|
12
12
|
|
|
13
|
-
export {
|
|
13
|
+
export { BlurCover } from './blur_cover';
|
|
14
14
|
|
|
15
|
-
export {
|
|
15
|
+
export { ReloadPrompt } from './reload_prompt';
|
|
16
16
|
|
|
17
|
-
export {
|
|
17
|
+
export { Tags } from './tags';
|
|
18
18
|
|
|
19
|
-
export {
|
|
20
|
-
|
|
21
|
-
export { Tags } from "./tags";
|
|
22
|
-
|
|
23
|
-
export { MySuspense } from "./my_suspense";
|
|
19
|
+
export { MySuspense } from './my_suspense';
|
|
24
20
|
|
|
25
21
|
export const CenterLinkList = (props: any) => {
|
|
26
22
|
return (
|
|
27
23
|
<div className="flex justify-center relative p-16 h-full">
|
|
28
24
|
<LinkList {...props} />
|
|
29
|
-
<BlurCover status={props.loading ?
|
|
25
|
+
<BlurCover status={props.loading ? 'show' : 'silent'} />
|
|
30
26
|
</div>
|
|
31
27
|
);
|
|
32
28
|
};
|
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
import React, { ReactElement, useContext, useEffect } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { useBlogScrollReset } from "@/hooks/use_blog_scroll_pos_restoration";
|
|
14
|
-
|
|
15
|
-
type TArticleMap = {
|
|
16
|
-
[key: string]: ReactElement;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const ArticleMap: TArticleMap = {};
|
|
20
|
-
|
|
21
|
-
MdxArticleList.forEach((article: unknown) => {
|
|
22
|
-
const { meta, default: component } = article as MdxArticle;
|
|
23
|
-
const dateStr = meta.created_at
|
|
24
|
-
? meta.created_at.toISOString().split("T")[0]
|
|
25
|
-
: "";
|
|
26
|
-
const Article = withArticleWrapper(component);
|
|
27
|
-
ArticleMap[meta.title] = <Article {...meta} date={dateStr} />;
|
|
28
|
-
});
|
|
1
|
+
import React, { ReactElement, useContext, useEffect } from 'react';
|
|
2
|
+
import { withArticleWrapper } from '@/components';
|
|
3
|
+
import { MdxArticle } from '@/types/articles';
|
|
4
|
+
import { NotFound, DropZone } from '@bbki.ng/components';
|
|
5
|
+
import { useLocation, useParams } from 'react-router-dom';
|
|
6
|
+
import { usePosts } from '@/hooks/use_posts';
|
|
7
|
+
import { ArticlePage } from '@/components/article';
|
|
8
|
+
import { GlobalLoadingContext } from '@/context/global_loading_state_provider';
|
|
9
|
+
import { useFile2Post } from '@/hooks/use_file_to_post';
|
|
10
|
+
import { useAuthed } from '@/hooks/use_authed';
|
|
11
|
+
import { ArticleCtxMenu } from '@/components/article_ctx_menu';
|
|
12
|
+
import { useBlogScrollReset } from '@/hooks/use_blog_scroll_pos_restoration';
|
|
29
13
|
|
|
30
14
|
export default () => {
|
|
31
15
|
const { title } = useParams();
|
|
@@ -41,10 +25,6 @@ export default () => {
|
|
|
41
25
|
return <NotFound />;
|
|
42
26
|
}
|
|
43
27
|
|
|
44
|
-
if (ArticleMap[title]) {
|
|
45
|
-
return ArticleMap[title];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
28
|
if (isError) {
|
|
49
29
|
return <NotFound />;
|
|
50
30
|
}
|
|
@@ -53,7 +33,7 @@ export default () => {
|
|
|
53
33
|
return null;
|
|
54
34
|
}
|
|
55
35
|
|
|
56
|
-
const date = posts.created_at ? posts.created_at.split(
|
|
36
|
+
const date = posts.created_at ? posts.created_at.split('T')[0] : '';
|
|
57
37
|
|
|
58
38
|
return (
|
|
59
39
|
<DropZone onDrop={reader} disabled={!isKing}>
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
useBlogScroll,
|
|
12
|
-
useBlogScrollRestoration,
|
|
13
|
-
} from "@/hooks/use_blog_scroll_pos_restoration";
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LinkProps, DropZone, Button } from '@bbki.ng/components';
|
|
3
|
+
import { usePosts } from '@/hooks/use_posts';
|
|
4
|
+
import { CenterLinkList } from '@/components';
|
|
5
|
+
import { useAuthed } from '@/hooks/use_authed';
|
|
6
|
+
import { useFile2Post } from '@/hooks/use_file_to_post';
|
|
7
|
+
import { useClipboardToPost } from '@/hooks/use_clipboard_to_post';
|
|
8
|
+
import { useLocation } from 'react-router-dom';
|
|
9
|
+
import { useBlogScroll, useBlogScrollRestoration } from '@/hooks/use_blog_scroll_pos_restoration';
|
|
14
10
|
|
|
15
11
|
type TxtProps = {
|
|
16
12
|
title?: string;
|
|
@@ -29,10 +25,10 @@ const Posts = (props: TxtProps) => {
|
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
if (isError) {
|
|
32
|
-
return <CenterLinkList links={props.articleList
|
|
28
|
+
return <CenterLinkList links={props.articleList} />;
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
const links = [...titleList
|
|
31
|
+
const links = [...titleList];
|
|
36
32
|
|
|
37
33
|
return (
|
|
38
34
|
<CenterLinkList
|
package/vite.config.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import { defineConfig } from
|
|
3
|
-
import { VitePWA } from
|
|
4
|
-
import mdx from
|
|
5
|
-
import remarkGfm from
|
|
6
|
-
import remarkParse from
|
|
7
|
-
import remarkToc from
|
|
8
|
-
import crossOriginIsolation from
|
|
9
|
-
import tailwindcss from
|
|
10
|
-
import remarkFrontMatter from
|
|
11
|
-
import { remarkMdxFrontmatter } from
|
|
12
|
-
import rehypeSlug from
|
|
13
|
-
import rehypeHighlight from
|
|
14
|
-
import rehypeAutolinkHeadings from
|
|
15
|
-
import react from
|
|
16
|
-
import glsl from
|
|
17
|
-
import { visualizer } from
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
import { VitePWA } from 'vite-plugin-pwa';
|
|
4
|
+
import mdx from '@mdx-js/rollup';
|
|
5
|
+
import remarkGfm from 'remark-gfm';
|
|
6
|
+
import remarkParse from 'remark-parse';
|
|
7
|
+
import remarkToc from 'remark-toc';
|
|
8
|
+
import crossOriginIsolation from 'vite-plugin-cross-origin-isolation';
|
|
9
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
10
|
+
import remarkFrontMatter from 'remark-frontmatter';
|
|
11
|
+
import { remarkMdxFrontmatter } from 'remark-mdx-frontmatter';
|
|
12
|
+
import rehypeSlug from 'rehype-slug';
|
|
13
|
+
import rehypeHighlight from 'rehype-highlight';
|
|
14
|
+
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
|
15
|
+
import react from '@vitejs/plugin-react';
|
|
16
|
+
import glsl from 'vite-plugin-glsl';
|
|
17
|
+
import { visualizer } from 'rollup-plugin-visualizer';
|
|
18
18
|
|
|
19
19
|
const options = {
|
|
20
20
|
remarkPlugins: [
|
|
21
21
|
remarkParse,
|
|
22
|
-
[remarkToc, { maxDepth: 3, heading:
|
|
23
|
-
[remarkFrontMatter, { type:
|
|
24
|
-
[remarkMdxFrontmatter, { name:
|
|
22
|
+
[remarkToc, { maxDepth: 3, heading: '目录', tight: true }],
|
|
23
|
+
[remarkFrontMatter, { type: 'yaml', marker: '-' }],
|
|
24
|
+
[remarkMdxFrontmatter, { name: 'meta' }],
|
|
25
25
|
remarkGfm,
|
|
26
26
|
],
|
|
27
27
|
rehypePlugins: [rehypeHighlight, rehypeSlug, rehypeAutolinkHeadings],
|
|
@@ -31,15 +31,15 @@ const options = {
|
|
|
31
31
|
export default defineConfig({
|
|
32
32
|
server: {
|
|
33
33
|
proxy: {
|
|
34
|
-
|
|
35
|
-
target:
|
|
36
|
-
rewrite:
|
|
34
|
+
'/api/streaming': {
|
|
35
|
+
target: 'http://localhost:8787',
|
|
36
|
+
rewrite: path => path.replace(/^\/api/, ''),
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
resolve: {
|
|
41
41
|
alias: {
|
|
42
|
-
|
|
42
|
+
'@': path.resolve(__dirname, './src/blog'),
|
|
43
43
|
// "@bbki.ng/commponents": path.resolve(__dirname, "../components/lib"),
|
|
44
44
|
},
|
|
45
45
|
// preserveSymlinks: true,
|
|
@@ -51,8 +51,8 @@ export default defineConfig({
|
|
|
51
51
|
output: {
|
|
52
52
|
manualChunks: (id, meta) => {
|
|
53
53
|
console.log(id);
|
|
54
|
-
if (id.includes(
|
|
55
|
-
return
|
|
54
|
+
if (id.includes('node_modules')) {
|
|
55
|
+
return 'vendor';
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
},
|
|
@@ -62,7 +62,7 @@ export default defineConfig({
|
|
|
62
62
|
GLOBAL_BBKING_VERSION: JSON.stringify(process.env.npm_package_version),
|
|
63
63
|
},
|
|
64
64
|
esbuild: {
|
|
65
|
-
logOverride: {
|
|
65
|
+
logOverride: { 'this-is-undefined-in-esm': 'silent' },
|
|
66
66
|
},
|
|
67
67
|
plugins: [
|
|
68
68
|
react(),
|
|
@@ -70,52 +70,19 @@ export default defineConfig({
|
|
|
70
70
|
glsl(),
|
|
71
71
|
tailwindcss(),
|
|
72
72
|
VitePWA({
|
|
73
|
-
injectRegister:
|
|
74
|
-
includeAssets: [
|
|
75
|
-
"favicon.svg",
|
|
76
|
-
"robots.txt",
|
|
77
|
-
"apple-touch-icon.png",
|
|
78
|
-
"Logo.svg",
|
|
79
|
-
],
|
|
73
|
+
injectRegister: 'auto',
|
|
74
|
+
includeAssets: ['favicon.svg', 'robots.txt', 'apple-touch-icon.png', 'Logo.svg'],
|
|
80
75
|
devOptions: {
|
|
81
76
|
enabled: true,
|
|
82
77
|
},
|
|
83
78
|
workbox: {
|
|
84
79
|
cleanupOutdatedCaches: true,
|
|
85
80
|
runtimeCaching: [
|
|
86
|
-
{
|
|
87
|
-
urlPattern:
|
|
88
|
-
/^https:\/\/zjh-im-res\.oss-cn-shenzhen\.aliyuncs\.com\/.*/i,
|
|
89
|
-
handler: "CacheFirst",
|
|
90
|
-
options: {
|
|
91
|
-
cacheName: "oss-resource-cache",
|
|
92
|
-
expiration: {
|
|
93
|
-
maxEntries: 100,
|
|
94
|
-
maxAgeSeconds: 60 * 60 * 24 * 365, // <== 365 days
|
|
95
|
-
},
|
|
96
|
-
cacheableResponse: {
|
|
97
|
-
statuses: [0, 200],
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
urlPattern: /new-content-handler/,
|
|
103
|
-
method: "GET",
|
|
104
|
-
handler: ({ event, data }) => {
|
|
105
|
-
const url = new URL(event.request.url);
|
|
106
|
-
const sharedContent = url.searchParams.get("text");
|
|
107
|
-
|
|
108
|
-
// post the shared content to the main thread
|
|
109
|
-
if (sharedContent) {
|
|
110
|
-
window.postMessage(sharedContent, {});
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
81
|
{
|
|
115
82
|
urlPattern: /^https:\/\/fonts\.gstatic.com\.com\/.*/i,
|
|
116
|
-
handler:
|
|
83
|
+
handler: 'CacheFirst',
|
|
117
84
|
options: {
|
|
118
|
-
cacheName:
|
|
85
|
+
cacheName: 'fonts',
|
|
119
86
|
expiration: {
|
|
120
87
|
maxEntries: 100,
|
|
121
88
|
maxAgeSeconds: 60 * 60 * 24 * 365, // <== 365 days
|
|
@@ -128,36 +95,36 @@ export default defineConfig({
|
|
|
128
95
|
],
|
|
129
96
|
},
|
|
130
97
|
manifest: {
|
|
131
|
-
name:
|
|
132
|
-
description:
|
|
133
|
-
theme_color:
|
|
134
|
-
display:
|
|
135
|
-
start_url:
|
|
98
|
+
name: 'bbki.ng',
|
|
99
|
+
description: 'A personal blog.',
|
|
100
|
+
theme_color: '#ffffff',
|
|
101
|
+
display: 'fullscreen',
|
|
102
|
+
start_url: '/',
|
|
136
103
|
share_target: {
|
|
137
|
-
action:
|
|
138
|
-
method:
|
|
104
|
+
action: '/new-content-handler/',
|
|
105
|
+
method: 'GET',
|
|
139
106
|
params: {
|
|
140
|
-
title:
|
|
141
|
-
text:
|
|
142
|
-
url:
|
|
107
|
+
title: 'title',
|
|
108
|
+
text: 'text',
|
|
109
|
+
url: 'url',
|
|
143
110
|
},
|
|
144
111
|
},
|
|
145
112
|
icons: [
|
|
146
113
|
{
|
|
147
|
-
src:
|
|
148
|
-
sizes:
|
|
149
|
-
type:
|
|
114
|
+
src: 'pwa-192x192.png',
|
|
115
|
+
sizes: '192x192',
|
|
116
|
+
type: 'image/png',
|
|
150
117
|
},
|
|
151
118
|
{
|
|
152
|
-
src:
|
|
153
|
-
sizes:
|
|
154
|
-
type:
|
|
119
|
+
src: 'pwa-512x512.png',
|
|
120
|
+
sizes: '512x512',
|
|
121
|
+
type: 'image/png',
|
|
155
122
|
},
|
|
156
123
|
{
|
|
157
|
-
src:
|
|
158
|
-
sizes:
|
|
159
|
-
type:
|
|
160
|
-
purpose:
|
|
124
|
+
src: 'pwa-512x512.png',
|
|
125
|
+
sizes: '512x512',
|
|
126
|
+
type: 'image/png',
|
|
127
|
+
purpose: 'any maskable',
|
|
161
128
|
},
|
|
162
129
|
],
|
|
163
130
|
},
|
package/jest.config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
|
2
|
-
const config = {
|
|
3
|
-
preset: "ts-jest",
|
|
4
|
-
testEnvironment: "jsdom",
|
|
5
|
-
collectCoverageFrom: [
|
|
6
|
-
"src/utils/index.ts",
|
|
7
|
-
"!**/node_modules/**",
|
|
8
|
-
"!**/vendor/**",
|
|
9
|
-
],
|
|
10
|
-
moduleNameMapper: {
|
|
11
|
-
"@/(.*)$": "<rootDir>/src/blog/$1",
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default config;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
delay,
|
|
3
|
-
floatNumberToPercentageString,
|
|
4
|
-
getEnv,
|
|
5
|
-
minDelay,
|
|
6
|
-
} from "@/utils";
|
|
7
|
-
|
|
8
|
-
jest.useFakeTimers();
|
|
9
|
-
jest.spyOn(window, "setTimeout");
|
|
10
|
-
|
|
11
|
-
describe("floatNumberToPercentageString", () => {
|
|
12
|
-
it("should return percentage string correctly", () => {
|
|
13
|
-
expect(floatNumberToPercentageString(0.8)).toBe("80%");
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe("delay", () => {
|
|
18
|
-
it("should delay correctly", () => {
|
|
19
|
-
delay(5000);
|
|
20
|
-
expect(setTimeout).toHaveBeenCalledTimes(1);
|
|
21
|
-
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 5000);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
describe("minDelay", () => {
|
|
26
|
-
it("should delay at least specific duration", () => {
|
|
27
|
-
const promise = delay(1000);
|
|
28
|
-
expect(minDelay(promise, 2000)).toEqual(promise);
|
|
29
|
-
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 2000);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe("getEnv", () => {
|
|
34
|
-
it("should return development when href start with http://localhost", () => {
|
|
35
|
-
const locationSpy = jest.spyOn(window, "location", "get");
|
|
36
|
-
locationSpy.mockImplementation(
|
|
37
|
-
() =>
|
|
38
|
-
({
|
|
39
|
-
href: "http://localhost:3000",
|
|
40
|
-
} as Location)
|
|
41
|
-
);
|
|
42
|
-
expect(getEnv()).toEqual("development");
|
|
43
|
-
locationSpy.mockRestore();
|
|
44
|
-
});
|
|
45
|
-
it("should return production when href is NOT start with http://localhost", () => {
|
|
46
|
-
const locationSpy = jest.spyOn(window, "location", "get");
|
|
47
|
-
locationSpy.mockImplementation(
|
|
48
|
-
() =>
|
|
49
|
-
({
|
|
50
|
-
href: "https://bbki.ng",
|
|
51
|
-
} as Location)
|
|
52
|
-
);
|
|
53
|
-
expect(getEnv()).toEqual("production");
|
|
54
|
-
locationSpy.mockRestore();
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import * as 回暖 from "./warming-up.mdx";
|
|
2
|
-
import * as 离开 from "./travel.mdx";
|
|
3
|
-
import * as 降温 from "./cooldown.mdx";
|
|
4
|
-
import * as 大雪 from "./fall.mdx";
|
|
5
|
-
import * as 大寒 from "./major-cold.mdx";
|
|
6
|
-
import * as 春雨 from "./spring-rain.mdx";
|
|
7
|
-
import * as 春寒 from "./spring-cooldown.mdx";
|
|
8
|
-
import * as 入夏 from "./web-burnning.mdx";
|
|
9
|
-
import * as 六月 from "./black-river.mdx";
|
|
10
|
-
import * as 立秋 from "./liqiu.mdx";
|
|
11
|
-
import * as 照片 from "./photos.mdx";
|
|
12
|
-
// import * as 小乌鸦 from "./xwy.mdx";
|
|
13
|
-
import * as 我要看雪 from "./xwy-and-snowing.mdx";
|
|
14
|
-
import * as 做饭 from "./cooking.mdx";
|
|
15
|
-
import * as 堂兄 from "./cousin.mdx";
|
|
16
|
-
import * as 红色的枪 from "./red-gun.mdx";
|
|
17
|
-
import * as 圆粉 from "./rice-noodle.mdx";
|
|
18
|
-
import * as 树叶 from "./leaves.mdx";
|
|
19
|
-
import * as 惊醒 from "./woke-up.mdx";
|
|
20
|
-
import * as 口蘑 from "./marshroom.mdx";
|
|
21
|
-
import * as 站一下 from "./moment.mdx";
|
|
22
|
-
import * as 干衣服 from "./cloth.mdx";
|
|
23
|
-
|
|
24
|
-
export const MdxArticleList = [
|
|
25
|
-
离开,
|
|
26
|
-
降温,
|
|
27
|
-
大雪,
|
|
28
|
-
大寒,
|
|
29
|
-
回暖,
|
|
30
|
-
春雨,
|
|
31
|
-
春寒,
|
|
32
|
-
入夏,
|
|
33
|
-
六月,
|
|
34
|
-
立秋,
|
|
35
|
-
照片,
|
|
36
|
-
// 小乌鸦,
|
|
37
|
-
做饭,
|
|
38
|
-
堂兄,
|
|
39
|
-
红色的枪,
|
|
40
|
-
圆粉,
|
|
41
|
-
树叶,
|
|
42
|
-
惊醒,
|
|
43
|
-
口蘑,
|
|
44
|
-
站一下,
|
|
45
|
-
干衣服,
|
|
46
|
-
];
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React, { FunctionComponent, ReactElement, ReactNode } from "react";
|
|
2
|
-
import classnames from "classnames";
|
|
3
|
-
import { Photo } from "@/types/photo";
|
|
4
|
-
import { Article, Img } from "@bbki.ng/components";
|
|
5
|
-
|
|
6
|
-
interface imgListProps {
|
|
7
|
-
className: string;
|
|
8
|
-
imgList: Photo[];
|
|
9
|
-
description?: any;
|
|
10
|
-
beforeListRenderer?: () => ReactNode;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const BaseImgList: FunctionComponent<imgListProps> = (props: imgListProps) => {
|
|
14
|
-
const { imgList, className, beforeListRenderer } = props;
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<div className={classnames("max-h-full no-scrollbar overflow-auto", className)}>
|
|
18
|
-
{beforeListRenderer && <>{beforeListRenderer()}</>}
|
|
19
|
-
{imgList.map((img, index) => {
|
|
20
|
-
const isLast = index === imgList.length - 1;
|
|
21
|
-
return (
|
|
22
|
-
<div key={img.src}>
|
|
23
|
-
<Img {...img} className={classnames({ "mb-256": !isLast })} />
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
})}
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
interface TitledImageListProps extends imgListProps {
|
|
32
|
-
title: string | ReactElement;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const ImgList = (props: TitledImageListProps) => {
|
|
36
|
-
const { title, description, ...rest } = props;
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<Article title={title} description={description}>
|
|
40
|
-
<BaseImgList {...rest} />
|
|
41
|
-
</Article>
|
|
42
|
-
);
|
|
43
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Img } from "@bbki.ng/components";
|
|
3
|
-
import { NavLink, useLocation } from "react-router-dom";
|
|
4
|
-
|
|
5
|
-
export const Stickers = () => {
|
|
6
|
-
const { pathname } = useLocation();
|
|
7
|
-
|
|
8
|
-
if (pathname !== "/") {
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div className="fixed bottom-128 md:bottom-256 right-16 z-10 md:right-64">
|
|
14
|
-
<NavLink to="projects">
|
|
15
|
-
<Img
|
|
16
|
-
size="large"
|
|
17
|
-
src="https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/stickers/sticker-water-delivery.jpg"
|
|
18
|
-
className="-rotate-[32.95deg] relative top-0 md:-top-64 left-64 md:left-[unset]"
|
|
19
|
-
width={126}
|
|
20
|
-
height={59}
|
|
21
|
-
renderedWidth={126}
|
|
22
|
-
/>
|
|
23
|
-
</NavLink>
|
|
24
|
-
<NavLink to="404">
|
|
25
|
-
<Img
|
|
26
|
-
size="large"
|
|
27
|
-
src="https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/stickers/sticker-lock.jpg"
|
|
28
|
-
className="rotate-[10.77deg] relative left-64 md:left-[unset]"
|
|
29
|
-
width={93}
|
|
30
|
-
height={50}
|
|
31
|
-
renderedWidth={93}
|
|
32
|
-
/>
|
|
33
|
-
</NavLink>
|
|
34
|
-
<NavLink to="blog">
|
|
35
|
-
<Img
|
|
36
|
-
size="large"
|
|
37
|
-
src="https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/stickers/bar-code.jpg"
|
|
38
|
-
className="-rotate-[13.37deg] relative top-64 left-64 md:left-[unset] md:right-256 md:top-128"
|
|
39
|
-
width={176}
|
|
40
|
-
height={60}
|
|
41
|
-
renderedWidth={176}
|
|
42
|
-
/>
|
|
43
|
-
</NavLink>
|
|
44
|
-
</div>
|
|
45
|
-
);
|
|
46
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Skeleton, SkeletonColor, Table } from "@bbki.ng/components";
|
|
2
|
-
import React from "react";
|
|
3
|
-
|
|
4
|
-
const CELL_STYLE = {
|
|
5
|
-
width: 100,
|
|
6
|
-
maxWidth: 100,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const TableSkeleton = (props: {
|
|
10
|
-
headers?: string[];
|
|
11
|
-
cellStyle?: { width: number; maxWidth: number };
|
|
12
|
-
}) => {
|
|
13
|
-
const { headers, cellStyle = CELL_STYLE } = props;
|
|
14
|
-
const [name = "名字", status = "状态"] = headers || [];
|
|
15
|
-
const renderHeader = () => {
|
|
16
|
-
return (
|
|
17
|
-
<>
|
|
18
|
-
<Table.HCell style={cellStyle}>{name}</Table.HCell>
|
|
19
|
-
<Table.HCell style={cellStyle}>{status}</Table.HCell>
|
|
20
|
-
</>
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const renderRow = () => {
|
|
25
|
-
return (
|
|
26
|
-
<>
|
|
27
|
-
<Table.Cell style={cellStyle}>
|
|
28
|
-
<Skeleton width={84} height={16} bgColor={SkeletonColor.BLUE} />
|
|
29
|
-
</Table.Cell>
|
|
30
|
-
<Table.Cell style={cellStyle}>
|
|
31
|
-
<Skeleton width={32} height={16} bgColor={SkeletonColor.GRAY} />
|
|
32
|
-
</Table.Cell>
|
|
33
|
-
</>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<Table rowCount={3} rowRenderer={renderRow} headerRenderer={renderHeader} />
|
|
39
|
-
);
|
|
40
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { getAllTags } from "@/utils/tags";
|
|
3
|
-
import { MdxArticleList } from "@/articles";
|
|
4
|
-
import { Tags } from "@/components";
|
|
5
|
-
import { ROUTES } from "@/constants";
|
|
6
|
-
|
|
7
|
-
type tag =
|
|
8
|
-
| {
|
|
9
|
-
path: string;
|
|
10
|
-
name: string;
|
|
11
|
-
}
|
|
12
|
-
| string;
|
|
13
|
-
|
|
14
|
-
export default (props: {
|
|
15
|
-
inline?: boolean;
|
|
16
|
-
className?: string;
|
|
17
|
-
withAll?: boolean;
|
|
18
|
-
}) => {
|
|
19
|
-
const tags = [...getAllTags(MdxArticleList)] as tag[];
|
|
20
|
-
|
|
21
|
-
if (props.withAll) {
|
|
22
|
-
tags.unshift({
|
|
23
|
-
path: ROUTES.CONTENT,
|
|
24
|
-
name: "全部",
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
return <Tags tags={tags} {...props} />;
|
|
28
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import Txt from "@/pages/extensions/txt";
|
|
3
|
-
import { getArticleListByTag } from "@/utils/tags";
|
|
4
|
-
import { MdxArticleList } from "@/articles";
|
|
5
|
-
import { useParams } from "react-router-dom";
|
|
6
|
-
import { Error as ErrorPanel } from "@bbki.ng/components";
|
|
7
|
-
|
|
8
|
-
export default () => {
|
|
9
|
-
const { tag } = useParams();
|
|
10
|
-
if (!tag) {
|
|
11
|
-
return <ErrorPanel error={new Error("missing tagName")} />;
|
|
12
|
-
}
|
|
13
|
-
return (
|
|
14
|
-
<Txt
|
|
15
|
-
title={`#${tag}`}
|
|
16
|
-
articleList={getArticleListByTag(MdxArticleList, tag)}
|
|
17
|
-
/>
|
|
18
|
-
);
|
|
19
|
-
};
|