@netless/window-manager 1.0.13-test.11 → 1.0.13-test.13

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.11",
3
+ "version": "1.0.13-test.13",
4
4
  "description": "Multi-window mode for Netless Whiteboard",
5
5
  "author": "l1shen <lishen1635@gmail.com> (https://github.com/l1shen)",
6
6
  "license": "MIT",
@@ -19,6 +19,8 @@ export class MainViewProxy {
19
19
  private scale?: number;
20
20
  private started = false;
21
21
  private mainViewIsAddListener = false;
22
+ private mainViewResizeObserver?: ResizeObserver;
23
+ private isForcingMainViewDivElement = false;
22
24
  private mainView: View;
23
25
  private store = this.manager.store;
24
26
  private viewMode = this.manager.windowManger.viewMode;
@@ -31,13 +33,14 @@ export class MainViewProxy {
31
33
  this.mainView = this.createMainView();
32
34
  this.moveCameraSizeByAttributes();
33
35
  internalEmitter.once("mainViewMounted").then(() => {
36
+ this.observeMainViewDivElement();
34
37
  this.addMainViewListener();
35
38
  this.start();
36
39
  this.ensureCameraAndSize();
37
40
  this.startListenWritableChange();
38
41
  });
39
42
  const playgroundSizeChangeListener = () => {
40
- this.refreshScreenSizeIfStale();
43
+ // this.refreshScreenSizeIfStale();
41
44
  this.playgroundSizeChangeListenerLocalConsole.log(
42
45
  JSON.stringify(this.mainView.camera),
43
46
  JSON.stringify(this.mainView.size),
@@ -116,16 +119,48 @@ export class MainViewProxy {
116
119
 
117
120
  const { width, height } = element.getBoundingClientRect();
118
121
  if (width <= 0 || height <= 0) return;
122
+ this.forceSyncMainViewDivElement("playgroundSizeChange", { width, height }, element);
123
+ }
119
124
 
125
+ private forceSyncMainViewDivElement(
126
+ reason: string,
127
+ observedSize: Pick<Size, "width" | "height">,
128
+ element: HTMLDivElement
129
+ ) {
120
130
  const { width: viewWidth, height: viewHeight } = this.mainView.size;
121
- if (Math.abs(viewWidth - width) > 0.5 || Math.abs(viewHeight - height) > 0.5) {
122
- const resizableView = this.mainView as View & { resizeScreen?: () => void };
123
- console.log("[window-manager] forceResizeScreen stale size" + JSON.stringify({
131
+ if (
132
+ Math.abs(viewWidth - observedSize.width) <= 0.5 &&
133
+ Math.abs(viewHeight - observedSize.height) <= 0.5
134
+ ) {
135
+ return;
136
+ }
137
+ if (this.isForcingMainViewDivElement) {
138
+ console.log("[window-manager] skipForceSyncMainViewDivElement " + JSON.stringify({
139
+ reason,
140
+ observedSize,
124
141
  viewSize: this.mainView.size,
125
- domSize: { width, height },
126
142
  }));
127
- resizableView.resizeScreen?.();
143
+ return;
128
144
  }
145
+ this.isForcingMainViewDivElement = true;
146
+ console.log("[window-manager] forceSyncMainViewDivElement " + JSON.stringify({
147
+ reason,
148
+ observedSize,
149
+ viewSize: this.mainView.size,
150
+ mainViewSize: this.mainViewSize,
151
+ mainViewCamera: this.mainViewCamera,
152
+ }));
153
+ this.mainView.divElement = null;
154
+ this.mainView.divElement = element;
155
+ queueMicrotask(() => {
156
+ const rect = element.getBoundingClientRect();
157
+ console.log("[window-manager] forceSyncMainViewDivElementResult " + JSON.stringify({
158
+ reason,
159
+ viewSize: this.mainView.size,
160
+ rect: { width: rect.width, height: rect.height },
161
+ }));
162
+ this.isForcingMainViewDivElement = false;
163
+ });
129
164
  }
130
165
 
131
166
  public start() {
@@ -136,6 +171,7 @@ export class MainViewProxy {
136
171
  this.addCameraReaction();
137
172
  if (this.manager.room) this.syncMainView(this.manager.room);
138
173
  this.started = true;
174
+ console.log("[window-manager] start end " + JSON.stringify(this.mainViewSize), JSON.stringify(this.mainView.size));
139
175
  }
140
176
 
141
177
  public addCameraReaction = () => {
@@ -218,9 +254,11 @@ export class MainViewProxy {
218
254
  this.mainView.release();
219
255
  }
220
256
  this.removeMainViewListener();
257
+ this.disconnectMainViewResizeObserver();
221
258
  this.mainView = this.createMainView();
222
259
  this.mainView.disableCameraTransform = disableCameraTransform;
223
260
  this.mainView.divElement = divElement;
261
+ this.observeMainViewDivElement();
224
262
  this.addMainViewListener();
225
263
  this.start();
226
264
  callbacks.emit("onMainViewRebind", this.mainView);
@@ -267,25 +305,84 @@ export class MainViewProxy {
267
305
 
268
306
  private addCameraListener() {
269
307
  this.view.callbacks.on("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
270
- this.view.callbacks.on("onCameraUpdated", this.onCameraOrSizeUpdated);
271
- this.view.callbacks.on("onSizeUpdated", this.onCameraOrSizeUpdated);
308
+ this.view.callbacks.on("onCameraUpdated", this.onCameraUpdated);
309
+ this.view.callbacks.on("onSizeUpdated", this.onSizeUpdated);
272
310
  }
273
311
 
274
312
  private removeCameraListener() {
275
313
  this.view.callbacks.off("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
276
- this.view.callbacks.off("onCameraUpdated", this.onCameraOrSizeUpdated);
277
- this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
314
+ this.view.callbacks.off("onCameraUpdated", this.onCameraUpdated);
315
+ this.view.callbacks.off("onSizeUpdated", this.onSizeUpdated);
316
+ }
317
+
318
+ private observeMainViewDivElement() {
319
+ this.disconnectMainViewResizeObserver();
320
+ if (!("ResizeObserver" in window)) return;
321
+ if (!this.mainView.divElement) return;
322
+ console.log("[window-manager] observeMainViewDivElement " + JSON.stringify({
323
+ rect: this.mainView.divElement.getBoundingClientRect(),
324
+ viewSize: this.mainView.size,
325
+ }));
326
+ this.mainViewResizeObserver = new window.ResizeObserver(this.onResize);
327
+ this.mainViewResizeObserver.observe(this.mainView.divElement);
278
328
  }
279
329
 
330
+ private disconnectMainViewResizeObserver() {
331
+ this.mainViewResizeObserver?.disconnect();
332
+ this.mainViewResizeObserver = undefined;
333
+ }
334
+
335
+ private onResize = (entries: ResizeObserverEntry[]) => {
336
+ const entry = entries[0];
337
+ if (!entry) return;
338
+ const target = entry.target as HTMLDivElement;
339
+ const child = target.children[0] as HTMLElement | undefined;
340
+ const observedSize = {
341
+ width: entry.contentRect.width,
342
+ height: entry.contentRect.height,
343
+ };
344
+ console.log("[window-manager] mainViewResizeObserver " + JSON.stringify({
345
+ sameTarget: target === this.mainView.divElement,
346
+ contentRect: {
347
+ width: observedSize.width,
348
+ height: observedSize.height,
349
+ },
350
+ client: {
351
+ width: target.clientWidth,
352
+ height: target.clientHeight,
353
+ },
354
+ offset: {
355
+ width: target.offsetWidth,
356
+ height: target.offsetHeight,
357
+ },
358
+ rect: {
359
+ width: target.getBoundingClientRect().width,
360
+ height: target.getBoundingClientRect().height,
361
+ },
362
+ childRect: child
363
+ ? {
364
+ width: child.getBoundingClientRect().width,
365
+ height: child.getBoundingClientRect().height,
366
+ }
367
+ : null,
368
+ viewSize: this.mainView.size,
369
+ }));
370
+ this.forceSyncMainViewDivElement("mainViewResizeObserver", observedSize, target);
371
+ };
372
+
280
373
  private _syncMainViewTimer = 0;
281
- private onCameraOrSizeUpdated = () => {
282
- console.log("[window-manager] onCameraOrSizeUpdated " + JSON.stringify(this.cameraState));
374
+ private handleCameraOrSizeUpdated = (
375
+ source: "onCameraUpdated" | "onSizeUpdated",
376
+ payload: Camera | Size
377
+ ) => {
378
+ console.log("[window-manager] " + source + " payload " + JSON.stringify(payload));
379
+ console.log("[window-manager] " + source + " state " + JSON.stringify(this.cameraState));
283
380
  if(this.mainView.divElement){
284
381
  const children = this.mainView.divElement.children;
285
- console.log("[window-manager] onCameraOrSizeUpdated " + this.mainView.divElement.getBoundingClientRect());
382
+ console.log("[window-manager] " + source + " rect " + JSON.stringify(this.mainView.divElement.getBoundingClientRect()));
286
383
  const child = children[0];
287
384
  if (child) {
288
- console.log("[window-manager] child" + JSON.stringify(child.getBoundingClientRect()));
385
+ console.log("[window-manager] " + source + " child" + JSON.stringify(child.getBoundingClientRect()));
289
386
  }
290
387
  }
291
388
  callbacks.emit("cameraStateChange", this.cameraState);
@@ -298,6 +395,14 @@ export class MainViewProxy {
298
395
  this.ensureMainViewSize();
299
396
  };
300
397
 
398
+ private onCameraUpdated = (camera: Camera) => {
399
+ this.handleCameraOrSizeUpdated("onCameraUpdated", camera);
400
+ };
401
+
402
+ private onSizeUpdated = (size: Size) => {
403
+ this.handleCameraOrSizeUpdated("onSizeUpdated", size);
404
+ };
405
+
301
406
  private ensureMainViewSize() {
302
407
  if (
303
408
  (!this.mainViewSize ||
@@ -356,7 +461,9 @@ export class MainViewProxy {
356
461
  };
357
462
 
358
463
  public destroy() {
464
+ console.log("[window-manager] destroy ");
359
465
  this.removeMainViewListener();
466
+ this.disconnectMainViewResizeObserver();
360
467
  this.stop();
361
468
  this.sideEffectManager.flushAll();
362
469
  }