@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.
Files changed (56) hide show
  1. package/__mocks__/white-web-sdk.ts +10 -1
  2. package/dist/App/AppContext.d.ts +16 -15
  3. package/dist/App/AppPageStateImpl.d.ts +6 -2
  4. package/dist/App/AppProxy.d.ts +26 -5
  5. package/dist/App/AppViewSync.d.ts +11 -0
  6. package/dist/App/WhiteboardView.d.ts +24 -0
  7. package/dist/App/index.d.ts +1 -0
  8. package/dist/AppManager.d.ts +5 -3
  9. package/dist/AttributesDelegate.d.ts +6 -14
  10. package/dist/BoxManager.d.ts +9 -8
  11. package/dist/Helper.d.ts +12 -4
  12. package/dist/InternalEmitter.d.ts +6 -1
  13. package/dist/Page/PageController.d.ts +1 -0
  14. package/dist/ReconnectRefresher.d.ts +1 -1
  15. package/dist/Utils/Common.d.ts +1 -0
  16. package/dist/View/CameraSynchronizer.d.ts +17 -0
  17. package/dist/View/MainView.d.ts +4 -6
  18. package/dist/constants.d.ts +1 -0
  19. package/dist/index.cjs.js +21 -22
  20. package/dist/index.d.ts +6 -5
  21. package/dist/index.es.js +2512 -2059
  22. package/dist/index.umd.js +21 -22
  23. package/dist/style.css +1 -1
  24. package/dist/typings.d.ts +4 -0
  25. package/docs/app-context.md +98 -64
  26. package/docs/develop-app.md +2 -5
  27. package/package.json +4 -3
  28. package/pnpm-lock.yaml +90 -97
  29. package/src/App/AppContext.ts +72 -75
  30. package/src/App/AppPageStateImpl.ts +25 -6
  31. package/src/App/AppProxy.ts +206 -35
  32. package/src/App/AppViewSync.ts +73 -0
  33. package/src/App/Storage/index.ts +4 -4
  34. package/src/App/WhiteboardView.ts +89 -0
  35. package/src/App/index.ts +1 -0
  36. package/src/AppManager.ts +32 -23
  37. package/src/AttributesDelegate.ts +14 -17
  38. package/src/BoxManager.ts +107 -115
  39. package/src/Cursor/index.ts +5 -5
  40. package/src/Helper.ts +12 -16
  41. package/src/InternalEmitter.ts +10 -4
  42. package/src/Page/PageController.ts +1 -0
  43. package/src/ReconnectRefresher.ts +1 -0
  44. package/src/Utils/Common.ts +6 -0
  45. package/src/View/CameraSynchronizer.ts +72 -0
  46. package/src/View/MainView.ts +53 -78
  47. package/src/constants.ts +2 -0
  48. package/src/index.ts +31 -36
  49. package/src/style.css +9 -0
  50. package/src/typings.ts +4 -0
  51. package/vite.config.js +0 -1
  52. package/dist/ContainerResizeObserver.d.ts +0 -11
  53. package/dist/index.cjs.js.map +0 -1
  54. package/dist/index.es.js.map +0 -1
  55. package/dist/index.umd.js.map +0 -1
  56. package/src/ContainerResizeObserver.ts +0 -73
@@ -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, index?: number
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: DOMRect;
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;
@@ -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) {
@@ -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
+ }
@@ -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, isEmpty, isEqual } from "lodash";
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 { setViewFocusScenePath } from "../Utils/Common";
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
- const playgroundSizeChangeListener = () => {
32
- this.sizeChangeHandler(this.mainViewSize);
33
- };
34
- this.sideEffectManager.add(() => {
35
- return emitter.on("playgroundSizeChange", playgroundSizeChangeListener);
36
- });
37
- this.sideEffectManager.add(() => {
38
- return emitter.on("containerSizeRatioUpdate", this.onUpdateContainerSizeRatio);
39
- });
40
- this.sideEffectManager.add(() => {
41
- return emitter.on("startReconnect", () => {
42
- this.mainView.release();
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
- return emitter.on("writableChange", isWritable => {
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.moveCameraToContian(this.mainViewSize);
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?.add(Fields.MainViewCamera, this.cameraReaction);
91
+ this.manager.refresher.add(Fields.MainViewCamera, this.cameraReaction);
91
92
  };
92
93
 
93
94
  public setCameraAndSize(): void {
94
- const camera = { ...this.mainView.camera, id: this.manager.uid };
95
- const size = { ...this.mainView.size, id: this.manager.uid };
96
- this.store.setMainViewCameraAndSize(camera, size);
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.moveCameraToContian(this.mainViewSize);
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
- if (!this.didRelease) {
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.store.setMainViewCamera({ ...camera, id: this.manager.uid });
176
- if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.manager.uid })) {
177
- this.setMainViewSize(this.view.size);
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?.remove(Fields.MainViewCamera);
258
- this.manager.refresher?.remove(Fields.MainViewSize);
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
@@ -57,3 +57,5 @@ export const ROOT_DIR = "/";
57
57
  export const INIT_DIR = "/init";
58
58
 
59
59
  export const SETUP_APP_DELAY = 50;
60
+
61
+ export const MAX_PAGE_SIZE = 500;
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
- /** 显示 PS 透明背景,默认 true */
132
- chessboard?: boolean;
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, wrapper, sizer, mainViewElement } = setupWrapper(container);
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.destroy();
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.wrapper) {
347
- this.cursorManager?.setupWrapper(WindowManager.wrapper);
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.setCollectorContainer(container);
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
@@ -178,3 +178,12 @@
178
178
  right: 10px;
179
179
  bottom: 15px;
180
180
  }
181
+
182
+ .window-manager-view-wrapper {
183
+ z-index: 5000;
184
+ width: 100%;
185
+ height: 100%;
186
+ position: absolute;
187
+ left: 0;
188
+ top: 0;
189
+ }
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
@@ -39,7 +39,6 @@ export default defineConfig(({ mode }) => {
39
39
  fileName: "index"
40
40
  },
41
41
  outDir: "dist",
42
- sourcemap: true,
43
42
  rollupOptions: {
44
43
  external: Object.keys({
45
44
  ...omit(dependencies, ["@netless/telebox-insider"]),
@@ -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
- }