@netless/window-manager 0.4.30 → 1.0.0-canary.0

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 (44) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/App/AppProxy.d.ts +0 -1
  3. package/dist/AppManager.d.ts +5 -1
  4. package/dist/BoxEmitter.d.ts +34 -0
  5. package/dist/BoxManager.d.ts +8 -6
  6. package/dist/Cursor/index.d.ts +3 -1
  7. package/dist/Helper.d.ts +0 -2
  8. package/dist/InternalEmitter.d.ts +2 -19
  9. package/dist/Utils/AppCreateQueue.d.ts +2 -3
  10. package/dist/View/CameraSynchronizer.d.ts +17 -0
  11. package/dist/View/MainView.d.ts +4 -5
  12. package/dist/index.cjs.js +21 -22
  13. package/dist/index.d.ts +2 -3
  14. package/dist/index.es.js +2283 -1898
  15. package/dist/index.umd.js +21 -22
  16. package/dist/style.css +1 -1
  17. package/dist/typings.d.ts +2 -1
  18. package/docs/api.md +1 -1
  19. package/docs/app-context.md +127 -36
  20. package/docs/develop-app.md +1 -1
  21. package/package.json +5 -4
  22. package/pnpm-lock.yaml +150 -133
  23. package/src/App/AppContext.ts +1 -1
  24. package/src/App/AppProxy.ts +2 -10
  25. package/src/AppManager.ts +67 -59
  26. package/src/BoxEmitter.ts +19 -0
  27. package/src/BoxManager.ts +99 -108
  28. package/src/Cursor/Cursor.ts +3 -3
  29. package/src/Cursor/index.ts +13 -7
  30. package/src/Helper.ts +2 -15
  31. package/src/InternalEmitter.ts +6 -8
  32. package/src/Utils/AppCreateQueue.ts +2 -3
  33. package/src/View/CameraSynchronizer.ts +67 -0
  34. package/src/View/MainView.ts +45 -53
  35. package/src/index.ts +33 -57
  36. package/src/typings.ts +3 -0
  37. package/vite.config.js +0 -1
  38. package/dist/ContainerResizeObserver.d.ts +0 -11
  39. package/dist/ScenePath/index.d.ts +0 -12
  40. package/dist/index.cjs.js.map +0 -1
  41. package/dist/index.es.js.map +0 -1
  42. package/dist/index.umd.js.map +0 -1
  43. package/src/ContainerResizeObserver.ts +0 -73
  44. package/src/ScenePath/index.ts +0 -47
package/src/AppManager.ts CHANGED
@@ -4,6 +4,8 @@ import { AppListeners } from "./AppListener";
4
4
  import { AppProxy } from "./App";
5
5
  import { appRegister } from "./Register";
6
6
  import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
7
+ import { boxEmitter } from "./BoxEmitter";
8
+ import { calculateNextIndex } from "./Page";
7
9
  import { callbacks } from "./callback";
8
10
  import { debounce, get, isInteger, orderBy } from "lodash";
9
11
  import { emitter } from "./InternalEmitter";
@@ -16,7 +18,7 @@ import { RedoUndo } from "./RedoUndo";
16
18
  import { SideEffectManager } from "side-effect-manager";
17
19
  import { ViewManager } from "./View/ViewManager";
18
20
  import type { SyncRegisterAppPayload } from "./Register";
19
- import type { EmitterEvent , RemoveSceneParams } from "./InternalEmitter";
21
+ import type { RemoveSceneParams } from "./InternalEmitter";
20
22
  import {
21
23
  entireScenes,
22
24
  genAppId,
@@ -37,7 +39,14 @@ import type {
37
39
  SceneState,
38
40
  } from "white-web-sdk";
39
41
  import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
40
- import { calculateNextIndex } from "./Page";
42
+ import type {
43
+ BoxClosePayload,
44
+ BoxFocusPayload,
45
+ BoxMovePayload,
46
+ BoxResizePayload,
47
+ BoxStateChangePayload,
48
+ } from "./BoxEmitter";
49
+
41
50
 
42
51
  export class AppManager {
43
52
  public displayer: Displayer;
@@ -202,27 +211,30 @@ export class AppManager {
202
211
  const scene = this.callbacksNode?.scenes[index];
203
212
  setTimeout(() => {
204
213
  if (scene) {
205
- removeScenes(this.room, `${ROOT_DIR}${scene}`, index)
214
+ removeScenes(this.room, `${ROOT_DIR}${scene}`, index);
206
215
  }
207
216
  }, 100);
208
217
  return new Promise<boolean>((resolve, reject) => {
209
- emitter.once("rootDirSceneRemoved").then(name => {
210
- if (name === scene) {
211
- resolve(true);
212
- }
213
- }).catch(e => {
214
- console.log(`[WindowManager]: removePage error: ${e}`);
215
- reject(false);
216
- });
218
+ emitter
219
+ .once("rootDirSceneRemoved")
220
+ .then(name => {
221
+ if (name === scene) {
222
+ resolve(true);
223
+ }
224
+ })
225
+ .catch(e => {
226
+ console.log(`[WindowManager]: removePage error: ${e}`);
227
+ reject(false);
228
+ });
217
229
  });
218
- }
230
+ };
219
231
 
220
232
  public setSceneIndexWithoutSync = (index: number) => {
221
233
  const sceneName = this.callbacksNode?.scenes[index];
222
234
  if (sceneName) {
223
235
  this.mainViewProxy.setFocusScenePath(`${ROOT_DIR}${sceneName}`);
224
236
  }
225
- }
237
+ };
226
238
 
227
239
  private onSceneChange = (node: ScenesCallbacksNode) => {
228
240
  this.mainViewScenesLength = node.scenes.length;
@@ -299,7 +311,11 @@ export class AppManager {
299
311
  private async onCreated() {
300
312
  await this.attributesUpdateCallback(this.attributes.apps);
301
313
  emitter.emit("updateManagerRect");
302
- emitter.onAny(this.boxEventListener);
314
+ boxEmitter.on("move", this.onBoxMove);
315
+ boxEmitter.on("resize", this.onBoxResize);
316
+ boxEmitter.on("focus", this.onBoxFocus);
317
+ boxEmitter.on("close", this.onBoxClose);
318
+ boxEmitter.on("boxStateChange", this.onBoxStateChange);
303
319
 
304
320
  this.addAppsChangeListener();
305
321
  this.addAppCloseListener();
@@ -352,6 +368,39 @@ export class AppManager {
352
368
  });
353
369
  }
354
370
 
371
+ private onBoxMove = (payload: BoxMovePayload) => {
372
+ this.dispatchInternalEvent(Events.AppMove, payload);
373
+ this.store.updateAppState(payload.appId, AppAttributes.Position, {
374
+ x: payload.x,
375
+ y: payload.y,
376
+ });
377
+ };
378
+
379
+ private onBoxResize = (payload: BoxResizePayload) => {
380
+ if (payload.width && payload.height) {
381
+ this.dispatchInternalEvent(Events.AppResize, payload);
382
+ this.store.updateAppState(payload.appId, AppAttributes.Size, {
383
+ width: payload.width,
384
+ height: payload.height,
385
+ });
386
+ }
387
+ };
388
+
389
+ private onBoxFocus = (payload: BoxFocusPayload) => {
390
+ this.windowManger.safeSetAttributes({ focus: payload.appId });
391
+ };
392
+
393
+ private onBoxClose = (payload: BoxClosePayload) => {
394
+ const appProxy = this.appProxies.get(payload.appId);
395
+ if (appProxy) {
396
+ appProxy.destroy(false, true, true, payload.error);
397
+ }
398
+ };
399
+
400
+ private onBoxStateChange = (payload: BoxStateChangePayload) => {
401
+ this.dispatchInternalEvent(Events.AppBoxStateChange, payload);
402
+ };
403
+
355
404
  public addAppsChangeListener = () => {
356
405
  this.refresher?.add("apps", () => {
357
406
  return safeListenPropsUpdated(
@@ -371,7 +420,6 @@ export class AppManager {
371
420
  });
372
421
  };
373
422
 
374
-
375
423
  private onMainViewIndexChange = (index: number) => {
376
424
  if (index !== undefined && this._prevSceneIndex !== index) {
377
425
  callbacks.emit("mainViewSceneIndexChange", index);
@@ -432,7 +480,7 @@ export class AppManager {
432
480
  if (!appAttributes) {
433
481
  throw new Error("appAttributes is undefined");
434
482
  }
435
- this.appCreateQueue.push(() => {
483
+ this.appCreateQueue.push<AppProxy>(() => {
436
484
  this.appStatus.set(id, AppStatus.StartCreate);
437
485
  return this.baseInsertApp(
438
486
  {
@@ -558,7 +606,7 @@ export class AppManager {
558
606
  private afterAddApp(appProxy: AppProxy | undefined) {
559
607
  if (appProxy && appProxy.box) {
560
608
  const box = appProxy.box;
561
- emitter.emit("move", {
609
+ boxEmitter.emit("move", {
562
610
  appId: appProxy.id,
563
611
  x: box?.intrinsicX,
564
612
  y: box?.intrinsicY,
@@ -694,7 +742,7 @@ export class AppManager {
694
742
  if (this.room) {
695
743
  if (this.store.getMainViewSceneIndex() === index) return;
696
744
  const sceneName = this.callbacksNode?.scenes[index];
697
- const scenePath =`${ROOT_DIR}${sceneName}`;
745
+ const scenePath = `${ROOT_DIR}${sceneName}`;
698
746
  if (sceneName) {
699
747
  const success = this.setMainViewFocusPath(scenePath);
700
748
  if (success) {
@@ -727,46 +775,6 @@ export class AppManager {
727
775
  }
728
776
  }
729
777
 
730
- private boxEventListener = (eventName: keyof EmitterEvent, payload: any) => {
731
- switch (eventName) {
732
- case "move": {
733
- this.dispatchInternalEvent(Events.AppMove, payload);
734
- this.store.updateAppState(payload.appId, AppAttributes.Position, {
735
- x: payload.x,
736
- y: payload.y,
737
- });
738
- break;
739
- }
740
- case "focus": {
741
- this.windowManger.safeSetAttributes({ focus: payload.appId });
742
- break;
743
- }
744
- case "resize": {
745
- if (payload.width && payload.height) {
746
- this.dispatchInternalEvent(Events.AppResize, payload);
747
- this.store.updateAppState(payload.appId, AppAttributes.Size, {
748
- width: payload.width,
749
- height: payload.height,
750
- });
751
- }
752
- break;
753
- }
754
- case "close": {
755
- const appProxy = this.appProxies.get(payload.appId);
756
- if (appProxy) {
757
- appProxy.destroy(false, true, payload.error);
758
- }
759
- break;
760
- }
761
- case "boxStateChange": {
762
- this.dispatchInternalEvent(Events.AppBoxStateChange, payload);
763
- break;
764
- }
765
- default:
766
- break;
767
- }
768
- };
769
-
770
778
  public focusByAttributes(apps: any) {
771
779
  if (apps && Object.keys(apps).length === this.boxManager?.boxSize) {
772
780
  const focusAppId = this.store.focus;
@@ -806,7 +814,7 @@ export class AppManager {
806
814
  this.displayer.callbacks.off(this.eventName, this.displayerStateListener);
807
815
  this.displayer.callbacks.off("onEnableWriteNowChanged", this.displayerWritableListener);
808
816
  this.appListeners.removeListeners();
809
- emitter.offAny(this.boxEventListener);
817
+ boxEmitter.clearListeners();
810
818
  emitter.clearListeners();
811
819
  if (this.appProxies.size) {
812
820
  this.appProxies.forEach(appProxy => {
@@ -0,0 +1,19 @@
1
+ import type { TELE_BOX_STATE } from "@netless/telebox-insider";
2
+ import Emittery from "emittery";
3
+
4
+ export type BoxMovePayload = { appId: string, x: number; y: number };
5
+ export type BoxFocusPayload = { appId: string };
6
+ export type BoxResizePayload = { appId: string, width: number; height: number, x?: number, y?: number };
7
+ export type BoxClosePayload = { appId: string, error?: Error };
8
+ export type BoxStateChangePayload = { appId: string, state: TELE_BOX_STATE };
9
+
10
+ export type BoxEvent = {
11
+ move: BoxMovePayload;
12
+ focus: BoxFocusPayload;
13
+ resize: BoxResizePayload;
14
+ close: BoxClosePayload;
15
+ boxStateChange: BoxStateChangePayload
16
+ }
17
+
18
+ export type BoxEmitterType = Emittery<BoxEvent>;
19
+ export const boxEmitter: BoxEmitterType = new Emittery();
package/src/BoxManager.ts CHANGED
@@ -1,7 +1,8 @@
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
+ import type { BoxEmitterType } from "./BoxEmitter";
5
6
  import type { AddAppOptions, AppInitState } from "./index";
6
7
  import type {
7
8
  TeleBoxManagerUpdateConfig,
@@ -17,6 +18,7 @@ import type { NetlessApp } from "./typings";
17
18
  import type { View } from "white-web-sdk";
18
19
  import type { CallbacksType } from "./callback";
19
20
  import type { EmitterType } from "./InternalEmitter";
21
+ import { SideEffectManager } from "side-effect-manager";
20
22
 
21
23
  export { TELE_BOX_STATE };
22
24
 
@@ -44,6 +46,7 @@ export type CreateTeleBoxManagerConfig = {
44
46
  collectorContainer?: HTMLElement;
45
47
  collectorStyles?: Partial<CSSStyleDeclaration>;
46
48
  prefersColorScheme?: TeleBoxColorScheme;
49
+ stageRatio?: number;
47
50
  };
48
51
 
49
52
  export type BoxManagerContext = {
@@ -51,6 +54,7 @@ export type BoxManagerContext = {
51
54
  getMainView: () => View;
52
55
  updateAppState: (appId: string, field: AppAttributes, value: any) => void;
53
56
  emitter: EmitterType;
57
+ boxEmitter: BoxEmitterType;
54
58
  callbacks: CallbacksType;
55
59
  canOperate: () => boolean;
56
60
  notifyContainerRectUpdate: (rect: TeleBoxRect) => void;
@@ -62,6 +66,7 @@ export const createBoxManager = (
62
66
  manager: WindowManager,
63
67
  callbacks: CallbacksType,
64
68
  emitter: EmitterType,
69
+ boxEmitter: BoxEmitterType,
65
70
  options: CreateTeleBoxManagerConfig
66
71
  ) => {
67
72
  return new BoxManager(
@@ -76,6 +81,7 @@ export const createBoxManager = (
76
81
  setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
77
82
  callbacks,
78
83
  emitter,
84
+ boxEmitter
79
85
  },
80
86
  options
81
87
  );
@@ -83,79 +89,93 @@ export const createBoxManager = (
83
89
 
84
90
  export class BoxManager {
85
91
  public teleBoxManager: TeleBoxManager;
92
+ protected sideEffectManager: SideEffectManager;
86
93
 
87
94
  constructor(
88
95
  private context: BoxManagerContext,
89
- private createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
96
+ createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
90
97
  ) {
91
- const { emitter, callbacks } = context;
98
+ this.sideEffectManager = new SideEffectManager();
99
+ const { emitter, callbacks, boxEmitter } = context;
92
100
  this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
93
-
94
- // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
95
- this.teleBoxManager._state$.reaction(state => {
96
- callbacks.emit("boxStateChange", state);
97
- emitter.emit("boxStateChange", state);
98
- });
99
-
100
- this.teleBoxManager._darkMode$.reaction(darkMode => {
101
- callbacks.emit("darkModeChange", darkMode);
102
- });
103
- this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
104
- callbacks.emit("prefersColorSchemeChange", colorScheme);
105
- });
106
-
107
- // events.on 的值则会根据 skipUpdate 来决定是否触发回调
108
- this.teleBoxManager.events.on("minimized", minimized => {
109
- this.context.safeSetAttributes({ minimized });
110
- if (minimized) {
111
- this.context.cleanFocus();
112
- this.blurAllBox();
113
- } else {
114
- const topBox = this.getTopBox();
115
- if (topBox) {
116
- this.context.setAppFocus(topBox.id);
117
- this.focusBox({ appId: topBox.id }, false);
101
+ this.sideEffectManager.add(() => [
102
+ // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
103
+ this.teleBoxManager._state$.reaction(state => {
104
+ callbacks.emit("boxStateChange", state);
105
+ emitter.emit("boxStateChange", state);
106
+ }),
107
+ this.teleBoxManager._darkMode$.reaction(darkMode => {
108
+ callbacks.emit("darkModeChange", darkMode);
109
+ }),
110
+ this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
111
+ callbacks.emit("prefersColorSchemeChange", colorScheme);
112
+ }),
113
+ this.teleBoxManager._minimized$.reaction((minimized, skipUpdate) => {
114
+ if (skipUpdate) {
115
+ return;
118
116
  }
119
- }
120
- });
121
- this.teleBoxManager.events.on("maximized", maximized => {
122
- this.context.safeSetAttributes({ maximized });
123
- });
124
- this.teleBoxManager.events.on("removed", boxes => {
125
- boxes.forEach(box => {
126
- emitter.emit("close", { appId: box.id });
127
- });
128
- });
129
- this.teleBoxManager.events.on(
130
- "intrinsic_move",
131
- debounce((box: ReadonlyTeleBox): void => {
132
- emitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
133
- }, 50)
134
- );
135
- this.teleBoxManager.events.on(
136
- "intrinsic_resize",
137
- debounce((box: ReadonlyTeleBox): void => {
138
- emitter.emit("resize", {
139
- appId: box.id,
140
- width: box.intrinsicWidth,
141
- height: box.intrinsicHeight,
142
- });
143
- }, 200)
144
- );
145
- this.teleBoxManager.events.on("focused", box => {
146
- if (box) {
147
- if (this.canOperate) {
148
- emitter.emit("focus", { appId: box.id });
117
+ this.context.safeSetAttributes({ minimized });
118
+ if (minimized) {
119
+ this.context.cleanFocus();
120
+ this.blurAllBox();
149
121
  } else {
150
- this.teleBoxManager.blurBox(box.id);
122
+ const topBox = this.getTopBox();
123
+ if (topBox) {
124
+ this.context.setAppFocus(topBox.id);
125
+ this.focusBox({ appId: topBox.id }, false);
126
+ }
151
127
  }
152
- }
153
- });
154
- this.teleBoxManager.events.on("z_index", box => {
155
- this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
156
- });
157
- emitter.on("playgroundSizeChange", () => this.updateManagerRect());
158
- emitter.on("updateManagerRect", () => this.updateManagerRect());
128
+ }),
129
+ this.teleBoxManager._maximized$.reaction((maximized, skipUpdate) => {
130
+ if (skipUpdate) {
131
+ return;
132
+ }
133
+ this.context.safeSetAttributes({ maximized });
134
+ }),
135
+ this.teleBoxManager.events.on("removed", boxes => {
136
+ boxes.forEach(box => {
137
+ boxEmitter.emit("close", { appId: box.id });
138
+ });
139
+ }),
140
+ this.teleBoxManager.events.on(
141
+ "intrinsic_move",
142
+ debounce((box: ReadonlyTeleBox): void => {
143
+ boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
144
+ }, 50)
145
+ ),
146
+ this.teleBoxManager.events.on(
147
+ "intrinsic_resize",
148
+ debounce((box: ReadonlyTeleBox): void => {
149
+ boxEmitter.emit("resize", {
150
+ appId: box.id,
151
+ width: box.intrinsicWidth,
152
+ height: box.intrinsicHeight,
153
+ });
154
+ }, 200)
155
+ ),
156
+ this.teleBoxManager.events.on("focused", box => {
157
+ if (box) {
158
+ if (this.canOperate) {
159
+ boxEmitter.emit("focus", { appId: box.id });
160
+ } else {
161
+ this.teleBoxManager.blurBox(box.id);
162
+ }
163
+ }
164
+ }),
165
+ this.teleBoxManager.events.on("z_index", box => {
166
+ this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
167
+ }),
168
+ this.teleBoxManager._stageRect$.subscribe(stage => {
169
+ emitter.emit("playgroundSizeChange", stage);
170
+ this.context.notifyContainerRectUpdate(stage);
171
+ }),
172
+ emitter.on("writableChange", isWritable => {
173
+ this.teleBoxManager.setHighlightStage(isWritable);
174
+ }),
175
+ emitter.on("containerSizeRatioUpdate", ratio => {
176
+ this.teleBoxManager._stageRatio$.setValue(ratio);
177
+ }),
178
+ ]);
159
179
  }
160
180
 
161
181
  private get mainView() {
@@ -195,7 +215,7 @@ export class BoxManager {
195
215
  let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
196
216
  const { width, height } = params.app.config ?? {};
197
217
  const title = params.options?.title || params.appId;
198
- const rect = this.teleBoxManager.containerRect;
218
+ const rect = this.teleBoxManager.rootRect;
199
219
 
200
220
  if (minwidth > 1) {
201
221
  minwidth = minwidth / rect.width;
@@ -217,34 +237,13 @@ export class BoxManager {
217
237
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
218
238
  }
219
239
 
220
- public setBoxInitState(appId: string): void {
221
- const box = this.teleBoxManager.queryOne({ id: appId });
222
- if (box) {
223
- if (box.state === TELE_BOX_STATE.Maximized) {
224
- this.context.emitter.emit("resize", {
225
- appId: appId,
226
- x: box.x,
227
- y: box.y,
228
- width: box.intrinsicWidth,
229
- height: box.intrinsicHeight,
230
- });
231
- }
232
- }
233
- }
234
-
235
240
  public setupBoxManager(
236
241
  createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
237
242
  ): TeleBoxManager {
238
- const root = WindowManager.wrapper ? WindowManager.wrapper : document.body;
239
- const rect = root.getBoundingClientRect();
243
+ const root = WindowManager.playground;
240
244
  const initManagerState: TeleBoxManagerConfig = {
245
+ stageRatio: 3 / 4,
241
246
  root: root,
242
- containerRect: {
243
- x: 0,
244
- y: 0,
245
- width: rect.width,
246
- height: rect.height,
247
- },
248
247
  fence: false,
249
248
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
250
249
  };
@@ -254,20 +253,16 @@ export class BoxManager {
254
253
  this.teleBoxManager.destroy();
255
254
  }
256
255
  this.teleBoxManager = manager;
257
- const container = createTeleBoxManagerConfig?.collectorContainer || WindowManager.wrapper;
256
+ const container = createTeleBoxManagerConfig?.collectorContainer;
258
257
  if (container) {
259
- this.setCollectorContainer(container);
258
+ this.teleBoxManager.collector.set$collector(container);
259
+ }
260
+ if (createTeleBoxManagerConfig?.collectorStyles) {
261
+ this.teleBoxManager.collector.setStyles(createTeleBoxManagerConfig.collectorStyles);
260
262
  }
261
263
  return manager;
262
264
  }
263
265
 
264
- public setCollectorContainer(container: HTMLElement) {
265
- const collector = new TeleBoxCollector({
266
- styles: this.createTeleBoxManagerConfig?.collectorStyles,
267
- }).mount(container);
268
- this.teleBoxManager.setCollector(collector);
269
- }
270
-
271
266
  public getBox(appId: string): ReadonlyTeleBox | undefined {
272
267
  return this.teleBoxManager.queryOne({ id: appId });
273
268
  }
@@ -320,15 +315,6 @@ export class BoxManager {
320
315
  }
321
316
  }
322
317
 
323
- public updateManagerRect(): void {
324
- const rect = this.mainView.divElement?.getBoundingClientRect();
325
- if (rect && rect.width > 0 && rect.height > 0) {
326
- const containerRect = { x: 0, y: 0, width: rect.width, height: rect.height };
327
- this.teleBoxManager.setContainerRect(containerRect);
328
- this.context.notifyContainerRectUpdate(this.teleBoxManager.containerRect);
329
- }
330
- }
331
-
332
318
  public moveBox({ appId, x, y }: MoveBoxParams): void {
333
319
  this.teleBoxManager.update(appId, { x, y }, true);
334
320
  }
@@ -400,7 +386,12 @@ export class BoxManager {
400
386
  this.teleBoxManager.update(id, { zIndex }, skipUpdate);
401
387
  }
402
388
 
389
+ public setRoot(root: HTMLElement) {
390
+ this.teleBoxManager._root$.setValue(root);
391
+ }
392
+
403
393
  public destroy() {
394
+ this.sideEffectManager.flushAll();
404
395
  this.teleBoxManager.destroy();
405
396
  }
406
397
  }
@@ -1,5 +1,4 @@
1
1
  import App from "./Cursor.svelte";
2
- import { ApplianceMap } from "./icons";
3
2
  import { ApplianceNames } from "white-web-sdk";
4
3
  import { findMemberByUid } from "../Helper";
5
4
  import { omit } from "lodash";
@@ -159,8 +158,9 @@ export class Cursor {
159
158
 
160
159
  private getIcon() {
161
160
  if (this.member) {
162
- const applianceSrc = ApplianceMap[this.memberApplianceName || ApplianceNames.shape];
163
- return applianceSrc || ApplianceMap[ApplianceNames.shape];
161
+ const icons = this.cursorManager.applianceIcons;
162
+ const applianceSrc = icons[this.memberApplianceName || ApplianceNames.shape];
163
+ return applianceSrc || icons[ApplianceNames.shape];
164
164
  }
165
165
  }
166
166
 
@@ -5,10 +5,11 @@ import { emitter } from "../InternalEmitter";
5
5
  import { SideEffectManager } from "side-effect-manager";
6
6
  import { throttle } from "lodash";
7
7
  import { WindowManager } from "../index";
8
- import type { CursorMovePayload } from "../index";
8
+ import type { CursorMovePayload , ApplianceIcons} from "../index";
9
9
  import type { PositionType } from "../AttributesDelegate";
10
10
  import type { Point, RoomMember, View } from "white-web-sdk";
11
11
  import type { AppManager } from "../AppManager";
12
+ import { ApplianceMap } from "./icons";
12
13
 
13
14
  export type EventType = {
14
15
  type: PositionType;
@@ -20,6 +21,7 @@ export type MoveCursorParams = {
20
21
  x: number;
21
22
  y: number;
22
23
  };
24
+
23
25
  export class CursorManager {
24
26
  public containerRect?: DOMRect;
25
27
  public wrapperRect?: DOMRect;
@@ -28,12 +30,13 @@ export class CursorManager {
28
30
  private mainViewElement?: HTMLDivElement;
29
31
  private sideEffectManager = new SideEffectManager();
30
32
  private store = this.manager.store;
33
+ public applianceIcons: ApplianceIcons = ApplianceMap;
31
34
 
32
- constructor(private manager: AppManager, private enableCursor: boolean) {
35
+ constructor(private manager: AppManager, private enableCursor: boolean, applianceIcons?: ApplianceIcons) {
33
36
  this.roomMembers = this.manager.room?.state.roomMembers;
34
- const wrapper = WindowManager.wrapper;
35
- if (wrapper) {
36
- this.setupWrapper(wrapper);
37
+ const playground = WindowManager.playground;
38
+ if (playground) {
39
+ this.setupWrapper(playground);
37
40
  }
38
41
  this.sideEffectManager.add(() => {
39
42
  return emitter.on("cursorMove", this.onCursorMove);
@@ -42,6 +45,9 @@ export class CursorManager {
42
45
  this.sideEffectManager.add(() => {
43
46
  return emitter.on("playgroundSizeChange", () => this.updateContainerRect());
44
47
  });
48
+ if (applianceIcons) {
49
+ this.applianceIcons = { ...ApplianceMap, ...applianceIcons };
50
+ }
45
51
  }
46
52
 
47
53
  private onCursorMove = (payload: CursorMovePayload) => {
@@ -59,7 +65,7 @@ export class CursorManager {
59
65
  private initCursorInstance = (uid: string) => {
60
66
  let cursorInstance = this.cursorInstances.get(uid);
61
67
  if (!cursorInstance) {
62
- cursorInstance = new Cursor(this.manager, uid, this, WindowManager.wrapper);
68
+ cursorInstance = new Cursor(this.manager, uid, this, WindowManager.playground);
63
69
  this.cursorInstances.set(uid, cursorInstance);
64
70
  }
65
71
  return cursorInstance;
@@ -163,7 +169,7 @@ export class CursorManager {
163
169
 
164
170
  public updateContainerRect() {
165
171
  this.containerRect = WindowManager.container?.getBoundingClientRect();
166
- this.wrapperRect = WindowManager.wrapper?.getBoundingClientRect();
172
+ this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
167
173
  }
168
174
 
169
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
5
  import type { Room } 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 = () => {