@netless/window-manager 1.0.7-beta.1 → 1.0.7-beta.3

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.
@@ -4,11 +4,14 @@ import { setViewFocusScenePath } from "./Utils/Common";
4
4
  import type { AddAppParams, AppSyncAttributes } from "./index";
5
5
  import type { Camera, Size, View } from "white-web-sdk";
6
6
  import type { Cursor } from "./Cursor/Cursor";
7
+ import { ExtendClass, getExtendClass } from "./Utils/extendClass";
8
+ import { NotMinimizedBoxState, TELE_BOX_STATE, TeleBoxState } from "@netless/telebox-insider";
7
9
 
8
10
  export enum Fields {
9
11
  Apps = "apps",
10
12
  Focus = "focus",
11
13
  State = "state",
14
+ /** 默认窗口状态, (用于窗口状态的统一管理) */
12
15
  BoxState = "boxState",
13
16
  MainViewCamera = "mainViewCamera",
14
17
  MainViewSize = "mainViewSize",
@@ -19,6 +22,10 @@ export enum Fields {
19
22
  FullPath = "fullPath",
20
23
  Registered = "registered",
21
24
  IframeBridge = "iframeBridge",
25
+ /** 所有窗口状态, (用于窗口状态的单独管理) */
26
+ BoxesStatus = "boxesStatus",
27
+ /** 上次非最小化窗口状态 */
28
+ LastNotMinimizedBoxesStatus = "lastNotMinimizedBoxesStatus",
22
29
  }
23
30
 
24
31
  export type Apps = {
@@ -79,6 +86,42 @@ export class AttributesDelegate {
79
86
  return get(this.attributes, ["minimized"]);
80
87
  }
81
88
 
89
+ public getBoxesStatus(): Record<string, TELE_BOX_STATE> | undefined {
90
+ return get(this.attributes, [Fields.BoxesStatus]);
91
+ }
92
+
93
+ public getBoxStatus(id: string): TELE_BOX_STATE | undefined {
94
+ return get(this.attributes, [Fields.BoxesStatus, id]);
95
+ }
96
+
97
+ public setBoxStatus(id: string, status?: TeleBoxState) {
98
+ const attributes = this.attributes;
99
+ if (!attributes.boxesStatus) {
100
+ this.context.safeSetAttributes({ boxesStatus: {} });
101
+ }
102
+ if (this.getBoxStatus(id) !== status) {
103
+ this.context.safeUpdateAttributes([Fields.BoxesStatus, id], status);
104
+ }
105
+ }
106
+
107
+ public getLastNotMinimizedBoxesStatus(): Record<string, NotMinimizedBoxState> | undefined {
108
+ return get(this.attributes, [Fields.LastNotMinimizedBoxesStatus]);
109
+ }
110
+
111
+ public getLastNotMinimizedBoxStatus(id: string): NotMinimizedBoxState | undefined {
112
+ return get(this.attributes, [Fields.LastNotMinimizedBoxesStatus, id]);
113
+ }
114
+
115
+ public setLastNotMinimizedBoxStatus(id: string, status?: NotMinimizedBoxState) {
116
+ const attributes = this.attributes;
117
+ if (!attributes.lastNotMinimizedBoxesStatus) {
118
+ this.context.safeSetAttributes({ lastNotMinimizedBoxesStatus: {} });
119
+ }
120
+ if (this.getLastNotMinimizedBoxStatus(id) !== status) {
121
+ this.context.safeUpdateAttributes([Fields.LastNotMinimizedBoxesStatus, id], status);
122
+ }
123
+ }
124
+
82
125
  public setupAppAttributes(params: AddAppParams, id: string, isDynamicPPT: boolean) {
83
126
  const attributes = this.attributes;
84
127
  if (!attributes.apps) {
@@ -249,14 +292,32 @@ export type Cursors = {
249
292
  [key: string]: Cursor;
250
293
  };
251
294
 
252
- export const store = new AttributesDelegate({
253
- getAttributes: () => {
254
- throw new Error("getAttributes not implemented");
255
- },
256
- safeSetAttributes: () => {
257
- throw new Error("safeSetAttributes not implemented");
258
- },
259
- safeUpdateAttributes: () => {
260
- throw new Error("safeUpdateAttributes not implemented");
261
- },
262
- });
295
+ // export const store = new AttributesDelegate({
296
+ // getAttributes: () => {
297
+ // throw new Error("getAttributes not implemented");
298
+ // },
299
+ // safeSetAttributes: () => {
300
+ // throw new Error("safeSetAttributes not implemented");
301
+ // },
302
+ // safeUpdateAttributes: () => {
303
+ // throw new Error("safeUpdateAttributes not implemented");
304
+ // },
305
+ // });
306
+
307
+ export const createAttributesDelegate = (
308
+ extendClass?: ExtendClass,
309
+ context: StoreContext = {
310
+ getAttributes: () => {
311
+ throw new Error("getAttributes not implemented");
312
+ },
313
+ safeSetAttributes: () => {
314
+ throw new Error("safeSetAttributes not implemented");
315
+ },
316
+ safeUpdateAttributes: () => {
317
+ throw new Error("safeUpdateAttributes not implemented");
318
+ },
319
+ }
320
+ ) => {
321
+ const AttributesDelegateClass = getExtendClass(AttributesDelegate, extendClass);
322
+ return new AttributesDelegateClass(context);
323
+ };
package/src/BoxEmitter.ts CHANGED
@@ -3,6 +3,7 @@ import Emittery from "emittery";
3
3
 
4
4
  export type BoxMovePayload = { appId: string; x: number; y: number };
5
5
  export type BoxFocusPayload = { appId: string };
6
+ export type BoxBlurredPayload = { appId: string };
6
7
  export type BoxResizePayload = {
7
8
  appId: string;
8
9
  width: number;
@@ -19,6 +20,7 @@ export type BoxEvent = {
19
20
  resize: BoxResizePayload;
20
21
  close: BoxClosePayload;
21
22
  boxStateChange: BoxStateChangePayload;
23
+ blurred: BoxBlurredPayload;
22
24
  };
23
25
 
24
26
  export type BoxEmitterType = Emittery<BoxEvent>;
package/src/BoxManager.ts CHANGED
@@ -12,12 +12,15 @@ import type {
12
12
  TeleBoxColorScheme,
13
13
  TeleBoxRect,
14
14
  TeleBoxConfig,
15
+ TeleBoxState,
16
+ NotMinimizedBoxState,
15
17
  } from "@netless/telebox-insider";
16
18
  import type Emittery from "emittery";
17
19
  import type { NetlessApp } from "./typings";
18
20
  import type { View } from "white-web-sdk";
19
21
  import type { CallbacksType } from "./callback";
20
22
  import type { EmitterType } from "./InternalEmitter";
23
+ import { getExtendClass } from "./Utils/extendClass";
21
24
 
22
25
  export { TELE_BOX_STATE };
23
26
 
@@ -29,6 +32,7 @@ export type CreateBoxParams = {
29
32
  options?: AddAppOptions;
30
33
  canOperate?: boolean;
31
34
  smartPosition?: boolean;
35
+ boxStatus?: TeleBoxState;
32
36
  };
33
37
 
34
38
  type AppId = { appId: string };
@@ -45,12 +49,15 @@ export type CreateTeleBoxManagerConfig = {
45
49
  collectorContainer?: HTMLElement;
46
50
  collectorStyles?: Partial<CSSStyleDeclaration>;
47
51
  prefersColorScheme?: TeleBoxColorScheme;
52
+ useBoxesStatus?: boolean;
48
53
  };
49
54
 
50
55
  export type BoxManagerContext = {
51
56
  safeSetAttributes: (attributes: any) => void;
52
57
  getMainView: () => View;
53
58
  updateAppState: (appId: string, field: AppAttributes, value: any) => void;
59
+ setBoxStatus: (appId: string, status?: TeleBoxState) => void;
60
+ setLastNotMinimizedBoxStatus: (appId: string, status?: NotMinimizedBoxState) => void;
54
61
  emitter: EmitterType;
55
62
  boxEmitter: BoxEmitterType;
56
63
  callbacks: CallbacksType;
@@ -67,11 +74,22 @@ export const createBoxManager = (
67
74
  boxEmitter: BoxEmitterType,
68
75
  options: CreateTeleBoxManagerConfig
69
76
  ) => {
70
- return new BoxManager(
77
+ const BoxManagerClass = getExtendClass(BoxManager, WindowManager.extendClass);
78
+ return new BoxManagerClass(
71
79
  {
72
80
  safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
73
81
  getMainView: () => manager.mainView,
74
82
  updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
83
+ setBoxStatus: (id: string, boxStatus?: TeleBoxState) =>
84
+ manager.appManager?.store.setBoxStatus(id, boxStatus),
85
+ setLastNotMinimizedBoxStatus: (
86
+ id: string,
87
+ lastNotMinimizedBoxStatus?: NotMinimizedBoxState
88
+ ) =>
89
+ manager.appManager?.store.setLastNotMinimizedBoxStatus(
90
+ id,
91
+ lastNotMinimizedBoxStatus
92
+ ),
75
93
  canOperate: () => manager.canOperate,
76
94
  notifyContainerRectUpdate: (rect: TeleBoxRect) =>
77
95
  manager.appManager?.notifyContainerRectUpdate(rect),
@@ -167,9 +185,32 @@ export class BoxManager {
167
185
  }
168
186
  }
169
187
  });
188
+ this.teleBoxManager.events.on("blurred", box => {
189
+ if (box) {
190
+ if (this.canOperate) {
191
+ boxEmitter.emit("blurred", { appId: box.id });
192
+ }
193
+ }
194
+ });
170
195
  this.teleBoxManager.events.on("z_index", box => {
171
196
  this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
172
197
  });
198
+ this.teleBoxManager.events.on(
199
+ "box_status",
200
+ (box: { id: string; boxStatus?: TeleBoxState }) => {
201
+ if (this.canOperate) {
202
+ this.context.setBoxStatus(box.id, box.boxStatus);
203
+ }
204
+ }
205
+ );
206
+ this.teleBoxManager.events.on(
207
+ "last_not_minimized_box_status",
208
+ (box: { id: string; boxStatus?: NotMinimizedBoxState }) => {
209
+ if (this.canOperate) {
210
+ this.context.setLastNotMinimizedBoxStatus(box.id, box.boxStatus);
211
+ }
212
+ }
213
+ );
173
214
  emitter.on("playgroundSizeChange", () => this.updateManagerRect());
174
215
  emitter.on("updateManagerRect", () => this.updateManagerRect());
175
216
  }
@@ -228,6 +269,7 @@ export class BoxManager {
228
269
  width,
229
270
  height,
230
271
  id: params.appId,
272
+ boxStatus: params.boxStatus,
231
273
  };
232
274
  this.teleBoxManager.create(createBoxConfig, params.smartPosition);
233
275
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
@@ -247,6 +289,21 @@ export class BoxManager {
247
289
  }
248
290
  }
249
291
  }
292
+ public setBoxesStatus(status?: Record<string, TeleBoxState>): void {
293
+ this.teleBoxManager.setBoxesStatus(new Map(Object.entries(status ?? {})), true);
294
+ }
295
+
296
+ public setBoxStatus(appId: string, status?: TeleBoxState): void {
297
+ this.teleBoxManager.update(appId, { boxStatus: status }, true);
298
+ }
299
+
300
+ public setLastNotMinimizedBoxesStatus(status?: Record<string, NotMinimizedBoxState>): void {
301
+ this.teleBoxManager.setLastNotMinimizedBoxesStatus(new Map(Object.entries(status ?? {})), true);
302
+ }
303
+
304
+ public setLastNotMinimizedBoxStatus(appId: string, status?: NotMinimizedBoxState): void {
305
+ this.teleBoxManager.update(appId, { lastNotMinimizedBoxStatus: status }, true);
306
+ }
250
307
 
251
308
  public setupBoxManager(
252
309
  createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
@@ -263,6 +320,7 @@ export class BoxManager {
263
320
  },
264
321
  fence: false,
265
322
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
323
+ useBoxesStatus: createTeleBoxManagerConfig?.useBoxesStatus || false,
266
324
  };
267
325
 
268
326
  const manager = new TeleBoxManager(initManagerState);
@@ -318,6 +376,8 @@ export class BoxManager {
318
376
  width: state.width || 0.5,
319
377
  height: state.height || 0.5,
320
378
  zIndex: state.zIndex,
379
+ boxStatus: state.boxStatus,
380
+ lastNotMinimizedBoxStatus: state.lastNotMinimizedBoxStatus,
321
381
  },
322
382
  true
323
383
  );
@@ -0,0 +1,49 @@
1
+ import { AppContext, AppProxy } from "../App";
2
+ import { AppManager } from "../AppManager";
3
+ import { AttributesDelegate } from "../AttributesDelegate";
4
+ import { BoxManager } from "../BoxManager";
5
+ import { CursorManager } from "../Cursor";
6
+
7
+ export { AppManager } from "../AppManager";
8
+ export { AppContext, AppProxy } from "../App";
9
+ export { BoxManager } from "../BoxManager";
10
+ export { AttributesDelegate } from "../AttributesDelegate";
11
+ export { CursorManager } from "../Cursor";
12
+
13
+ export type ExtendClassAble =
14
+ | typeof AppManager
15
+ | typeof AppProxy
16
+ | typeof AppContext
17
+ | typeof BoxManager
18
+ | typeof AttributesDelegate
19
+ | typeof CursorManager
20
+
21
+ export type ExtendClass = {
22
+ AppManager?: typeof AppManager;
23
+ BoxManager?: typeof BoxManager;
24
+ AttributesDelegate?: typeof AttributesDelegate;
25
+ CursorManager?: typeof CursorManager;
26
+ AppProxy?: typeof AppProxy;
27
+ AppContext?: typeof AppContext;
28
+ };
29
+ export function getExtendClass<T extends ExtendClassAble>(
30
+ baseClass: T,
31
+ extendClass?: ExtendClass
32
+ ): T {
33
+ switch (baseClass.name) {
34
+ case "AppManager":
35
+ return (extendClass?.AppManager || AppManager) as T;
36
+ case "BoxManager":
37
+ return (extendClass?.BoxManager || BoxManager) as T;
38
+ case "AttributesDelegate":
39
+ return (extendClass?.AttributesDelegate || AttributesDelegate) as T;
40
+ case "CursorManager":
41
+ return (extendClass?.CursorManager || CursorManager) as T;
42
+ case "AppProxy":
43
+ return (extendClass?.AppProxy || AppProxy) as T;
44
+ case "AppContext":
45
+ return (extendClass?.AppContext || AppContext) as T;
46
+ default:
47
+ return baseClass;
48
+ }
49
+ }
package/src/callback.ts CHANGED
@@ -4,6 +4,7 @@ import type { CameraState, SceneState, View, ViewVisionMode } from "white-web-sd
4
4
  import type { LoadAppEvent } from "./Register";
5
5
  import type { PageState } from "./Page";
6
6
  import type {
7
+ BoxBlurredPayload,
7
8
  BoxClosePayload,
8
9
  BoxFocusPayload,
9
10
  BoxMovePayload,
@@ -33,6 +34,7 @@ export type PublicEvent = {
33
34
  onBoxMove: BoxMovePayload;
34
35
  onBoxResize: BoxResizePayload;
35
36
  onBoxFocus: BoxFocusPayload;
37
+ onBoxBlurred: BoxBlurredPayload;
36
38
  onBoxClose: BoxClosePayload;
37
39
  onBoxStateChange: BoxStateChangePayload;
38
40
  onMainViewMounted: View;
package/src/index.ts CHANGED
@@ -28,9 +28,9 @@ import {
28
28
  putScenes,
29
29
  wait,
30
30
  } from "./Utils/Common";
31
- import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
31
+ import { TELE_BOX_STATE, BoxManager } from "./BoxManager";
32
32
  import * as Errors from "./Utils/error";
33
- import type { Apps, Position } from "./AttributesDelegate";
33
+ import { Apps, Position } from "./AttributesDelegate";
34
34
  import type {
35
35
  Displayer,
36
36
  SceneDefinition,
@@ -49,8 +49,12 @@ import type {
49
49
  } from "white-web-sdk";
50
50
  import type { AppListeners } from "./AppListener";
51
51
  import type { ApplianceIcons, NetlessApp, RegisterParams } from "./typings";
52
- import type { TeleBoxColorScheme, TeleBoxState } from "@netless/telebox-insider";
53
- import type { AppProxy } from "./App";
52
+ import type {
53
+ NotMinimizedBoxState,
54
+ TeleBoxColorScheme,
55
+ TeleBoxState,
56
+ } from "@netless/telebox-insider";
57
+ import { AppProxy } from "./App";
54
58
  import type { PublicEvent } from "./callback";
55
59
  import type Emittery from "emittery";
56
60
  import type { PageController, AddPageParams, PageState } from "./Page";
@@ -59,7 +63,9 @@ import { IframeBridge } from "./View/IframeBridge";
59
63
  import { setOptions } from "@netless/app-media-player";
60
64
  import type { ExtendPluginInstance } from "./ExtendPluginManager";
61
65
  import { ExtendPluginManager } from "./ExtendPluginManager";
62
- export * from "./View/IframeBridge";
66
+ import { ExtendClass, getExtendClass } from "./Utils/extendClass";
67
+
68
+ export * from "./utils/extendClass";
63
69
 
64
70
  export type WindowMangerAttributes = {
65
71
  modelValue?: string;
@@ -122,8 +128,13 @@ export type AppInitState = {
122
128
  maximized?: boolean;
123
129
  minimized?: boolean;
124
130
  sceneIndex?: number;
131
+ /** 所有box的基本状态 */
125
132
  boxState?: TeleBoxState; // 兼容旧版 telebox
126
133
  zIndex?: number;
134
+ /** 扩展版本,单个box的状态 */
135
+ boxStatus?: TeleBoxState;
136
+ /** 上次非最小化窗口状态 */
137
+ lastNotMinimizedBoxStatus?: NotMinimizedBoxState;
127
138
  };
128
139
 
129
140
  export type CursorMovePayload = { uid: string; state?: "leave"; position: Position };
@@ -156,10 +167,11 @@ export type MountParams = {
156
167
  fullscreen?: boolean;
157
168
  polling?: boolean;
158
169
  supportAppliancePlugin?: boolean;
170
+ /** 是否使用 boxesStatus 状态管理窗口 */
171
+ useBoxesStatus?: boolean;
159
172
  };
160
173
 
161
174
  export const reconnectRefresher = new ReconnectRefresher({ emitter: internalEmitter });
162
-
163
175
  export class WindowManager
164
176
  extends InvisiblePlugin<WindowMangerAttributes, any>
165
177
  implements PageController
@@ -194,6 +206,7 @@ export class WindowManager
194
206
 
195
207
  private boxManager?: BoxManager;
196
208
  private static params?: MountParams;
209
+ static extendClass?: ExtendClass;
197
210
 
198
211
  private containerResizeObserver?: ContainerResizeObserver;
199
212
  public containerSizeRatio = WindowManager.containerSizeRatio;
@@ -210,7 +223,10 @@ export class WindowManager
210
223
  WindowManager._resolve(manager);
211
224
  }
212
225
 
213
- public static async mount(params: MountParams): Promise<WindowManager> {
226
+ public static async mount(
227
+ params: MountParams,
228
+ extendClass?: ExtendClass
229
+ ): Promise<WindowManager> {
214
230
  const room = params.room;
215
231
  WindowManager.container = params.container;
216
232
  WindowManager.supportAppliancePlugin = params.supportAppliancePlugin;
@@ -219,6 +235,7 @@ export class WindowManager
219
235
 
220
236
  const cursor = params.cursor;
221
237
  WindowManager.params = params;
238
+ WindowManager.extendClass = extendClass;
222
239
  WindowManager.displayer = params.room;
223
240
  checkVersion();
224
241
  let manager: WindowManager | undefined = undefined;
@@ -269,11 +286,14 @@ export class WindowManager
269
286
  }
270
287
  await manager.ensureAttributes();
271
288
 
289
+ const AppManagerClass = getExtendClass(AppManager, WindowManager.extendClass);
290
+ const CursorManagerClass = getExtendClass(CursorManager, WindowManager.extendClass);
291
+
272
292
  manager._fullscreen = params.fullscreen;
273
- manager.appManager = new AppManager(manager);
293
+ manager.appManager = new AppManagerClass(manager);
274
294
  manager.appManager.polling = params.polling || false;
275
295
  manager._pageState = new PageStateImpl(manager.appManager);
276
- manager.cursorManager = new CursorManager(
296
+ manager.cursorManager = new CursorManagerClass(
277
297
  manager.appManager,
278
298
  Boolean(cursor),
279
299
  params.cursorOptions,
@@ -369,9 +389,14 @@ export class WindowManager
369
389
  collectorContainer: params.collectorContainer,
370
390
  collectorStyles: params.collectorStyles,
371
391
  prefersColorScheme: params.prefersColorScheme,
392
+ useBoxesStatus: params.useBoxesStatus,
372
393
  });
373
394
  this.boxManager = boxManager;
374
- this.appManager?.setBoxManager(boxManager);
395
+ if (this.appManager) {
396
+ this.appManager.useBoxesStatus = params.useBoxesStatus || false;
397
+ this.appManager.setBoxManager(boxManager);
398
+
399
+ }
375
400
  this.bindMainView(mainViewElement, params.disableCameraTransform);
376
401
  if (WindowManager.wrapper) {
377
402
  this.cursorManager?.setupWrapper(WindowManager.wrapper);
@@ -696,6 +721,21 @@ export class WindowManager
696
721
  this.boxManager?.setMinimized(minimized, false);
697
722
  }
698
723
 
724
+ /** 设置指定 box 的状态, 如果为 undefined, 则移除状态*/
725
+ public setBoxStatus(boxId: string, boxStatus?: TELE_BOX_STATE): void {
726
+ if (!this.canOperate) return;
727
+ this.boxManager?.setBoxStatus(boxId, boxStatus);
728
+ }
729
+
730
+ /** 设置指定 box 的非最小化状态, 如果为 undefined, 则移除状态 */
731
+ public setLastNotMinimizedBoxStatus(
732
+ boxId: string,
733
+ lastNotMinimizedBoxStatus?: NotMinimizedBoxState
734
+ ): void {
735
+ if (!this.canOperate) return;
736
+ this.boxManager?.setLastNotMinimizedBoxStatus(boxId, lastNotMinimizedBoxStatus);
737
+ }
738
+
699
739
  public setFullscreen(fullscreen: boolean): void {
700
740
  if (this._fullscreen !== fullscreen) {
701
741
  this._fullscreen = fullscreen;
@@ -761,6 +801,22 @@ export class WindowManager
761
801
  }
762
802
  }
763
803
 
804
+ public get boxStatus(): Record<string, TELE_BOX_STATE> | undefined {
805
+ if (this.appManager) {
806
+ return this.appManager.store.getBoxesStatus();
807
+ } else {
808
+ throw new Errors.AppManagerNotInitError();
809
+ }
810
+ }
811
+
812
+ public get lastNotMinimizedBoxStatus(): Record<string, NotMinimizedBoxState> | undefined {
813
+ if (this.appManager) {
814
+ return this.appManager.store.getLastNotMinimizedBoxesStatus();
815
+ } else {
816
+ throw new Errors.AppManagerNotInitError();
817
+ }
818
+ }
819
+
764
820
  public get darkMode(): boolean {
765
821
  return Boolean(this.appManager?.boxManager?.darkMode);
766
822
  }
package/src/shim.d.ts CHANGED
@@ -5,6 +5,10 @@ declare module "*.svelte" {
5
5
  export default app;
6
6
  }
7
7
 
8
+ declare module "@netless/telebox-insider" {
9
+ export * from "@netless/telebox-insider/dist/index.d.ts";
10
+ }
11
+
8
12
  declare global {
9
13
  const __APP_VERSION__: string;
10
14
  const __APP_DEPENDENCIES__: Record<string, string>;