@bbki.ng/site 5.8.11 → 6.0.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.
Files changed (93) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +6 -3
  3. package/src/app/app.tsx +8 -7
  4. package/src/app/components/BaseLayout.tsx +6 -4
  5. package/src/app/components/cover/index.tsx +9 -5
  6. package/src/app/context/bbcontext.tsx +1 -1
  7. package/src/app/index.tsx +18 -1
  8. package/src/types/hostApi.ts +1 -2
  9. package/src/app/context/global_loading_state_provider.tsx +0 -65
  10. package/src/app/hooks/use_global_loading.ts +0 -47
  11. package/src/app/hooks/use_plugin_entries.ts +0 -34
  12. package/src/core/components/SlotComp.tsx +0 -14
  13. package/src/core/const/index.ts +0 -3
  14. package/src/core/context/createPluginCtx.tsx +0 -60
  15. package/src/core/context/index.ts +0 -1
  16. package/src/core/hooks/index.ts +0 -6
  17. package/src/core/hooks/useMiddlewareTransData.ts +0 -13
  18. package/src/core/hooks/useSlotComp.ts +0 -4
  19. package/src/core/hooks/use_plugins.ts +0 -115
  20. package/src/core/plugin-system/bbplugin.ts +0 -15
  21. package/src/core/plugin-system/manifest.ts +0 -56
  22. package/src/core/plugin-system/pluginManager.ts +0 -126
  23. package/src/core/plugin-system/pluginManifestService.ts +0 -97
  24. package/src/core/plugin-system/pluginStore.ts +0 -200
  25. package/src/core/plugin-system/registry.ts +0 -17
  26. package/src/core/plugin-system/services/coreService.ts +0 -75
  27. package/src/core/plugin-system/services/systemUIService.ts +0 -64
  28. package/src/core/shared-service/contract/ICoreService.ts +0 -28
  29. package/src/core/shared-service/contract/IUIService.ts +0 -53
  30. package/src/core/shared-service/factory/createUIService.ts +0 -121
  31. package/src/core/shared-service/factory/createUIServiceReactKit.tsx +0 -149
  32. package/src/core/shared-service/service-proxy.ts +0 -28
  33. package/src/core/shared-service/service-registry.ts +0 -54
  34. package/src/core/utils/eventBus.ts +0 -29
  35. package/src/plugins/blog/components/BlogLink.tsx +0 -11
  36. package/src/plugins/blog/components/BlogSlotCom.tsx +0 -14
  37. package/src/plugins/blog/components/app.tsx +0 -15
  38. package/src/plugins/blog/components/article/index.tsx +0 -51
  39. package/src/plugins/blog/components/index.tsx +0 -10
  40. package/src/plugins/blog/constants/index.ts +0 -1
  41. package/src/plugins/blog/context/index.ts +0 -7
  42. package/src/plugins/blog/hooks/useMiddlewareTransData.ts +0 -14
  43. package/src/plugins/blog/hooks/use_blog_scroll_pos_restoration.ts +0 -89
  44. package/src/plugins/blog/hooks/use_blog_slot_com.ts +0 -5
  45. package/src/plugins/blog/hooks/use_posts.ts +0 -74
  46. package/src/plugins/blog/index.ts +0 -79
  47. package/src/plugins/blog/pages/extensions/txt/article.tsx +0 -42
  48. package/src/plugins/blog/pages/extensions/txt/index.tsx +0 -58
  49. package/src/plugins/blog/services/BlogUIService.ts +0 -27
  50. package/src/plugins/blog/services/IBlogUIService.ts +0 -16
  51. package/src/plugins/extra-cd/index.ts +0 -36
  52. package/src/plugins/extra-entry/components/page.tsx +0 -14
  53. package/src/plugins/extra-entry/index.ts +0 -28
  54. package/src/plugins/fx/components/index.tsx +0 -45
  55. package/src/plugins/fx/context/index.ts +0 -12
  56. package/src/plugins/fx/hooks/useTextEffects.ts +0 -39
  57. package/src/plugins/fx/index.ts +0 -53
  58. package/src/plugins/fx/services/FxService.ts +0 -47
  59. package/src/plugins/fx/services/IFxService.ts +0 -15
  60. package/src/plugins/notification/components/index.tsx +0 -26
  61. package/src/plugins/notification/index.ts +0 -26
  62. package/src/plugins/notification/services/INotificationService.ts +0 -24
  63. package/src/plugins/notification/services/NotificationService.ts +0 -29
  64. package/src/plugins/now/components/NowLink.tsx +0 -7
  65. package/src/plugins/now/components/index.tsx +0 -9
  66. package/src/plugins/now/components/streaming/arrow-down.tsx +0 -26
  67. package/src/plugins/now/components/streaming/index.tsx +0 -99
  68. package/src/plugins/now/components/streaming/useScrollBtnVisibility.ts +0 -28
  69. package/src/plugins/now/context/index.ts +0 -10
  70. package/src/plugins/now/hooks/use_streaming.ts +0 -88
  71. package/src/plugins/now/index.ts +0 -62
  72. package/src/plugins/now/utils/streaming.ts +0 -33
  73. package/src/plugins/sticker/components/StickerCom.tsx +0 -45
  74. package/src/plugins/sticker/const.ts +0 -76
  75. package/src/plugins/sticker/context.ts +0 -7
  76. package/src/plugins/sticker/index.ts +0 -43
  77. package/src/plugins/sticker/types.ts +0 -10
  78. package/src/plugins/store/components/ArrowCom.tsx +0 -34
  79. package/src/plugins/store/components/ArrowSvg.tsx +0 -1133
  80. package/src/plugins/store/components/storeIcon.tsx +0 -16
  81. package/src/plugins/store/components/storePage.tsx +0 -202
  82. package/src/plugins/store/context/index.ts +0 -15
  83. package/src/plugins/store/index.ts +0 -57
  84. package/src/plugins/store/utils/index.ts +0 -26
  85. package/src/plugins/version/index.ts +0 -28
  86. package/src/plugins/xwy/components/XwyLink.tsx +0 -7
  87. package/src/plugins/xwy/components/article.tsx +0 -13
  88. package/src/plugins/xwy/components/logo.tsx +0 -28
  89. package/src/plugins/xwy/const/index.ts +0 -28
  90. package/src/plugins/xwy/index.ts +0 -103
  91. package/src/plugins/xwy/transformers/index.ts +0 -67
  92. package/src/plugins/xwy/types/index.ts +0 -17
  93. package/src/plugins/xwy/utils/index.ts +0 -43
@@ -1,99 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import { Panel, Link } from '@bbki.ng/ui';
3
- import classNames from 'classnames';
4
-
5
- import { formatStreamingData } from '#/plugins/now/utils/streaming';
6
-
7
- import { useStreaming } from '../../hooks/use_streaming';
8
-
9
- import { useScrollBtnVisibility } from './useScrollBtnVisibility';
10
-
11
- declare global {
12
- // eslint-disable-next-line @typescript-eslint/no-namespace
13
- namespace JSX {
14
- interface IntrinsicElements {
15
- 'bb-msg-history': React.DetailedHTMLProps<
16
- React.HTMLAttributes<HTMLElement>,
17
- BbMsgHistoryElement
18
- > & {
19
- loading?: boolean;
20
- infinite?: boolean;
21
- };
22
- }
23
- }
24
- }
25
-
26
- export interface BbMsgHistoryElement extends HTMLElement {
27
- setAuthor(name: string, config: { avatar: string; side: string; bubbleColor: string }): void;
28
- scrollToBottom(): void;
29
- }
30
-
31
- const Streaming = () => {
32
- const { streaming, isLoading, isError } = useStreaming();
33
- const bbMsgHistoryRef = useRef<BbMsgHistoryElement>(null);
34
-
35
- const [scrolled, setScrolled] = useState(false);
36
-
37
- const showScrollBtn = useScrollBtnVisibility(bbMsgHistoryRef.current!);
38
-
39
- const formattedData = formatStreamingData(streaming || []);
40
-
41
- useEffect(() => {
42
- const el = bbMsgHistoryRef.current;
43
- let timer: ReturnType<typeof setTimeout>;
44
- if (!isLoading && el) {
45
- // 检查自定义元素是否已定义并升级
46
- if (el.scrollToBottom) {
47
- requestAnimationFrame(() => {
48
- el.scrollToBottom();
49
- });
50
- } else {
51
- // 等待 custom element 定义完成
52
- customElements.whenDefined('bb-msg-history').then(() => {
53
- el.scrollToBottom?.();
54
- });
55
- }
56
-
57
- // delay to set scrolled state after scrollToBottom
58
- timer = setTimeout(() => {
59
- setScrolled(true);
60
- }, 500);
61
- }
62
- return () => {
63
- clearTimeout(timer);
64
- };
65
- }, [isLoading, formattedData]);
66
-
67
- if (isLoading || isError) {
68
- return null;
69
- }
70
-
71
- return (
72
- <>
73
- <Panel className="p-2.5! mt-16">
74
- <bb-msg-history
75
- // infinite
76
- hide-scroll-bar
77
- hide-scroll-button
78
- ref={bbMsgHistoryRef}
79
- style={{ height: '100%', '--bb-max-height': '260px' } as React.CSSProperties}
80
- >
81
- {formattedData}
82
- </bb-msg-history>
83
- </Panel>
84
- <Link
85
- className={classNames('w-fit relative opacity-0 transition-all duration-300 mt-16', {
86
- 'opacity-100': scrolled,
87
- 'opacity-0': showScrollBtn,
88
- 'pointer-events-none': showScrollBtn || !scrolled,
89
- })}
90
- to="/"
91
- style={{ left: -4 }}
92
- >
93
- cd ..
94
- </Link>
95
- </>
96
- );
97
- };
98
-
99
- export default Streaming;
@@ -1,28 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- import { BbMsgHistoryElement } from '.';
4
-
5
- export const useScrollBtnVisibility = (ele: BbMsgHistoryElement) => {
6
- const [visible, setVisible] = useState(false);
7
-
8
- useEffect(() => {
9
- if (!ele) {
10
- return;
11
- }
12
-
13
- const handleShow = () => setVisible(true);
14
- const handleHide = () => setVisible(false);
15
-
16
- ele.addEventListener('bb-scrollbuttonshow', handleShow);
17
- ele.addEventListener('bb-scrollbuttonhide', handleHide);
18
-
19
- console.log('add event listeners');
20
-
21
- return () => {
22
- ele.removeEventListener('bb-scrollbuttonshow', handleShow);
23
- ele.removeEventListener('bb-scrollbuttonhide', handleHide);
24
- };
25
- }, [ele]);
26
-
27
- return visible;
28
- };
@@ -1,10 +0,0 @@
1
- import { Fetcher } from 'swr';
2
-
3
- import { createPluginCtx } from '#/core/context';
4
-
5
- export interface INowCtx {
6
- setLoading: (loading: boolean) => void;
7
- fetch: Fetcher;
8
- }
9
-
10
- export const NowCtx = createPluginCtx<INowCtx>();
@@ -1,88 +0,0 @@
1
- import useSWR, { type BareFetcher } from 'swr';
2
- import { useEffect, useState } from 'react';
3
-
4
- import { NowCtx } from '../context';
5
-
6
- export type StreamingItem = {
7
- id: string;
8
- author: string;
9
- content: string;
10
- type?: string;
11
- createdAt: string;
12
- };
13
-
14
- interface StreamingResponse {
15
- status: string;
16
- data: StreamingItem[];
17
- }
18
-
19
- export interface StreamingQueryParams {
20
- /** Fetch records older than this ID (for pagination / next page) */
21
- before?: string;
22
- /** Fetch records newer than this ID (for polling / new messages) */
23
- after?: string;
24
- /** Number of records to fetch (default: 8, max: 100) */
25
- offset?: number;
26
- }
27
-
28
- // SWR key generator for streaming queries
29
- const getStreamingKey = (params: StreamingQueryParams) => {
30
- const parts = [];
31
- if (params.before) parts.push(`before=${params.before}`);
32
- if (params.after) parts.push(`after=${params.after}`);
33
- if (params.offset) parts.push(`offset=${params.offset}`);
34
- return 'streaming?' + parts.join('&');
35
- };
36
-
37
- interface UseStreamingOptions {
38
- /** Polling interval in ms (default: 1000, set to 0 to disable) */
39
- refreshInterval?: number;
40
- /** Initial offset for first fetch (default: 8) */
41
- offset?: number;
42
- }
43
-
44
- /**
45
- * Hook for fetching streaming data with polling
46
- * Use this for simple cases where you just need the latest data
47
- */
48
- export function useStreaming(options: UseStreamingOptions = {}) {
49
- const { refreshInterval = 1000, offset = 8 } = options;
50
-
51
- const { fetch } = NowCtx.useCtx();
52
-
53
- const key = getStreamingKey({ offset });
54
-
55
- const { data, error, mutate } = useSWR<StreamingResponse>(
56
- key,
57
- fetch as BareFetcher<StreamingResponse>,
58
- {
59
- revalidateOnFocus: true,
60
- refreshInterval,
61
- }
62
- );
63
-
64
- const isLoading = !data && !error;
65
-
66
- const nowCtx = NowCtx.useCtx();
67
-
68
- const [, forceUpdate] = useState(0);
69
-
70
- // make rerender when customElement defined
71
- useEffect(() => {
72
- customElements.whenDefined('bb-msg-history').then(() => {
73
- forceUpdate(prev => prev + 1);
74
- });
75
- }, []);
76
-
77
- useEffect(() => {
78
- nowCtx.setLoading(isLoading);
79
- }, [nowCtx, isLoading]);
80
-
81
- return {
82
- streaming: data?.data ?? [],
83
- isError: error,
84
- isLoading,
85
- /** Refetch data manually */
86
- mutate,
87
- };
88
- }
@@ -1,62 +0,0 @@
1
- import { BBPlugin } from '#/core/plugin-system/bbplugin';
2
- import { IHostContext } from '#/types/hostApi';
3
- import { PluginID } from '#/types/plugin';
4
-
5
- import { pageNow } from './components';
6
- import { NowLink } from './components/NowLink';
7
- import { NowCtx } from './context';
8
-
9
- export class NowPlugin extends BBPlugin {
10
- id: PluginID = 'now';
11
-
12
- private _serviceRegistry?: IHostContext['service'];
13
-
14
- override onInstall = async (ctx: IHostContext): Promise<void> => {
15
- const systemUIService = ctx.service.get('core:uiService');
16
- this._serviceRegistry = ctx.service;
17
- if (!systemUIService) {
18
- console.warn(`[${this.id}] core:uiService not found, cannot register entry`);
19
- return;
20
- }
21
- const { withCtx } = NowCtx;
22
-
23
- const coreService = ctx.service.get('core:baseService');
24
-
25
- if (!coreService) {
26
- console.error('Core service not found. NowPlugin installation failed.');
27
- return;
28
- }
29
-
30
- systemUIService.registerPluginEntry(
31
- {
32
- path: '/now',
33
- label: 'cd ./now',
34
- pageComponent: withCtx(
35
- {
36
- setLoading: loading => {
37
- // ctx.api.setLoading('now', loading);
38
- coreService.setLoading('now', loading);
39
- },
40
- fetch: coreService.fetch, // 直接使用 coreService 的 fetch 方法
41
- },
42
- pageNow
43
- ),
44
- },
45
- this.id
46
- );
47
- };
48
-
49
- override onManualInstall = () => {
50
- this.promptToOpen();
51
- };
52
-
53
- private promptToOpen = () => {
54
- const notificationService = this._serviceRegistry?.get('notification');
55
- notificationService?.notify({
56
- message: '安装成功.',
57
- action: NowLink,
58
- });
59
- };
60
- }
61
-
62
- export default new NowPlugin();
@@ -1,33 +0,0 @@
1
- export type StreamingItem = {
2
- id: string;
3
- author: string;
4
- content: string;
5
- type?: string;
6
- createdAt: string;
7
- };
8
-
9
- export const formatStreamingData = (items: StreamingItem[]): string => {
10
- if (!items || items.length === 0) {
11
- return '';
12
- }
13
- // Reverse to show oldest first (bb-msg-history appends to bottom)
14
- return [...items]
15
- .reverse()
16
- .map(item => {
17
- const time = item.createdAt
18
- ? new Date(item.createdAt)
19
- .toLocaleString('zh-CN', {
20
- year: 'numeric',
21
- month: '2-digit',
22
- day: '2-digit',
23
- hour: '2-digit',
24
- minute: '2-digit',
25
- second: '2-digit',
26
- hour12: false,
27
- })
28
- .replace(/\//g, '-')
29
- : '';
30
- return time ? `[${time}] ${item.author}: ${item.content}` : `${item.author}: ${item.content}`;
31
- })
32
- .join('\n');
33
- };
@@ -1,45 +0,0 @@
1
- import React from 'react';
2
- import { PathObj } from '@bbki.ng/ui';
3
-
4
- import { IComPropsRegisteredToSlot } from '#/types/slots';
5
-
6
- import { STICKERS } from '../const';
7
-
8
- export const StickerCom = ({ data }: IComPropsRegisteredToSlot) => {
9
- const paths = data as PathObj[];
10
-
11
- if (paths.length === 0) {
12
- return null;
13
- }
14
-
15
- // const lastPath = paths[paths.length - 1];
16
-
17
- // if (lastPath.name !== '~') {
18
- // return null;
19
- // }
20
-
21
- return (
22
- <div className="fixed bottom-32 left-16">
23
- {STICKERS.map(sticker => (
24
- <div
25
- key={sticker.id}
26
- className="inline-flex"
27
- style={{
28
- transform: `rotate(${sticker.rotation}deg)`,
29
- marginRight: '16px',
30
- }}
31
- >
32
- <bb-img
33
- src={sticker.imageUrl}
34
- max-width={sticker.maxWidth || 80}
35
- max-height={sticker.maxHeight || 80}
36
- aspect-ratio={sticker.aspectRatio || '1/1'}
37
- style={{
38
- transform: `translate(${sticker.xOffset || 0}px, ${sticker.yOffset || 0}px)`,
39
- }}
40
- ></bb-img>
41
- </div>
42
- ))}
43
- </div>
44
- );
45
- };
@@ -1,76 +0,0 @@
1
- import { IStickerConfig } from './types';
2
-
3
- export const STICKERS: IStickerConfig[] = [
4
- // {
5
- // id: 'copilot',
6
- // imageUrl: '/stickers/copilot.svg',
7
- // rotation: 20,
8
- // maxWidth: 60,
9
- // aspectRatio: '505/410',
10
- // xOffset: 0,
11
- // yOffset: 0,
12
- // },
13
- {
14
- id: 'unlock',
15
- imageUrl: '/stickers/sticker-unlock.svg',
16
- rotation: -17,
17
- maxWidth: 66,
18
- aspectRatio: '66/35',
19
- xOffset: 0,
20
- yOffset: 0,
21
- },
22
- // {
23
- // id: 'npm',
24
- // imageUrl: '/stickers/npm.svg',
25
- // rotation: -10,
26
- // maxHeight: 220,
27
- // aspectRatio: '540/210',
28
- // xOffset: 0,
29
- // yOffset: -70,
30
- // },
31
- // {
32
- // id: 'react',
33
- // imageUrl: '/stickers/react.svg',
34
- // rotation: 10,
35
- // maxHeight: 200,
36
- // aspectRatio: '512/456',
37
- // xOffset: -250,
38
- // yOffset: -50,
39
- // },
40
- // {
41
- // id: 'vite',
42
- // imageUrl: '/stickers/vitejs.svg',
43
- // rotation: -5,
44
- // maxWidth: 30,
45
- // aspectRatio: '512/512',
46
- // xOffset: 100,
47
- // yOffset: -30,
48
- // },
49
- {
50
- id: 'ollama',
51
- imageUrl: '/stickers/ollama.svg',
52
- rotation: 15,
53
- maxHeight: 150,
54
- aspectRatio: '17/25',
55
- xOffset: 150,
56
- yOffset: -20,
57
- },
58
- {
59
- id: 'cat',
60
- imageUrl: '/stickers/cat.svg',
61
- rotation: -40,
62
- maxWidth: 30,
63
- aspectRatio: '187/249',
64
- xOffset: 150,
65
- yOffset: -20,
66
- },
67
- {
68
- id: 'dog',
69
- imageUrl: '/stickers/dog.svg',
70
- rotation: -90,
71
- maxWidth: 40,
72
- aspectRatio: '82/76',
73
- xOffset: 50,
74
- yOffset: 170,
75
- },
76
- ];
@@ -1,7 +0,0 @@
1
- import { createPluginCtx } from '#/core/context';
2
-
3
- export interface IStickerCtx {
4
- deviceId: string;
5
- }
6
-
7
- export const StickerCtx = createPluginCtx<IStickerCtx>();
@@ -1,43 +0,0 @@
1
- import { BBPlugin } from '#/core/plugin-system/bbplugin';
2
- import { IHostContext } from '#/types/hostApi';
3
- import { PluginID } from '#/types/plugin';
4
-
5
- import { StickerCom } from './components/StickerCom';
6
- import { IStickerCtx, StickerCtx } from './context';
7
-
8
- class Sticker extends BBPlugin {
9
- id: PluginID = 'sticker';
10
-
11
- private createPluginCtx = async (ctx: IHostContext): Promise<IStickerCtx> => {
12
- const coreService = ctx.service.get('core:baseService');
13
-
14
- if (!coreService) {
15
- console.error('Core service not found. StickerPlugin installation failed.');
16
- return {
17
- deviceId: '',
18
- };
19
- }
20
-
21
- return {
22
- deviceId: (await coreService.getDeviceId()).id,
23
- };
24
- };
25
-
26
- override onInstall = async (ctx: IHostContext): Promise<void> => {
27
- const { withCtx } = StickerCtx;
28
-
29
- const pluginCtx = await this.createPluginCtx(ctx);
30
-
31
- const Sticker = withCtx(pluginCtx, StickerCom);
32
-
33
- const systemUIService = ctx.service.get('core:uiService');
34
- if (!systemUIService) {
35
- console.error('UI service not found. StickerPlugin installation failed.');
36
- return;
37
- }
38
-
39
- systemUIService.registerSlot('centerEntryArea', Sticker, this.id);
40
- };
41
- }
42
-
43
- export default new Sticker();
@@ -1,10 +0,0 @@
1
- export interface IStickerConfig {
2
- id: string;
3
- imageUrl: string;
4
- rotation: number;
5
- maxWidth?: number;
6
- maxHeight?: number;
7
- xOffset?: number;
8
- aspectRatio?: string;
9
- yOffset?: number;
10
- }
@@ -1,34 +0,0 @@
1
- import { FC, useEffect, useState } from 'react';
2
-
3
- import { IComPropsRegisteredToSlot } from '#/types/slots';
4
-
5
- import { ArrowSvg } from './ArrowSvg';
6
-
7
- export const ArrowCom: FC<IComPropsRegisteredToSlot> = ({ data }) => {
8
- const hasEntry = data as boolean;
9
-
10
- const [visible, setVisible] = useState(false);
11
-
12
- useEffect(() => {
13
- // Delay one frame so the initial opacity:0 is painted first
14
- const raf = requestAnimationFrame(() => setVisible(true));
15
- return () => cancelAnimationFrame(raf);
16
- }, []);
17
-
18
- if (hasEntry) {
19
- return null;
20
- }
21
-
22
- // transition from opacity 0 to 1 when hasEntry changes from true to false
23
-
24
- return (
25
- <div
26
- style={{
27
- opacity: visible ? 1 : 0,
28
- transition: 'opacity 1s ease-in',
29
- }}
30
- >
31
- <ArrowSvg />
32
- </div>
33
- );
34
- };