@netless/window-manager 1.0.13-test.2 → 1.0.13-test.20

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "1.0.13-test.2",
3
+ "version": "1.0.13-test.20",
4
4
  "description": "Multi-window mode for Netless Whiteboard",
5
5
  "author": "l1shen <lishen1635@gmail.com> (https://github.com/l1shen)",
6
6
  "license": "MIT",
@@ -47,18 +47,10 @@ export class AppListeners {
47
47
  break;
48
48
  }
49
49
  case Events.SetMainViewScenePath: {
50
- console.log("[window-manager] mainMagixEventListener====>", JSON.stringify(data.payload));
50
+ console.log("[window-manager] mainMagixEventListener " + JSON.stringify(data.payload));
51
51
  this.setMainViewScenePathHandler(data.payload);
52
52
  break;
53
53
  }
54
- // case Events.MoveCamera: {
55
- // this.moveCameraHandler(data.payload);
56
- // break;
57
- // }
58
- // case Events.MoveCameraToContain: {
59
- // this.moveCameraToContainHandler(data.payload);
60
- // break;
61
- // }
62
54
  case Events.CursorMove: {
63
55
  this.cursorMoveHandler(data.payload);
64
56
  break;
@@ -103,17 +95,6 @@ export class AppListeners {
103
95
  callbacks.emit("mainViewScenePathChange", nextScenePath);
104
96
  };
105
97
 
106
- // private moveCameraHandler = (
107
- // payload: Camera & { animationMode?: AnimationMode | undefined }
108
- // ) => {
109
- // if (isEqual(omit(payload, ["animationMode"]), { ...this.manager.mainView.camera })) return;
110
- // this.manager.mainView.moveCamera(payload);
111
- // };
112
-
113
- // private moveCameraToContainHandler = (payload: any) => {
114
- // this.manager.mainView.moveCameraToContain(payload);
115
- // };
116
-
117
98
  private cursorMoveHandler = (payload: any) => {
118
99
  internalEmitter.emit("cursorMove", payload);
119
100
  };
package/src/AppManager.ts CHANGED
@@ -51,7 +51,6 @@ import type {
51
51
  } from "./BoxEmitter";
52
52
  import { getExtendClass } from "./Utils/extendClass";
53
53
  import type { TeleBoxState } from "@netless/telebox-insider";
54
- import { getAttribute } from "video.js/dist/types/utils/dom";
55
54
 
56
55
  export class AppManager {
57
56
  static readonly kind = "AppManager";
@@ -147,6 +146,7 @@ export class AppManager {
147
146
  const { scenePath } = params;
148
147
  // 如果移除根目录就把 scenePath 设置为初始值
149
148
  if (scenePath === ROOT_DIR) {
149
+ console.log("[window-manager] onRemoveScenes ROOT_DIR");
150
150
  await this.onRootDirRemoved();
151
151
  this.dispatchInternalEvent(Events.RootDirRemoved);
152
152
  return;
@@ -159,6 +159,7 @@ export class AppManager {
159
159
  sceneName = this.callbacksNode?.scenes[nextIndex];
160
160
  }
161
161
  if (sceneName) {
162
+ console.log(`[window-manager] onRemoveScenes setMainViewScenePath ${ROOT_DIR}${sceneName}`);
162
163
  this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
163
164
  }
164
165
  await this.setMainViewSceneIndex(nextIndex);
@@ -710,6 +711,31 @@ export class AppManager {
710
711
  }
711
712
  internalEmitter.emit("mainViewMounted");
712
713
  callbacks.emit("onMainViewMounted", mainView);
714
+ const hasRoot = this.hasRoot(mainView.divElement);
715
+ const rect = this.getRectByDivElement(mainView.divElement);
716
+ let log = `[window-manager] bindMainView hasRoot:${hasRoot}, rect:${JSON.stringify(rect)}, outerHeight:${window.outerHeight}, outerWidth:${window.outerWidth}`;
717
+ const visualViewport = window.visualViewport;
718
+ if (visualViewport) {
719
+ log += `, visualViewportWidth:${visualViewport.width}, visualViewportHeight:${visualViewport.height}, visualViewportOffsetLeft:${visualViewport.offsetLeft}, visualViewportOffsetTop:${visualViewport.offsetTop}`;
720
+ }
721
+ console.log(log);
722
+ }
723
+
724
+ private hasRoot(divElement: HTMLDivElement){
725
+ let current = divElement;
726
+ while (current) {
727
+ if (current.parentElement === document.body) {
728
+ return true;
729
+ }
730
+ current = current.parentElement as HTMLDivElement;
731
+ }
732
+ return false;
733
+ }
734
+
735
+ private getRectByDivElement(divElement: HTMLDivElement){
736
+ // 获取当前divElement的矩形区域
737
+ const rect = divElement.getBoundingClientRect();
738
+ return rect;
713
739
  }
714
740
 
715
741
  public setMainViewFocusPath(scenePath?: string) {
@@ -854,7 +880,7 @@ export class AppManager {
854
880
  private async _setMainViewScenePath(scenePath: string) {
855
881
  const success = this.setMainViewFocusPath(scenePath);
856
882
  if (success) {
857
- console.log("[window-manager] _setMainViewScenePath====>", scenePath);
883
+ console.log("[window-manager] _setMainViewScenePath " + scenePath);
858
884
  this.safeSetAttributes({ _mainScenePath: scenePath });
859
885
  this.store.setMainViewFocusPath(this.mainView);
860
886
  this.updateSceneIndex();
@@ -871,7 +897,7 @@ export class AppManager {
871
897
  const pageName = scenePath.replace(sceneDir, "").replace("/", "");
872
898
  const index = scenes.findIndex(scene => scene.name === pageName);
873
899
  if (isInteger(index) && index >= 0) {
874
- console.log("[window-manager] updateSceneIndex====>", index);
900
+ console.log("[window-manager] updateSceneIndex " + index);
875
901
  this.safeSetAttributes({ _mainSceneIndex: index });
876
902
  }
877
903
  }
@@ -897,7 +923,6 @@ export class AppManager {
897
923
  }
898
924
 
899
925
  private dispatchSetMainViewScenePath(scenePath: string): void {
900
- console.log("[window-manager] dispatchSetMainViewScenePath====>", JSON.stringify(scenePath));
901
926
  this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
902
927
  callbacks.emit("mainViewScenePathChange", scenePath);
903
928
  // 兼容 15 的 SDK, 需要 room 的当前 ScenePath
@@ -7,6 +7,7 @@ import type { Cursor } from "./Cursor/Cursor";
7
7
  import { getExtendClass } from "./Utils/extendClass";
8
8
  import type { ExtendClass } from "./Utils/extendClass";
9
9
  import type { NotMinimizedBoxState, TeleBoxState } from "@netless/telebox-insider";
10
+ import { LocalConsole } from "./Utils/log";
10
11
 
11
12
  export enum Fields {
12
13
  Apps = "apps",
@@ -54,6 +55,7 @@ export type ISize = Size & { id: string };
54
55
 
55
56
  export class AttributesDelegate {
56
57
  static readonly kind = "AttributesDelegate";
58
+ private setMainViewCameraConsole = new LocalConsole("setMainViewCamera", 30);
57
59
  constructor(private context: StoreContext) {}
58
60
 
59
61
  public setContext(context: StoreContext) {
@@ -194,12 +196,12 @@ export class AttributesDelegate {
194
196
  }
195
197
 
196
198
  public setMainViewScenePath(scenePath: string) {
197
- console.log("[window-manager] setMainViewScenePath====>", scenePath);
199
+ console.log("[window-manager] setMainViewScenePath " + scenePath);
198
200
  this.context.safeSetAttributes({ _mainScenePath: scenePath });
199
201
  }
200
202
 
201
203
  public setMainViewSceneIndex(index: number) {
202
- console.log("[window-manager] setMainViewSceneIndex====>", index);
204
+ console.log("[window-manager] setMainViewSceneIndex " + index);
203
205
  this.context.safeSetAttributes({ _mainSceneIndex: index });
204
206
  }
205
207
 
@@ -212,19 +214,19 @@ export class AttributesDelegate {
212
214
  }
213
215
 
214
216
  public setMainViewCamera(camera: ICamera) {
215
- console.log("[window-manager] setMainViewCamera====>", JSON.stringify(camera));
217
+ this.setMainViewCameraConsole.log(JSON.stringify(camera));
216
218
  this.context.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });
217
219
  }
218
220
 
219
221
  public setMainViewSize(size: ISize) {
220
222
  if (size.width === 0 || size.height === 0) return;
221
- console.log("[window-manager] setMainViewSize====>", JSON.stringify(size));
223
+ console.log("[window-manager] setMainViewSize size:" + JSON.stringify(size));
222
224
  this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
223
225
  }
224
226
 
225
227
  public setMainViewCameraAndSize(camera: ICamera, size: ISize) {
226
228
  if (size.width === 0 || size.height === 0) return;
227
- console.log("[window-manager] setMainViewCameraAndSize====>", JSON.stringify(camera), JSON.stringify(size));
229
+ console.log("[window-manager] setMainViewCameraAndSize camera:" + JSON.stringify(camera) + ", size:" + JSON.stringify(size));
228
230
  this.context.safeSetAttributes({
229
231
  [Fields.MainViewCamera]: { ...camera },
230
232
  [Fields.MainViewSize]: { ...size },
@@ -3,12 +3,15 @@ import { isFunction } from "lodash";
3
3
  import { WindowManager } from "./index";
4
4
  import type { EmitterType } from "./InternalEmitter";
5
5
  import type { UnsubscribeFn } from "emittery";
6
+ import { LocalConsole } from "./Utils/log";
6
7
 
7
8
  const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
8
9
 
9
10
  export class ContainerResizeObserver {
10
11
  private containerResizeObserver?: ResizeObserver;
11
12
  private disposer?: UnsubscribeFn;
13
+
14
+ private updateSizerLocalConsole = new LocalConsole("updateSizer", 30);
12
15
 
13
16
  constructor(private emitter: EmitterType) {}
14
17
 
@@ -28,19 +31,19 @@ export class ContainerResizeObserver {
28
31
  sizer: HTMLElement,
29
32
  wrapper: HTMLDivElement
30
33
  ) {
31
- this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
34
+ this.updateSizer(container.getBoundingClientRect(), sizer, wrapper, 'observePlaygroundSize');
32
35
 
33
36
  this.containerResizeObserver = new ResizeObserver(entries => {
34
37
  const containerRect = entries[0]?.contentRect;
35
38
  if (containerRect) {
36
- this.updateSizer(containerRect, sizer, wrapper);
39
+ this.updateSizer(containerRect, sizer, wrapper, 'containerResizeObserver');
37
40
  this.emitter.emit("playgroundSizeChange", containerRect);
38
41
  }
39
42
  });
40
43
 
41
44
  this.disposer = this.emitter.on("containerSizeRatioUpdate", () => {
42
45
  const containerRect = container.getBoundingClientRect();
43
- this.updateSizer(containerRect, sizer, wrapper);
46
+ this.updateSizer(containerRect, sizer, wrapper, 'containerSizeRatioUpdate');
44
47
  this.emitter.emit("playgroundSizeChange", containerRect);
45
48
  });
46
49
 
@@ -50,7 +53,8 @@ export class ContainerResizeObserver {
50
53
  public updateSizer(
51
54
  { width, height }: DOMRectReadOnly,
52
55
  sizer: HTMLElement,
53
- wrapper: HTMLDivElement
56
+ wrapper: HTMLDivElement,
57
+ origin?: string
54
58
  ) {
55
59
  if (width && height) {
56
60
  if (height / width > WindowManager.containerSizeRatio) {
@@ -62,6 +66,13 @@ export class ContainerResizeObserver {
62
66
  }
63
67
  wrapper.style.width = `${width}px`;
64
68
  wrapper.style.height = `${height}px`;
69
+ const wrapperRect = wrapper.getBoundingClientRect();
70
+ this.updateSizerLocalConsole.log(`from ${origin}, traget size: ${JSON.stringify({ width, height })}, wrapperRect: ${wrapperRect.width} ${wrapperRect.height}`);
71
+ this.emitter.emit("wrapperRectChange", {
72
+ width: wrapperRect.width,
73
+ height: wrapperRect.height,
74
+ origin,
75
+ });
65
76
  }
66
77
  }
67
78
 
@@ -29,6 +29,7 @@ export type EmitterEvent = {
29
29
  changePageState: undefined;
30
30
  writableChange: boolean;
31
31
  containerSizeRatioUpdate: number;
32
+ wrapperRectChange: { width: number; height: number; origin?: string };
32
33
  boxesStatusChange: Map<string, TeleBoxState>;
33
34
  lastNotMinimizedBoxesStatusChange: Map<string, NotMinimizedBoxState>;
34
35
  };
@@ -34,7 +34,6 @@ export const setScenePath = (room: Room | undefined, scenePath: string) => {
34
34
  if (room && room.isWritable) {
35
35
  if (room.state.sceneState.scenePath !== scenePath) {
36
36
  const nextScenePath = scenePath === "/" ? "" : scenePath;
37
- console.log("[window-manager] real setScenePath for current room====>", nextScenePath);
38
37
  room.setScenePath(nextScenePath);
39
38
  }
40
39
  }
@@ -30,8 +30,8 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
30
30
  };
31
31
  };
32
32
 
33
- export const safeListenPropsUpdated = <T>(
34
- getProps: () => T,
33
+ export const safeListenPropsUpdated = <T extends Record<string, unknown>>(
34
+ getProps: () => T | null | undefined,
35
35
  callback: AkkoObjectUpdatedListener<T>,
36
36
  onDestroyed?: (props: unknown) => void
37
37
  ) => {
@@ -35,8 +35,25 @@ export const replaceRoomFunction = (room: Room | Player, manager: WindowManager)
35
35
  });
36
36
  const _scalePptToFit = room.scalePptToFit;
37
37
  room.scalePptToFit = (...args) => {
38
- console.log("[window-manager] scalePptToFit====>", JSON.stringify(args));
39
38
  _scalePptToFit.call(room, ...args);
39
+ if (manager.appManager?.mainViewProxy) {
40
+ manager.appManager.mainViewProxy.setCameraAndSize();
41
+ }
42
+ };
43
+ const _putScenes = room.putScenes;
44
+ room.putScenes = (...args) => {
45
+ const [path, scenes] = args;
46
+ const currentScenePath = manager.mainView.focusScenePath;
47
+ if (currentScenePath && path && scenes) {
48
+ console.log("[window-manager] putScenes " + JSON.stringify(args));
49
+ for (const scene of scenes) {
50
+ if (`${path}${scene.name}` === currentScenePath) {
51
+ console.error(`[window-manager] putScenes: scene name can not be the same as the current scene path: ${currentScenePath}`);
52
+ return;
53
+ }
54
+ }
55
+ }
56
+ return _putScenes.call(room, ...args);
40
57
  };
41
58
  room.moveCamera = (camera: Camera) => manager.moveCamera(camera);
42
59
  room.moveCameraToContain = (...args) => manager.moveCameraToContain(...args);
package/src/Utils/log.ts CHANGED
@@ -5,3 +5,40 @@ export const log = (...args: any[]): void => {
5
5
  console.log(`[WindowManager]:`, ...args);
6
6
  }
7
7
  };
8
+
9
+ /**
10
+ * 按 `[window-manager][tagName]` 前缀输出。
11
+ * 若传入 `debounceTime`(毫秒):窗口内多次 `log` 不立即输出,只在连续停止调用满 `debounceTime` 后输出**最后一次**的参数(尾部 debounce)。
12
+ */
13
+ export class LocalConsole {
14
+ private pendingArgs: unknown[] | null = null;
15
+ private flushTimer: ReturnType<typeof setTimeout> | null = null;
16
+
17
+ constructor(
18
+ private readonly name: string,
19
+ private readonly debounceTime?: number,
20
+ ) {}
21
+
22
+ private flush(): void {
23
+ this.flushTimer = null;
24
+ const args = this.pendingArgs;
25
+ this.pendingArgs = null;
26
+ if (args === null) {
27
+ return;
28
+ }
29
+ console.log(`[window-manager][${this.name}]: ${args.join(", ")}`);
30
+ }
31
+
32
+ log(...args: unknown[]): void {
33
+ const ms = this.debounceTime;
34
+ if (ms != null && ms > 0) {
35
+ this.pendingArgs = args;
36
+ if (this.flushTimer != null) {
37
+ clearTimeout(this.flushTimer);
38
+ }
39
+ this.flushTimer = setTimeout(() => this.flush(), ms);
40
+ return;
41
+ }
42
+ console.log(`[window-manager][${this.name}]: ${args.join(", ")}`);
43
+ }
44
+ }
@@ -9,6 +9,7 @@ import { SideEffectManager } from "side-effect-manager";
9
9
  import type { Camera, Room, Size, View } from "white-web-sdk";
10
10
  import type { AppManager } from "../AppManager";
11
11
  import { Events } from "../constants";
12
+ import { LocalConsole } from "../Utils/log";
12
13
 
13
14
  export class MainViewProxy {
14
15
  /** Refresh the view's camera in an interval of 1.5s. */
@@ -17,12 +18,19 @@ export class MainViewProxy {
17
18
  private scale?: number;
18
19
  private started = false;
19
20
  private mainViewIsAddListener = false;
21
+ private isForcingMainViewDivElement = false;
22
+ private wrapperRectWorkaroundFrame = 0;
23
+ private pendingWrapperRectChange?: { width: number; height: number; origin?: string };
20
24
  private mainView: View;
21
25
  private store = this.manager.store;
22
26
  private viewMode = this.manager.windowManger.viewMode;
23
27
 
24
28
  private sideEffectManager = new SideEffectManager();
25
29
 
30
+ private playgroundSizeChangeListenerLocalConsole = new LocalConsole("playgroundSizeChangeListener", 30);
31
+ private sizeUpdatedLocalConsole = new LocalConsole("sizeUpdated", 30);
32
+ private cameraUpdatedLocalConsole = new LocalConsole("cameraUpdated", 30);
33
+
26
34
  constructor(private manager: AppManager) {
27
35
  this.mainView = this.createMainView();
28
36
  this.moveCameraSizeByAttributes();
@@ -33,7 +41,15 @@ export class MainViewProxy {
33
41
  this.startListenWritableChange();
34
42
  });
35
43
  const playgroundSizeChangeListener = () => {
36
- console.log("[window-manager] playgroundSizeChangeListener====>", JSON.stringify(this.mainViewSize));
44
+ this.playgroundSizeChangeListenerLocalConsole.log(
45
+ JSON.stringify(this.mainView.camera),
46
+ JSON.stringify(this.mainView.size),
47
+ JSON.stringify(this.mainViewSize),
48
+ JSON.stringify(this.mainViewCamera),
49
+ window.outerHeight, window.outerWidth,
50
+ window.visualViewport?.width ?? "null", window.visualViewport?.height ?? "null",
51
+ window.visualViewport?.offsetLeft ?? "null", window.visualViewport?.offsetTop ?? "null",
52
+ );
37
53
  this.sizeChangeHandler(this.mainViewSize);
38
54
  };
39
55
  this.sideEffectManager.add(() => {
@@ -42,6 +58,9 @@ export class MainViewProxy {
42
58
  this.sideEffectManager.add(() => {
43
59
  return internalEmitter.on("containerSizeRatioUpdate", this.onUpdateContainerSizeRatio);
44
60
  });
61
+ this.sideEffectManager.add(() => {
62
+ return internalEmitter.on("wrapperRectChange", this.onWrapperRectChange);
63
+ });
45
64
  this.sideEffectManager.add(() => {
46
65
  return internalEmitter.on("startReconnect", () => {
47
66
  if (!this.didRelease) {
@@ -97,14 +116,92 @@ export class MainViewProxy {
97
116
  this.moveCamera(this.mainViewCamera);
98
117
  }
99
118
 
119
+ private onWrapperRectChange = (payload: { width: number; height: number; origin?: string }) => {
120
+ this.pendingWrapperRectChange = payload;
121
+ if (this.wrapperRectWorkaroundFrame) {
122
+ cancelAnimationFrame(this.wrapperRectWorkaroundFrame);
123
+ }
124
+ this.wrapperRectWorkaroundFrame = requestAnimationFrame(this.runWrapperRectWorkaround);
125
+ };
126
+
127
+ private runWrapperRectWorkaround = () => {
128
+ this.wrapperRectWorkaroundFrame = 0;
129
+ const payload = this.pendingWrapperRectChange;
130
+ const element = this.mainView.divElement;
131
+ this.pendingWrapperRectChange = undefined;
132
+ if (!payload || !element) return;
133
+
134
+ const rect = element.getBoundingClientRect();
135
+ const observedSize = { width: rect.width, height: rect.height };
136
+ const wrapperMatchesDom =
137
+ Math.abs(payload.width - observedSize.width) <= 0.5 &&
138
+ Math.abs(payload.height - observedSize.height) <= 0.5;
139
+ const viewIsStale =
140
+ Math.abs(this.mainView.size.width - observedSize.width) > 0.5 ||
141
+ Math.abs(this.mainView.size.height - observedSize.height) > 0.5;
142
+
143
+ if (wrapperMatchesDom && viewIsStale) {
144
+ this.forceSyncMainViewDivElement(
145
+ `wrapperRectChange:${payload.origin || "unknown"}`,
146
+ observedSize,
147
+ element
148
+ );
149
+ }
150
+ };
151
+
152
+ private forceSyncMainViewDivElement(
153
+ reason: string,
154
+ observedSize: Pick<Size, "width" | "height">,
155
+ element: HTMLDivElement
156
+ ) {
157
+ const { width: viewWidth, height: viewHeight } = this.mainView.size;
158
+ if (
159
+ Math.abs(viewWidth - observedSize.width) <= 0.5 &&
160
+ Math.abs(viewHeight - observedSize.height) <= 0.5
161
+ ) {
162
+ return;
163
+ }
164
+ if (this.isForcingMainViewDivElement) {
165
+ console.log("[window-manager] skipForceSyncMainViewDivElement " + JSON.stringify({
166
+ reason,
167
+ observedSize,
168
+ viewSize: this.mainView.size,
169
+ }));
170
+ return;
171
+ }
172
+ this.isForcingMainViewDivElement = true;
173
+ console.log("[window-manager] forceSyncMainViewDivElement " + JSON.stringify({
174
+ reason,
175
+ observedSize,
176
+ viewSize: this.mainView.size,
177
+ mainViewSize: this.mainViewSize,
178
+ mainViewCamera: this.mainViewCamera,
179
+ }));
180
+ this.mainView.divElement = null;
181
+ this.mainView.divElement = element;
182
+ queueMicrotask(() => {
183
+ const rect = element.getBoundingClientRect();
184
+ console.log("[window-manager] forceSyncMainViewDivElementResult " + JSON.stringify({
185
+ reason,
186
+ viewSize: this.mainView.size,
187
+ rect: { width: rect.width, height: rect.height },
188
+ }));
189
+ this.isForcingMainViewDivElement = false;
190
+ });
191
+ }
192
+
100
193
  public start() {
101
- console.log("[window-manager] start====>", JSON.stringify(this.mainViewSize));
194
+ console.log("[window-manager] start attributes size:" + JSON.stringify(this.mainViewSize));
102
195
  this.sizeChangeHandler(this.mainViewSize);
103
196
  if (this.started) return;
104
197
  this.addCameraListener();
105
198
  this.addCameraReaction();
106
199
  if (this.manager.room) this.syncMainView(this.manager.room);
107
200
  this.started = true;
201
+ if(this.mainView.focusScenePath) {
202
+ this.manager.windowManger.onMainViewScenePathChangeHandler(this.mainView.focusScenePath);
203
+ }
204
+ console.log("[window-manager] start end mainView size:" + JSON.stringify(this.mainView.size));
108
205
  }
109
206
 
110
207
  public addCameraReaction = () => {
@@ -122,7 +219,7 @@ export class MainViewProxy {
122
219
  () => this.mainViewCamera,
123
220
  camera => {
124
221
  if (camera && camera.id !== this.manager.uid) {
125
- console.log("[window-manager] cameraReaction====>", JSON.stringify(camera), JSON.stringify(this.mainViewSize));
222
+ console.log("[window-manager] cameraReaction " + JSON.stringify(camera) + JSON.stringify(this.mainViewSize));
126
223
  this.moveCameraToContian(this.mainViewSize);
127
224
  this.moveCamera(camera);
128
225
  }
@@ -135,14 +232,15 @@ export class MainViewProxy {
135
232
  if (size) {
136
233
  this.moveCameraToContian(size);
137
234
  this.moveCamera(this.mainViewCamera);
138
- console.log("[window-manager] sizeChangeHandler====> current size and camera", JSON.stringify(size), JSON.stringify(this.mainViewCamera));
235
+ console.log("[window-manager] sizeChangeHandler current size and camera" + JSON.stringify(size) + JSON.stringify(this.mainViewCamera) +
236
+ JSON.stringify(this.mainView.camera) + JSON.stringify(this.mainView.size));
139
237
  }
140
238
  this.ensureMainViewSize();
141
239
  }, 30);
142
240
 
143
241
  public onUpdateContainerSizeRatio = () => {
144
242
  const size = this.store.getMainViewSize();
145
- console.log("[window-manager] onUpdateContainerSizeRatio====>", JSON.stringify(size));
243
+ console.log("[window-manager] onUpdateContainerSizeRatio " + JSON.stringify(size));
146
244
  this.sizeChangeHandler(size);
147
245
  };
148
246
 
@@ -235,18 +333,18 @@ export class MainViewProxy {
235
333
 
236
334
  private addCameraListener() {
237
335
  this.view.callbacks.on("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
238
- this.view.callbacks.on("onCameraUpdated", this.onCameraOrSizeUpdated);
239
- this.view.callbacks.on("onSizeUpdated", this.onCameraOrSizeUpdated);
336
+ this.view.callbacks.on("onCameraUpdated", this.onCameraUpdated);
337
+ this.view.callbacks.on("onSizeUpdated", this.onSizeUpdated);
240
338
  }
241
339
 
242
340
  private removeCameraListener() {
243
341
  this.view.callbacks.off("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
244
- this.view.callbacks.off("onCameraUpdated", this.onCameraOrSizeUpdated);
245
- this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
342
+ this.view.callbacks.off("onCameraUpdated", this.onCameraUpdated);
343
+ this.view.callbacks.off("onSizeUpdated", this.onSizeUpdated);
246
344
  }
247
345
 
248
346
  private _syncMainViewTimer = 0;
249
- private onCameraOrSizeUpdated = () => {
347
+ private handleCameraOrSizeUpdated = () => {
250
348
  callbacks.emit("cameraStateChange", this.cameraState);
251
349
  // sdk >= 2.16.43 的 syncMainView() 可以写入当前 main view 的 camera, 以修复复制粘贴元素的位置
252
350
  // 注意到这个操作会发送信令,应当避免频繁调用
@@ -254,10 +352,19 @@ export class MainViewProxy {
254
352
  clearTimeout(this._syncMainViewTimer);
255
353
  this._syncMainViewTimer = setTimeout(this.syncMainView, 100, this.manager.room);
256
354
  }
257
- console.log("[window-manager] onCameraOrSizeUpdated====>", JSON.stringify(this.cameraState));
258
355
  this.ensureMainViewSize();
259
356
  };
260
357
 
358
+ private onCameraUpdated = (camera: Camera) => {
359
+ this.cameraUpdatedLocalConsole.log(JSON.stringify(camera));
360
+ this.handleCameraOrSizeUpdated();
361
+ };
362
+
363
+ private onSizeUpdated = (size: Size) => {
364
+ this.sizeUpdatedLocalConsole.log(JSON.stringify(size));
365
+ this.handleCameraOrSizeUpdated();
366
+ };
367
+
261
368
  private ensureMainViewSize() {
262
369
  if (
263
370
  (!this.mainViewSize ||
@@ -272,7 +379,7 @@ export class MainViewProxy {
272
379
 
273
380
  private syncMainView = (room: Room) => {
274
381
  if (room.isWritable) {
275
- console.log("[window-manager] syncMainView====>");
382
+ console.log("[window-manager] syncMainView ");
276
383
  room.syncMainView(this.mainView);
277
384
  }
278
385
  };
@@ -316,6 +423,11 @@ export class MainViewProxy {
316
423
  };
317
424
 
318
425
  public destroy() {
426
+ console.log("[window-manager] destroy ");
427
+ if (this.wrapperRectWorkaroundFrame) {
428
+ cancelAnimationFrame(this.wrapperRectWorkaroundFrame);
429
+ this.wrapperRectWorkaroundFrame = 0;
430
+ }
319
431
  this.removeMainViewListener();
320
432
  this.stop();
321
433
  this.sideEffectManager.flushAll();