@bbki.ng/site 5.4.21 → 5.4.24
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 +22 -0
- package/index.html +12 -19
- package/package.json +5 -8
- package/src/blog/app.tsx +32 -44
- package/src/blog/components/article/index.tsx +8 -17
- package/src/blog/components/index.tsx +0 -12
- package/src/blog/components/share/share-btn.tsx +5 -8
- package/src/blog/constants/index.ts +1 -16
- package/src/blog/constants/routes.ts +12 -22
- package/src/blog/context/bbcontext.tsx +7 -7
- package/src/blog/hooks/index.ts +3 -18
- package/src/blog/hooks/use_dynamic_logo.tsx +6 -11
- package/src/blog/hooks/use_posts.ts +19 -10
- package/src/blog/hooks/use_role.ts +9 -14
- package/src/blog/hooks/use_streaming.ts +16 -16
- package/src/blog/index.tsx +5 -11
- package/src/blog/pages/cover/index.tsx +0 -1
- package/src/blog/pages/extensions/txt/article.tsx +7 -21
- package/src/blog/pages/extensions/txt/index.tsx +3 -20
- package/src/blog/pages/login/index.tsx +18 -42
- package/src/blog/swr.tsx +4 -7
- package/src/blog/utils/index.ts +9 -172
- package/vite.config.js +2 -1
- package/src/blog/articles/anti-logic.mdx +0 -61
- package/src/blog/articles/bbking-manual.mdx +0 -7
- package/src/blog/articles/black-river.mdx +0 -8
- package/src/blog/articles/celebration.mdx +0 -21
- package/src/blog/articles/cloth.mdx +0 -11
- package/src/blog/articles/cooking.mdx +0 -7
- package/src/blog/articles/cooldown.mdx +0 -12
- package/src/blog/articles/cousin.mdx +0 -15
- package/src/blog/articles/fall.mdx +0 -8
- package/src/blog/articles/img.mdx +0 -104
- package/src/blog/articles/leaves.mdx +0 -7
- package/src/blog/articles/liqiu.mdx +0 -7
- package/src/blog/articles/loading.mdx +0 -144
- package/src/blog/articles/love.mdx +0 -19
- package/src/blog/articles/major-cold.mdx +0 -14
- package/src/blog/articles/marshroom.mdx +0 -17
- package/src/blog/articles/men-without-women.mdx +0 -19
- package/src/blog/articles/moment.mdx +0 -9
- package/src/blog/articles/movie-day.mdx +0 -15
- package/src/blog/articles/photos.mdx +0 -13
- package/src/blog/articles/projects.mdx +0 -8
- package/src/blog/articles/pseudo-spring.mdx +0 -7
- package/src/blog/articles/quote.mdx +0 -26
- package/src/blog/articles/red-gun.mdx +0 -19
- package/src/blog/articles/rice-noodle.mdx +0 -21
- package/src/blog/articles/spring-cooldown.mdx +0 -8
- package/src/blog/articles/spring-rain.mdx +0 -10
- package/src/blog/articles/travel.mdx +0 -22
- package/src/blog/articles/warming-up.mdx +0 -10
- package/src/blog/articles/web-burnning.mdx +0 -10
- package/src/blog/articles/woke-up.mdx +0 -7
- package/src/blog/articles/xwy-and-snowing.mdx +0 -13
- package/src/blog/articles/xwy.mdx +0 -9
- package/src/blog/components/ImageUploader.tsx +0 -55
- package/src/blog/components/Img_ctx_menu/index.tsx +0 -67
- package/src/blog/components/Logger.tsx +0 -9
- package/src/blog/components/Pochacco/Pochacco.tsx +0 -29
- package/src/blog/components/Pochacco/idle.tsx +0 -31
- package/src/blog/components/Pochacco/watch.tsx +0 -28
- package/src/blog/components/Version.tsx +0 -14
- package/src/blog/components/app_ctx_menu/LoginMenuItem.tsx +0 -72
- package/src/blog/components/app_ctx_menu/PostMenuItem.tsx +0 -22
- package/src/blog/components/app_ctx_menu/VersionMenuItem.tsx +0 -13
- package/src/blog/components/app_ctx_menu/ViewSourceMenuItem.tsx +0 -34
- package/src/blog/components/app_ctx_menu/index.tsx +0 -35
- package/src/blog/components/article_ctx_menu/index.tsx +0 -58
- package/src/blog/components/aspect_ratio_box/index.tsx +0 -29
- package/src/blog/components/blur_cover/index.tsx +0 -28
- package/src/blog/components/hotkey_nav/index.tsx +0 -51
- package/src/blog/components/progress_bar/index.tsx +0 -31
- package/src/blog/components/reaction/emojis.tsx +0 -143
- package/src/blog/components/reaction/oh_reaction.tsx +0 -105
- package/src/blog/components/reload_prompt/index.tsx +0 -51
- package/src/blog/components/tags/index.tsx +0 -52
- package/src/blog/components/video_player/index.tsx +0 -82
- package/src/blog/global/mdx.d.ts +0 -9
- package/src/blog/hooks/useLoadingIndicator.ts +0 -12
- package/src/blog/hooks/useScrollToTop.ts +0 -24
- package/src/blog/hooks/useTransitionCls.ts +0 -36
- package/src/blog/hooks/use_authed.ts +0 -7
- package/src/blog/hooks/use_authed_fetcher.ts +0 -8
- package/src/blog/hooks/use_authed_string_post.ts +0 -42
- package/src/blog/hooks/use_clipboard_content.ts +0 -21
- package/src/blog/hooks/use_clipboard_to_post.ts +0 -48
- package/src/blog/hooks/use_del_img.ts +0 -22
- package/src/blog/hooks/use_delete_post.ts +0 -22
- package/src/blog/hooks/use_file_to_post.ts +0 -38
- package/src/blog/hooks/use_img_loading.ts +0 -16
- package/src/blog/hooks/use_post.ts +0 -26
- package/src/blog/hooks/use_projects.ts +0 -67
- package/src/blog/hooks/use_route_name.ts +0 -7
- package/src/blog/hooks/use_shared_string_to_post.ts +0 -23
- package/src/blog/hooks/use_supa_session.ts +0 -31
- package/src/blog/hooks/use_text_plain_file.ts +0 -36
- package/src/blog/hooks/use_uploader.ts +0 -34
- package/src/blog/hooks/use_video_controls.ts +0 -71
- package/src/blog/pages/upload/index.tsx +0 -39
- package/src/blog/types/supabase.ts +0 -12
- package/src/blog/types/upload.ts +0 -16
- package/src/blog/utils/tags.ts +0 -21
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import useSWR, { useSWRConfig } from "swr";
|
|
2
|
-
import { API } from "@/constants/routes";
|
|
3
|
-
import { useCallback, useContext, useEffect } from "react";
|
|
4
|
-
import { Photo } from "@/types/photo";
|
|
5
|
-
import { GlobalLoadingContext } from "@/context/global_loading_state_provider";
|
|
6
|
-
|
|
7
|
-
export const useProjects = (name: string = "", suspense?: boolean) => {
|
|
8
|
-
const URL = `${API.PROJECTS}${name ? "/" : ""}${name}`;
|
|
9
|
-
|
|
10
|
-
const { data, error } = useSWR(URL, {
|
|
11
|
-
revalidateOnFocus: false,
|
|
12
|
-
suspense,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
let isLoading = !data && !error;
|
|
16
|
-
|
|
17
|
-
const { setIsLoading } = useContext(GlobalLoadingContext);
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
setIsLoading(isLoading);
|
|
21
|
-
}, [isLoading]);
|
|
22
|
-
|
|
23
|
-
const { mutate, cache } = useSWRConfig();
|
|
24
|
-
|
|
25
|
-
const getCachedProjects = (n: string) => {
|
|
26
|
-
if (!n) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
return cache
|
|
30
|
-
.get("projects")
|
|
31
|
-
?.data.find((p: { name: string }) => p.name === n);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const refresh = useCallback(() => {
|
|
35
|
-
return mutate(URL);
|
|
36
|
-
}, [URL]);
|
|
37
|
-
|
|
38
|
-
const addLocalPhotoImmediately = useCallback(
|
|
39
|
-
(photo: Photo) => {
|
|
40
|
-
if (!name) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!data || error) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return mutate(
|
|
49
|
-
URL,
|
|
50
|
-
{
|
|
51
|
-
...data,
|
|
52
|
-
images: [photo, ...data.images],
|
|
53
|
-
},
|
|
54
|
-
false
|
|
55
|
-
);
|
|
56
|
-
},
|
|
57
|
-
[data, error]
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
refresh,
|
|
62
|
-
addLocalPhotoImmediately,
|
|
63
|
-
projects: data || getCachedProjects(name),
|
|
64
|
-
isError: error,
|
|
65
|
-
isLoading: !data && !error,
|
|
66
|
-
};
|
|
67
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import {useEffect} from "react";
|
|
2
|
-
import {useAuthedStringPost} from "@/hooks/use_authed_string_post";
|
|
3
|
-
|
|
4
|
-
export const useSharedStringToPost = () => {
|
|
5
|
-
const post = useAuthedStringPost();
|
|
6
|
-
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
const handleSharedString = (event: MessageEvent) => {
|
|
9
|
-
if (event.data && typeof event.data === "string") {
|
|
10
|
-
const content = event.data;
|
|
11
|
-
if (content) {
|
|
12
|
-
post(content);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
window.addEventListener("message", handleSharedString);
|
|
18
|
-
|
|
19
|
-
return () => {
|
|
20
|
-
window.removeEventListener("message", handleSharedString);
|
|
21
|
-
}
|
|
22
|
-
}, []);
|
|
23
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { createClient, Session } from "@supabase/supabase-js";
|
|
2
|
-
import { SUPABASE } from "@/constants";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import { BBKingSession } from "@/types/supabase";
|
|
5
|
-
|
|
6
|
-
export const useSupabaseSession = (): BBKingSession | null => {
|
|
7
|
-
const supabase = createClient(SUPABASE.URL, SUPABASE.ANNO);
|
|
8
|
-
|
|
9
|
-
const extendSess = (sess: Session | null) => {
|
|
10
|
-
if (!sess) {
|
|
11
|
-
return sess;
|
|
12
|
-
}
|
|
13
|
-
return {
|
|
14
|
-
...sess,
|
|
15
|
-
isKing: sess.user?.id === SUPABASE.BB_KING_ID,
|
|
16
|
-
isQueen: sess.user?.id === SUPABASE.BB_QUEEN_ID,
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const [session, setSession] = useState(extendSess(supabase.auth.session()));
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
supabase.auth.onAuthStateChange((event, session) => {
|
|
24
|
-
if (event === "SIGNED_IN") {
|
|
25
|
-
setSession(extendSess(session));
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}, []);
|
|
29
|
-
|
|
30
|
-
return session;
|
|
31
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
|
|
3
|
-
export type Result = {
|
|
4
|
-
content: string;
|
|
5
|
-
title: string;
|
|
6
|
-
reader: (f: File) => void;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const useTextPlainFile = (): Result => {
|
|
10
|
-
const [content, setContent] = useState("");
|
|
11
|
-
const [file, setFile] = useState<File | null>(null);
|
|
12
|
-
|
|
13
|
-
const reader = new FileReader();
|
|
14
|
-
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
if (file != null) {
|
|
17
|
-
reader.readAsText(file, "utf-8");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
reader.onload = function () {
|
|
21
|
-
setContent(reader.result as string);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return () => {
|
|
25
|
-
reader.onload = null;
|
|
26
|
-
};
|
|
27
|
-
}, [file]);
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
content,
|
|
31
|
-
title: file?.name ?? "",
|
|
32
|
-
reader: (f: File) => {
|
|
33
|
-
setFile(f);
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
import { useSupabaseSession } from "@/hooks/use_supa_session";
|
|
3
|
-
import { apiFetcher, getImageFileSize, withToken } from "@/utils";
|
|
4
|
-
import { Photo } from "@/types/photo";
|
|
5
|
-
import { API } from "@/constants/routes";
|
|
6
|
-
import { UploadResult } from "@/types/oss";
|
|
7
|
-
|
|
8
|
-
export const useUploader = () => {
|
|
9
|
-
const { access_token: token } = useSupabaseSession() || {};
|
|
10
|
-
const authedApiFetcher = withToken(apiFetcher)(token);
|
|
11
|
-
|
|
12
|
-
return useCallback(
|
|
13
|
-
async (pid: string, projectName: string, file: File): Promise<Photo> => {
|
|
14
|
-
const { width, height } = await getImageFileSize(file);
|
|
15
|
-
|
|
16
|
-
const url = `${API.UPLOAD_IMG}?pid=${pid}&fileName=${file.name}&projectName=${projectName}&width=${width}&height=${height}`;
|
|
17
|
-
|
|
18
|
-
const result = (await authedApiFetcher(url, {
|
|
19
|
-
method: "POST",
|
|
20
|
-
headers: {
|
|
21
|
-
"Content-Type": "application/octet-stream",
|
|
22
|
-
},
|
|
23
|
-
body: file,
|
|
24
|
-
})) as UploadResult;
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
width,
|
|
28
|
-
height,
|
|
29
|
-
src: result.url,
|
|
30
|
-
};
|
|
31
|
-
},
|
|
32
|
-
[token]
|
|
33
|
-
);
|
|
34
|
-
};
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ReactEventHandler,
|
|
3
|
-
useRef,
|
|
4
|
-
useState,
|
|
5
|
-
RefObject,
|
|
6
|
-
useEffect,
|
|
7
|
-
} from "react";
|
|
8
|
-
|
|
9
|
-
export const useVideoControls = () => {
|
|
10
|
-
const videoRef = useRef<HTMLVideoElement>(null);
|
|
11
|
-
const [isPlay, setIsPlay] = useState(false);
|
|
12
|
-
|
|
13
|
-
const toggle = async () => {
|
|
14
|
-
const { current: video } = videoRef;
|
|
15
|
-
|
|
16
|
-
if (!video) return;
|
|
17
|
-
|
|
18
|
-
if (video.paused || video.ended) {
|
|
19
|
-
await video.play();
|
|
20
|
-
setIsPlay(true);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
video.pause();
|
|
24
|
-
setIsPlay(false);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const isEnd = videoRef && videoRef.current && videoRef.current.ended;
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
videoRef,
|
|
31
|
-
isPlay: isPlay && !isEnd,
|
|
32
|
-
toggle,
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const useVideoProgress = () => {
|
|
37
|
-
const [progress, setProgress] = useState(0);
|
|
38
|
-
const onTimeUpdate: ReactEventHandler<HTMLVideoElement> = (event) => {
|
|
39
|
-
const video = event.currentTarget;
|
|
40
|
-
if (!video.duration) {
|
|
41
|
-
setProgress(0);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
setProgress(video.currentTime / video.duration);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
return { progress, onTimeUpdate };
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const useVideoEleHeight = (
|
|
51
|
-
videoRef: RefObject<HTMLVideoElement>
|
|
52
|
-
): number => {
|
|
53
|
-
const [height, setHeight] = useState(0);
|
|
54
|
-
const updateHeight = () => {
|
|
55
|
-
if (!videoRef.current) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const { height } = videoRef.current.getBoundingClientRect();
|
|
59
|
-
setHeight(height);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
window.addEventListener("resize", updateHeight);
|
|
64
|
-
return () => {
|
|
65
|
-
window.removeEventListener("resize", updateHeight);
|
|
66
|
-
};
|
|
67
|
-
}, []);
|
|
68
|
-
|
|
69
|
-
useEffect(updateHeight);
|
|
70
|
-
return height;
|
|
71
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { ArticlePage } from "@/components/article";
|
|
3
|
-
import { threeColWrapper } from "@/components/with_wrapper";
|
|
4
|
-
import { ImageUploader } from "@/components/ImageUploader";
|
|
5
|
-
import { UploadResult } from "@/types/upload";
|
|
6
|
-
import { Button } from "@bbki.ng/components";
|
|
7
|
-
import { copyToClipboard } from "@/utils";
|
|
8
|
-
|
|
9
|
-
const Upload = () => {
|
|
10
|
-
const [source, setSource] = useState("");
|
|
11
|
-
const buildSource = (result: UploadResult) =>
|
|
12
|
-
`<Img
|
|
13
|
-
src="${result.src}"
|
|
14
|
-
height={${result.height}}
|
|
15
|
-
width={${result.width}}
|
|
16
|
-
renderedWidth={${result.width}}
|
|
17
|
-
removeBlurBgAfterLoad
|
|
18
|
-
/>`;
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<ArticlePage title="图片素材上传">
|
|
22
|
-
<>
|
|
23
|
-
<ImageUploader
|
|
24
|
-
onUploadSuccess={(res) => {
|
|
25
|
-
setSource(buildSource(res));
|
|
26
|
-
}}
|
|
27
|
-
/>
|
|
28
|
-
{source && <pre>{source}</pre>}
|
|
29
|
-
{source && (
|
|
30
|
-
<Button className="m-16" onClick={() => copyToClipboard(source)}>
|
|
31
|
-
复制代码
|
|
32
|
-
</Button>
|
|
33
|
-
)}
|
|
34
|
-
</>
|
|
35
|
-
</ArticlePage>
|
|
36
|
-
);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const UploadPage = Upload;
|
package/src/blog/types/upload.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ImageDropProps } from "@bbki.ng/components/lib";
|
|
2
|
-
|
|
3
|
-
export type UploadResult = {
|
|
4
|
-
width: number;
|
|
5
|
-
height: number;
|
|
6
|
-
src: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export interface ImageUploaderProps
|
|
10
|
-
extends Pick<ImageDropProps<undefined>, "onUploadFinish" | "placeholder"> {
|
|
11
|
-
onBeforeUpload?: () => void;
|
|
12
|
-
onUploadError?: () => void;
|
|
13
|
-
onUploadSuccess?: (res: UploadResult) => void;
|
|
14
|
-
projectId?: string;
|
|
15
|
-
projectName?: string;
|
|
16
|
-
}
|
package/src/blog/utils/tags.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
};
|