@bbki.ng/site 0.0.17
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/.github/workflows/deploy.yml +44 -0
- package/.husky/pre-commit +4 -0
- package/.prettierignore +1 -0
- package/.prettierrc.json +1 -0
- package/.rush/temp/shrinkwrap-deps.json +908 -0
- package/CODE_OF_CONDUCT.md +45 -0
- package/CONTRIBUTING.md +11 -0
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/index.html +33 -0
- package/jest.config.js +15 -0
- package/package.json +69 -0
- package/postcss.config.cjs +6 -0
- package/public/Logo.svg +9 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +9 -0
- package/public/pwa-192x192.png +0 -0
- package/public/pwa-512x512.png +0 -0
- package/public/robots.txt +2 -0
- package/src/__test__/utils/index.test.ts +90 -0
- package/src/app.tsx +97 -0
- package/src/articles/anti-logic.mdx +61 -0
- package/src/articles/bbking-manual.mdx +88 -0
- package/src/articles/black-river.mdx +8 -0
- package/src/articles/cooldown.mdx +12 -0
- package/src/articles/fall.mdx +8 -0
- package/src/articles/img.mdx +104 -0
- package/src/articles/index.ts +35 -0
- package/src/articles/loading.mdx +129 -0
- package/src/articles/major-cold.mdx +14 -0
- package/src/articles/men-without-women.mdx +19 -0
- package/src/articles/movie-day.mdx +15 -0
- package/src/articles/now.mdx +15 -0
- package/src/articles/projects.mdx +9 -0
- package/src/articles/quote.mdx +27 -0
- package/src/articles/spring-cooldown.mdx +7 -0
- package/src/articles/spring-rain.mdx +9 -0
- package/src/articles/travel.mdx +21 -0
- package/src/articles/warming-up.mdx +10 -0
- package/src/articles/web-burnning.mdx +10 -0
- package/src/auth_required.tsx +17 -0
- package/src/components/Spinner.tsx +33 -0
- package/src/components/article/index.tsx +31 -0
- package/src/components/aspect_ratio_box/index.tsx +29 -0
- package/src/components/blur_cover/index.tsx +28 -0
- package/src/components/book_list/index.tsx +50 -0
- package/src/components/comment/index.tsx +70 -0
- package/src/components/comment/use_cusdis_event.ts +37 -0
- package/src/components/corner_prompt_box/index.tsx +63 -0
- package/src/components/disabled_text/index.tsx +23 -0
- package/src/components/fade_out_cover/index.tsx +37 -0
- package/src/components/footer/footer_links.ts +13 -0
- package/src/components/footer/index.tsx +21 -0
- package/src/components/hotkey_nav/index.tsx +50 -0
- package/src/components/img_list/index.tsx +43 -0
- package/src/components/index.tsx +27 -0
- package/src/components/movie_list/index.tsx +50 -0
- package/src/components/my_suspense.tsx +14 -0
- package/src/components/progress_bar/index.tsx +31 -0
- package/src/components/reload_prompt/index.tsx +36 -0
- package/src/components/stickers/index.tsx +46 -0
- package/src/components/table_skeleton/index.tsx +40 -0
- package/src/components/tags/index.tsx +52 -0
- package/src/components/video_player/index.tsx +81 -0
- package/src/components/with_wrapper/index.tsx +13 -0
- package/src/constants/cusdis.ts +6 -0
- package/src/constants/index.ts +16 -0
- package/src/constants/photo_projects.ts +54 -0
- package/src/constants/photos.ts +270 -0
- package/src/constants/routes.ts +24 -0
- package/src/constants/video_logs.ts +16 -0
- package/src/demo/DemoBox.tsx +15 -0
- package/src/demo/ImgDemo.tsx +34 -0
- package/src/demo/SpinnerDemo.tsx +17 -0
- package/src/global/mdx.d.ts +8 -0
- package/src/global_loading_state_provider.tsx +27 -0
- package/src/hooks/index.ts +15 -0
- package/src/hooks/useScrollToTop.ts +24 -0
- package/src/hooks/useTransitionCls.ts +36 -0
- package/src/hooks/use_img_loading.ts +16 -0
- package/src/hooks/use_pathname.ts +6 -0
- package/src/hooks/use_paths.ts +30 -0
- package/src/hooks/use_projects.ts +56 -0
- package/src/hooks/use_route_name.ts +7 -0
- package/src/hooks/use_supa_session.ts +30 -0
- package/src/hooks/use_uploader.ts +34 -0
- package/src/hooks/use_video_controls.ts +71 -0
- package/src/main.css +156 -0
- package/src/main.tsx +19 -0
- package/src/pages/cover/index.tsx +10 -0
- package/src/pages/extensions/png/consts.ts +9 -0
- package/src/pages/extensions/png/index.tsx +41 -0
- package/src/pages/extensions/png/png_projects.tsx +63 -0
- package/src/pages/extensions/txt/article.tsx +26 -0
- package/src/pages/extensions/txt/consts.ts +8 -0
- package/src/pages/extensions/txt/index.tsx +21 -0
- package/src/pages/index.tsx +14 -0
- package/src/pages/login/index.tsx +33 -0
- package/src/pages/now/index.tsx +7 -0
- package/src/pages/tags/index.tsx +28 -0
- package/src/pages/tags/tag_result.tsx +19 -0
- package/src/swr.tsx +18 -0
- package/src/types/articles.ts +6 -0
- package/src/types/color.ts +21 -0
- package/src/types/cusdis.ts +4 -0
- package/src/types/oss.ts +15 -0
- package/src/types/path.ts +11 -0
- package/src/types/photo.ts +17 -0
- package/src/types/supabase.ts +9 -0
- package/src/utils/index.ts +143 -0
- package/src/utils/tags.ts +21 -0
- package/tailwind.config.cjs +10 -0
- package/tsconfig.json +24 -0
- package/vite.config.ts +108 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import React, { ReactEventHandler, useEffect, useState } from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import { useVideoControls, useVideoEleHeight, useVideoProgress } from "@/hooks";
|
|
4
|
+
import { BlurCover, ProgressBar } from "@/components";
|
|
5
|
+
import { BgColors, TextColors } from "@/types/color";
|
|
6
|
+
import { AspectRatioBox } from "@/components/aspect_ratio_box";
|
|
7
|
+
import { VIDEO_TAG_ASPECT_RATIO } from "@/constants";
|
|
8
|
+
|
|
9
|
+
type videoPlayProps = {
|
|
10
|
+
src: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const VideoPlayer = (props: videoPlayProps) => {
|
|
15
|
+
const { src, className } = props;
|
|
16
|
+
const [hovered, setHovered] = useState(false);
|
|
17
|
+
const [showPlayer, setShowPlayer] = useState(false);
|
|
18
|
+
const { videoRef, toggle, isPlay } = useVideoControls();
|
|
19
|
+
const { progress, onTimeUpdate } = useVideoProgress();
|
|
20
|
+
const VideoHeight = useVideoEleHeight(videoRef);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!videoRef.current) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
videoRef.current.load();
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
const onPlayerReady: ReactEventHandler = () => {
|
|
30
|
+
setShowPlayer(true);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const cls = classnames({ hidden: !showPlayer });
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
className={classnames(
|
|
38
|
+
"flex flex-col relative cursor-pointer",
|
|
39
|
+
className,
|
|
40
|
+
BgColors.LIGHT_GRAY
|
|
41
|
+
)}
|
|
42
|
+
onClick={async () => {
|
|
43
|
+
await toggle();
|
|
44
|
+
if (!isPlay) {
|
|
45
|
+
setHovered(false);
|
|
46
|
+
}
|
|
47
|
+
}}
|
|
48
|
+
onMouseEnter={() => {
|
|
49
|
+
setHovered(true);
|
|
50
|
+
}}
|
|
51
|
+
onMouseLeave={() => {
|
|
52
|
+
setHovered(false);
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<AspectRatioBox
|
|
56
|
+
width="100%"
|
|
57
|
+
hwRatio={VIDEO_TAG_ASPECT_RATIO}
|
|
58
|
+
className={BgColors.LIGHT_GRAY}
|
|
59
|
+
>
|
|
60
|
+
<video
|
|
61
|
+
playsInline
|
|
62
|
+
ref={videoRef}
|
|
63
|
+
src={src}
|
|
64
|
+
className={cls}
|
|
65
|
+
onTimeUpdate={onTimeUpdate}
|
|
66
|
+
onCanPlayThrough={onPlayerReady}
|
|
67
|
+
/>
|
|
68
|
+
</AspectRatioBox>
|
|
69
|
+
{hovered && showPlayer && (
|
|
70
|
+
<BlurCover
|
|
71
|
+
textColor={isPlay ? TextColors.RED : TextColors.BLUE}
|
|
72
|
+
height={VideoHeight}
|
|
73
|
+
visibleOnHover
|
|
74
|
+
>
|
|
75
|
+
{isPlay ? "pause" : "play"}
|
|
76
|
+
</BlurCover>
|
|
77
|
+
)}
|
|
78
|
+
{showPlayer && <ProgressBar progress={progress} />}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FunctionComponent } from "react";
|
|
3
|
+
import { ArticlePage } from "@/components/article";
|
|
4
|
+
|
|
5
|
+
export const withArticleWrapper =
|
|
6
|
+
(Component: FunctionComponent<any>): FunctionComponent<any> =>
|
|
7
|
+
(props: any) => {
|
|
8
|
+
return (
|
|
9
|
+
<ArticlePage {...props}>
|
|
10
|
+
<Component />
|
|
11
|
+
</ArticlePage>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createClient } from "@supabase/supabase-js";
|
|
2
|
+
|
|
3
|
+
export { PHOTO_PROJECTS } from "./photo_projects";
|
|
4
|
+
export { VIDEO_LOGS, VIDEO_TAG_ASPECT_RATIO } from "./video_logs";
|
|
5
|
+
export { ROUTES, ROUTE_NAME, GITHUB_REPO_ADDRESS } from "./routes";
|
|
6
|
+
export const DEFAULT_DELAY = 200;
|
|
7
|
+
export const SUPABASE: {
|
|
8
|
+
ANNO: string;
|
|
9
|
+
URL: string;
|
|
10
|
+
BB_KING_ID: string;
|
|
11
|
+
} = {
|
|
12
|
+
ANNO: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImN2eHFtdXNmYXh3dXl2eXV1ZWNvIiwicm9sZSI6ImFub24iLCJpYXQiOjE2NDQ4MjkwNTEsImV4cCI6MTk2MDQwNTA1MX0.lg90OVR7s6tjbDamVaI9FR2M2fc6OVfsfGd4j9MXu3M",
|
|
13
|
+
URL: "https://cvxqmusfaxwuyvyuueco.supabase.co",
|
|
14
|
+
BB_KING_ID: "e6795b1d-7ee0-4afe-be63-796670848175",
|
|
15
|
+
};
|
|
16
|
+
export const supabase = createClient(SUPABASE.URL, SUPABASE.ANNO);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { OSS_PHOTOS } from "@/constants/photos";
|
|
2
|
+
import { PhotoProject } from "@/types/photo";
|
|
3
|
+
|
|
4
|
+
export const PHOTO_PROJECTS: PhotoProject[] = [
|
|
5
|
+
{
|
|
6
|
+
name: "过去的来意",
|
|
7
|
+
description: '"往事越千年"',
|
|
8
|
+
images: [OSS_PHOTOS.quyuan, OSS_PHOTOS.weapons, OSS_PHOTOS.stone],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "敬县城",
|
|
12
|
+
description: '"早秋惊落叶,飘零似客心。翻飞未肯下,犹言忆故林。"',
|
|
13
|
+
images: [
|
|
14
|
+
OSS_PHOTOS.motorcycle,
|
|
15
|
+
OSS_PHOTOS.cycle,
|
|
16
|
+
OSS_PHOTOS.corner,
|
|
17
|
+
OSS_PHOTOS.streetGames,
|
|
18
|
+
OSS_PHOTOS.localDishes,
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "海底的家",
|
|
23
|
+
description:
|
|
24
|
+
'"河流用一生梳理 \\ 地球的表情 \\ 沿岸收集人類的喜怒哀樂 \\ 檔案堆滿了海底的家"',
|
|
25
|
+
images: [
|
|
26
|
+
OSS_PHOTOS.playWithWater,
|
|
27
|
+
OSS_PHOTOS.shopping,
|
|
28
|
+
OSS_PHOTOS.chess,
|
|
29
|
+
OSS_PHOTOS.player,
|
|
30
|
+
// OSS_PHOTOS.swimmer,
|
|
31
|
+
OSS_PHOTOS.players,
|
|
32
|
+
// OSS_PHOTOS.dragonRiver,
|
|
33
|
+
// OSS_PHOTOS.riverAndBoats,
|
|
34
|
+
OSS_PHOTOS.riverSide,
|
|
35
|
+
OSS_PHOTOS.quilt,
|
|
36
|
+
// OSS_PHOTOS.fishing,
|
|
37
|
+
OSS_PHOTOS.waterLine,
|
|
38
|
+
OSS_PHOTOS.bridge,
|
|
39
|
+
OSS_PHOTOS.building,
|
|
40
|
+
OSS_PHOTOS.smoking,
|
|
41
|
+
// OSS_PHOTOS.jzBridge,
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
// {
|
|
45
|
+
// name: "光前",
|
|
46
|
+
// description: "城中村,个人深圳经历出入口。",
|
|
47
|
+
// images: [OSS_PHOTOS.oldMan, OSS_PHOTOS.oldWomen, OSS_PHOTOS.littleChild],
|
|
48
|
+
// },
|
|
49
|
+
// {
|
|
50
|
+
// name: "三百零一",
|
|
51
|
+
// description: "陋室光影",
|
|
52
|
+
// images: [OSS_PHOTOS.phone, OSS_PHOTOS.chair],
|
|
53
|
+
// },
|
|
54
|
+
];
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { BgColors } from "@/types/color";
|
|
2
|
+
import { ossProcessType } from "@/types/oss";
|
|
3
|
+
|
|
4
|
+
export const OSS_PHOTOS = {
|
|
5
|
+
playWithWater: {
|
|
6
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/DSCF2203-1.jpg",
|
|
7
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
8
|
+
processType: ossProcessType.PROG,
|
|
9
|
+
width: 1879,
|
|
10
|
+
height: 1238,
|
|
11
|
+
},
|
|
12
|
+
shopping: {
|
|
13
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/shopping.jpg",
|
|
14
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
15
|
+
width: 1746,
|
|
16
|
+
height: 1746,
|
|
17
|
+
},
|
|
18
|
+
quyuan: {
|
|
19
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/from-the-past/quyuan.webp",
|
|
20
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
21
|
+
width: 4126,
|
|
22
|
+
height: 6262,
|
|
23
|
+
},
|
|
24
|
+
stone: {
|
|
25
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/from-the-past/stone.webp",
|
|
26
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
27
|
+
renderedWidth: 300,
|
|
28
|
+
width: 5536,
|
|
29
|
+
height: 4126,
|
|
30
|
+
},
|
|
31
|
+
weapons: {
|
|
32
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/from-the-past/weapon.webp",
|
|
33
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
34
|
+
width: 6155,
|
|
35
|
+
height: 4126,
|
|
36
|
+
},
|
|
37
|
+
roof: {
|
|
38
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/DSCF1807.RAF.jpg",
|
|
39
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
40
|
+
width: 6262,
|
|
41
|
+
height: 3278,
|
|
42
|
+
},
|
|
43
|
+
chess: {
|
|
44
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/checkmate.webp",
|
|
45
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
46
|
+
width: 6262,
|
|
47
|
+
height: 4126,
|
|
48
|
+
},
|
|
49
|
+
swimmer: {
|
|
50
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/swimmer.jpg",
|
|
51
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
52
|
+
width: 6081,
|
|
53
|
+
height: 4126,
|
|
54
|
+
},
|
|
55
|
+
player: {
|
|
56
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/player-min.webp",
|
|
57
|
+
width: 2692,
|
|
58
|
+
height: 3546,
|
|
59
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
60
|
+
},
|
|
61
|
+
players: {
|
|
62
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/players.jpg",
|
|
63
|
+
width: 3368,
|
|
64
|
+
height: 2344,
|
|
65
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
66
|
+
},
|
|
67
|
+
fishing: {
|
|
68
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/p2705047873.webp",
|
|
69
|
+
thumbnailSrc:
|
|
70
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/p2705047873.webp?x-oss-process=style/thumbnail",
|
|
71
|
+
width: 1080,
|
|
72
|
+
height: 720,
|
|
73
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
74
|
+
},
|
|
75
|
+
dragonRiver: {
|
|
76
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/164-2.jpg",
|
|
77
|
+
width: 4021,
|
|
78
|
+
height: 4021,
|
|
79
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
80
|
+
},
|
|
81
|
+
waterLine: {
|
|
82
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/p2704851973.webp",
|
|
83
|
+
thumbnailSrc:
|
|
84
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/p2704851973.webp?x-oss-process=style/thumbnail",
|
|
85
|
+
renderedWidth: 500,
|
|
86
|
+
width: 1080,
|
|
87
|
+
height: 720,
|
|
88
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
89
|
+
},
|
|
90
|
+
phone: {
|
|
91
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/301/DSCF1355.RAF.min.jpg",
|
|
92
|
+
width: 924,
|
|
93
|
+
height: 619,
|
|
94
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
95
|
+
},
|
|
96
|
+
riverAndBoats: {
|
|
97
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/x2705749244.jpg",
|
|
98
|
+
renderedWidth: 800,
|
|
99
|
+
width: 1080,
|
|
100
|
+
height: 830,
|
|
101
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
102
|
+
},
|
|
103
|
+
riverSide: {
|
|
104
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/x2705752731.jpg",
|
|
105
|
+
renderedWidth: 400,
|
|
106
|
+
width: 1080,
|
|
107
|
+
height: 720,
|
|
108
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
109
|
+
},
|
|
110
|
+
quilt: {
|
|
111
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/x2710816755.jpg",
|
|
112
|
+
thumbnailSrc:
|
|
113
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/x2710816755.jpg?x-oss-process=style/thumbnail",
|
|
114
|
+
renderedWidth: 490,
|
|
115
|
+
width: 1080,
|
|
116
|
+
height: 832,
|
|
117
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
118
|
+
},
|
|
119
|
+
bridge: {
|
|
120
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/p2705529760.webp",
|
|
121
|
+
thumbnailSrc:
|
|
122
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/p2705529760.webp?x-oss-process=style/thumbnail",
|
|
123
|
+
renderedWidth: 450,
|
|
124
|
+
width: 1080,
|
|
125
|
+
height: 726,
|
|
126
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
127
|
+
},
|
|
128
|
+
building: {
|
|
129
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211025194518.jpg",
|
|
130
|
+
thumbnailSrc:
|
|
131
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20211025194518.jpg?x-oss-process=style/thumbnail",
|
|
132
|
+
width: 3019,
|
|
133
|
+
height: 2293,
|
|
134
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
135
|
+
},
|
|
136
|
+
chair: {
|
|
137
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/301/room-301.jpg",
|
|
138
|
+
renderedWidth: 490,
|
|
139
|
+
width: 970,
|
|
140
|
+
height: 745,
|
|
141
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
142
|
+
},
|
|
143
|
+
smoking: {
|
|
144
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/DSCF1383.jpg",
|
|
145
|
+
width: 2023,
|
|
146
|
+
height: 2670,
|
|
147
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
148
|
+
},
|
|
149
|
+
jzBridge: {
|
|
150
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/xiang-jiang-river/DSCF1401.jpg",
|
|
151
|
+
width: 5980,
|
|
152
|
+
height: 3699,
|
|
153
|
+
renderedWidth: 700,
|
|
154
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
155
|
+
},
|
|
156
|
+
motorcycle: {
|
|
157
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/4688FF3F-8EF5-4F63-B726-9AC275C1A97E-50268-000009856F7D5885.jpg",
|
|
158
|
+
thumbnailSrc:
|
|
159
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/4688FF3F-8EF5-4F63-B726-9AC275C1A97E-50268-000009856F7D5885.jpg?x-oss-process=style/thumbnail",
|
|
160
|
+
width: 1306,
|
|
161
|
+
height: 821,
|
|
162
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
163
|
+
},
|
|
164
|
+
cycle: {
|
|
165
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/3922C86B-79D5-455F-9FA8-7EB405CE95A6-38852-000007863DB50E30.jpg",
|
|
166
|
+
thumbnailSrc:
|
|
167
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/3922C86B-79D5-455F-9FA8-7EB405CE95A6-38852-000007863DB50E30.jpg?x-oss-process=style/thumbnail",
|
|
168
|
+
renderedWidth: 400,
|
|
169
|
+
width: 1501,
|
|
170
|
+
height: 1144,
|
|
171
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
172
|
+
},
|
|
173
|
+
streetGames: {
|
|
174
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/B3AACBCA-807B-44C0-9CA2-E1F7E0C00C93_black.jpg",
|
|
175
|
+
thumbnailSrc:
|
|
176
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/B3AACBCA-807B-44C0-9CA2-E1F7E0C00C93_black.jpg?x-oss-process=style/thumbnail",
|
|
177
|
+
width: 898,
|
|
178
|
+
height: 729,
|
|
179
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
180
|
+
},
|
|
181
|
+
corner: {
|
|
182
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/E2FDA467-AD6D-4410-9B50-66E1624C13D6-38852-0000078630EDA7C4.jpg",
|
|
183
|
+
thumbnailSrc:
|
|
184
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/E2FDA467-AD6D-4410-9B50-66E1624C13D6-38852-0000078630EDA7C4.jpg?x-oss-process=style/thumbnail",
|
|
185
|
+
renderedWidth: 500,
|
|
186
|
+
width: 1776,
|
|
187
|
+
height: 1184,
|
|
188
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
189
|
+
},
|
|
190
|
+
localDishes: {
|
|
191
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/IMG_3869.JPG",
|
|
192
|
+
thumbnailSrc:
|
|
193
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/county-town/IMG_3869.JPG?x-oss-process=style/thumbnail",
|
|
194
|
+
renderedWidth: 490,
|
|
195
|
+
width: 897,
|
|
196
|
+
height: 720,
|
|
197
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
198
|
+
},
|
|
199
|
+
oldMan: {
|
|
200
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/before-the-light/IMG_1844.jpg?x-oss-process=style/webp",
|
|
201
|
+
thumbnailSrc:
|
|
202
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/before-the-light/IMG_1844.jpg?x-oss-process=style/thumbnail",
|
|
203
|
+
renderedWidth: 400,
|
|
204
|
+
width: 2673,
|
|
205
|
+
height: 3564,
|
|
206
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
207
|
+
},
|
|
208
|
+
oldWomen: {
|
|
209
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/before-the-light/IMG_E1668.JPG?x-oss-process=style/webp",
|
|
210
|
+
thumbnailSrc:
|
|
211
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/before-the-light/IMG_E1668.JPG?x-oss-process=style/thumbnail",
|
|
212
|
+
width: 1325,
|
|
213
|
+
height: 1960,
|
|
214
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
215
|
+
},
|
|
216
|
+
littleChild: {
|
|
217
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/before-the-light/IMG_E1677.JPG",
|
|
218
|
+
thumbnailSrc:
|
|
219
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/before-the-light/IMG_E1677.JPG?x-oss-process=style/thumbnail",
|
|
220
|
+
width: 2801,
|
|
221
|
+
renderedWidth: 600,
|
|
222
|
+
height: 2801,
|
|
223
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
224
|
+
},
|
|
225
|
+
logoPreview: {
|
|
226
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/favicon.png",
|
|
227
|
+
width: 640,
|
|
228
|
+
height: 640,
|
|
229
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
230
|
+
},
|
|
231
|
+
validLogoExample: {
|
|
232
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/Logo-with-image.png",
|
|
233
|
+
width: 1092,
|
|
234
|
+
height: 1386,
|
|
235
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
236
|
+
},
|
|
237
|
+
logoVariants: {
|
|
238
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/valid-variations.png",
|
|
239
|
+
width: 2800,
|
|
240
|
+
height: 640,
|
|
241
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
242
|
+
},
|
|
243
|
+
badLogoExamples: {
|
|
244
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/Bad-Examples.png",
|
|
245
|
+
width: 2801,
|
|
246
|
+
height: 1362,
|
|
247
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
248
|
+
},
|
|
249
|
+
logoColors: {
|
|
250
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/colors.png",
|
|
251
|
+
thumbnailSrc:
|
|
252
|
+
"https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/colors.png?x-oss-process=style/thumbnail",
|
|
253
|
+
width: 2466,
|
|
254
|
+
height: 640,
|
|
255
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
256
|
+
},
|
|
257
|
+
logoExcludesZone: {
|
|
258
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/image/illustration/illustration/Logo-Clear-Area.png",
|
|
259
|
+
width: 1000,
|
|
260
|
+
height: 1000,
|
|
261
|
+
avgColor: BgColors.LIGHT_GRAY,
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export const PHOTOS_FOR_DEMO = [
|
|
266
|
+
OSS_PHOTOS.riverSide,
|
|
267
|
+
OSS_PHOTOS.stone,
|
|
268
|
+
OSS_PHOTOS.chair,
|
|
269
|
+
OSS_PHOTOS.weapons,
|
|
270
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const ROUTES = {
|
|
2
|
+
INDEX: "/",
|
|
3
|
+
CONTENT: "/blog",
|
|
4
|
+
HELP: "/blog/说明书",
|
|
5
|
+
TAGS: "/tags",
|
|
6
|
+
BLOG: "/blog",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const ROUTE_NAME = {
|
|
10
|
+
[ROUTES.CONTENT]: "目录",
|
|
11
|
+
[ROUTES.BLOG]: "文章",
|
|
12
|
+
unknown: "未知",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const GITHUB_REPO_ADDRESS = "https://github.com/bbbottle/bbki.ng";
|
|
16
|
+
export const OSS_ADDRESS = "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com";
|
|
17
|
+
export const API_ENDPOINT = "https://api.bbki.ng";
|
|
18
|
+
export const API = {
|
|
19
|
+
PROJECTS: "projects",
|
|
20
|
+
UPLOAD_IMG: "upload",
|
|
21
|
+
MOVIES: "movies",
|
|
22
|
+
IMAGES: "images",
|
|
23
|
+
BOOKS: "books",
|
|
24
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const VIDEO_LOGS = [
|
|
2
|
+
{
|
|
3
|
+
name: "2021-09-10",
|
|
4
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/video/2021-09-10",
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
name: "2020-09-18",
|
|
8
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/video/2021-09-18.mov",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "2020-09-28",
|
|
12
|
+
src: "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com/video/2021-09-28-4k30H.mov",
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export const VIDEO_TAG_ASPECT_RATIO = 0.5624910522548318;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export const DemoBox = (props: {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
style?: React.CSSProperties;
|
|
6
|
+
}) => {
|
|
7
|
+
return (
|
|
8
|
+
<div
|
|
9
|
+
className="grid place-items-center md:p-32 border-gray-400 aspect-square border border-dotted"
|
|
10
|
+
style={props.style || {}}
|
|
11
|
+
>
|
|
12
|
+
{props.children}
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { Button, Img, ImgProps } from "@bbki.ng/components";
|
|
3
|
+
import { PHOTOS_FOR_DEMO } from "@/constants/photos";
|
|
4
|
+
import { DemoBox } from "@/demo/DemoBox";
|
|
5
|
+
import { Photo } from "@/types/photo";
|
|
6
|
+
|
|
7
|
+
const ImgWrapper = (props: ImgProps) => {
|
|
8
|
+
return (
|
|
9
|
+
<DemoBox>
|
|
10
|
+
<Img {...props} />
|
|
11
|
+
</DemoBox>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const ImgDemo = () => {
|
|
16
|
+
const [count, setCount] = useState(0);
|
|
17
|
+
const refresh = () => {
|
|
18
|
+
setCount(count + 1);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const images: Photo[] = PHOTOS_FOR_DEMO;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
<ImgWrapper
|
|
26
|
+
{...images[count % images.length]}
|
|
27
|
+
key={count}
|
|
28
|
+
/>
|
|
29
|
+
<Button onClick={refresh} className="mx-32 my-16">
|
|
30
|
+
刷新
|
|
31
|
+
</Button>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { DemoBox } from "@/demo/DemoBox.js";
|
|
3
|
+
import { Spinner } from "@/components/Spinner";
|
|
4
|
+
|
|
5
|
+
export const SpinnerDemo = () => {
|
|
6
|
+
return (
|
|
7
|
+
<DemoBox style={{ background: "#dc5530", borderColor: "white" }}>
|
|
8
|
+
<Spinner
|
|
9
|
+
disableDotIndicator
|
|
10
|
+
offset={0}
|
|
11
|
+
length={0.4}
|
|
12
|
+
color={[255, 255, 255, 1]}
|
|
13
|
+
multiplier={20000}
|
|
14
|
+
/>
|
|
15
|
+
</DemoBox>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
ReactNode,
|
|
4
|
+
useState,
|
|
5
|
+
Dispatch,
|
|
6
|
+
SetStateAction,
|
|
7
|
+
} from "react";
|
|
8
|
+
|
|
9
|
+
type LoadingContext = {
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
setIsLoading: Dispatch<SetStateAction<boolean>>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const GlobalLoadingContext = createContext<LoadingContext>({
|
|
15
|
+
isLoading: false,
|
|
16
|
+
setIsLoading: () => false,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const GlobalLoadingStateProvider = (props: { children: ReactNode }) => {
|
|
20
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<GlobalLoadingContext.Provider value={{ isLoading, setIsLoading }}>
|
|
24
|
+
{props.children}
|
|
25
|
+
</GlobalLoadingContext.Provider>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { buildSimpleApiHooks } from "@/utils";
|
|
2
|
+
import { API } from "@/constants/routes";
|
|
3
|
+
|
|
4
|
+
export { usePaths } from "./use_paths";
|
|
5
|
+
export { useRouteName } from "./use_route_name";
|
|
6
|
+
export { useImgLoading } from "./use_img_loading";
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
useVideoControls,
|
|
10
|
+
useVideoProgress,
|
|
11
|
+
useVideoEleHeight,
|
|
12
|
+
} from "./use_video_controls";
|
|
13
|
+
|
|
14
|
+
export const useMovies = buildSimpleApiHooks(API.MOVIES, "movies");
|
|
15
|
+
export const useBooks = buildSimpleApiHooks(API.BOOKS, "books");
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useLocation } from "react-router-dom";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
|
|
4
|
+
export const useScrollToTop = (excludePath = "") => {
|
|
5
|
+
const { pathname } = useLocation();
|
|
6
|
+
|
|
7
|
+
const resetScroll = () => {
|
|
8
|
+
if (excludePath && pathname.includes(excludePath)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
window.scrollTo(0, 0);
|
|
13
|
+
}, 0);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
window.addEventListener("popstate", resetScroll);
|
|
18
|
+
return () => {
|
|
19
|
+
window.removeEventListener("popstate", resetScroll);
|
|
20
|
+
};
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
useEffect(resetScroll, [pathname]);
|
|
24
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
|
|
4
|
+
interface TransOption {
|
|
5
|
+
originCls?: string;
|
|
6
|
+
opacity?: boolean;
|
|
7
|
+
offset?: boolean;
|
|
8
|
+
blur?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const defaultOpt = {
|
|
12
|
+
originCls: "",
|
|
13
|
+
opacity: true,
|
|
14
|
+
offset: true,
|
|
15
|
+
blur: true,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const useTransitionCls = (options: TransOption = defaultOpt) => {
|
|
19
|
+
const [visible, setVisible] = React.useState(false);
|
|
20
|
+
const { originCls, opacity, offset, blur } = options;
|
|
21
|
+
|
|
22
|
+
const cls = classnames(originCls, "transition-all", "duration-500", {
|
|
23
|
+
"blur-sm": !visible && blur,
|
|
24
|
+
"blur-none": visible && blur,
|
|
25
|
+
"translate-y-0": visible && offset,
|
|
26
|
+
"translate-y-8": !visible && offset,
|
|
27
|
+
"opacity-10": !visible && opacity,
|
|
28
|
+
"opacity-100": visible && opacity,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
setVisible(true);
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
return cls;
|
|
36
|
+
};
|