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

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.
Files changed (83) hide show
  1. package/dist/App/AppContext.d.ts +1 -1
  2. package/dist/App/WhiteboardView.d.ts +6 -4
  3. package/dist/AppListener.d.ts +0 -2
  4. package/dist/BoxManager.d.ts +2 -1
  5. package/dist/BuiltinApps.d.ts +3 -0
  6. package/dist/Cursor/index.d.ts +3 -2
  7. package/dist/Helper.d.ts +3 -1
  8. package/dist/callback.d.ts +5 -0
  9. package/dist/constants.d.ts +0 -2
  10. package/dist/index.cjs.js +82 -12
  11. package/dist/index.d.ts +16 -9
  12. package/dist/index.es.js +1620 -704
  13. package/dist/index.umd.js +82 -12
  14. package/dist/src/App/AppContext.d.ts +78 -0
  15. package/dist/src/App/AppPageStateImpl.d.ts +21 -0
  16. package/dist/src/App/AppProxy.d.ts +98 -0
  17. package/dist/src/App/MagixEvent/index.d.ts +29 -0
  18. package/dist/src/App/Storage/StorageEvent.d.ts +8 -0
  19. package/dist/src/App/Storage/index.d.ts +39 -0
  20. package/dist/src/App/Storage/typings.d.ts +22 -0
  21. package/dist/src/App/Storage/utils.d.ts +5 -0
  22. package/dist/src/App/WhiteboardView.d.ts +27 -0
  23. package/dist/src/App/index.d.ts +4 -0
  24. package/dist/src/App/type.d.ts +21 -0
  25. package/dist/src/AppListener.d.ts +19 -0
  26. package/dist/src/AppManager.d.ts +107 -0
  27. package/dist/src/AttributesDelegate.d.ts +83 -0
  28. package/dist/src/BoxEmitter.d.ts +34 -0
  29. package/dist/src/BoxManager.d.ts +102 -0
  30. package/dist/src/BuiltinApps.d.ts +8 -0
  31. package/dist/src/Cursor/Cursor.d.ts +39 -0
  32. package/dist/src/Cursor/icons.d.ts +3 -0
  33. package/dist/src/Cursor/index.d.ts +46 -0
  34. package/dist/src/Helper.d.ts +19 -0
  35. package/dist/src/InternalEmitter.d.ts +38 -0
  36. package/dist/src/Page/PageController.d.ts +21 -0
  37. package/dist/src/Page/index.d.ts +3 -0
  38. package/dist/src/PageState.d.ts +9 -0
  39. package/dist/src/ReconnectRefresher.d.ts +24 -0
  40. package/dist/src/RedoUndo.d.ts +18 -0
  41. package/dist/src/Register/index.d.ts +28 -0
  42. package/dist/src/Register/loader.d.ts +4 -0
  43. package/dist/src/Register/storage.d.ts +8 -0
  44. package/dist/src/Utils/AppCreateQueue.d.ts +15 -0
  45. package/dist/src/Utils/Common.d.ts +23 -0
  46. package/dist/src/Utils/Reactive.d.ts +6 -0
  47. package/dist/src/Utils/RoomHacker.d.ts +3 -0
  48. package/dist/src/Utils/error.d.ts +27 -0
  49. package/dist/src/Utils/log.d.ts +1 -0
  50. package/dist/src/View/CameraSynchronizer.d.ts +17 -0
  51. package/dist/src/View/MainView.d.ts +59 -0
  52. package/dist/src/View/ViewManager.d.ts +13 -0
  53. package/dist/src/View/ViewSync.d.ts +24 -0
  54. package/dist/src/callback.d.ts +29 -0
  55. package/dist/src/constants.d.ts +51 -0
  56. package/dist/src/image.d.ts +19 -0
  57. package/dist/src/index.d.ts +267 -0
  58. package/dist/src/shim.d.ts +11 -0
  59. package/dist/src/typings.d.ts +88 -0
  60. package/dist/style.css +1 -1
  61. package/dist/typings.d.ts +6 -0
  62. package/docs/app-context.md +68 -26
  63. package/package.json +10 -5
  64. package/playwright.config.ts +28 -0
  65. package/pnpm-lock.yaml +516 -30
  66. package/src/App/AppContext.ts +14 -6
  67. package/src/App/AppProxy.ts +17 -7
  68. package/src/App/WhiteboardView.ts +23 -18
  69. package/src/AppListener.ts +1 -21
  70. package/src/AppManager.ts +2 -1
  71. package/src/BoxManager.ts +32 -24
  72. package/src/BuiltinApps.ts +5 -0
  73. package/src/Cursor/Cursor.ts +6 -2
  74. package/src/Cursor/index.ts +5 -5
  75. package/src/Helper.ts +23 -5
  76. package/src/View/CameraSynchronizer.ts +5 -9
  77. package/src/View/MainView.ts +3 -1
  78. package/src/callback.ts +1 -0
  79. package/src/constants.ts +0 -2
  80. package/src/index.ts +69 -45
  81. package/src/style.css +2 -45
  82. package/src/typings.ts +6 -0
  83. package/vite.config.js +5 -3
@@ -107,18 +107,26 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
107
107
  const viewWrapper = document.createElement("div");
108
108
  this._viewWrapper = viewWrapper;
109
109
  viewWrapper.className = "window-manager-view-wrapper";
110
- this.box.$content.parentElement?.appendChild(viewWrapper);
110
+ this.box.$main.appendChild(viewWrapper);
111
111
  view.divElement = viewWrapper;
112
112
  this.appProxy.fireMemberStateChange();
113
113
  if (this.isAddApp) {
114
114
  this.ensurePageSize(params?.size);
115
115
  }
116
116
  this.whiteBoardView = new WhiteBoardView(view, this, this.appProxy, this.ensurePageSize);
117
- this.appProxy.sideEffectManager.add(() => {
118
- return () => {
119
- this.whiteBoardView = undefined;
117
+ this.appProxy.sideEffectManager.add(() => [
118
+ this.box._stageRect$.subscribe(rect => {
119
+ viewWrapper.style.left = `${rect.x}px`;
120
+ viewWrapper.style.top = `${rect.y}px`;
121
+ viewWrapper.style.width = `${rect.width}px`;
122
+ viewWrapper.style.height = `${rect.height}px`;
123
+ }),
124
+ () => {
125
+ return () => {
126
+ this.whiteBoardView = undefined;
127
+ }
120
128
  }
121
- });
129
+ ]);
122
130
  this.appProxy.whiteBoardViewCreated$.setValue(true);
123
131
  return this.whiteBoardView;
124
132
  }
@@ -162,7 +170,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
162
170
  return this.manager.members;
163
171
  }
164
172
 
165
- public get memberState(): Member {
173
+ public get currentMember(): Member {
166
174
  const self = findMemberByUid(this.room, this.manager.uid);
167
175
  if (!self) {
168
176
  throw new Error(`Member ${this.manager.uid} not found.`);
@@ -32,9 +32,10 @@ import type {
32
32
  import type { SceneState, View, SceneDefinition, MemberState} from "white-web-sdk";
33
33
  import type { AppManager } from "../AppManager";
34
34
  import type { NetlessApp } from "../typings";
35
- import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
35
+ import type { ReadonlyTeleBox, TeleBox, TeleBoxRect } from "@netless/telebox-insider";
36
36
  import type { PageRemoveService, PageState } from "../Page";
37
37
  import type { AppState } from "./type";
38
+ import { callbacks } from "../callback";
38
39
 
39
40
  export type AppEmitter = Emittery<AppEmitterEvent>;
40
41
 
@@ -142,10 +143,10 @@ export class AppProxy implements PageRemoveService {
142
143
  });
143
144
  this.camera$.setValue(toJS(this.appAttributes.camera));
144
145
  }
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;
146
+ if (!this.size$.value && box.stageRect) {
147
+ const initialRect = this.computedInitialRect(box.stageRect);
148
+ const width = initialRect?.width || box.stageRect.width;
149
+ const height = initialRect?.height || box.stageRect.height;
149
150
  this.storeSize({
150
151
  id: this.uid,
151
152
  width,
@@ -158,7 +159,7 @@ export class AppProxy implements PageRemoveService {
158
159
  view$: this.view$,
159
160
  camera$: this.camera$,
160
161
  size$: this.size$,
161
- stageRect$: box._contentStageRect$,
162
+ stageRect$: box._stageRect$,
162
163
  storeCamera: this.storeCamera,
163
164
  storeSize: this.storeSize
164
165
  });
@@ -341,10 +342,18 @@ export class AppProxy implements PageRemoveService {
341
342
  options,
342
343
  canOperate: this.manager.canOperate,
343
344
  smartPosition: this.isAddApp,
344
- });
345
+ }) as TeleBox;
346
+ const registerParams = appRegister.registered.get(this.kind);
347
+ if (registerParams?.contentStyles) {
348
+ box?.mountUserStyles(registerParams.contentStyles);
349
+ }
345
350
  this.box$.setValue(box);
346
351
  if (this.isAddApp && this.box) {
347
352
  this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
353
+ this.store.updateAppState(appId, AppAttributes.Size, {
354
+ width: this.box.intrinsicWidth,
355
+ height: this.box.intrinsicHeight,
356
+ });
348
357
  this.boxManager.focusBox({ appId }, false);
349
358
  }
350
359
  } catch (error: any) {
@@ -622,6 +631,7 @@ export class AppProxy implements PageRemoveService {
622
631
  this.status = "destroyed";
623
632
  try {
624
633
  await appRegister.notifyApp(this.kind, "destroy", { appId: this.id });
634
+ callbacks.emit("appClose", { appId: this.id, kind: this.kind, error });
625
635
  await this.appEmitter.emit("destroy", { error });
626
636
  } catch (error) {
627
637
  console.error("[WindowManager]: notifyApp error", error.message, error.stack);
@@ -6,15 +6,17 @@ import type { ReadonlyVal } from "value-enhancer";
6
6
  import type { AddPageParams, PageController, PageState } from "../Page";
7
7
  import type { AppProxy } from "./AppProxy";
8
8
  import type { AppContext } from "./AppContext";
9
- import type { View } from "white-web-sdk";
9
+ import type { Camera, View } from "white-web-sdk";
10
10
  import type { TeleBoxRect } from "@netless/telebox-insider";
11
- import type { ICamera } from "../AttributesDelegate";
11
+ import type { ICamera, ISize } from "../AttributesDelegate";
12
12
 
13
- export type WhiteBoardViewCamera = Omit<ICamera, "scale" | "id">;
13
+ export type WhiteBoardViewCamera = Omit<ICamera, "id">;
14
+ export type WhiteBoardViewRect = Omit<ISize, "id">;
14
15
 
15
16
  export class WhiteBoardView implements PageController {
16
17
  public readonly pageState$: ReadonlyVal<PageState>;
17
- public readonly camera$: ReadonlyVal<WhiteBoardViewCamera>;
18
+ public readonly baseCamera$: ReadonlyVal<WhiteBoardViewCamera>;
19
+ public readonly baseRect$: ReadonlyVal<WhiteBoardViewRect | undefined>;
18
20
 
19
21
  constructor(
20
22
  public view: View,
@@ -23,23 +25,26 @@ export class WhiteBoardView implements PageController {
23
25
  public ensureSize: (size: number) => void
24
26
  ) {
25
27
  const pageState$ = new Val<PageState>(appProxy.pageState);
28
+ const baseRect$ = new Val<WhiteBoardViewRect | undefined>(appProxy.size$.value);
29
+ const pickCamera = (camera: Camera | ICamera) =>
30
+ pick(camera, ["centerX", "centerY", "scale"]);
31
+ const camera$ = new Val<WhiteBoardViewCamera>(pickCamera(this.view.camera));
32
+ this.baseRect$ = baseRect$;
26
33
  this.pageState$ = pageState$;
27
- this.appProxy.sideEffectManager.add(() =>
28
- appProxy.appEmitter.on("pageStateChange", pageState => {
29
- pageState$.setValue(pageState);
30
- })
31
- );
32
- const camera$ = new Val<WhiteBoardViewCamera>(
33
- pick(this.view.camera, ["centerX", "centerY"])
34
- );
35
- this.camera$ = camera$;
36
- this.appProxy.sideEffectManager.add(() =>
34
+ this.baseCamera$ = camera$;
35
+ this.appProxy.sideEffectManager.add(() => [
36
+ appProxy.appEmitter.on("pageStateChange", pageState => pageState$.setValue(pageState)),
37
37
  appProxy.camera$.subscribe(camera => {
38
38
  if (camera) {
39
- camera$.setValue(pick(camera, ["centerX", "centerY"]));
39
+ camera$.setValue(pickCamera(camera));
40
40
  }
41
- })
42
- );
41
+ }),
42
+ appProxy.size$.subscribe(size => {
43
+ if (size) {
44
+ baseRect$.setValue(pick(size, ["width", "height"]));
45
+ }
46
+ }),
47
+ ]);
43
48
  view.disableCameraTransform = true;
44
49
  }
45
50
 
@@ -96,7 +101,7 @@ export class WhiteBoardView implements PageController {
96
101
  return this.appProxy.removeSceneByIndex(needRemoveIndex);
97
102
  };
98
103
 
99
- public setRect(rect: Omit<TeleBoxRect, "x" | "y">) {
104
+ public setBaseRect(rect: Omit<TeleBoxRect, "x" | "y">) {
100
105
  this.appProxy.updateSize(rect.width, rect.height);
101
106
  }
102
107
  }
@@ -1,9 +1,8 @@
1
1
  import { callbacks } from "./callback";
2
2
  import { emitter } from "./InternalEmitter";
3
3
  import { Events, MagixEventName } from "./constants";
4
- import { isEqual, omit } from "lodash";
5
4
  import { setViewFocusScenePath } from "./Utils/Common";
6
- import type { AnimationMode, Camera, Event } from "white-web-sdk";
5
+ import type { Event } from "white-web-sdk";
7
6
  import type { AppManager } from "./AppManager";
8
7
  import type { TeleBoxState } from "@netless/telebox-insider";
9
8
 
@@ -50,14 +49,6 @@ export class AppListeners {
50
49
  this.setMainViewScenePathHandler(data.payload);
51
50
  break;
52
51
  }
53
- case Events.MoveCamera: {
54
- this.moveCameraHandler(data.payload);
55
- break;
56
- }
57
- case Events.MoveCameraToContain: {
58
- this.moveCameraToContainHandler(data.payload);
59
- break;
60
- }
61
52
  case Events.CursorMove: {
62
53
  this.cursorMoveHandler(data.payload);
63
54
  break;
@@ -102,17 +93,6 @@ export class AppListeners {
102
93
  callbacks.emit("mainViewScenePathChange", nextScenePath);
103
94
  };
104
95
 
105
- private moveCameraHandler = (
106
- payload: Camera & { animationMode?: AnimationMode | undefined }
107
- ) => {
108
- if (isEqual(omit(payload, ["animationMode"]), { ...this.manager.mainView.camera })) return;
109
- this.manager.mainView.moveCamera(payload);
110
- };
111
-
112
- private moveCameraToContainHandler = (payload: any) => {
113
- this.manager.mainView.moveCameraToContain(payload);
114
- };
115
-
116
96
  private cursorMoveHandler = (payload: any) => {
117
97
  emitter.emit("cursorMove", payload);
118
98
  };
package/src/AppManager.ts CHANGED
@@ -409,7 +409,7 @@ export class AppManager {
409
409
  };
410
410
 
411
411
  public addAppsChangeListener = () => {
412
- this.refresher?.add("apps", () => {
412
+ this.refresher.add("apps", () => {
413
413
  return safeListenPropsUpdated(
414
414
  () => this.attributes.apps,
415
415
  () => {
@@ -800,6 +800,7 @@ export class AppManager {
800
800
  }
801
801
 
802
802
  public async onReconnected() {
803
+ this.attributesUpdateCallback(this.attributes.apps);
803
804
  const appProxies = Array.from(this.appProxies.values());
804
805
  const reconnected = appProxies.map(appProxy => {
805
806
  return appProxy.onReconnected();
package/src/BoxManager.ts CHANGED
@@ -3,6 +3,7 @@ import { debounce } from "lodash";
3
3
  import { SideEffectManager } from "side-effect-manager";
4
4
  import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
5
5
  import { WindowManager } from "./index";
6
+ import type { Writeable } from "./typings";
6
7
  import type { BoxEmitterType } from "./BoxEmitter";
7
8
  import type { AddAppOptions } from "./index";
8
9
  import type {
@@ -48,7 +49,8 @@ export type CreateTeleBoxManagerConfig = {
48
49
  collectorStyles?: Partial<CSSStyleDeclaration>;
49
50
  prefersColorScheme?: TeleBoxColorScheme;
50
51
  stageRatio?: number;
51
- highlightStage?: boolean;
52
+ containerStyle?: string;
53
+ stageStyle?: string;
52
54
  };
53
55
 
54
56
  export type BoxManagerContext = {
@@ -169,13 +171,6 @@ export class BoxManager {
169
171
  this.teleBoxManager.events.on("z_index", box => {
170
172
  this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
171
173
  }),
172
- this.teleBoxManager._stageRect$.subscribe(stage => {
173
- emitter.emit("playgroundSizeChange", stage);
174
- this.context.notifyContainerRectUpdate(stage);
175
- }),
176
- emitter.on("writableChange", isWritable => {
177
- this.teleBoxManager.setHighlightStage(isWritable);
178
- }),
179
174
  emitter.on("containerSizeRatioUpdate", ratio => {
180
175
  this.teleBoxManager._stageRatio$.setValue(ratio);
181
176
  }),
@@ -220,7 +215,8 @@ export class BoxManager {
220
215
 
221
216
  public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
222
217
  if (!this.teleBoxManager) return;
223
- let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
218
+ // eslint-disable-next-line prefer-const
219
+ let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT, enableShadowDOM = true } = params.app.config ?? {};
224
220
  const { width, height } = params.app.config ?? {};
225
221
  const title = params.options?.title || params.appId;
226
222
  const rect = this.teleBoxManager.rootRect;
@@ -240,6 +236,7 @@ export class BoxManager {
240
236
  width,
241
237
  height,
242
238
  id: params.appId,
239
+ enableShadowDOM,
243
240
  };
244
241
  const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
245
242
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
@@ -250,14 +247,21 @@ export class BoxManager {
250
247
  createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
251
248
  ): TeleBoxManager {
252
249
  const root = WindowManager.playground;
253
- const initManagerState: TeleBoxManagerConfig = {
250
+ const initManagerState: Writeable<TeleBoxManagerConfig> = {
254
251
  stageRatio: createTeleBoxManagerConfig?.stageRatio,
255
252
  root: root,
256
253
  fence: false,
257
254
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
258
- highlightStage: createTeleBoxManagerConfig?.highlightStage,
259
255
  };
260
256
 
257
+ if (createTeleBoxManagerConfig?.containerStyle) {
258
+ initManagerState.containerStyle = createTeleBoxManagerConfig.containerStyle;
259
+ }
260
+
261
+ if (createTeleBoxManagerConfig?.stageStyle) {
262
+ initManagerState.stageStyle = createTeleBoxManagerConfig.stageStyle;
263
+ }
264
+
261
265
  const manager = new TeleBoxManager(initManagerState);
262
266
  if (this.teleBoxManager) {
263
267
  this.teleBoxManager.destroy();
@@ -299,17 +303,15 @@ export class BoxManager {
299
303
  if (!state) return;
300
304
  const box = this.getBox(state.id);
301
305
  if (box) {
302
- this.teleBoxManager.update(
303
- box.id,
304
- {
305
- x: state.position?.x,
306
- y: state.position?.y,
307
- width: state.size?.width || 0.5,
308
- height: state.size?.height || 0.5,
309
- zIndex: state.zIndex,
310
- },
311
- true
312
- );
306
+ if (state.size) {
307
+ box._intrinsicSize$.setValue(state.size, true);
308
+ }
309
+ if (state.position) {
310
+ box._intrinsicCoord$.setValue(state.position, true);
311
+ }
312
+ if (state.zIndex) {
313
+ box._zIndex$.setValue(state.zIndex, true);
314
+ }
313
315
  setTimeout(() => {
314
316
  if (state.focus) {
315
317
  this.teleBoxManager.focusBox(box.id, true);
@@ -326,7 +328,10 @@ export class BoxManager {
326
328
  }
327
329
 
328
330
  public moveBox({ appId, x, y }: MoveBoxParams): void {
329
- this.teleBoxManager.update(appId, { x, y }, true);
331
+ const box = this.getBox(appId);
332
+ if (box) {
333
+ box._intrinsicCoord$.setValue({ x, y}, true);
334
+ }
330
335
  }
331
336
 
332
337
  public focusBox({ appId }: AppId, skipUpdate = true): void {
@@ -334,7 +339,10 @@ export class BoxManager {
334
339
  }
335
340
 
336
341
  public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {
337
- this.teleBoxManager.update(appId, { width, height }, skipUpdate);
342
+ const box = this.getBox(appId);
343
+ if (box) {
344
+ box._intrinsicSize$.setValue({ width, height }, skipUpdate);
345
+ }
338
346
  }
339
347
 
340
348
  public setBoxMinSize(params: SetBoxMinSizeParams): void {
@@ -21,3 +21,8 @@ export const BuiltinApps = {
21
21
  DocsViewer: AppDocsViewer.kind as string,
22
22
  MediaPlayer: AppMediaPlayer.kind as string,
23
23
  };
24
+
25
+ export const BuiltinAppsMap = {
26
+ [BuiltinApps.DocsViewer]: AppDocsViewer,
27
+ [BuiltinApps.MediaPlayer]: AppMediaPlayer,
28
+ }
@@ -7,6 +7,7 @@ import type { RoomMember } from "white-web-sdk";
7
7
  import type { CursorManager } from "./index";
8
8
  import type { SvelteComponent } from "svelte";
9
9
  import type { AppManager } from "../AppManager";
10
+ import type { TeleBoxRect } from "@netless/telebox-insider";
10
11
 
11
12
  export type Payload = {
12
13
  [key: string]: any;
@@ -50,18 +51,21 @@ export class Cursor {
50
51
  this.hide();
51
52
  };
52
53
 
53
- private moveCursor(cursor: Position, rect: DOMRect, view: any) {
54
+ private moveCursor(cursor: Position, rect: TeleBoxRect, view: any) {
54
55
  const { x, y, type } = cursor;
55
56
  const point = view?.screen.convertPointToScreen(x, y);
56
57
  if (point) {
57
58
  let translateX = point.x - 2;
58
59
  let translateY = point.y - 18;
59
60
  if (type === "app") {
60
- const wrapperRect = this.cursorManager.wrapperRect;
61
+ const wrapperRect = this.cursorManager.playgroundRect;
61
62
  if (wrapperRect) {
62
63
  translateX = translateX + rect.x - wrapperRect.x;
63
64
  translateY = translateY + rect.y - wrapperRect.y;
64
65
  }
66
+ } else {
67
+ translateX = translateX + rect.x;
68
+ translateY = translateY + rect.y;
65
69
  }
66
70
  if (point.x < 0 || point.x > rect.width || point.y < 0 || point.y > rect.height) {
67
71
  this.component?.$set({ visible: false, x: translateX, y: translateY });
@@ -5,7 +5,7 @@ import { emitter } from "../InternalEmitter";
5
5
  import { SideEffectManager } from "side-effect-manager";
6
6
  import { throttle } from "lodash";
7
7
  import { WindowManager } from "../index";
8
- import type { CursorMovePayload , ApplianceIcons} from "../index";
8
+ import type { CursorMovePayload , ApplianceIcons, TeleBoxRect } from "../index";
9
9
  import type { PositionType } from "../AttributesDelegate";
10
10
  import type { Point, RoomMember, View } from "white-web-sdk";
11
11
  import type { AppManager } from "../AppManager";
@@ -23,7 +23,8 @@ export type MoveCursorParams = {
23
23
  };
24
24
 
25
25
  export class CursorManager {
26
- public wrapperRect?: DOMRect;
26
+ public wrapperRect?: TeleBoxRect;
27
+ public playgroundRect?: DOMRect;
27
28
  public cursorInstances: Map<string, Cursor> = new Map();
28
29
  public roomMembers?: readonly RoomMember[];
29
30
  private mainViewElement?: HTMLDivElement;
@@ -88,8 +89,6 @@ export class CursorManager {
88
89
  wrapper.removeEventListener("pointerleave", this.mouseLeaveListener);
89
90
  };
90
91
  });
91
-
92
- this.wrapperRect = wrapper.getBoundingClientRect();
93
92
  }
94
93
 
95
94
  public setMainViewDivElement(div: HTMLDivElement) {
@@ -167,7 +166,8 @@ export class CursorManager {
167
166
  };
168
167
 
169
168
  public updateContainerRect() {
170
- this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
169
+ this.wrapperRect = this.manager.boxManager?.teleBoxManager.stageRect;
170
+ this.playgroundRect = WindowManager.playground?.getBoundingClientRect();
171
171
  }
172
172
 
173
173
  public deleteCursor(uid: string) {
package/src/Helper.ts CHANGED
@@ -1,11 +1,14 @@
1
- import { getVersionNumber } from "./Utils/Common";
1
+ import { getVersionNumber, wait } from "./Utils/Common";
2
+ import { log } from "./Utils/log";
2
3
  import { REQUIRE_VERSION } from "./constants";
3
4
  import { WhiteVersion } from "white-web-sdk";
4
5
  import { WhiteWebSDKInvalidError } from "./Utils/error";
5
- import type { Room , RoomMember} from "white-web-sdk";
6
+ import { WindowManager } from "./index";
7
+ import type { Room, RoomMember } from "white-web-sdk";
6
8
 
7
9
  export const setupWrapper = (
8
- root: HTMLElement
10
+ root: HTMLElement,
11
+ target: HTMLElement
9
12
  ): {
10
13
  playground: HTMLDivElement;
11
14
  mainViewElement: HTMLDivElement;
@@ -15,7 +18,7 @@ export const setupWrapper = (
15
18
 
16
19
  const mainViewElement = document.createElement("div");
17
20
  mainViewElement.className = "netless-window-manager-main-view";
18
- playground.appendChild(mainViewElement);
21
+ target.appendChild(mainViewElement);
19
22
  root.appendChild(playground);
20
23
 
21
24
  return { playground, mainViewElement };
@@ -40,4 +43,19 @@ export const serializeRoomMembers = (members: readonly RoomMember[]) => {
40
43
  uid: member.payload?.uid || "",
41
44
  ...member,
42
45
  }));
43
- }
46
+ };
47
+
48
+ export const createInvisiblePlugin = async (room: Room) => {
49
+ try {
50
+ const manager = (await room.createInvisiblePlugin(WindowManager, {})) as WindowManager;
51
+ return manager;
52
+ } catch (error) {
53
+ // 如果有两个用户同时调用 WindowManager.mount 有概率出现这个错误
54
+ if (error.message === `invisible plugin "WindowManager" exits`) {
55
+ await wait(200);
56
+ return room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
57
+ } else {
58
+ log("createInvisiblePlugin failed", error);
59
+ }
60
+ }
61
+ };
@@ -30,16 +30,12 @@ export class CameraSynchronizer {
30
30
  this.remoteCamera = camera;
31
31
  this.remoteSize = size;
32
32
  if (this.remoteSize && this.rect) {
33
- let scale: number;
34
- if (size.width < size.height) {
35
- scale = this.rect.width / size.width;
36
- } else {
37
- scale = this.rect.height / size.height;
38
- }
39
- const nextScale = camera.scale * scale;
33
+ const wScale = this.rect.width / size.width;
34
+ const hScale = this.rect.height / size.height;
35
+ const nextScale = camera.scale * Math.min(wScale, hScale);
40
36
  const config: Partial<Camera> & { animationMode: AnimationMode } = {
41
37
  scale: nextScale,
42
- animationMode: AnimationMode.Immediately,
38
+ animationMode: AnimationMode.Continuous,
43
39
  }
44
40
  if (camera.centerX !== null) {
45
41
  config.centerX = camera.centerX;
@@ -59,7 +55,7 @@ export class CameraSynchronizer {
59
55
  const nextScale = this.remoteCamera.scale * scale;
60
56
  this.view?.moveCamera({
61
57
  scale: nextScale,
62
- animationMode: AnimationMode.Immediately,
58
+ animationMode: AnimationMode.Continuous,
63
59
  })
64
60
  }
65
61
  }
@@ -4,7 +4,7 @@ import { debounce, get, isEqual } from "lodash";
4
4
  import { emitter } from "../InternalEmitter";
5
5
  import { Events } from "../constants";
6
6
  import { Fields } from "../AttributesDelegate";
7
- import { reaction, toJS } from "white-web-sdk";
7
+ import { AnimationMode, reaction, toJS } from "white-web-sdk";
8
8
  import { releaseView, setScenePath, setViewFocusScenePath } from "../Utils/Common";
9
9
  import { SideEffectManager } from "side-effect-manager";
10
10
  import { Val } from "value-enhancer";
@@ -211,12 +211,14 @@ export class MainViewProxy {
211
211
  public rebind(): void {
212
212
  const divElement = this.mainView.divElement;
213
213
  const disableCameraTransform = this.mainView.disableCameraTransform;
214
+ const camera = { ...this.mainView.camera };
214
215
  this.stop();
215
216
  releaseView(this.mainView);
216
217
  this.removeMainViewListener();
217
218
  this.mainView = this.createMainView();
218
219
  this.mainView.disableCameraTransform = disableCameraTransform;
219
220
  this.mainView.divElement = divElement;
221
+ this.mainView.moveCamera({ ...camera, animationMode: AnimationMode.Immediately });
220
222
  this.addMainViewListener();
221
223
  this.start();
222
224
  }
package/src/callback.ts CHANGED
@@ -20,6 +20,7 @@ export type PublicEvent = {
20
20
  ready: undefined; // 所有 APP 创建完毕时触发
21
21
  sceneStateChange: SceneState;
22
22
  pageStateChange: PageState;
23
+ appClose: { appId: string; kind: string, error?: Error };
23
24
  };
24
25
 
25
26
  export type CallbacksType = Emittery<PublicEvent>;
package/src/constants.ts CHANGED
@@ -10,8 +10,6 @@ export enum Events {
10
10
  SetMainViewSceneIndex = "SetMainViewSceneIndex",
11
11
  SetAppFocusIndex = "SetAppFocusIndex",
12
12
  SwitchViewsToFreedom = "SwitchViewsToFreedom",
13
- MoveCamera = "MoveCamera",
14
- MoveCameraToContain = "MoveCameraToContain",
15
13
  CursorMove = "CursorMove",
16
14
  RootDirRemoved = "RootDirRemoved",
17
15
  Refresh = "Refresh",