@netless/window-manager 1.0.0-canary.0 → 1.0.0-canary.11
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 +16 -15
- package/dist/App/AppPageStateImpl.d.ts +6 -2
- package/dist/App/AppProxy.d.ts +26 -4
- package/dist/App/AppViewSync.d.ts +11 -0
- package/dist/App/WhiteboardView.d.ts +24 -0
- package/dist/App/index.d.ts +1 -0
- package/dist/AppManager.d.ts +5 -3
- package/dist/AttributesDelegate.d.ts +6 -14
- package/dist/BoxManager.d.ts +4 -3
- package/dist/Helper.d.ts +12 -2
- package/dist/InternalEmitter.d.ts +4 -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/View/CameraSynchronizer.d.ts +7 -7
- package/dist/View/MainView.d.ts +0 -1
- package/dist/constants.d.ts +1 -0
- package/dist/index.cjs.js +12 -12
- package/dist/index.d.ts +6 -3
- package/dist/index.es.js +722 -652
- package/dist/index.umd.js +12 -12
- package/dist/style.css +1 -1
- package/dist/typings.d.ts +4 -0
- package/docs/app-context.md +98 -64
- package/docs/develop-app.md +2 -5
- package/package.json +3 -2
- package/pnpm-lock.yaml +11 -5
- package/src/App/AppContext.ts +71 -74
- package/src/App/AppPageStateImpl.ts +25 -6
- package/src/App/AppProxy.ts +206 -26
- package/src/App/AppViewSync.ts +73 -0
- package/src/App/Storage/index.ts +4 -4
- package/src/App/WhiteboardView.ts +89 -0
- package/src/App/index.ts +1 -0
- package/src/AppManager.ts +32 -23
- package/src/AttributesDelegate.ts +14 -17
- package/src/BoxManager.ts +14 -9
- package/src/Helper.ts +10 -1
- package/src/InternalEmitter.ts +4 -0
- package/src/Page/PageController.ts +1 -0
- package/src/ReconnectRefresher.ts +1 -0
- package/src/Utils/Common.ts +6 -0
- package/src/View/CameraSynchronizer.ts +32 -27
- package/src/View/MainView.ts +24 -41
- package/src/constants.ts +2 -0
- package/src/index.ts +20 -5
- package/src/style.css +9 -0
- package/src/typings.ts +4 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
import { CameraSynchronizer } from "../View/CameraSynchronizer";
|
2
|
+
import { SideEffectManager } from "side-effect-manager";
|
3
|
+
import type { Camera, View } from "white-web-sdk";
|
4
|
+
import type { AppProxy } from "./AppProxy";
|
5
|
+
import { isEqual } from "lodash";
|
6
|
+
import { combine } from "value-enhancer";
|
7
|
+
|
8
|
+
export class AppViewSync {
|
9
|
+
private sem = new SideEffectManager();
|
10
|
+
private synchronizer: CameraSynchronizer;
|
11
|
+
|
12
|
+
constructor(private appProxy: AppProxy) {
|
13
|
+
this.synchronizer = new CameraSynchronizer((camera: Camera) => {
|
14
|
+
this.appProxy.storeCamera({
|
15
|
+
id: this.appProxy.uid,
|
16
|
+
...camera,
|
17
|
+
});
|
18
|
+
});
|
19
|
+
this.bindView(appProxy.view);
|
20
|
+
this.sem.add(() => this.appProxy.camera$.subscribe(camera => {
|
21
|
+
const size = this.appProxy.size$.value;
|
22
|
+
if (camera && size) {
|
23
|
+
this.synchronizer.onRemoteUpdate(camera, size);
|
24
|
+
}
|
25
|
+
}));
|
26
|
+
this.sem.add(() => this.appProxy.size$.subscribe(size => {
|
27
|
+
if (size) {
|
28
|
+
this.synchronizer.onRemoteSizeUpdate(size);
|
29
|
+
}
|
30
|
+
}));
|
31
|
+
const box = this.appProxy.box;
|
32
|
+
if (box && box.contentStageRect) {
|
33
|
+
this.synchronizer.setRect(box.contentStageRect);
|
34
|
+
this.sem.add(() =>
|
35
|
+
box._contentStageRect$.subscribe(rect => {
|
36
|
+
if (rect) {
|
37
|
+
this.synchronizer.setRect(rect);
|
38
|
+
}
|
39
|
+
}),
|
40
|
+
);
|
41
|
+
}
|
42
|
+
this.sem.add(() => combine([this.appProxy.camera$, this.appProxy.size$]).subscribe(([camera, size]) => {
|
43
|
+
if (camera && size) {
|
44
|
+
this.synchronizer.onRemoteUpdate(camera, size);
|
45
|
+
}
|
46
|
+
}));
|
47
|
+
}
|
48
|
+
|
49
|
+
public bindView = (view?: View) => {
|
50
|
+
if (!view) return;
|
51
|
+
this.synchronizer.setView(view);
|
52
|
+
this.sem.add(() => {
|
53
|
+
view.callbacks.on("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
|
54
|
+
return () =>
|
55
|
+
view.callbacks.off("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
|
56
|
+
});
|
57
|
+
};
|
58
|
+
|
59
|
+
private onCameraUpdatedByDevice = (camera: Camera) => {
|
60
|
+
this.synchronizer.onLocalCameraUpdate(camera);
|
61
|
+
const stage = this.appProxy.box?.contentStageRect;
|
62
|
+
if (stage) {
|
63
|
+
const size = { width: stage.width, height: stage.height, id: this.appProxy.uid };
|
64
|
+
if (!isEqual(size, this.appProxy.size$.value)) {
|
65
|
+
this.appProxy.storeSize(size);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
};
|
69
|
+
|
70
|
+
public destroy() {
|
71
|
+
this.sem.flushAll();
|
72
|
+
}
|
73
|
+
}
|
package/src/App/Storage/index.ts
CHANGED
@@ -37,7 +37,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
37
37
|
this._state = {} as TState;
|
38
38
|
const rawState = this._getRawState(this._state);
|
39
39
|
|
40
|
-
if (this._context.
|
40
|
+
if (this._context.isWritable) {
|
41
41
|
if (this.id === null) {
|
42
42
|
if (context.isAddApp && defaultState) {
|
43
43
|
this.setState(defaultState);
|
@@ -115,7 +115,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
115
115
|
return;
|
116
116
|
}
|
117
117
|
|
118
|
-
if (!this._context.
|
118
|
+
if (!this._context.isWritable) {
|
119
119
|
console.error(new Error(`Cannot setState on Storage "${this.id}" without writable access`), state);
|
120
120
|
return;
|
121
121
|
}
|
@@ -165,7 +165,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
165
165
|
return;
|
166
166
|
}
|
167
167
|
|
168
|
-
if (!this._context.
|
168
|
+
if (!this._context.isWritable) {
|
169
169
|
console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
|
170
170
|
return;
|
171
171
|
}
|
@@ -181,7 +181,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
181
181
|
throw new Error(`Cannot delete main Storage`);
|
182
182
|
}
|
183
183
|
|
184
|
-
if (!this._context.
|
184
|
+
if (!this._context.isWritable) {
|
185
185
|
console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
|
186
186
|
return;
|
187
187
|
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
import { putScenes } from "../Utils/Common";
|
2
|
+
import { Val } from "value-enhancer";
|
3
|
+
|
4
|
+
import type { ReadonlyVal } from "value-enhancer";
|
5
|
+
import type { AddPageParams, PageController, PageState } from "../Page";
|
6
|
+
import type { AppProxy } from "./AppProxy";
|
7
|
+
import type { AppContext } from "./AppContext";
|
8
|
+
import type { Camera, View } from "white-web-sdk";
|
9
|
+
import type { TeleBoxRect } from "@netless/telebox-insider";
|
10
|
+
|
11
|
+
export class WhiteBoardView implements PageController {
|
12
|
+
public readonly pageState$: ReadonlyVal<PageState>;
|
13
|
+
|
14
|
+
constructor(
|
15
|
+
public view: View,
|
16
|
+
protected appContext: AppContext,
|
17
|
+
protected appProxy: AppProxy,
|
18
|
+
private removeViewWrapper: () => void,
|
19
|
+
public ensureSize: (size: number) => void
|
20
|
+
) {
|
21
|
+
const pageState$ = new Val<PageState>(appProxy.pageState);
|
22
|
+
this.pageState$ = pageState$;
|
23
|
+
appProxy.appEmitter.on("pageStateChange", pageState => {
|
24
|
+
pageState$.setValue(pageState);
|
25
|
+
});
|
26
|
+
}
|
27
|
+
|
28
|
+
public get pageState() {
|
29
|
+
return this.pageState$.value;
|
30
|
+
}
|
31
|
+
|
32
|
+
public moveCamera(camera: Camera) {
|
33
|
+
this.appProxy.moveCamera(camera);
|
34
|
+
}
|
35
|
+
|
36
|
+
public nextPage = async (): Promise<boolean> => {
|
37
|
+
const nextIndex = this.pageState.index + 1;
|
38
|
+
return this.jumpPage(nextIndex);
|
39
|
+
};
|
40
|
+
|
41
|
+
public prevPage = async (): Promise<boolean> => {
|
42
|
+
const nextIndex = this.pageState.index - 1;
|
43
|
+
return this.jumpPage(nextIndex);
|
44
|
+
};
|
45
|
+
|
46
|
+
public jumpPage = async (index: number): Promise<boolean> => {
|
47
|
+
if (index < 0 || index >= this.pageState.length) {
|
48
|
+
console.warn(`[WindowManager]: index ${index} out of range`);
|
49
|
+
return false;
|
50
|
+
}
|
51
|
+
this.appProxy.setSceneIndex(index);
|
52
|
+
return true;
|
53
|
+
};
|
54
|
+
|
55
|
+
public addPage = async (params?: AddPageParams) => {
|
56
|
+
const after = params?.after;
|
57
|
+
const scene = params?.scene;
|
58
|
+
const scenePath = this.appProxy.scenePath;
|
59
|
+
if (!scenePath) return;
|
60
|
+
if (after) {
|
61
|
+
const nextIndex = this.pageState.index + 1;
|
62
|
+
putScenes(this.appContext.room, scenePath, [scene || {}], nextIndex);
|
63
|
+
} else {
|
64
|
+
putScenes(this.appContext.room, scenePath, [scene || {}]);
|
65
|
+
}
|
66
|
+
};
|
67
|
+
|
68
|
+
public removePage = async (index?: number): Promise<boolean> => {
|
69
|
+
const needRemoveIndex = index === undefined ? this.pageState.index : index;
|
70
|
+
if (this.pageState.length === 1) {
|
71
|
+
console.warn(`[WindowManager]: can not remove the last page`);
|
72
|
+
return false;
|
73
|
+
}
|
74
|
+
if (needRemoveIndex < 0 || needRemoveIndex >= this.pageState.length) {
|
75
|
+
console.warn(`[WindowManager]: page index ${index} out of range`);
|
76
|
+
return false;
|
77
|
+
}
|
78
|
+
return this.appProxy.removeSceneByIndex(needRemoveIndex);
|
79
|
+
};
|
80
|
+
|
81
|
+
public setRect(rect: Omit<TeleBoxRect, "x" | "y">) {
|
82
|
+
this.appProxy.updateSize(rect.width, rect.height);
|
83
|
+
}
|
84
|
+
|
85
|
+
public destroy() {
|
86
|
+
this.pageState$.destroy();
|
87
|
+
this.removeViewWrapper();
|
88
|
+
}
|
89
|
+
}
|
package/src/App/index.ts
CHANGED
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";
|
@@ -15,8 +15,10 @@ import { MainViewProxy } from "./View/MainView";
|
|
15
15
|
import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
|
16
16
|
import { reconnectRefresher, WindowManager } from "./index";
|
17
17
|
import { RedoUndo } from "./RedoUndo";
|
18
|
+
import { serializeRoomMembers } from "./Helper";
|
18
19
|
import { SideEffectManager } from "side-effect-manager";
|
19
20
|
import { ViewManager } from "./View/ViewManager";
|
21
|
+
import { Val } from "value-enhancer";
|
20
22
|
import type { SyncRegisterAppPayload } from "./Register";
|
21
23
|
import type { RemoveSceneParams } from "./InternalEmitter";
|
22
24
|
import {
|
@@ -33,10 +35,10 @@ import type { ReconnectRefresher } from "./ReconnectRefresher";
|
|
33
35
|
import type { BoxManager } from "./BoxManager";
|
34
36
|
import type {
|
35
37
|
Displayer,
|
36
|
-
DisplayerState,
|
37
38
|
Room,
|
38
39
|
ScenesCallbacksNode,
|
39
40
|
SceneState,
|
41
|
+
RoomState,
|
40
42
|
} from "white-web-sdk";
|
41
43
|
import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
|
42
44
|
import type {
|
@@ -46,7 +48,7 @@ import type {
|
|
46
48
|
BoxResizePayload,
|
47
49
|
BoxStateChangePayload,
|
48
50
|
} from "./BoxEmitter";
|
49
|
-
|
51
|
+
import type { Member } from "./Helper";
|
50
52
|
|
51
53
|
export class AppManager {
|
52
54
|
public displayer: Displayer;
|
@@ -55,17 +57,17 @@ export class AppManager {
|
|
55
57
|
public appStatus: Map<string, AppStatus> = new Map();
|
56
58
|
public store = store;
|
57
59
|
public mainViewProxy: MainViewProxy;
|
58
|
-
public refresher
|
60
|
+
public refresher: ReconnectRefresher;
|
59
61
|
public isReplay = this.windowManger.isReplay;
|
60
62
|
public mainViewScenesLength = 0;
|
61
63
|
|
62
64
|
private appListeners: AppListeners;
|
63
65
|
public boxManager?: BoxManager;
|
64
66
|
|
65
|
-
private _prevSceneIndex: number | undefined;
|
66
|
-
private _prevFocused: string | undefined;
|
67
67
|
private callbacksNode: ScenesCallbacksNode | null = null;
|
68
68
|
private appCreateQueue = new AppCreateQueue();
|
69
|
+
private sceneIndex$ = new Val<number | undefined>(undefined);
|
70
|
+
private focused$ = new Val<string | undefined>(undefined);
|
69
71
|
|
70
72
|
private sideEffectManager = new SideEffectManager();
|
71
73
|
|
@@ -299,6 +301,10 @@ export class AppManager {
|
|
299
301
|
return this.room?.uid || "";
|
300
302
|
}
|
301
303
|
|
304
|
+
public get members(): Member[] {
|
305
|
+
return serializeRoomMembers(this.displayer.state.roomMembers);
|
306
|
+
}
|
307
|
+
|
302
308
|
public getMainViewSceneDir() {
|
303
309
|
const scenePath = this.store.getMainViewScenePath();
|
304
310
|
if (scenePath) {
|
@@ -319,31 +325,31 @@ export class AppManager {
|
|
319
325
|
|
320
326
|
this.addAppsChangeListener();
|
321
327
|
this.addAppCloseListener();
|
322
|
-
this.refresher
|
328
|
+
this.refresher.add("maximized", () => {
|
323
329
|
return autorun(() => {
|
324
330
|
const maximized = this.attributes.maximized;
|
325
331
|
this.boxManager?.setMaximized(Boolean(maximized));
|
326
332
|
});
|
327
333
|
});
|
328
|
-
this.refresher
|
334
|
+
this.refresher.add("minimized", () => {
|
329
335
|
return autorun(() => {
|
330
336
|
const minimized = this.attributes.minimized;
|
331
337
|
this.onMinimized(minimized);
|
332
338
|
});
|
333
339
|
});
|
334
|
-
this.refresher
|
340
|
+
this.refresher.add("mainViewIndex", () => {
|
335
341
|
return autorun(() => {
|
336
342
|
const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
|
337
343
|
this.onMainViewIndexChange(mainSceneIndex);
|
338
344
|
});
|
339
345
|
});
|
340
|
-
this.refresher
|
346
|
+
this.refresher.add("focusedChange", () => {
|
341
347
|
return autorun(() => {
|
342
348
|
const focused = get(this.attributes, "focus");
|
343
349
|
this.onFocusChange(focused);
|
344
350
|
});
|
345
351
|
});
|
346
|
-
this.refresher
|
352
|
+
this.refresher.add("registeredChange", () => {
|
347
353
|
return autorun(() => {
|
348
354
|
const registered = get(this.attributes, Fields.Registered);
|
349
355
|
this.onRegisteredChange(registered);
|
@@ -356,7 +362,7 @@ export class AppManager {
|
|
356
362
|
}
|
357
363
|
this.displayerWritableListener(!this.room?.isWritable);
|
358
364
|
this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
|
359
|
-
this.
|
365
|
+
this.focused$.setValue(this.attributes.focus);
|
360
366
|
|
361
367
|
this.sideEffectManager.add(() => {
|
362
368
|
const redoUndo = new RedoUndo({
|
@@ -421,21 +427,21 @@ export class AppManager {
|
|
421
427
|
};
|
422
428
|
|
423
429
|
private onMainViewIndexChange = (index: number) => {
|
424
|
-
if (index !== undefined && this.
|
430
|
+
if (index !== undefined && this.sceneIndex$.value !== index) {
|
425
431
|
callbacks.emit("mainViewSceneIndexChange", index);
|
426
432
|
emitter.emit("changePageState");
|
427
433
|
if (this.callbacksNode) {
|
428
434
|
this.updateSceneState(this.callbacksNode);
|
429
435
|
}
|
430
|
-
this.
|
436
|
+
this.sceneIndex$.setValue(index);
|
431
437
|
}
|
432
438
|
};
|
433
439
|
|
434
440
|
private onFocusChange = (focused: string | undefined) => {
|
435
|
-
if (this.
|
441
|
+
if (this.focused$.value !== focused) {
|
436
442
|
callbacks.emit("focusedChange", focused);
|
437
|
-
emitter.emit("focusedChange", { focused, prev: this.
|
438
|
-
this.
|
443
|
+
emitter.emit("focusedChange", { focused, prev: this.focused$.value });
|
444
|
+
this.focused$.setValue(focused);
|
439
445
|
if (focused !== undefined) {
|
440
446
|
this.boxManager?.focusBox({ appId: focused });
|
441
447
|
// 确保 focus 修改的时候, appProxy 已经创建
|
@@ -646,7 +652,7 @@ export class AppManager {
|
|
646
652
|
}
|
647
653
|
}
|
648
654
|
|
649
|
-
private displayerStateListener = (state: Partial<
|
655
|
+
private displayerStateListener = (state: Partial<RoomState>) => {
|
650
656
|
const sceneState = state.sceneState;
|
651
657
|
if (sceneState) {
|
652
658
|
const scenePath = sceneState.scenePath;
|
@@ -660,7 +666,13 @@ export class AppManager {
|
|
660
666
|
this.appProxies.forEach(appProxy => {
|
661
667
|
appProxy.appEmitter.emit("roomStateChange", state);
|
662
668
|
});
|
669
|
+
if (state.roomMembers) {
|
670
|
+
emitter.emit("roomMembersChange", this.members);
|
671
|
+
}
|
663
672
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
673
|
+
if (state.memberState) {
|
674
|
+
emitter.emit("memberStateChange", toJS(state.memberState));
|
675
|
+
}
|
664
676
|
};
|
665
677
|
|
666
678
|
public displayerWritableListener = (isReadonly: boolean) => {
|
@@ -676,12 +688,9 @@ export class AppManager {
|
|
676
688
|
appProxy.emitAppIsWritableChange();
|
677
689
|
});
|
678
690
|
if (isWritable === true) {
|
679
|
-
this.mainView.disableCameraTransform = false;
|
680
691
|
if (this.room && this.room.disableSerialization === true) {
|
681
692
|
this.room.disableSerialization = false;
|
682
693
|
}
|
683
|
-
} else {
|
684
|
-
this.mainView.disableCameraTransform = true;
|
685
694
|
}
|
686
695
|
emitter.emit("writableChange", isWritable);
|
687
696
|
};
|
@@ -823,7 +832,7 @@ export class AppManager {
|
|
823
832
|
}
|
824
833
|
callbacks.clearListeners();
|
825
834
|
this.sideEffectManager.flushAll();
|
826
|
-
this.
|
827
|
-
this.
|
835
|
+
this.sceneIndex$.destroy();
|
836
|
+
this.focused$.destroy();
|
828
837
|
}
|
829
838
|
}
|
@@ -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,13 @@ export type StoreContext = {
|
|
39
41
|
safeSetAttributes: (attributes: any) => void;
|
40
42
|
}
|
41
43
|
|
42
|
-
export type ICamera = Camera & {
|
44
|
+
export type ICamera = Camera & {
|
45
|
+
id: string; // room uid
|
46
|
+
};
|
43
47
|
|
44
|
-
export type ISize = Size & {
|
48
|
+
export type ISize = Size & {
|
49
|
+
id: string; // room uid
|
50
|
+
};
|
45
51
|
|
46
52
|
export class AttributesDelegate {
|
47
53
|
|
@@ -108,6 +114,10 @@ export class AttributesDelegate {
|
|
108
114
|
}
|
109
115
|
}
|
110
116
|
|
117
|
+
public updateAppAttributes(appId: string, key: string, value: any) {
|
118
|
+
this.context.safeUpdateAttributes([Fields.Apps, appId, key], value);
|
119
|
+
}
|
120
|
+
|
111
121
|
public cleanAppAttributes(id: string) {
|
112
122
|
this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
|
113
123
|
this.context.safeSetAttributes({ [id]: undefined });
|
@@ -149,11 +159,11 @@ export class AttributesDelegate {
|
|
149
159
|
this.context.safeSetAttributes({ _mainSceneIndex: index });
|
150
160
|
}
|
151
161
|
|
152
|
-
public getMainViewCamera():
|
162
|
+
public getMainViewCamera(): ICamera {
|
153
163
|
return get(this.attributes, [Fields.MainViewCamera]);
|
154
164
|
}
|
155
165
|
|
156
|
-
public getMainViewSize():
|
166
|
+
public getMainViewSize(): ISize {
|
157
167
|
return get(this.attributes, [Fields.MainViewSize]);
|
158
168
|
}
|
159
169
|
|
@@ -214,19 +224,6 @@ export class AttributesDelegate {
|
|
214
224
|
}
|
215
225
|
}
|
216
226
|
|
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
227
|
export type Cursors = {
|
231
228
|
[key: string]: Cursor;
|
232
229
|
};
|
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) =>
|
@@ -178,10 +177,6 @@ export class BoxManager {
|
|
178
177
|
]);
|
179
178
|
}
|
180
179
|
|
181
|
-
private get mainView() {
|
182
|
-
return this.context.getMainView();
|
183
|
-
}
|
184
|
-
|
185
180
|
private get canOperate() {
|
186
181
|
return this.context.canOperate();
|
187
182
|
}
|
@@ -210,7 +205,11 @@ export class BoxManager {
|
|
210
205
|
return this.teleBoxManager.boxes.length;
|
211
206
|
}
|
212
207
|
|
213
|
-
public
|
208
|
+
public get stageRect() {
|
209
|
+
return this.teleBoxManager.stageRect;
|
210
|
+
}
|
211
|
+
|
212
|
+
public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
|
214
213
|
if (!this.teleBoxManager) return;
|
215
214
|
let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
|
216
215
|
const { width, height } = params.app.config ?? {};
|
@@ -233,8 +232,9 @@ export class BoxManager {
|
|
233
232
|
height,
|
234
233
|
id: params.appId,
|
235
234
|
};
|
236
|
-
this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
235
|
+
const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
237
236
|
this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
|
237
|
+
return box;
|
238
238
|
}
|
239
239
|
|
240
240
|
public setupBoxManager(
|
@@ -242,10 +242,11 @@ export class BoxManager {
|
|
242
242
|
): TeleBoxManager {
|
243
243
|
const root = WindowManager.playground;
|
244
244
|
const initManagerState: TeleBoxManagerConfig = {
|
245
|
-
stageRatio:
|
245
|
+
stageRatio: createTeleBoxManagerConfig?.stageRatio,
|
246
246
|
root: root,
|
247
247
|
fence: false,
|
248
248
|
prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
|
249
|
+
highlightStage: createTeleBoxManagerConfig?.highlightStage,
|
249
250
|
};
|
250
251
|
|
251
252
|
const manager = new TeleBoxManager(initManagerState);
|
@@ -390,6 +391,10 @@ export class BoxManager {
|
|
390
391
|
this.teleBoxManager._root$.setValue(root);
|
391
392
|
}
|
392
393
|
|
394
|
+
public setCollector(collector: HTMLElement) {
|
395
|
+
this.teleBoxManager.collector.set$collector(collector);
|
396
|
+
}
|
397
|
+
|
393
398
|
public destroy() {
|
394
399
|
this.sideEffectManager.flushAll();
|
395
400
|
this.teleBoxManager.destroy();
|
package/src/Helper.ts
CHANGED
@@ -2,7 +2,7 @@ import { getVersionNumber } from "./Utils/Common";
|
|
2
2
|
import { REQUIRE_VERSION } from "./constants";
|
3
3
|
import { WhiteVersion } from "white-web-sdk";
|
4
4
|
import { WhiteWebSDKInvalidError } from "./Utils/error";
|
5
|
-
import type { Room } from "white-web-sdk";
|
5
|
+
import type { Room , RoomMember} from "white-web-sdk";
|
6
6
|
|
7
7
|
export const setupWrapper = (
|
8
8
|
root: HTMLElement
|
@@ -32,3 +32,12 @@ export const findMemberByUid = (room: Room | undefined, uid: string) => {
|
|
32
32
|
const roomMembers = room?.state.roomMembers;
|
33
33
|
return roomMembers?.find(member => member.payload?.uid === uid);
|
34
34
|
};
|
35
|
+
|
36
|
+
export type Member = RoomMember & { uid: string };
|
37
|
+
|
38
|
+
export const serializeRoomMembers = (members: readonly RoomMember[]) => {
|
39
|
+
return members.map(member => ({
|
40
|
+
uid: member.payload?.uid || "",
|
41
|
+
...member,
|
42
|
+
}));
|
43
|
+
}
|
package/src/InternalEmitter.ts
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
2
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
3
3
|
import type { AppInitState, CursorMovePayload } from "./index";
|
4
|
+
import type { Member } from "./Helper";
|
5
|
+
import type { MemberState } from "white-web-sdk";
|
4
6
|
|
5
7
|
export type RemoveSceneParams = {
|
6
8
|
scenePath: string;
|
@@ -29,6 +31,8 @@ export type EmitterEvent = {
|
|
29
31
|
changePageState: undefined;
|
30
32
|
writableChange: boolean;
|
31
33
|
containerSizeRatioUpdate: number;
|
34
|
+
roomMembersChange: Member[];
|
35
|
+
memberStateChange: MemberState;
|
32
36
|
};
|
33
37
|
|
34
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/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) {
|