@netless/window-manager 0.4.32 → 1.0.0-canary.10
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 -5
- 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 +9 -8
- package/dist/Helper.d.ts +12 -4
- package/dist/InternalEmitter.d.ts +6 -1
- 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 +17 -0
- package/dist/View/MainView.d.ts +4 -6
- package/dist/constants.d.ts +1 -0
- package/dist/index.cjs.js +21 -22
- package/dist/index.d.ts +6 -5
- package/dist/index.es.js +2512 -2059
- package/dist/index.umd.js +21 -22
- 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 +4 -3
- package/pnpm-lock.yaml +90 -97
- package/src/App/AppContext.ts +72 -75
- package/src/App/AppPageStateImpl.ts +25 -6
- package/src/App/AppProxy.ts +206 -35
- 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 +107 -115
- package/src/Cursor/index.ts +5 -5
- package/src/Helper.ts +12 -16
- package/src/InternalEmitter.ts +10 -4
- 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 +72 -0
- package/src/View/MainView.ts +53 -78
- package/src/constants.ts +2 -0
- package/src/index.ts +31 -36
- package/src/style.css +9 -0
- package/src/typings.ts +4 -0
- package/vite.config.js +0 -1
- package/dist/ContainerResizeObserver.d.ts +0 -11
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.es.js.map +0 -1
- package/dist/index.umd.js.map +0 -1
- package/src/ContainerResizeObserver.ts +0 -73
package/src/InternalEmitter.ts
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
|
+
import type { TeleBoxRect } from "@netless/telebox-insider";
|
2
3
|
import type { AppInitState, CursorMovePayload } from "./index";
|
4
|
+
import type { Member } from "./Helper";
|
5
|
+
import type { MemberState } from "white-web-sdk";
|
3
6
|
|
4
7
|
export type RemoveSceneParams = {
|
5
|
-
scenePath: string
|
6
|
-
|
8
|
+
scenePath: string;
|
9
|
+
index?: number;
|
10
|
+
};
|
7
11
|
|
8
12
|
export type EmitterEvent = {
|
9
13
|
onCreated: undefined;
|
@@ -14,19 +18,21 @@ export type EmitterEvent = {
|
|
14
18
|
mainViewMounted: undefined;
|
15
19
|
observerIdChange: number;
|
16
20
|
boxStateChange: string;
|
17
|
-
playgroundSizeChange:
|
21
|
+
playgroundSizeChange: TeleBoxRect;
|
18
22
|
startReconnect: undefined;
|
19
23
|
onReconnected: undefined;
|
20
24
|
removeScenes: RemoveSceneParams;
|
21
25
|
cursorMove: CursorMovePayload;
|
22
26
|
updateManagerRect: undefined;
|
23
27
|
focusedChange: { focused: string | undefined; prev: string | undefined };
|
24
|
-
rootDirRemoved: undefined;
|
28
|
+
rootDirRemoved: undefined; // 根目录整个被删除
|
25
29
|
rootDirSceneRemoved: string; // 根目录下的场景被删除
|
26
30
|
setReadonly: boolean;
|
27
31
|
changePageState: undefined;
|
28
32
|
writableChange: boolean;
|
29
33
|
containerSizeRatioUpdate: number;
|
34
|
+
roomMembersChange: Member[];
|
35
|
+
memberStateChange: MemberState;
|
30
36
|
};
|
31
37
|
|
32
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) {
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import { AnimationMode } from "white-web-sdk";
|
2
|
+
import { debounce, delay, throttle } from "lodash";
|
3
|
+
import type { TeleBoxRect } from "@netless/telebox-insider";
|
4
|
+
import type { Camera, View } from "white-web-sdk";
|
5
|
+
import type { ISize } from "../AttributesDelegate";
|
6
|
+
|
7
|
+
export type SaveCamera = (camera: Camera) => void;
|
8
|
+
|
9
|
+
export class CameraSynchronizer {
|
10
|
+
public remoteCamera?: Camera;
|
11
|
+
public remoteSize?: ISize;
|
12
|
+
protected rect?: TeleBoxRect;
|
13
|
+
protected view?: View;
|
14
|
+
|
15
|
+
constructor(protected saveCamera: SaveCamera) {}
|
16
|
+
|
17
|
+
public setRect = debounce((rect: TeleBoxRect) => {
|
18
|
+
this.rect = rect;
|
19
|
+
if (this.remoteCamera && this.remoteSize) {
|
20
|
+
this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
|
21
|
+
}
|
22
|
+
}, 50);
|
23
|
+
|
24
|
+
public setView(view: View) {
|
25
|
+
this.view = view;
|
26
|
+
}
|
27
|
+
|
28
|
+
// 远端 Camera 或者 size 更新
|
29
|
+
public onRemoteUpdate = throttle((camera: Camera, size: ISize) => {
|
30
|
+
this.remoteCamera = camera;
|
31
|
+
this.remoteSize = size;
|
32
|
+
if (this.remoteSize && this.rect) {
|
33
|
+
let scale: number;
|
34
|
+
if (size.width < size.height) {
|
35
|
+
scale = this.rect.width / size.width;
|
36
|
+
} else {
|
37
|
+
scale = this.rect.height / size.height;
|
38
|
+
}
|
39
|
+
const nextScale = camera.scale * scale;
|
40
|
+
|
41
|
+
const moveCamera = () => {
|
42
|
+
this.view?.moveCamera({
|
43
|
+
centerX: camera.centerX,
|
44
|
+
centerY: camera.centerY,
|
45
|
+
scale: nextScale,
|
46
|
+
animationMode: AnimationMode.Immediately,
|
47
|
+
});
|
48
|
+
}
|
49
|
+
// TODO 直接调用 moveCamera 依然会出现 camera 错误的情况,这里暂时加一个 delay 保证 camera 是对的, 后续需要 SDK 进行修改
|
50
|
+
delay(moveCamera, 50);
|
51
|
+
}
|
52
|
+
}, 50);
|
53
|
+
|
54
|
+
public onRemoteSizeUpdate(size: ISize) {
|
55
|
+
if (this.rect) {
|
56
|
+
const nextScale = this.rect.width / size.width;
|
57
|
+
const moveCamera = () => {
|
58
|
+
this.view?.moveCamera({
|
59
|
+
scale: nextScale,
|
60
|
+
animationMode: AnimationMode.Immediately,
|
61
|
+
})
|
62
|
+
};
|
63
|
+
delay(moveCamera, 50);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
public onLocalCameraUpdate(camera: Camera) {
|
69
|
+
this.saveCamera(camera);
|
70
|
+
this.remoteCamera = camera;
|
71
|
+
}
|
72
|
+
}
|
package/src/View/MainView.ts
CHANGED
@@ -1,25 +1,29 @@
|
|
1
|
-
import { AnimationMode, reaction } from "white-web-sdk";
|
2
1
|
import { callbacks } from "../callback";
|
2
|
+
import { CameraSynchronizer } from "./CameraSynchronizer";
|
3
3
|
import { createView } from "./ViewManager";
|
4
|
-
import { debounce, get,
|
4
|
+
import { debounce, get, isEqual } from "lodash";
|
5
5
|
import { emitter } from "../InternalEmitter";
|
6
|
+
import { Events } from "../constants";
|
6
7
|
import { Fields } from "../AttributesDelegate";
|
7
|
-
import {
|
8
|
+
import { reaction } from "white-web-sdk";
|
9
|
+
import { releaseView, setViewFocusScenePath } from "../Utils/Common";
|
8
10
|
import { SideEffectManager } from "side-effect-manager";
|
9
11
|
import type { Camera, Size, View } from "white-web-sdk";
|
10
12
|
import type { AppManager } from "../AppManager";
|
11
|
-
import { Events } from "../constants";
|
12
13
|
|
13
14
|
export class MainViewProxy {
|
14
|
-
private scale?: number;
|
15
15
|
private started = false;
|
16
16
|
private mainViewIsAddListener = false;
|
17
17
|
private mainView: View;
|
18
18
|
private store = this.manager.store;
|
19
|
+
private synchronizer: CameraSynchronizer;
|
19
20
|
|
20
21
|
private sideEffectManager = new SideEffectManager();
|
21
22
|
|
22
23
|
constructor(private manager: AppManager) {
|
24
|
+
this.synchronizer = new CameraSynchronizer(camera =>
|
25
|
+
this.store.setMainViewCamera({ ...camera, id: this.manager.uid })
|
26
|
+
);
|
23
27
|
this.mainView = this.createMainView();
|
24
28
|
this.moveCameraSizeByAttributes();
|
25
29
|
emitter.once("mainViewMounted").then(() => {
|
@@ -28,31 +32,30 @@ export class MainViewProxy {
|
|
28
32
|
this.ensureCameraAndSize();
|
29
33
|
this.startListenWritableChange();
|
30
34
|
});
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
this.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
});
|
35
|
+
this.sideEffectManager.add(() => [
|
36
|
+
emitter.on("containerSizeRatioUpdate", this.onUpdateContainerSizeRatio),
|
37
|
+
emitter.on("startReconnect", () => {
|
38
|
+
releaseView(this.mainView);
|
39
|
+
}),
|
40
|
+
emitter.on("playgroundSizeChange", rect => {
|
41
|
+
this.synchronizer.setRect(rect);
|
42
|
+
})
|
43
|
+
]);
|
44
|
+
const rect = this.manager.boxManager?.stageRect;
|
45
|
+
if (rect) {
|
46
|
+
this.synchronizer.setRect(rect);
|
47
|
+
}
|
45
48
|
}
|
46
49
|
|
47
50
|
private startListenWritableChange = () => {
|
48
|
-
this.sideEffectManager.add(() =>
|
49
|
-
|
51
|
+
this.sideEffectManager.add(() =>
|
52
|
+
emitter.on("writableChange", isWritable => {
|
50
53
|
if (isWritable) {
|
51
54
|
this.ensureCameraAndSize();
|
52
55
|
}
|
53
|
-
})
|
54
|
-
|
55
|
-
}
|
56
|
+
})
|
57
|
+
);
|
58
|
+
};
|
56
59
|
|
57
60
|
public ensureCameraAndSize() {
|
58
61
|
if (!this.mainViewCamera || !this.mainViewSize) {
|
@@ -74,26 +77,27 @@ export class MainViewProxy {
|
|
74
77
|
}
|
75
78
|
|
76
79
|
private moveCameraSizeByAttributes() {
|
77
|
-
this.
|
78
|
-
this.moveCamera(this.mainViewCamera);
|
80
|
+
this.synchronizer.onRemoteUpdate(this.mainViewCamera, this.mainViewSize);
|
79
81
|
}
|
80
82
|
|
81
83
|
public start() {
|
82
84
|
if (this.started) return;
|
83
|
-
this.sizeChangeHandler(this.mainViewSize);
|
84
85
|
this.addCameraListener();
|
85
86
|
this.addCameraReaction();
|
86
87
|
this.started = true;
|
87
88
|
}
|
88
89
|
|
89
90
|
public addCameraReaction = () => {
|
90
|
-
this.manager.refresher
|
91
|
+
this.manager.refresher.add(Fields.MainViewCamera, this.cameraReaction);
|
91
92
|
};
|
92
93
|
|
93
94
|
public setCameraAndSize(): void {
|
94
|
-
const
|
95
|
-
|
96
|
-
|
95
|
+
const stageSize = this.getStageSize();
|
96
|
+
if (stageSize) {
|
97
|
+
const camera = { ...this.mainView.camera, id: this.manager.uid };
|
98
|
+
const size = { ...stageSize, id: this.manager.uid };
|
99
|
+
this.store.setMainViewCameraAndSize(camera, size);
|
100
|
+
}
|
97
101
|
}
|
98
102
|
|
99
103
|
private cameraReaction = () => {
|
@@ -101,28 +105,19 @@ export class MainViewProxy {
|
|
101
105
|
() => this.mainViewCamera,
|
102
106
|
camera => {
|
103
107
|
if (camera && camera.id !== this.manager.uid) {
|
104
|
-
this.
|
105
|
-
this.moveCamera(camera);
|
108
|
+
this.synchronizer.onRemoteUpdate(camera, this.mainViewSize);
|
106
109
|
}
|
107
110
|
},
|
108
111
|
{ fireImmediately: true }
|
109
112
|
);
|
110
113
|
};
|
111
114
|
|
112
|
-
public sizeChangeHandler = debounce((size: Size) => {
|
113
|
-
if (size) {
|
114
|
-
this.moveCameraToContian(size);
|
115
|
-
this.moveCamera(this.mainViewCamera);
|
116
|
-
}
|
117
|
-
}, 30);
|
118
|
-
|
119
115
|
public onUpdateContainerSizeRatio = () => {
|
120
116
|
const size = this.store.getMainViewSize();
|
121
|
-
this.sizeChangeHandler(size);
|
122
117
|
if (size.id === this.manager.uid) {
|
123
118
|
this.setCameraAndSize();
|
124
119
|
}
|
125
|
-
}
|
120
|
+
};
|
126
121
|
|
127
122
|
public get view(): View {
|
128
123
|
return this.mainView;
|
@@ -138,6 +133,7 @@ export class MainViewProxy {
|
|
138
133
|
if (mainViewScenePath) {
|
139
134
|
setViewFocusScenePath(mainView, mainViewScenePath);
|
140
135
|
}
|
136
|
+
this.synchronizer.setView(mainView);
|
141
137
|
return mainView;
|
142
138
|
}
|
143
139
|
|
@@ -160,9 +156,7 @@ export class MainViewProxy {
|
|
160
156
|
const divElement = this.mainView.divElement;
|
161
157
|
const disableCameraTransform = this.mainView.disableCameraTransform;
|
162
158
|
this.stop();
|
163
|
-
|
164
|
-
this.mainView.release();
|
165
|
-
}
|
159
|
+
releaseView(this.mainView);
|
166
160
|
this.removeMainViewListener();
|
167
161
|
this.mainView = this.createMainView();
|
168
162
|
this.mainView.disableCameraTransform = disableCameraTransform;
|
@@ -172,12 +166,20 @@ export class MainViewProxy {
|
|
172
166
|
}
|
173
167
|
|
174
168
|
private onCameraUpdatedByDevice = (camera: Camera) => {
|
175
|
-
this.
|
176
|
-
|
177
|
-
|
169
|
+
this.synchronizer.onLocalCameraUpdate(camera);
|
170
|
+
const size = this.getStageSize();
|
171
|
+
if (size && !isEqual(size, this.mainViewSize)) {
|
172
|
+
this.setMainViewSize(size);
|
178
173
|
}
|
179
174
|
};
|
180
175
|
|
176
|
+
private getStageSize(): Size | undefined {
|
177
|
+
const stage = this.manager.boxManager?.stageRect;
|
178
|
+
if (stage) {
|
179
|
+
return { width: stage.width, height: stage.height };
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
181
183
|
public addMainViewListener(): void {
|
182
184
|
if (this.mainViewIsAddListener) return;
|
183
185
|
if (this.view.divElement) {
|
@@ -205,7 +207,7 @@ export class MainViewProxy {
|
|
205
207
|
this.manager.boxManager?.blurAllBox();
|
206
208
|
}
|
207
209
|
|
208
|
-
public setMainViewSize = debounce(size => {
|
210
|
+
public setMainViewSize = debounce((size: Size) => {
|
209
211
|
this.store.setMainViewSize({ ...size, id: this.manager.uid });
|
210
212
|
}, 50);
|
211
213
|
|
@@ -225,37 +227,10 @@ export class MainViewProxy {
|
|
225
227
|
callbacks.emit("cameraStateChange", this.cameraState);
|
226
228
|
};
|
227
229
|
|
228
|
-
public moveCameraToContian(size: Size): void {
|
229
|
-
if (!isEmpty(size)) {
|
230
|
-
this.view.moveCameraToContain({
|
231
|
-
width: size.width,
|
232
|
-
height: size.height,
|
233
|
-
originX: -size.width / 2,
|
234
|
-
originY: -size.height / 2,
|
235
|
-
animationMode: AnimationMode.Immediately,
|
236
|
-
});
|
237
|
-
this.scale = this.view.camera.scale;
|
238
|
-
}
|
239
|
-
}
|
240
|
-
|
241
|
-
public moveCamera(camera: Camera): void {
|
242
|
-
if (!isEmpty(camera)) {
|
243
|
-
if (isEqual(camera, this.view.camera)) return;
|
244
|
-
const { centerX, centerY, scale } = camera;
|
245
|
-
const needScale = scale * (this.scale || 1);
|
246
|
-
this.view.moveCamera({
|
247
|
-
centerX: centerX,
|
248
|
-
centerY: centerY,
|
249
|
-
scale: needScale,
|
250
|
-
animationMode: AnimationMode.Immediately,
|
251
|
-
});
|
252
|
-
}
|
253
|
-
}
|
254
|
-
|
255
230
|
public stop() {
|
256
231
|
this.removeCameraListener();
|
257
|
-
this.manager.refresher
|
258
|
-
this.manager.refresher
|
232
|
+
this.manager.refresher.remove(Fields.MainViewCamera);
|
233
|
+
this.manager.refresher.remove(Fields.MainViewSize);
|
259
234
|
this.started = false;
|
260
235
|
}
|
261
236
|
|
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
@@ -3,7 +3,6 @@ import { AppManager } from "./AppManager";
|
|
3
3
|
import { appRegister } from "./Register";
|
4
4
|
import { callbacks } from "./callback";
|
5
5
|
import { checkVersion, setupWrapper } from "./Helper";
|
6
|
-
import { ContainerResizeObserver } from "./ContainerResizeObserver";
|
7
6
|
import { createBoxManager } from "./BoxManager";
|
8
7
|
import { CursorManager } from "./Cursor";
|
9
8
|
import { DEFAULT_CONTAINER_RATIO, Events, INIT_DIR, ROOT_DIR } from "./constants";
|
@@ -30,7 +29,7 @@ import {
|
|
30
29
|
} from "./Utils/Common";
|
31
30
|
import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
|
32
31
|
import * as Errors from "./Utils/error";
|
33
|
-
import type { Apps, Position } from "./AttributesDelegate";
|
32
|
+
import type { Apps, Position , ICamera, ISize } from "./AttributesDelegate";
|
34
33
|
import type {
|
35
34
|
Displayer,
|
36
35
|
SceneDefinition,
|
@@ -105,6 +104,8 @@ export type AppSyncAttributes = {
|
|
105
104
|
isDynamicPPT?: boolean;
|
106
105
|
fullPath?: string;
|
107
106
|
createdAt?: number;
|
107
|
+
camera?: ICamera;
|
108
|
+
size?: ISize;
|
108
109
|
};
|
109
110
|
|
110
111
|
export type AppInitState = {
|
@@ -128,8 +129,8 @@ export type MountParams = {
|
|
128
129
|
container?: HTMLElement;
|
129
130
|
/** 白板高宽比例, 默认为 9 / 16 */
|
130
131
|
containerSizeRatio?: number;
|
131
|
-
/**
|
132
|
-
|
132
|
+
/** 是否高亮显示同步区域, 默认为 true */
|
133
|
+
highlightStage?: boolean;
|
133
134
|
collectorContainer?: HTMLElement;
|
134
135
|
collectorStyles?: Partial<CSSStyleDeclaration>;
|
135
136
|
overwriteStyles?: string;
|
@@ -145,7 +146,6 @@ export const reconnectRefresher = new ReconnectRefresher({ emitter });
|
|
145
146
|
export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> implements PageController {
|
146
147
|
public static kind = "WindowManager";
|
147
148
|
public static displayer: Displayer;
|
148
|
-
public static wrapper?: HTMLElement;
|
149
149
|
public static playground?: HTMLElement;
|
150
150
|
public static container?: HTMLElement;
|
151
151
|
public static debug = false;
|
@@ -168,7 +168,6 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
168
168
|
private boxManager?: BoxManager;
|
169
169
|
private static params?: MountParams;
|
170
170
|
|
171
|
-
private containerResizeObserver?: ContainerResizeObserver;
|
172
171
|
public containerSizeRatio = WindowManager.containerSizeRatio;
|
173
172
|
|
174
173
|
constructor(context: InvisiblePluginContext) {
|
@@ -237,7 +236,14 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
237
236
|
if (containerSizeRatio) {
|
238
237
|
manager.containerSizeRatio = containerSizeRatio;
|
239
238
|
}
|
240
|
-
|
239
|
+
manager.boxManager = createBoxManager(manager, callbacks, emitter, boxEmitter, {
|
240
|
+
collectorContainer: params.collectorContainer,
|
241
|
+
collectorStyles: params.collectorStyles,
|
242
|
+
prefersColorScheme: params.prefersColorScheme,
|
243
|
+
stageRatio: params.containerSizeRatio,
|
244
|
+
highlightStage: params.highlightStage
|
245
|
+
});
|
246
|
+
manager.appManager?.setBoxManager(manager.boxManager);
|
241
247
|
if (params.container) {
|
242
248
|
manager.bindContainer(params.container);
|
243
249
|
}
|
@@ -283,31 +289,19 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
283
289
|
}
|
284
290
|
|
285
291
|
private static initContainer(
|
286
|
-
manager: WindowManager,
|
287
292
|
container: HTMLElement,
|
288
|
-
chessboard: boolean | undefined,
|
289
293
|
overwriteStyles: string | undefined
|
290
294
|
) {
|
291
295
|
if (!WindowManager.container) {
|
292
296
|
WindowManager.container = container;
|
293
297
|
}
|
294
|
-
const { playground,
|
298
|
+
const { playground, mainViewElement } = setupWrapper(container);
|
295
299
|
WindowManager.playground = playground;
|
296
|
-
if (chessboard) {
|
297
|
-
sizer.classList.add("netless-window-manager-chess-sizer");
|
298
|
-
}
|
299
300
|
if (overwriteStyles) {
|
300
301
|
const style = document.createElement("style");
|
301
302
|
style.textContent = overwriteStyles;
|
302
303
|
playground.appendChild(style);
|
303
304
|
}
|
304
|
-
manager.containerResizeObserver = ContainerResizeObserver.create(
|
305
|
-
playground,
|
306
|
-
sizer,
|
307
|
-
wrapper,
|
308
|
-
emitter
|
309
|
-
);
|
310
|
-
WindowManager.wrapper = wrapper;
|
311
305
|
return mainViewElement;
|
312
306
|
}
|
313
307
|
|
@@ -327,24 +321,15 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
327
321
|
if (WindowManager.params) {
|
328
322
|
const params = WindowManager.params;
|
329
323
|
const mainViewElement = WindowManager.initContainer(
|
330
|
-
this,
|
331
324
|
container,
|
332
|
-
params.chessboard,
|
333
325
|
params.overwriteStyles
|
334
326
|
);
|
335
|
-
if (this.boxManager) {
|
336
|
-
this.boxManager.
|
327
|
+
if (this.boxManager && WindowManager.playground) {
|
328
|
+
this.boxManager.setRoot(WindowManager.playground);
|
337
329
|
}
|
338
|
-
const boxManager = createBoxManager(this, callbacks, emitter, boxEmitter, {
|
339
|
-
collectorContainer: params.collectorContainer,
|
340
|
-
collectorStyles: params.collectorStyles,
|
341
|
-
prefersColorScheme: params.prefersColorScheme,
|
342
|
-
});
|
343
|
-
this.boxManager = boxManager;
|
344
|
-
this.appManager?.setBoxManager(boxManager);
|
345
330
|
this.bindMainView(mainViewElement, params.disableCameraTransform);
|
346
|
-
if (WindowManager.
|
347
|
-
this.cursorManager?.setupWrapper(WindowManager.
|
331
|
+
if (WindowManager.playground) {
|
332
|
+
this.cursorManager?.setupWrapper(WindowManager.playground);
|
348
333
|
}
|
349
334
|
}
|
350
335
|
}
|
@@ -358,7 +343,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
358
343
|
|
359
344
|
public bindCollectorContainer(container: HTMLElement) {
|
360
345
|
if (WindowManager.isCreated && this.boxManager) {
|
361
|
-
this.boxManager.
|
346
|
+
this.boxManager.setCollector(container);
|
362
347
|
} else {
|
363
348
|
if (WindowManager.params) {
|
364
349
|
WindowManager.params.collectorContainer = container;
|
@@ -520,6 +505,18 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
520
505
|
}
|
521
506
|
}
|
522
507
|
|
508
|
+
public async jumpPage(index: number): Promise<boolean> {
|
509
|
+
if (!this.appManager) {
|
510
|
+
return false;
|
511
|
+
}
|
512
|
+
if (index < 0 || index >= this.pageState.length) {
|
513
|
+
console.warn(`[WindowManager]: index ${index} out of range`);
|
514
|
+
return false;
|
515
|
+
}
|
516
|
+
await this.appManager.setMainViewSceneIndex(index);
|
517
|
+
return true;
|
518
|
+
}
|
519
|
+
|
523
520
|
public async addPage(params?: AddPageParams): Promise<void> {
|
524
521
|
if (this.appManager) {
|
525
522
|
const after = params?.after;
|
@@ -802,11 +799,9 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
802
799
|
}
|
803
800
|
|
804
801
|
private _destroy() {
|
805
|
-
this.containerResizeObserver?.disconnect();
|
806
802
|
this.appManager?.destroy();
|
807
803
|
this.cursorManager?.destroy();
|
808
804
|
WindowManager.container = undefined;
|
809
|
-
WindowManager.wrapper = undefined;
|
810
805
|
WindowManager.isCreated = false;
|
811
806
|
if (WindowManager.playground) {
|
812
807
|
WindowManager.playground.parentNode?.removeChild(WindowManager.playground);
|
package/src/style.css
CHANGED
package/src/typings.ts
CHANGED
@@ -13,6 +13,7 @@ import type {
|
|
13
13
|
import type { AppContext } from "./App";
|
14
14
|
import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
|
15
15
|
import type { PageState } from "./Page";
|
16
|
+
import type { Member } from "./Helper";
|
16
17
|
|
17
18
|
export interface NetlessApp<Attributes = any, MagixEventPayloads = any, AppOptions = any, SetupResult = any> {
|
18
19
|
kind: string;
|
@@ -53,6 +54,7 @@ export type AppEmitterEvent<T = any> = {
|
|
53
54
|
reconnected: void;
|
54
55
|
seek: number;
|
55
56
|
pageStateChange: PageState,
|
57
|
+
roomMembersChange: Member[];
|
56
58
|
};
|
57
59
|
|
58
60
|
export type RegisterEventData = {
|
@@ -79,8 +81,10 @@ export type AppListenerKeys = keyof AppEmitterEvent;
|
|
79
81
|
export type ApplianceIcons = Partial<Record<ApplianceNames, string>>;
|
80
82
|
|
81
83
|
export type { AppContext } from "./App/AppContext";
|
84
|
+
export type { WhiteBoardView } from "./App";
|
82
85
|
export type { ReadonlyTeleBox, TeleBoxRect };
|
83
86
|
export type { SceneState, SceneDefinition, View, AnimationMode, Displayer, Room, Player };
|
84
87
|
export type { Storage, StorageStateChangedEvent, StorageStateChangedListener } from "./App/Storage";
|
85
88
|
export * from "./Page";
|
86
89
|
export * from "./Utils/error";
|
90
|
+
export type { Member } from "./Helper";
|
package/vite.config.js
CHANGED
@@ -1,11 +0,0 @@
|
|
1
|
-
import type { EmitterType } from "./InternalEmitter";
|
2
|
-
export declare class ContainerResizeObserver {
|
3
|
-
private emitter;
|
4
|
-
private containerResizeObserver?;
|
5
|
-
private disposer?;
|
6
|
-
constructor(emitter: EmitterType);
|
7
|
-
static create(container: HTMLElement, sizer: HTMLElement, wrapper: HTMLDivElement, emitter: EmitterType): ContainerResizeObserver;
|
8
|
-
observePlaygroundSize(container: HTMLElement, sizer: HTMLElement, wrapper: HTMLDivElement): void;
|
9
|
-
updateSizer({ width, height }: DOMRectReadOnly, sizer: HTMLElement, wrapper: HTMLDivElement): void;
|
10
|
-
disconnect(): void;
|
11
|
-
}
|