@netless/window-manager 1.0.0-canary.2 → 1.0.0-canary.20
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/__mocks__/white-web-sdk.ts +10 -1
- package/dist/App/AppContext.d.ts +6 -6
- package/dist/App/AppProxy.d.ts +30 -5
- package/dist/App/{WhiteBoardView.d.ts → WhiteboardView.d.ts} +10 -1
- package/dist/App/index.d.ts +1 -1
- package/dist/AppManager.d.ts +5 -5
- package/dist/AttributesDelegate.d.ts +11 -16
- package/dist/BoxManager.d.ts +3 -3
- package/dist/InternalEmitter.d.ts +2 -0
- package/dist/Page/PageController.d.ts +1 -0
- package/dist/ReconnectRefresher.d.ts +1 -1
- package/dist/Utils/Common.d.ts +1 -0
- package/dist/Utils/Reactive.d.ts +2 -0
- package/dist/View/CameraSynchronizer.d.ts +9 -9
- package/dist/View/MainView.d.ts +18 -7
- package/dist/View/ViewSync.d.ts +24 -0
- package/dist/constants.d.ts +6 -1
- package/dist/index.cjs.js +12 -12
- package/dist/index.d.ts +19 -2
- package/dist/index.es.js +791 -380
- package/dist/index.umd.js +12 -12
- package/dist/style.css +1 -1
- package/docs/app-context.md +98 -64
- package/docs/develop-app.md +2 -5
- package/docs/mirgrate-to-1.0.md +28 -0
- package/package.json +3 -3
- package/pnpm-lock.yaml +9 -9
- package/src/App/AppContext.ts +30 -19
- package/src/App/AppProxy.ts +251 -39
- package/src/App/{WhiteBoardView.ts → WhiteboardView.ts} +38 -4
- package/src/App/index.ts +1 -1
- package/src/AppManager.ts +33 -30
- package/src/AttributesDelegate.ts +18 -18
- package/src/BoxManager.ts +20 -15
- package/src/InternalEmitter.ts +2 -0
- package/src/Page/PageController.ts +1 -0
- package/src/PageState.ts +1 -1
- package/src/ReconnectRefresher.ts +2 -1
- package/src/Utils/Common.ts +6 -0
- package/src/Utils/Reactive.ts +43 -26
- package/src/Utils/RoomHacker.ts +3 -0
- package/src/View/CameraSynchronizer.ts +43 -30
- package/src/View/MainView.ts +106 -81
- package/src/View/ViewSync.ts +116 -0
- package/src/constants.ts +5 -0
- package/src/index.ts +59 -15
- package/src/style.css +8 -0
package/src/AppManager.ts
CHANGED
@@ -3,7 +3,7 @@ import { AppCreateQueue } from "./Utils/AppCreateQueue";
|
|
3
3
|
import { AppListeners } from "./AppListener";
|
4
4
|
import { AppProxy } from "./App";
|
5
5
|
import { appRegister } from "./Register";
|
6
|
-
import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
|
6
|
+
import { autorun, isPlayer, isRoom, ScenePathType, toJS } from "white-web-sdk";
|
7
7
|
import { boxEmitter } from "./BoxEmitter";
|
8
8
|
import { calculateNextIndex } from "./Page";
|
9
9
|
import { callbacks } from "./callback";
|
@@ -18,6 +18,7 @@ import { RedoUndo } from "./RedoUndo";
|
|
18
18
|
import { serializeRoomMembers } from "./Helper";
|
19
19
|
import { SideEffectManager } from "side-effect-manager";
|
20
20
|
import { ViewManager } from "./View/ViewManager";
|
21
|
+
import { Val } from "value-enhancer";
|
21
22
|
import type { SyncRegisterAppPayload } from "./Register";
|
22
23
|
import type { RemoveSceneParams } from "./InternalEmitter";
|
23
24
|
import {
|
@@ -34,10 +35,10 @@ import type { ReconnectRefresher } from "./ReconnectRefresher";
|
|
34
35
|
import type { BoxManager } from "./BoxManager";
|
35
36
|
import type {
|
36
37
|
Displayer,
|
37
|
-
DisplayerState,
|
38
38
|
Room,
|
39
39
|
ScenesCallbacksNode,
|
40
40
|
SceneState,
|
41
|
+
RoomState,
|
41
42
|
} from "white-web-sdk";
|
42
43
|
import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
|
43
44
|
import type {
|
@@ -56,17 +57,17 @@ export class AppManager {
|
|
56
57
|
public appStatus: Map<string, AppStatus> = new Map();
|
57
58
|
public store = store;
|
58
59
|
public mainViewProxy: MainViewProxy;
|
59
|
-
public refresher
|
60
|
+
public refresher: ReconnectRefresher;
|
60
61
|
public isReplay = this.windowManger.isReplay;
|
61
62
|
public mainViewScenesLength = 0;
|
62
63
|
|
63
64
|
private appListeners: AppListeners;
|
64
65
|
public boxManager?: BoxManager;
|
65
66
|
|
66
|
-
private _prevSceneIndex: number | undefined;
|
67
|
-
private _prevFocused: string | undefined;
|
68
67
|
private callbacksNode: ScenesCallbacksNode | null = null;
|
69
68
|
private appCreateQueue = new AppCreateQueue();
|
69
|
+
private sceneIndex$ = new Val<number | undefined>(undefined);
|
70
|
+
private focused$ = new Val<string | undefined>(undefined);
|
70
71
|
|
71
72
|
private sideEffectManager = new SideEffectManager();
|
72
73
|
|
@@ -137,7 +138,7 @@ export class AppManager {
|
|
137
138
|
sceneName = this.callbacksNode?.scenes[nextIndex];
|
138
139
|
}
|
139
140
|
if (sceneName) {
|
140
|
-
this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
|
141
|
+
await this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
|
141
142
|
}
|
142
143
|
await this.setMainViewSceneIndex(nextIndex);
|
143
144
|
} else {
|
@@ -152,7 +153,7 @@ export class AppManager {
|
|
152
153
|
* 所以需要关掉所有开启了 view 的 app
|
153
154
|
*/
|
154
155
|
public async onRootDirRemoved(needClose = true) {
|
155
|
-
this.setMainViewScenePath(INIT_DIR);
|
156
|
+
await this.setMainViewScenePath(INIT_DIR);
|
156
157
|
this.createRootDirScenesCallback();
|
157
158
|
|
158
159
|
for (const [id, appProxy] of this.appProxies.entries()) {
|
@@ -160,9 +161,9 @@ export class AppManager {
|
|
160
161
|
await this.closeApp(id, needClose);
|
161
162
|
}
|
162
163
|
}
|
163
|
-
// 删除了根目录的 scenes 之后
|
164
|
+
// 删除了根目录的 scenes 之后 main-view 需要重新绑定, 否则主白板会不能渲染
|
164
165
|
this.mainViewProxy.rebind();
|
165
|
-
emitter.emit("rootDirRemoved");
|
166
|
+
await emitter.emit("rootDirRemoved");
|
166
167
|
this.updateRootDirRemoving(false);
|
167
168
|
}
|
168
169
|
|
@@ -324,31 +325,31 @@ export class AppManager {
|
|
324
325
|
|
325
326
|
this.addAppsChangeListener();
|
326
327
|
this.addAppCloseListener();
|
327
|
-
this.refresher
|
328
|
+
this.refresher.add("maximized", () => {
|
328
329
|
return autorun(() => {
|
329
330
|
const maximized = this.attributes.maximized;
|
330
331
|
this.boxManager?.setMaximized(Boolean(maximized));
|
331
332
|
});
|
332
333
|
});
|
333
|
-
this.refresher
|
334
|
+
this.refresher.add("minimized", () => {
|
334
335
|
return autorun(() => {
|
335
336
|
const minimized = this.attributes.minimized;
|
336
337
|
this.onMinimized(minimized);
|
337
338
|
});
|
338
339
|
});
|
339
|
-
this.refresher
|
340
|
+
this.refresher.add("mainViewIndex", () => {
|
340
341
|
return autorun(() => {
|
341
342
|
const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
|
342
343
|
this.onMainViewIndexChange(mainSceneIndex);
|
343
344
|
});
|
344
345
|
});
|
345
|
-
this.refresher
|
346
|
+
this.refresher.add("focusedChange", () => {
|
346
347
|
return autorun(() => {
|
347
348
|
const focused = get(this.attributes, "focus");
|
348
349
|
this.onFocusChange(focused);
|
349
350
|
});
|
350
351
|
});
|
351
|
-
this.refresher
|
352
|
+
this.refresher.add("registeredChange", () => {
|
352
353
|
return autorun(() => {
|
353
354
|
const registered = get(this.attributes, Fields.Registered);
|
354
355
|
this.onRegisteredChange(registered);
|
@@ -361,7 +362,7 @@ export class AppManager {
|
|
361
362
|
}
|
362
363
|
this.displayerWritableListener(!this.room?.isWritable);
|
363
364
|
this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
|
364
|
-
this.
|
365
|
+
this.focused$.setValue(this.attributes.focus);
|
365
366
|
|
366
367
|
this.sideEffectManager.add(() => {
|
367
368
|
const redoUndo = new RedoUndo({
|
@@ -426,27 +427,28 @@ export class AppManager {
|
|
426
427
|
};
|
427
428
|
|
428
429
|
private onMainViewIndexChange = (index: number) => {
|
429
|
-
if (index !== undefined && this.
|
430
|
+
if (index !== undefined && this.sceneIndex$.value !== index) {
|
430
431
|
callbacks.emit("mainViewSceneIndexChange", index);
|
431
432
|
emitter.emit("changePageState");
|
432
433
|
if (this.callbacksNode) {
|
433
434
|
this.updateSceneState(this.callbacksNode);
|
434
435
|
}
|
435
|
-
this.
|
436
|
+
this.sceneIndex$.setValue(index);
|
436
437
|
}
|
437
438
|
};
|
438
439
|
|
439
440
|
private onFocusChange = (focused: string | undefined) => {
|
440
|
-
if (this.
|
441
|
+
if (this.focused$.value !== focused) {
|
441
442
|
callbacks.emit("focusedChange", focused);
|
442
|
-
emitter.emit("focusedChange", { focused, prev: this.
|
443
|
-
this.
|
443
|
+
emitter.emit("focusedChange", { focused, prev: this.focused$.value });
|
444
|
+
this.focused$.setValue(focused);
|
444
445
|
if (focused !== undefined) {
|
445
446
|
this.boxManager?.focusBox({ appId: focused });
|
446
447
|
// 确保 focus 修改的时候, appProxy 已经创建
|
447
448
|
setTimeout(() => {
|
448
449
|
const appProxy = this.appProxies.get(focused);
|
449
450
|
if (appProxy) {
|
451
|
+
appProxy.onFocus();
|
450
452
|
appRegister.notifyApp(appProxy.kind, "focus", { appId: focused });
|
451
453
|
}
|
452
454
|
}, 0);
|
@@ -460,9 +462,9 @@ export class AppManager {
|
|
460
462
|
);
|
461
463
|
|
462
464
|
/**
|
463
|
-
* 插件更新
|
465
|
+
* 插件更新 apps 时的回调
|
464
466
|
*
|
465
|
-
* @param {*}
|
467
|
+
* @param {*} apps
|
466
468
|
* @memberof WindowManager
|
467
469
|
*/
|
468
470
|
public async _attributesUpdateCallback(apps: any) {
|
@@ -536,6 +538,7 @@ export class AppManager {
|
|
536
538
|
|
537
539
|
public setBoxManager(boxManager: BoxManager) {
|
538
540
|
this.boxManager = boxManager;
|
541
|
+
this.mainViewProxy.createViewSync();
|
539
542
|
}
|
540
543
|
|
541
544
|
public resetMaximized() {
|
@@ -651,7 +654,7 @@ export class AppManager {
|
|
651
654
|
}
|
652
655
|
}
|
653
656
|
|
654
|
-
private displayerStateListener = (state: Partial<
|
657
|
+
private displayerStateListener = (state: Partial<RoomState>) => {
|
655
658
|
const sceneState = state.sceneState;
|
656
659
|
if (sceneState) {
|
657
660
|
const scenePath = sceneState.scenePath;
|
@@ -669,12 +672,15 @@ export class AppManager {
|
|
669
672
|
emitter.emit("roomMembersChange", this.members);
|
670
673
|
}
|
671
674
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
675
|
+
if (state.memberState) {
|
676
|
+
emitter.emit("memberStateChange", toJS(state.memberState));
|
677
|
+
}
|
672
678
|
};
|
673
679
|
|
674
680
|
public displayerWritableListener = (isReadonly: boolean) => {
|
675
681
|
const isWritable = !isReadonly;
|
676
682
|
const isManualWritable =
|
677
|
-
this.windowManger.readonly === undefined || this.windowManger.readonly
|
683
|
+
this.windowManger.readonly === undefined || !this.windowManger.readonly;
|
678
684
|
if (this.windowManger.readonly === undefined) {
|
679
685
|
this.boxManager?.setReadonly(isReadonly);
|
680
686
|
} else {
|
@@ -683,13 +689,10 @@ export class AppManager {
|
|
683
689
|
this.appProxies.forEach(appProxy => {
|
684
690
|
appProxy.emitAppIsWritableChange();
|
685
691
|
});
|
686
|
-
if (isWritable
|
687
|
-
this.mainView.disableCameraTransform = false;
|
692
|
+
if (isWritable) {
|
688
693
|
if (this.room && this.room.disableSerialization === true) {
|
689
694
|
this.room.disableSerialization = false;
|
690
695
|
}
|
691
|
-
} else {
|
692
|
-
this.mainView.disableCameraTransform = true;
|
693
696
|
}
|
694
697
|
emitter.emit("writableChange", isWritable);
|
695
698
|
};
|
@@ -831,7 +834,7 @@ export class AppManager {
|
|
831
834
|
}
|
832
835
|
callbacks.clearListeners();
|
833
836
|
this.sideEffectManager.flushAll();
|
834
|
-
this.
|
835
|
-
this.
|
837
|
+
this.sceneIndex$.destroy();
|
838
|
+
this.focused$.destroy();
|
836
839
|
}
|
837
840
|
}
|
@@ -2,7 +2,7 @@ import { AppAttributes } from "./constants";
|
|
2
2
|
import { get, pick } from "lodash";
|
3
3
|
import { setViewFocusScenePath } from "./Utils/Common";
|
4
4
|
import type { AddAppParams, AppSyncAttributes } from "./index";
|
5
|
-
import type {
|
5
|
+
import type { Size, View } from "white-web-sdk";
|
6
6
|
import type { Cursor } from "./Cursor/Cursor";
|
7
7
|
|
8
8
|
export enum Fields {
|
@@ -18,6 +18,8 @@ export enum Fields {
|
|
18
18
|
CursorState = "cursorState",
|
19
19
|
FullPath = "fullPath",
|
20
20
|
Registered = "registered",
|
21
|
+
Camera = "camera",
|
22
|
+
Size = "size",
|
21
23
|
}
|
22
24
|
|
23
25
|
export type Apps = {
|
@@ -39,9 +41,16 @@ export type StoreContext = {
|
|
39
41
|
safeSetAttributes: (attributes: any) => void;
|
40
42
|
}
|
41
43
|
|
42
|
-
export type ICamera =
|
44
|
+
export type ICamera = & {
|
45
|
+
id: string; // room uid
|
46
|
+
centerX: number | null,
|
47
|
+
centerY: number | null,
|
48
|
+
scale: number
|
49
|
+
};
|
43
50
|
|
44
|
-
export type ISize = Size & {
|
51
|
+
export type ISize = Size & {
|
52
|
+
id: string; // room uid
|
53
|
+
};
|
45
54
|
|
46
55
|
export class AttributesDelegate {
|
47
56
|
|
@@ -108,6 +117,10 @@ export class AttributesDelegate {
|
|
108
117
|
}
|
109
118
|
}
|
110
119
|
|
120
|
+
public updateAppAttributes(appId: string, key: string, value: any) {
|
121
|
+
this.context.safeUpdateAttributes([Fields.Apps, appId, key], value);
|
122
|
+
}
|
123
|
+
|
111
124
|
public cleanAppAttributes(id: string) {
|
112
125
|
this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
|
113
126
|
this.context.safeSetAttributes({ [id]: undefined });
|
@@ -149,11 +162,11 @@ export class AttributesDelegate {
|
|
149
162
|
this.context.safeSetAttributes({ _mainSceneIndex: index });
|
150
163
|
}
|
151
164
|
|
152
|
-
public getMainViewCamera():
|
165
|
+
public getMainViewCamera(): ICamera {
|
153
166
|
return get(this.attributes, [Fields.MainViewCamera]);
|
154
167
|
}
|
155
168
|
|
156
|
-
public getMainViewSize():
|
169
|
+
public getMainViewSize(): ISize {
|
157
170
|
return get(this.attributes, [Fields.MainViewSize]);
|
158
171
|
}
|
159
172
|
|
@@ -214,19 +227,6 @@ export class AttributesDelegate {
|
|
214
227
|
}
|
215
228
|
}
|
216
229
|
|
217
|
-
export type MainViewSize = {
|
218
|
-
id: string;
|
219
|
-
width: number;
|
220
|
-
height: number;
|
221
|
-
};
|
222
|
-
|
223
|
-
export type MainViewCamera = {
|
224
|
-
id: string;
|
225
|
-
centerX: number;
|
226
|
-
centerY: number;
|
227
|
-
scale: number;
|
228
|
-
};
|
229
|
-
|
230
230
|
export type Cursors = {
|
231
231
|
[key: string]: Cursor;
|
232
232
|
};
|
package/src/BoxManager.ts
CHANGED
@@ -47,11 +47,11 @@ export type CreateTeleBoxManagerConfig = {
|
|
47
47
|
collectorStyles?: Partial<CSSStyleDeclaration>;
|
48
48
|
prefersColorScheme?: TeleBoxColorScheme;
|
49
49
|
stageRatio?: number;
|
50
|
+
highlightStage?: boolean;
|
50
51
|
};
|
51
52
|
|
52
53
|
export type BoxManagerContext = {
|
53
54
|
safeSetAttributes: (attributes: any) => void;
|
54
|
-
getMainView: () => View;
|
55
55
|
updateAppState: (appId: string, field: AppAttributes, value: any) => void;
|
56
56
|
emitter: EmitterType;
|
57
57
|
boxEmitter: BoxEmitterType;
|
@@ -72,7 +72,6 @@ export const createBoxManager = (
|
|
72
72
|
return new BoxManager(
|
73
73
|
{
|
74
74
|
safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
|
75
|
-
getMainView: () => manager.mainView,
|
76
75
|
updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
|
77
76
|
canOperate: () => manager.canOperate,
|
78
77
|
notifyContainerRectUpdate: (rect: TeleBoxRect) =>
|
@@ -81,7 +80,7 @@ export const createBoxManager = (
|
|
81
80
|
setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
|
82
81
|
callbacks,
|
83
82
|
emitter,
|
84
|
-
boxEmitter
|
83
|
+
boxEmitter,
|
85
84
|
},
|
86
85
|
options
|
87
86
|
);
|
@@ -100,17 +99,17 @@ export class BoxManager {
|
|
100
99
|
this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
|
101
100
|
this.sideEffectManager.add(() => [
|
102
101
|
// 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
|
103
|
-
this.teleBoxManager.
|
102
|
+
this.teleBoxManager.onValChanged("state", state => {
|
104
103
|
callbacks.emit("boxStateChange", state);
|
105
104
|
emitter.emit("boxStateChange", state);
|
106
105
|
}),
|
107
|
-
this.teleBoxManager.
|
106
|
+
this.teleBoxManager.onValChanged("darkMode", darkMode => {
|
108
107
|
callbacks.emit("darkModeChange", darkMode);
|
109
108
|
}),
|
110
|
-
this.teleBoxManager.
|
109
|
+
this.teleBoxManager.onValChanged("prefersColorScheme", colorScheme => {
|
111
110
|
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
112
111
|
}),
|
113
|
-
this.teleBoxManager.
|
112
|
+
this.teleBoxManager.onValChanged("minimized", (minimized, skipUpdate) => {
|
114
113
|
if (skipUpdate) {
|
115
114
|
return;
|
116
115
|
}
|
@@ -126,7 +125,7 @@ export class BoxManager {
|
|
126
125
|
}
|
127
126
|
}
|
128
127
|
}),
|
129
|
-
this.teleBoxManager.
|
128
|
+
this.teleBoxManager.onValChanged("maximized", (maximized, skipUpdate) => {
|
130
129
|
if (skipUpdate) {
|
131
130
|
return;
|
132
131
|
}
|
@@ -140,7 +139,11 @@ export class BoxManager {
|
|
140
139
|
this.teleBoxManager.events.on(
|
141
140
|
"intrinsic_move",
|
142
141
|
debounce((box: ReadonlyTeleBox): void => {
|
143
|
-
boxEmitter.emit("move", {
|
142
|
+
boxEmitter.emit("move", {
|
143
|
+
appId: box.id,
|
144
|
+
x: box.intrinsicX,
|
145
|
+
y: box.intrinsicY,
|
146
|
+
});
|
144
147
|
}, 50)
|
145
148
|
),
|
146
149
|
this.teleBoxManager.events.on(
|
@@ -178,10 +181,6 @@ export class BoxManager {
|
|
178
181
|
]);
|
179
182
|
}
|
180
183
|
|
181
|
-
private get mainView() {
|
182
|
-
return this.context.getMainView();
|
183
|
-
}
|
184
|
-
|
185
184
|
private get canOperate() {
|
186
185
|
return this.context.canOperate();
|
187
186
|
}
|
@@ -214,7 +213,11 @@ export class BoxManager {
|
|
214
213
|
return this.teleBoxManager.stageRect;
|
215
214
|
}
|
216
215
|
|
217
|
-
public
|
216
|
+
public get stageRect$() {
|
217
|
+
return this.teleBoxManager._stageRect$;
|
218
|
+
}
|
219
|
+
|
220
|
+
public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
|
218
221
|
if (!this.teleBoxManager) return;
|
219
222
|
let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
|
220
223
|
const { width, height } = params.app.config ?? {};
|
@@ -237,8 +240,9 @@ export class BoxManager {
|
|
237
240
|
height,
|
238
241
|
id: params.appId,
|
239
242
|
};
|
240
|
-
this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
243
|
+
const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
241
244
|
this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
|
245
|
+
return box;
|
242
246
|
}
|
243
247
|
|
244
248
|
public setupBoxManager(
|
@@ -250,6 +254,7 @@ export class BoxManager {
|
|
250
254
|
root: root,
|
251
255
|
fence: false,
|
252
256
|
prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
|
257
|
+
highlightStage: createTeleBoxManagerConfig?.highlightStage,
|
253
258
|
};
|
254
259
|
|
255
260
|
const manager = new TeleBoxManager(initManagerState);
|
package/src/InternalEmitter.ts
CHANGED
@@ -2,6 +2,7 @@ import Emittery from "emittery";
|
|
2
2
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
3
3
|
import type { AppInitState, CursorMovePayload } from "./index";
|
4
4
|
import type { Member } from "./Helper";
|
5
|
+
import type { MemberState } from "white-web-sdk";
|
5
6
|
|
6
7
|
export type RemoveSceneParams = {
|
7
8
|
scenePath: string;
|
@@ -31,6 +32,7 @@ export type EmitterEvent = {
|
|
31
32
|
writableChange: boolean;
|
32
33
|
containerSizeRatioUpdate: number;
|
33
34
|
roomMembersChange: Member[];
|
35
|
+
memberStateChange: MemberState;
|
34
36
|
};
|
35
37
|
|
36
38
|
export type EmitterType = Emittery<EmitterEvent>;
|
@@ -13,6 +13,7 @@ export type PageState = {
|
|
13
13
|
export interface PageController {
|
14
14
|
nextPage: () => Promise<boolean>;
|
15
15
|
prevPage: () => Promise<boolean>;
|
16
|
+
jumpPage: (index: number) => Promise<boolean>;
|
16
17
|
addPage: (params?: AddPageParams) => Promise<void>;
|
17
18
|
removePage: (index: number) => Promise<boolean>;
|
18
19
|
pageState: PageState;
|
package/src/PageState.ts
CHANGED
@@ -6,7 +6,7 @@ import type { PageState } from "./Page";
|
|
6
6
|
export class PageStateImpl {
|
7
7
|
constructor(private manager: AppManager) {
|
8
8
|
emitter.on("changePageState", () => {
|
9
|
-
|
9
|
+
callbacks.emit("pageStateChange", this.toObject());
|
10
10
|
});
|
11
11
|
}
|
12
12
|
|
@@ -53,7 +53,7 @@ export class ReconnectRefresher {
|
|
53
53
|
|
54
54
|
private onReconnected = debounce(() => {
|
55
55
|
this._onReconnected();
|
56
|
-
},
|
56
|
+
}, 1000);
|
57
57
|
|
58
58
|
private _onReconnected = () => {
|
59
59
|
log("onReconnected refresh reactors");
|
@@ -88,6 +88,7 @@ export class ReconnectRefresher {
|
|
88
88
|
this.reactors.set(id, func);
|
89
89
|
this.disposers.set(id, func());
|
90
90
|
}
|
91
|
+
return () => this.remove(id);
|
91
92
|
}
|
92
93
|
|
93
94
|
public remove(id: string) {
|
package/src/Utils/Common.ts
CHANGED
@@ -30,6 +30,12 @@ export const setViewSceneIndex = (view: View, index: number) => {
|
|
30
30
|
}
|
31
31
|
};
|
32
32
|
|
33
|
+
export const releaseView = (view: View) => {
|
34
|
+
if (!(view as any).didRelease) {
|
35
|
+
view.release();
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
33
39
|
export const setScenePath = (room: Room | undefined, scenePath: string) => {
|
34
40
|
if (room && room.isWritable) {
|
35
41
|
if (room.state.sceneState.scenePath !== scenePath) {
|
package/src/Utils/Reactive.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from "white-web-sdk";
|
2
|
-
import type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from "white-web-sdk";
|
3
1
|
import { isObject } from "lodash";
|
2
|
+
import { listenUpdated, reaction, unlistenUpdated, UpdateEventKind } from "white-web-sdk";
|
3
|
+
import type { AkkoObjectUpdatedProperty, AkkoObjectUpdatedListener } from "white-web-sdk";
|
4
|
+
import type { Val } from "value-enhancer";
|
4
5
|
|
5
6
|
// 兼容 13 和 14 版本 SDK
|
6
7
|
export const onObjectByEvent = (event: UpdateEventKind) => {
|
@@ -12,7 +13,7 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
12
13
|
if (kinds.includes(event)) {
|
13
14
|
func();
|
14
15
|
}
|
15
|
-
}
|
16
|
+
};
|
16
17
|
listenUpdated(object, listener);
|
17
18
|
func();
|
18
19
|
return () => unlistenUpdated(object, listener);
|
@@ -21,43 +22,59 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
21
22
|
() => object,
|
22
23
|
() => {
|
23
24
|
func();
|
24
|
-
},
|
25
|
+
},
|
26
|
+
{
|
25
27
|
fireImmediately: true,
|
26
28
|
}
|
27
|
-
)
|
29
|
+
);
|
28
30
|
}
|
29
|
-
}
|
30
|
-
}
|
31
|
+
};
|
32
|
+
};
|
31
33
|
|
32
34
|
export const safeListenPropsUpdated = <T>(
|
33
35
|
getProps: () => T,
|
34
36
|
callback: AkkoObjectUpdatedListener<T>,
|
35
37
|
onDestroyed?: (props: unknown) => void
|
36
|
-
|
38
|
+
) => {
|
37
39
|
let disposeListenUpdated: (() => void) | null = null;
|
38
40
|
const disposeReaction = reaction(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
41
|
+
getProps,
|
42
|
+
() => {
|
43
|
+
if (disposeListenUpdated) {
|
44
|
+
disposeListenUpdated();
|
45
|
+
disposeListenUpdated = null;
|
46
|
+
}
|
47
|
+
const props = getProps();
|
48
|
+
if (isObject(props)) {
|
49
|
+
disposeListenUpdated = () => unlistenUpdated(props, callback);
|
50
|
+
listenUpdated(props, callback);
|
51
|
+
} else {
|
52
|
+
onDestroyed?.(props);
|
53
|
+
}
|
54
|
+
},
|
55
|
+
{ fireImmediately: true }
|
54
56
|
);
|
55
57
|
|
56
58
|
return () => {
|
57
|
-
|
58
|
-
|
59
|
+
disposeListenUpdated?.();
|
60
|
+
disposeReaction();
|
59
61
|
};
|
60
|
-
}
|
62
|
+
};
|
61
63
|
|
62
64
|
export const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);
|
63
65
|
export const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);
|
66
|
+
|
67
|
+
export const createValSync = <T>(expr: any, Val: Val<T, boolean>, isAddApp: boolean): (() => void) => {
|
68
|
+
let skipUpdate = false;
|
69
|
+
return reaction(
|
70
|
+
expr,
|
71
|
+
val => {
|
72
|
+
if (isAddApp && !skipUpdate) {
|
73
|
+
skipUpdate = true;
|
74
|
+
} else {
|
75
|
+
Val.setValue(val as T);
|
76
|
+
}
|
77
|
+
},
|
78
|
+
{ fireImmediately: true }
|
79
|
+
);
|
80
|
+
};
|
package/src/Utils/RoomHacker.ts
CHANGED
@@ -56,6 +56,9 @@ export const replaceRoomFunction = (room: Room | Player, manager: WindowManager)
|
|
56
56
|
room.lockImages = (...args) => manager.lockImages(...args);
|
57
57
|
|
58
58
|
delegateRemoveScenes(room, manager);
|
59
|
+
if (!(room as any).dynamicPpt.slideStateAdapter.pptHandler) {
|
60
|
+
(room as any).dynamicPpt.slideStateAdapter.pptHandler = manager.createPPTHandler();
|
61
|
+
}
|
59
62
|
}
|
60
63
|
};
|
61
64
|
|