@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.
Files changed (117) hide show
  1. package/.github/workflows/deploy.yml +44 -0
  2. package/.husky/pre-commit +4 -0
  3. package/.prettierignore +1 -0
  4. package/.prettierrc.json +1 -0
  5. package/.rush/temp/shrinkwrap-deps.json +908 -0
  6. package/CODE_OF_CONDUCT.md +45 -0
  7. package/CONTRIBUTING.md +11 -0
  8. package/LICENSE +21 -0
  9. package/README.md +21 -0
  10. package/index.html +33 -0
  11. package/jest.config.js +15 -0
  12. package/package.json +69 -0
  13. package/postcss.config.cjs +6 -0
  14. package/public/Logo.svg +9 -0
  15. package/public/apple-touch-icon.png +0 -0
  16. package/public/favicon-16x16.png +0 -0
  17. package/public/favicon-32x32.png +0 -0
  18. package/public/favicon.ico +0 -0
  19. package/public/favicon.svg +9 -0
  20. package/public/pwa-192x192.png +0 -0
  21. package/public/pwa-512x512.png +0 -0
  22. package/public/robots.txt +2 -0
  23. package/src/__test__/utils/index.test.ts +90 -0
  24. package/src/app.tsx +97 -0
  25. package/src/articles/anti-logic.mdx +61 -0
  26. package/src/articles/bbking-manual.mdx +88 -0
  27. package/src/articles/black-river.mdx +8 -0
  28. package/src/articles/cooldown.mdx +12 -0
  29. package/src/articles/fall.mdx +8 -0
  30. package/src/articles/img.mdx +104 -0
  31. package/src/articles/index.ts +35 -0
  32. package/src/articles/loading.mdx +129 -0
  33. package/src/articles/major-cold.mdx +14 -0
  34. package/src/articles/men-without-women.mdx +19 -0
  35. package/src/articles/movie-day.mdx +15 -0
  36. package/src/articles/now.mdx +15 -0
  37. package/src/articles/projects.mdx +9 -0
  38. package/src/articles/quote.mdx +27 -0
  39. package/src/articles/spring-cooldown.mdx +7 -0
  40. package/src/articles/spring-rain.mdx +9 -0
  41. package/src/articles/travel.mdx +21 -0
  42. package/src/articles/warming-up.mdx +10 -0
  43. package/src/articles/web-burnning.mdx +10 -0
  44. package/src/auth_required.tsx +17 -0
  45. package/src/components/Spinner.tsx +33 -0
  46. package/src/components/article/index.tsx +31 -0
  47. package/src/components/aspect_ratio_box/index.tsx +29 -0
  48. package/src/components/blur_cover/index.tsx +28 -0
  49. package/src/components/book_list/index.tsx +50 -0
  50. package/src/components/comment/index.tsx +70 -0
  51. package/src/components/comment/use_cusdis_event.ts +37 -0
  52. package/src/components/corner_prompt_box/index.tsx +63 -0
  53. package/src/components/disabled_text/index.tsx +23 -0
  54. package/src/components/fade_out_cover/index.tsx +37 -0
  55. package/src/components/footer/footer_links.ts +13 -0
  56. package/src/components/footer/index.tsx +21 -0
  57. package/src/components/hotkey_nav/index.tsx +50 -0
  58. package/src/components/img_list/index.tsx +43 -0
  59. package/src/components/index.tsx +27 -0
  60. package/src/components/movie_list/index.tsx +50 -0
  61. package/src/components/my_suspense.tsx +14 -0
  62. package/src/components/progress_bar/index.tsx +31 -0
  63. package/src/components/reload_prompt/index.tsx +36 -0
  64. package/src/components/stickers/index.tsx +46 -0
  65. package/src/components/table_skeleton/index.tsx +40 -0
  66. package/src/components/tags/index.tsx +52 -0
  67. package/src/components/video_player/index.tsx +81 -0
  68. package/src/components/with_wrapper/index.tsx +13 -0
  69. package/src/constants/cusdis.ts +6 -0
  70. package/src/constants/index.ts +16 -0
  71. package/src/constants/photo_projects.ts +54 -0
  72. package/src/constants/photos.ts +270 -0
  73. package/src/constants/routes.ts +24 -0
  74. package/src/constants/video_logs.ts +16 -0
  75. package/src/demo/DemoBox.tsx +15 -0
  76. package/src/demo/ImgDemo.tsx +34 -0
  77. package/src/demo/SpinnerDemo.tsx +17 -0
  78. package/src/global/mdx.d.ts +8 -0
  79. package/src/global_loading_state_provider.tsx +27 -0
  80. package/src/hooks/index.ts +15 -0
  81. package/src/hooks/useScrollToTop.ts +24 -0
  82. package/src/hooks/useTransitionCls.ts +36 -0
  83. package/src/hooks/use_img_loading.ts +16 -0
  84. package/src/hooks/use_pathname.ts +6 -0
  85. package/src/hooks/use_paths.ts +30 -0
  86. package/src/hooks/use_projects.ts +56 -0
  87. package/src/hooks/use_route_name.ts +7 -0
  88. package/src/hooks/use_supa_session.ts +30 -0
  89. package/src/hooks/use_uploader.ts +34 -0
  90. package/src/hooks/use_video_controls.ts +71 -0
  91. package/src/main.css +156 -0
  92. package/src/main.tsx +19 -0
  93. package/src/pages/cover/index.tsx +10 -0
  94. package/src/pages/extensions/png/consts.ts +9 -0
  95. package/src/pages/extensions/png/index.tsx +41 -0
  96. package/src/pages/extensions/png/png_projects.tsx +63 -0
  97. package/src/pages/extensions/txt/article.tsx +26 -0
  98. package/src/pages/extensions/txt/consts.ts +8 -0
  99. package/src/pages/extensions/txt/index.tsx +21 -0
  100. package/src/pages/index.tsx +14 -0
  101. package/src/pages/login/index.tsx +33 -0
  102. package/src/pages/now/index.tsx +7 -0
  103. package/src/pages/tags/index.tsx +28 -0
  104. package/src/pages/tags/tag_result.tsx +19 -0
  105. package/src/swr.tsx +18 -0
  106. package/src/types/articles.ts +6 -0
  107. package/src/types/color.ts +21 -0
  108. package/src/types/cusdis.ts +4 -0
  109. package/src/types/oss.ts +15 -0
  110. package/src/types/path.ts +11 -0
  111. package/src/types/photo.ts +17 -0
  112. package/src/types/supabase.ts +9 -0
  113. package/src/utils/index.ts +143 -0
  114. package/src/utils/tags.ts +21 -0
  115. package/tailwind.config.cjs +10 -0
  116. package/tsconfig.json +24 -0
  117. package/vite.config.ts +108 -0
@@ -0,0 +1,28 @@
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
+ };
@@ -0,0 +1,19 @@
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
+ };
package/src/swr.tsx ADDED
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { SWRConfig } from "swr";
3
+ import { apiFetcher, withToken } from "@/utils";
4
+ import { useSupabaseSession } from "@/hooks/use_supa_session";
5
+
6
+ export const SWR = (props: { children: any }) => {
7
+ const { access_token: token } = useSupabaseSession() || {};
8
+ const authedApiFetcher = withToken(apiFetcher)(token);
9
+ return (
10
+ <SWRConfig
11
+ value={{
12
+ fetcher: authedApiFetcher,
13
+ }}
14
+ >
15
+ {props.children}
16
+ </SWRConfig>
17
+ );
18
+ };
@@ -0,0 +1,6 @@
1
+ import { FunctionComponent } from "react";
2
+
3
+ export type MdxArticle = {
4
+ default: FunctionComponent<any>;
5
+ meta: any;
6
+ };
@@ -0,0 +1,21 @@
1
+ export enum TextColors {
2
+ GRAY = "text-gray-400",
3
+ RED = "text-red-500",
4
+ BLUE = "text-blue-600",
5
+ }
6
+
7
+ export enum BgColors {
8
+ WHITE_GRAY = "bg-gray-50",
9
+ LIGHT_GRAY = "bg-gray-100",
10
+ GRAY = "bg-gray-400",
11
+ RED = "bg-red-500",
12
+ BLUE = "bg-blue-600",
13
+ LIGHT_BLUE = "bg-blue-300",
14
+ WHITE_BLUE = "bg-blue-100",
15
+ }
16
+
17
+ export enum HoveredTextColors {
18
+ GRAY = "hover:bg-gray-100",
19
+ RED = "hover:bg-red-100",
20
+ BLUR = "hover:bg-blue-100",
21
+ }
@@ -0,0 +1,4 @@
1
+ export enum cusdisEvent {
2
+ COMMENTS_LOADED = "COMMENTS_LOADED",
3
+ COMMENT_SENT = "COMMENT_SENT",
4
+ }
@@ -0,0 +1,15 @@
1
+ export enum ossProcessType {
2
+ THUMBNAIL = "thumbnail",
3
+ WEBP = "webp",
4
+ NULL = "null",
5
+ oWEBP = "owebp",
6
+ PROG = "prog",
7
+ }
8
+
9
+ export interface UploadResult {
10
+ name: string;
11
+ res: {
12
+ status: number;
13
+ };
14
+ url: string;
15
+ }
@@ -0,0 +1,11 @@
1
+ import { FunctionComponent } from "react";
2
+
3
+ export interface pathObj {
4
+ path?: string;
5
+ name: string;
6
+ }
7
+
8
+ export interface compPathObj extends pathObj {
9
+ component: FunctionComponent<any>;
10
+ componentProps?: any;
11
+ }
@@ -0,0 +1,17 @@
1
+ import { ossProcessType } from "@/types/oss";
2
+
3
+ export interface Photo {
4
+ src: string;
5
+ width: number;
6
+ height: number;
7
+ processType?: ossProcessType;
8
+ avgColor?: string;
9
+ thumbnailSrc?: string;
10
+ renderedWidth?: number;
11
+ }
12
+
13
+ export interface PhotoProject {
14
+ name: string;
15
+ description?: string;
16
+ images: Photo[];
17
+ }
@@ -0,0 +1,9 @@
1
+ import { Session } from "@supabase/supabase-js";
2
+
3
+ export interface BBKingSession extends Session {
4
+ isKing: boolean;
5
+ }
6
+
7
+ export enum OauthProvider {
8
+ GITHUB = "github",
9
+ }
@@ -0,0 +1,143 @@
1
+ import { Photo } from "@/types/photo";
2
+ import { ossProcessType } from "@/types/oss";
3
+ import { API_ENDPOINT, OSS_ADDRESS } from "@/constants/routes";
4
+ import { DEFAULT_DELAY } from "@/constants";
5
+ import useSWR, { Fetcher } from "swr";
6
+
7
+ export const floatNumberToPercentageString = (num: number): string => {
8
+ return `${num * 100}%`;
9
+ };
10
+
11
+ export const delay = (time: number) => {
12
+ return new Promise((resolve) => {
13
+ setTimeout(resolve, time);
14
+ });
15
+ };
16
+
17
+ export const minDelay = async (
18
+ promise: Promise<any>,
19
+ time: number = DEFAULT_DELAY
20
+ ): Promise<any> => {
21
+ const delayPromise = delay(time);
22
+ await Promise.all([delayPromise, promise]);
23
+ return promise;
24
+ };
25
+
26
+ export const addOssWebpProcessStyle = (
27
+ originUrl: string,
28
+ style: ossProcessType
29
+ ): string => {
30
+ const isInvalidOSSImgUrl = !originUrl.startsWith(OSS_ADDRESS);
31
+ const isProcessedOssImg = /x-oss-process=style\/\w+/.test(originUrl);
32
+ const isWebpImg = /webp$/.test(originUrl);
33
+
34
+ if (
35
+ isInvalidOSSImgUrl ||
36
+ isProcessedOssImg ||
37
+ (isWebpImg && style === ossProcessType.WEBP) ||
38
+ style === ossProcessType.NULL
39
+ ) {
40
+ return originUrl;
41
+ }
42
+ return `${originUrl}?x-oss-process=style/${style}`;
43
+ };
44
+
45
+ export const calcDefaultImgSize = (
46
+ img: Photo,
47
+ defaultWidth?: number,
48
+ scale?: number
49
+ ): { width: number; height: number } => {
50
+ const { width, height } = img;
51
+ const whRatio = width / height;
52
+ const isHorizontal = width > height;
53
+
54
+ const finalWidth =
55
+ (defaultWidth || (isHorizontal ? 576 : 384)) * (scale || 1);
56
+
57
+ return {
58
+ width: finalWidth,
59
+ height: finalWidth / whRatio,
60
+ };
61
+ };
62
+
63
+ export const getEnv = () => {
64
+ return /^http:\/\/localhost/.test(location.href)
65
+ ? "development"
66
+ : "production";
67
+ };
68
+
69
+ export const baseFetcher = (resource: string, init: RequestInit = {}) =>
70
+ fetch(resource, init).then((res) => res.json());
71
+
72
+ export const withToken =
73
+ (fetcher: Fetcher) =>
74
+ (token?: string) =>
75
+ (resource: string, init: RequestInit = {}) => {
76
+ const { headers = {} } = init;
77
+ const tokenHeaders = token
78
+ ? {
79
+ "X-Supabase-Auth": token,
80
+ }
81
+ : {};
82
+ const finalHeaders = {
83
+ ...headers,
84
+ ...tokenHeaders,
85
+ };
86
+ return fetcher(resource, {
87
+ ...init,
88
+ headers: finalHeaders,
89
+ });
90
+ };
91
+
92
+ export const withBBApi =
93
+ (fetcher: Fetcher<Promise<void>>) =>
94
+ (apiEndPoint = API_ENDPOINT): Fetcher =>
95
+ async (resource: string, init: RequestInit = {}) =>
96
+ fetcher(`${apiEndPoint}/${resource}`, { ...init, mode: "cors" });
97
+
98
+ export const apiFetcher = withBBApi(baseFetcher)(API_ENDPOINT);
99
+
100
+ export const getImageFileSize = (
101
+ file: File
102
+ ): Promise<{ width: number; height: number }> => {
103
+ const url = URL.createObjectURL(file);
104
+ const img = new Image();
105
+ return new Promise((resolve) => {
106
+ img.src = url;
107
+ img.onload = function (e) {
108
+ resolve({
109
+ width: img.naturalWidth,
110
+ height: img.naturalHeight,
111
+ });
112
+ };
113
+ });
114
+ };
115
+
116
+ export const buildSimpleApiHooks = (api: string, payloadKey: string) => {
117
+ return () => {
118
+ const { data, error } = useSWR(api);
119
+ return {
120
+ [payloadKey]: data,
121
+ isError: error,
122
+ isLoading: !data && !error,
123
+ };
124
+ };
125
+ };
126
+
127
+ export const imageFormatter = (image: any) => {
128
+ const { rendered_width, thumbnail_src, avg_color, process_type, ...rest } =
129
+ image;
130
+ return {
131
+ renderedWidth: rendered_width,
132
+ thumbnailSrc: thumbnail_src,
133
+ avgColor: avg_color,
134
+ processType: process_type,
135
+ ...rest,
136
+ };
137
+ };
138
+
139
+ export const getRandomInt = (min: number, max: number) => {
140
+ min = Math.ceil(min);
141
+ max = Math.floor(max);
142
+ return Math.floor(Math.random() * (max - min + 1)) + min;
143
+ };
@@ -0,0 +1,21 @@
1
+ import { MdxArticle } from "@/types/articles";
2
+ import { ROUTES } from "@/constants";
3
+
4
+ export const getAllTags = (mdxArticles: MdxArticle[]): string[] => {
5
+ return Array.from(
6
+ new Set(mdxArticles.map(({ meta }) => meta.tags || []).flat())
7
+ );
8
+ };
9
+
10
+ export const getArticleListByTag = (mdxArticles: MdxArticle[], tag: string) => {
11
+ return mdxArticles
12
+ .filter(({ meta }) => {
13
+ return meta.tags && meta.tags.includes(tag);
14
+ })
15
+ .map(({ meta }) => {
16
+ return {
17
+ to: `${ROUTES.CONTENT}/${meta.title}`,
18
+ name: meta.title,
19
+ };
20
+ });
21
+ };
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ mode: "jit",
3
+ content: [
4
+ "./index.html",
5
+ "./src/**/*.{js,ts,jsx,tsx, mdx}",
6
+ ],
7
+ presets: [
8
+ require('@bbki.ng/stylebase')
9
+ ],
10
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
6
+ "allowJs": false,
7
+ "skipLibCheck": true,
8
+ "esModuleInterop": false,
9
+ "allowSyntheticDefaultImports": true,
10
+ "strict": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "module": "ESNext",
13
+ "moduleResolution": "Node",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true,
17
+ "jsx": "react",
18
+ "baseUrl": ".",
19
+ "paths": {
20
+ "@/*": ["src/*"]
21
+ }
22
+ },
23
+ "include": ["./src", "vite.config.ts"]
24
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,108 @@
1
+ import path from "path";
2
+ import { defineConfig } from "vite";
3
+ import { VitePWA } from "vite-plugin-pwa";
4
+ import mdx from "vite-plugin-mdx";
5
+ import remarkGfm from "remark-gfm";
6
+ import remarkParse from "remark-parse";
7
+ import remarkToc from "remark-toc";
8
+ import remarkFrontmatter from "remark-frontmatter";
9
+ import { remarkMdxFrontmatter } from "remark-mdx-frontmatter";
10
+ import rehypeSlug from "rehype-slug";
11
+ import rehypeHighlight from "rehype-highlight";
12
+ import rehypeAutolinkHeadings from "rehype-autolink-headings";
13
+ import react from "@vitejs/plugin-react";
14
+
15
+ const options = {
16
+ // See https://mdxjs.com/advanced/plugins
17
+ remarkPlugins: [
18
+ remarkParse,
19
+ [remarkToc, { maxDepth: 3, heading: "目录", tight: true }],
20
+ [remarkFrontmatter, { type: "yaml", marker: "-" }],
21
+ [remarkMdxFrontmatter, { name: "meta" }],
22
+ remarkGfm,
23
+ ],
24
+ rehypePlugins: [rehypeHighlight, rehypeSlug, rehypeAutolinkHeadings],
25
+ };
26
+
27
+ // https://vitejs.dev/config/
28
+ export default defineConfig({
29
+ resolve: {
30
+ alias: {
31
+ "@": path.resolve(__dirname, "./src"),
32
+ },
33
+ },
34
+ // build.rollupOptions.output.manualChunks
35
+ build: {
36
+ rollupOptions: {
37
+ output: {
38
+ manualChunks: (id) => {
39
+ if (id.includes("node_modules")) {
40
+ return "vendor";
41
+ }
42
+ },
43
+ },
44
+ },
45
+ },
46
+ define: {
47
+ GLOBAL_BBKING_VERSION: JSON.stringify(process.env.npm_package_version),
48
+ },
49
+ esbuild: {
50
+ logOverride: { 'this-is-undefined-in-esm': 'silent' }
51
+ },
52
+ plugins: [
53
+ react(),
54
+ (mdx as any).default(options),
55
+ VitePWA({
56
+ includeAssets: [
57
+ "favicon.svg",
58
+ "robots.txt",
59
+ "apple-touch-icon.png",
60
+ "Logo.svg",
61
+ ],
62
+ workbox: {
63
+ cleanupOutdatedCaches: false,
64
+ runtimeCaching: [
65
+ {
66
+ urlPattern:
67
+ /^https:\/\/zjh-im-res\.oss-cn-shenzhen\.aliyuncs\.com\/.*/i,
68
+ handler: "CacheFirst",
69
+ options: {
70
+ cacheName: "oss-resource-cache",
71
+ expiration: {
72
+ maxEntries: 100,
73
+ maxAgeSeconds: 60 * 60 * 24 * 365, // <== 365 days
74
+ },
75
+ cacheableResponse: {
76
+ statuses: [0, 200],
77
+ },
78
+ },
79
+ },
80
+ ],
81
+ },
82
+ manifest: {
83
+ name: "BBKi.ng",
84
+ short_name: "BBKi.ng",
85
+ description: "A Personal Site.",
86
+ theme_color: "#ffffff",
87
+ icons: [
88
+ {
89
+ src: "pwa-192x192.png",
90
+ sizes: "192x192",
91
+ type: "image/png",
92
+ },
93
+ {
94
+ src: "pwa-512x512.png",
95
+ sizes: "512x512",
96
+ type: "image/png",
97
+ },
98
+ {
99
+ src: "pwa-512x512.png",
100
+ sizes: "512x512",
101
+ type: "image/png",
102
+ purpose: "any maskable",
103
+ },
104
+ ],
105
+ },
106
+ }),
107
+ ],
108
+ });