@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,79 +0,0 @@
|
|
|
1
|
-
import { BBPlugin } from '#/core/plugin-system/bbplugin';
|
|
2
|
-
import { SystemUIService } from '#/core/plugin-system/services/systemUIService';
|
|
3
|
-
import { ServiceRegistry } from '#/core/shared-service/service-registry';
|
|
4
|
-
import { IHostContext } from '#/types/hostApi';
|
|
5
|
-
import { PluginID } from '#/types/plugin';
|
|
6
|
-
|
|
7
|
-
import { BlogPageApp } from './components/app';
|
|
8
|
-
import { BlogLink } from './components/BlogLink';
|
|
9
|
-
import { BlogContext } from './context';
|
|
10
|
-
import { BlogUIService } from './services/BlogUIService';
|
|
11
|
-
|
|
12
|
-
const { withCtx } = BlogContext;
|
|
13
|
-
|
|
14
|
-
export class BlogPlugin extends BBPlugin {
|
|
15
|
-
id: PluginID = 'blog';
|
|
16
|
-
|
|
17
|
-
private _serviceRegistry?: ServiceRegistry;
|
|
18
|
-
|
|
19
|
-
private _unsubscribePluginUninstall?: () => void;
|
|
20
|
-
|
|
21
|
-
override onInstall = async (ctx: IHostContext) => {
|
|
22
|
-
ctx.service.register('blog:uiService', BlogUIService.getInstance());
|
|
23
|
-
|
|
24
|
-
this._serviceRegistry = ctx.service;
|
|
25
|
-
|
|
26
|
-
const coreService = ctx.service.get('core:baseService');
|
|
27
|
-
const systemUIService = ctx.service.get('core:uiService');
|
|
28
|
-
|
|
29
|
-
if (!coreService) {
|
|
30
|
-
console.error('Core service not found. BlogPlugin installation failed.');
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
this._unsubscribePluginUninstall = coreService.subscribePluginUninstall(
|
|
35
|
-
this.handlePluginUninstall
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
systemUIService?.registerPluginEntry(
|
|
39
|
-
{
|
|
40
|
-
path: '/blog',
|
|
41
|
-
label: 'cd ./blog',
|
|
42
|
-
pageComponent: withCtx(
|
|
43
|
-
{
|
|
44
|
-
setLoading: loading => {
|
|
45
|
-
coreService.setLoading('blog', loading);
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
BlogPageApp
|
|
49
|
-
),
|
|
50
|
-
},
|
|
51
|
-
this.id
|
|
52
|
-
);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
override onManualInstall = () => {
|
|
56
|
-
this.promptToOpen();
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
private promptToOpen = () => {
|
|
60
|
-
const notificationService = this._serviceRegistry?.get('notification');
|
|
61
|
-
notificationService?.notify({
|
|
62
|
-
message: '博客安装成功.',
|
|
63
|
-
action: BlogLink,
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
override onDestroy?: (() => void) | undefined = () => {
|
|
68
|
-
BlogUIService.getInstance().unregisterAllByPluginId(this.id);
|
|
69
|
-
this._serviceRegistry?.unregister('blog:uiService');
|
|
70
|
-
this._unsubscribePluginUninstall?.();
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
private handlePluginUninstall = (payload: PluginID) => {
|
|
74
|
-
BlogUIService.getInstance().unregisterAllByPluginId(payload);
|
|
75
|
-
SystemUIService.getInstance().unregisterAllByPluginId(payload);
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default new BlogPlugin();
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { NotFound } from '@bbki.ng/ui';
|
|
3
|
-
import { useParams } from 'react-router-dom';
|
|
4
|
-
|
|
5
|
-
import { usePosts } from '#/plugins/blog/hooks/use_posts';
|
|
6
|
-
import { ArticlePage } from '#/plugins/blog/components/article';
|
|
7
|
-
import { useBlogScrollReset } from '#/plugins/blog/hooks/use_blog_scroll_pos_restoration';
|
|
8
|
-
import { useMiddlewareTransformedData } from '#/plugins/blog/hooks/useMiddlewareTransData';
|
|
9
|
-
import { IPost } from '#/types/posts';
|
|
10
|
-
|
|
11
|
-
function TxtArticle() {
|
|
12
|
-
const { title } = useParams();
|
|
13
|
-
const { posts, isError, isLoading } = usePosts(title);
|
|
14
|
-
|
|
15
|
-
useBlogScrollReset();
|
|
16
|
-
|
|
17
|
-
const p = posts as IPost;
|
|
18
|
-
|
|
19
|
-
const transformedContent = useMiddlewareTransformedData('blog:transformPostContent', p?.content);
|
|
20
|
-
|
|
21
|
-
if (!title) {
|
|
22
|
-
return <NotFound />;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (isError) {
|
|
26
|
-
return <NotFound />;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (isLoading || !posts) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const date = p.createdAt ? p.createdAt.split('T')[0] : '';
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<ArticlePage title={title} date={date}>
|
|
37
|
-
<div dangerouslySetInnerHTML={{ __html: transformedContent }} />
|
|
38
|
-
</ArticlePage>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default TxtArticle;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { LinkProps, Button } from '@bbki.ng/ui';
|
|
3
|
-
|
|
4
|
-
import { usePosts } from '#/plugins/blog/hooks/use_posts';
|
|
5
|
-
import { CenterLinkList } from '#/plugins/blog/components';
|
|
6
|
-
import {
|
|
7
|
-
useBlogScroll,
|
|
8
|
-
useBlogScrollRestoration,
|
|
9
|
-
} from '#/plugins/blog/hooks/use_blog_scroll_pos_restoration';
|
|
10
|
-
|
|
11
|
-
type TxtProps = {
|
|
12
|
-
title?: string;
|
|
13
|
-
articleList?: LinkProps[];
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const Txt = (props: TxtProps) => {
|
|
17
|
-
const { titleList, isError } = usePosts();
|
|
18
|
-
|
|
19
|
-
useBlogScrollRestoration();
|
|
20
|
-
|
|
21
|
-
const { gotoTop } = useBlogScroll();
|
|
22
|
-
|
|
23
|
-
if (isError) {
|
|
24
|
-
return <CenterLinkList links={props.articleList ?? titleList} />;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const links = props.articleList ?? titleList;
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<CenterLinkList
|
|
31
|
-
links={links}
|
|
32
|
-
footer={
|
|
33
|
-
links.length > 0 ? (
|
|
34
|
-
<Button onClick={gotoTop} className="mt-32">
|
|
35
|
-
<svg
|
|
36
|
-
data-testid="geist-icon"
|
|
37
|
-
height="16"
|
|
38
|
-
strokeLinejoin="round"
|
|
39
|
-
viewBox="0 0 16 16"
|
|
40
|
-
width="16"
|
|
41
|
-
>
|
|
42
|
-
<path
|
|
43
|
-
fillRule="evenodd"
|
|
44
|
-
clipRule="evenodd"
|
|
45
|
-
d="M8.70711 1.39644C8.31659 1.00592 7.68342 1.00592 7.2929 1.39644L2.21968 6.46966L1.68935 6.99999L2.75001 8.06065L3.28034 7.53032L7.25001 3.56065V14.25V15H8.75001V14.25V3.56065L12.7197 7.53032L13.25 8.06065L14.3107 6.99999L13.7803 6.46966L8.70711 1.39644Z"
|
|
46
|
-
fill="currentColor"
|
|
47
|
-
></path>
|
|
48
|
-
</svg>
|
|
49
|
-
</Button>
|
|
50
|
-
) : null
|
|
51
|
-
}
|
|
52
|
-
/>
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
Txt.displayName = 'Txt';
|
|
57
|
-
|
|
58
|
-
export default Txt;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { createUIService } from '#/core/shared-service/factory/createUIService';
|
|
2
|
-
|
|
3
|
-
import { BlogDataHookPoint, BlogSlotName, IBlogUIService } from './IBlogUIService';
|
|
4
|
-
|
|
5
|
-
const baseService = createUIService<BlogSlotName, BlogDataHookPoint>('blog');
|
|
6
|
-
|
|
7
|
-
export class BlogUIService implements IBlogUIService {
|
|
8
|
-
private static instance: BlogUIService;
|
|
9
|
-
|
|
10
|
-
private constructor() {}
|
|
11
|
-
|
|
12
|
-
static getInstance(): BlogUIService {
|
|
13
|
-
if (!BlogUIService.instance) {
|
|
14
|
-
BlogUIService.instance = new BlogUIService();
|
|
15
|
-
}
|
|
16
|
-
return BlogUIService.instance;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
registerSlot = baseService.registerSlot.bind(baseService);
|
|
20
|
-
registerMiddleware = baseService.registerMiddleware.bind(baseService);
|
|
21
|
-
unregisterAllByPluginId = baseService.unregisterAllByPluginId.bind(baseService);
|
|
22
|
-
getSlotEntries = baseService.getSlotEntries.bind(baseService);
|
|
23
|
-
getComponents = baseService.getComponents.bind(baseService);
|
|
24
|
-
subscribeSlotChange = baseService.subscribeSlotChange.bind(baseService);
|
|
25
|
-
subscribeMiddlewareChange = baseService.subscribeMiddlewareChange.bind(baseService);
|
|
26
|
-
runMiddlewares = baseService.runMiddlewares.bind(baseService);
|
|
27
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type IBaseUIService } from '#/core/shared-service/contract/IUIService';
|
|
2
|
-
|
|
3
|
-
declare module '#/core/shared-service/service-registry' {
|
|
4
|
-
interface ServiceIdentifierMap {
|
|
5
|
-
'blog:uiService': IBlogUIService;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type BlogSlotName = 'blog:articleActionRow' | 'blog:articleTitle';
|
|
10
|
-
|
|
11
|
-
export type BlogDataHookPoint =
|
|
12
|
-
| 'blog:filterPosts'
|
|
13
|
-
| 'blog:transformPostContent'
|
|
14
|
-
| 'blog:transformTitleList';
|
|
15
|
-
|
|
16
|
-
export interface IBlogUIService extends IBaseUIService<BlogSlotName, BlogDataHookPoint> {}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { BBPlugin } from '#/core/plugin-system/bbplugin';
|
|
2
|
-
import { IHostContext } from '#/types/hostApi';
|
|
3
|
-
import { PluginID } from '#/types/plugin';
|
|
4
|
-
import { TitleListItem } from '#/types/posts';
|
|
5
|
-
|
|
6
|
-
class ExtraCd extends BBPlugin {
|
|
7
|
-
id: PluginID = 'extra-cd';
|
|
8
|
-
|
|
9
|
-
override onInstall = async (ctx: IHostContext): Promise<void> => {
|
|
10
|
-
const blogUIService = ctx.service.get('blog:uiService');
|
|
11
|
-
if (!blogUIService) {
|
|
12
|
-
console.error('Blog UI service not found. ExtraCd installation failed.');
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
blogUIService.registerMiddleware(
|
|
17
|
-
'blog:transformTitleList',
|
|
18
|
-
this.transformTitleList,
|
|
19
|
-
this.id,
|
|
20
|
-
10
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
private transformTitleList = (titleList: Array<TitleListItem>) => {
|
|
25
|
-
return [
|
|
26
|
-
...titleList,
|
|
27
|
-
{
|
|
28
|
-
name: 'cd ~',
|
|
29
|
-
to: '/',
|
|
30
|
-
children: 'cd ~',
|
|
31
|
-
},
|
|
32
|
-
];
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default new ExtraCd();
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { PathRouteProps } from 'react-router-dom';
|
|
3
|
-
|
|
4
|
-
import { IComPropsRegisteredToSlot } from '#/types/slots';
|
|
5
|
-
|
|
6
|
-
export const ExtendedRoutesPage = ({ data }: IComPropsRegisteredToSlot) => {
|
|
7
|
-
const route = data as Omit<PathRouteProps, 'element'>;
|
|
8
|
-
|
|
9
|
-
if (route.path === '/hello') {
|
|
10
|
-
return <div className="p-4 text-center">Hello from Extra Entry Plugin!</div>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return <></>;
|
|
14
|
-
};
|
|
@@ -1,28 +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 { ExtendedRoutesPage } from './components/page';
|
|
6
|
-
|
|
7
|
-
export class ExtraEntryPlugin extends BBPlugin {
|
|
8
|
-
id: PluginID = 'extra-entry';
|
|
9
|
-
|
|
10
|
-
override onInstall = async (ctx: IHostContext): Promise<void> => {
|
|
11
|
-
const systemUIService = ctx.service.get('core:uiService');
|
|
12
|
-
if (!systemUIService) {
|
|
13
|
-
console.warn(`[${this.id}] core:uiService not found, cannot register entry`);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
systemUIService.registerPluginEntry(
|
|
18
|
-
{
|
|
19
|
-
pageComponent: ExtendedRoutesPage,
|
|
20
|
-
path: '/hello',
|
|
21
|
-
label: 'cd ./hello',
|
|
22
|
-
},
|
|
23
|
-
this.id
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default new ExtraEntryPlugin();
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React, { useMemo } from 'react';
|
|
2
|
-
import { EffectLayer, grain, paper, spiral, watermark, Effect } from '@bbki.ng/ui';
|
|
3
|
-
|
|
4
|
-
import { IComPropsRegisteredToSlot } from '#/types/slots';
|
|
5
|
-
|
|
6
|
-
import { FxContext } from '../context';
|
|
7
|
-
import { useTextEffects } from '../hooks/useTextEffects';
|
|
8
|
-
|
|
9
|
-
const useLoadingState = () => {
|
|
10
|
-
const ctx = FxContext.useCtx();
|
|
11
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
12
|
-
|
|
13
|
-
React.useEffect(() => {
|
|
14
|
-
const unsubscribe = ctx.subscribeToLoading(setIsLoading);
|
|
15
|
-
return () => {
|
|
16
|
-
unsubscribe();
|
|
17
|
-
};
|
|
18
|
-
}, [ctx]);
|
|
19
|
-
|
|
20
|
-
return isLoading;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const FxCom = (_: IComPropsRegisteredToSlot) => {
|
|
24
|
-
const ctx = FxContext.useCtx();
|
|
25
|
-
// const hashStr = ctx.versionHash;
|
|
26
|
-
const deviceId = ctx.deviceId;
|
|
27
|
-
const isLoading = useLoadingState();
|
|
28
|
-
|
|
29
|
-
const textEffects = useTextEffects();
|
|
30
|
-
|
|
31
|
-
const effects: Effect[] = useMemo(() => {
|
|
32
|
-
const wmLines = [];
|
|
33
|
-
if (deviceId) wmLines.push(deviceId);
|
|
34
|
-
|
|
35
|
-
return [
|
|
36
|
-
grain(),
|
|
37
|
-
paper(),
|
|
38
|
-
spiral({ active: isLoading }),
|
|
39
|
-
watermark({ lines: wmLines }),
|
|
40
|
-
...textEffects,
|
|
41
|
-
];
|
|
42
|
-
}, [isLoading, deviceId, textEffects]);
|
|
43
|
-
|
|
44
|
-
return <EffectLayer effects={effects} />;
|
|
45
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { createPluginCtx } from '#/core/context';
|
|
2
|
-
import { PluginEvents } from '#/types/plugin';
|
|
3
|
-
|
|
4
|
-
export interface IFxContext {
|
|
5
|
-
versionHash: string;
|
|
6
|
-
deviceId: string;
|
|
7
|
-
subscribeToLoading: (
|
|
8
|
-
listener: (payload: PluginEvents['site:loading:changed']) => void
|
|
9
|
-
) => () => void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const FxContext = createPluginCtx<IFxContext>();
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { drawText } from '@bbki.ng/ui';
|
|
3
|
-
|
|
4
|
-
import { DrawTextConfig } from '../services/IFxService';
|
|
5
|
-
import { FxService } from '../services/FxService';
|
|
6
|
-
|
|
7
|
-
const empty = {};
|
|
8
|
-
|
|
9
|
-
export const useTextEffects = () => {
|
|
10
|
-
const fxServiceInst = FxService.getInstance();
|
|
11
|
-
const [fxMap, setFxMap] = useState<Record<string, DrawTextConfig>>(empty);
|
|
12
|
-
const [v, setVersion] = useState(0); // 用于强制更新组件
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
const drawTextUnsub = fxServiceInst.subscribeDrawText(config => {
|
|
16
|
-
setFxMap(prev => ({ ...prev, [config.id]: config }));
|
|
17
|
-
setVersion(v => v + 1); // 强制更新组件以应用新的文本效果
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const clearTextUnsub = fxServiceInst.subscribeClearText(id => {
|
|
21
|
-
setFxMap(prev => {
|
|
22
|
-
const newMap = { ...prev };
|
|
23
|
-
delete newMap[id];
|
|
24
|
-
return newMap;
|
|
25
|
-
});
|
|
26
|
-
setVersion(v => v + 1); // 强制更新组件以移除文本效果
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
return () => {
|
|
30
|
-
drawTextUnsub();
|
|
31
|
-
clearTextUnsub();
|
|
32
|
-
};
|
|
33
|
-
}, [fxServiceInst]);
|
|
34
|
-
|
|
35
|
-
return useMemo(() => {
|
|
36
|
-
console.log("fx text's snapshot version:", v);
|
|
37
|
-
return Object.values(fxMap).map(drawText);
|
|
38
|
-
}, [fxMap, v]);
|
|
39
|
-
};
|
package/src/plugins/fx/index.ts
DELETED
|
@@ -1,53 +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 { FxCom } from './components';
|
|
6
|
-
import { FxContext } from './context';
|
|
7
|
-
import { FxService } from './services/FxService';
|
|
8
|
-
|
|
9
|
-
class FxPlugin extends BBPlugin {
|
|
10
|
-
id: PluginID = 'fx';
|
|
11
|
-
|
|
12
|
-
private _ctx: IHostContext | null = null;
|
|
13
|
-
|
|
14
|
-
override onInstall = async (ctx: IHostContext) => {
|
|
15
|
-
this._ctx = ctx;
|
|
16
|
-
|
|
17
|
-
const coreService = ctx.service.get('core:baseService');
|
|
18
|
-
|
|
19
|
-
if (!coreService) {
|
|
20
|
-
console.error('Core service not found. FxPlugin installation failed.');
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const systemUIService = ctx.service.get('core:uiService');
|
|
25
|
-
if (!systemUIService) {
|
|
26
|
-
console.error('UI service not found. FxPlugin installation failed.');
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
ctx.service.register('fx:service', FxService.getInstance());
|
|
31
|
-
|
|
32
|
-
systemUIService.registerSlot(
|
|
33
|
-
'pageFooter',
|
|
34
|
-
FxContext.withCtx(
|
|
35
|
-
{
|
|
36
|
-
versionHash: await coreService.getVersionHash(),
|
|
37
|
-
deviceId: (await coreService.getDeviceId())?.id,
|
|
38
|
-
subscribeToLoading: listener => {
|
|
39
|
-
return coreService.subscribeLoadingChange(listener);
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
FxCom
|
|
43
|
-
),
|
|
44
|
-
this.id
|
|
45
|
-
);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
override onDestroy?: (() => void) | undefined = () => {
|
|
49
|
-
this._ctx?.service.unregister('fx:service');
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export default new FxPlugin();
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { createEventBus } from '#/core/utils/eventBus';
|
|
2
|
-
|
|
3
|
-
import { DrawTextConfig, IFxService } from './IFxService';
|
|
4
|
-
|
|
5
|
-
export type DrawTextEvent = {
|
|
6
|
-
'fx:drawText': DrawTextConfig & { id: string };
|
|
7
|
-
'fx:clearText': string; // id of the text to clear
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export class FxService implements IFxService {
|
|
11
|
-
private bus = createEventBus<DrawTextEvent>();
|
|
12
|
-
|
|
13
|
-
private configs: Array<DrawTextConfig & { id: string }> = [];
|
|
14
|
-
|
|
15
|
-
drawText: (c: DrawTextConfig) => () => void = (opts: DrawTextConfig) => {
|
|
16
|
-
const id = `${Date.now()}-${Math.random()}`;
|
|
17
|
-
|
|
18
|
-
const fullConfig = { ...opts, id };
|
|
19
|
-
|
|
20
|
-
this.configs.push(fullConfig);
|
|
21
|
-
|
|
22
|
-
this.bus.emit('fx:drawText', fullConfig);
|
|
23
|
-
|
|
24
|
-
return () => {
|
|
25
|
-
this.configs = this.configs.filter(c => c.id !== id);
|
|
26
|
-
// Emit an empty config to signal clearing the text
|
|
27
|
-
this.bus.emit('fx:clearText', id);
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
subscribeDrawText(listener: (payload: DrawTextEvent['fx:drawText']) => void) {
|
|
32
|
-
return this.bus.on('fx:drawText', listener);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
subscribeClearText(listener: (payload: DrawTextEvent['fx:clearText']) => void) {
|
|
36
|
-
return this.bus.on('fx:clearText', listener);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private static instance: FxService | null = null;
|
|
40
|
-
|
|
41
|
-
static getInstance(): FxService {
|
|
42
|
-
if (!FxService.instance) {
|
|
43
|
-
FxService.instance = new FxService();
|
|
44
|
-
}
|
|
45
|
-
return FxService.instance;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { DrawTextEffect } from '@bbki.ng/ui';
|
|
2
|
-
|
|
3
|
-
declare module '#/core/shared-service/service-registry' {
|
|
4
|
-
interface ServiceIdentifierMap {
|
|
5
|
-
'fx:service': IFxService;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type DrawTextConfig = Omit<DrawTextEffect, 'clear' | 'type'>;
|
|
10
|
-
|
|
11
|
-
export interface IFxService {
|
|
12
|
-
drawText: (opts: DrawTextConfig) => () => void;
|
|
13
|
-
subscribeDrawText: (listener: (payload: DrawTextConfig & { id: string }) => void) => () => void;
|
|
14
|
-
subscribeClearText: (listener: (payload: string) => void) => () => void;
|
|
15
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import React, { FC } from 'react';
|
|
2
|
-
import { Toaster } from 'sonner';
|
|
3
|
-
|
|
4
|
-
import { IComPropsRegisteredToSlot } from '#/types/slots';
|
|
5
|
-
|
|
6
|
-
export const NotifyComp: FC<IComPropsRegisteredToSlot> = _ => {
|
|
7
|
-
return (
|
|
8
|
-
<Toaster
|
|
9
|
-
position="bottom-center"
|
|
10
|
-
style={{
|
|
11
|
-
position: 'fixed',
|
|
12
|
-
zIndex: 998,
|
|
13
|
-
}}
|
|
14
|
-
toastOptions={{
|
|
15
|
-
style: {
|
|
16
|
-
borderRadius: 0,
|
|
17
|
-
border: 'none',
|
|
18
|
-
},
|
|
19
|
-
classNames: {
|
|
20
|
-
actionButton: 'rounded-none!',
|
|
21
|
-
toast: 'font-mono',
|
|
22
|
-
},
|
|
23
|
-
}}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
@@ -1,26 +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 { NotifyComp } from './components';
|
|
6
|
-
import { NotificationService } from './services/NotificationService';
|
|
7
|
-
|
|
8
|
-
export class NotificationPlugin extends BBPlugin {
|
|
9
|
-
id: PluginID = 'notification' as const;
|
|
10
|
-
|
|
11
|
-
private _serviceRegistry?: IHostContext['service'];
|
|
12
|
-
|
|
13
|
-
override onInstall = async (ctx: IHostContext) => {
|
|
14
|
-
this._serviceRegistry = ctx.service;
|
|
15
|
-
this._serviceRegistry.register('notification', NotificationService.getInstance());
|
|
16
|
-
|
|
17
|
-
const coreUIService = ctx.service.get('core:uiService');
|
|
18
|
-
coreUIService.registerSlot('pageFooter', NotifyComp, this.id);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
override onDestroy = () => {
|
|
22
|
-
this._serviceRegistry?.unregister('notification');
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default new NotificationPlugin();
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type React from 'react';
|
|
2
|
-
import { ToastT } from 'sonner';
|
|
3
|
-
|
|
4
|
-
declare module '#/core/shared-service/service-registry' {
|
|
5
|
-
interface ServiceIdentifierMap {
|
|
6
|
-
notification: INotificationService;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type NotificationType = 'toast' | 'banner' | 'modal';
|
|
11
|
-
|
|
12
|
-
export interface INotificationOptions extends Omit<
|
|
13
|
-
ToastT,
|
|
14
|
-
'message' | 'id' | 'type' | 'title' | 'jsx' | 'delete' | 'promise'
|
|
15
|
-
> {
|
|
16
|
-
uiType?: NotificationType;
|
|
17
|
-
message: (() => React.ReactNode) | React.ReactNode;
|
|
18
|
-
duration?: number; // 持续时间,单位为毫秒,默认为4000ms
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface INotificationService {
|
|
22
|
-
notify: (options: INotificationOptions) => string;
|
|
23
|
-
dismiss: (id: string) => void;
|
|
24
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { toast } from 'sonner';
|
|
2
|
-
|
|
3
|
-
import { INotificationOptions, INotificationService } from './INotificationService';
|
|
4
|
-
|
|
5
|
-
export class NotificationService implements INotificationService {
|
|
6
|
-
private static instance: NotificationService;
|
|
7
|
-
|
|
8
|
-
private constructor() {}
|
|
9
|
-
|
|
10
|
-
static getInstance(): NotificationService {
|
|
11
|
-
if (!NotificationService.instance) {
|
|
12
|
-
NotificationService.instance = new NotificationService();
|
|
13
|
-
}
|
|
14
|
-
return NotificationService.instance;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
notify(options: INotificationOptions): string {
|
|
18
|
-
const id = toast(options.message, {
|
|
19
|
-
duration: options.duration || 3000,
|
|
20
|
-
...options,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return id as string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
dismiss(id: string): void {
|
|
27
|
-
toast.dismiss(id);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import classNames from 'classnames';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
|
|
4
|
-
export const ArrowDownIcon = ({ show }: { show: boolean }) => (
|
|
5
|
-
<svg
|
|
6
|
-
data-testid="geist-icon"
|
|
7
|
-
height="16"
|
|
8
|
-
strokeLinejoin="round"
|
|
9
|
-
viewBox="0 0 16 16"
|
|
10
|
-
width="16"
|
|
11
|
-
style={{
|
|
12
|
-
rotate: '180deg',
|
|
13
|
-
}}
|
|
14
|
-
className={classNames('transition-opacity duration-200 inline-block', {
|
|
15
|
-
'opacity-0': !show,
|
|
16
|
-
'opacity-100': show,
|
|
17
|
-
})}
|
|
18
|
-
>
|
|
19
|
-
<path
|
|
20
|
-
fillRule="evenodd"
|
|
21
|
-
clipRule="evenodd"
|
|
22
|
-
d="M8.70711 1.39644C8.31659 1.00592 7.68342 1.00592 7.2929 1.39644L2.21968 6.46966L1.68935 6.99999L2.75001 8.06065L3.28034 7.53032L7.25001 3.56065V14.25V15H8.75001V14.25V3.56065L12.7197 7.53032L13.25 8.06065L14.3107 6.99999L13.7803 6.46966L8.70711 1.39644Z"
|
|
23
|
-
fill="currentColor"
|
|
24
|
-
></path>
|
|
25
|
-
</svg>
|
|
26
|
-
);
|