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

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.20",
3
+ "version": "1.0.0-canary.21",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -9,7 +9,7 @@ import { boxEmitter } from "../BoxEmitter";
9
9
  import { BoxManagerNotFoundError } from "../Utils/error";
10
10
  import { calculateNextIndex } from "../Page";
11
11
  import { combine, Val, ValManager } from "value-enhancer";
12
- import { debounce, get, isEqual } from "lodash";
12
+ import { debounce, get, isEqual, isUndefined, omitBy } from "lodash";
13
13
  import { emitter } from "../InternalEmitter";
14
14
  import { Fields } from "../AttributesDelegate";
15
15
  import { log } from "../Utils/log";
@@ -25,7 +25,6 @@ import {
25
25
  } from "../Utils/Common";
26
26
  import type {
27
27
  AppEmitterEvent,
28
- AppInitState,
29
28
  BaseInsertParams,
30
29
  setAppOptions,
31
30
  AppListenerKeys,
@@ -35,7 +34,7 @@ import type { AppManager } from "../AppManager";
35
34
  import type { NetlessApp } from "../typings";
36
35
  import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
37
36
  import type { PageRemoveService, PageState } from "../Page";
38
- import { createValSync } from "../Utils/Reactive";
37
+ import type { AppState } from "./type";
39
38
 
40
39
  export type AppEmitter = Emittery<AppEmitterEvent>;
41
40
 
@@ -158,42 +157,52 @@ export class AppProxy implements PageRemoveService {
158
157
  createValSync(
159
158
  () => this.appAttributes?.state.visible,
160
159
  box._visible$,
161
- this.isAddApp,
162
160
  ),
163
161
  createValSync(
164
162
  () => this.appAttributes?.state.ratio,
165
163
  box._ratio$,
166
- this.isAddApp,
167
164
  ),
168
165
  createValSync(
169
166
  () => this.appAttributes?.state.stageRatio,
170
167
  box._stageRatio$,
171
- this.isAddApp,
172
168
  ),
173
169
  createValSync(
174
170
  () => this.appAttributes?.state.draggable,
175
171
  box._draggable$,
176
- this.isAddApp,
177
172
  ),
178
173
  createValSync(
179
174
  () => this.appAttributes?.state.resizable,
180
175
  box._resizable$,
181
- this.isAddApp,
182
176
  ),
183
- box._visible$.subscribe(visible => {
177
+ box._visible$.reaction((visible, skipUpdate) => {
178
+ if (skipUpdate) {
179
+ return;
180
+ }
184
181
  this.store.updateAppState(this.id, AppAttributes.Visible, visible);
185
182
  }),
186
- box._ratio$.subscribe(ratio => {
183
+ box._ratio$.reaction((ratio, skipUpdate) => {
184
+ console.log("ratio change", ratio, skipUpdate);
185
+ if (skipUpdate) {
186
+ return;
187
+ }
187
188
  this.store.updateAppState(this.id, AppAttributes.Ratio, ratio);
188
189
  }),
189
- box._stageRatio$.subscribe(stageRatio => {
190
+ box._stageRatio$.reaction((stageRatio, skipUpdate) => {
191
+ if (skipUpdate) {
192
+ return;
193
+ }
190
194
  this.store.updateAppState(this.id, AppAttributes.StageRatio, stageRatio);
191
195
  }),
192
- box._draggable$.subscribe(draggable => {
196
+ box._draggable$.reaction((draggable, skipUpdate) => {
197
+ if (skipUpdate) {
198
+ return;
199
+ }
193
200
  this.store.updateAppState(this.id, AppAttributes.Draggable, draggable);
194
201
  }),
195
- box._resizable$.subscribe(resizable => {
196
- console.log("resizable change", resizable);
202
+ box._resizable$.reaction((resizable, skipUpdate) => {
203
+ if (skipUpdate) {
204
+ return;
205
+ }
197
206
  this.store.updateAppState(this.id, AppAttributes.Resizable, resizable);
198
207
  }),
199
208
  ])
@@ -348,7 +357,7 @@ export class AppProxy implements PageRemoveService {
348
357
  this.appContext = context;
349
358
  try {
350
359
  emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
351
- let boxInitState: AppInitState | undefined;
360
+ let boxInitState: AppState | undefined;
352
361
  if (!skipUpdate) {
353
362
  boxInitState = this.getAppInitState(appId);
354
363
  this.boxManager?.updateBoxState(boxInitState);
@@ -374,6 +383,11 @@ export class AppProxy implements PageRemoveService {
374
383
  this.box$.setValue(box);
375
384
  if (this.isAddApp && this.box) {
376
385
  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);
377
391
  this.boxManager.focusBox({ appId }, false);
378
392
  }
379
393
  } catch (error: any) {
@@ -438,30 +452,18 @@ export class AppProxy implements PageRemoveService {
438
452
  }
439
453
  }
440
454
 
441
- public getAppInitState = (id: string) => {
455
+ public getAppInitState = (id: string): AppState | undefined => {
442
456
  const attrs = this.store.getAppState(id);
443
457
  if (!attrs) return;
444
- const position = attrs?.[AppAttributes.Position];
445
458
  const focus = this.store.focus;
446
- const size = attrs?.[AppAttributes.Size];
447
- const sceneIndex = attrs?.[AppAttributes.SceneIndex];
448
459
  const maximized = this.attributes?.["maximized"];
449
460
  const minimized = this.attributes?.["minimized"];
450
- const zIndex = attrs?.zIndex;
451
- let payload = { maximized, minimized, zIndex } as AppInitState;
452
- if (position) {
453
- payload = { ...payload, id: id, x: position.x, y: position.y };
454
- }
461
+ let payload = { maximized, minimized, id } as AppState;
462
+ const state = omitBy(attrs, isUndefined);
455
463
  if (focus === id) {
456
464
  payload = { ...payload, focus: true };
457
465
  }
458
- if (size) {
459
- payload = { ...payload, width: size.width, height: size.height };
460
- }
461
- if (sceneIndex) {
462
- payload = { ...payload, sceneIndex };
463
- }
464
- return payload;
466
+ return Object.assign(payload, state);;
465
467
  };
466
468
 
467
469
  public emitAppSceneStateChange(sceneState: SceneState) {
@@ -733,3 +735,16 @@ export class AppProxy implements PageRemoveService {
733
735
  return this.destroy(true, true, false);
734
736
  }
735
737
  }
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
+ };
package/src/App/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./AppProxy";
2
2
  export * from "./AppContext";
3
3
  export * from "./WhiteboardView";
4
+ export * from "./type";
@@ -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
@@ -30,6 +30,7 @@ import {
30
30
  removeScenes,
31
31
  setScenePath,
32
32
  setViewFocusScenePath,
33
+ wait,
33
34
  } from "./Utils/Common";
34
35
  import type { ReconnectRefresher } from "./ReconnectRefresher";
35
36
  import type { BoxManager } from "./BoxManager";
@@ -568,7 +569,10 @@ export class AppManager {
568
569
  public bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean) {
569
570
  const mainView = this.mainViewProxy.view;
570
571
  mainView.disableCameraTransform = disableCameraTransform;
571
- mainView.divElement = divElement;
572
+ // 延迟挂载 mainView dom, 避免因为同步 camera 的闪动
573
+ wait(30).then(() => {
574
+ mainView.divElement = divElement;
575
+ });
572
576
  if (!mainView.focusScenePath) {
573
577
  this.setMainViewFocusPath();
574
578
  }
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
 
@@ -294,17 +295,17 @@ export class BoxManager {
294
295
  return this.teleBoxManager.topBox;
295
296
  }
296
297
 
297
- public updateBoxState(state?: AppInitState): void {
298
+ public updateBoxState(state?: AppState): void {
298
299
  if (!state) return;
299
300
  const box = this.getBox(state.id);
300
301
  if (box) {
301
302
  this.teleBoxManager.update(
302
303
  box.id,
303
304
  {
304
- x: state.x,
305
- y: state.y,
306
- width: state.width || 0.5,
307
- 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,
308
309
  zIndex: state.zIndex,
309
310
  },
310
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,6 +1,6 @@
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
5
  import type { MemberState } from "white-web-sdk";
6
6
 
@@ -11,7 +11,6 @@ export type RemoveSceneParams = {
11
11
 
12
12
  export type EmitterEvent = {
13
13
  onCreated: undefined;
14
- InitReplay: AppInitState;
15
14
  error: Error;
16
15
  seekStart: undefined;
17
16
  seek: number;
@@ -1,7 +1,6 @@
1
1
  import { isObject } from "lodash";
2
2
  import { listenUpdated, reaction, unlistenUpdated, UpdateEventKind } from "white-web-sdk";
3
3
  import type { AkkoObjectUpdatedProperty, AkkoObjectUpdatedListener } from "white-web-sdk";
4
- import type { Val } from "value-enhancer";
5
4
 
6
5
  // 兼容 13 和 14 版本 SDK
7
6
  export const onObjectByEvent = (event: UpdateEventKind) => {
@@ -63,18 +62,3 @@ export const safeListenPropsUpdated = <T>(
63
62
 
64
63
  export const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);
65
64
  export const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);
66
-
67
- export const createValSync = <T>(expr: any, Val: Val<T, boolean>, isAddApp: boolean): (() => void) => {
68
- let skipUpdate = false;
69
- return reaction(
70
- expr,
71
- val => {
72
- if (isAddApp && !skipUpdate) {
73
- skipUpdate = true;
74
- } else {
75
- Val.setValue(val as T);
76
- }
77
- },
78
- { fireImmediately: true }
79
- );
80
- };
@@ -1,4 +1,4 @@
1
- import { AnimationMode, ViewMode } from "white-web-sdk";
1
+ import { AnimationMode, toJS, ViewMode } from "white-web-sdk";
2
2
  import { CameraSynchronizer } from "./CameraSynchronizer";
3
3
  import { combine } from "value-enhancer";
4
4
  import { isEqual } from "lodash";
@@ -42,7 +42,7 @@ export class ViewSync {
42
42
  }
43
43
  });
44
44
  this.bindView(this.context.view$.value);
45
- this.sem.add(() =>
45
+ this.sem.add(() => [
46
46
  this.context.view$.subscribe(view => {
47
47
  const currentCamera = this.context.camera$.value;
48
48
  if (currentCamera && this.context.size$.value) {
@@ -54,30 +54,24 @@ export class ViewSync {
54
54
  }
55
55
 
56
56
  this.bindView(view);
57
- })
58
- );
59
- this.sem.add(() =>
57
+ }),
60
58
  this.context.camera$.subscribe((camera, skipUpdate) => {
61
59
  const size = this.context.size$.value;
62
60
  if (camera && size && !skipUpdate) {
63
61
  this.synchronizer.onRemoteUpdate(camera, size);
64
62
  }
65
- })
66
- );
67
- this.sem.add(() =>
63
+ }),
68
64
  this.context.size$.subscribe(size => {
69
65
  if (size) {
70
66
  this.synchronizer.onRemoteSizeUpdate(size);
71
67
  }
72
- })
73
- );
74
- this.sem.add(() =>
68
+ }),
75
69
  this.context.stageRect$.reaction(rect => {
76
70
  if (rect) {
77
71
  this.synchronizer.setRect(rect);
78
72
  }
79
73
  })
80
- );
74
+ ]);
81
75
  const camera$size$ = combine([this.context.camera$, this.context.size$]);
82
76
  camera$size$.reaction(([camera, size]) => {
83
77
  if (camera && size) {
@@ -99,8 +93,7 @@ export class ViewSync {
99
93
  };
100
94
 
101
95
  private onCameraUpdatedByDevice = (camera: Camera) => {
102
- if (!camera) return;
103
- this.synchronizer.onLocalCameraUpdate(Object.assign(camera, { id: this.context.uid }));
96
+ this.synchronizer.onLocalCameraUpdate(Object.assign(toJS(camera), { id: this.context.uid }));
104
97
  const stage = this.context.stageRect$.value;
105
98
  if (stage) {
106
99
  const size = { width: stage.width, height: stage.height, id: this.context.uid };
package/src/constants.ts CHANGED
@@ -5,7 +5,6 @@ export enum Events {
5
5
  AppBoxStateChange = "AppBoxStateChange",
6
6
  GetAttributes = "GetAttributes",
7
7
  UpdateWindowManagerWrapper = "UpdateWindowManagerWrapper",
8
- InitReplay = "InitReplay",
9
8
  WindowCreated = "WindowCreated",
10
9
  SetMainViewScenePath = "SetMainViewScenePath",
11
10
  SetMainViewSceneIndex = "SetMainViewSceneIndex",