@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
package/src/AppManager.ts CHANGED
@@ -1,66 +1,55 @@
1
1
  import pRetry from "p-retry";
2
- import {
3
- AppAttributes,
4
- AppStatus,
5
- Events,
6
- MagixEventName
7
- } from "./constants";
2
+ import { AppAttributes, AppStatus, Events, MagixEventName } from "./constants";
8
3
  import { AppListeners } from "./AppListener";
9
4
  import { AppProxy } from "./AppProxy";
10
- import { AttributesDelegate } from "./AttributesDelegate";
11
- import {
12
- autorun,
13
- isPlayer,
14
- isRoom,
15
- ScenePathType,
16
- ViewVisionMode
17
- } from "white-web-sdk";
18
- import { BoxManager } from "./BoxManager";
19
- import { callbacks, emitter } from "./index";
20
- import { CameraStore } from "./Utils/CameraStore";
21
- import { genAppId, makeValidScenePath, setScenePath } from "./Utils/Common";
5
+ import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
6
+ import { callbacks, emitter, WindowManager, reconnectRefresher } from "./index";
7
+ import { genAppId, makeValidScenePath, setScenePath, setViewFocusScenePath } from "./Utils/Common";
22
8
  import { log } from "./Utils/log";
23
- import { MainViewProxy } from "./MainView";
9
+ import { MainViewProxy } from "./View/MainView";
24
10
  import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
25
- import { ReconnectRefresher } from "./ReconnectRefresher";
26
- import { ViewManager } from "./ViewManager";
11
+ import { get, sortBy } from "lodash";
12
+ import { store } from "./AttributesDelegate";
13
+ import { ViewManager } from "./View/ViewManager";
14
+ import type { ReconnectRefresher } from "./ReconnectRefresher";
15
+ import type { BoxManager } from "./BoxManager";
27
16
  import type { Displayer, DisplayerState, Room } from "white-web-sdk";
28
- import type { CreateTeleBoxManagerConfig } from "./BoxManager";
29
- import type {
30
- AddAppParams,
31
- BaseInsertParams,
32
- WindowManager,
33
- TeleBoxRect,
34
- EmitterEvent,
35
- } from "./index";
17
+ import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "./index";
18
+
36
19
  export class AppManager {
37
20
  public displayer: Displayer;
38
- public boxManager: BoxManager;
39
- public cameraStore: CameraStore;
40
21
  public viewManager: ViewManager;
41
22
  public appProxies: Map<string, AppProxy> = new Map();
42
23
  public appStatus: Map<string, AppStatus> = new Map();
43
- public store = new AttributesDelegate(this);
24
+ public store = store;
44
25
  public mainViewProxy: MainViewProxy;
45
26
  public refresher?: ReconnectRefresher;
46
27
  public isReplay = this.windowManger.isReplay;
47
28
 
48
29
  private appListeners: AppListeners;
30
+ public boxManager?: BoxManager;
31
+
32
+ private _prevSceneIndex: number | undefined;
49
33
 
50
- constructor(public windowManger: WindowManager, options: CreateTeleBoxManagerConfig) {
34
+ constructor(public windowManger: WindowManager) {
51
35
  this.displayer = windowManger.displayer;
52
- this.cameraStore = new CameraStore();
36
+ this.store.setContext({
37
+ getAttributes: () => this.attributes,
38
+ safeSetAttributes: attributes => this.safeSetAttributes(attributes),
39
+ safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),
40
+ });
53
41
  this.mainViewProxy = new MainViewProxy(this);
54
- this.viewManager = new ViewManager(this);
55
- this.boxManager = new BoxManager(this, options);
42
+ this.viewManager = new ViewManager(this.displayer);
56
43
  this.appListeners = new AppListeners(this);
57
44
  this.displayer.callbacks.on(this.eventName, this.displayerStateListener);
58
45
  this.appListeners.addListeners();
59
46
 
60
- this.refresher = new ReconnectRefresher(this.room, this);
47
+ this.refresher = reconnectRefresher;
48
+ this.refresher.setRoom(this.room);
49
+ this.refresher.setContext({ emitter });
61
50
 
62
51
  emitter.once("onCreated").then(() => this.onCreated());
63
-
52
+ emitter.on("onReconnected", () => this.onReconnected());
64
53
  if (isPlayer(this.displayer)) {
65
54
  emitter.on("seek", time => {
66
55
  this.appProxies.forEach(appProxy => {
@@ -74,12 +63,15 @@ export class AppManager {
74
63
 
75
64
  private async onCreated() {
76
65
  await this.attributesUpdateCallback(this.attributes.apps);
77
- this.boxManager.updateManagerRect();
66
+ this.boxManager?.updateManagerRect();
78
67
  emitter.onAny(this.boxEventListener);
79
68
  this.refresher?.add("apps", () => {
80
- return safeListenPropsUpdated(() => this.attributes.apps, () => {
81
- this.attributesUpdateCallback(this.attributes.apps);
82
- });
69
+ return safeListenPropsUpdated(
70
+ () => this.attributes.apps,
71
+ () => {
72
+ this.attributesUpdateCallback(this.attributes.apps);
73
+ }
74
+ );
83
75
  });
84
76
  this.refresher?.add("appsClose", () => {
85
77
  return onObjectRemoved(this.attributes.apps, () => {
@@ -89,19 +81,28 @@ export class AppManager {
89
81
  this.refresher?.add("maximized", () => {
90
82
  return autorun(() => {
91
83
  const maximized = this.attributes.maximized;
92
- if (this.boxManager.maximized !== maximized) {
93
- this.boxManager.setMaximized(Boolean(maximized));
94
- }
84
+ this.boxManager?.setMaximized(Boolean(maximized));
95
85
  });
96
86
  });
97
87
  this.refresher?.add("minimized", () => {
98
88
  return autorun(() => {
99
89
  const minimized = this.attributes.minimized;
100
- if (this.boxManager.minimized !== minimized) {
90
+ if (this.boxManager?.minimized !== minimized) {
101
91
  if (minimized === true) {
102
- this.boxManager.blurAllBox();
92
+ this.boxManager?.blurAllBox();
103
93
  }
104
- this.boxManager.setMinimized(Boolean(minimized));
94
+ setTimeout(() => {
95
+ this.boxManager?.setMinimized(Boolean(minimized));
96
+ }, 0);
97
+ }
98
+ });
99
+ });
100
+ this.refresher?.add("mainViewIndex", () => {
101
+ return autorun(() => {
102
+ const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
103
+ if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {
104
+ callbacks.emit("mainViewSceneIndexChange", mainSceneIndex);
105
+ this._prevSceneIndex = mainSceneIndex;
105
106
  }
106
107
  });
107
108
  });
@@ -124,29 +125,39 @@ export class AppManager {
124
125
  * @memberof WindowManager
125
126
  */
126
127
  public async attributesUpdateCallback(apps: any) {
127
- if (apps) {
128
- for (const id in apps) {
128
+ if (apps && WindowManager.container) {
129
+ const appIds = Object.keys(apps);
130
+ const appsWithCreatedAt = appIds.map(appId => {
131
+ return {
132
+ id: appId,
133
+ createdAt: apps[appId].createdAt,
134
+ };
135
+ });
136
+ for (const { id } of sortBy(appsWithCreatedAt, "createdAt")) {
129
137
  if (!this.appProxies.has(id) && !this.appStatus.has(id)) {
130
138
  const app = apps[id];
131
139
 
132
- pRetry(async () => {
133
- this.appStatus.set(id, AppStatus.StartCreate);
134
- // 防御 appAttributes 有可能为 undefined 的情况,这里做一个重试
135
- const appAttributes = this.attributes[id];
136
- if (!appAttributes) {
137
- throw new Error("appAttributes is undefined");
138
- }
139
- await this.baseInsertApp(
140
- {
141
- kind: app.kind,
142
- options: app.options,
143
- isDynamicPPT: app.isDynamicPPT,
144
- },
145
- id,
146
- false
147
- );
148
- this.focusByAttributes(apps);
149
- }, { retries: 3 }).catch(err => {
140
+ pRetry(
141
+ async () => {
142
+ this.appStatus.set(id, AppStatus.StartCreate);
143
+ // 防御 appAttributes 有可能为 undefined 的情况,这里做一个重试
144
+ const appAttributes = this.attributes[id];
145
+ if (!appAttributes) {
146
+ throw new Error("appAttributes is undefined");
147
+ }
148
+ await this.baseInsertApp(
149
+ {
150
+ kind: app.kind,
151
+ options: app.options,
152
+ isDynamicPPT: app.isDynamicPPT,
153
+ },
154
+ id,
155
+ false
156
+ );
157
+ this.focusByAttributes(apps);
158
+ },
159
+ { retries: 3 }
160
+ ).catch(err => {
150
161
  console.warn(`[WindowManager]: Insert App Error`, err);
151
162
  this.appStatus.delete(id);
152
163
  });
@@ -155,6 +166,22 @@ export class AppManager {
155
166
  }
156
167
  }
157
168
 
169
+ public refresh() {
170
+ this.attributesUpdateCallback(this.attributes.apps);
171
+ }
172
+
173
+ public setBoxManager(boxManager: BoxManager) {
174
+ this.boxManager = boxManager;
175
+ }
176
+
177
+ public resetMaximized() {
178
+ this.boxManager?.setMaximized(Boolean(this.store.getMaximized()));
179
+ }
180
+
181
+ public resetMinimized() {
182
+ this.boxManager?.setMinimized(Boolean(this.store.getMinimized()));
183
+ }
184
+
158
185
  private onAppDelete = (apps: any) => {
159
186
  const ids = Object.keys(apps);
160
187
  this.appProxies.forEach((appProxy, id) => {
@@ -169,15 +196,18 @@ export class AppManager {
169
196
  mainView.disableCameraTransform = disableCameraTransform;
170
197
  mainView.divElement = divElement;
171
198
  if (!mainView.focusScenePath) {
172
- this.store.setMainViewFocusPath();
199
+ this.setMainViewFocusPath();
173
200
  }
174
- if (this.store.focus === undefined && mainView.mode !== ViewVisionMode.Writable) {
175
- this.viewManager.switchMainViewToWriter();
176
- }
177
- this.mainViewProxy.addMainViewListener();
178
201
  emitter.emit("mainViewMounted");
179
202
  }
180
203
 
204
+ public setMainViewFocusPath() {
205
+ const scenePath = this.store.getMainViewScenePath();
206
+ if (scenePath) {
207
+ setViewFocusScenePath(this.mainView, scenePath);
208
+ }
209
+ }
210
+
181
211
  public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {
182
212
  log("addApp", params);
183
213
  const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);
@@ -192,7 +222,7 @@ export class AppManager {
192
222
  const attrs = params.attributes ?? {};
193
223
  this.safeUpdateAttributes([appId], attrs);
194
224
  this.store.setupAppAttributes(params, appId, isDynamicPPT);
195
- const needFocus = !this.boxManager.minimized;
225
+ const needFocus = !this.boxManager?.minimized;
196
226
  if (needFocus) {
197
227
  this.store.setAppFocus(appId, true);
198
228
  }
@@ -209,8 +239,8 @@ export class AppManager {
209
239
  });
210
240
  this.store.updateAppState(appProxy.id, AppAttributes.ZIndex, box.zIndex);
211
241
  }
212
- if (this.boxManager.minimized) {
213
- this.boxManager.setMinimized(false, false);
242
+ if (this.boxManager?.minimized) {
243
+ this.boxManager?.setMinimized(false, false);
214
244
  }
215
245
  }
216
246
 
@@ -263,22 +293,19 @@ export class AppManager {
263
293
  emitter.emit("observerIdChange", this.displayer.observerId);
264
294
  };
265
295
 
266
- private displayerWritableListener = (isReadonly: boolean) => {
296
+ public displayerWritableListener = (isReadonly: boolean) => {
267
297
  const isWritable = !isReadonly;
268
298
  const isManualWritable =
269
299
  this.windowManger.readonly === undefined || this.windowManger.readonly === false;
270
300
  if (this.windowManger.readonly === undefined) {
271
- this.boxManager.setReadonly(isReadonly);
301
+ this.boxManager?.setReadonly(isReadonly);
272
302
  } else {
273
- this.boxManager.setReadonly(!(isWritable && isManualWritable));
303
+ this.boxManager?.setReadonly(!(isWritable && isManualWritable));
274
304
  }
275
305
  this.appProxies.forEach(appProxy => {
276
306
  appProxy.emitAppIsWritableChange();
277
307
  });
278
308
  if (isWritable === true) {
279
- if (!this.store.focus) {
280
- this.mainViewProxy.switchViewModeToWriter();
281
- }
282
309
  this.mainView.disableCameraTransform = false;
283
310
  } else {
284
311
  this.mainView.disableCameraTransform = true;
@@ -328,28 +355,37 @@ export class AppManager {
328
355
  await this._setMainViewScenePath(scenePath);
329
356
  } else if (scenePathType === ScenePathType.Dir) {
330
357
  const validScenePath = makeValidScenePath(this.displayer, scenePath);
331
- await this._setMainViewScenePath(validScenePath);
358
+ if (validScenePath) {
359
+ await this._setMainViewScenePath(validScenePath);
360
+ }
332
361
  }
333
362
  }
334
363
  }
335
364
 
336
365
  private async _setMainViewScenePath(scenePath: string) {
337
366
  this.safeSetAttributes({ _mainScenePath: scenePath });
338
- await this.viewManager.switchMainViewToWriter();
339
- setScenePath(this.room, scenePath);
340
- this.store.setMainViewFocusPath();
367
+ this.setMainViewFocusPath();
368
+ this.store.setMainViewFocusPath(this.mainView);
341
369
  this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
342
370
  }
343
371
 
344
372
  public async setMainViewSceneIndex(index: number) {
345
373
  if (this.room) {
346
374
  this.safeSetAttributes({ _mainSceneIndex: index });
347
- await this.viewManager.switchMainViewToWriter();
348
- this.room.setSceneIndex(index);
349
- const nextScenePath = this.room.state.sceneState.scenePath;
350
- this.store.setMainViewScenePath(nextScenePath);
351
- this.store.setMainViewFocusPath();
352
- this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath });
375
+ const mainViewScenePath = this.store.getMainViewScenePath() as string;
376
+ if (mainViewScenePath) {
377
+ const sceneList = mainViewScenePath.split("/");
378
+ sceneList.pop();
379
+ let sceneDir = sceneList.join("/");
380
+ if (sceneDir === "") {
381
+ sceneDir = "/";
382
+ }
383
+ const scenePath = makeValidScenePath(this.displayer, sceneDir, index);
384
+ if (scenePath) {
385
+ this.store.setMainViewScenePath(scenePath);
386
+ this.setMainViewFocusPath();
387
+ }
388
+ }
353
389
  }
354
390
  }
355
391
 
@@ -407,7 +443,7 @@ export class AppManager {
407
443
  };
408
444
 
409
445
  public focusByAttributes(apps: any) {
410
- if (apps && Object.keys(apps).length === this.boxManager.appBoxMap.size) {
446
+ if (apps && Object.keys(apps).length === this.boxManager?.boxSize) {
411
447
  const focusAppId = this.store.focus;
412
448
  if (focusAppId) {
413
449
  this.boxManager.focusBox({ appId: focusAppId });
@@ -415,7 +451,7 @@ export class AppManager {
415
451
  }
416
452
  }
417
453
 
418
- public async notifyReconnected() {
454
+ public async onReconnected() {
419
455
  const appProxies = Array.from(this.appProxies.values());
420
456
  const reconnected = appProxies.map(appProxy => {
421
457
  return appProxy.onReconnected();
@@ -448,9 +484,10 @@ export class AppManager {
448
484
  });
449
485
  }
450
486
  this.viewManager.destroy();
451
- this.boxManager.destroy();
487
+ this.boxManager?.destroy();
452
488
  this.refresher?.destroy();
453
489
  this.mainViewProxy.destroy();
454
490
  callbacks.clearListeners();
491
+ this._prevSceneIndex = undefined;
455
492
  }
456
493
  }
package/src/AppProxy.ts CHANGED
@@ -2,16 +2,15 @@ import Emittery from "emittery";
2
2
  import { AppAttributes, AppEvents, Events } from "./constants";
3
3
  import { AppContext } from "./AppContext";
4
4
  import { appRegister } from "./Register";
5
- import { autorun, ViewVisionMode } from "white-web-sdk";
6
- import { callbacks, emitter } from "./index";
5
+ import { autorun } from "white-web-sdk";
6
+ import { emitter } from "./index";
7
7
  import { Fields } from "./AttributesDelegate";
8
8
  import { get } from "lodash";
9
9
  import { log } from "./Utils/log";
10
10
  import {
11
- notifyMainViewModeChange,
12
11
  setScenePath,
13
12
  setViewFocusScenePath,
14
- setViewMode,
13
+ getScenePath
15
14
  } from "./Utils/Common";
16
15
  import type {
17
16
  AppEmitterEvent,
@@ -25,6 +24,7 @@ import type { AppManager } from "./AppManager";
25
24
  import type { NetlessApp } from "./typings";
26
25
  import type { ReadonlyTeleBox } from "@netless/telebox-insider";
27
26
  import { Base } from "./Base";
27
+ import { BoxManagerNotFoundError } from "./Utils/error";
28
28
 
29
29
  export class AppProxy extends Base {
30
30
  public id: string;
@@ -36,10 +36,12 @@ export class AppProxy extends Base {
36
36
  private boxManager = this.manager.boxManager;
37
37
  private appProxies = this.manager.appProxies;
38
38
  private viewManager = this.manager.viewManager;
39
- private cameraStore = this.manager.cameraStore;
40
39
  private kind: string;
41
40
  public isAddApp: boolean;
42
41
  private status: "normal" | "destroyed" = "normal";
42
+ private stateKey: string;
43
+ private appResult?: NetlessApp<any>;
44
+ private appContext?: AppContext<any, any>;
43
45
 
44
46
  constructor(
45
47
  private params: BaseInsertParams,
@@ -50,6 +52,7 @@ export class AppProxy extends Base {
50
52
  super(manager);
51
53
  this.kind = params.kind;
52
54
  this.id = appId;
55
+ this.stateKey = `${this.id}_state`;
53
56
  this.appProxies.set(this.id, this);
54
57
  this.appEmitter = new Emittery();
55
58
  this.appListener = this.makeAppEventListener(this.id);
@@ -93,17 +96,25 @@ export class AppProxy extends Base {
93
96
 
94
97
  public getFullScenePath(): string | undefined {
95
98
  if (this.scenePath) {
96
- return get(this.appAttributes, [Fields.FullPath], this.scenePath);
99
+ return get(this.appAttributes, [Fields.FullPath], this.getFullScenePathFromScenes());
97
100
  }
98
101
  }
99
102
 
103
+ private getFullScenePathFromScenes() {
104
+ const sceneIndex = get(this.appAttributes, ["state", "SceneIndex"], 0);
105
+ const fullPath = getScenePath(this.manager.room, this.scenePath, sceneIndex);
106
+ if (fullPath) {
107
+ this.setFullPath(fullPath);
108
+ }
109
+ return fullPath;
110
+ }
111
+
100
112
  public setFullPath(path: string) {
101
113
  this.manager.safeUpdateAttributes(["apps", this.id, Fields.FullPath], path);
102
114
  }
103
115
 
104
116
  public async baseInsertApp(
105
117
  skipUpdate = false,
106
- focus?: boolean
107
118
  ): Promise<{ appId: string; app: NetlessApp }> {
108
119
  const params = this.params;
109
120
  if (!params.kind) {
@@ -117,9 +128,6 @@ export class AppProxy extends Base {
117
128
  throw new Error(`[WindowManager]: app load failed ${params.kind} ${params.src}`);
118
129
  }
119
130
  this.context.updateManagerRect();
120
- if (focus) {
121
- this.focusApp();
122
- }
123
131
  return {
124
132
  appId: this.id,
125
133
  app: appImpl,
@@ -128,16 +136,15 @@ export class AppProxy extends Base {
128
136
 
129
137
  private focusApp() {
130
138
  this.focusBox();
131
- this.context.switchAppToWriter(this.id);
132
- this.store.setMainViewFocusPath();
139
+ this.store.setMainViewFocusPath(this.manager.mainView);
133
140
  }
134
141
 
135
142
  public get box(): ReadonlyTeleBox | undefined {
136
- return this.boxManager.getBox(this.id);
143
+ return this.boxManager?.getBox(this.id);
137
144
  }
138
145
 
139
146
  public focusBox() {
140
- this.boxManager.focusBox({ appId: this.id });
147
+ this.boxManager?.focusBox({ appId: this.id });
141
148
  }
142
149
 
143
150
  private async setupApp(
@@ -148,13 +155,17 @@ export class AppProxy extends Base {
148
155
  appOptions?: any
149
156
  ) {
150
157
  log("setupApp", appId, app, options);
151
- const context = new AppContext(this.manager, appId, this, appOptions);
158
+ if (!this.boxManager) {
159
+ throw new BoxManagerNotFoundError();
160
+ }
161
+ const context = new AppContext(this.manager, this.boxManager, appId, this, appOptions);
162
+ this.appContext = context;
152
163
  try {
153
164
  emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
154
165
  let boxInitState: AppInitState | undefined;
155
166
  if (!skipUpdate) {
156
167
  boxInitState = this.getAppInitState(appId);
157
- this.boxManager.updateBoxState(boxInitState);
168
+ this.boxManager?.updateBoxState(boxInitState);
158
169
  }
159
170
  this.appEmitter.onAny(this.appListener);
160
171
  this.appAttributesUpdateListener(appId);
@@ -162,12 +173,13 @@ export class AppProxy extends Base {
162
173
  setTimeout(async () => {
163
174
  // 延迟执行 setup, 防止初始化的属性没有更新成功
164
175
  const result = await app.setup(context);
176
+ this.appResult = result;
165
177
  appRegister.notifyApp(app.kind, "created", { appId, result });
166
178
  this.afterSetupApp(boxInitState);
167
179
  this.fixMobileSize();
168
180
  }, 50);
169
181
  });
170
- this.boxManager.createBox({
182
+ this.boxManager?.createBox({
171
183
  appId: appId,
172
184
  app,
173
185
  options,
@@ -182,9 +194,9 @@ export class AppProxy extends Base {
182
194
 
183
195
  // 兼容移动端创建时会出现 PPT 不适配的问题
184
196
  private fixMobileSize() {
185
- const box = this.boxManager.getBox(this.id);
197
+ const box = this.boxManager?.getBox(this.id);
186
198
  if (box) {
187
- this.boxManager.resizeBox({
199
+ this.boxManager?.resizeBox({
188
200
  appId: this.id,
189
201
  width: box.intrinsicWidth + 0.001,
190
202
  height: box.intrinsicHeight + 0.001,
@@ -195,11 +207,8 @@ export class AppProxy extends Base {
195
207
 
196
208
  private afterSetupApp(boxInitState: AppInitState | undefined): void {
197
209
  if (boxInitState) {
198
- if (boxInitState.focus && this.scenePath) {
199
- this.context.switchAppToWriter(this.id);
200
- }
201
210
  if (!boxInitState?.x || !boxInitState.y) {
202
- this.boxManager.setBoxInitState(this.id);
211
+ this.boxManager?.setBoxInitState(this.id);
203
212
  }
204
213
  }
205
214
  }
@@ -207,7 +216,7 @@ export class AppProxy extends Base {
207
216
  public onSeek(time: number) {
208
217
  this.appEmitter.emit("seek", time);
209
218
  const boxInitState = this.getAppInitState(this.id);
210
- this.boxManager.updateBoxState(boxInitState);
219
+ this.boxManager?.updateBoxState(boxInitState);
211
220
  }
212
221
 
213
222
  public async onReconnected() {
@@ -216,27 +225,8 @@ export class AppProxy extends Base {
216
225
  await this.destroy(true, false, true);
217
226
  const params = this.params;
218
227
  const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);
219
- await appProxy.baseInsertApp(true, this.store.focus === this.id);
220
- this.boxManager.updateBoxState(currentAppState);
221
- }
222
-
223
- public switchToWritable() {
224
- appRegister.notifyApp(this.kind, "focus", { appId: this.id });
225
- this.cameraStore.switchView(this.id, this.view, () => {
226
- if (this.view) {
227
- if (this.view.mode === ViewVisionMode.Writable) return;
228
- try {
229
- if (this.manager.mainView.mode === ViewVisionMode.Writable) {
230
- this.store.setMainViewFocusPath();
231
- notifyMainViewModeChange(callbacks, ViewVisionMode.Freedom);
232
- setViewMode(this.manager.mainView, ViewVisionMode.Freedom);
233
- }
234
- setViewMode(this.view, ViewVisionMode.Writable);
235
- } catch (error) {
236
- log("switch view failed", error);
237
- }
238
- }
239
- });
228
+ await appProxy.baseInsertApp(true);
229
+ this.boxManager?.updateBoxState(currentAppState);
240
230
  }
241
231
 
242
232
  public getAppInitState = (id: string) => {
@@ -278,7 +268,7 @@ export class AppProxy extends Base {
278
268
  if (!this.manager.canOperate) return;
279
269
  switch (eventName) {
280
270
  case "setBoxSize": {
281
- this.boxManager.resizeBox({
271
+ this.boxManager?.resizeBox({
282
272
  appId,
283
273
  width: data.width,
284
274
  height: data.height,
@@ -287,7 +277,7 @@ export class AppProxy extends Base {
287
277
  break;
288
278
  }
289
279
  case "setBoxMinSize": {
290
- this.boxManager.setBoxMinSize({
280
+ this.boxManager?.setBoxMinSize({
291
281
  appId,
292
282
  minWidth: data.minwidth,
293
283
  minHeight: data.minheight,
@@ -295,7 +285,7 @@ export class AppProxy extends Base {
295
285
  break;
296
286
  }
297
287
  case "setBoxTitle": {
298
- this.boxManager.setBoxTitle({ appId, title: data.title });
288
+ this.boxManager?.setBoxTitle({ appId, title: data.title });
299
289
  break;
300
290
  }
301
291
  case AppEvents.destroy: {
@@ -307,7 +297,7 @@ export class AppProxy extends Base {
307
297
  break;
308
298
  }
309
299
  case "focus": {
310
- this.boxManager.focusBox({ appId: this.id });
300
+ this.boxManager?.focusBox({ appId: this.id });
311
301
  emitter.emit("focus", { appId: this.id });
312
302
  break;
313
303
  }
@@ -327,6 +317,14 @@ export class AppProxy extends Base {
327
317
  }
328
318
  });
329
319
  });
320
+ this.manager.refresher?.add(this.stateKey,() => {
321
+ return autorun(() => {
322
+ const appState = this.appAttributes?.state;
323
+ if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
324
+ this.boxManager?.setZIndex(appId, appState.zIndex);
325
+ }
326
+ });
327
+ });
330
328
  };
331
329
 
332
330
  public setScenePath(): void {
@@ -346,7 +344,6 @@ export class AppProxy extends Base {
346
344
 
347
345
  private async createView(): Promise<View> {
348
346
  const view = await this.viewManager.createView(this.id);
349
- this.cameraStore.register(this.id, view);
350
347
  this.setViewFocusScenePath();
351
348
  return view;
352
349
  }
@@ -364,17 +361,17 @@ export class AppProxy extends Base {
364
361
  this.appEmitter.clearListeners();
365
362
  emitter.emit(`destroy-${this.id}` as any, { error });
366
363
  if (needCloseBox) {
367
- this.boxManager.closeBox(this.id, skipUpdate);
364
+ this.boxManager?.closeBox(this.id, skipUpdate);
368
365
  }
369
366
  if (cleanAttrs) {
370
367
  this.store.cleanAppAttributes(this.id);
371
368
  }
372
369
  this.appProxies.delete(this.id);
373
- this.cameraStore.unregister(this.id, this.view);
374
370
 
375
371
  this.viewManager.destroyView(this.id);
376
372
  this.manager.appStatus.delete(this.id);
377
373
  this.manager.refresher?.remove(this.id);
374
+ this.manager.refresher?.remove(this.stateKey);
378
375
  }
379
376
 
380
377
  public close(): Promise<void> {