@vnejs/plugins.views.screens.history 0.1.8 → 0.1.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/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/modules/controller.d.ts +24 -0
- package/dist/modules/controller.js +40 -0
- package/dist/modules/history.d.ts +18 -0
- package/dist/modules/history.js +48 -0
- package/dist/modules/view.d.ts +11 -0
- package/dist/modules/view.js +10 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +1 -0
- package/dist/utils/history.d.ts +43 -0
- package/dist/utils/history.js +1 -0
- package/dist/view/components/HistoryClose.d.ts +6 -0
- package/dist/view/components/HistoryClose.js +8 -0
- package/dist/view/components/HistoryLines.d.ts +11 -0
- package/dist/view/components/HistoryLines.js +37 -0
- package/dist/view/components/index.d.ts +2 -0
- package/dist/view/components/index.js +2 -0
- package/dist/view/index.d.ts +3 -0
- package/dist/view/index.js +13 -0
- package/package.json +41 -6
- package/src/index.ts +8 -0
- package/src/modules/controller.ts +64 -0
- package/{modules/history.js → src/modules/history.ts} +20 -11
- package/src/modules/view.ts +22 -0
- package/src/types.ts +24 -0
- package/src/utils/history.ts +53 -0
- package/src/view/components/HistoryClose.tsx +21 -0
- package/src/view/components/HistoryLines.tsx +78 -0
- package/src/view/components/index.ts +2 -0
- package/src/view/index.tsx +42 -0
- package/tsconfig.json +10 -0
- package/const/events.js +0 -14
- package/const/params.js +0 -11
- package/index.js +0 -10
- package/modules/controller.js +0 -49
- package/modules/view.js +0 -14
- package/view/components/HistoryClose.jsx +0 -15
- package/view/components/HistoryLines.jsx +0 -53
- package/view/components/index.js +0 -2
- package/view/index.jsx +0 -27
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { regPlugin } from "@vnejs/shared";
|
|
2
|
+
import { PARAMS, PLUGIN_NAME, SUBSCRIBE_EVENTS } from "@vnejs/plugins.views.screens.history.contract";
|
|
3
|
+
import { HistoryController } from "./modules/controller.js";
|
|
4
|
+
import { History } from "./modules/history.js";
|
|
5
|
+
import { HistoryView } from "./modules/view.js";
|
|
6
|
+
regPlugin(PLUGIN_NAME, { events: SUBSCRIBE_EVENTS, params: PARAMS }, [HistoryController, History, HistoryView]);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ModuleController } from "@vnejs/module.components";
|
|
2
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
3
|
+
import type { HistoryClickPayload, HistoryEntry, HistoryPluginState } from "../utils/history.js";
|
|
4
|
+
export declare class HistoryController extends ModuleController<HistoryPluginEvents, HistoryPluginConstants, HistoryPluginSettings, HistoryPluginParams, HistoryPluginState> {
|
|
5
|
+
name: string;
|
|
6
|
+
emitHide: () => undefined;
|
|
7
|
+
updateEvent: "vne:history:update";
|
|
8
|
+
controls: {
|
|
9
|
+
abstract_back: () => undefined;
|
|
10
|
+
abstract_menu: () => undefined;
|
|
11
|
+
abstract_gamemenu: () => undefined;
|
|
12
|
+
abstract_arrow_up: () => undefined;
|
|
13
|
+
abstract_arrow_bottom: () => undefined;
|
|
14
|
+
abstract_accept: () => undefined;
|
|
15
|
+
};
|
|
16
|
+
controlsIndex: number;
|
|
17
|
+
subscribe: () => void;
|
|
18
|
+
beforeShow: () => Promise<void>;
|
|
19
|
+
afterHide: () => void;
|
|
20
|
+
onAccept: () => false | undefined;
|
|
21
|
+
onClick: ({ uid }?: HistoryClickPayload) => false | undefined;
|
|
22
|
+
onStateSet: () => undefined;
|
|
23
|
+
getHistoryText: ({ label, text, args, uid }: HistoryEntry) => Promise<string>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ModuleController } from "@vnejs/module.components";
|
|
2
|
+
export class HistoryController extends ModuleController {
|
|
3
|
+
name = "history.controller";
|
|
4
|
+
emitHide = () => void this.emit(this.EVENTS.HISTORY.HIDE);
|
|
5
|
+
updateEvent = this.EVENTS.HISTORY.UPDATE;
|
|
6
|
+
controls = {
|
|
7
|
+
[this.CONST.CONTROLS.BUTTONS.BACK]: () => void this.emitHide(),
|
|
8
|
+
[this.CONST.CONTROLS.BUTTONS.MENU]: () => void this.emitHide(),
|
|
9
|
+
[this.CONST.CONTROLS.BUTTONS.GAMEMENU]: () => void this.emitHide(),
|
|
10
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_UP]: () => void this.decCurrentItem(),
|
|
11
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_BOTTOM]: () => void this.incCurrentItem(),
|
|
12
|
+
[this.CONST.CONTROLS.BUTTONS.ACCEPT]: () => void this.emit(this.EVENTS.HISTORY.ACCEPT),
|
|
13
|
+
};
|
|
14
|
+
controlsIndex = this.PARAMS.HISTORY.ZINDEX;
|
|
15
|
+
subscribe = () => {
|
|
16
|
+
this.on(this.EVENTS.HISTORY.SHOW, this.onShow);
|
|
17
|
+
this.on(this.EVENTS.HISTORY.HIDE, this.onHide);
|
|
18
|
+
this.on(this.EVENTS.HISTORY.ACCEPT, this.onAccept);
|
|
19
|
+
this.on(this.EVENTS.HISTORY.CLICK, this.onClick);
|
|
20
|
+
this.on(this.EVENTS.STATE.SET, this.onStateSet);
|
|
21
|
+
};
|
|
22
|
+
beforeShow = async () => {
|
|
23
|
+
const history = this.globalState.history.history;
|
|
24
|
+
this.maxCurrentItem = history.length - 1;
|
|
25
|
+
this.updateState({
|
|
26
|
+
historyLocs: await Promise.all(history.map(this.getHistoryText)),
|
|
27
|
+
historyKeys: (await this.emitOne(this.EVENTS.HISTORY.KEYS)),
|
|
28
|
+
history,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
afterHide = () => this.setDefaultState();
|
|
32
|
+
onAccept = () => this.currentItem !== null &&
|
|
33
|
+
void this.emit(this.EVENTS.HISTORY.CLICK, { uid: this.globalState.history.history[this.currentItem].uid });
|
|
34
|
+
onClick = ({ uid } = {}) => this.state.historyKeys?.includes(uid) && void this.emit(this.EVENTS.HISTORY.LOAD, { uid });
|
|
35
|
+
onStateSet = () => void this.emit(this.EVENTS.HISTORY.HIDE, { isForce: true });
|
|
36
|
+
getHistoryText = async ({ label, text, args, uid }) => {
|
|
37
|
+
const state = (await this.emitOne(this.EVENTS.HISTORY.GET, { uid }));
|
|
38
|
+
return this.emitOne(this.EVENTS.TEXT.REPLACE, { label, text, args, state });
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "@vnejs/plugins.core.scenario.contract";
|
|
2
|
+
import { Module, type ModuleGlobalStateRegistry } from "@vnejs/module";
|
|
3
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
4
|
+
import type { HistoryAddPayload, HistoryGetPayload, HistoryLoadPayload, HistoryModuleState } from "../utils/history.js";
|
|
5
|
+
export declare class History extends Module<HistoryPluginEvents, HistoryPluginConstants, HistoryPluginSettings, HistoryPluginParams, HistoryModuleState> {
|
|
6
|
+
name: string;
|
|
7
|
+
isLoadInProcess: boolean;
|
|
8
|
+
subscribe: () => void;
|
|
9
|
+
init: () => Promise<unknown[]> | undefined;
|
|
10
|
+
onHistoryAdd: (historyObj?: HistoryAddPayload) => Promise<void>;
|
|
11
|
+
onHistoryLoad: ({ uid }?: HistoryLoadPayload) => Promise<undefined>;
|
|
12
|
+
onHistoryBack: () => false | 0 | Promise<unknown[]> | undefined;
|
|
13
|
+
onHistoryKeys: () => Promise<unknown> | undefined;
|
|
14
|
+
onHistoryGet: ({ uid }?: HistoryGetPayload) => Promise<unknown> | undefined;
|
|
15
|
+
onStateSet: (payload: ModuleGlobalStateRegistry) => Promise<void>;
|
|
16
|
+
updateHistoryKeys: () => Promise<unknown[]>;
|
|
17
|
+
getDefaultState: () => HistoryModuleState;
|
|
18
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import "@vnejs/plugins.core.scenario.contract";
|
|
2
|
+
import { Module } from "@vnejs/module";
|
|
3
|
+
export class History extends Module {
|
|
4
|
+
name = "history";
|
|
5
|
+
isLoadInProcess = false;
|
|
6
|
+
subscribe = () => {
|
|
7
|
+
this.on(this.EVENTS.HISTORY.ADD, this.onHistoryAdd);
|
|
8
|
+
this.on(this.EVENTS.HISTORY.GET, this.onHistoryGet);
|
|
9
|
+
this.on(this.EVENTS.HISTORY.LOAD, this.onHistoryLoad);
|
|
10
|
+
this.on(this.EVENTS.HISTORY.BACK, this.onHistoryBack);
|
|
11
|
+
this.on(this.EVENTS.HISTORY.KEYS, this.onHistoryKeys);
|
|
12
|
+
this.on(this.EVENTS.STATE.CLEAR, this.setDefaultState);
|
|
13
|
+
this.on(this.EVENTS.STATE.SET, this.onStateSet);
|
|
14
|
+
};
|
|
15
|
+
init = () => this.emit(this.EVENTS.MEMORY.REG, { module: this.name });
|
|
16
|
+
onHistoryAdd = async (historyObj = {}) => {
|
|
17
|
+
if (this.isLoadInProcess)
|
|
18
|
+
return;
|
|
19
|
+
const [state, uid] = (await Promise.all([this.emitOne(this.EVENTS.STATE.GET), this.emitOne(this.EVENTS.VENDORS.UID)]));
|
|
20
|
+
this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "add", uid } });
|
|
21
|
+
await this.emit(this.EVENTS.MEMORY.SET, { module: this.name, key: uid, value: state });
|
|
22
|
+
this.state.history.push({ uid, ...historyObj });
|
|
23
|
+
if (this.state.history.length > this.PARAMS.HISTORY.MAX_LENGTH)
|
|
24
|
+
this.state.history = this.state.history.slice(this.state.history.length - this.PARAMS.HISTORY.MAX_LENGTH, this.state.history.length);
|
|
25
|
+
this.updateHistoryKeys();
|
|
26
|
+
};
|
|
27
|
+
onHistoryLoad = async ({ uid } = {}) => {
|
|
28
|
+
this.isLoadInProcess = true;
|
|
29
|
+
this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "load start", uid } });
|
|
30
|
+
const state = (await this.emitOne(this.EVENTS.HISTORY.GET, { uid }));
|
|
31
|
+
if (!state)
|
|
32
|
+
return void this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "load deleted", uid } });
|
|
33
|
+
await this.emit(this.EVENTS.STATE.LOAD, await this.emitOne(this.EVENTS.VENDORS.CLONE, state));
|
|
34
|
+
this.emit(this.EVENTS.SCENARIO.LABEL_GET, { label: state.scenario?.label });
|
|
35
|
+
this.isLoadInProcess = false;
|
|
36
|
+
this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "load end", uid } });
|
|
37
|
+
this.updateHistoryKeys();
|
|
38
|
+
};
|
|
39
|
+
onHistoryBack = () => !this.isLoadInProcess && this.state.history.length && this.emit(this.EVENTS.HISTORY.LOAD, { uid: this.state.history[this.state.history.length - 1].uid });
|
|
40
|
+
onHistoryKeys = () => this.emitOne(this.EVENTS.MEMORY.KEYS, { module: this.name });
|
|
41
|
+
onHistoryGet = ({ uid = "" } = {}) => this.emitOne(this.EVENTS.MEMORY.GET, { module: this.name, key: uid });
|
|
42
|
+
onStateSet = async (payload) => {
|
|
43
|
+
const state = payload[this.name];
|
|
44
|
+
return this.setState((await this.emitOne(this.EVENTS.VENDORS.CLONE, state)));
|
|
45
|
+
};
|
|
46
|
+
updateHistoryKeys = () => Promise.all(this.state.history.map(({ uid }) => this.emitOne(this.EVENTS.HISTORY.GET, { uid })));
|
|
47
|
+
getDefaultState = () => ({ history: [] });
|
|
48
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ModuleView } from "@vnejs/module.components";
|
|
2
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
3
|
+
import type { HistoryPluginState } from "../utils/history.js";
|
|
4
|
+
export declare class HistoryView extends ModuleView<HistoryPluginEvents, HistoryPluginConstants, HistoryPluginSettings, HistoryPluginParams, HistoryPluginState> {
|
|
5
|
+
name: string;
|
|
6
|
+
locLabel: string;
|
|
7
|
+
animationTime: number;
|
|
8
|
+
updateEvent: "vne:history:update";
|
|
9
|
+
renderFunc: import("@vnejs/module.components").ViewRenderFunc<HistoryPluginState>;
|
|
10
|
+
updateHandler: (state?: HistoryPluginState | undefined) => Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ModuleView } from "@vnejs/module.components";
|
|
2
|
+
import { render } from "../view/index.js";
|
|
3
|
+
export class HistoryView extends ModuleView {
|
|
4
|
+
name = "history.view";
|
|
5
|
+
locLabel = this.PARAMS.HISTORY.LOC_LABEL;
|
|
6
|
+
animationTime = this.PARAMS.HISTORY.TRANSITION;
|
|
7
|
+
updateEvent = this.EVENTS.HISTORY.UPDATE;
|
|
8
|
+
renderFunc = render;
|
|
9
|
+
updateHandler = this.onUpdateStoreComponent;
|
|
10
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ModuleComponentsConstants, ModuleComponentsEvents, ModuleComponentsParams, ModuleComponentsSettings } from "@vnejs/module.components";
|
|
2
|
+
import type { Constants as ControlsConstants, PluginName as ControlsPluginName } from "@vnejs/plugins.controls.contract";
|
|
3
|
+
import type { PluginName as LogsPluginName, SubscribeEvents as LogsSubscribeEvents } from "@vnejs/plugins.core.logs.contract";
|
|
4
|
+
import type { PluginName as MemoryPluginName, SubscribeEvents as MemorySubscribeEvents } from "@vnejs/plugins.core.memory.contract";
|
|
5
|
+
import type { PluginName as ScenarioPluginName, SubscribeEvents as ScenarioSubscribeEvents } from "@vnejs/plugins.core.scenario.contract";
|
|
6
|
+
import type { PluginName as StatePluginName, SubscribeEvents as StateSubscribeEvents } from "@vnejs/plugins.core.state.contract";
|
|
7
|
+
import type { PluginName as VendorsPluginName, SubscribeEvents as VendorsSubscribeEvents } from "@vnejs/plugins.core.vendors.contract";
|
|
8
|
+
import type { Params as TextParams, PluginName as TextPluginName, SubscribeEvents as TextSubscribeEvents } from "@vnejs/plugins.text.contract";
|
|
9
|
+
import type { Params, PluginName, SubscribeEvents } from "@vnejs/plugins.views.screens.history.contract";
|
|
10
|
+
export type HistoryPluginEvents = ModuleComponentsEvents & Record<PluginName, SubscribeEvents> & Record<MemoryPluginName, MemorySubscribeEvents> & Record<StatePluginName, StateSubscribeEvents> & Record<VendorsPluginName, VendorsSubscribeEvents> & Record<LogsPluginName, LogsSubscribeEvents> & Record<ScenarioPluginName, ScenarioSubscribeEvents> & Record<TextPluginName, TextSubscribeEvents>;
|
|
11
|
+
export type HistoryPluginConstants = ModuleComponentsConstants & Record<ControlsPluginName, ControlsConstants>;
|
|
12
|
+
export type HistoryPluginSettings = ModuleComponentsSettings;
|
|
13
|
+
export type HistoryPluginParams = ModuleComponentsParams & Record<PluginName, Params> & Record<TextPluginName, TextParams>;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Module, ModuleGlobalState } from "@vnejs/module";
|
|
2
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
3
|
+
export type HistoryEntry = {
|
|
4
|
+
uid: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
args?: Record<string, unknown>;
|
|
8
|
+
speaker?: string;
|
|
9
|
+
meet?: number | string;
|
|
10
|
+
};
|
|
11
|
+
export type HistoryModuleState = {
|
|
12
|
+
history: HistoryEntry[];
|
|
13
|
+
};
|
|
14
|
+
export type HistoryPluginState = {
|
|
15
|
+
isShow: boolean;
|
|
16
|
+
isForce: boolean;
|
|
17
|
+
locs?: Record<string, string>;
|
|
18
|
+
history?: HistoryEntry[];
|
|
19
|
+
historyLocs?: string[];
|
|
20
|
+
historyKeys?: (string | null | undefined)[];
|
|
21
|
+
currentItem?: number | null;
|
|
22
|
+
};
|
|
23
|
+
export type HistoryViewContext = {
|
|
24
|
+
emit: Module<HistoryPluginEvents, HistoryPluginConstants, HistoryPluginSettings, HistoryPluginParams, HistoryPluginState>["emit"];
|
|
25
|
+
EVENTS: HistoryPluginEvents;
|
|
26
|
+
PARAMS: HistoryPluginParams;
|
|
27
|
+
};
|
|
28
|
+
export type HistoryAddPayload = Partial<HistoryEntry>;
|
|
29
|
+
export type HistoryGetPayload = {
|
|
30
|
+
uid?: string;
|
|
31
|
+
};
|
|
32
|
+
export type HistoryLoadPayload = {
|
|
33
|
+
uid?: string;
|
|
34
|
+
};
|
|
35
|
+
export type HistoryClickPayload = {
|
|
36
|
+
uid?: string;
|
|
37
|
+
};
|
|
38
|
+
export type HistoryReplacePayload = {
|
|
39
|
+
label?: string;
|
|
40
|
+
text?: string;
|
|
41
|
+
args?: Record<string, unknown>;
|
|
42
|
+
state?: ModuleGlobalState;
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HistoryViewContext } from "../../utils/history.js";
|
|
2
|
+
type HistoryCloseProps = HistoryViewContext & {
|
|
3
|
+
locs?: Record<string, string>;
|
|
4
|
+
};
|
|
5
|
+
export declare const HistoryClose: ({ locs, emit, EVENTS, PARAMS }: HistoryCloseProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useMemo } from "react";
|
|
3
|
+
import { PositionBox, Text } from "@vnejs/uis.react";
|
|
4
|
+
export const HistoryClose = ({ locs = {}, emit, EVENTS, PARAMS }) => {
|
|
5
|
+
const onClick = useCallback(() => void emit(EVENTS.HISTORY.HIDE), [emit, EVENTS.HISTORY.HIDE]);
|
|
6
|
+
const propsText = useMemo(() => ({ ...PARAMS.HISTORY.VIEW_PROPS.close.text, text: locs.back, onClick }), [locs, PARAMS.HISTORY.VIEW_PROPS.close.text, onClick]);
|
|
7
|
+
return (_jsx(PositionBox, { ...PARAMS.HISTORY.VIEW_PROPS.close.position, children: _jsx(Text, { ...propsText }) }));
|
|
8
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HistoryEntry, HistoryViewContext } from "../../utils/history.js";
|
|
2
|
+
type HistoryLinesProps = HistoryViewContext & {
|
|
3
|
+
isShow?: boolean;
|
|
4
|
+
history?: HistoryEntry[];
|
|
5
|
+
currentItem?: number | null;
|
|
6
|
+
historyLocs?: string[];
|
|
7
|
+
historyKeys?: (string | null | undefined)[];
|
|
8
|
+
locs?: Record<string, string>;
|
|
9
|
+
};
|
|
10
|
+
export declare const HistoryLines: ({ isShow, history, currentItem, historyLocs, historyKeys, locs, emit, EVENTS, PARAMS, }: HistoryLinesProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import { PositionBox, Text, TextControls } from "@vnejs/uis.react";
|
|
4
|
+
const scrollToBottom = (scrollbarWrapRef) => {
|
|
5
|
+
if (!scrollbarWrapRef.current)
|
|
6
|
+
return requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
7
|
+
if (scrollbarWrapRef.current.clientHeight === scrollbarWrapRef.current.scrollHeight || scrollbarWrapRef.current.scrollTop !== 0)
|
|
8
|
+
return;
|
|
9
|
+
scrollbarWrapRef.current.scrollTop = 9999999;
|
|
10
|
+
requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
11
|
+
};
|
|
12
|
+
export const HistoryLines = ({ isShow = false, history = [], currentItem = null, historyLocs = [], historyKeys = [], locs = {}, emit, EVENTS, PARAMS, }) => {
|
|
13
|
+
const scrollbarWrapRef = useRef(null);
|
|
14
|
+
const onClick = useCallback((uid) => historyKeys.includes(uid) && void emit(EVENTS.HISTORY.CLICK, { uid }), [historyKeys, emit, EVENTS.HISTORY.CLICK]);
|
|
15
|
+
const mapTexts = useCallback(({ text, uid, speaker, meet }, i) => {
|
|
16
|
+
const speakers = PARAMS.TEXT.SPEAKERS_INFO;
|
|
17
|
+
const { speakerColor = "white" } = (speakers[speaker || ""] || speakers.default || {});
|
|
18
|
+
const speakerName = locs[`speaker.${speaker}.${meet}`];
|
|
19
|
+
return {
|
|
20
|
+
text: (historyLocs && historyLocs[i]) || text,
|
|
21
|
+
value: uid,
|
|
22
|
+
textPrefix: speakerName ? `${speakerName}: ` : undefined,
|
|
23
|
+
colorPrefix: speakerColor,
|
|
24
|
+
weightPrefix: Text.WEIGHT.BOLD,
|
|
25
|
+
isHoverable: Boolean(historyKeys.find((key) => key === uid)),
|
|
26
|
+
};
|
|
27
|
+
}, [historyLocs, historyKeys, locs, PARAMS.TEXT.SPEAKERS_INFO]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (isShow)
|
|
30
|
+
requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
31
|
+
}, [isShow]);
|
|
32
|
+
const texts = useMemo(() => history.map(mapTexts), [history, mapTexts]);
|
|
33
|
+
const propsView = PARAMS.HISTORY.VIEW_PROPS.lines;
|
|
34
|
+
const propsControlsCommon = useMemo(() => ({ ...propsView.controls, onClick, scrollbarWrapRef }), [propsView.controls, onClick]);
|
|
35
|
+
const propsControls = useMemo(() => ({ ...propsControlsCommon, texts, selectedIndex: currentItem ?? undefined }), [propsControlsCommon, texts, currentItem]);
|
|
36
|
+
return (_jsx(PositionBox, { ...propsView.position, children: _jsx(TextControls, { ...propsControls }) }));
|
|
37
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Screen, createRenderFunc, useMemo, useStoreState } from "@vnejs/uis.react";
|
|
3
|
+
import { HistoryClose, HistoryLines } from "./components/index.js";
|
|
4
|
+
const History = ({ store, onMount, PARAMS, emit, EVENTS }) => {
|
|
5
|
+
const { isShow = false, isForce = false, locs = {}, history = [], historyLocs = [], historyKeys = [], currentItem = null, } = useStoreState(store, onMount);
|
|
6
|
+
const viewProps = useMemo(() => ({ emit, EVENTS, PARAMS }), [emit, EVENTS, PARAMS]);
|
|
7
|
+
const propsScreen = useMemo(() => ({ ...PARAMS.HISTORY.VIEW_PROPS.screen, isShow, isForce }), [isShow, isForce, PARAMS.HISTORY.VIEW_PROPS.screen]);
|
|
8
|
+
const propsHistory = useMemo(() => ({ history, historyLocs, historyKeys }), [history, historyLocs, historyKeys]);
|
|
9
|
+
const propsLines = useMemo(() => ({ ...viewProps, ...propsHistory, isShow, currentItem, locs }), [viewProps, propsHistory, isShow, currentItem, locs]);
|
|
10
|
+
const propsClose = useMemo(() => ({ ...viewProps, locs }), [viewProps, locs]);
|
|
11
|
+
return (_jsxs(Screen, { ...propsScreen, children: [_jsx(HistoryLines, { ...propsLines }), _jsx(HistoryClose, { ...propsClose })] }));
|
|
12
|
+
};
|
|
13
|
+
export const render = createRenderFunc(History);
|
package/package.json
CHANGED
|
@@ -1,17 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vnejs/plugins.views.screens.history",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src",
|
|
18
|
+
"tsconfig.json"
|
|
19
|
+
],
|
|
5
20
|
"scripts": {
|
|
6
21
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
22
|
+
"build": "npx @vnejs/monorepo package",
|
|
7
23
|
"publish:major:plugin": "npm run publish:major",
|
|
8
24
|
"publish:minor:plugin": "npm run publish:minor",
|
|
9
25
|
"publish:patch:plugin": "npm run publish:patch",
|
|
10
|
-
"publish:major": "
|
|
11
|
-
"publish:minor": "
|
|
12
|
-
"publish:patch": "
|
|
26
|
+
"publish:major": "npx @vnejs/monorepo publish major --access public",
|
|
27
|
+
"publish:minor": "npx @vnejs/monorepo publish minor --access public",
|
|
28
|
+
"publish:patch": "npx @vnejs/monorepo publish patch --access public"
|
|
13
29
|
},
|
|
14
30
|
"author": "",
|
|
15
31
|
"license": "ISC",
|
|
16
|
-
"
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@vnejs/plugins.views.screens.history.contract": "~0.0.1"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@vnejs/helpers": "~0.1.0",
|
|
37
|
+
"@vnejs/module": "~0.0.1",
|
|
38
|
+
"@vnejs/module.components": "~0.0.1",
|
|
39
|
+
"@vnejs/plugins.controls.contract": "~0.0.1",
|
|
40
|
+
"@vnejs/plugins.core.logs.contract": "~0.0.1",
|
|
41
|
+
"@vnejs/plugins.core.memory.contract": "~0.0.1",
|
|
42
|
+
"@vnejs/plugins.core.scenario.contract": "~0.0.1",
|
|
43
|
+
"@vnejs/plugins.core.state.contract": "~0.0.1",
|
|
44
|
+
"@vnejs/plugins.core.vendors.contract": "~0.0.1",
|
|
45
|
+
"@vnejs/plugins.text.contract": "~0.0.1",
|
|
46
|
+
"@vnejs/shared": "~0.0.9",
|
|
47
|
+
"@vnejs/uis.react": "~0.1.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@vnejs/configs.ts-common": "~0.0.1"
|
|
51
|
+
}
|
|
17
52
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { regPlugin } from "@vnejs/shared";
|
|
2
|
+
import { PARAMS, PLUGIN_NAME, SUBSCRIBE_EVENTS } from "@vnejs/plugins.views.screens.history.contract";
|
|
3
|
+
|
|
4
|
+
import { HistoryController } from "./modules/controller.js";
|
|
5
|
+
import { History } from "./modules/history.js";
|
|
6
|
+
import { HistoryView } from "./modules/view.js";
|
|
7
|
+
|
|
8
|
+
regPlugin(PLUGIN_NAME, { events: SUBSCRIBE_EVENTS, params: PARAMS }, [HistoryController, History, HistoryView]);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ModuleController } from "@vnejs/module.components";
|
|
2
|
+
|
|
3
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
4
|
+
import type { ModuleGlobalState } from "@vnejs/module";
|
|
5
|
+
|
|
6
|
+
import type { HistoryClickPayload, HistoryEntry, HistoryModuleState, HistoryPluginState, HistoryReplacePayload } from "../utils/history.js";
|
|
7
|
+
|
|
8
|
+
export class HistoryController extends ModuleController<
|
|
9
|
+
HistoryPluginEvents,
|
|
10
|
+
HistoryPluginConstants,
|
|
11
|
+
HistoryPluginSettings,
|
|
12
|
+
HistoryPluginParams,
|
|
13
|
+
HistoryPluginState
|
|
14
|
+
> {
|
|
15
|
+
name = "history.controller";
|
|
16
|
+
|
|
17
|
+
emitHide = () => void this.emit(this.EVENTS.HISTORY.HIDE);
|
|
18
|
+
|
|
19
|
+
updateEvent = this.EVENTS.HISTORY.UPDATE;
|
|
20
|
+
controls = {
|
|
21
|
+
[this.CONST.CONTROLS.BUTTONS.BACK]: () => void this.emitHide(),
|
|
22
|
+
[this.CONST.CONTROLS.BUTTONS.MENU]: () => void this.emitHide(),
|
|
23
|
+
[this.CONST.CONTROLS.BUTTONS.GAMEMENU]: () => void this.emitHide(),
|
|
24
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_UP]: () => void this.decCurrentItem(),
|
|
25
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_BOTTOM]: () => void this.incCurrentItem(),
|
|
26
|
+
[this.CONST.CONTROLS.BUTTONS.ACCEPT]: () => void this.emit(this.EVENTS.HISTORY.ACCEPT),
|
|
27
|
+
};
|
|
28
|
+
controlsIndex = this.PARAMS.HISTORY.ZINDEX;
|
|
29
|
+
|
|
30
|
+
subscribe = () => {
|
|
31
|
+
this.on(this.EVENTS.HISTORY.SHOW, this.onShow);
|
|
32
|
+
this.on(this.EVENTS.HISTORY.HIDE, this.onHide);
|
|
33
|
+
this.on(this.EVENTS.HISTORY.ACCEPT, this.onAccept);
|
|
34
|
+
this.on(this.EVENTS.HISTORY.CLICK, this.onClick);
|
|
35
|
+
|
|
36
|
+
this.on(this.EVENTS.STATE.SET, this.onStateSet);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
beforeShow = async () => {
|
|
40
|
+
const history = (this.globalState.history as HistoryModuleState).history;
|
|
41
|
+
|
|
42
|
+
this.maxCurrentItem = history.length - 1;
|
|
43
|
+
|
|
44
|
+
this.updateState({
|
|
45
|
+
historyLocs: await Promise.all(history.map(this.getHistoryText)),
|
|
46
|
+
historyKeys: (await this.emitOne(this.EVENTS.HISTORY.KEYS)) as (string | null | undefined)[],
|
|
47
|
+
history,
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
afterHide = () => this.setDefaultState();
|
|
51
|
+
|
|
52
|
+
onAccept = () =>
|
|
53
|
+
this.currentItem !== null &&
|
|
54
|
+
void this.emit(this.EVENTS.HISTORY.CLICK, { uid: (this.globalState.history as HistoryModuleState).history[this.currentItem].uid });
|
|
55
|
+
onClick = ({ uid }: HistoryClickPayload = {}) => this.state.historyKeys?.includes(uid) && void this.emit(this.EVENTS.HISTORY.LOAD, { uid });
|
|
56
|
+
|
|
57
|
+
onStateSet = () => void this.emit(this.EVENTS.HISTORY.HIDE, { isForce: true });
|
|
58
|
+
|
|
59
|
+
getHistoryText = async ({ label, text, args, uid }: HistoryEntry) => {
|
|
60
|
+
const state = (await this.emitOne(this.EVENTS.HISTORY.GET, { uid })) as ModuleGlobalState;
|
|
61
|
+
|
|
62
|
+
return this.emitOne(this.EVENTS.TEXT.REPLACE, { label, text, args, state } satisfies HistoryReplacePayload) as Promise<string>;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "@vnejs/plugins.core.scenario.contract";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { Module, type ModuleGlobalState, type ModuleGlobalStateRegistry } from "@vnejs/module";
|
|
4
|
+
|
|
5
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
6
|
+
import type { HistoryAddPayload, HistoryGetPayload, HistoryLoadPayload, HistoryModuleState } from "../utils/history.js";
|
|
7
|
+
|
|
8
|
+
export class History extends Module<HistoryPluginEvents, HistoryPluginConstants, HistoryPluginSettings, HistoryPluginParams, HistoryModuleState> {
|
|
4
9
|
name = "history";
|
|
5
10
|
|
|
6
11
|
isLoadInProcess = false;
|
|
@@ -18,10 +23,10 @@ export class History extends Module {
|
|
|
18
23
|
|
|
19
24
|
init = () => this.emit(this.EVENTS.MEMORY.REG, { module: this.name });
|
|
20
25
|
|
|
21
|
-
onHistoryAdd = async (historyObj = {}) => {
|
|
26
|
+
onHistoryAdd = async (historyObj: HistoryAddPayload = {}) => {
|
|
22
27
|
if (this.isLoadInProcess) return;
|
|
23
28
|
|
|
24
|
-
const [state, uid] = await Promise.all([this.emitOne(this.EVENTS.STATE.GET), this.emitOne(this.EVENTS.VENDORS.UID)]);
|
|
29
|
+
const [state, uid] = (await Promise.all([this.emitOne(this.EVENTS.STATE.GET), this.emitOne(this.EVENTS.VENDORS.UID)])) as [ModuleGlobalState, string];
|
|
25
30
|
|
|
26
31
|
this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "add", uid } });
|
|
27
32
|
|
|
@@ -34,18 +39,18 @@ export class History extends Module {
|
|
|
34
39
|
|
|
35
40
|
this.updateHistoryKeys();
|
|
36
41
|
};
|
|
37
|
-
onHistoryLoad = async ({ uid } = {}) => {
|
|
42
|
+
onHistoryLoad = async ({ uid }: HistoryLoadPayload = {}) => {
|
|
38
43
|
this.isLoadInProcess = true;
|
|
39
44
|
|
|
40
45
|
this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "load start", uid } });
|
|
41
46
|
|
|
42
|
-
const state = await this.emitOne(this.EVENTS.HISTORY.GET, { uid });
|
|
47
|
+
const state = (await this.emitOne(this.EVENTS.HISTORY.GET, { uid })) as ModuleGlobalState | null | undefined;
|
|
43
48
|
|
|
44
49
|
if (!state) return void this.emit(this.EVENTS.LOGS.EMIT, { module: this.name, value: { action: "load deleted", uid } });
|
|
45
50
|
|
|
46
51
|
await this.emit(this.EVENTS.STATE.LOAD, await this.emitOne(this.EVENTS.VENDORS.CLONE, state));
|
|
47
52
|
|
|
48
|
-
this.emit(this.EVENTS.SCENARIO.LABEL_GET, { label: state.scenario
|
|
53
|
+
this.emit(this.EVENTS.SCENARIO.LABEL_GET, { label: state.scenario?.label });
|
|
49
54
|
|
|
50
55
|
this.isLoadInProcess = false;
|
|
51
56
|
|
|
@@ -56,11 +61,15 @@ export class History extends Module {
|
|
|
56
61
|
onHistoryBack = () =>
|
|
57
62
|
!this.isLoadInProcess && this.state.history.length && this.emit(this.EVENTS.HISTORY.LOAD, { uid: this.state.history[this.state.history.length - 1].uid });
|
|
58
63
|
onHistoryKeys = () => this.emitOne(this.EVENTS.MEMORY.KEYS, { module: this.name });
|
|
59
|
-
onHistoryGet = ({ uid = "" } = {}) => this.emitOne(this.EVENTS.MEMORY.GET, { module: this.name, key: uid });
|
|
64
|
+
onHistoryGet = ({ uid = "" }: HistoryGetPayload = {}) => this.emitOne(this.EVENTS.MEMORY.GET, { module: this.name, key: uid });
|
|
60
65
|
|
|
61
|
-
onStateSet = async (
|
|
66
|
+
onStateSet = async (payload: ModuleGlobalStateRegistry) => {
|
|
67
|
+
const state = payload[this.name] as HistoryModuleState | undefined;
|
|
68
|
+
|
|
69
|
+
return this.setState((await this.emitOne(this.EVENTS.VENDORS.CLONE, state)) as HistoryModuleState);
|
|
70
|
+
};
|
|
62
71
|
|
|
63
|
-
updateHistoryKeys = () => Promise.all(this.state.history.map(({ uid
|
|
72
|
+
updateHistoryKeys = () => Promise.all(this.state.history.map(({ uid }) => this.emitOne(this.EVENTS.HISTORY.GET, { uid })));
|
|
64
73
|
|
|
65
|
-
getDefaultState = () => ({ history: [] });
|
|
74
|
+
getDefaultState = (): HistoryModuleState => ({ history: [] });
|
|
66
75
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ModuleView } from "@vnejs/module.components";
|
|
2
|
+
|
|
3
|
+
import { render } from "../view/index.js";
|
|
4
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
5
|
+
import type { HistoryPluginState } from "../utils/history.js";
|
|
6
|
+
|
|
7
|
+
export class HistoryView extends ModuleView<
|
|
8
|
+
HistoryPluginEvents,
|
|
9
|
+
HistoryPluginConstants,
|
|
10
|
+
HistoryPluginSettings,
|
|
11
|
+
HistoryPluginParams,
|
|
12
|
+
HistoryPluginState
|
|
13
|
+
> {
|
|
14
|
+
name = "history.view";
|
|
15
|
+
|
|
16
|
+
locLabel = this.PARAMS.HISTORY.LOC_LABEL;
|
|
17
|
+
animationTime = this.PARAMS.HISTORY.TRANSITION;
|
|
18
|
+
updateEvent = this.EVENTS.HISTORY.UPDATE;
|
|
19
|
+
|
|
20
|
+
renderFunc = render;
|
|
21
|
+
updateHandler = this.onUpdateStoreComponent;
|
|
22
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ModuleComponentsConstants, ModuleComponentsEvents, ModuleComponentsParams, ModuleComponentsSettings } from "@vnejs/module.components";
|
|
2
|
+
import type { Constants as ControlsConstants, PluginName as ControlsPluginName } from "@vnejs/plugins.controls.contract";
|
|
3
|
+
import type { PluginName as LogsPluginName, SubscribeEvents as LogsSubscribeEvents } from "@vnejs/plugins.core.logs.contract";
|
|
4
|
+
import type { PluginName as MemoryPluginName, SubscribeEvents as MemorySubscribeEvents } from "@vnejs/plugins.core.memory.contract";
|
|
5
|
+
import type { PluginName as ScenarioPluginName, SubscribeEvents as ScenarioSubscribeEvents } from "@vnejs/plugins.core.scenario.contract";
|
|
6
|
+
import type { PluginName as StatePluginName, SubscribeEvents as StateSubscribeEvents } from "@vnejs/plugins.core.state.contract";
|
|
7
|
+
import type { PluginName as VendorsPluginName, SubscribeEvents as VendorsSubscribeEvents } from "@vnejs/plugins.core.vendors.contract";
|
|
8
|
+
import type { Params as TextParams, PluginName as TextPluginName, SubscribeEvents as TextSubscribeEvents } from "@vnejs/plugins.text.contract";
|
|
9
|
+
import type { Params, PluginName, SubscribeEvents } from "@vnejs/plugins.views.screens.history.contract";
|
|
10
|
+
|
|
11
|
+
export type HistoryPluginEvents = ModuleComponentsEvents &
|
|
12
|
+
Record<PluginName, SubscribeEvents> &
|
|
13
|
+
Record<MemoryPluginName, MemorySubscribeEvents> &
|
|
14
|
+
Record<StatePluginName, StateSubscribeEvents> &
|
|
15
|
+
Record<VendorsPluginName, VendorsSubscribeEvents> &
|
|
16
|
+
Record<LogsPluginName, LogsSubscribeEvents> &
|
|
17
|
+
Record<ScenarioPluginName, ScenarioSubscribeEvents> &
|
|
18
|
+
Record<TextPluginName, TextSubscribeEvents>;
|
|
19
|
+
|
|
20
|
+
export type HistoryPluginConstants = ModuleComponentsConstants & Record<ControlsPluginName, ControlsConstants>;
|
|
21
|
+
|
|
22
|
+
export type HistoryPluginSettings = ModuleComponentsSettings;
|
|
23
|
+
|
|
24
|
+
export type HistoryPluginParams = ModuleComponentsParams & Record<PluginName, Params> & Record<TextPluginName, TextParams>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Module, ModuleGlobalState } from "@vnejs/module";
|
|
2
|
+
|
|
3
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
4
|
+
|
|
5
|
+
export type HistoryEntry = {
|
|
6
|
+
uid: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
args?: Record<string, unknown>;
|
|
10
|
+
speaker?: string;
|
|
11
|
+
meet?: number | string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type HistoryModuleState = {
|
|
15
|
+
history: HistoryEntry[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type HistoryPluginState = {
|
|
19
|
+
isShow: boolean;
|
|
20
|
+
isForce: boolean;
|
|
21
|
+
locs?: Record<string, string>;
|
|
22
|
+
history?: HistoryEntry[];
|
|
23
|
+
historyLocs?: string[];
|
|
24
|
+
historyKeys?: (string | null | undefined)[];
|
|
25
|
+
currentItem?: number | null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type HistoryViewContext = {
|
|
29
|
+
emit: Module<HistoryPluginEvents, HistoryPluginConstants, HistoryPluginSettings, HistoryPluginParams, HistoryPluginState>["emit"];
|
|
30
|
+
EVENTS: HistoryPluginEvents;
|
|
31
|
+
PARAMS: HistoryPluginParams;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type HistoryAddPayload = Partial<HistoryEntry>;
|
|
35
|
+
|
|
36
|
+
export type HistoryGetPayload = {
|
|
37
|
+
uid?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type HistoryLoadPayload = {
|
|
41
|
+
uid?: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type HistoryClickPayload = {
|
|
45
|
+
uid?: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type HistoryReplacePayload = {
|
|
49
|
+
label?: string;
|
|
50
|
+
text?: string;
|
|
51
|
+
args?: Record<string, unknown>;
|
|
52
|
+
state?: ModuleGlobalState;
|
|
53
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
import { PositionBox, Text } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
import type { HistoryViewContext } from "../../utils/history.js";
|
|
6
|
+
|
|
7
|
+
type HistoryCloseProps = HistoryViewContext & {
|
|
8
|
+
locs?: Record<string, string>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const HistoryClose = ({ locs = {}, emit, EVENTS, PARAMS }: HistoryCloseProps) => {
|
|
12
|
+
const onClick = useCallback(() => void emit(EVENTS.HISTORY.HIDE), [emit, EVENTS.HISTORY.HIDE]);
|
|
13
|
+
|
|
14
|
+
const propsText = useMemo(() => ({ ...PARAMS.HISTORY.VIEW_PROPS.close.text, text: locs.back, onClick }), [locs, PARAMS.HISTORY.VIEW_PROPS.close.text, onClick]);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<PositionBox {...PARAMS.HISTORY.VIEW_PROPS.close.position}>
|
|
18
|
+
<Text {...propsText} />
|
|
19
|
+
</PositionBox>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
import type { TextSpeakerInfo } from "@vnejs/plugins.text.contract";
|
|
4
|
+
import { PositionBox, Text, TextControls } from "@vnejs/uis.react";
|
|
5
|
+
|
|
6
|
+
import type { HistoryEntry, HistoryViewContext } from "../../utils/history.js";
|
|
7
|
+
|
|
8
|
+
type HistoryLinesProps = HistoryViewContext & {
|
|
9
|
+
isShow?: boolean;
|
|
10
|
+
history?: HistoryEntry[];
|
|
11
|
+
currentItem?: number | null;
|
|
12
|
+
historyLocs?: string[];
|
|
13
|
+
historyKeys?: (string | null | undefined)[];
|
|
14
|
+
locs?: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const scrollToBottom = (scrollbarWrapRef: React.RefObject<HTMLDivElement | null>) => {
|
|
18
|
+
if (!scrollbarWrapRef.current) return requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
19
|
+
if (scrollbarWrapRef.current.clientHeight === scrollbarWrapRef.current.scrollHeight || scrollbarWrapRef.current.scrollTop !== 0) return;
|
|
20
|
+
|
|
21
|
+
scrollbarWrapRef.current.scrollTop = 9999999;
|
|
22
|
+
requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const HistoryLines = ({
|
|
26
|
+
isShow = false,
|
|
27
|
+
history = [],
|
|
28
|
+
currentItem = null,
|
|
29
|
+
historyLocs = [],
|
|
30
|
+
historyKeys = [],
|
|
31
|
+
locs = {},
|
|
32
|
+
emit,
|
|
33
|
+
EVENTS,
|
|
34
|
+
PARAMS,
|
|
35
|
+
}: HistoryLinesProps) => {
|
|
36
|
+
const scrollbarWrapRef = useRef<HTMLDivElement | null>(null);
|
|
37
|
+
|
|
38
|
+
const onClick = useCallback(
|
|
39
|
+
(uid?: unknown) => historyKeys.includes(uid as string) && void emit(EVENTS.HISTORY.CLICK, { uid }),
|
|
40
|
+
[historyKeys, emit, EVENTS.HISTORY.CLICK],
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const mapTexts = useCallback(
|
|
44
|
+
({ text, uid, speaker, meet }: HistoryEntry, i: number) => {
|
|
45
|
+
const speakers = PARAMS.TEXT.SPEAKERS_INFO;
|
|
46
|
+
|
|
47
|
+
const { speakerColor = "white" } = (speakers[speaker || ""] || speakers.default || {}) as TextSpeakerInfo;
|
|
48
|
+
const speakerName = locs[`speaker.${speaker}.${meet}`];
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
text: (historyLocs && historyLocs[i]) || text,
|
|
52
|
+
value: uid,
|
|
53
|
+
textPrefix: speakerName ? `${speakerName}: ` : undefined,
|
|
54
|
+
colorPrefix: speakerColor,
|
|
55
|
+
weightPrefix: Text.WEIGHT.BOLD,
|
|
56
|
+
isHoverable: Boolean(historyKeys.find((key) => key === uid)),
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
[historyLocs, historyKeys, locs, PARAMS.TEXT.SPEAKERS_INFO],
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (isShow) requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
64
|
+
}, [isShow]);
|
|
65
|
+
|
|
66
|
+
const texts = useMemo(() => history.map(mapTexts), [history, mapTexts]);
|
|
67
|
+
|
|
68
|
+
const propsView = PARAMS.HISTORY.VIEW_PROPS.lines;
|
|
69
|
+
|
|
70
|
+
const propsControlsCommon = useMemo(() => ({ ...propsView.controls, onClick, scrollbarWrapRef }), [propsView.controls, onClick]);
|
|
71
|
+
const propsControls = useMemo(() => ({ ...propsControlsCommon, texts, selectedIndex: currentItem ?? undefined }), [propsControlsCommon, texts, currentItem]);
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<PositionBox {...propsView.position}>
|
|
75
|
+
<TextControls {...propsControls} />
|
|
76
|
+
</PositionBox>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ViewRenderFunc } from "@vnejs/module.components";
|
|
2
|
+
import type { ReactComponentProps } from "@vnejs/uis.react";
|
|
3
|
+
import { Screen, createRenderFunc, useMemo, useStoreState } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
import type { HistoryPluginConstants, HistoryPluginEvents, HistoryPluginParams, HistoryPluginSettings } from "../types.js";
|
|
6
|
+
import type { HistoryPluginState, HistoryViewContext } from "../utils/history.js";
|
|
7
|
+
import { HistoryClose, HistoryLines } from "./components/index.js";
|
|
8
|
+
|
|
9
|
+
type HistoryComponentProps = ReactComponentProps<
|
|
10
|
+
HistoryPluginEvents,
|
|
11
|
+
HistoryPluginConstants,
|
|
12
|
+
HistoryPluginSettings,
|
|
13
|
+
HistoryPluginParams,
|
|
14
|
+
HistoryPluginState
|
|
15
|
+
>;
|
|
16
|
+
|
|
17
|
+
const History = ({ store, onMount, PARAMS, emit, EVENTS }: HistoryComponentProps) => {
|
|
18
|
+
const {
|
|
19
|
+
isShow = false,
|
|
20
|
+
isForce = false,
|
|
21
|
+
locs = {},
|
|
22
|
+
history = [],
|
|
23
|
+
historyLocs = [],
|
|
24
|
+
historyKeys = [],
|
|
25
|
+
currentItem = null,
|
|
26
|
+
} = useStoreState<HistoryPluginState>(store, onMount);
|
|
27
|
+
|
|
28
|
+
const viewProps = useMemo<HistoryViewContext>(() => ({ emit, EVENTS, PARAMS }), [emit, EVENTS, PARAMS]);
|
|
29
|
+
const propsScreen = useMemo(() => ({ ...PARAMS.HISTORY.VIEW_PROPS.screen, isShow, isForce }), [isShow, isForce, PARAMS.HISTORY.VIEW_PROPS.screen]);
|
|
30
|
+
const propsHistory = useMemo(() => ({ history, historyLocs, historyKeys }), [history, historyLocs, historyKeys]);
|
|
31
|
+
const propsLines = useMemo(() => ({ ...viewProps, ...propsHistory, isShow, currentItem, locs }), [viewProps, propsHistory, isShow, currentItem, locs]);
|
|
32
|
+
const propsClose = useMemo(() => ({ ...viewProps, locs }), [viewProps, locs]);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Screen {...propsScreen}>
|
|
36
|
+
<HistoryLines {...propsLines} />
|
|
37
|
+
<HistoryClose {...propsClose} />
|
|
38
|
+
</Screen>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const render: ViewRenderFunc<HistoryPluginState> = createRenderFunc(History);
|
package/tsconfig.json
ADDED
package/const/events.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export const SUBSCRIBE_EVENTS = {
|
|
2
|
-
GET: "vne:history:get",
|
|
3
|
-
ADD: "vne:history:add",
|
|
4
|
-
LOAD: "vne:history:load",
|
|
5
|
-
BACK: "vne:history:back",
|
|
6
|
-
KEYS: "vne:history:keys",
|
|
7
|
-
CLEAR: "vne:history:clear",
|
|
8
|
-
|
|
9
|
-
HIDE: "vne:history:hide",
|
|
10
|
-
SHOW: "vne:history:show",
|
|
11
|
-
CLICK: "vne:history:click",
|
|
12
|
-
UPDATE: "vne:history:update",
|
|
13
|
-
ACCEPT: "vne:history:accept",
|
|
14
|
-
};
|
package/const/params.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const MAX_LENGTH = 50;
|
|
2
|
-
|
|
3
|
-
export const ZINDEX = 2000;
|
|
4
|
-
export const TRANSITION = 300;
|
|
5
|
-
export const LOC_LABEL = "history";
|
|
6
|
-
|
|
7
|
-
export const VIEW_PROPS = {
|
|
8
|
-
screen: { isDisableAutoread: true, withBlur: true, withDark: true, zIndex: ZINDEX, transition: TRANSITION },
|
|
9
|
-
lines: { position: { top: 120, left: 120, right: 120 }, controls: { wrapHeight: 1800, withScrollbar: true, flexGap: 36, textSize: 60, textMarginTop: 36 } },
|
|
10
|
-
close: { position: { bottom: 120, left: 120 }, text: { size: 60 } },
|
|
11
|
-
};
|
package/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { regPlugin } from "@vnejs/shared";
|
|
2
|
-
|
|
3
|
-
import { SUBSCRIBE_EVENTS } from "./const/events";
|
|
4
|
-
import * as params from "./const/params";
|
|
5
|
-
|
|
6
|
-
import { HistoryController } from "./modules/controller";
|
|
7
|
-
import { History } from "./modules/history";
|
|
8
|
-
import { HistoryView } from "./modules/view";
|
|
9
|
-
|
|
10
|
-
regPlugin("HISTORY", { events: SUBSCRIBE_EVENTS, params }, [HistoryController, History, HistoryView]);
|
package/modules/controller.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { ModuleController } from "@vnejs/module.components";
|
|
2
|
-
|
|
3
|
-
export class HistoryController extends ModuleController {
|
|
4
|
-
name = "history.controller";
|
|
5
|
-
|
|
6
|
-
emitHide = () => this.emit(this.EVENTS.HISTORY.HIDE);
|
|
7
|
-
|
|
8
|
-
updateEvent = this.EVENTS.HISTORY.UPDATE;
|
|
9
|
-
controls = {
|
|
10
|
-
[this.CONST.CONTROLS.BUTTONS.BACK]: this.emitHide,
|
|
11
|
-
[this.CONST.CONTROLS.BUTTONS.MENU]: this.emitHide,
|
|
12
|
-
[this.CONST.CONTROLS.BUTTONS.GAMEMENU]: this.emitHide,
|
|
13
|
-
[this.CONST.CONTROLS.BUTTONS.ARROW_UP]: this.decCurrentItem,
|
|
14
|
-
[this.CONST.CONTROLS.BUTTONS.ARROW_BOTTOM]: this.incCurrentItem,
|
|
15
|
-
[this.CONST.CONTROLS.BUTTONS.ACCEPT]: () => this.emit(this.EVENTS.HISTORY.ACCEPT),
|
|
16
|
-
};
|
|
17
|
-
controlsIndex = this.PARAMS.HISTORY.ZINDEX;
|
|
18
|
-
|
|
19
|
-
subscribe = () => {
|
|
20
|
-
this.on(this.EVENTS.HISTORY.SHOW, this.onShow);
|
|
21
|
-
this.on(this.EVENTS.HISTORY.HIDE, this.onHide);
|
|
22
|
-
this.on(this.EVENTS.HISTORY.ACCEPT, this.onAccept);
|
|
23
|
-
this.on(this.EVENTS.HISTORY.CLICK, this.onClick);
|
|
24
|
-
|
|
25
|
-
this.on(this.EVENTS.STATE.SET, this.onStateSet);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
beforeShow = async () => {
|
|
29
|
-
this.maxCurrentItem = this.globalState.history.history.length - 1;
|
|
30
|
-
|
|
31
|
-
this.updateState({
|
|
32
|
-
historyLocs: await Promise.all(this.globalState.history.history.map(this.getHistoryText)),
|
|
33
|
-
historyKeys: await this.emitOne(this.EVENTS.HISTORY.KEYS),
|
|
34
|
-
history: this.globalState.history.history,
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
|
-
afterHide = () => this.setDefaultState();
|
|
38
|
-
|
|
39
|
-
onAccept = () => this.currentItem !== null && this.emit(this.EVENTS.HISTORY.CLICK, { uid: this.globalState.history.history[this.currentItem].uid });
|
|
40
|
-
onClick = ({ uid } = {}) => this.state.historyKeys.includes(uid) && this.emit(this.EVENTS.HISTORY.LOAD, { uid });
|
|
41
|
-
|
|
42
|
-
onStateSet = () => this.emit(this.EVENTS.HISTORY.HIDE, { isForce: true });
|
|
43
|
-
|
|
44
|
-
getHistoryText = async ({ label, text, args, uid } = {}) => {
|
|
45
|
-
const state = await this.emitOne(this.EVENTS.HISTORY.GET, { uid });
|
|
46
|
-
|
|
47
|
-
return this.emitOne(this.EVENTS.TEXT.REPLACE, { label, text, args, state });
|
|
48
|
-
};
|
|
49
|
-
}
|
package/modules/view.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { ModuleView } from "@vnejs/module.components";
|
|
2
|
-
|
|
3
|
-
import { render } from "../view";
|
|
4
|
-
|
|
5
|
-
export class HistoryView extends ModuleView {
|
|
6
|
-
name = "history.view";
|
|
7
|
-
|
|
8
|
-
locLabel = this.PARAMS.HISTORY.LOC_LABEL;
|
|
9
|
-
animationTime = this.PARAMS.HISTORY.TRANSITION;
|
|
10
|
-
updateEvent = this.EVENTS.HISTORY.UPDATE;
|
|
11
|
-
|
|
12
|
-
renderFunc = render;
|
|
13
|
-
updateHandler = this.onUpdateStoreComponent;
|
|
14
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { useCallback, useMemo } from "react";
|
|
2
|
-
|
|
3
|
-
import { PositionBox, Text } from "@vnejs/uis.react";
|
|
4
|
-
|
|
5
|
-
export const HistoryClose = ({ locs = {}, ...props } = {}) => {
|
|
6
|
-
const onClick = useCallback(() => props.emit(props.EVENTS.HISTORY.HIDE), []);
|
|
7
|
-
|
|
8
|
-
const propsText = useMemo(() => ({ ...props.PARAMS.HISTORY.VIEW_PROPS.close.text, text: locs.back, onClick }), [locs]);
|
|
9
|
-
|
|
10
|
-
return (
|
|
11
|
-
<PositionBox {...props.PARAMS.HISTORY.VIEW_PROPS.close.position}>
|
|
12
|
-
<Text {...propsText} />
|
|
13
|
-
</PositionBox>
|
|
14
|
-
);
|
|
15
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
2
|
-
|
|
3
|
-
import { PositionBox, Text, TextControls } from "@vnejs/uis.react";
|
|
4
|
-
|
|
5
|
-
const scrollToBottom = (scrollbarWrapRef) => {
|
|
6
|
-
if (!scrollbarWrapRef.current) return requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
7
|
-
if (scrollbarWrapRef.current.clientHeight === scrollbarWrapRef.current.scrollHeight || scrollbarWrapRef.current.scrollTop !== 0) return;
|
|
8
|
-
|
|
9
|
-
scrollbarWrapRef.current.scrollTop = 9999999;
|
|
10
|
-
requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const HistoryLines = ({ isShow = false, history = [], currentItem = null, historyLocs = [], historyKeys = [], locs = {}, ...props } = {}) => {
|
|
14
|
-
const scrollbarWrapRef = useRef(null);
|
|
15
|
-
|
|
16
|
-
const onClick = useCallback((uid) => historyKeys.includes(uid) && props.emit(props.EVENTS.HISTORY.CLICK, { uid }), [historyKeys]);
|
|
17
|
-
|
|
18
|
-
const mapTexts = useCallback(
|
|
19
|
-
({ text, uid, speaker, meet }, i) => {
|
|
20
|
-
const speakers = props.PARAMS.TEXT.SPEAKERS_INFO;
|
|
21
|
-
|
|
22
|
-
const { speakerColor = "white" } = speakers[speaker] || speakers.default;
|
|
23
|
-
const speakerName = locs[`speaker.${speaker}.${meet}`];
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
text: (historyLocs && historyLocs[i]) || text,
|
|
27
|
-
value: uid,
|
|
28
|
-
textPrefix: speakerName ? `${speakerName}: ` : undefined,
|
|
29
|
-
colorPrefix: speakerColor,
|
|
30
|
-
weightPrefix: Text.WEIGHT.BOLD,
|
|
31
|
-
isHoverable: Boolean(historyKeys.find((key) => key === uid)),
|
|
32
|
-
};
|
|
33
|
-
},
|
|
34
|
-
[historyLocs, historyKeys],
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (isShow) requestAnimationFrame(() => scrollToBottom(scrollbarWrapRef));
|
|
39
|
-
}, [isShow]);
|
|
40
|
-
|
|
41
|
-
const texts = useMemo(() => history.map(mapTexts), [history, mapTexts]);
|
|
42
|
-
|
|
43
|
-
const propsView = props.PARAMS.HISTORY.VIEW_PROPS.lines;
|
|
44
|
-
|
|
45
|
-
const propsControlsCommon = useMemo(() => ({ ...propsView.controls, onClick, scrollbarWrapRef }), [scrollbarWrapRef]);
|
|
46
|
-
const propsControls = useMemo(() => ({ ...propsControlsCommon, texts, selectedIndex: currentItem }), [texts, currentItem]);
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<PositionBox {...propsView.position}>
|
|
50
|
-
<TextControls {...propsControls} />
|
|
51
|
-
</PositionBox>
|
|
52
|
-
);
|
|
53
|
-
};
|
package/view/components/index.js
DELETED
package/view/index.jsx
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { useEffect, useMemo, useState } from "react";
|
|
2
|
-
import { createRoot } from "react-dom/client";
|
|
3
|
-
|
|
4
|
-
import { Screen } from "@vnejs/uis.react";
|
|
5
|
-
|
|
6
|
-
import { HistoryClose, HistoryLines } from "./components";
|
|
7
|
-
|
|
8
|
-
const History = ({ store, onMount, ...props } = {}) => {
|
|
9
|
-
const [{ isShow = false, isForce = false, locs = {}, history = [], historyLocs = [], historyKeys = [], currentItem = null }, setState] = useState({});
|
|
10
|
-
|
|
11
|
-
useEffect(() => store.subscribe(setState), []);
|
|
12
|
-
useEffect(() => void onMount(), []);
|
|
13
|
-
|
|
14
|
-
const propsScreen = useMemo(() => ({ ...props.PARAMS.HISTORY.VIEW_PROPS.screen, isShow, isForce }), [isShow, isForce]);
|
|
15
|
-
const propsHistory = useMemo(() => ({ history, historyLocs, historyKeys }), [history, historyLocs, historyKeys]);
|
|
16
|
-
const propsLines = useMemo(() => ({ ...props, ...propsHistory, isShow, currentItem, locs }), [propsHistory, isShow, currentItem, locs]);
|
|
17
|
-
const propsClose = useMemo(() => ({ ...props, locs }), [locs]);
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<Screen {...propsScreen}>
|
|
21
|
-
<HistoryLines {...propsLines} />
|
|
22
|
-
<HistoryClose {...propsClose} />
|
|
23
|
-
</Screen>
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const render = (props, root) => createRoot(root).render(<History {...props} />);
|