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

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, Rectangle, 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,12 @@ 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;
236
+ moveCameraToContain(rectangle: Rectangle & {
237
+ animationMode?: AnimationMode;
238
+ }): void;
229
239
  convertToPointInWorld(point: Point): Point;
230
240
  setCameraBound(cameraBound: CameraBound): void;
231
241
  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.36",
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/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();
@@ -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 = () => {
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,8 +9,8 @@ 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";
13
- import { isEqual, isNull, isObject, isNumber } from "lodash";
12
+ import { AnimationMode, InvisiblePlugin, isPlayer, isRoom, RoomPhase, ViewMode } from "white-web-sdk";
13
+ import { isEqual, isNull, isObject, isNumber, isEmpty } from "lodash";
14
14
  import { log } from "./Utils/log";
15
15
  import { PageStateImpl } from "./PageState";
16
16
  import { ReconnectRefresher } from "./ReconnectRefresher";
@@ -44,14 +44,17 @@ import type {
44
44
  Player,
45
45
  ImageInformation,
46
46
  SceneState,
47
- Rectangle} from "white-web-sdk";
47
+ Rectangle,
48
+ Size
49
+ } from "white-web-sdk";
48
50
  import type { AppListeners } from "./AppListener";
49
51
  import type { ApplianceIcons, NetlessApp, RegisterParams } from "./typings";
50
- import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxState } from "@netless/telebox-insider";
52
+ import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxManagerThemeConfig, TeleBoxState } from "@netless/telebox-insider";
51
53
  import type { AppProxy } from "./App";
52
54
  import type { PublicEvent } from "./callback";
53
55
  import type Emittery from "emittery";
54
56
  import type { PageController, AddPageParams, PageState } from "./Page";
57
+ import { computedMinScale } from "./View/CameraSynchronizer";
55
58
 
56
59
  export type WindowMangerAttributes = {
57
60
  modelValue?: string;
@@ -146,6 +149,12 @@ export type MountParams = {
146
149
  prefersColorScheme?: TeleBoxColorScheme;
147
150
  applianceIcons?: ApplianceIcons;
148
151
  fullscreen?: TeleBoxFullscreen;
152
+ /** Custom `style` attribute value for content area of all boxes. Can be overwritten by box. */
153
+ defaultBoxBodyStyle?: string | null;
154
+ /** Custom `style` attribute value for stage area of all boxes. Can be overwritten by box. */
155
+ defaultBoxStageStyle?: string | null;
156
+ /** Theme variable */
157
+ theme?: TeleBoxManagerThemeConfig;
149
158
  };
150
159
 
151
160
  export const reconnectRefresher = new ReconnectRefresher({ emitter });
@@ -790,30 +799,86 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
790
799
  return this.appManager?.closeApp(appId);
791
800
  }
792
801
 
793
- public moveCamera(camera: Partial<Camera> ): void {
802
+ public moveCamera(camera: Partial<Camera> & { animationMode?: AnimationMode } ): void {
794
803
  const mainViewCamera = { ...this.mainView.camera };
795
804
  const nextCamera = { ...mainViewCamera, ...camera };
796
805
  if (isEqual(nextCamera, mainViewCamera)) return;
797
806
  if (!this.appManager) return;
798
- this.appManager.mainViewProxy.storeCamera({
799
- id: this.appManager.uid,
800
- ...nextCamera
801
- });
807
+ if (camera.animationMode === AnimationMode.Immediately) {
808
+ this.appManager.mainViewProxy.storeCamera({
809
+ id: this.appManager.uid,
810
+ ...nextCamera
811
+ });
812
+ } else {
813
+ const remoteCamera = this.appManager.mainViewProxy.size$.value;
814
+ const currentSize = this.boxManager?.stageRect;
815
+ let nextScale;
816
+ if (camera.scale && remoteCamera && currentSize) {
817
+ nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
818
+ }
819
+ if (nextScale) {
820
+ this.mainView.moveCamera({
821
+ ...camera,
822
+ scale: nextScale,
823
+ });
824
+ } else {
825
+ this.mainView.moveCamera(camera);
826
+ }
827
+ this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
828
+ setTimeout(() => {
829
+ if (!this.appManager) return;
830
+ this.appManager.mainViewProxy.storeCamera({
831
+ id: this.appManager.uid,
832
+ ...nextCamera
833
+ });
834
+ }, 200);
835
+ }
802
836
  }
803
837
 
804
- public moveCameraToContain(rectangle: Rectangle): void {
838
+ public moveCameraToContain(rectangle: Rectangle & { animationMode?: AnimationMode }): void {
805
839
  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);
811
- this.appManager.mainViewProxy.storeCamera({
840
+ const camera: Partial<Camera> = {};
841
+ if (isNumber(rectangle.originX)) {
842
+ camera.centerX = rectangle.originX;
843
+ }
844
+ if (isNumber(rectangle.originY)) {
845
+ camera.centerY = rectangle.originY;
846
+ }
847
+ if (rectangle.animationMode === AnimationMode.Immediately) {
848
+ this.appManager.mainViewProxy.storeSize({
812
849
  id: this.appManager.uid,
813
- scale: nextScale,
814
- centerX: rectangle.originX,
815
- centerY: rectangle.originY,
850
+ width: rectangle.width,
851
+ height: rectangle.height,
816
852
  });
853
+ this.mainView.moveCameraToContain(rectangle);
854
+ if (!isEmpty(camera) && this.appManager.mainViewProxy.camera$.value) {
855
+ this.appManager.mainViewProxy.storeCamera({
856
+ ...this.appManager.mainViewProxy.camera$.value,
857
+ id: this.appManager.uid,
858
+ centerX: this.mainView.camera.centerX,
859
+ centerY: this.mainView.camera.centerY
860
+ });
861
+ }
862
+ } else {
863
+ this.appManager.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
864
+ this.mainView.moveCameraToContain(rectangle);
865
+ setTimeout(() => {
866
+ if (!this.appManager) return;
867
+ this.appManager.mainViewProxy.storeSize({
868
+ id: this.appManager.uid,
869
+ width: rectangle.width,
870
+ height: rectangle.height,
871
+ });
872
+
873
+ if (!isEmpty(camera) && this.appManager.mainViewProxy.camera$.value) {
874
+ this.appManager.mainViewProxy.storeCamera({
875
+ ...this.appManager.mainViewProxy.camera$.value,
876
+ id: this.appManager.uid,
877
+ centerX: this.mainView.camera.centerX,
878
+ centerY: this.mainView.camera.centerY
879
+ });
880
+ }
881
+ }, 200);
817
882
  }
818
883
  }
819
884