@bbki.ng/site 5.8.8 → 5.8.9
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 +8 -0
- package/package.json +2 -2
- package/src/core/shared-service/service-proxy.ts +3 -1
- package/src/plugins/fx/components/index.tsx +10 -4
- package/src/plugins/fx/hooks/useTextEffects.ts +39 -0
- package/src/plugins/fx/index.ts +11 -0
- package/src/plugins/fx/services/FxService.ts +47 -0
- package/src/plugins/fx/services/IFxService.ts +15 -0
- package/src/plugins/sticker/components/StickerCom.tsx +4 -4
- package/src/plugins/sticker/index.ts +1 -1
- package/src/plugins/store/components/storePage.tsx +3 -3
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbki.ng/site",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.9",
|
|
4
4
|
"description": "code behind bbki.ng",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"react-router-dom": "6",
|
|
16
16
|
"sonner": "^2.0.7",
|
|
17
17
|
"swr": "^2.2.5",
|
|
18
|
-
"@bbki.ng/ui": "0.2.
|
|
18
|
+
"@bbki.ng/ui": "0.2.21"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@eslint/compat": "^1.0.0",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ServiceIdentifierMap, ServiceRegistry } from '#/core/shared-service/service-registry';
|
|
2
2
|
|
|
3
|
+
const empty = {};
|
|
4
|
+
|
|
3
5
|
// core/ServiceProxy.ts
|
|
4
6
|
export function createServiceProxy<T extends object, K extends keyof ServiceIdentifierMap>(
|
|
5
7
|
serviceId: K,
|
|
@@ -14,7 +16,7 @@ export function createServiceProxy<T extends object, K extends keyof ServiceIden
|
|
|
14
16
|
console.warn(
|
|
15
17
|
`[System] Service ${serviceId} is currently unavailable. Call to ${String(prop)} ignored.`
|
|
16
18
|
);
|
|
17
|
-
return
|
|
19
|
+
return empty;
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -4,6 +4,7 @@ import { EffectLayer, grain, paper, spiral, watermark, Effect } from '@bbki.ng/u
|
|
|
4
4
|
import { IComPropsRegisteredToSlot } from '#/types/slots';
|
|
5
5
|
|
|
6
6
|
import { FxContext } from '../context';
|
|
7
|
+
import { useTextEffects } from '../hooks/useTextEffects';
|
|
7
8
|
|
|
8
9
|
const useLoadingState = () => {
|
|
9
10
|
const ctx = FxContext.useCtx();
|
|
@@ -25,15 +26,20 @@ export const FxCom = (_: IComPropsRegisteredToSlot) => {
|
|
|
25
26
|
const deviceId = ctx.deviceId;
|
|
26
27
|
const isLoading = useLoadingState();
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
const textEffects = useTextEffects();
|
|
29
30
|
|
|
30
31
|
const effects: Effect[] = useMemo(() => {
|
|
31
32
|
const wmLines = [hashStr];
|
|
32
33
|
if (deviceId) wmLines.push(deviceId);
|
|
33
|
-
wmLines.push('hello world');
|
|
34
34
|
|
|
35
|
-
return [
|
|
36
|
-
|
|
35
|
+
return [
|
|
36
|
+
grain(),
|
|
37
|
+
paper(),
|
|
38
|
+
spiral({ active: isLoading }),
|
|
39
|
+
watermark({ lines: wmLines }),
|
|
40
|
+
...textEffects,
|
|
41
|
+
];
|
|
42
|
+
}, [isLoading, deviceId, hashStr, textEffects]);
|
|
37
43
|
|
|
38
44
|
return <EffectLayer effects={effects} />;
|
|
39
45
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
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
CHANGED
|
@@ -4,11 +4,16 @@ import { PluginID } from '#/types/plugin';
|
|
|
4
4
|
|
|
5
5
|
import { FxCom } from './components';
|
|
6
6
|
import { FxContext } from './context';
|
|
7
|
+
import { FxService } from './services/FxService';
|
|
7
8
|
|
|
8
9
|
class FxPlugin extends BBPlugin {
|
|
9
10
|
id: PluginID = 'fx';
|
|
10
11
|
|
|
12
|
+
private _ctx: IHostContext | null = null;
|
|
13
|
+
|
|
11
14
|
override onInstall = async (ctx: IHostContext) => {
|
|
15
|
+
this._ctx = ctx;
|
|
16
|
+
|
|
12
17
|
const coreService = ctx.service.get('core:baseService');
|
|
13
18
|
|
|
14
19
|
if (!coreService) {
|
|
@@ -22,6 +27,8 @@ class FxPlugin extends BBPlugin {
|
|
|
22
27
|
return;
|
|
23
28
|
}
|
|
24
29
|
|
|
30
|
+
ctx.service.register('fx:service', FxService.getInstance());
|
|
31
|
+
|
|
25
32
|
systemUIService.registerSlot(
|
|
26
33
|
'pageFooter',
|
|
27
34
|
FxContext.withCtx(
|
|
@@ -37,6 +44,10 @@ class FxPlugin extends BBPlugin {
|
|
|
37
44
|
this.id
|
|
38
45
|
);
|
|
39
46
|
};
|
|
47
|
+
|
|
48
|
+
override onDestroy?: (() => void) | undefined = () => {
|
|
49
|
+
this._ctx?.service.unregister('fx:service');
|
|
50
|
+
};
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
export default new FxPlugin();
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
}
|
|
@@ -12,11 +12,11 @@ export const StickerCom = ({ data }: IComPropsRegisteredToSlot) => {
|
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const lastPath = paths[paths.length - 1];
|
|
15
|
+
// const lastPath = paths[paths.length - 1];
|
|
16
16
|
|
|
17
|
-
if (lastPath.name !== '~') {
|
|
18
|
-
|
|
19
|
-
}
|
|
17
|
+
// if (lastPath.name !== '~') {
|
|
18
|
+
// return null;
|
|
19
|
+
// }
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<div className="fixed bottom-32 left-16">
|
|
@@ -118,9 +118,9 @@ export const StorePage = (_: IComPropsRegisteredToSlot) => {
|
|
|
118
118
|
const headerRenderer = useCallback(() => {
|
|
119
119
|
return (
|
|
120
120
|
<>
|
|
121
|
-
<Table.HCell
|
|
122
|
-
<Table.HCell style={{ width: 'unset', maxWidth: 'unset' }}
|
|
123
|
-
<Table.HCell style={{ textAlign: 'right' }}
|
|
121
|
+
<Table.HCell>功能清单</Table.HCell>
|
|
122
|
+
<Table.HCell style={{ width: 'unset', maxWidth: 'unset' }}> </Table.HCell>
|
|
123
|
+
<Table.HCell style={{ textAlign: 'right' }}> </Table.HCell>
|
|
124
124
|
</>
|
|
125
125
|
);
|
|
126
126
|
}, []);
|