@netless/window-manager 0.3.17 → 0.4.0-canary.10

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 (73) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +4 -43
  3. package/dist/App/Storage/StorageEvent.d.ts +8 -0
  4. package/dist/App/Storage/index.d.ts +26 -0
  5. package/dist/App/Storage/typings.d.ts +21 -0
  6. package/dist/App/Storage/utils.d.ts +5 -0
  7. package/dist/AppContext.d.ts +6 -3
  8. package/dist/AppListener.d.ts +2 -2
  9. package/dist/AppManager.d.ts +17 -14
  10. package/dist/AppProxy.d.ts +5 -3
  11. package/dist/AttributesDelegate.d.ts +19 -11
  12. package/dist/Base/Context.d.ts +0 -1
  13. package/dist/Base/index.d.ts +1 -2
  14. package/dist/BoxManager.d.ts +25 -8
  15. package/dist/BuiltinApps.d.ts +6 -0
  16. package/dist/ContainerResizeObserver.d.ts +10 -0
  17. package/dist/Cursor/Cursor.d.ts +2 -3
  18. package/dist/Cursor/index.d.ts +9 -5
  19. package/dist/Helper.d.ts +6 -0
  20. package/dist/ReconnectRefresher.d.ts +9 -3
  21. package/dist/Utils/Common.d.ts +3 -1
  22. package/dist/Utils/Reactive.d.ts +1 -1
  23. package/dist/Utils/RoomHacker.d.ts +2 -2
  24. package/dist/Utils/error.d.ts +3 -0
  25. package/dist/{MainView.d.ts → View/MainView.d.ts} +3 -4
  26. package/dist/View/ViewManager.d.ts +13 -0
  27. package/dist/constants.d.ts +3 -7
  28. package/dist/index.d.ts +24 -27
  29. package/dist/index.es.js +1 -1
  30. package/dist/index.es.js.map +1 -1
  31. package/dist/index.umd.js +1 -1
  32. package/dist/index.umd.js.map +1 -1
  33. package/dist/style.css +1 -1
  34. package/dist/typings.d.ts +1 -0
  35. package/docs/api.md +17 -0
  36. package/docs/migrate.md +42 -0
  37. package/package.json +6 -4
  38. package/src/App/Storage/StorageEvent.ts +21 -0
  39. package/src/App/Storage/index.ts +243 -0
  40. package/src/App/Storage/typings.ts +21 -0
  41. package/src/App/Storage/utils.ts +17 -0
  42. package/src/AppContext.ts +12 -4
  43. package/src/AppListener.ts +15 -11
  44. package/src/AppManager.ts +132 -95
  45. package/src/AppProxy.ts +49 -52
  46. package/src/AttributesDelegate.ts +76 -49
  47. package/src/Base/Context.ts +2 -6
  48. package/src/Base/index.ts +2 -2
  49. package/src/BoxManager.ts +95 -35
  50. package/src/BuiltinApps.ts +24 -0
  51. package/src/ContainerResizeObserver.ts +62 -0
  52. package/src/Cursor/Cursor.ts +35 -39
  53. package/src/Cursor/index.ts +79 -43
  54. package/src/Helper.ts +30 -0
  55. package/src/ReconnectRefresher.ts +25 -10
  56. package/src/Utils/Common.ts +35 -13
  57. package/src/Utils/Reactive.ts +9 -3
  58. package/src/Utils/RoomHacker.ts +20 -5
  59. package/src/Utils/error.ts +6 -1
  60. package/src/{MainView.ts → View/MainView.ts} +19 -27
  61. package/src/View/ViewManager.ts +53 -0
  62. package/src/constants.ts +2 -3
  63. package/src/index.ts +143 -171
  64. package/src/shim.d.ts +4 -0
  65. package/src/style.css +7 -1
  66. package/src/typings.ts +1 -0
  67. package/vite.config.js +4 -1
  68. package/dist/Utils/CameraStore.d.ts +0 -15
  69. package/dist/ViewManager.d.ts +0 -29
  70. package/dist/sdk.d.ts +0 -14
  71. package/src/Utils/CameraStore.ts +0 -72
  72. package/src/sdk.ts +0 -39
  73. package/src/viewManager.ts +0 -177
@@ -2,8 +2,7 @@ import { AppAttributes } from "./constants";
2
2
  import { get, pick } from "lodash";
3
3
  import { setViewFocusScenePath } from "./Utils/Common";
4
4
  import type { AddAppParams, AppSyncAttributes } from "./index";
5
- import type { Camera, Size } from "white-web-sdk";
6
- import type { AppManager } from "./AppManager";
5
+ import type { Camera, Size, View } from "white-web-sdk";
7
6
  import type { Cursor } from "./Cursor/Cursor";
8
7
 
9
8
  export enum Fields {
@@ -17,7 +16,7 @@ export enum Fields {
17
16
  Cursors = "cursors",
18
17
  Position = "position",
19
18
  CursorState = "cursorState",
20
- FullPath = "fullPath"
19
+ FullPath = "fullPath",
21
20
  }
22
21
 
23
22
  export type Apps = {
@@ -33,15 +32,29 @@ export type Position = {
33
32
 
34
33
  export type PositionType = "main" | "app";
35
34
 
35
+ export type StoreContext = {
36
+ getAttributes: () => any;
37
+ safeUpdateAttributes: (keys: string[], value: any) => void;
38
+ safeSetAttributes: (attributes: any) => void;
39
+ }
36
40
  export class AttributesDelegate {
37
- constructor(private manager: AppManager) {}
41
+
42
+ constructor(private context: StoreContext) {}
43
+
44
+ public setContext(context: StoreContext) {
45
+ this.context = context;
46
+ }
47
+
48
+ public get attributes() {
49
+ return this.context.getAttributes();
50
+ }
38
51
 
39
52
  public apps(): Apps {
40
- return get(this.manager.attributes, [Fields.Apps]);
53
+ return get(this.attributes, [Fields.Apps]);
41
54
  }
42
55
 
43
56
  public get focus(): string | undefined {
44
- return get(this.manager.attributes, [Fields.Focus]);
57
+ return get(this.attributes, [Fields.Focus]);
45
58
  }
46
59
 
47
60
  public getAppAttributes(id: string): AppSyncAttributes {
@@ -53,13 +66,17 @@ export class AttributesDelegate {
53
66
  }
54
67
 
55
68
  public getMaximized() {
56
- return get(this.manager.attributes, ["maximized"])
69
+ return get(this.attributes, ["maximized"]);
70
+ }
71
+
72
+ public getMinimized() {
73
+ return get(this.attributes, ["minimized"]);
57
74
  }
58
75
 
59
76
  public setupAppAttributes(params: AddAppParams, id: string, isDynamicPPT: boolean) {
60
- const attributes = this.manager.attributes;
77
+ const attributes = this.attributes;
61
78
  if (!attributes.apps) {
62
- this.manager.safeSetAttributes({ apps: {} });
79
+ this.context.safeSetAttributes({ apps: {} });
63
80
  }
64
81
  const attrNames = ["scenePath", "title"];
65
82
  if (!isDynamicPPT) {
@@ -70,32 +87,32 @@ export class AttributesDelegate {
70
87
  if (typeof params.src === "string") {
71
88
  attrs.src = params.src;
72
89
  }
73
- this.manager.safeUpdateAttributes([Fields.Apps, id], attrs);
74
- this.manager.safeUpdateAttributes([Fields.Apps, id, Fields.State], {
90
+ attrs.createdAt = Date.now();
91
+ this.context.safeUpdateAttributes([Fields.Apps, id], attrs);
92
+ this.context.safeUpdateAttributes([Fields.Apps, id, Fields.State], {
75
93
  [AppAttributes.Size]: {},
76
94
  [AppAttributes.Position]: {},
77
95
  [AppAttributes.SceneIndex]: 0,
78
- [AppAttributes.ZIndex]: 100,
79
96
  });
80
97
  }
81
98
 
82
99
  public updateAppState(appId: string, stateName: AppAttributes, state: any) {
83
- if (get(this.manager.attributes, [Fields.Apps, appId, Fields.State])) {
84
- this.manager.safeUpdateAttributes([Fields.Apps, appId, Fields.State, stateName], state);
100
+ if (get(this.attributes, [Fields.Apps, appId, Fields.State])) {
101
+ this.context.safeUpdateAttributes([Fields.Apps, appId, Fields.State, stateName], state);
85
102
  }
86
103
  }
87
104
 
88
105
  public cleanAppAttributes(id: string) {
89
- this.manager.safeUpdateAttributes([Fields.Apps, id], undefined);
90
- this.manager.safeSetAttributes({ [id]: undefined });
91
- const focus = this.manager.attributes[Fields.Focus];
106
+ this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
107
+ this.context.safeSetAttributes({ [id]: undefined });
108
+ const focus = this.attributes[Fields.Focus];
92
109
  if (focus === id) {
93
110
  this.cleanFocus();
94
111
  }
95
112
  }
96
113
 
97
114
  public cleanFocus() {
98
- this.manager.safeSetAttributes({ [Fields.Focus]: undefined });
115
+ this.context.safeSetAttributes({ [Fields.Focus]: undefined });
99
116
  }
100
117
 
101
118
  public getAppSceneIndex(id: string) {
@@ -107,82 +124,79 @@ export class AttributesDelegate {
107
124
  }
108
125
 
109
126
  public getMainViewScenePath() {
110
- return this.manager.attributes["_mainScenePath"];
127
+ return this.attributes["_mainScenePath"];
111
128
  }
112
129
 
113
130
  public getMainViewSceneIndex() {
114
- return this.manager.attributes["_mainSceneIndex"];
131
+ return this.attributes["_mainSceneIndex"];
115
132
  }
116
133
 
117
134
  public getBoxState() {
118
- return this.manager.attributes[Fields.BoxState];
135
+ return this.attributes[Fields.BoxState];
119
136
  }
120
137
 
121
138
  public setMainViewScenePath(scenePath: string) {
122
- this.manager.safeSetAttributes({ _mainScenePath: scenePath });
139
+ this.context.safeSetAttributes({ _mainScenePath: scenePath });
123
140
  }
124
141
 
125
142
  public setMainViewSceneIndex(index: number) {
126
- this.manager.safeSetAttributes({ _mainSceneIndex: index });
143
+ this.context.safeSetAttributes({ _mainSceneIndex: index });
127
144
  }
128
145
 
129
146
  public getMainViewCamera(): MainViewCamera {
130
- return get(this.manager.attributes, [Fields.MainViewCamera]);
147
+ return get(this.attributes, [Fields.MainViewCamera]);
131
148
  }
132
149
 
133
150
  public getMainViewSize(): MainViewSize {
134
- return get(this.manager.attributes, [Fields.MainViewSize]);
151
+ return get(this.attributes, [Fields.MainViewSize]);
135
152
  }
136
153
 
137
- public setMainViewCamera(camera: Camera & { id: string } | undefined) {
138
- this.manager.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });
154
+ public setMainViewCamera(camera: (Camera & { id: string }) | undefined) {
155
+ this.context.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });
139
156
  }
140
157
 
141
- public setMainViewSize(size: Size & { id: string } | undefined) {
142
- this.manager.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
158
+ public setMainViewSize(size: (Size & { id: string }) | undefined) {
159
+ this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
143
160
  }
144
161
 
145
162
  public setAppFocus(appId: string, focus: boolean) {
146
163
  if (focus) {
147
- this.manager.safeSetAttributes({ [Fields.Focus]: appId });
164
+ this.context.safeSetAttributes({ [Fields.Focus]: appId });
148
165
  } else {
149
- this.manager.safeSetAttributes({ [Fields.Focus]: undefined });
166
+ this.context.safeSetAttributes({ [Fields.Focus]: undefined });
150
167
  }
151
168
  }
152
169
 
153
170
  public updateCursor(uid: string, position: Position) {
154
- if (!get(this.manager.attributes, [Fields.Cursors])) {
155
- this.manager.safeUpdateAttributes([Fields.Cursors], {});
171
+ if (!get(this.attributes, [Fields.Cursors])) {
172
+ this.context.safeUpdateAttributes([Fields.Cursors], {});
156
173
  }
157
- if (!get(this.manager.attributes, [Fields.Cursors, uid])) {
158
- this.manager.safeUpdateAttributes([Fields.Cursors, uid], {});
174
+ if (!get(this.attributes, [Fields.Cursors, uid])) {
175
+ this.context.safeUpdateAttributes([Fields.Cursors, uid], {});
159
176
  }
160
- this.manager.safeUpdateAttributes([Fields.Cursors, uid, Fields.Position], position);
177
+ this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.Position], position);
161
178
  }
162
179
 
163
180
  public updateCursorState(uid: string, cursorState: string | undefined) {
164
- if (!get(this.manager.attributes, [Fields.Cursors, uid])) {
165
- this.manager.safeUpdateAttributes([Fields.Cursors, uid], {});
181
+ if (!get(this.attributes, [Fields.Cursors, uid])) {
182
+ this.context.safeUpdateAttributes([Fields.Cursors, uid], {});
166
183
  }
167
- this.manager.safeUpdateAttributes(
168
- [Fields.Cursors, uid, Fields.CursorState],
169
- cursorState
170
- );
184
+ this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.CursorState], cursorState);
171
185
  }
172
186
 
173
187
  public getCursorState(uid: string) {
174
- return get(this.manager.attributes, [Fields.Cursors, uid, Fields.CursorState]);
188
+ return get(this.attributes, [Fields.Cursors, uid, Fields.CursorState]);
175
189
  }
176
190
 
177
191
  public cleanCursor(uid: string) {
178
- this.manager.safeUpdateAttributes([Fields.Cursors, uid], undefined);
192
+ this.context.safeUpdateAttributes([Fields.Cursors, uid], undefined);
179
193
  }
180
194
 
181
195
  // TODO 状态中保存一个 SceneName 优化性能
182
- public setMainViewFocusPath() {
196
+ public setMainViewFocusPath(mainView: View) {
183
197
  const scenePath = this.getMainViewScenePath();
184
198
  if (scenePath) {
185
- setViewFocusScenePath(this.manager.mainView, scenePath);
199
+ setViewFocusScenePath(mainView, scenePath);
186
200
  }
187
201
  }
188
202
  }
@@ -191,15 +205,28 @@ export type MainViewSize = {
191
205
  id: string;
192
206
  width: number;
193
207
  height: number;
194
- }
208
+ };
195
209
 
196
210
  export type MainViewCamera = {
197
211
  id: string;
198
212
  centerX: number;
199
213
  centerY: number;
200
214
  scale: number;
201
- }
215
+ };
202
216
 
203
217
  export type Cursors = {
204
218
  [key: string]: Cursor;
205
- }
219
+ };
220
+
221
+
222
+ export const store = new AttributesDelegate({
223
+ getAttributes: () => {
224
+ throw new Error("getAttributes not implemented")
225
+ },
226
+ safeSetAttributes: () => {
227
+ throw new Error("safeSetAttributes not implemented")
228
+ },
229
+ safeUpdateAttributes: () => {
230
+ throw new Error("safeUpdateAttributes not implemented")
231
+ },
232
+ });
@@ -27,15 +27,11 @@ export class Context {
27
27
  }
28
28
 
29
29
  public updateManagerRect() {
30
- this.manager.boxManager.updateManagerRect();
30
+ this.manager.boxManager?.updateManagerRect();
31
31
  }
32
32
 
33
33
  public blurFocusBox() {
34
- this.manager.boxManager.blurAllBox();
35
- }
36
-
37
- public switchAppToWriter(id: string) {
38
- this.manager.viewManager.switchAppToWriter(id);
34
+ this.manager.boxManager?.blurAllBox();
39
35
  }
40
36
  }
41
37
 
package/src/Base/index.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { AppManager } from "../AppManager";
2
- import { AttributesDelegate } from "../AttributesDelegate";
2
+ import { store } from "../AttributesDelegate";
3
3
  import { createContext } from "./Context";
4
4
 
5
5
  export class Base {
6
- public store = new AttributesDelegate(this.manager);
6
+ public store = store;
7
7
  public context = createContext(this.manager);
8
8
 
9
9
  constructor(public manager: AppManager) {}
package/src/BoxManager.ts CHANGED
@@ -1,22 +1,22 @@
1
- import { callbacks, emitter, WindowManager } from "./index";
1
+ import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
2
2
  import { debounce, maxBy } from "lodash";
3
- import { AppAttributes, DEFAULT_COLLECTOR_STYLE, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
4
3
  import {
5
4
  TELE_BOX_MANAGER_EVENT,
6
5
  TELE_BOX_STATE,
7
6
  TeleBoxCollector,
8
7
  TeleBoxManager,
9
8
  } from "@netless/telebox-insider";
10
- import type { AddAppOptions, AppInitState } from "./index";
9
+ import { emitter, WindowManager } from "./index";
10
+ import type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from "./index";
11
11
  import type {
12
12
  TeleBoxManagerUpdateConfig,
13
13
  TeleBoxManagerCreateConfig,
14
14
  ReadonlyTeleBox,
15
15
  TeleBoxManagerConfig,
16
16
  TeleBoxColorScheme,
17
+ TeleBoxRect,
17
18
  } from "@netless/telebox-insider";
18
19
  import type Emittery from "emittery";
19
- import type { AppManager } from "./AppManager";
20
20
  import type { NetlessApp } from "./typings";
21
21
  import type { View } from "white-web-sdk";
22
22
 
@@ -48,31 +48,63 @@ export type CreateTeleBoxManagerConfig = {
48
48
  prefersColorScheme?: TeleBoxColorScheme;
49
49
  };
50
50
 
51
+ export type BoxManagerContext = {
52
+ safeSetAttributes: (attributes: any) => void;
53
+ getMainView: () => View;
54
+ updateAppState: (appId: string, field: AppAttributes, value: any) => void;
55
+ emitter: EmitterType;
56
+ callbacks: CallbacksType;
57
+ canOperate: () => boolean;
58
+ notifyContainerRectUpdate: (rect: TeleBoxRect) => void;
59
+ cleanFocus: () => void;
60
+ };
61
+
62
+ export const createBoxManager = (
63
+ manager: WindowManager,
64
+ callbacks: CallbacksType,
65
+ emitter: EmitterType,
66
+ options: CreateTeleBoxManagerConfig
67
+ ) => {
68
+ return new BoxManager(
69
+ {
70
+ safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
71
+ getMainView: () => manager.mainView,
72
+ updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
73
+ canOperate: () => manager.canOperate,
74
+ notifyContainerRectUpdate: (rect: TeleBoxRect) =>
75
+ manager.appManager?.notifyContainerRectUpdate(rect),
76
+ cleanFocus: () => manager.appManager?.store.cleanFocus(),
77
+ callbacks,
78
+ emitter,
79
+ },
80
+ options
81
+ );
82
+ };
83
+
51
84
  export class BoxManager {
52
85
  public teleBoxManager: TeleBoxManager;
53
- public appBoxMap: Map<string, string> = new Map();
54
- private mainView = this.manager.mainView;
55
86
 
56
87
  constructor(
57
- private manager: AppManager,
58
- createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
88
+ private context: BoxManagerContext,
89
+ private createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
59
90
  ) {
91
+ const { emitter, callbacks } = context;
60
92
  this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
61
93
  this.teleBoxManager.events.on(TELE_BOX_MANAGER_EVENT.State, state => {
62
94
  if (state) {
63
- callbacks.emit("boxStateChange", state);
64
- emitter.emit("boxStateChange", state);
95
+ this.context.callbacks.emit("boxStateChange", state);
96
+ this.context.emitter.emit("boxStateChange", state);
65
97
  }
66
98
  });
67
99
  this.teleBoxManager.events.on("minimized", minimized => {
68
- this.manager.safeSetAttributes({ minimized });
100
+ this.context.safeSetAttributes({ minimized });
69
101
  if (minimized) {
70
- this.manager.store.cleanFocus();
102
+ this.context.cleanFocus();
71
103
  this.blurAllBox();
72
104
  }
73
105
  });
74
106
  this.teleBoxManager.events.on("maximized", maximized => {
75
- this.manager.safeSetAttributes({ maximized });
107
+ this.context.safeSetAttributes({ maximized });
76
108
  });
77
109
  this.teleBoxManager.events.on("removed", boxes => {
78
110
  boxes.forEach(box => {
@@ -97,7 +129,7 @@ export class BoxManager {
97
129
  );
98
130
  this.teleBoxManager.events.on("focused", box => {
99
131
  if (box) {
100
- if (this.manager.canOperate) {
132
+ if (this.canOperate) {
101
133
  emitter.emit("focus", { appId: box.id });
102
134
  } else {
103
135
  this.teleBoxManager.blurBox(box.id);
@@ -111,8 +143,21 @@ export class BoxManager {
111
143
  callbacks.emit("prefersColorSchemeChange", colorScheme);
112
144
  });
113
145
  this.teleBoxManager.events.on("z_index", box => {
114
- this.manager.store.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
146
+ this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
115
147
  });
148
+ emitter.on("playgroundSizeChange", this.playgroundSizeChangeListener);
149
+ }
150
+
151
+ private playgroundSizeChangeListener = () => {
152
+ this.updateManagerRect();
153
+ }
154
+
155
+ private get mainView() {
156
+ return this.context.getMainView();
157
+ }
158
+
159
+ private get canOperate() {
160
+ return this.context.canOperate();
116
161
  }
117
162
 
118
163
  public get boxState() {
@@ -135,6 +180,10 @@ export class BoxManager {
135
180
  return this.teleBoxManager.prefersColorScheme;
136
181
  }
137
182
 
183
+ public get boxSize() {
184
+ return this.teleBoxManager.boxes.length;
185
+ }
186
+
138
187
  public createBox(params: CreateBoxParams): void {
139
188
  if (!this.teleBoxManager) return;
140
189
  let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
@@ -159,14 +208,14 @@ export class BoxManager {
159
208
  id: params.appId,
160
209
  };
161
210
  this.teleBoxManager.create(createBoxConfig, params.smartPosition);
162
- emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
211
+ this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
163
212
  }
164
213
 
165
214
  public setBoxInitState(appId: string): void {
166
215
  const box = this.teleBoxManager.queryOne({ id: appId });
167
216
  if (box) {
168
217
  if (box.state === TELE_BOX_STATE.Maximized) {
169
- emitter.emit("resize", {
218
+ this.context.emitter.emit("resize", {
170
219
  appId: appId,
171
220
  x: box.x,
172
221
  y: box.y,
@@ -193,24 +242,26 @@ export class BoxManager {
193
242
  fence: false,
194
243
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
195
244
  };
196
- const container = createTeleBoxManagerConfig?.collectorContainer || WindowManager.wrapper;
197
- const styles = {
198
- ...DEFAULT_COLLECTOR_STYLE,
199
- ...createTeleBoxManagerConfig?.collectorStyles,
200
- };
201
- const teleBoxCollector = new TeleBoxCollector({
202
- styles: styles,
203
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
204
- }).mount(container!);
205
- initManagerState.collector = teleBoxCollector;
245
+
206
246
  const manager = new TeleBoxManager(initManagerState);
207
247
  if (this.teleBoxManager) {
208
248
  this.teleBoxManager.destroy();
209
249
  }
210
250
  this.teleBoxManager = manager;
251
+ const container = createTeleBoxManagerConfig?.collectorContainer || WindowManager.wrapper;
252
+ if (container) {
253
+ this.setCollectorContainer(container);
254
+ }
211
255
  return manager;
212
256
  }
213
257
 
258
+ public setCollectorContainer(container: HTMLElement) {
259
+ const collector = new TeleBoxCollector({
260
+ styles: this.createTeleBoxManagerConfig?.collectorStyles,
261
+ }).mount(container);
262
+ this.teleBoxManager.setCollector(collector);
263
+ }
264
+
214
265
  public getBox(appId: string): ReadonlyTeleBox | undefined {
215
266
  return this.teleBoxManager.queryOne({ id: appId });
216
267
  }
@@ -249,16 +300,18 @@ export class BoxManager {
249
300
  },
250
301
  true
251
302
  );
252
- if (state.maximized != null) {
253
- this.teleBoxManager.setMaximized(Boolean(state.maximized), true);
254
- this.teleBoxManager.setMinimized(Boolean(state.minimized), true);
255
- }
256
303
  setTimeout(() => {
257
304
  if (state.focus) {
258
- this.teleBoxManager.focusBox(box.id, true)
305
+ this.teleBoxManager.focusBox(box.id, true);
306
+ }
307
+ if (state.maximized != null) {
308
+ this.teleBoxManager.setMaximized(Boolean(state.maximized), true);
309
+ }
310
+ if (state.minimized != null) {
311
+ this.teleBoxManager.setMinimized(Boolean(state.minimized), true);
259
312
  }
260
313
  }, 50);
261
- callbacks.emit("boxStateChange", this.teleBoxManager.state);
314
+ this.context.callbacks.emit("boxStateChange", this.teleBoxManager.state);
262
315
  }
263
316
  }
264
317
 
@@ -267,7 +320,7 @@ export class BoxManager {
267
320
  if (rect && rect.width > 0 && rect.height > 0) {
268
321
  const containerRect = { x: 0, y: 0, width: rect.width, height: rect.height };
269
322
  this.teleBoxManager.setContainerRect(containerRect);
270
- this.manager.notifyContainerRectUpdate(this.teleBoxManager.containerRect);
323
+ this.context.notifyContainerRectUpdate(this.teleBoxManager.containerRect);
271
324
  }
272
325
  }
273
326
 
@@ -307,7 +360,9 @@ export class BoxManager {
307
360
  }
308
361
 
309
362
  public setMaximized(maximized: boolean) {
310
- this.teleBoxManager.setMaximized(maximized, true);
363
+ if (maximized !== this.maximized) {
364
+ this.teleBoxManager.setMaximized(maximized, true);
365
+ }
311
366
  }
312
367
 
313
368
  public setMinimized(minimized: boolean, skipUpdate = true) {
@@ -332,7 +387,12 @@ export class BoxManager {
332
387
  this.teleBoxManager.setPrefersColorScheme(colorScheme);
333
388
  }
334
389
 
390
+ public setZIndex(id: string, zIndex: number, skipUpdate = true) {
391
+ this.teleBoxManager.update(id, { zIndex }, skipUpdate);
392
+ }
393
+
335
394
  public destroy() {
395
+ emitter.off("playgroundSizeChange", this.playgroundSizeChangeListener);
336
396
  this.teleBoxManager.destroy();
337
397
  }
338
398
  }
@@ -0,0 +1,24 @@
1
+ import AppDocsViewer from "@netless/app-docs-viewer";
2
+ import AppMediaPlayer, { setOptions } from "@netless/app-media-player";
3
+ import { WindowManager } from "./index";
4
+ import "@netless/app-docs-viewer/dist/style.css";
5
+
6
+ export const setupBuiltin = () => {
7
+ if (WindowManager.debug) {
8
+ setOptions({ verbose: true });
9
+ }
10
+
11
+ WindowManager.register({
12
+ kind: AppDocsViewer.kind,
13
+ src: AppDocsViewer,
14
+ });
15
+ WindowManager.register({
16
+ kind: AppMediaPlayer.kind,
17
+ src: AppMediaPlayer,
18
+ });
19
+ };
20
+
21
+ export const BuiltinApps = {
22
+ DocsViewer: AppDocsViewer.kind as string,
23
+ MediaPlayer: AppMediaPlayer.kind as string,
24
+ };
@@ -0,0 +1,62 @@
1
+ import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
2
+ import { WindowManager } from "./index";
3
+ import type { EmitterType} from "./index";
4
+
5
+ const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
6
+
7
+ export class ContainerResizeObserver {
8
+ private containerResizeObserver?: ResizeObserver;
9
+
10
+ constructor(private emitter: EmitterType) {}
11
+
12
+ public static create(
13
+ container: HTMLElement,
14
+ sizer: HTMLElement,
15
+ wrapper: HTMLDivElement,
16
+ emitter: EmitterType,
17
+ ) {
18
+ const containerResizeObserver = new ContainerResizeObserver(emitter);
19
+ containerResizeObserver.observePlaygroundSize(container, sizer, wrapper);
20
+ return containerResizeObserver;
21
+ }
22
+
23
+ public observePlaygroundSize(
24
+ container: HTMLElement,
25
+ sizer: HTMLElement,
26
+ wrapper: HTMLDivElement
27
+ ) {
28
+ this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
29
+
30
+ this.containerResizeObserver = new ResizeObserver(entries => {
31
+ const containerRect = entries[0]?.contentRect;
32
+ if (containerRect) {
33
+ this.updateSizer(containerRect, sizer, wrapper);
34
+ this.emitter.emit("playgroundSizeChange", containerRect)
35
+ }
36
+ });
37
+
38
+ this.containerResizeObserver.observe(container);
39
+ }
40
+
41
+ private updateSizer(
42
+ { width, height }: DOMRectReadOnly,
43
+ sizer: HTMLElement,
44
+ wrapper: HTMLDivElement
45
+ ) {
46
+ if (width && height) {
47
+ if (height / width > WindowManager.containerSizeRatio) {
48
+ height = width * WindowManager.containerSizeRatio;
49
+ sizer.classList.toggle("netless-window-manager-sizer-horizontal", true);
50
+ } else {
51
+ width = height / WindowManager.containerSizeRatio;
52
+ sizer.classList.toggle("netless-window-manager-sizer-horizontal", false);
53
+ }
54
+ wrapper.style.width = `${width}px`;
55
+ wrapper.style.height = `${height}px`;
56
+ }
57
+ }
58
+
59
+ public disconnect() {
60
+ this.containerResizeObserver?.disconnect();
61
+ }
62
+ }