@netless/window-manager 1.0.0-canary.3 → 1.0.0-canary.6

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.
@@ -5,14 +5,15 @@ import type { ReadonlyVal } from "value-enhancer";
5
5
  import type { AddPageParams, PageController, PageState } from "../Page";
6
6
  import type { AppProxy } from "./AppProxy";
7
7
  import type { AppContext } from "./AppContext";
8
+ import type { Camera } from "white-web-sdk";
8
9
 
9
10
  export class WhiteBoardView implements PageController {
10
11
  public readonly pageState$: ReadonlyVal<PageState>;
11
12
 
12
13
  constructor(
13
- protected appContext: AppContext,
14
+ protected appContext: AppContext,
14
15
  protected appProxy: AppProxy,
15
- private removeViewWrapper: () => void,
16
+ private removeViewWrapper: () => void
16
17
  ) {
17
18
  const pageState$ = new Val<PageState>(appProxy.pageState);
18
19
  this.pageState$ = pageState$;
@@ -21,10 +22,18 @@ export class WhiteBoardView implements PageController {
21
22
  });
22
23
  }
23
24
 
25
+ public get view() {
26
+ return this.appContext.view;
27
+ }
28
+
24
29
  public get pageState() {
25
30
  return this.pageState$.value;
26
31
  }
27
32
 
33
+ public moveCamera(camera: Camera) {
34
+ this.appProxy.moveCamera(camera);
35
+ }
36
+
28
37
  public nextPage = async (): Promise<boolean> => {
29
38
  const nextIndex = this.pageState.index + 1;
30
39
  return this.jumpPage(nextIndex);
package/src/App/index.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from "./AppProxy";
2
2
  export * from "./AppContext";
3
- export * from "./WhiteBoardView";
3
+ export * from "./WhiteboardView";
package/src/AppManager.ts CHANGED
@@ -3,7 +3,7 @@ import { AppCreateQueue } from "./Utils/AppCreateQueue";
3
3
  import { AppListeners } from "./AppListener";
4
4
  import { AppProxy } from "./App";
5
5
  import { appRegister } from "./Register";
6
- import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
6
+ import { autorun, isPlayer, isRoom, ScenePathType, toJS } from "white-web-sdk";
7
7
  import { boxEmitter } from "./BoxEmitter";
8
8
  import { calculateNextIndex } from "./Page";
9
9
  import { callbacks } from "./callback";
@@ -34,10 +34,10 @@ import type { ReconnectRefresher } from "./ReconnectRefresher";
34
34
  import type { BoxManager } from "./BoxManager";
35
35
  import type {
36
36
  Displayer,
37
- DisplayerState,
38
37
  Room,
39
38
  ScenesCallbacksNode,
40
39
  SceneState,
40
+ RoomState,
41
41
  } from "white-web-sdk";
42
42
  import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
43
43
  import type {
@@ -56,7 +56,7 @@ export class AppManager {
56
56
  public appStatus: Map<string, AppStatus> = new Map();
57
57
  public store = store;
58
58
  public mainViewProxy: MainViewProxy;
59
- public refresher?: ReconnectRefresher;
59
+ public refresher: ReconnectRefresher;
60
60
  public isReplay = this.windowManger.isReplay;
61
61
  public mainViewScenesLength = 0;
62
62
 
@@ -651,7 +651,7 @@ export class AppManager {
651
651
  }
652
652
  }
653
653
 
654
- private displayerStateListener = (state: Partial<DisplayerState>) => {
654
+ private displayerStateListener = (state: Partial<RoomState>) => {
655
655
  const sceneState = state.sceneState;
656
656
  if (sceneState) {
657
657
  const scenePath = sceneState.scenePath;
@@ -669,6 +669,9 @@ export class AppManager {
669
669
  emitter.emit("roomMembersChange", this.members);
670
670
  }
671
671
  emitter.emit("observerIdChange", this.displayer.observerId);
672
+ if (state.memberState) {
673
+ emitter.emit("memberStateChange", toJS(state.memberState));
674
+ }
672
675
  };
673
676
 
674
677
  public displayerWritableListener = (isReadonly: boolean) => {
@@ -18,6 +18,8 @@ export enum Fields {
18
18
  CursorState = "cursorState",
19
19
  FullPath = "fullPath",
20
20
  Registered = "registered",
21
+ Camera = "camera",
22
+ Size = "size",
21
23
  }
22
24
 
23
25
  export type Apps = {
@@ -39,9 +41,13 @@ export type StoreContext = {
39
41
  safeSetAttributes: (attributes: any) => void;
40
42
  }
41
43
 
42
- export type ICamera = Camera & { id: string };
44
+ export type ICamera = Camera & {
45
+ id: string; // room uid
46
+ };
43
47
 
44
- export type ISize = Size & { id: string };
48
+ export type ISize = Size & {
49
+ id: string; // room uid
50
+ };
45
51
 
46
52
  export class AttributesDelegate {
47
53
 
@@ -108,6 +114,10 @@ export class AttributesDelegate {
108
114
  }
109
115
  }
110
116
 
117
+ public updateAppAttributes(appId: string, key: string, value: any) {
118
+ this.context.safeUpdateAttributes([Fields.Apps, appId, key], value);
119
+ }
120
+
111
121
  public cleanAppAttributes(id: string) {
112
122
  this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
113
123
  this.context.safeSetAttributes({ [id]: undefined });
@@ -149,11 +159,11 @@ export class AttributesDelegate {
149
159
  this.context.safeSetAttributes({ _mainSceneIndex: index });
150
160
  }
151
161
 
152
- public getMainViewCamera(): MainViewCamera {
162
+ public getMainViewCamera(): ICamera {
153
163
  return get(this.attributes, [Fields.MainViewCamera]);
154
164
  }
155
165
 
156
- public getMainViewSize(): MainViewSize {
166
+ public getMainViewSize(): ISize {
157
167
  return get(this.attributes, [Fields.MainViewSize]);
158
168
  }
159
169
 
@@ -214,19 +224,6 @@ export class AttributesDelegate {
214
224
  }
215
225
  }
216
226
 
217
- export type MainViewSize = {
218
- id: string;
219
- width: number;
220
- height: number;
221
- };
222
-
223
- export type MainViewCamera = {
224
- id: string;
225
- centerX: number;
226
- centerY: number;
227
- scale: number;
228
- };
229
-
230
227
  export type Cursors = {
231
228
  [key: string]: Cursor;
232
229
  };
package/src/BoxManager.ts CHANGED
@@ -214,7 +214,7 @@ export class BoxManager {
214
214
  return this.teleBoxManager.stageRect;
215
215
  }
216
216
 
217
- public createBox(params: CreateBoxParams): void {
217
+ public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
218
218
  if (!this.teleBoxManager) return;
219
219
  let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
220
220
  const { width, height } = params.app.config ?? {};
@@ -237,8 +237,9 @@ export class BoxManager {
237
237
  height,
238
238
  id: params.appId,
239
239
  };
240
- this.teleBoxManager.create(createBoxConfig, params.smartPosition);
240
+ const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
241
241
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
242
+ return box;
242
243
  }
243
244
 
244
245
  public setupBoxManager(
@@ -2,6 +2,7 @@ import Emittery from "emittery";
2
2
  import type { TeleBoxRect } from "@netless/telebox-insider";
3
3
  import type { AppInitState, CursorMovePayload } from "./index";
4
4
  import type { Member } from "./Helper";
5
+ import type { MemberState } from "white-web-sdk";
5
6
 
6
7
  export type RemoveSceneParams = {
7
8
  scenePath: string;
@@ -31,6 +32,7 @@ export type EmitterEvent = {
31
32
  writableChange: boolean;
32
33
  containerSizeRatioUpdate: number;
33
34
  roomMembersChange: Member[];
35
+ memberStateChange: MemberState;
34
36
  };
35
37
 
36
38
  export type EmitterType = Emittery<EmitterEvent>;
@@ -88,6 +88,7 @@ export class ReconnectRefresher {
88
88
  this.reactors.set(id, func);
89
89
  this.disposers.set(id, func());
90
90
  }
91
+ return () => this.remove(id);
91
92
  }
92
93
 
93
94
  public remove(id: string) {
@@ -30,6 +30,12 @@ export const setViewSceneIndex = (view: View, index: number) => {
30
30
  }
31
31
  };
32
32
 
33
+ export const releaseView = (view: View) => {
34
+ if (!(view as any).didRelease) {
35
+ view.release();
36
+ }
37
+ }
38
+
33
39
  export const setScenePath = (room: Room | undefined, scenePath: string) => {
34
40
  if (room && room.isWritable) {
35
41
  if (room.state.sceneState.scenePath !== scenePath) {
@@ -2,13 +2,13 @@ import { AnimationMode } from "white-web-sdk";
2
2
  import { delay, throttle } from "lodash";
3
3
  import type { TeleBoxRect } from "@netless/telebox-insider";
4
4
  import type { Camera, View, Size } from "white-web-sdk";
5
- import type { MainViewSize } from "../AttributesDelegate";
5
+ import type { ISize } from "../AttributesDelegate";
6
6
 
7
7
  export type SaveCamera = (camera: Camera) => void;
8
8
 
9
9
  export class CameraSynchronizer {
10
10
  protected remoteCamera?: Camera;
11
- protected remoteSize?: MainViewSize;
11
+ protected remoteSize?: ISize;
12
12
  protected rect?: TeleBoxRect;
13
13
  protected view?: View;
14
14
 
@@ -26,7 +26,7 @@ export class CameraSynchronizer {
26
26
  }
27
27
 
28
28
  // 远端 Camera 或者 size 更新
29
- public onRemoteUpdate = throttle((camera: Camera, size: MainViewSize) => {
29
+ public onRemoteUpdate = throttle((camera: Camera, size: ISize) => {
30
30
  this.remoteCamera = camera;
31
31
  this.remoteSize = size;
32
32
  if (this.remoteSize && this.rect) {
@@ -37,27 +37,33 @@ export class CameraSynchronizer {
37
37
  scale = this.rect.height / size.height;
38
38
  }
39
39
  const nextScale = camera.scale * scale;
40
- const moveCamera = () => this.view?.moveCamera({
40
+ const moveCamera = () => this.view?.moveCamera({
41
41
  centerX: camera.centerX,
42
42
  centerY: camera.centerY,
43
43
  scale: nextScale,
44
44
  animationMode: AnimationMode.Immediately,
45
45
  });
46
46
  // TODO 直接调用 moveCamera 依然会出现 camera 错误的情况,这里暂时加一个 delay 保证 camera 是对的, 后续需要 SDK 进行修改
47
- delay(moveCamera, 10);
47
+ delay(moveCamera, 50);
48
48
  }
49
49
  }, 50);
50
50
 
51
51
 
52
52
  public onLocalCameraUpdate(camera: Camera) {
53
53
  this.saveCamera(camera);
54
+ this.remoteCamera = camera;
54
55
  }
55
56
 
56
57
  // 本地 Size 更新, 先匹配 camera 到新的 size 然后再发送 camera 数据到远端
57
- public onLocalSizeUpdate(size: Size) {
58
+ public onLocalSizeUpdate = (size: Size) => {
58
59
  if (this.rect && this.view) {
59
- const scale = this.rect.width / size.width;
60
- const nextScale = this.view.camera.scale * scale;
60
+ let scale: number;
61
+ if (size.width < size.height) {
62
+ scale = this.rect.width / size.width;
63
+ } else {
64
+ scale = this.rect.height / size.height;
65
+ }
66
+ const nextScale = this.view.camera.scale / scale;
61
67
  this.view.moveCamera({
62
68
  scale: nextScale,
63
69
  animationMode: AnimationMode.Immediately
@@ -1,15 +1,15 @@
1
- import { reaction } from "white-web-sdk";
2
1
  import { callbacks } from "../callback";
2
+ import { CameraSynchronizer } from "./CameraSynchronizer";
3
3
  import { createView } from "./ViewManager";
4
4
  import { debounce, get, isEqual } from "lodash";
5
5
  import { emitter } from "../InternalEmitter";
6
6
  import { Events } from "../constants";
7
7
  import { Fields } from "../AttributesDelegate";
8
- import { setViewFocusScenePath } from "../Utils/Common";
8
+ import { reaction } from "white-web-sdk";
9
+ import { releaseView, setViewFocusScenePath } from "../Utils/Common";
9
10
  import { SideEffectManager } from "side-effect-manager";
10
11
  import type { Camera, Size, View } from "white-web-sdk";
11
12
  import type { AppManager } from "../AppManager";
12
- import { CameraSynchronizer } from "./CameraSynchronizer";
13
13
 
14
14
  export class MainViewProxy {
15
15
  private started = false;
@@ -21,8 +21,8 @@ export class MainViewProxy {
21
21
  private sideEffectManager = new SideEffectManager();
22
22
 
23
23
  constructor(private manager: AppManager) {
24
- this.synchronizer = new CameraSynchronizer(
25
- camera => this.store.setMainViewCamera({ ...camera, id: this.manager.uid })
24
+ this.synchronizer = new CameraSynchronizer(camera =>
25
+ this.store.setMainViewCamera({ ...camera, id: this.manager.uid })
26
26
  );
27
27
  this.mainView = this.createMainView();
28
28
  this.moveCameraSizeByAttributes();
@@ -37,9 +37,7 @@ export class MainViewProxy {
37
37
  });
38
38
  this.sideEffectManager.add(() => {
39
39
  return emitter.on("startReconnect", () => {
40
- if (!(this.mainView as any).didRelease) {
41
- this.mainView.release();
42
- }
40
+ releaseView(this.mainView);
43
41
  });
44
42
  });
45
43
  const rect = this.manager.boxManager?.stageRect;
@@ -49,7 +47,7 @@ export class MainViewProxy {
49
47
  this.sideEffectManager.add(() => {
50
48
  return emitter.on("playgroundSizeChange", rect => {
51
49
  this.synchronizer.setRect(rect);
52
- this.synchronizer.onLocalSizeUpdate(rect);
50
+ // this.synchronizer.onLocalSizeUpdate(rect);
53
51
  });
54
52
  });
55
53
  }
@@ -122,7 +120,7 @@ export class MainViewProxy {
122
120
 
123
121
  public sizeChangeHandler = debounce((size: Size) => {
124
122
  if (size) {
125
- this.synchronizer.onLocalSizeUpdate(size);
123
+ // this.synchronizer.onLocalSizeUpdate(size);
126
124
  }
127
125
  }, 30);
128
126
 
@@ -171,9 +169,7 @@ export class MainViewProxy {
171
169
  const divElement = this.mainView.divElement;
172
170
  const disableCameraTransform = this.mainView.disableCameraTransform;
173
171
  this.stop();
174
- if (!this.didRelease) {
175
- this.mainView.release();
176
- }
172
+ releaseView(this.mainView);
177
173
  this.removeMainViewListener();
178
174
  this.mainView = this.createMainView();
179
175
  this.mainView.disableCameraTransform = disableCameraTransform;
@@ -0,0 +1,10 @@
1
+ import type { Camera, Size } from "white-web-sdk";
2
+
3
+
4
+ export interface ViewSync {
5
+ readonly camera: Camera;
6
+ readonly size: Size;
7
+
8
+ setCamera: (camera: Camera) => void;
9
+ setSize: (size: Size) => void;
10
+ }
package/src/index.ts CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  } from "./Utils/Common";
30
30
  import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
31
31
  import * as Errors from "./Utils/error";
32
- import type { Apps, Position } from "./AttributesDelegate";
32
+ import type { Apps, Position , ICamera, ISize } from "./AttributesDelegate";
33
33
  import type {
34
34
  Displayer,
35
35
  SceneDefinition,
@@ -104,6 +104,8 @@ export type AppSyncAttributes = {
104
104
  isDynamicPPT?: boolean;
105
105
  fullPath?: string;
106
106
  createdAt?: number;
107
+ camera?: ICamera;
108
+ size?: ISize;
107
109
  };
108
110
 
109
111
  export type AppInitState = {