@netless/window-manager 1.0.7-beta.0 → 1.0.7-beta.2

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),
@@ -161,15 +179,40 @@ export class BoxManager {
161
179
  this.teleBoxManager.events.on("focused", box => {
162
180
  if (box) {
163
181
  if (this.canOperate) {
182
+ console.log("focused===>focused", box.id, box.zIndex)
164
183
  boxEmitter.emit("focus", { appId: box.id });
165
184
  } else {
166
185
  this.teleBoxManager.blurBox(box.id);
167
186
  }
168
187
  }
169
188
  });
189
+ this.teleBoxManager.events.on("blurred", box => {
190
+ if (box) {
191
+ if (this.canOperate) {
192
+ console.log("focused===>blurred", box.id, box.zIndex)
193
+ boxEmitter.emit("blurred", { appId: box.id });
194
+ }
195
+ }
196
+ });
170
197
  this.teleBoxManager.events.on("z_index", box => {
171
198
  this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
172
199
  });
200
+ this.teleBoxManager.events.on(
201
+ "box_status",
202
+ (box: { id: string; boxStatus?: TeleBoxState }) => {
203
+ if (this.canOperate) {
204
+ this.context.setBoxStatus(box.id, box.boxStatus);
205
+ }
206
+ }
207
+ );
208
+ this.teleBoxManager.events.on(
209
+ "last_not_minimized_box_status",
210
+ (box: { id: string; boxStatus?: NotMinimizedBoxState }) => {
211
+ if (this.canOperate) {
212
+ this.context.setLastNotMinimizedBoxStatus(box.id, box.boxStatus);
213
+ }
214
+ }
215
+ );
173
216
  emitter.on("playgroundSizeChange", () => this.updateManagerRect());
174
217
  emitter.on("updateManagerRect", () => this.updateManagerRect());
175
218
  }
@@ -228,7 +271,9 @@ export class BoxManager {
228
271
  width,
229
272
  height,
230
273
  id: params.appId,
274
+ boxStatus: params.boxStatus,
231
275
  };
276
+ console.log("createBox===>", createBoxConfig.id, params.boxStatus)
232
277
  this.teleBoxManager.create(createBoxConfig, params.smartPosition);
233
278
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
234
279
  }
@@ -247,6 +292,21 @@ export class BoxManager {
247
292
  }
248
293
  }
249
294
  }
295
+ public setBoxesStatus(status?: Record<string, TeleBoxState>): void {
296
+ this.teleBoxManager.setBoxesStatus(new Map(Object.entries(status ?? {})), true);
297
+ }
298
+
299
+ public setBoxStatus(appId: string, status?: TeleBoxState): void {
300
+ this.teleBoxManager.update(appId, { boxStatus: status }, true);
301
+ }
302
+
303
+ public setLastNotMinimizedBoxesStatus(status?: Record<string, NotMinimizedBoxState>): void {
304
+ this.teleBoxManager.setLastNotMinimizedBoxesStatus(new Map(Object.entries(status ?? {})), true);
305
+ }
306
+
307
+ public setLastNotMinimizedBoxStatus(appId: string, status?: NotMinimizedBoxState): void {
308
+ this.teleBoxManager.update(appId, { lastNotMinimizedBoxStatus: status }, true);
309
+ }
250
310
 
251
311
  public setupBoxManager(
252
312
  createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
@@ -263,6 +323,7 @@ export class BoxManager {
263
323
  },
264
324
  fence: false,
265
325
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
326
+ useBoxesStatus: createTeleBoxManagerConfig?.useBoxesStatus || false,
266
327
  };
267
328
 
268
329
  const manager = new TeleBoxManager(initManagerState);
@@ -318,6 +379,8 @@ export class BoxManager {
318
379
  width: state.width || 0.5,
319
380
  height: state.height || 0.5,
320
381
  zIndex: state.zIndex,
382
+ boxStatus: state.boxStatus,
383
+ lastNotMinimizedBoxStatus: state.lastNotMinimizedBoxStatus,
321
384
  },
322
385
  true
323
386
  );
@@ -0,0 +1,39 @@
1
+ import { 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 type ExtendClassAble =
8
+ | typeof AppManager
9
+ | typeof BoxManager
10
+ | typeof AttributesDelegate
11
+ | typeof CursorManager
12
+ | typeof AppProxy;
13
+
14
+ export type ExtendClass = {
15
+ AppManager?: typeof AppManager;
16
+ BoxManager?: typeof BoxManager;
17
+ AttributesDelegate?: typeof AttributesDelegate;
18
+ CursorManager?: typeof CursorManager;
19
+ AppProxy?: typeof AppProxy;
20
+ };
21
+ export function getExtendClass<T extends ExtendClassAble>(
22
+ baseClass: T,
23
+ extendClass?: ExtendClass
24
+ ): T {
25
+ switch (baseClass.constructor.name) {
26
+ case "AppManager":
27
+ return (extendClass?.AppManager || AppManager) as T;
28
+ case "BoxManager":
29
+ return (extendClass?.BoxManager || BoxManager) as T;
30
+ case "AttributesDelegate":
31
+ return (extendClass?.AttributesDelegate || AttributesDelegate) as T;
32
+ case "CursorManager":
33
+ return (extendClass?.CursorManager || CursorManager) as T;
34
+ case "AppProxy":
35
+ return (extendClass?.AppProxy || AppProxy) as T;
36
+ default:
37
+ return baseClass;
38
+ }
39
+ }
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,6 +63,7 @@ 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";
66
+ import { ExtendClass, getExtendClass } from "./Utils/extendClass";
62
67
  export * from "./View/IframeBridge";
63
68
 
64
69
  export type WindowMangerAttributes = {
@@ -122,8 +127,13 @@ export type AppInitState = {
122
127
  maximized?: boolean;
123
128
  minimized?: boolean;
124
129
  sceneIndex?: number;
130
+ /** 所有box的基本状态 */
125
131
  boxState?: TeleBoxState; // 兼容旧版 telebox
126
132
  zIndex?: number;
133
+ /** 扩展版本,单个box的状态 */
134
+ boxStatus?: TeleBoxState;
135
+ /** 上次非最小化窗口状态 */
136
+ lastNotMinimizedBoxStatus?: NotMinimizedBoxState;
127
137
  };
128
138
 
129
139
  export type CursorMovePayload = { uid: string; state?: "leave"; position: Position };
@@ -156,10 +166,11 @@ export type MountParams = {
156
166
  fullscreen?: boolean;
157
167
  polling?: boolean;
158
168
  supportAppliancePlugin?: boolean;
169
+ /** 是否使用 boxesStatus 状态 */
170
+ useBoxesStatus?: boolean;
159
171
  };
160
172
 
161
173
  export const reconnectRefresher = new ReconnectRefresher({ emitter: internalEmitter });
162
-
163
174
  export class WindowManager
164
175
  extends InvisiblePlugin<WindowMangerAttributes, any>
165
176
  implements PageController
@@ -194,6 +205,7 @@ export class WindowManager
194
205
 
195
206
  private boxManager?: BoxManager;
196
207
  private static params?: MountParams;
208
+ static extendClass?: ExtendClass;
197
209
 
198
210
  private containerResizeObserver?: ContainerResizeObserver;
199
211
  public containerSizeRatio = WindowManager.containerSizeRatio;
@@ -210,7 +222,10 @@ export class WindowManager
210
222
  WindowManager._resolve(manager);
211
223
  }
212
224
 
213
- public static async mount(params: MountParams): Promise<WindowManager> {
225
+ public static async mount(
226
+ params: MountParams,
227
+ extendClass?: ExtendClass
228
+ ): Promise<WindowManager> {
214
229
  const room = params.room;
215
230
  WindowManager.container = params.container;
216
231
  WindowManager.supportAppliancePlugin = params.supportAppliancePlugin;
@@ -219,6 +234,7 @@ export class WindowManager
219
234
 
220
235
  const cursor = params.cursor;
221
236
  WindowManager.params = params;
237
+ WindowManager.extendClass = extendClass;
222
238
  WindowManager.displayer = params.room;
223
239
  checkVersion();
224
240
  let manager: WindowManager | undefined = undefined;
@@ -269,11 +285,14 @@ export class WindowManager
269
285
  }
270
286
  await manager.ensureAttributes();
271
287
 
288
+ const AppManagerClass = getExtendClass(AppManager, WindowManager.extendClass);
289
+ const CursorManagerClass = getExtendClass(CursorManager, WindowManager.extendClass);
290
+
272
291
  manager._fullscreen = params.fullscreen;
273
- manager.appManager = new AppManager(manager);
292
+ manager.appManager = new AppManagerClass(manager);
274
293
  manager.appManager.polling = params.polling || false;
275
294
  manager._pageState = new PageStateImpl(manager.appManager);
276
- manager.cursorManager = new CursorManager(
295
+ manager.cursorManager = new CursorManagerClass(
277
296
  manager.appManager,
278
297
  Boolean(cursor),
279
298
  params.cursorOptions,
@@ -369,9 +388,14 @@ export class WindowManager
369
388
  collectorContainer: params.collectorContainer,
370
389
  collectorStyles: params.collectorStyles,
371
390
  prefersColorScheme: params.prefersColorScheme,
391
+ useBoxesStatus: params.useBoxesStatus,
372
392
  });
373
393
  this.boxManager = boxManager;
374
- this.appManager?.setBoxManager(boxManager);
394
+ if (this.appManager) {
395
+ this.appManager.useBoxesStatus = params.useBoxesStatus || false;
396
+ this.appManager.setBoxManager(boxManager);
397
+
398
+ }
375
399
  this.bindMainView(mainViewElement, params.disableCameraTransform);
376
400
  if (WindowManager.wrapper) {
377
401
  this.cursorManager?.setupWrapper(WindowManager.wrapper);
@@ -696,6 +720,21 @@ export class WindowManager
696
720
  this.boxManager?.setMinimized(minimized, false);
697
721
  }
698
722
 
723
+ /** 设置指定 box 的状态, 如果为 undefined, 则移除状态*/
724
+ public setBoxStatus(boxId: string, boxStatus?: TELE_BOX_STATE): void {
725
+ if (!this.canOperate) return;
726
+ this.boxManager?.setBoxStatus(boxId, boxStatus);
727
+ }
728
+
729
+ /** 设置指定 box 的非最小化状态, 如果为 undefined, 则移除状态 */
730
+ public setLastNotMinimizedBoxStatus(
731
+ boxId: string,
732
+ lastNotMinimizedBoxStatus?: NotMinimizedBoxState
733
+ ): void {
734
+ if (!this.canOperate) return;
735
+ this.boxManager?.setLastNotMinimizedBoxStatus(boxId, lastNotMinimizedBoxStatus);
736
+ }
737
+
699
738
  public setFullscreen(fullscreen: boolean): void {
700
739
  if (this._fullscreen !== fullscreen) {
701
740
  this._fullscreen = fullscreen;
@@ -761,6 +800,22 @@ export class WindowManager
761
800
  }
762
801
  }
763
802
 
803
+ public get boxStatus(): Record<string, TELE_BOX_STATE> | undefined {
804
+ if (this.appManager) {
805
+ return this.appManager.store.getBoxesStatus();
806
+ } else {
807
+ throw new Errors.AppManagerNotInitError();
808
+ }
809
+ }
810
+
811
+ public get lastNotMinimizedBoxStatus(): Record<string, NotMinimizedBoxState> | undefined {
812
+ if (this.appManager) {
813
+ return this.appManager.store.getLastNotMinimizedBoxesStatus();
814
+ } else {
815
+ throw new Errors.AppManagerNotInitError();
816
+ }
817
+ }
818
+
764
819
  public get darkMode(): boolean {
765
820
  return Boolean(this.appManager?.boxManager?.darkMode);
766
821
  }
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>;