@netless/window-manager 1.0.0-canary.9 → 1.0.1

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 (132) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +90 -64
  3. package/README.zh-cn.md +224 -0
  4. package/dist/index.d.ts +1133 -40
  5. package/dist/index.js +62 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/{index.es.js → index.mjs} +7954 -5445
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/style.css +1 -1
  10. package/docs/advanced.md +55 -55
  11. package/docs/api.md +126 -113
  12. package/docs/app-context.md +248 -209
  13. package/docs/basic.md +25 -26
  14. package/docs/camera.md +21 -21
  15. package/docs/cn/advanced.md +137 -0
  16. package/docs/cn/api.md +311 -0
  17. package/docs/cn/app-context.md +369 -0
  18. package/docs/cn/basic.md +64 -0
  19. package/docs/cn/camera.md +53 -0
  20. package/docs/cn/concept.md +9 -0
  21. package/docs/cn/custom-max-bar.md +31 -0
  22. package/docs/cn/develop-app.md +94 -0
  23. package/docs/cn/export-pdf.md +48 -0
  24. package/docs/cn/migrate.md +60 -0
  25. package/docs/cn/replay.md +40 -0
  26. package/docs/concept.md +6 -5
  27. package/docs/custom-max-bar.md +31 -0
  28. package/docs/develop-app.md +22 -19
  29. package/docs/export-pdf.md +48 -0
  30. package/docs/migrate.md +25 -27
  31. package/docs/quickstart.md +50 -0
  32. package/docs/replay.md +20 -20
  33. package/package.json +32 -22
  34. package/src/App/AppContext.ts +105 -73
  35. package/src/App/AppPageStateImpl.ts +6 -25
  36. package/src/App/AppProxy.ts +41 -166
  37. package/src/App/MagixEvent/index.ts +38 -38
  38. package/src/App/Storage/StorageEvent.ts +13 -13
  39. package/src/App/Storage/index.ts +269 -245
  40. package/src/App/Storage/typings.ts +4 -2
  41. package/src/App/Storage/utils.ts +3 -3
  42. package/src/App/index.ts +0 -1
  43. package/src/AppListener.ts +8 -8
  44. package/src/AppManager.ts +88 -77
  45. package/src/AttributesDelegate.ts +42 -22
  46. package/src/BoxEmitter.ts +12 -6
  47. package/src/BoxManager.ts +128 -108
  48. package/src/ContainerResizeObserver.ts +75 -0
  49. package/src/Cursor/Cursor.svelte +16 -5
  50. package/src/Cursor/Cursor.svelte.d.ts +21 -0
  51. package/src/Cursor/Cursor.ts +77 -13
  52. package/src/Cursor/icons.ts +6 -0
  53. package/src/Cursor/icons2.ts +66 -0
  54. package/src/Cursor/index.ts +127 -26
  55. package/src/Helper.ts +94 -14
  56. package/src/InternalEmitter.ts +2 -7
  57. package/src/Page/index.ts +1 -1
  58. package/src/PageState.ts +6 -5
  59. package/src/ReconnectRefresher.ts +9 -4
  60. package/src/RedoUndo.ts +3 -3
  61. package/src/Register/index.ts +22 -17
  62. package/src/Register/loader.ts +26 -22
  63. package/src/Register/storage.ts +13 -13
  64. package/src/Utils/Common.ts +18 -14
  65. package/src/Utils/Reactive.ts +26 -25
  66. package/src/Utils/RoomHacker.ts +4 -4
  67. package/src/Utils/error.ts +0 -1
  68. package/src/View/IframeBridge.ts +680 -0
  69. package/src/View/MainView.ts +127 -53
  70. package/src/callback.ts +21 -1
  71. package/src/constants.ts +0 -2
  72. package/src/image/pencil-eraser-1.svg +3 -0
  73. package/src/image/pencil-eraser-2.svg +3 -0
  74. package/src/image/pencil-eraser-3.svg +3 -0
  75. package/src/index.ts +220 -83
  76. package/src/style.css +27 -10
  77. package/src/typings.ts +20 -10
  78. package/.prettierignore +0 -7
  79. package/.prettierrc.json +0 -9
  80. package/CHANGELOG.md +0 -196
  81. package/__mocks__/white-web-sdk.ts +0 -50
  82. package/dist/App/AppContext.d.ts +0 -76
  83. package/dist/App/AppPageStateImpl.d.ts +0 -21
  84. package/dist/App/AppProxy.d.ts +0 -86
  85. package/dist/App/AppViewSync.d.ts +0 -11
  86. package/dist/App/MagixEvent/index.d.ts +0 -29
  87. package/dist/App/Storage/StorageEvent.d.ts +0 -8
  88. package/dist/App/Storage/index.d.ts +0 -39
  89. package/dist/App/Storage/typings.d.ts +0 -22
  90. package/dist/App/Storage/utils.d.ts +0 -5
  91. package/dist/App/WhiteboardView.d.ts +0 -22
  92. package/dist/App/index.d.ts +0 -3
  93. package/dist/AppListener.d.ts +0 -21
  94. package/dist/AppManager.d.ts +0 -107
  95. package/dist/AttributesDelegate.d.ts +0 -80
  96. package/dist/BoxEmitter.d.ts +0 -34
  97. package/dist/BoxManager.d.ts +0 -99
  98. package/dist/BuiltinApps.d.ts +0 -5
  99. package/dist/Cursor/Cursor.d.ts +0 -39
  100. package/dist/Cursor/icons.d.ts +0 -3
  101. package/dist/Cursor/index.d.ts +0 -46
  102. package/dist/Helper.d.ts +0 -17
  103. package/dist/InternalEmitter.d.ts +0 -39
  104. package/dist/Page/PageController.d.ts +0 -21
  105. package/dist/Page/index.d.ts +0 -3
  106. package/dist/PageState.d.ts +0 -9
  107. package/dist/ReconnectRefresher.d.ts +0 -24
  108. package/dist/RedoUndo.d.ts +0 -18
  109. package/dist/Register/index.d.ts +0 -28
  110. package/dist/Register/loader.d.ts +0 -4
  111. package/dist/Register/storage.d.ts +0 -8
  112. package/dist/Utils/AppCreateQueue.d.ts +0 -15
  113. package/dist/Utils/Common.d.ts +0 -23
  114. package/dist/Utils/Reactive.d.ts +0 -6
  115. package/dist/Utils/RoomHacker.d.ts +0 -3
  116. package/dist/Utils/error.d.ts +0 -27
  117. package/dist/Utils/log.d.ts +0 -1
  118. package/dist/View/CameraSynchronizer.d.ts +0 -16
  119. package/dist/View/MainView.d.ts +0 -47
  120. package/dist/View/ViewManager.d.ts +0 -13
  121. package/dist/callback.d.ts +0 -24
  122. package/dist/constants.d.ts +0 -49
  123. package/dist/index.cjs.js +0 -46
  124. package/dist/index.umd.js +0 -46
  125. package/dist/typings.d.ts +0 -82
  126. package/jest.config.js +0 -27
  127. package/pnpm-lock.yaml +0 -6302
  128. package/src/App/AppViewSync.ts +0 -68
  129. package/src/App/WhiteboardView.ts +0 -83
  130. package/src/View/CameraSynchronizer.ts +0 -56
  131. package/vite.config.js +0 -51
  132. /package/docs/{qickstart.md → cn/quickstart.md} +0 -0
package/src/AppManager.ts CHANGED
@@ -3,22 +3,20 @@ 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, toJS } from "white-web-sdk";
6
+ import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
7
7
  import { boxEmitter } from "./BoxEmitter";
8
8
  import { calculateNextIndex } from "./Page";
9
9
  import { callbacks } from "./callback";
10
10
  import { debounce, get, isInteger, orderBy } from "lodash";
11
- import { emitter } from "./InternalEmitter";
11
+ import { internalEmitter } from "./InternalEmitter";
12
12
  import { Fields, store } from "./AttributesDelegate";
13
13
  import { log } from "./Utils/log";
14
14
  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";
19
18
  import { SideEffectManager } from "side-effect-manager";
20
19
  import { ViewManager } from "./View/ViewManager";
21
- import { Val } from "value-enhancer";
22
20
  import type { SyncRegisterAppPayload } from "./Register";
23
21
  import type { RemoveSceneParams } from "./InternalEmitter";
24
22
  import {
@@ -39,6 +37,7 @@ import type {
39
37
  ScenesCallbacksNode,
40
38
  SceneState,
41
39
  RoomState,
40
+ MemberState,
42
41
  } from "white-web-sdk";
43
42
  import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
44
43
  import type {
@@ -48,7 +47,6 @@ import type {
48
47
  BoxResizePayload,
49
48
  BoxStateChangePayload,
50
49
  } from "./BoxEmitter";
51
- import type { Member } from "./Helper";
52
50
 
53
51
  export class AppManager {
54
52
  public displayer: Displayer;
@@ -64,10 +62,10 @@ export class AppManager {
64
62
  private appListeners: AppListeners;
65
63
  public boxManager?: BoxManager;
66
64
 
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);
71
69
 
72
70
  private sideEffectManager = new SideEffectManager();
73
71
 
@@ -91,29 +89,27 @@ export class AppManager {
91
89
 
92
90
  this.refresher = reconnectRefresher;
93
91
  this.refresher.setRoom(this.room);
94
- this.refresher.setContext({ emitter });
95
-
96
- this.sideEffectManager.add(() => {
97
- return () => {
98
- this.appCreateQueue.destroy();
99
- this.mainViewProxy.destroy();
100
- this.refresher?.destroy();
101
- this.viewManager.destroy();
102
- this.boxManager?.destroy();
103
- this.callbacksNode?.dispose();
104
- };
92
+ this.refresher.setContext({ emitter: internalEmitter });
93
+
94
+ this.sideEffectManager.addDisposer(() => {
95
+ this.appCreateQueue.destroy();
96
+ this.mainViewProxy.destroy();
97
+ this.refresher.destroy();
98
+ this.viewManager.destroy();
99
+ this.boxManager?.destroy();
100
+ this.callbacksNode?.dispose();
105
101
  });
106
102
 
107
- emitter.once("onCreated").then(() => this.onCreated());
108
- emitter.on("onReconnected", () => this.onReconnected());
103
+ internalEmitter.once("onCreated").then(() => this.onCreated());
104
+ internalEmitter.on("onReconnected", () => this.onReconnected());
109
105
 
110
106
  if (isPlayer(this.displayer)) {
111
- emitter.on("seekStart", this.onPlayerSeekStart);
112
- emitter.on("seek", this.onPlayerSeekDone);
107
+ internalEmitter.on("seekStart", this.onPlayerSeekStart);
108
+ internalEmitter.on("seek", this.onPlayerSeekDone);
113
109
  }
114
110
 
115
- emitter.on("removeScenes", this.onRemoveScenes);
116
- emitter.on("setReadonly", this.onReadonlyChanged);
111
+ internalEmitter.on("removeScenes", this.onRemoveScenes);
112
+ internalEmitter.on("setReadonly", this.onReadonlyChanged);
117
113
 
118
114
  this.createRootDirScenesCallback();
119
115
 
@@ -122,6 +118,10 @@ export class AppManager {
122
118
  });
123
119
  }
124
120
 
121
+ public getMemberState(): MemberState {
122
+ return this.room?.state.memberState || ({ strokeColor: [0, 0, 0] } as MemberState);
123
+ }
124
+
125
125
  private onRemoveScenes = async (params: RemoveSceneParams) => {
126
126
  const { scenePath } = params;
127
127
  // 如果移除根目录就把 scenePath 设置为初始值
@@ -163,7 +163,7 @@ export class AppManager {
163
163
  }
164
164
  // 删除了根目录的 scenes 之后 mainview 需要重新绑定, 否则主白板会不能渲染
165
165
  this.mainViewProxy.rebind();
166
- emitter.emit("rootDirRemoved");
166
+ internalEmitter.emit("rootDirRemoved");
167
167
  this.updateRootDirRemoving(false);
168
168
  }
169
169
 
@@ -194,7 +194,7 @@ export class AppManager {
194
194
  onAddScene: this.onSceneChange,
195
195
  onRemoveScene: async (node, name) => {
196
196
  await this.onSceneChange(node);
197
- emitter.emit("rootDirSceneRemoved", name);
197
+ internalEmitter.emit("rootDirSceneRemoved", name);
198
198
  },
199
199
  });
200
200
  if (this.callbacksNode) {
@@ -217,7 +217,7 @@ export class AppManager {
217
217
  }
218
218
  }, 100);
219
219
  return new Promise<boolean>((resolve, reject) => {
220
- emitter
220
+ internalEmitter
221
221
  .once("rootDirSceneRemoved")
222
222
  .then(name => {
223
223
  if (name === scene) {
@@ -247,7 +247,7 @@ export class AppManager {
247
247
  private emitMainViewScenesChange = (length: number) => {
248
248
  return Promise.all([
249
249
  callbacks.emit("mainViewScenesLengthChange", length),
250
- emitter.emit("changePageState"),
250
+ internalEmitter.emit("changePageState"),
251
251
  ]);
252
252
  };
253
253
 
@@ -291,6 +291,14 @@ export class AppManager {
291
291
  return this.mainViewProxy.view;
292
292
  }
293
293
 
294
+ public get polling() {
295
+ return this.mainViewProxy.polling;
296
+ }
297
+
298
+ public set polling(b: boolean) {
299
+ this.mainViewProxy.polling = b;
300
+ }
301
+
294
302
  public get focusApp() {
295
303
  if (this.store.focus) {
296
304
  return this.appProxies.get(this.store.focus);
@@ -301,10 +309,6 @@ export class AppManager {
301
309
  return this.room?.uid || "";
302
310
  }
303
311
 
304
- public get members(): Member[] {
305
- return serializeRoomMembers(this.displayer.state.roomMembers);
306
- }
307
-
308
312
  public getMainViewSceneDir() {
309
313
  const scenePath = this.store.getMainViewScenePath();
310
314
  if (scenePath) {
@@ -316,7 +320,7 @@ export class AppManager {
316
320
 
317
321
  private async onCreated() {
318
322
  await this.attributesUpdateCallback(this.attributes.apps);
319
- emitter.emit("updateManagerRect");
323
+ internalEmitter.emit("updateManagerRect");
320
324
  boxEmitter.on("move", this.onBoxMove);
321
325
  boxEmitter.on("resize", this.onBoxResize);
322
326
  boxEmitter.on("focus", this.onBoxFocus);
@@ -362,7 +366,7 @@ export class AppManager {
362
366
  }
363
367
  this.displayerWritableListener(!this.room?.isWritable);
364
368
  this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
365
- this.focused$.setValue(this.attributes.focus);
369
+ this._prevFocused = this.attributes.focus;
366
370
 
367
371
  this.sideEffectManager.add(() => {
368
372
  const redoUndo = new RedoUndo({
@@ -380,6 +384,7 @@ export class AppManager {
380
384
  x: payload.x,
381
385
  y: payload.y,
382
386
  });
387
+ callbacks.emit("onBoxMove", payload);
383
388
  };
384
389
 
385
390
  private onBoxResize = (payload: BoxResizePayload) => {
@@ -389,11 +394,13 @@ export class AppManager {
389
394
  width: payload.width,
390
395
  height: payload.height,
391
396
  });
397
+ callbacks.emit("onBoxResize", payload);
392
398
  }
393
399
  };
394
400
 
395
401
  private onBoxFocus = (payload: BoxFocusPayload) => {
396
402
  this.windowManger.safeSetAttributes({ focus: payload.appId });
403
+ callbacks.emit("onBoxFocus", payload);
397
404
  };
398
405
 
399
406
  private onBoxClose = (payload: BoxClosePayload) => {
@@ -401,14 +408,16 @@ export class AppManager {
401
408
  if (appProxy) {
402
409
  appProxy.destroy(false, true, true, payload.error);
403
410
  }
411
+ callbacks.emit("onBoxClose", payload);
404
412
  };
405
413
 
406
414
  private onBoxStateChange = (payload: BoxStateChangePayload) => {
407
415
  this.dispatchInternalEvent(Events.AppBoxStateChange, payload);
416
+ callbacks.emit("onBoxStateChange", payload);
408
417
  };
409
418
 
410
419
  public addAppsChangeListener = () => {
411
- this.refresher?.add("apps", () => {
420
+ this.refresher.add("apps", () => {
412
421
  return safeListenPropsUpdated(
413
422
  () => this.attributes.apps,
414
423
  () => {
@@ -419,7 +428,7 @@ export class AppManager {
419
428
  };
420
429
 
421
430
  public addAppCloseListener = () => {
422
- this.refresher?.add("appsClose", () => {
431
+ this.refresher.add("appsClose", () => {
423
432
  return onObjectRemoved(this.attributes.apps, () => {
424
433
  this.onAppDelete(this.attributes.apps);
425
434
  });
@@ -427,21 +436,21 @@ export class AppManager {
427
436
  };
428
437
 
429
438
  private onMainViewIndexChange = (index: number) => {
430
- if (index !== undefined && this.sceneIndex$.value !== index) {
439
+ if (index !== undefined && this._prevSceneIndex !== index) {
431
440
  callbacks.emit("mainViewSceneIndexChange", index);
432
- emitter.emit("changePageState");
441
+ internalEmitter.emit("changePageState");
433
442
  if (this.callbacksNode) {
434
443
  this.updateSceneState(this.callbacksNode);
435
444
  }
436
- this.sceneIndex$.setValue(index);
445
+ this._prevSceneIndex = index;
437
446
  }
438
447
  };
439
448
 
440
449
  private onFocusChange = (focused: string | undefined) => {
441
- if (this.focused$.value !== focused) {
450
+ if (this._prevFocused !== focused) {
442
451
  callbacks.emit("focusedChange", focused);
443
- emitter.emit("focusedChange", { focused, prev: this.focused$.value });
444
- this.focused$.setValue(focused);
452
+ internalEmitter.emit("focusedChange", { focused, prev: this._prevFocused });
453
+ this._prevFocused = focused;
445
454
  if (focused !== undefined) {
446
455
  this.boxManager?.focusBox({ appId: focused });
447
456
  // 确保 focus 修改的时候, appProxy 已经创建
@@ -460,6 +469,17 @@ export class AppManager {
460
469
  100
461
470
  );
462
471
 
472
+ private _appIds: string[] = [];
473
+ public notifyAppsChange(appIds: string[]): void {
474
+ if (
475
+ this._appIds.length !== appIds.length ||
476
+ !this._appIds.every(id => appIds.includes(id))
477
+ ) {
478
+ this._appIds = appIds;
479
+ callbacks.emit("appsChange", appIds);
480
+ }
481
+ }
482
+
463
483
  /**
464
484
  * 插件更新 attributes 时的回调
465
485
  *
@@ -472,13 +492,19 @@ export class AppManager {
472
492
  if (appIds.length === 0) {
473
493
  this.appCreateQueue.emitReady();
474
494
  }
475
- const appsWithCreatedAt = appIds.map(appId => {
476
- return {
477
- id: appId,
478
- createdAt: apps[appId].createdAt,
479
- };
480
- });
481
- for (const { id } of orderBy(appsWithCreatedAt, "createdAt", "asc")) {
495
+ const appsWithCreatedAt = orderBy(
496
+ appIds.map(appId => {
497
+ return {
498
+ id: appId,
499
+ createdAt: apps[appId].createdAt,
500
+ };
501
+ }),
502
+ "createdAt",
503
+ "asc"
504
+ );
505
+ const orderedAppIds = appsWithCreatedAt.map(({ id }) => id);
506
+ this.notifyAppsChange(orderedAppIds);
507
+ for (const id of orderedAppIds) {
482
508
  if (!this.appProxies.has(id) && !this.appStatus.has(id)) {
483
509
  const app = apps[id];
484
510
  try {
@@ -570,7 +596,8 @@ export class AppManager {
570
596
  if (!mainView.focusScenePath) {
571
597
  this.setMainViewFocusPath();
572
598
  }
573
- emitter.emit("mainViewMounted");
599
+ internalEmitter.emit("mainViewMounted");
600
+ callbacks.emit("onMainViewMounted", mainView);
574
601
  }
575
602
 
576
603
  public setMainViewFocusPath(scenePath?: string) {
@@ -653,26 +680,10 @@ export class AppManager {
653
680
  }
654
681
 
655
682
  private displayerStateListener = (state: Partial<RoomState>) => {
656
- const sceneState = state.sceneState;
657
- if (sceneState) {
658
- const scenePath = sceneState.scenePath;
659
- this.appProxies.forEach(appProxy => {
660
- if (appProxy.scenePath && scenePath.startsWith(appProxy.scenePath)) {
661
- appProxy.emitAppSceneStateChange(sceneState);
662
- appProxy.setFullPath(scenePath);
663
- }
664
- });
665
- }
666
683
  this.appProxies.forEach(appProxy => {
667
684
  appProxy.appEmitter.emit("roomStateChange", state);
668
685
  });
669
- if (state.roomMembers) {
670
- emitter.emit("roomMembersChange", this.members);
671
- }
672
- emitter.emit("observerIdChange", this.displayer.observerId);
673
- if (state.memberState) {
674
- emitter.emit("memberStateChange", toJS(state.memberState));
675
- }
686
+ internalEmitter.emit("observerIdChange", this.displayer.observerId);
676
687
  };
677
688
 
678
689
  public displayerWritableListener = (isReadonly: boolean) => {
@@ -687,12 +698,7 @@ export class AppManager {
687
698
  this.appProxies.forEach(appProxy => {
688
699
  appProxy.emitAppIsWritableChange();
689
700
  });
690
- if (isWritable === true) {
691
- if (this.room && this.room.disableSerialization === true) {
692
- this.room.disableSerialization = false;
693
- }
694
- }
695
- emitter.emit("writableChange", isWritable);
701
+ internalEmitter.emit("writableChange", isWritable);
696
702
  };
697
703
 
698
704
  public safeSetAttributes(attributes: any) {
@@ -756,7 +762,7 @@ export class AppManager {
756
762
  const success = this.setMainViewFocusPath(scenePath);
757
763
  if (success) {
758
764
  this.store.setMainViewScenePath(scenePath);
759
- this.safeSetAttributes({ _mainSceneIndex: index });
765
+ this.store.setMainViewSceneIndex(index);
760
766
  this.dispatchSetMainViewScenePath(scenePath);
761
767
  }
762
768
  } else {
@@ -767,6 +773,7 @@ export class AppManager {
767
773
 
768
774
  private dispatchSetMainViewScenePath(scenePath: string): void {
769
775
  this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
776
+ callbacks.emit("mainViewScenePathChange", scenePath);
770
777
  // 兼容 15 的 SDK, 需要 room 的当前 ScenePath
771
778
  setScenePath(this.room, scenePath);
772
779
  }
@@ -794,12 +801,16 @@ export class AppManager {
794
801
  }
795
802
 
796
803
  public async onReconnected() {
804
+ this.attributesUpdateCallback(this.attributes.apps);
797
805
  const appProxies = Array.from(this.appProxies.values());
798
806
  const reconnected = appProxies.map(appProxy => {
799
807
  return appProxy.onReconnected();
800
808
  });
801
809
  this.mainViewProxy.onReconnect();
802
810
  await Promise.all(reconnected);
811
+ if (this.callbacksNode) {
812
+ this.onSceneChange(this.callbacksNode);
813
+ }
803
814
  }
804
815
 
805
816
  public notifyContainerRectUpdate(rect: TeleBoxRect) {
@@ -824,7 +835,7 @@ export class AppManager {
824
835
  this.displayer.callbacks.off("onEnableWriteNowChanged", this.displayerWritableListener);
825
836
  this.appListeners.removeListeners();
826
837
  boxEmitter.clearListeners();
827
- emitter.clearListeners();
838
+ internalEmitter.clearListeners();
828
839
  if (this.appProxies.size) {
829
840
  this.appProxies.forEach(appProxy => {
830
841
  appProxy.destroy(true, false, true);
@@ -832,7 +843,7 @@ export class AppManager {
832
843
  }
833
844
  callbacks.clearListeners();
834
845
  this.sideEffectManager.flushAll();
835
- this.sceneIndex$.destroy();
836
- this.focused$.destroy();
846
+ this._prevFocused = undefined;
847
+ this._prevSceneIndex = undefined;
837
848
  }
838
849
  }
@@ -1,5 +1,5 @@
1
1
  import { AppAttributes } from "./constants";
2
- import { get, pick } from "lodash";
2
+ import { get, isObject, pick } from "lodash";
3
3
  import { setViewFocusScenePath } from "./Utils/Common";
4
4
  import type { AddAppParams, AppSyncAttributes } from "./index";
5
5
  import type { Camera, Size, View } from "white-web-sdk";
@@ -18,8 +18,7 @@ export enum Fields {
18
18
  CursorState = "cursorState",
19
19
  FullPath = "fullPath",
20
20
  Registered = "registered",
21
- Camera = "camera",
22
- Size = "size",
21
+ IframeBridge = "iframeBridge",
23
22
  }
24
23
 
25
24
  export type Apps = {
@@ -39,18 +38,13 @@ export type StoreContext = {
39
38
  getAttributes: () => any;
40
39
  safeUpdateAttributes: (keys: string[], value: any) => void;
41
40
  safeSetAttributes: (attributes: any) => void;
42
- }
43
-
44
- export type ICamera = Camera & {
45
- id: string; // room uid
46
41
  };
47
42
 
48
- export type ISize = Size & {
49
- id: string; // room uid
50
- };
43
+ export type ICamera = Camera & { id: string };
51
44
 
52
- export class AttributesDelegate {
45
+ export type ISize = Size & { id: string };
53
46
 
47
+ export class AttributesDelegate {
54
48
  constructor(private context: StoreContext) {}
55
49
 
56
50
  public setContext(context: StoreContext) {
@@ -114,10 +108,6 @@ export class AttributesDelegate {
114
108
  }
115
109
  }
116
110
 
117
- public updateAppAttributes(appId: string, key: string, value: any) {
118
- this.context.safeUpdateAttributes([Fields.Apps, appId, key], value);
119
- }
120
-
121
111
  public cleanAppAttributes(id: string) {
122
112
  this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
123
113
  this.context.safeSetAttributes({ [id]: undefined });
@@ -159,11 +149,11 @@ export class AttributesDelegate {
159
149
  this.context.safeSetAttributes({ _mainSceneIndex: index });
160
150
  }
161
151
 
162
- public getMainViewCamera(): ICamera {
152
+ public getMainViewCamera(): MainViewCamera {
163
153
  return get(this.attributes, [Fields.MainViewCamera]);
164
154
  }
165
155
 
166
- public getMainViewSize(): ISize {
156
+ public getMainViewSize(): MainViewSize {
167
157
  return get(this.attributes, [Fields.MainViewSize]);
168
158
  }
169
159
 
@@ -172,10 +162,12 @@ export class AttributesDelegate {
172
162
  }
173
163
 
174
164
  public setMainViewSize(size: ISize) {
165
+ if (size.width === 0 || size.height === 0) return;
175
166
  this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
176
167
  }
177
168
 
178
169
  public setMainViewCameraAndSize(camera: ICamera, size: ISize) {
170
+ if (size.width === 0 || size.height === 0) return;
179
171
  this.context.safeSetAttributes({
180
172
  [Fields.MainViewCamera]: { ...camera },
181
173
  [Fields.MainViewSize]: { ...size },
@@ -188,7 +180,7 @@ export class AttributesDelegate {
188
180
  } else {
189
181
  this.context.safeSetAttributes({ [Fields.Focus]: undefined });
190
182
  }
191
- }
183
+ };
192
184
 
193
185
  public updateCursor(uid: string, position: Position) {
194
186
  if (!get(this.attributes, [Fields.Cursors])) {
@@ -222,21 +214,49 @@ export class AttributesDelegate {
222
214
  setViewFocusScenePath(mainView, scenePath);
223
215
  }
224
216
  }
217
+
218
+ public getIframeBridge() {
219
+ return get(this.attributes, [Fields.IframeBridge]);
220
+ }
221
+
222
+ public setIframeBridge(data: any) {
223
+ if (isObject(data)) {
224
+ const oldState = this.getIframeBridge();
225
+ for (const key in data) {
226
+ const value = (data as any)[key];
227
+ if (oldState[key] !== value) {
228
+ this.context.safeUpdateAttributes([Fields.IframeBridge, key], value);
229
+ }
230
+ }
231
+ }
232
+ }
225
233
  }
226
234
 
235
+ export type MainViewSize = {
236
+ id: string;
237
+ width: number;
238
+ height: number;
239
+ };
240
+
241
+ export type MainViewCamera = {
242
+ id: string;
243
+ centerX: number;
244
+ centerY: number;
245
+ scale: number;
246
+ };
247
+
227
248
  export type Cursors = {
228
249
  [key: string]: Cursor;
229
250
  };
230
251
 
231
-
232
252
  export const store = new AttributesDelegate({
233
253
  getAttributes: () => {
234
- throw new Error("getAttributes not implemented")
254
+ throw new Error("getAttributes not implemented");
235
255
  },
236
256
  safeSetAttributes: () => {
237
- throw new Error("safeSetAttributes not implemented")
257
+ throw new Error("safeSetAttributes not implemented");
238
258
  },
239
259
  safeUpdateAttributes: () => {
240
- throw new Error("safeUpdateAttributes not implemented")
260
+ throw new Error("safeUpdateAttributes not implemented");
241
261
  },
242
262
  });
package/src/BoxEmitter.ts CHANGED
@@ -1,19 +1,25 @@
1
1
  import type { TELE_BOX_STATE } from "@netless/telebox-insider";
2
2
  import Emittery from "emittery";
3
3
 
4
- export type BoxMovePayload = { appId: string, x: number; y: number };
4
+ export type BoxMovePayload = { appId: string; x: number; y: number };
5
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 };
6
+ export type BoxResizePayload = {
7
+ appId: string;
8
+ width: number;
9
+ height: number;
10
+ x?: number;
11
+ y?: number;
12
+ };
13
+ export type BoxClosePayload = { appId: string; error?: Error };
14
+ export type BoxStateChangePayload = { appId: string; state: TELE_BOX_STATE };
9
15
 
10
16
  export type BoxEvent = {
11
17
  move: BoxMovePayload;
12
18
  focus: BoxFocusPayload;
13
19
  resize: BoxResizePayload;
14
20
  close: BoxClosePayload;
15
- boxStateChange: BoxStateChangePayload
16
- }
21
+ boxStateChange: BoxStateChangePayload;
22
+ };
17
23
 
18
24
  export type BoxEmitterType = Emittery<BoxEvent>;
19
25
  export const boxEmitter: BoxEmitterType = new Emittery();