@bbki.ng/site 5.2.12 → 5.3.0

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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # @bbki.ng/site
2
2
 
3
+ ## 5.3.0
4
+
3
5
  ## 5.2.12
4
6
 
5
7
  ## 5.2.11
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.2.0/dist/index.js"></script>
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
@@ -8,7 +8,7 @@ const config = {
8
8
  "!**/vendor/**",
9
9
  ],
10
10
  moduleNameMapper: {
11
- "@/(.*)$": "<rootDir>/src/$1",
11
+ "@/(.*)$": "<rootDir>/src/blog/$1",
12
12
  },
13
13
  };
14
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/site",
3
- "version": "5.2.12",
3
+ "version": "5.3.0",
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.1",
24
- "@bbki.ng/stylebase": "3.1.0"
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.0"
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="streaming" 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
  };
@@ -13,3 +13,6 @@ export {
13
13
 
14
14
  export const useMovies = buildSimpleApiHooks(API.MOVIES, "movies");
15
15
  export const useBooks = buildSimpleApiHooks(API.BOOKS, "books");
16
+
17
+ export { useStreaming } from "./use_streaming";
18
+ export type { StreamingItem } from "./use_streaming";
@@ -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: "/streaming",
22
+ name: "cd ./streaming",
23
+ },
25
24
  ...pluginEntry,
26
25
  ]}
27
26
  title=""
28
- footer={<Version className="" />}
27
+ // footer={<Version className="" />}
29
28
  />
30
29
  </>
31
30
  );
@@ -12,3 +12,4 @@ const NowPage = () => {
12
12
 
13
13
  export { Cover } from "./cover";
14
14
  export { NowPage };
15
+ export { default as Streaming } from "./streaming";
@@ -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;
@@ -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"),