@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
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?: ReconnectRefresher;
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?.add("maximized", () => {
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?.add("minimized", () => {
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?.add("mainViewIndex", () => {
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?.add("focusedChange", () => {
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?.add("registeredChange", () => {
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._prevFocused = this.attributes.focus;
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._prevSceneIndex !== index) {
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._prevSceneIndex = index;
436
+ this.sceneIndex$.setValue(index);
431
437
  }
432
438
  };
433
439
 
434
440
  private onFocusChange = (focused: string | undefined) => {
435
- if (this._prevFocused !== focused) {
441
+ if (this.focused$.value !== focused) {
436
442
  callbacks.emit("focusedChange", focused);
437
- emitter.emit("focusedChange", { focused, prev: this._prevFocused });
438
- this._prevFocused = focused;
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<DisplayerState>) => {
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._prevFocused = undefined;
827
- this._prevSceneIndex = undefined;
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 & { id: string };
44
+ export type ICamera = Camera & {
45
+ id: string; // room uid
46
+ };
43
47
 
44
- export type ISize = Size & { id: string };
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(): MainViewCamera {
162
+ public getMainViewCamera(): ICamera {
153
163
  return get(this.attributes, [Fields.MainViewCamera]);
154
164
  }
155
165
 
156
- public getMainViewSize(): MainViewSize {
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
@@ -1,6 +1,6 @@
1
1
  import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
2
2
  import { debounce } from "lodash";
3
- import { TELE_BOX_STATE, TeleBoxCollector, TeleBoxManager } from "@netless/telebox-insider";
3
+ import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
4
4
  import { WindowManager } from "./index";
5
5
  import type { BoxEmitterType } from "./BoxEmitter";
6
6
  import type { AddAppOptions, AppInitState } from "./index";
@@ -18,6 +18,7 @@ import type { NetlessApp } from "./typings";
18
18
  import type { View } from "white-web-sdk";
19
19
  import type { CallbacksType } from "./callback";
20
20
  import type { EmitterType } from "./InternalEmitter";
21
+ import { SideEffectManager } from "side-effect-manager";
21
22
 
22
23
  export { TELE_BOX_STATE };
23
24
 
@@ -45,11 +46,12 @@ export type CreateTeleBoxManagerConfig = {
45
46
  collectorContainer?: HTMLElement;
46
47
  collectorStyles?: Partial<CSSStyleDeclaration>;
47
48
  prefersColorScheme?: TeleBoxColorScheme;
49
+ stageRatio?: number;
50
+ highlightStage?: boolean;
48
51
  };
49
52
 
50
53
  export type BoxManagerContext = {
51
54
  safeSetAttributes: (attributes: any) => void;
52
- getMainView: () => View;
53
55
  updateAppState: (appId: string, field: AppAttributes, value: any) => void;
54
56
  emitter: EmitterType;
55
57
  boxEmitter: BoxEmitterType;
@@ -70,7 +72,6 @@ export const createBoxManager = (
70
72
  return new BoxManager(
71
73
  {
72
74
  safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
73
- getMainView: () => manager.mainView,
74
75
  updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
75
76
  canOperate: () => manager.canOperate,
76
77
  notifyContainerRectUpdate: (rect: TeleBoxRect) =>
@@ -87,83 +88,93 @@ export const createBoxManager = (
87
88
 
88
89
  export class BoxManager {
89
90
  public teleBoxManager: TeleBoxManager;
91
+ protected sideEffectManager: SideEffectManager;
90
92
 
91
93
  constructor(
92
94
  private context: BoxManagerContext,
93
- private createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
95
+ createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
94
96
  ) {
97
+ this.sideEffectManager = new SideEffectManager();
95
98
  const { emitter, callbacks, boxEmitter } = context;
96
99
  this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
97
-
98
- // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
99
- this.teleBoxManager._state$.reaction(state => {
100
- callbacks.emit("boxStateChange", state);
101
- emitter.emit("boxStateChange", state);
102
- });
103
-
104
- this.teleBoxManager._darkMode$.reaction(darkMode => {
105
- callbacks.emit("darkModeChange", darkMode);
106
- });
107
- this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
108
- callbacks.emit("prefersColorSchemeChange", colorScheme);
109
- });
110
-
111
- // events.on 的值则会根据 skipUpdate 来决定是否触发回调
112
- this.teleBoxManager.events.on("minimized", minimized => {
113
- this.context.safeSetAttributes({ minimized });
114
- if (minimized) {
115
- this.context.cleanFocus();
116
- this.blurAllBox();
117
- } else {
118
- const topBox = this.getTopBox();
119
- if (topBox) {
120
- this.context.setAppFocus(topBox.id);
121
- this.focusBox({ appId: topBox.id }, false);
100
+ this.sideEffectManager.add(() => [
101
+ // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
102
+ this.teleBoxManager._state$.reaction(state => {
103
+ callbacks.emit("boxStateChange", state);
104
+ emitter.emit("boxStateChange", state);
105
+ }),
106
+ this.teleBoxManager._darkMode$.reaction(darkMode => {
107
+ callbacks.emit("darkModeChange", darkMode);
108
+ }),
109
+ this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
110
+ callbacks.emit("prefersColorSchemeChange", colorScheme);
111
+ }),
112
+ this.teleBoxManager._minimized$.reaction((minimized, skipUpdate) => {
113
+ if (skipUpdate) {
114
+ return;
122
115
  }
123
- }
124
- });
125
- this.teleBoxManager.events.on("maximized", maximized => {
126
- this.context.safeSetAttributes({ maximized });
127
- });
128
- this.teleBoxManager.events.on("removed", boxes => {
129
- boxes.forEach(box => {
130
- boxEmitter.emit("close", { appId: box.id });
131
- });
132
- });
133
- this.teleBoxManager.events.on(
134
- "intrinsic_move",
135
- debounce((box: ReadonlyTeleBox): void => {
136
- boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
137
- }, 50)
138
- );
139
- this.teleBoxManager.events.on(
140
- "intrinsic_resize",
141
- debounce((box: ReadonlyTeleBox): void => {
142
- boxEmitter.emit("resize", {
143
- appId: box.id,
144
- width: box.intrinsicWidth,
145
- height: box.intrinsicHeight,
146
- });
147
- }, 200)
148
- );
149
- this.teleBoxManager.events.on("focused", box => {
150
- if (box) {
151
- if (this.canOperate) {
152
- boxEmitter.emit("focus", { appId: box.id });
116
+ this.context.safeSetAttributes({ minimized });
117
+ if (minimized) {
118
+ this.context.cleanFocus();
119
+ this.blurAllBox();
153
120
  } else {
154
- this.teleBoxManager.blurBox(box.id);
121
+ const topBox = this.getTopBox();
122
+ if (topBox) {
123
+ this.context.setAppFocus(topBox.id);
124
+ this.focusBox({ appId: topBox.id }, false);
125
+ }
155
126
  }
156
- }
157
- });
158
- this.teleBoxManager.events.on("z_index", box => {
159
- this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
160
- });
161
- emitter.on("playgroundSizeChange", () => this.updateManagerRect());
162
- emitter.on("updateManagerRect", () => this.updateManagerRect());
163
- }
164
-
165
- private get mainView() {
166
- return this.context.getMainView();
127
+ }),
128
+ this.teleBoxManager._maximized$.reaction((maximized, skipUpdate) => {
129
+ if (skipUpdate) {
130
+ return;
131
+ }
132
+ this.context.safeSetAttributes({ maximized });
133
+ }),
134
+ this.teleBoxManager.events.on("removed", boxes => {
135
+ boxes.forEach(box => {
136
+ boxEmitter.emit("close", { appId: box.id });
137
+ });
138
+ }),
139
+ this.teleBoxManager.events.on(
140
+ "intrinsic_move",
141
+ debounce((box: ReadonlyTeleBox): void => {
142
+ boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
143
+ }, 50)
144
+ ),
145
+ this.teleBoxManager.events.on(
146
+ "intrinsic_resize",
147
+ debounce((box: ReadonlyTeleBox): void => {
148
+ boxEmitter.emit("resize", {
149
+ appId: box.id,
150
+ width: box.intrinsicWidth,
151
+ height: box.intrinsicHeight,
152
+ });
153
+ }, 200)
154
+ ),
155
+ this.teleBoxManager.events.on("focused", box => {
156
+ if (box) {
157
+ if (this.canOperate) {
158
+ boxEmitter.emit("focus", { appId: box.id });
159
+ } else {
160
+ this.teleBoxManager.blurBox(box.id);
161
+ }
162
+ }
163
+ }),
164
+ this.teleBoxManager.events.on("z_index", box => {
165
+ this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
166
+ }),
167
+ this.teleBoxManager._stageRect$.subscribe(stage => {
168
+ emitter.emit("playgroundSizeChange", stage);
169
+ this.context.notifyContainerRectUpdate(stage);
170
+ }),
171
+ emitter.on("writableChange", isWritable => {
172
+ this.teleBoxManager.setHighlightStage(isWritable);
173
+ }),
174
+ emitter.on("containerSizeRatioUpdate", ratio => {
175
+ this.teleBoxManager._stageRatio$.setValue(ratio);
176
+ }),
177
+ ]);
167
178
  }
168
179
 
169
180
  private get canOperate() {
@@ -194,12 +205,16 @@ export class BoxManager {
194
205
  return this.teleBoxManager.boxes.length;
195
206
  }
196
207
 
197
- public createBox(params: CreateBoxParams): void {
208
+ public get stageRect() {
209
+ return this.teleBoxManager.stageRect;
210
+ }
211
+
212
+ public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
198
213
  if (!this.teleBoxManager) return;
199
214
  let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
200
215
  const { width, height } = params.app.config ?? {};
201
216
  const title = params.options?.title || params.appId;
202
- const rect = this.teleBoxManager.containerRect;
217
+ const rect = this.teleBoxManager.rootRect;
203
218
 
204
219
  if (minwidth > 1) {
205
220
  minwidth = minwidth / rect.width;
@@ -217,40 +232,21 @@ export class BoxManager {
217
232
  height,
218
233
  id: params.appId,
219
234
  };
220
- this.teleBoxManager.create(createBoxConfig, params.smartPosition);
235
+ const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
221
236
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
222
- }
223
-
224
- public setBoxInitState(appId: string): void {
225
- const box = this.teleBoxManager.queryOne({ id: appId });
226
- if (box) {
227
- if (box.state === TELE_BOX_STATE.Maximized) {
228
- this.context.boxEmitter.emit("resize", {
229
- appId: appId,
230
- x: box.x,
231
- y: box.y,
232
- width: box.intrinsicWidth,
233
- height: box.intrinsicHeight,
234
- });
235
- }
236
- }
237
+ return box;
237
238
  }
238
239
 
239
240
  public setupBoxManager(
240
241
  createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
241
242
  ): TeleBoxManager {
242
- const root = WindowManager.wrapper ? WindowManager.wrapper : document.body;
243
- const rect = root.getBoundingClientRect();
243
+ const root = WindowManager.playground;
244
244
  const initManagerState: TeleBoxManagerConfig = {
245
+ stageRatio: createTeleBoxManagerConfig?.stageRatio,
245
246
  root: root,
246
- containerRect: {
247
- x: 0,
248
- y: 0,
249
- width: rect.width,
250
- height: rect.height,
251
- },
252
247
  fence: false,
253
248
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
249
+ highlightStage: createTeleBoxManagerConfig?.highlightStage,
254
250
  };
255
251
 
256
252
  const manager = new TeleBoxManager(initManagerState);
@@ -258,20 +254,16 @@ export class BoxManager {
258
254
  this.teleBoxManager.destroy();
259
255
  }
260
256
  this.teleBoxManager = manager;
261
- const container = createTeleBoxManagerConfig?.collectorContainer || WindowManager.wrapper;
257
+ const container = createTeleBoxManagerConfig?.collectorContainer;
262
258
  if (container) {
263
- this.setCollectorContainer(container);
259
+ this.teleBoxManager.collector.set$collector(container);
260
+ }
261
+ if (createTeleBoxManagerConfig?.collectorStyles) {
262
+ this.teleBoxManager.collector.setStyles(createTeleBoxManagerConfig.collectorStyles);
264
263
  }
265
264
  return manager;
266
265
  }
267
266
 
268
- public setCollectorContainer(container: HTMLElement) {
269
- const collector = new TeleBoxCollector({
270
- styles: this.createTeleBoxManagerConfig?.collectorStyles,
271
- }).mount(container);
272
- this.teleBoxManager.setCollector(collector);
273
- }
274
-
275
267
  public getBox(appId: string): ReadonlyTeleBox | undefined {
276
268
  return this.teleBoxManager.queryOne({ id: appId });
277
269
  }
@@ -324,15 +316,6 @@ export class BoxManager {
324
316
  }
325
317
  }
326
318
 
327
- public updateManagerRect(): void {
328
- const rect = this.mainView.divElement?.getBoundingClientRect();
329
- if (rect && rect.width > 0 && rect.height > 0) {
330
- const containerRect = { x: 0, y: 0, width: rect.width, height: rect.height };
331
- this.teleBoxManager.setContainerRect(containerRect);
332
- this.context.notifyContainerRectUpdate(this.teleBoxManager.containerRect);
333
- }
334
- }
335
-
336
319
  public moveBox({ appId, x, y }: MoveBoxParams): void {
337
320
  this.teleBoxManager.update(appId, { x, y }, true);
338
321
  }
@@ -404,7 +387,16 @@ export class BoxManager {
404
387
  this.teleBoxManager.update(id, { zIndex }, skipUpdate);
405
388
  }
406
389
 
390
+ public setRoot(root: HTMLElement) {
391
+ this.teleBoxManager._root$.setValue(root);
392
+ }
393
+
394
+ public setCollector(collector: HTMLElement) {
395
+ this.teleBoxManager.collector.set$collector(collector);
396
+ }
397
+
407
398
  public destroy() {
399
+ this.sideEffectManager.flushAll();
408
400
  this.teleBoxManager.destroy();
409
401
  }
410
402
  }
@@ -34,9 +34,9 @@ export class CursorManager {
34
34
 
35
35
  constructor(private manager: AppManager, private enableCursor: boolean, applianceIcons?: ApplianceIcons) {
36
36
  this.roomMembers = this.manager.room?.state.roomMembers;
37
- const wrapper = WindowManager.wrapper;
38
- if (wrapper) {
39
- this.setupWrapper(wrapper);
37
+ const playground = WindowManager.playground;
38
+ if (playground) {
39
+ this.setupWrapper(playground);
40
40
  }
41
41
  this.sideEffectManager.add(() => {
42
42
  return emitter.on("cursorMove", this.onCursorMove);
@@ -65,7 +65,7 @@ export class CursorManager {
65
65
  private initCursorInstance = (uid: string) => {
66
66
  let cursorInstance = this.cursorInstances.get(uid);
67
67
  if (!cursorInstance) {
68
- cursorInstance = new Cursor(this.manager, uid, this, WindowManager.wrapper);
68
+ cursorInstance = new Cursor(this.manager, uid, this, WindowManager.playground);
69
69
  this.cursorInstances.set(uid, cursorInstance);
70
70
  }
71
71
  return cursorInstance;
@@ -169,7 +169,7 @@ export class CursorManager {
169
169
 
170
170
  public updateContainerRect() {
171
171
  this.containerRect = WindowManager.container?.getBoundingClientRect();
172
- this.wrapperRect = WindowManager.wrapper?.getBoundingClientRect();
172
+ this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
173
173
  }
174
174
 
175
175
  public deleteCursor(uid: string) {
package/src/Helper.ts CHANGED
@@ -2,36 +2,23 @@ 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 { WindowManager } from "./index";
6
- import type { Room } from "white-web-sdk";
5
+ import type { Room , RoomMember} from "white-web-sdk";
7
6
 
8
7
  export const setupWrapper = (
9
8
  root: HTMLElement
10
9
  ): {
11
10
  playground: HTMLDivElement;
12
- wrapper: HTMLDivElement;
13
- sizer: HTMLDivElement;
14
11
  mainViewElement: HTMLDivElement;
15
12
  } => {
16
13
  const playground = document.createElement("div");
17
14
  playground.className = "netless-window-manager-playground";
18
15
 
19
- const sizer = document.createElement("div");
20
- sizer.className = "netless-window-manager-sizer";
21
-
22
- const wrapper = document.createElement("div");
23
- wrapper.className = "netless-window-manager-wrapper";
24
-
25
16
  const mainViewElement = document.createElement("div");
26
17
  mainViewElement.className = "netless-window-manager-main-view";
27
-
28
- playground.appendChild(sizer);
29
- sizer.appendChild(wrapper);
30
- wrapper.appendChild(mainViewElement);
18
+ playground.appendChild(mainViewElement);
31
19
  root.appendChild(playground);
32
- WindowManager.wrapper = wrapper;
33
20
 
34
- return { playground, wrapper, sizer, mainViewElement };
21
+ return { playground, mainViewElement };
35
22
  };
36
23
 
37
24
  export const checkVersion = () => {
@@ -45,3 +32,12 @@ export const findMemberByUid = (room: Room | undefined, uid: string) => {
45
32
  const roomMembers = room?.state.roomMembers;
46
33
  return roomMembers?.find(member => member.payload?.uid === uid);
47
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
+ }