@netless/window-manager 1.0.0-canary.21 → 1.0.0-canary.24

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.
@@ -71,6 +71,8 @@ export class AppProxy implements PageRemoveService {
71
71
  public size$ = this.valManager.attach(new Val<ISize | undefined>(undefined));
72
72
  public box$ = this.valManager.attach(new Val<ReadonlyTeleBox | undefined>(undefined));
73
73
  public view$ = this.valManager.attach(new Val<View | undefined>(undefined));
74
+ public syncCamera$ = this.valManager.attach(new Val<boolean>(true));
75
+ public whiteBoardViewCreated$ = this.valManager.attach(new Val<boolean>(false));
74
76
 
75
77
  constructor(
76
78
  private params: BaseInsertParams,
@@ -112,101 +114,61 @@ export class AppProxy implements PageRemoveService {
112
114
  this.size$.setValue(toJS(this.appAttributes.size));
113
115
  this.addCameraReaction();
114
116
  this.addSizeReaction();
115
- this.sideEffectManager.add(() =>
116
- combine([this.box$, this.view$]).subscribe(([box, view]) => {
117
- if (box && view) {
118
- if (!this.camera$.value) {
119
- this.storeCamera({
120
- centerX: null,
121
- centerY: null,
122
- scale: 1,
123
- id: this.uid,
124
- });
125
- this.camera$.setValue(toJS(this.appAttributes.camera));
126
- }
127
- if (!this.size$.value && box.contentStageRect) {
128
- const initialRect = this.computedInitialRect(box.contentStageRect);
129
- const width = initialRect?.width || box.contentStageRect.width;
130
- const height = initialRect?.height || box.contentStageRect.height;
131
- this.storeSize({
132
- id: this.uid,
133
- width,
134
- height,
135
- });
136
- this.size$.setValue(toJS(this.appAttributes.size));
137
- }
138
- this.viewSync = new ViewSync({
139
- uid: this.uid,
140
- view$: this.view$,
141
- camera$: this.camera$,
142
- size$: this.size$,
143
- stageRect$: box._contentStageRect$,
144
- storeCamera: this.storeCamera,
145
- storeSize: this.storeSize
146
- });
147
- this.sideEffectManager.add(() => () => this.viewSync?.destroy());
148
- }
149
- })
150
- );
151
117
  this.sideEffectManager.add(() =>
152
118
  emitter.on("memberStateChange", this.onMemberStateChange)
153
119
  );
154
- this.box$.subscribe(box => {
155
- if (!box) return;
156
- this.sideEffectManager.add(() => [
157
- createValSync(
158
- () => this.appAttributes?.state.visible,
159
- box._visible$,
160
- ),
161
- createValSync(
162
- () => this.appAttributes?.state.ratio,
163
- box._ratio$,
164
- ),
165
- createValSync(
166
- () => this.appAttributes?.state.stageRatio,
167
- box._stageRatio$,
168
- ),
169
- createValSync(
170
- () => this.appAttributes?.state.draggable,
171
- box._draggable$,
172
- ),
173
- createValSync(
174
- () => this.appAttributes?.state.resizable,
175
- box._resizable$,
176
- ),
177
- box._visible$.reaction((visible, skipUpdate) => {
178
- if (skipUpdate) {
179
- return;
180
- }
181
- this.store.updateAppState(this.id, AppAttributes.Visible, visible);
182
- }),
183
- box._ratio$.reaction((ratio, skipUpdate) => {
184
- console.log("ratio change", ratio, skipUpdate);
185
- if (skipUpdate) {
186
- return;
187
- }
188
- this.store.updateAppState(this.id, AppAttributes.Ratio, ratio);
189
- }),
190
- box._stageRatio$.reaction((stageRatio, skipUpdate) => {
191
- if (skipUpdate) {
192
- return;
120
+ this.sideEffectManager.add(() => [
121
+ this.syncCamera$.reaction(syncCamera => {
122
+ if (!syncCamera) {
123
+ if (this.viewSync) {
124
+ this.viewSync.destroy();
125
+ this.viewSync = undefined;
126
+ this.sideEffectManager.flush("camera");
127
+ this.sideEffectManager.flush("size");
193
128
  }
194
- this.store.updateAppState(this.id, AppAttributes.StageRatio, stageRatio);
195
- }),
196
- box._draggable$.reaction((draggable, skipUpdate) => {
197
- if (skipUpdate) {
198
- return;
199
- }
200
- this.store.updateAppState(this.id, AppAttributes.Draggable, draggable);
201
- }),
202
- box._resizable$.reaction((resizable, skipUpdate) => {
203
- if (skipUpdate) {
204
- return;
205
- }
206
- this.store.updateAppState(this.id, AppAttributes.Resizable, resizable);
207
- }),
208
- ])
209
- });
129
+ }
130
+ }),
131
+ this.whiteBoardViewCreated$.reaction(created => {
132
+ if (created && this.box) {
133
+ if (!this.syncCamera$.value) return;
134
+ combine([this.box$, this.view$]).subscribe(([box, view]) => {
135
+ if (box && view) {
136
+ if (!this.camera$.value) {
137
+ this.storeCamera({
138
+ centerX: null,
139
+ centerY: null,
140
+ scale: 1,
141
+ id: this.uid,
142
+ });
143
+ this.camera$.setValue(toJS(this.appAttributes.camera));
144
+ }
145
+ if (!this.size$.value && box.contentStageRect) {
146
+ const initialRect = this.computedInitialRect(box.contentStageRect);
147
+ const width = initialRect?.width || box.contentStageRect.width;
148
+ const height = initialRect?.height || box.contentStageRect.height;
149
+ this.storeSize({
150
+ id: this.uid,
151
+ width,
152
+ height,
153
+ });
154
+ this.size$.setValue(toJS(this.appAttributes.size));
155
+ }
156
+ this.viewSync = new ViewSync({
157
+ uid: this.uid,
158
+ view$: this.view$,
159
+ camera$: this.camera$,
160
+ size$: this.size$,
161
+ stageRect$: box._contentStageRect$,
162
+ storeCamera: this.storeCamera,
163
+ storeSize: this.storeSize
164
+ });
165
+ this.sideEffectManager.add(() => () => this.viewSync?.destroy());
166
+ this.whiteBoardViewCreated$.destroy();
167
+ }
168
+ })
169
+ }
170
+ })
171
+ ]);
210
172
  }
211
173
 
212
174
  public fireMemberStateChange = () => {
@@ -383,11 +345,6 @@ export class AppProxy implements PageRemoveService {
383
345
  this.box$.setValue(box);
384
346
  if (this.isAddApp && this.box) {
385
347
  this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
386
- this.store.updateAppState(appId, AppAttributes.Visible, this.box.visible);
387
- this.store.updateAppState(appId, AppAttributes.Ratio, this.box.ratio);
388
- this.store.updateAppState(appId, AppAttributes.StageRatio, this.box.stageRatio);
389
- this.store.updateAppState(appId, AppAttributes.Draggable, this.box.draggable);
390
- this.store.updateAppState(appId, AppAttributes.Resizable, this.box.resizable);
391
348
  this.boxManager.focusBox({ appId }, false);
392
349
  }
393
350
  } catch (error: any) {
@@ -520,32 +477,34 @@ export class AppProxy implements PageRemoveService {
520
477
  }
521
478
 
522
479
  private appAttributesUpdateListener = (appId: string) => {
523
- this.manager.refresher.add(appId, () => {
524
- return autorun(() => {
525
- const attrs = this.manager.attributes[appId];
526
- if (attrs) {
527
- this.appEmitter.emit("attributesUpdate", attrs);
528
- }
529
- });
530
- });
531
- this.manager.refresher.add(this.stateKey, () => {
532
- return autorun(() => {
533
- const appState = this.appAttributes?.state;
534
- if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
535
- this.boxManager?.setZIndex(appId, appState.zIndex);
536
- }
537
- });
538
- });
539
- this.manager.refresher.add(`${appId}-fullPath`, () => {
540
- return autorun(() => {
541
- const fullPath = this.appAttributes?.fullPath;
542
- this.setFocusScenePathHandler(fullPath);
543
- if (this.fullPath$.value !== fullPath) {
544
- this.notifyPageStateChange();
545
- this.fullPath$.setValue(fullPath);
546
- }
547
- });
548
- });
480
+ this.sideEffectManager.add(() => [
481
+ this.manager.refresher.add(appId, () => {
482
+ return autorun(() => {
483
+ const attrs = this.manager.attributes[appId];
484
+ if (attrs) {
485
+ this.appEmitter.emit("attributesUpdate", attrs);
486
+ }
487
+ });
488
+ }),
489
+ this.manager.refresher.add(this.stateKey, () => {
490
+ return autorun(() => {
491
+ const appState = this.appAttributes?.state;
492
+ if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
493
+ this.boxManager?.setZIndex(appId, appState.zIndex);
494
+ }
495
+ });
496
+ }),
497
+ this.manager.refresher.add(`${appId}-fullPath`, () => {
498
+ return autorun(() => {
499
+ const fullPath = this.appAttributes?.fullPath;
500
+ this.setFocusScenePathHandler(fullPath);
501
+ if (this.fullPath$.value !== fullPath) {
502
+ this.notifyPageStateChange();
503
+ this.fullPath$.setValue(fullPath);
504
+ }
505
+ });
506
+ }),
507
+ ]);
549
508
  };
550
509
 
551
510
  private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
@@ -683,11 +642,6 @@ export class AppProxy implements PageRemoveService {
683
642
 
684
643
  this.viewManager.destroyView(this.id);
685
644
  this.manager.appStatus.delete(this.id);
686
- this.manager.refresher.remove(this.id);
687
- this.manager.refresher.remove(this.stateKey);
688
- this.manager.refresher.remove(`${this.id}-fullPath`);
689
- this.manager.refresher.remove(`${this.id}-camera`);
690
- this.manager.refresher.remove(`${this.id}-size`);
691
645
  this.valManager.destroy();
692
646
  }
693
647
 
@@ -735,16 +689,3 @@ export class AppProxy implements PageRemoveService {
735
689
  return this.destroy(true, true, false);
736
690
  }
737
691
  }
738
-
739
-
740
- const createValSync = (expr: any, Val: Val): (() => void) => {
741
- return reaction(
742
- expr,
743
- val => {
744
- if (Val.value !== val && val !== undefined) {
745
- Val.setValue(val, true);
746
- }
747
- },
748
- { fireImmediately: true }
749
- );
750
- };
@@ -46,7 +46,11 @@ 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
  };
@@ -1,5 +1,5 @@
1
1
  import { AnimationMode } from "white-web-sdk";
2
- import { debounce, delay, isEqual, pick, throttle } from "lodash";
2
+ import { isEqual, pick, throttle } from "lodash";
3
3
  import type { TeleBoxRect } from "@netless/telebox-insider";
4
4
  import type { Camera, View } from "white-web-sdk";
5
5
  import type { ICamera, ISize } from "../AttributesDelegate";
@@ -14,12 +14,12 @@ export class CameraSynchronizer {
14
14
 
15
15
  constructor(protected saveCamera: SaveCamera) {}
16
16
 
17
- public setRect = debounce((rect: TeleBoxRect) => {
17
+ public setRect = (rect: TeleBoxRect) => {
18
18
  this.rect = rect;
19
19
  if (this.remoteCamera && this.remoteSize) {
20
20
  this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
21
21
  }
22
- }, 10);
22
+ }
23
23
 
24
24
  public setView(view: View) {
25
25
  this.view = view;
@@ -37,22 +37,17 @@ export class CameraSynchronizer {
37
37
  scale = this.rect.height / size.height;
38
38
  }
39
39
  const nextScale = camera.scale * scale;
40
- const moveCamera = () => {
41
- const config: Partial<Camera> & { animationMode: AnimationMode } = {
42
- scale: nextScale,
43
- animationMode: AnimationMode.Immediately,
44
- }
45
- if (camera.centerX !== null) {
46
- config.centerX = camera.centerX;
47
- }
48
- if (camera.centerY !== null) {
49
- config.centerY = camera.centerY;
50
- }
51
- this.view?.moveCamera(config);
40
+ const config: Partial<Camera> & { animationMode: AnimationMode } = {
41
+ scale: nextScale,
42
+ animationMode: AnimationMode.Immediately,
43
+ }
44
+ if (camera.centerX !== null) {
45
+ config.centerX = camera.centerX;
46
+ }
47
+ if (camera.centerY !== null) {
48
+ config.centerY = camera.centerY;
52
49
  }
53
- moveCamera();
54
- // TODO 直接调用 moveCamera 依然会出现 camera 错误的情况,这里暂时加一个 delay 保证 camera 是对的, 后续需要 SDK 进行修改
55
- delay(moveCamera, 50);
50
+ this.view?.moveCamera(config);
56
51
  }
57
52
  }, 10);
58
53
 
@@ -62,14 +57,10 @@ export class CameraSynchronizer {
62
57
  if (this.rect && this.remoteCamera && needMoveCamera) {
63
58
  const scale = this.rect.width / size.width;
64
59
  const nextScale = this.remoteCamera.scale * scale;
65
- const moveCamera = () => {
66
- this.view?.moveCamera({
67
- scale: nextScale,
68
- animationMode: AnimationMode.Immediately,
69
- })
70
- };
71
- moveCamera();
72
- delay(moveCamera, 50);
60
+ this.view?.moveCamera({
61
+ scale: nextScale,
62
+ animationMode: AnimationMode.Immediately,
63
+ })
73
64
  }
74
65
  }
75
66
 
@@ -1,4 +1,4 @@
1
- import { AnimationMode, toJS, ViewMode } from "white-web-sdk";
1
+ import { AnimationMode, ViewMode } from "white-web-sdk";
2
2
  import { CameraSynchronizer } from "./CameraSynchronizer";
3
3
  import { combine } from "value-enhancer";
4
4
  import { isEqual } from "lodash";
@@ -93,7 +93,8 @@ export class ViewSync {
93
93
  };
94
94
 
95
95
  private onCameraUpdatedByDevice = (camera: Camera) => {
96
- this.synchronizer.onLocalCameraUpdate(Object.assign(toJS(camera), { id: this.context.uid }));
96
+ if (!camera) return;
97
+ this.synchronizer.onLocalCameraUpdate({ ...camera, id: this.context.uid });
97
98
  const stage = this.context.stageRect$.value;
98
99
  if (stage) {
99
100
  const size = { width: stage.width, height: stage.height, id: this.context.uid };
package/src/style.css CHANGED
@@ -185,4 +185,5 @@
185
185
  position: absolute;
186
186
  left: 0;
187
187
  top: 0;
188
+ z-index: 1;
188
189
  }