@netless/window-manager 1.0.0-canary.2 → 1.0.0-canary.22

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 (50) hide show
  1. package/__mocks__/white-web-sdk.ts +10 -1
  2. package/dist/App/AppContext.d.ts +11 -7
  3. package/dist/App/AppProxy.d.ts +35 -7
  4. package/dist/App/{WhiteBoardView.d.ts → WhiteboardView.d.ts} +10 -1
  5. package/dist/App/index.d.ts +2 -1
  6. package/dist/App/type.d.ts +21 -0
  7. package/dist/AppManager.d.ts +5 -5
  8. package/dist/AttributesDelegate.d.ts +11 -16
  9. package/dist/BoxManager.d.ts +7 -6
  10. package/dist/Cursor/index.d.ts +0 -1
  11. package/dist/InternalEmitter.d.ts +3 -2
  12. package/dist/Page/PageController.d.ts +1 -0
  13. package/dist/ReconnectRefresher.d.ts +1 -1
  14. package/dist/Utils/Common.d.ts +1 -0
  15. package/dist/View/CameraSynchronizer.d.ts +9 -9
  16. package/dist/View/MainView.d.ts +18 -7
  17. package/dist/View/ViewSync.d.ts +24 -0
  18. package/dist/constants.d.ts +6 -2
  19. package/dist/index.cjs.js +12 -12
  20. package/dist/index.d.ts +19 -2
  21. package/dist/index.es.js +803 -425
  22. package/dist/index.umd.js +12 -12
  23. package/dist/style.css +1 -1
  24. package/docs/app-context.md +98 -64
  25. package/docs/develop-app.md +2 -5
  26. package/docs/mirgrate-to-1.0.md +28 -0
  27. package/package.json +3 -3
  28. package/pnpm-lock.yaml +9 -9
  29. package/src/App/AppContext.ts +43 -21
  30. package/src/App/AppProxy.ts +247 -79
  31. package/src/App/{WhiteBoardView.ts → WhiteboardView.ts} +38 -4
  32. package/src/App/index.ts +2 -1
  33. package/src/App/type.ts +22 -0
  34. package/src/AppManager.ts +38 -31
  35. package/src/AttributesDelegate.ts +18 -18
  36. package/src/BoxManager.ts +28 -22
  37. package/src/Cursor/index.ts +0 -2
  38. package/src/InternalEmitter.ts +3 -2
  39. package/src/Page/PageController.ts +1 -0
  40. package/src/PageState.ts +1 -1
  41. package/src/ReconnectRefresher.ts +7 -2
  42. package/src/Utils/Common.ts +6 -0
  43. package/src/Utils/Reactive.ts +27 -26
  44. package/src/Utils/RoomHacker.ts +3 -0
  45. package/src/View/CameraSynchronizer.ts +43 -30
  46. package/src/View/MainView.ts +106 -81
  47. package/src/View/ViewSync.ts +110 -0
  48. package/src/constants.ts +5 -1
  49. package/src/index.ts +59 -15
  50. package/src/style.css +8 -0
@@ -0,0 +1,22 @@
1
+
2
+ export type AppState = {
3
+ id: string;
4
+ focus?: boolean;
5
+ SceneIndex?: number;
6
+ draggable?: boolean;
7
+ position?: {
8
+ x: number;
9
+ y: number;
10
+ }
11
+ ratio?: number;
12
+ resizable?: boolean;
13
+ size?: {
14
+ width: number;
15
+ height: number;
16
+ }
17
+ stageRatio?: number;
18
+ visible?: boolean;
19
+ zIndex?: number;
20
+ maximized: boolean | null;
21
+ minimized: boolean | null;
22
+ }
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";
@@ -18,6 +18,7 @@ import { RedoUndo } from "./RedoUndo";
18
18
  import { serializeRoomMembers } from "./Helper";
19
19
  import { SideEffectManager } from "side-effect-manager";
20
20
  import { ViewManager } from "./View/ViewManager";
21
+ import { Val } from "value-enhancer";
21
22
  import type { SyncRegisterAppPayload } from "./Register";
22
23
  import type { RemoveSceneParams } from "./InternalEmitter";
23
24
  import {
@@ -29,15 +30,16 @@ import {
29
30
  removeScenes,
30
31
  setScenePath,
31
32
  setViewFocusScenePath,
33
+ wait,
32
34
  } from "./Utils/Common";
33
35
  import type { ReconnectRefresher } from "./ReconnectRefresher";
34
36
  import type { BoxManager } from "./BoxManager";
35
37
  import type {
36
38
  Displayer,
37
- DisplayerState,
38
39
  Room,
39
40
  ScenesCallbacksNode,
40
41
  SceneState,
42
+ RoomState,
41
43
  } from "white-web-sdk";
42
44
  import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
43
45
  import type {
@@ -56,17 +58,17 @@ export class AppManager {
56
58
  public appStatus: Map<string, AppStatus> = new Map();
57
59
  public store = store;
58
60
  public mainViewProxy: MainViewProxy;
59
- public refresher?: ReconnectRefresher;
61
+ public refresher: ReconnectRefresher;
60
62
  public isReplay = this.windowManger.isReplay;
61
63
  public mainViewScenesLength = 0;
62
64
 
63
65
  private appListeners: AppListeners;
64
66
  public boxManager?: BoxManager;
65
67
 
66
- private _prevSceneIndex: number | undefined;
67
- private _prevFocused: string | undefined;
68
68
  private callbacksNode: ScenesCallbacksNode | null = null;
69
69
  private appCreateQueue = new AppCreateQueue();
70
+ private sceneIndex$ = new Val<number | undefined>(undefined);
71
+ private focused$ = new Val<string | undefined>(undefined);
70
72
 
71
73
  private sideEffectManager = new SideEffectManager();
72
74
 
@@ -137,7 +139,7 @@ export class AppManager {
137
139
  sceneName = this.callbacksNode?.scenes[nextIndex];
138
140
  }
139
141
  if (sceneName) {
140
- this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
142
+ await this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
141
143
  }
142
144
  await this.setMainViewSceneIndex(nextIndex);
143
145
  } else {
@@ -152,7 +154,7 @@ export class AppManager {
152
154
  * 所以需要关掉所有开启了 view 的 app
153
155
  */
154
156
  public async onRootDirRemoved(needClose = true) {
155
- this.setMainViewScenePath(INIT_DIR);
157
+ await this.setMainViewScenePath(INIT_DIR);
156
158
  this.createRootDirScenesCallback();
157
159
 
158
160
  for (const [id, appProxy] of this.appProxies.entries()) {
@@ -160,9 +162,9 @@ export class AppManager {
160
162
  await this.closeApp(id, needClose);
161
163
  }
162
164
  }
163
- // 删除了根目录的 scenes 之后 mainview 需要重新绑定, 否则主白板会不能渲染
165
+ // 删除了根目录的 scenes 之后 main-view 需要重新绑定, 否则主白板会不能渲染
164
166
  this.mainViewProxy.rebind();
165
- emitter.emit("rootDirRemoved");
167
+ await emitter.emit("rootDirRemoved");
166
168
  this.updateRootDirRemoving(false);
167
169
  }
168
170
 
@@ -324,31 +326,31 @@ export class AppManager {
324
326
 
325
327
  this.addAppsChangeListener();
326
328
  this.addAppCloseListener();
327
- this.refresher?.add("maximized", () => {
329
+ this.refresher.add("maximized", () => {
328
330
  return autorun(() => {
329
331
  const maximized = this.attributes.maximized;
330
332
  this.boxManager?.setMaximized(Boolean(maximized));
331
333
  });
332
334
  });
333
- this.refresher?.add("minimized", () => {
335
+ this.refresher.add("minimized", () => {
334
336
  return autorun(() => {
335
337
  const minimized = this.attributes.minimized;
336
338
  this.onMinimized(minimized);
337
339
  });
338
340
  });
339
- this.refresher?.add("mainViewIndex", () => {
341
+ this.refresher.add("mainViewIndex", () => {
340
342
  return autorun(() => {
341
343
  const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
342
344
  this.onMainViewIndexChange(mainSceneIndex);
343
345
  });
344
346
  });
345
- this.refresher?.add("focusedChange", () => {
347
+ this.refresher.add("focusedChange", () => {
346
348
  return autorun(() => {
347
349
  const focused = get(this.attributes, "focus");
348
350
  this.onFocusChange(focused);
349
351
  });
350
352
  });
351
- this.refresher?.add("registeredChange", () => {
353
+ this.refresher.add("registeredChange", () => {
352
354
  return autorun(() => {
353
355
  const registered = get(this.attributes, Fields.Registered);
354
356
  this.onRegisteredChange(registered);
@@ -361,7 +363,7 @@ export class AppManager {
361
363
  }
362
364
  this.displayerWritableListener(!this.room?.isWritable);
363
365
  this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
364
- this._prevFocused = this.attributes.focus;
366
+ this.focused$.setValue(this.attributes.focus);
365
367
 
366
368
  this.sideEffectManager.add(() => {
367
369
  const redoUndo = new RedoUndo({
@@ -426,27 +428,28 @@ export class AppManager {
426
428
  };
427
429
 
428
430
  private onMainViewIndexChange = (index: number) => {
429
- if (index !== undefined && this._prevSceneIndex !== index) {
431
+ if (index !== undefined && this.sceneIndex$.value !== index) {
430
432
  callbacks.emit("mainViewSceneIndexChange", index);
431
433
  emitter.emit("changePageState");
432
434
  if (this.callbacksNode) {
433
435
  this.updateSceneState(this.callbacksNode);
434
436
  }
435
- this._prevSceneIndex = index;
437
+ this.sceneIndex$.setValue(index);
436
438
  }
437
439
  };
438
440
 
439
441
  private onFocusChange = (focused: string | undefined) => {
440
- if (this._prevFocused !== focused) {
442
+ if (this.focused$.value !== focused) {
441
443
  callbacks.emit("focusedChange", focused);
442
- emitter.emit("focusedChange", { focused, prev: this._prevFocused });
443
- this._prevFocused = focused;
444
+ emitter.emit("focusedChange", { focused, prev: this.focused$.value });
445
+ this.focused$.setValue(focused);
444
446
  if (focused !== undefined) {
445
447
  this.boxManager?.focusBox({ appId: focused });
446
448
  // 确保 focus 修改的时候, appProxy 已经创建
447
449
  setTimeout(() => {
448
450
  const appProxy = this.appProxies.get(focused);
449
451
  if (appProxy) {
452
+ appProxy.onFocus();
450
453
  appRegister.notifyApp(appProxy.kind, "focus", { appId: focused });
451
454
  }
452
455
  }, 0);
@@ -460,9 +463,9 @@ export class AppManager {
460
463
  );
461
464
 
462
465
  /**
463
- * 插件更新 attributes 时的回调
466
+ * 插件更新 apps 时的回调
464
467
  *
465
- * @param {*} attributes
468
+ * @param {*} apps
466
469
  * @memberof WindowManager
467
470
  */
468
471
  public async _attributesUpdateCallback(apps: any) {
@@ -536,6 +539,7 @@ export class AppManager {
536
539
 
537
540
  public setBoxManager(boxManager: BoxManager) {
538
541
  this.boxManager = boxManager;
542
+ this.mainViewProxy.createViewSync();
539
543
  }
540
544
 
541
545
  public resetMaximized() {
@@ -565,7 +569,10 @@ export class AppManager {
565
569
  public bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean) {
566
570
  const mainView = this.mainViewProxy.view;
567
571
  mainView.disableCameraTransform = disableCameraTransform;
568
- mainView.divElement = divElement;
572
+ // 延迟挂载 mainView dom, 避免因为同步 camera 的闪动
573
+ wait(30).then(() => {
574
+ mainView.divElement = divElement;
575
+ });
569
576
  if (!mainView.focusScenePath) {
570
577
  this.setMainViewFocusPath();
571
578
  }
@@ -651,7 +658,7 @@ export class AppManager {
651
658
  }
652
659
  }
653
660
 
654
- private displayerStateListener = (state: Partial<DisplayerState>) => {
661
+ private displayerStateListener = (state: Partial<RoomState>) => {
655
662
  const sceneState = state.sceneState;
656
663
  if (sceneState) {
657
664
  const scenePath = sceneState.scenePath;
@@ -669,12 +676,15 @@ export class AppManager {
669
676
  emitter.emit("roomMembersChange", this.members);
670
677
  }
671
678
  emitter.emit("observerIdChange", this.displayer.observerId);
679
+ if (state.memberState) {
680
+ emitter.emit("memberStateChange", toJS(state.memberState));
681
+ }
672
682
  };
673
683
 
674
684
  public displayerWritableListener = (isReadonly: boolean) => {
675
685
  const isWritable = !isReadonly;
676
686
  const isManualWritable =
677
- this.windowManger.readonly === undefined || this.windowManger.readonly === false;
687
+ this.windowManger.readonly === undefined || !this.windowManger.readonly;
678
688
  if (this.windowManger.readonly === undefined) {
679
689
  this.boxManager?.setReadonly(isReadonly);
680
690
  } else {
@@ -683,13 +693,10 @@ export class AppManager {
683
693
  this.appProxies.forEach(appProxy => {
684
694
  appProxy.emitAppIsWritableChange();
685
695
  });
686
- if (isWritable === true) {
687
- this.mainView.disableCameraTransform = false;
696
+ if (isWritable) {
688
697
  if (this.room && this.room.disableSerialization === true) {
689
698
  this.room.disableSerialization = false;
690
699
  }
691
- } else {
692
- this.mainView.disableCameraTransform = true;
693
700
  }
694
701
  emitter.emit("writableChange", isWritable);
695
702
  };
@@ -831,7 +838,7 @@ export class AppManager {
831
838
  }
832
839
  callbacks.clearListeners();
833
840
  this.sideEffectManager.flushAll();
834
- this._prevFocused = undefined;
835
- this._prevSceneIndex = undefined;
841
+ this.sceneIndex$.destroy();
842
+ this.focused$.destroy();
836
843
  }
837
844
  }
@@ -2,7 +2,7 @@ import { AppAttributes } from "./constants";
2
2
  import { get, pick } from "lodash";
3
3
  import { setViewFocusScenePath } from "./Utils/Common";
4
4
  import type { AddAppParams, AppSyncAttributes } from "./index";
5
- import type { Camera, Size, View } from "white-web-sdk";
5
+ import type { Size, View } from "white-web-sdk";
6
6
  import type { Cursor } from "./Cursor/Cursor";
7
7
 
8
8
  export enum Fields {
@@ -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,16 @@ export type StoreContext = {
39
41
  safeSetAttributes: (attributes: any) => void;
40
42
  }
41
43
 
42
- export type ICamera = Camera & { id: string };
44
+ export type ICamera = & {
45
+ id: string; // room uid
46
+ centerX: number | null,
47
+ centerY: number | null,
48
+ scale: number
49
+ };
43
50
 
44
- export type ISize = Size & { id: string };
51
+ export type ISize = Size & {
52
+ id: string; // room uid
53
+ };
45
54
 
46
55
  export class AttributesDelegate {
47
56
 
@@ -108,6 +117,10 @@ export class AttributesDelegate {
108
117
  }
109
118
  }
110
119
 
120
+ public updateAppAttributes(appId: string, key: string, value: any) {
121
+ this.context.safeUpdateAttributes([Fields.Apps, appId, key], value);
122
+ }
123
+
111
124
  public cleanAppAttributes(id: string) {
112
125
  this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
113
126
  this.context.safeSetAttributes({ [id]: undefined });
@@ -149,11 +162,11 @@ export class AttributesDelegate {
149
162
  this.context.safeSetAttributes({ _mainSceneIndex: index });
150
163
  }
151
164
 
152
- public getMainViewCamera(): MainViewCamera {
165
+ public getMainViewCamera(): ICamera {
153
166
  return get(this.attributes, [Fields.MainViewCamera]);
154
167
  }
155
168
 
156
- public getMainViewSize(): MainViewSize {
169
+ public getMainViewSize(): ISize {
157
170
  return get(this.attributes, [Fields.MainViewSize]);
158
171
  }
159
172
 
@@ -214,19 +227,6 @@ export class AttributesDelegate {
214
227
  }
215
228
  }
216
229
 
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
230
  export type Cursors = {
231
231
  [key: string]: Cursor;
232
232
  };
package/src/BoxManager.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
2
2
  import { debounce } from "lodash";
3
+ import { SideEffectManager } from "side-effect-manager";
3
4
  import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
4
5
  import { WindowManager } from "./index";
5
6
  import type { BoxEmitterType } from "./BoxEmitter";
6
- import type { AddAppOptions, AppInitState } from "./index";
7
+ import type { AddAppOptions } from "./index";
7
8
  import type {
8
9
  TeleBoxManagerUpdateConfig,
9
10
  TeleBoxManagerCreateConfig,
@@ -18,7 +19,7 @@ import type { NetlessApp } from "./typings";
18
19
  import type { View } from "white-web-sdk";
19
20
  import type { CallbacksType } from "./callback";
20
21
  import type { EmitterType } from "./InternalEmitter";
21
- import { SideEffectManager } from "side-effect-manager";
22
+ import type { AppState } from "./App/type";
22
23
 
23
24
  export { TELE_BOX_STATE };
24
25
 
@@ -47,11 +48,11 @@ export type CreateTeleBoxManagerConfig = {
47
48
  collectorStyles?: Partial<CSSStyleDeclaration>;
48
49
  prefersColorScheme?: TeleBoxColorScheme;
49
50
  stageRatio?: number;
51
+ highlightStage?: boolean;
50
52
  };
51
53
 
52
54
  export type BoxManagerContext = {
53
55
  safeSetAttributes: (attributes: any) => void;
54
- getMainView: () => View;
55
56
  updateAppState: (appId: string, field: AppAttributes, value: any) => void;
56
57
  emitter: EmitterType;
57
58
  boxEmitter: BoxEmitterType;
@@ -72,7 +73,6 @@ export const createBoxManager = (
72
73
  return new BoxManager(
73
74
  {
74
75
  safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
75
- getMainView: () => manager.mainView,
76
76
  updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
77
77
  canOperate: () => manager.canOperate,
78
78
  notifyContainerRectUpdate: (rect: TeleBoxRect) =>
@@ -81,7 +81,7 @@ export const createBoxManager = (
81
81
  setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
82
82
  callbacks,
83
83
  emitter,
84
- boxEmitter
84
+ boxEmitter,
85
85
  },
86
86
  options
87
87
  );
@@ -100,17 +100,17 @@ export class BoxManager {
100
100
  this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
101
101
  this.sideEffectManager.add(() => [
102
102
  // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
103
- this.teleBoxManager._state$.reaction(state => {
103
+ this.teleBoxManager.onValChanged("state", state => {
104
104
  callbacks.emit("boxStateChange", state);
105
105
  emitter.emit("boxStateChange", state);
106
106
  }),
107
- this.teleBoxManager._darkMode$.reaction(darkMode => {
107
+ this.teleBoxManager.onValChanged("darkMode", darkMode => {
108
108
  callbacks.emit("darkModeChange", darkMode);
109
109
  }),
110
- this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
110
+ this.teleBoxManager.onValChanged("prefersColorScheme", colorScheme => {
111
111
  callbacks.emit("prefersColorSchemeChange", colorScheme);
112
112
  }),
113
- this.teleBoxManager._minimized$.reaction((minimized, skipUpdate) => {
113
+ this.teleBoxManager.onValChanged("minimized", (minimized, skipUpdate) => {
114
114
  if (skipUpdate) {
115
115
  return;
116
116
  }
@@ -126,7 +126,7 @@ export class BoxManager {
126
126
  }
127
127
  }
128
128
  }),
129
- this.teleBoxManager._maximized$.reaction((maximized, skipUpdate) => {
129
+ this.teleBoxManager.onValChanged("maximized", (maximized, skipUpdate) => {
130
130
  if (skipUpdate) {
131
131
  return;
132
132
  }
@@ -140,7 +140,11 @@ export class BoxManager {
140
140
  this.teleBoxManager.events.on(
141
141
  "intrinsic_move",
142
142
  debounce((box: ReadonlyTeleBox): void => {
143
- boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
143
+ boxEmitter.emit("move", {
144
+ appId: box.id,
145
+ x: box.intrinsicX,
146
+ y: box.intrinsicY,
147
+ });
144
148
  }, 50)
145
149
  ),
146
150
  this.teleBoxManager.events.on(
@@ -178,10 +182,6 @@ export class BoxManager {
178
182
  ]);
179
183
  }
180
184
 
181
- private get mainView() {
182
- return this.context.getMainView();
183
- }
184
-
185
185
  private get canOperate() {
186
186
  return this.context.canOperate();
187
187
  }
@@ -214,7 +214,11 @@ export class BoxManager {
214
214
  return this.teleBoxManager.stageRect;
215
215
  }
216
216
 
217
- public createBox(params: CreateBoxParams): void {
217
+ public get stageRect$() {
218
+ return this.teleBoxManager._stageRect$;
219
+ }
220
+
221
+ public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
218
222
  if (!this.teleBoxManager) return;
219
223
  let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
220
224
  const { width, height } = params.app.config ?? {};
@@ -237,8 +241,9 @@ export class BoxManager {
237
241
  height,
238
242
  id: params.appId,
239
243
  };
240
- this.teleBoxManager.create(createBoxConfig, params.smartPosition);
244
+ const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
241
245
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
246
+ return box;
242
247
  }
243
248
 
244
249
  public setupBoxManager(
@@ -250,6 +255,7 @@ export class BoxManager {
250
255
  root: root,
251
256
  fence: false,
252
257
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
258
+ highlightStage: createTeleBoxManagerConfig?.highlightStage,
253
259
  };
254
260
 
255
261
  const manager = new TeleBoxManager(initManagerState);
@@ -289,17 +295,17 @@ export class BoxManager {
289
295
  return this.teleBoxManager.topBox;
290
296
  }
291
297
 
292
- public updateBoxState(state?: AppInitState): void {
298
+ public updateBoxState(state?: AppState): void {
293
299
  if (!state) return;
294
300
  const box = this.getBox(state.id);
295
301
  if (box) {
296
302
  this.teleBoxManager.update(
297
303
  box.id,
298
304
  {
299
- x: state.x,
300
- y: state.y,
301
- width: state.width || 0.5,
302
- height: state.height || 0.5,
305
+ x: state.position?.x,
306
+ y: state.position?.y,
307
+ width: state.size?.width || 0.5,
308
+ height: state.size?.height || 0.5,
303
309
  zIndex: state.zIndex,
304
310
  },
305
311
  true
@@ -23,7 +23,6 @@ export type MoveCursorParams = {
23
23
  };
24
24
 
25
25
  export class CursorManager {
26
- public containerRect?: DOMRect;
27
26
  public wrapperRect?: DOMRect;
28
27
  public cursorInstances: Map<string, Cursor> = new Map();
29
28
  public roomMembers?: readonly RoomMember[];
@@ -168,7 +167,6 @@ export class CursorManager {
168
167
  };
169
168
 
170
169
  public updateContainerRect() {
171
- this.containerRect = WindowManager.container?.getBoundingClientRect();
172
170
  this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
173
171
  }
174
172
 
@@ -1,7 +1,8 @@
1
1
  import Emittery from "emittery";
2
2
  import type { TeleBoxRect } from "@netless/telebox-insider";
3
- import type { AppInitState, CursorMovePayload } from "./index";
3
+ import type { CursorMovePayload } from "./index";
4
4
  import type { Member } from "./Helper";
5
+ import type { MemberState } from "white-web-sdk";
5
6
 
6
7
  export type RemoveSceneParams = {
7
8
  scenePath: string;
@@ -10,7 +11,6 @@ export type RemoveSceneParams = {
10
11
 
11
12
  export type EmitterEvent = {
12
13
  onCreated: undefined;
13
- InitReplay: AppInitState;
14
14
  error: Error;
15
15
  seekStart: undefined;
16
16
  seek: number;
@@ -31,6 +31,7 @@ export type EmitterEvent = {
31
31
  writableChange: boolean;
32
32
  containerSizeRatioUpdate: number;
33
33
  roomMembersChange: Member[];
34
+ memberStateChange: MemberState;
34
35
  };
35
36
 
36
37
  export type EmitterType = Emittery<EmitterEvent>;
@@ -13,6 +13,7 @@ export type PageState = {
13
13
  export interface PageController {
14
14
  nextPage: () => Promise<boolean>;
15
15
  prevPage: () => Promise<boolean>;
16
+ jumpPage: (index: number) => Promise<boolean>;
16
17
  addPage: (params?: AddPageParams) => Promise<void>;
17
18
  removePage: (index: number) => Promise<boolean>;
18
19
  pageState: PageState;
package/src/PageState.ts CHANGED
@@ -6,7 +6,7 @@ import type { PageState } from "./Page";
6
6
  export class PageStateImpl {
7
7
  constructor(private manager: AppManager) {
8
8
  emitter.on("changePageState", () => {
9
- callbacks.emit("pageStateChange", this.toObject());
9
+ callbacks.emit("pageStateChange", this.toObject());
10
10
  });
11
11
  }
12
12
 
@@ -46,14 +46,18 @@ export class ReconnectRefresher {
46
46
  this.ctx.emitter.emit("startReconnect");
47
47
  }
48
48
  if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
49
- this.room?.dispatchMagixEvent(EnsureReconnectEvent, {});
49
+ if (this.room?.isWritable) {
50
+ this.room?.dispatchMagixEvent(EnsureReconnectEvent, {});
51
+ } else {
52
+ this.onReconnected();
53
+ }
50
54
  }
51
55
  this.phase = phase;
52
56
  };
53
57
 
54
58
  private onReconnected = debounce(() => {
55
59
  this._onReconnected();
56
- }, 3000);
60
+ }, 1000);
57
61
 
58
62
  private _onReconnected = () => {
59
63
  log("onReconnected refresh reactors");
@@ -88,6 +92,7 @@ export class ReconnectRefresher {
88
92
  this.reactors.set(id, func);
89
93
  this.disposers.set(id, func());
90
94
  }
95
+ return () => this.remove(id);
91
96
  }
92
97
 
93
98
  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) {