@bbki.ng/site 5.8.11 → 6.0.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 +30 -0
- package/package.json +6 -3
- package/src/app/app.tsx +8 -7
- package/src/app/components/BaseLayout.tsx +6 -4
- package/src/app/components/cover/index.tsx +9 -5
- package/src/app/context/bbcontext.tsx +1 -1
- package/src/app/index.tsx +18 -1
- package/src/types/hostApi.ts +1 -2
- package/src/app/context/global_loading_state_provider.tsx +0 -65
- package/src/app/hooks/use_global_loading.ts +0 -47
- package/src/app/hooks/use_plugin_entries.ts +0 -34
- package/src/core/components/SlotComp.tsx +0 -14
- package/src/core/const/index.ts +0 -3
- package/src/core/context/createPluginCtx.tsx +0 -60
- package/src/core/context/index.ts +0 -1
- package/src/core/hooks/index.ts +0 -6
- package/src/core/hooks/useMiddlewareTransData.ts +0 -13
- package/src/core/hooks/useSlotComp.ts +0 -4
- package/src/core/hooks/use_plugins.ts +0 -115
- package/src/core/plugin-system/bbplugin.ts +0 -15
- package/src/core/plugin-system/manifest.ts +0 -56
- package/src/core/plugin-system/pluginManager.ts +0 -126
- package/src/core/plugin-system/pluginManifestService.ts +0 -97
- package/src/core/plugin-system/pluginStore.ts +0 -200
- package/src/core/plugin-system/registry.ts +0 -17
- package/src/core/plugin-system/services/coreService.ts +0 -75
- package/src/core/plugin-system/services/systemUIService.ts +0 -64
- package/src/core/shared-service/contract/ICoreService.ts +0 -28
- package/src/core/shared-service/contract/IUIService.ts +0 -53
- package/src/core/shared-service/factory/createUIService.ts +0 -121
- package/src/core/shared-service/factory/createUIServiceReactKit.tsx +0 -149
- package/src/core/shared-service/service-proxy.ts +0 -28
- package/src/core/shared-service/service-registry.ts +0 -54
- package/src/core/utils/eventBus.ts +0 -29
- package/src/plugins/blog/components/BlogLink.tsx +0 -11
- package/src/plugins/blog/components/BlogSlotCom.tsx +0 -14
- package/src/plugins/blog/components/app.tsx +0 -15
- package/src/plugins/blog/components/article/index.tsx +0 -51
- package/src/plugins/blog/components/index.tsx +0 -10
- package/src/plugins/blog/constants/index.ts +0 -1
- package/src/plugins/blog/context/index.ts +0 -7
- package/src/plugins/blog/hooks/useMiddlewareTransData.ts +0 -14
- package/src/plugins/blog/hooks/use_blog_scroll_pos_restoration.ts +0 -89
- package/src/plugins/blog/hooks/use_blog_slot_com.ts +0 -5
- package/src/plugins/blog/hooks/use_posts.ts +0 -74
- package/src/plugins/blog/index.ts +0 -79
- package/src/plugins/blog/pages/extensions/txt/article.tsx +0 -42
- package/src/plugins/blog/pages/extensions/txt/index.tsx +0 -58
- package/src/plugins/blog/services/BlogUIService.ts +0 -27
- package/src/plugins/blog/services/IBlogUIService.ts +0 -16
- package/src/plugins/extra-cd/index.ts +0 -36
- package/src/plugins/extra-entry/components/page.tsx +0 -14
- package/src/plugins/extra-entry/index.ts +0 -28
- package/src/plugins/fx/components/index.tsx +0 -45
- package/src/plugins/fx/context/index.ts +0 -12
- package/src/plugins/fx/hooks/useTextEffects.ts +0 -39
- package/src/plugins/fx/index.ts +0 -53
- package/src/plugins/fx/services/FxService.ts +0 -47
- package/src/plugins/fx/services/IFxService.ts +0 -15
- package/src/plugins/notification/components/index.tsx +0 -26
- package/src/plugins/notification/index.ts +0 -26
- package/src/plugins/notification/services/INotificationService.ts +0 -24
- package/src/plugins/notification/services/NotificationService.ts +0 -29
- package/src/plugins/now/components/NowLink.tsx +0 -7
- package/src/plugins/now/components/index.tsx +0 -9
- package/src/plugins/now/components/streaming/arrow-down.tsx +0 -26
- package/src/plugins/now/components/streaming/index.tsx +0 -99
- package/src/plugins/now/components/streaming/useScrollBtnVisibility.ts +0 -28
- package/src/plugins/now/context/index.ts +0 -10
- package/src/plugins/now/hooks/use_streaming.ts +0 -88
- package/src/plugins/now/index.ts +0 -62
- package/src/plugins/now/utils/streaming.ts +0 -33
- package/src/plugins/sticker/components/StickerCom.tsx +0 -45
- package/src/plugins/sticker/const.ts +0 -76
- package/src/plugins/sticker/context.ts +0 -7
- package/src/plugins/sticker/index.ts +0 -43
- package/src/plugins/sticker/types.ts +0 -10
- package/src/plugins/store/components/ArrowCom.tsx +0 -34
- package/src/plugins/store/components/ArrowSvg.tsx +0 -1133
- package/src/plugins/store/components/storeIcon.tsx +0 -16
- package/src/plugins/store/components/storePage.tsx +0 -202
- package/src/plugins/store/context/index.ts +0 -15
- package/src/plugins/store/index.ts +0 -57
- package/src/plugins/store/utils/index.ts +0 -26
- package/src/plugins/version/index.ts +0 -28
- package/src/plugins/xwy/components/XwyLink.tsx +0 -7
- package/src/plugins/xwy/components/article.tsx +0 -13
- package/src/plugins/xwy/components/logo.tsx +0 -28
- package/src/plugins/xwy/const/index.ts +0 -28
- package/src/plugins/xwy/index.ts +0 -103
- package/src/plugins/xwy/transformers/index.ts +0 -67
- package/src/plugins/xwy/types/index.ts +0 -17
- 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,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
|
-
}
|
package/src/plugins/now/index.ts
DELETED
|
@@ -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,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,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
|
-
};
|