@bbki.ng/site 5.2.12 → 5.3.1
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 +4 -0
- package/index.html +1 -1
- package/jest.config.js +1 -1
- package/package.json +4 -4
- package/src/blog/app.tsx +2 -1
- package/src/blog/constants/routes.ts +2 -0
- package/src/blog/hooks/index.ts +3 -0
- package/src/blog/hooks/use_streaming.ts +29 -0
- package/src/blog/pages/cover/index.tsx +5 -6
- package/src/blog/pages/index.tsx +1 -0
- package/src/blog/pages/streaming/index.tsx +41 -0
- package/src/blog/utils/index.ts +3 -1
- package/src/blog/utils/streaming.ts +27 -0
- package/vite.config.js +8 -0
package/CHANGELOG.md
CHANGED
package/index.html
CHANGED
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
</style>
|
|
56
56
|
<script src="https://unpkg.com/open-heart-element" type="module"></script>
|
|
57
57
|
<script type="module" src="https://cdn.jsdelivr.net/npm/@bbki.ng/bbimg@0.0.3/dist/index.js"></script>
|
|
58
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/@bbki.ng/bb-msg-history@0.
|
|
58
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@bbki.ng/bb-msg-history@0.6.1/dist/index.js"></script>
|
|
59
59
|
</head>
|
|
60
60
|
|
|
61
61
|
<body class="h-full m-0 flex flex-col font-mono">
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbki.ng/site",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.1",
|
|
4
4
|
"description": "code behind bbki.ng",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"sonner": "1.4.0",
|
|
21
21
|
"swr": "^2.2.5",
|
|
22
22
|
"vaul": "1.1.2",
|
|
23
|
-
"@bbki.ng/components": "5.2.
|
|
24
|
-
"@bbki.ng/stylebase": "3.1.
|
|
23
|
+
"@bbki.ng/components": "5.2.2",
|
|
24
|
+
"@bbki.ng/stylebase": "3.1.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@mdx-js/mdx": "2.0.0-next.9",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"vite-plugin-mdx": "^3.5.8",
|
|
60
60
|
"vite-plugin-pwa": "0.19",
|
|
61
61
|
"workbox-window": "^6.3.0",
|
|
62
|
-
"@bbki.ng/stylebase": "3.1.
|
|
62
|
+
"@bbki.ng/stylebase": "3.1.1"
|
|
63
63
|
},
|
|
64
64
|
"author": "bbbottle",
|
|
65
65
|
"license": "MIT",
|
package/src/blog/app.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import React, { useContext } from "react";
|
|
|
2
2
|
import { Outlet, Route, Routes } from "react-router-dom";
|
|
3
3
|
import { Nav, NotFound, Page } from "@bbki.ng/components";
|
|
4
4
|
import { HotKeyNav } from "./components";
|
|
5
|
-
import { Cover } from "./pages";
|
|
5
|
+
import { Cover, Streaming } from "./pages";
|
|
6
6
|
|
|
7
7
|
import ArticlePage from "@/pages/extensions/txt/article";
|
|
8
8
|
import Tags from "@/pages/tags";
|
|
@@ -76,6 +76,7 @@ export const App = () => {
|
|
|
76
76
|
|
|
77
77
|
<Route path="bot" element={<BotRedirect />} />
|
|
78
78
|
<Route path="login" element={<Login />} />
|
|
79
|
+
<Route path="stream" element={<Streaming />} />
|
|
79
80
|
</Route>
|
|
80
81
|
<Route path="*" element={<NotFound />} />
|
|
81
82
|
</Routes>
|
|
@@ -17,6 +17,7 @@ export const GITHUB_REPO_ADDRESS =
|
|
|
17
17
|
"https://github.com/bbbottle/bottle/tree/main/packages/site";
|
|
18
18
|
export const OSS_ADDRESS = "https://zjh-im-res.oss-cn-shenzhen.aliyuncs.com";
|
|
19
19
|
export const API_ENDPOINT = "https://api.bbki.ng";
|
|
20
|
+
export const API_CF_ENDPOINT = "https://cf.bbki.ng";
|
|
20
21
|
export const API = {
|
|
21
22
|
PROJECTS: "projects",
|
|
22
23
|
UPLOAD_IMG: "upload",
|
|
@@ -27,4 +28,5 @@ export const API = {
|
|
|
27
28
|
IMAGES: "images",
|
|
28
29
|
BOOKS: "books",
|
|
29
30
|
POSTS: "posts",
|
|
31
|
+
STREAMING: "streaming",
|
|
30
32
|
};
|
package/src/blog/hooks/index.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import useSWR from "swr";
|
|
2
|
+
import { baseFetcher, withBBApi } from "@/utils";
|
|
3
|
+
import { API_CF_ENDPOINT } from "@/constants/routes";
|
|
4
|
+
|
|
5
|
+
// In dev, use /api prefix to leverage Vite proxy to localhost:8787
|
|
6
|
+
const isDev = typeof window !== "undefined" && /^http:\/\/localhost/.test(window.location.href);
|
|
7
|
+
const streamingFetcher = isDev
|
|
8
|
+
? (resource: string, init?: RequestInit) => baseFetcher(`/api/${resource}`, init)
|
|
9
|
+
: withBBApi(baseFetcher)(API_CF_ENDPOINT);
|
|
10
|
+
|
|
11
|
+
export type StreamingItem = {
|
|
12
|
+
id: string;
|
|
13
|
+
author: string;
|
|
14
|
+
content: string;
|
|
15
|
+
type?: string;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const useStreaming = () => {
|
|
20
|
+
const { data, error } = useSWR("streaming", streamingFetcher, {
|
|
21
|
+
revalidateOnFocus: false,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
streaming: data?.data as StreamingItem[] | undefined,
|
|
26
|
+
isError: error,
|
|
27
|
+
isLoading: !data && !error,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
@@ -11,21 +11,20 @@ export const Cover = (props: { className?: string }) => {
|
|
|
11
11
|
return (
|
|
12
12
|
<>
|
|
13
13
|
<CenterLinkList
|
|
14
|
-
spaceBetween
|
|
15
14
|
className="select-none"
|
|
16
15
|
links={[
|
|
17
|
-
// {
|
|
18
|
-
// to: "/projects",
|
|
19
|
-
// name: "cd ./projects",
|
|
20
|
-
// },
|
|
21
16
|
{
|
|
22
17
|
to: "/blog",
|
|
23
18
|
name: "cd ./blog",
|
|
24
19
|
},
|
|
20
|
+
{
|
|
21
|
+
to: "/stream",
|
|
22
|
+
name: "cd ./stream",
|
|
23
|
+
},
|
|
25
24
|
...pluginEntry,
|
|
26
25
|
]}
|
|
27
26
|
title=""
|
|
28
|
-
footer={<Version className="" />}
|
|
27
|
+
// footer={<Version className="" />}
|
|
29
28
|
/>
|
|
30
29
|
</>
|
|
31
30
|
);
|
package/src/blog/pages/index.tsx
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
|
2
|
+
import { useStreaming, StreamingItem } from "@/hooks/use_streaming";
|
|
3
|
+
import { formatStreamingData } from "@/utils/streaming";
|
|
4
|
+
import { Article } from "@bbki.ng/components";
|
|
5
|
+
|
|
6
|
+
// Extend JSX IntrinsicElements for the web component
|
|
7
|
+
declare global {
|
|
8
|
+
namespace JSX {
|
|
9
|
+
interface IntrinsicElements {
|
|
10
|
+
"bb-msg-history": React.DetailedHTMLProps<
|
|
11
|
+
React.HTMLAttributes<HTMLElement>,
|
|
12
|
+
HTMLElement
|
|
13
|
+
>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const Streaming = () => {
|
|
19
|
+
const { streaming, isLoading, isError } = useStreaming();
|
|
20
|
+
const bbMsgHistoryRef = useRef<HTMLElement>(null);
|
|
21
|
+
|
|
22
|
+
if (isError) {
|
|
23
|
+
return <div className="p-8 text-center text-gray-500">加载失败</div>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const formattedData = formatStreamingData(streaming || []);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
|
|
30
|
+
<div className="h-full w-full p-4">
|
|
31
|
+
<bb-msg-history
|
|
32
|
+
ref={bbMsgHistoryRef}
|
|
33
|
+
style={{ "height": "100%" }}
|
|
34
|
+
>
|
|
35
|
+
{formattedData}
|
|
36
|
+
</bb-msg-history>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default Streaming;
|
package/src/blog/utils/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Photo } from "@/types/photo";
|
|
2
2
|
import { ossProcessType } from "@/types/oss";
|
|
3
|
-
import { API_ENDPOINT, OSS_ADDRESS } from "@/constants/routes";
|
|
3
|
+
import { API_CF_ENDPOINT, API_ENDPOINT, OSS_ADDRESS } from "@/constants/routes";
|
|
4
4
|
import { DEFAULT_DELAY } from "@/constants";
|
|
5
5
|
import useSWR from "swr";
|
|
6
6
|
import { toast } from "sonner";
|
|
@@ -107,6 +107,8 @@ export const withBBApi =
|
|
|
107
107
|
|
|
108
108
|
export const apiFetcher = withBBApi(baseFetcher)(API_ENDPOINT);
|
|
109
109
|
|
|
110
|
+
export const cfApiFetcher = withBBApi(baseFetcher)(API_CF_ENDPOINT);
|
|
111
|
+
|
|
110
112
|
export const getImageFileSize = (
|
|
111
113
|
file: File
|
|
112
114
|
): Promise<{ width: number; height: number }> => {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { StreamingItem } from "@/hooks/use_streaming";
|
|
2
|
+
|
|
3
|
+
// Format: "author: content" (with optional timestamp)
|
|
4
|
+
// Timestamp format: YYYY-mm-dd HH:MM:SS
|
|
5
|
+
export const formatStreamingData = (items: StreamingItem[]): string => {
|
|
6
|
+
if (!items || items.length === 0) {
|
|
7
|
+
return "";
|
|
8
|
+
}
|
|
9
|
+
// Reverse to show oldest first (bb-msg-history appends to bottom)
|
|
10
|
+
return [...items]
|
|
11
|
+
.reverse()
|
|
12
|
+
.map((item) => {
|
|
13
|
+
const time = item.createdAt
|
|
14
|
+
? new Date(item.createdAt).toLocaleString("zh-CN", {
|
|
15
|
+
year: "numeric",
|
|
16
|
+
month: "2-digit",
|
|
17
|
+
day: "2-digit",
|
|
18
|
+
hour: "2-digit",
|
|
19
|
+
minute: "2-digit",
|
|
20
|
+
second: "2-digit",
|
|
21
|
+
hour12: false,
|
|
22
|
+
}).replace(/\//g, "-")
|
|
23
|
+
: "";
|
|
24
|
+
return time ? `[${time}] ${item.author}: ${item.content}` : `${item.author}: ${item.content}`;
|
|
25
|
+
})
|
|
26
|
+
.join("\n");
|
|
27
|
+
};
|
package/vite.config.js
CHANGED
|
@@ -29,6 +29,14 @@ const options = {
|
|
|
29
29
|
|
|
30
30
|
// https://vitejs.dev/config/
|
|
31
31
|
export default defineConfig({
|
|
32
|
+
server: {
|
|
33
|
+
proxy: {
|
|
34
|
+
"/api/streaming": {
|
|
35
|
+
target: "http://localhost:8787",
|
|
36
|
+
rewrite: (path) => path.replace(/^\/api/, ""),
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
32
40
|
resolve: {
|
|
33
41
|
alias: {
|
|
34
42
|
"@": path.resolve(__dirname, "./src/blog"),
|