@netless/window-manager 1.0.0-canary.21 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "1.0.0-canary.21",
3
+ "version": "1.0.0-canary.22",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -28,7 +28,12 @@ import type {
28
28
  import { WhiteBoardView } from "./WhiteboardView";
29
29
  import { findMemberByUid } from "../Helper";
30
30
  import { MAX_PAGE_SIZE } from "../constants";
31
- import { isNumber } from "lodash";
31
+ import { isBoolean, isNumber } from "lodash";
32
+
33
+ export type CreateWhiteBoardViewParams = {
34
+ size?: number;
35
+ syncCamera?: boolean;
36
+ }
32
37
 
33
38
  export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {
34
39
  public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
@@ -86,7 +91,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
86
91
  return this.appProxy.view;
87
92
  };
88
93
 
89
- public createWhiteBoardView = (size?: number): WhiteBoardView => {
94
+ public createWhiteBoardView = (params?: CreateWhiteBoardViewParams): WhiteBoardView => {
90
95
  if (this.whiteBoardView) {
91
96
  return this.whiteBoardView;
92
97
  }
@@ -94,6 +99,11 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
94
99
  if (!view) {
95
100
  view = this.appProxy.createAppDir();
96
101
  }
102
+ if (params) {
103
+ if (isBoolean(params.syncCamera)) {
104
+ this.appProxy.syncCamera$.setValue(params.syncCamera);
105
+ }
106
+ }
97
107
  const viewWrapper = document.createElement("div");
98
108
  this._viewWrapper = viewWrapper;
99
109
  viewWrapper.className = "window-manager-view-wrapper";
@@ -101,7 +111,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
101
111
  view.divElement = viewWrapper;
102
112
  this.appProxy.fireMemberStateChange();
103
113
  if (this.isAddApp) {
104
- this.ensurePageSize(size);
114
+ this.ensurePageSize(params?.size);
105
115
  }
106
116
  this.whiteBoardView = new WhiteBoardView(view, this, this.appProxy, this.ensurePageSize);
107
117
  this.appProxy.sideEffectManager.add(() => {
@@ -109,6 +119,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
109
119
  this.whiteBoardView = undefined;
110
120
  }
111
121
  });
122
+ this.appProxy.whiteBoardViewCreated$.setValue(true);
112
123
  return this.whiteBoardView;
113
124
  }
114
125
 
@@ -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,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 };