@netless/window-manager 1.0.0-canary.35 → 1.0.0-canary.38

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.
@@ -16,4 +16,6 @@ export declare class AppListeners {
16
16
  private refreshHandler;
17
17
  private initMainViewCameraHandler;
18
18
  private setAppFocusViewIndexHandler;
19
+ private moveCameraHandler;
20
+ private moveCameraToContainHandler;
19
21
  }
@@ -4,7 +4,7 @@ import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
4
4
  import { WindowManager } from "./index";
5
5
  import type { BoxEmitterType } from "./BoxEmitter";
6
6
  import type { AddAppOptions } from "./index";
7
- import type { TeleBoxManagerUpdateConfig, ReadonlyTeleBox, TeleBoxColorScheme, TeleBoxRect, TeleBoxConfig, TeleBoxFullscreen } from "@netless/telebox-insider";
7
+ import type { TeleBoxManagerUpdateConfig, ReadonlyTeleBox, TeleBoxColorScheme, TeleBoxRect, TeleBoxConfig, TeleBoxFullscreen, TeleBoxManagerThemeConfig } from "@netless/telebox-insider";
8
8
  import type Emittery from "emittery";
9
9
  import type { NetlessApp } from "./typings";
10
10
  import type { View } from "white-web-sdk";
@@ -48,6 +48,9 @@ export declare type CreateTeleBoxManagerConfig = {
48
48
  containerStyle?: string;
49
49
  stageStyle?: string;
50
50
  fullscreen?: TeleBoxFullscreen;
51
+ defaultBoxBodyStyle?: string | null;
52
+ defaultBoxStageStyle?: string | null;
53
+ theme?: TeleBoxManagerThemeConfig;
51
54
  };
52
55
  export declare type BoxManagerContext = {
53
56
  safeSetAttributes: (attributes: any) => void;
@@ -3,6 +3,7 @@ import type { TeleBoxColorScheme, TELE_BOX_STATE } from "@netless/telebox-inside
3
3
  import type { CameraState, SceneState, ViewVisionMode } from "white-web-sdk";
4
4
  import type { LoadAppEvent } from "./Register";
5
5
  import type { PageState } from "./Page";
6
+ import { ICamera, ISize } from "./AttributesDelegate";
6
7
  export declare type PublicEvent = {
7
8
  mainViewModeChange: ViewVisionMode;
8
9
  boxStateChange: `${TELE_BOX_STATE}`;
@@ -24,6 +25,8 @@ export declare type PublicEvent = {
24
25
  kind: string;
25
26
  error?: Error;
26
27
  };
28
+ baseCameraChange: ICamera;
29
+ baseSizeChange: ISize;
27
30
  };
28
31
  export declare type CallbacksType = Emittery<PublicEvent>;
29
32
  export declare const callbacks: CallbacksType;
@@ -14,7 +14,9 @@ export declare enum Events {
14
14
  RootDirRemoved = "RootDirRemoved",
15
15
  Refresh = "Refresh",
16
16
  InitMainViewCamera = "InitMainViewCamera",
17
- InvokeAttributesUpdateCallback = "InvokeAttributesUpdateCallback"
17
+ InvokeAttributesUpdateCallback = "InvokeAttributesUpdateCallback",
18
+ MoveCamera = "MoveCamera",
19
+ MoveCameraToContain = "moveCameraToContain"
18
20
  }
19
21
  export declare const MagixEventName = "__WindowManger";
20
22
  export declare const EnsureReconnectEvent = "__WindowMangerEnsureReconnected__";
@@ -1,14 +1,14 @@
1
1
  import { AppManager } from "./AppManager";
2
2
  import { CursorManager } from "./Cursor";
3
- import { InvisiblePlugin, Size, ViewMode } from "white-web-sdk";
3
+ import { AnimationMode, InvisiblePlugin, ViewMode } from "white-web-sdk";
4
4
  import { ReconnectRefresher } from "./ReconnectRefresher";
5
5
  import { Val } from "value-enhancer";
6
6
  import type { TELE_BOX_STATE } from "./BoxManager";
7
7
  import type { Apps, Position, ICamera, ISize } from "./AttributesDelegate";
8
- import type { Displayer, SceneDefinition, View, Room, InvisiblePluginContext, Camera, CameraBound, Point, CameraState, Player, ImageInformation, SceneState, Rectangle } from "white-web-sdk";
8
+ import type { Displayer, SceneDefinition, View, Room, InvisiblePluginContext, Camera, CameraBound, Point, CameraState, Player, ImageInformation, SceneState, Size } from "white-web-sdk";
9
9
  import type { AppListeners } from "./AppListener";
10
10
  import type { ApplianceIcons, NetlessApp, RegisterParams } from "./typings";
11
- import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxState } from "@netless/telebox-insider";
11
+ import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxManagerThemeConfig, TeleBoxState } from "@netless/telebox-insider";
12
12
  import type { AppProxy } from "./App";
13
13
  import type { PublicEvent } from "./callback";
14
14
  import type Emittery from "emittery";
@@ -97,6 +97,12 @@ export declare type MountParams = {
97
97
  prefersColorScheme?: TeleBoxColorScheme;
98
98
  applianceIcons?: ApplianceIcons;
99
99
  fullscreen?: TeleBoxFullscreen;
100
+ /** Custom `style` attribute value for content area of all boxes. Can be overwritten by box. */
101
+ defaultBoxBodyStyle?: string | null;
102
+ /** Custom `style` attribute value for stage area of all boxes. Can be overwritten by box. */
103
+ defaultBoxStageStyle?: string | null;
104
+ /** Theme variable */
105
+ theme?: TeleBoxManagerThemeConfig;
100
106
  };
101
107
  export declare const reconnectRefresher: ReconnectRefresher;
102
108
  export declare class WindowManager extends InvisiblePlugin<WindowMangerAttributes> implements PageController {
@@ -224,8 +230,9 @@ export declare class WindowManager extends InvisiblePlugin<WindowMangerAttribute
224
230
  * 关闭 APP
225
231
  */
226
232
  closeApp(appId: string): Promise<void>;
227
- moveCamera(camera: Partial<Camera>): void;
228
- moveCameraToContain(rectangle: Rectangle): void;
233
+ moveCamera(camera: Partial<Camera> & {
234
+ animationMode?: AnimationMode;
235
+ }): void;
229
236
  convertToPointInWorld(point: Point): Point;
230
237
  setCameraBound(cameraBound: CameraBound): void;
231
238
  onDestroy(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "1.0.0-canary.35",
3
+ "version": "1.0.0-canary.38",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -2,9 +2,10 @@ import { callbacks } from "./callback";
2
2
  import { emitter } from "./InternalEmitter";
3
3
  import { Events, MagixEventName } from "./constants";
4
4
  import { setViewFocusScenePath } from "./Utils/Common";
5
- import type { Event } from "white-web-sdk";
5
+ import type { AnimationMode, Camera, Event, Rectangle } from "white-web-sdk";
6
6
  import type { AppManager } from "./AppManager";
7
7
  import type { TeleBoxState } from "@netless/telebox-insider";
8
+ import { computedMinScale } from "./View/CameraSynchronizer";
8
9
 
9
10
  type SetAppFocusIndex = {
10
11
  type: "main" | "app";
@@ -73,6 +74,14 @@ export class AppListeners {
73
74
  this.manager.attributesUpdateCallback(this.manager.attributes.apps);
74
75
  break;
75
76
  }
77
+ case Events.MoveCamera: {
78
+ this.moveCameraHandler(data.payload);
79
+ break;
80
+ }
81
+ case Events.MoveCameraToContain: {
82
+ this.moveCameraToContainHandler(data.payload);
83
+ break;
84
+ }
76
85
  default:
77
86
  break;
78
87
  }
@@ -125,4 +134,20 @@ export class AppListeners {
125
134
  }
126
135
  }
127
136
  }
137
+
138
+ private moveCameraHandler = (payload: Camera) => {
139
+ const cameraPayload = payload;
140
+ if (payload.scale) {
141
+ const remoteSize = this.manager.mainViewProxy.size$.value;
142
+ const currentSize = this.manager.boxManager?.stageRect;
143
+ if (remoteSize && currentSize) {
144
+ cameraPayload.scale = payload.scale * computedMinScale(remoteSize, currentSize);
145
+ }
146
+ }
147
+ this.manager.mainView.moveCamera(cameraPayload);
148
+ }
149
+
150
+ private moveCameraToContainHandler = (payload: Rectangle & { animationMode?: AnimationMode }) => {
151
+ this.manager.mainView.moveCameraToContain(payload);
152
+ }
128
153
  }
package/src/AppManager.ts CHANGED
@@ -472,16 +472,25 @@ export class AppManager {
472
472
  if (appIds.length === 0) {
473
473
  this.appCreateQueue.emitReady();
474
474
  }
475
- const appsWithCreatedAt = appIds.map(appId => {
475
+ let appsWithCreatedAt = appIds.map(appId => {
476
476
  if (apps[appId].setup) {
477
477
  return {
478
478
  id: appId,
479
479
  createdAt: apps[appId].createdAt,
480
480
  };
481
481
  } else {
482
- return {}
482
+ return {};
483
483
  }
484
484
  });
485
+ // 兼容 1.0 之前版本的回放, 回放时直接过判断 setup 直接创建 app
486
+ if (this.isReplay) {
487
+ appsWithCreatedAt = appIds.map(appId => {
488
+ return {
489
+ id: appId,
490
+ createdAt: apps[appId].createdAt,
491
+ };
492
+ });
493
+ }
485
494
  for (const { id } of orderBy(appsWithCreatedAt, "createdAt", "asc")) {
486
495
  if (id && !this.appProxies.has(id) && !this.appStatus.has(id)) {
487
496
  const app = apps[id];
package/src/BoxManager.ts CHANGED
@@ -15,7 +15,7 @@ import type {
15
15
  TeleBoxRect,
16
16
  TeleBoxConfig,
17
17
  TeleBoxFullscreen
18
- } from "@netless/telebox-insider";
18
+ , TeleBoxManagerThemeConfig } from "@netless/telebox-insider";
19
19
  import type Emittery from "emittery";
20
20
  import type { NetlessApp } from "./typings";
21
21
  import type { View } from "white-web-sdk";
@@ -53,6 +53,9 @@ export type CreateTeleBoxManagerConfig = {
53
53
  containerStyle?: string;
54
54
  stageStyle?: string;
55
55
  fullscreen?: TeleBoxFullscreen;
56
+ defaultBoxBodyStyle?: string | null;
57
+ defaultBoxStageStyle?: string | null;
58
+ theme?: TeleBoxManagerThemeConfig;
56
59
  };
57
60
 
58
61
  export type BoxManagerContext = {
@@ -268,6 +271,18 @@ export class BoxManager {
268
271
  initManagerState.fullscreen = createTeleBoxManagerConfig.fullscreen;
269
272
  }
270
273
 
274
+ if (createTeleBoxManagerConfig?.defaultBoxBodyStyle !== undefined) {
275
+ initManagerState.defaultBoxBodyStyle = createTeleBoxManagerConfig.defaultBoxBodyStyle;
276
+ }
277
+
278
+ if (createTeleBoxManagerConfig?.defaultBoxStageStyle !== undefined) {
279
+ initManagerState.defaultBoxStageStyle = createTeleBoxManagerConfig.defaultBoxStageStyle;
280
+ }
281
+
282
+ if (createTeleBoxManagerConfig?.theme) {
283
+ initManagerState.theme = createTeleBoxManagerConfig.theme;
284
+ }
285
+
271
286
  const manager = new TeleBoxManager(initManagerState);
272
287
  if (this.teleBoxManager) {
273
288
  this.teleBoxManager.destroy();
@@ -48,11 +48,14 @@ export class CameraSynchronizer {
48
48
  this.remoteSize = size;
49
49
  const needMoveCamera = !isEqual(pick(this.rect, ["width", "height"]), pick(size, ["width", "height"]));
50
50
  if (this.rect && this.remoteCamera && needMoveCamera) {
51
- const scale = this.rect.width / size.width;
52
- const nextScale = this.remoteCamera.scale * scale;
53
- this.moveCamera({
54
- scale: nextScale,
55
- })
51
+ if (!this.view) return;
52
+ const currentCamera = this.view.camera;
53
+ this.view?.moveCameraToContain({
54
+ width: size.width,
55
+ height: size.height,
56
+ originX: currentCamera.centerX - (size.width / 2),
57
+ originY: currentCamera.centerY - (size.height / 2),
58
+ });
56
59
  }
57
60
  }
58
61
 
@@ -49,6 +49,16 @@ export class MainViewProxy {
49
49
  }
50
50
  }
51
51
  }));
52
+ this.camera$.reaction(camera => {
53
+ if (camera) {
54
+ callbacks.emit("baseCameraChange", camera);
55
+ }
56
+ });
57
+ this.size$.reaction(size => {
58
+ if (size) {
59
+ callbacks.emit("baseSizeChange", size);
60
+ }
61
+ });
52
62
  }
53
63
 
54
64
  public createViewSync = () => {
@@ -1,4 +1,4 @@
1
- import { ViewMode, AnimationMode, Size } from "white-web-sdk";
1
+ import { ViewMode, AnimationMode } from "white-web-sdk";
2
2
  import { CameraSynchronizer, computedMinScale } from "./CameraSynchronizer";
3
3
  import { combine } from "value-enhancer";
4
4
  import { SideEffectManager } from "side-effect-manager";
package/src/callback.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import Emittery from "emittery";
2
2
  import type { TeleBoxColorScheme, TELE_BOX_STATE } from "@netless/telebox-insider";
3
- import type { CameraState, SceneState, ViewVisionMode } from "white-web-sdk";
3
+ import type { Camera, CameraState, SceneState, Size, ViewVisionMode } from "white-web-sdk";
4
4
  import type { LoadAppEvent } from "./Register";
5
5
  import type { PageState } from "./Page";
6
+ import { ICamera, ISize } from "./AttributesDelegate";
6
7
 
7
8
  export type PublicEvent = {
8
9
  mainViewModeChange: ViewVisionMode;
@@ -21,6 +22,8 @@ export type PublicEvent = {
21
22
  sceneStateChange: SceneState;
22
23
  pageStateChange: PageState;
23
24
  appClose: { appId: string; kind: string, error?: Error };
25
+ baseCameraChange: ICamera;
26
+ baseSizeChange: ISize;
24
27
  };
25
28
 
26
29
  export type CallbacksType = Emittery<PublicEvent>;
package/src/constants.ts CHANGED
@@ -15,6 +15,8 @@ export enum Events {
15
15
  Refresh = "Refresh",
16
16
  InitMainViewCamera = "InitMainViewCamera",
17
17
  InvokeAttributesUpdateCallback = "InvokeAttributesUpdateCallback",
18
+ MoveCamera = "MoveCamera",
19
+ MoveCameraToContain = "moveCameraToContain",
18
20
  }
19
21
 
20
22
  export const MagixEventName = "__WindowManger";
package/src/index.ts CHANGED
@@ -9,7 +9,7 @@ import { DEFAULT_CONTAINER_RATIO, Events, INIT_DIR, ROOT_DIR } from "./constants
9
9
  import { emitter } from "./InternalEmitter";
10
10
  import { Fields } from "./AttributesDelegate";
11
11
  import { initDb } from "./Register/storage";
12
- import { InvisiblePlugin, isPlayer, isRoom, RoomPhase, Size, ViewMode } from "white-web-sdk";
12
+ import { AnimationMode, InvisiblePlugin, isPlayer, isRoom, RoomPhase, ViewMode } from "white-web-sdk";
13
13
  import { isEqual, isNull, isObject, isNumber } from "lodash";
14
14
  import { log } from "./Utils/log";
15
15
  import { PageStateImpl } from "./PageState";
@@ -44,14 +44,16 @@ import type {
44
44
  Player,
45
45
  ImageInformation,
46
46
  SceneState,
47
- Rectangle} from "white-web-sdk";
47
+ Size
48
+ } from "white-web-sdk";
48
49
  import type { AppListeners } from "./AppListener";
49
50
  import type { ApplianceIcons, NetlessApp, RegisterParams } from "./typings";
50
- import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxState } from "@netless/telebox-insider";
51
+ import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxManagerThemeConfig, TeleBoxState } from "@netless/telebox-insider";
51
52
  import type { AppProxy } from "./App";
52
53
  import type { PublicEvent } from "./callback";
53
54
  import type Emittery from "emittery";
54
55
  import type { PageController, AddPageParams, PageState } from "./Page";
56
+ import { computedMinScale } from "./View/CameraSynchronizer";
55
57
 
56
58
  export type WindowMangerAttributes = {
57
59
  modelValue?: string;
@@ -146,6 +148,12 @@ export type MountParams = {
146
148
  prefersColorScheme?: TeleBoxColorScheme;
147
149
  applianceIcons?: ApplianceIcons;
148
150
  fullscreen?: TeleBoxFullscreen;
151
+ /** Custom `style` attribute value for content area of all boxes. Can be overwritten by box. */
152
+ defaultBoxBodyStyle?: string | null;
153
+ /** Custom `style` attribute value for stage area of all boxes. Can be overwritten by box. */
154
+ defaultBoxStageStyle?: string | null;
155
+ /** Theme variable */
156
+ theme?: TeleBoxManagerThemeConfig;
149
157
  };
150
158
 
151
159
  export const reconnectRefresher = new ReconnectRefresher({ emitter });
@@ -790,33 +798,101 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
790
798
  return this.appManager?.closeApp(appId);
791
799
  }
792
800
 
793
- public moveCamera(camera: Partial<Camera> ): void {
801
+ public moveCamera(camera: Partial<Camera> & { animationMode?: AnimationMode } ): void {
794
802
  const mainViewCamera = { ...this.mainView.camera };
795
803
  const nextCamera = { ...mainViewCamera, ...camera };
796
804
  if (isEqual(nextCamera, mainViewCamera)) return;
797
805
  if (!this.appManager) return;
798
- this.appManager.mainViewProxy.storeCamera({
799
- id: this.appManager.uid,
800
- ...nextCamera
801
- });
802
- }
803
-
804
- public moveCameraToContain(rectangle: Rectangle): void {
805
- if (!this.appManager) return;
806
- const mainViewSize = this.appManager.mainViewProxy.size$.value;
807
- if (mainViewSize) {
808
- const wScale = mainViewSize.width / rectangle.width;
809
- const hScale = mainViewSize.height / rectangle.height;
810
- const nextScale = Math.min(wScale, hScale);
806
+ if (camera.animationMode === AnimationMode.Immediately) {
811
807
  this.appManager.mainViewProxy.storeCamera({
812
808
  id: this.appManager.uid,
813
- scale: nextScale,
814
- centerX: rectangle.originX,
815
- centerY: rectangle.originY,
809
+ ...nextCamera
816
810
  });
811
+ } else {
812
+ const remoteCamera = this.appManager.mainViewProxy.size$.value;
813
+ const currentSize = this.boxManager?.stageRect;
814
+ let nextScale;
815
+ if (camera.scale && remoteCamera && currentSize) {
816
+ nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
817
+ }
818
+ if (nextScale) {
819
+ this.mainView.moveCamera({
820
+ ...camera,
821
+ scale: nextScale,
822
+ });
823
+ } else {
824
+ this.mainView.moveCamera(camera);
825
+ }
826
+ this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
827
+ setTimeout(() => {
828
+ if (!this.appManager) return;
829
+ this.appManager.mainViewProxy.storeCamera({
830
+ id: this.appManager.uid,
831
+ ...nextCamera
832
+ });
833
+ }, 200);
817
834
  }
818
835
  }
819
836
 
837
+ // public moveCameraToContain(rectangle: Rectangle & { animationMode?: AnimationMode }): void {
838
+ // this.setBaseSize(rectangle);
839
+ // const centerX = rectangle.originX + (rectangle.width / 2);
840
+ // const centerY = rectangle.originY + (rectangle.height / 2);
841
+ // setTimeout(() => {
842
+ // this.moveCamera({ centerX, centerY, animationMode: rectangle.animationMode });
843
+ // }, 500);
844
+ // // if (!this.appManager) return;
845
+ // // const camera: Partial<Camera> = {};
846
+ // // if (isNumber(rectangle.originX)) {
847
+ // // camera.centerX = rectangle.originX;
848
+ // // }
849
+ // // if (isNumber(rectangle.originY)) {
850
+ // // camera.centerY = rectangle.originY;
851
+ // // }
852
+ // // if (rectangle.animationMode === AnimationMode.Immediately) {
853
+ // // this.appManager.mainViewProxy.storeSize({
854
+ // // id: this.appManager.uid,
855
+ // // width: rectangle.width,
856
+ // // height: rectangle.height,
857
+ // // });
858
+ // // this.mainView.moveCameraToContain(rectangle);
859
+ // // if (!isEmpty(camera) && this.appManager.mainViewProxy.camera$.value) {
860
+ // // this.appManager.mainViewProxy.storeCamera({
861
+ // // ...this.appManager.mainViewProxy.camera$.value,
862
+ // // id: this.appManager.uid,
863
+ // // centerX: this.mainView.camera.centerX,
864
+ // // centerY: this.mainView.camera.centerY
865
+ // // });
866
+ // // }
867
+ // // } else {
868
+ // // this.appManager.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
869
+ // // this.mainView.moveCameraToContain(rectangle);
870
+ // // if (!this.baseCamera) return;
871
+ // // const remoteSize = rectangle;
872
+ // // const currentSize = this.boxManager?.stageRect;
873
+ // // if (!currentSize) return;
874
+ // // const nextScale = this.baseCamera.scale * computedMinScale(remoteSize, currentSize);
875
+ // // setTimeout(() => {
876
+ // // if (!this.appManager) return;
877
+ // // this.appManager.mainViewProxy.storeSize({
878
+ // // id: this.appManager.uid,
879
+ // // width: rectangle.width,
880
+ // // height: rectangle.height,
881
+ // // });
882
+
883
+ // // if (!isEmpty(camera) && this.appManager.mainViewProxy.camera$.value) {
884
+ // // this.appManager.mainViewProxy.storeCamera({
885
+ // // ...this.appManager.mainViewProxy.camera$.value,
886
+ // // id: this.appManager.uid,
887
+ // // centerX: this.mainView.camera.centerX,
888
+ // // centerY: this.mainView.camera.centerY,
889
+ // // scale: nextScale
890
+ // // });
891
+ // // }
892
+ // // }, 500);
893
+ // // }
894
+ // }
895
+
820
896
  public convertToPointInWorld(point: Point): Point {
821
897
  return this.mainView.convertToPointInWorld(point);
822
898
  }