@netless/window-manager 0.4.0-canary.0 → 0.4.0-canary.12
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.
- package/CHANGELOG.md +6 -0
- package/dist/App/MagixEvent/index.d.ts +28 -0
- package/dist/App/Storage/StorageEvent.d.ts +8 -0
- package/dist/App/Storage/index.d.ts +38 -0
- package/dist/App/Storage/typings.d.ts +21 -0
- package/dist/App/Storage/utils.d.ts +5 -0
- package/dist/AppContext.d.ts +40 -16
- package/dist/AppListener.d.ts +1 -1
- package/dist/AppManager.d.ts +8 -7
- package/dist/AppProxy.d.ts +4 -4
- package/dist/Base/Context.d.ts +0 -1
- package/dist/BoxManager.d.ts +1 -0
- package/dist/BuiltinApps.d.ts +6 -0
- package/dist/ContainerResizeObserver.d.ts +10 -0
- package/dist/Cursor/Cursor.d.ts +2 -3
- package/dist/Cursor/index.d.ts +7 -4
- package/dist/Helper.d.ts +6 -0
- package/dist/ReconnectRefresher.d.ts +8 -3
- package/dist/Utils/Common.d.ts +3 -1
- package/dist/Utils/Reactive.d.ts +1 -1
- package/dist/{MainView.d.ts → View/MainView.d.ts} +3 -4
- package/dist/View/ViewManager.d.ts +13 -0
- package/dist/constants.d.ts +3 -7
- package/dist/index.d.ts +14 -14
- package/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/typings.d.ts +3 -2
- package/package.json +7 -5
- package/src/App/MagixEvent/index.ts +66 -0
- package/src/App/Storage/StorageEvent.ts +21 -0
- package/src/App/Storage/index.ts +284 -0
- package/src/App/Storage/typings.ts +21 -0
- package/src/App/Storage/utils.ts +17 -0
- package/src/AppContext.ts +61 -19
- package/src/AppListener.ts +9 -8
- package/src/AppManager.ts +71 -36
- package/src/AppProxy.ts +39 -48
- package/src/Base/Context.ts +0 -4
- package/src/BoxManager.ts +9 -8
- package/src/BuiltinApps.ts +24 -0
- package/src/ContainerResizeObserver.ts +62 -0
- package/src/Cursor/Cursor.ts +23 -34
- package/src/Cursor/index.ts +70 -41
- package/src/Helper.ts +30 -0
- package/src/ReconnectRefresher.ts +15 -4
- package/src/Utils/Common.ts +35 -13
- package/src/Utils/Reactive.ts +9 -3
- package/src/Utils/RoomHacker.ts +15 -0
- package/src/{MainView.ts → View/MainView.ts} +19 -27
- package/src/View/ViewManager.ts +53 -0
- package/src/constants.ts +2 -3
- package/src/index.ts +81 -117
- package/src/shim.d.ts +4 -0
- package/src/style.css +6 -0
- package/src/typings.ts +3 -2
- package/vite.config.js +4 -1
- package/dist/Utils/CameraStore.d.ts +0 -15
- package/dist/ViewManager.d.ts +0 -29
- package/dist/sdk.d.ts +0 -14
- package/src/Utils/CameraStore.ts +0 -72
- package/src/sdk.ts +0 -39
- package/src/viewManager.ts +0 -177
package/src/AppContext.ts
CHANGED
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
unlistenDisposed,
|
7
7
|
unlistenUpdated,
|
8
8
|
toJS
|
9
|
-
|
9
|
+
} from 'white-web-sdk';
|
10
10
|
import { BoxNotCreatedError } from './Utils/error';
|
11
11
|
import type { Room, SceneDefinition, View } from "white-web-sdk";
|
12
12
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
@@ -15,9 +15,11 @@ import type { BoxManager } from "./BoxManager";
|
|
15
15
|
import type { AppEmitterEvent } from "./index";
|
16
16
|
import type { AppManager } from "./AppManager";
|
17
17
|
import type { AppProxy } from "./AppProxy";
|
18
|
+
import { Storage } from './App/Storage';
|
19
|
+
import type { MagixEventAddListener, MagixEventDispatcher, MagixEventRemoveListener } from './App/MagixEvent';
|
18
20
|
|
19
|
-
export class AppContext<
|
20
|
-
public readonly emitter: Emittery<AppEmitterEvent<
|
21
|
+
export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {
|
22
|
+
public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
|
21
23
|
public readonly mobxUtils = {
|
22
24
|
autorun,
|
23
25
|
reaction,
|
@@ -39,21 +41,22 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
|
|
39
41
|
private boxManager: BoxManager,
|
40
42
|
public appId: string,
|
41
43
|
private appProxy: AppProxy,
|
42
|
-
private appOptions?:
|
44
|
+
private appOptions?: TAppOptions | (() => TAppOptions),
|
43
45
|
) {
|
44
46
|
this.emitter = appProxy.appEmitter;
|
45
47
|
this.isAddApp = appProxy.isAddApp;
|
46
48
|
}
|
47
49
|
|
48
|
-
public getDisplayer() {
|
50
|
+
public getDisplayer = () => {
|
49
51
|
return this.manager.displayer;
|
50
52
|
}
|
51
53
|
|
52
|
-
|
54
|
+
/** @deprecated Use context.storage.state instead. */
|
55
|
+
public getAttributes = (): TAttributes | undefined => {
|
53
56
|
return this.appProxy.attributes;
|
54
57
|
}
|
55
58
|
|
56
|
-
public getScenes(): SceneDefinition[] | undefined {
|
59
|
+
public getScenes = (): SceneDefinition[] | undefined => {
|
57
60
|
const appAttr = this.store.getAppAttributes(this.appId);
|
58
61
|
if (appAttr?.isDynamicPPT) {
|
59
62
|
const appProxy = this.manager.appProxies.get(this.appId);
|
@@ -65,19 +68,21 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
|
|
65
68
|
}
|
66
69
|
}
|
67
70
|
|
68
|
-
public getView(): View | undefined {
|
71
|
+
public getView = (): View | undefined => {
|
69
72
|
return this.appProxy.view;
|
70
73
|
}
|
71
74
|
|
72
|
-
public getInitScenePath() {
|
75
|
+
public getInitScenePath = () => {
|
73
76
|
return this.manager.getAppInitPath(this.appId);
|
74
77
|
}
|
75
78
|
|
76
|
-
|
79
|
+
/** Get App writable status. */
|
80
|
+
public getIsWritable = (): boolean => {
|
77
81
|
return this.manager.canOperate;
|
78
82
|
}
|
79
83
|
|
80
|
-
|
84
|
+
/** Get the App Window UI box. */
|
85
|
+
public getBox = (): ReadonlyTeleBox => {
|
81
86
|
const box = this.boxManager.getBox(this.appId);
|
82
87
|
if (box) {
|
83
88
|
return box;
|
@@ -86,27 +91,30 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
|
|
86
91
|
}
|
87
92
|
}
|
88
93
|
|
89
|
-
public getRoom(): Room | undefined {
|
94
|
+
public getRoom = (): Room | undefined => {
|
90
95
|
return this.manager.room;
|
91
96
|
}
|
92
97
|
|
93
|
-
|
98
|
+
/** @deprecated Use context.storage.setState instead. */
|
99
|
+
public setAttributes = (attributes: TAttributes) => {
|
94
100
|
this.manager.safeSetAttributes({ [this.appId]: attributes });
|
95
101
|
}
|
96
102
|
|
97
|
-
|
103
|
+
/** @deprecated Use context.storage.setState instead. */
|
104
|
+
public updateAttributes = (keys: string[], value: any) => {
|
98
105
|
if (this.manager.attributes[this.appId]) {
|
99
106
|
this.manager.safeUpdateAttributes([this.appId, ...keys], value);
|
100
107
|
}
|
101
108
|
}
|
102
109
|
|
103
|
-
public async
|
110
|
+
public setScenePath = async (scenePath: string): Promise<void> => {
|
104
111
|
if (!this.appProxy.box) return;
|
105
112
|
this.appProxy.setFullPath(scenePath);
|
106
|
-
|
113
|
+
// 兼容 15 版本 SDK 的切页
|
114
|
+
this.getRoom()?.setScenePath(scenePath);
|
107
115
|
}
|
108
116
|
|
109
|
-
public mountView(dom: HTMLDivElement): void {
|
117
|
+
public mountView = (dom: HTMLDivElement): void => {
|
110
118
|
const view = this.getView();
|
111
119
|
if (view) {
|
112
120
|
view.divElement = dom;
|
@@ -117,7 +125,41 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
|
|
117
125
|
}
|
118
126
|
}
|
119
127
|
|
120
|
-
|
121
|
-
|
128
|
+
/** Get the local App options. */
|
129
|
+
public getAppOptions = (): TAppOptions | undefined => {
|
130
|
+
return typeof this.appOptions === 'function' ? (this.appOptions as () => TAppOptions)() : this.appOptions
|
122
131
|
}
|
132
|
+
|
133
|
+
private _storage?: Storage<TAttributes>
|
134
|
+
|
135
|
+
/** Main Storage for attributes. */
|
136
|
+
public get storage(): Storage<TAttributes> {
|
137
|
+
if (!this._storage) {
|
138
|
+
this._storage = new Storage(this);
|
139
|
+
}
|
140
|
+
return this._storage;
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Create separated storages for flexible state management.
|
145
|
+
* @param storeId Namespace for the storage. Storages of the same namespace share the same data.
|
146
|
+
* @param defaultState Default state for initial storage creation.
|
147
|
+
* @returns
|
148
|
+
*/
|
149
|
+
public createStorage = <TState>(storeId: string, defaultState?: TState): Storage<TState> => {
|
150
|
+
const storage = new Storage(this, storeId, defaultState);
|
151
|
+
this.emitter.on("destroy", () => {
|
152
|
+
storage.destroy();
|
153
|
+
});
|
154
|
+
return storage;
|
155
|
+
}
|
156
|
+
|
157
|
+
/** Dispatch events to other clients (and self). */
|
158
|
+
public dispatchMagixEvent: MagixEventDispatcher<TMagixEventPayloads> = (this.manager.displayer as Room).dispatchMagixEvent.bind(this.manager.displayer)
|
159
|
+
|
160
|
+
/** Listen to events from others clients (and self messages). */
|
161
|
+
public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = this.manager.displayer.addMagixEventListener.bind(this.manager.displayer)
|
162
|
+
|
163
|
+
/** Remove a Magix event listener. */
|
164
|
+
public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(this.manager.displayer) as MagixEventRemoveListener<TMagixEventPayloads>
|
123
165
|
}
|
package/src/AppListener.ts
CHANGED
@@ -34,10 +34,6 @@ export class AppListeners {
|
|
34
34
|
this.appResizeHandler(data.payload);
|
35
35
|
break;
|
36
36
|
}
|
37
|
-
case Events.SwitchViewsToFreedom: {
|
38
|
-
this.switchViewsToFreedomHandler();
|
39
|
-
break;
|
40
|
-
}
|
41
37
|
case Events.AppBoxStateChange: {
|
42
38
|
this.boxStateChangeHandler(data.payload);
|
43
39
|
break;
|
@@ -46,6 +42,10 @@ export class AppListeners {
|
|
46
42
|
this.setMainViewScenePathHandler(data.payload);
|
47
43
|
break;
|
48
44
|
}
|
45
|
+
case Events.MoveCameraToContain: {
|
46
|
+
this.moveCameraToContainHandler(data.payload);
|
47
|
+
break;
|
48
|
+
}
|
49
49
|
default:
|
50
50
|
break;
|
51
51
|
}
|
@@ -61,15 +61,16 @@ export class AppListeners {
|
|
61
61
|
this.manager.room?.refreshViewSize();
|
62
62
|
};
|
63
63
|
|
64
|
-
private switchViewsToFreedomHandler = () => {
|
65
|
-
this.manager.viewManager.freedomAllViews();
|
66
|
-
};
|
67
|
-
|
68
64
|
private boxStateChangeHandler = (state: TeleBoxState) => {
|
69
65
|
callbacks.emit("boxStateChange", state);
|
70
66
|
}
|
71
67
|
|
72
68
|
private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {
|
73
69
|
setViewFocusScenePath(this.manager.mainView, nextScenePath);
|
70
|
+
callbacks.emit("mainViewScenePathChange", nextScenePath);
|
71
|
+
}
|
72
|
+
|
73
|
+
private moveCameraToContainHandler = (payload: any) => {
|
74
|
+
this.manager.mainView.moveCameraToContain(payload);
|
74
75
|
}
|
75
76
|
}
|
package/src/AppManager.ts
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
import pRetry from "p-retry";
|
2
|
-
import { sortBy } from "lodash";
|
3
2
|
import { AppAttributes, AppStatus, Events, MagixEventName } from "./constants";
|
4
3
|
import { AppListeners } from "./AppListener";
|
5
4
|
import { AppProxy } from "./AppProxy";
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
import {
|
9
|
-
import { CameraStore } from "./Utils/CameraStore";
|
10
|
-
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";
|
11
8
|
import { log } from "./Utils/log";
|
12
|
-
import { MainViewProxy } from "./MainView";
|
9
|
+
import { MainViewProxy } from "./View/MainView";
|
13
10
|
import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
|
14
|
-
import {
|
15
|
-
import {
|
11
|
+
import { get, sortBy } from "lodash";
|
12
|
+
import { store } from "./AttributesDelegate";
|
13
|
+
import { ViewManager } from "./View/ViewManager";
|
14
|
+
import type { ReconnectRefresher } from "./ReconnectRefresher";
|
16
15
|
import type { BoxManager } from "./BoxManager";
|
17
16
|
import type { Displayer, DisplayerState, Room } from "white-web-sdk";
|
18
17
|
import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "./index";
|
18
|
+
|
19
19
|
export class AppManager {
|
20
20
|
public displayer: Displayer;
|
21
|
-
public cameraStore: CameraStore;
|
22
21
|
public viewManager: ViewManager;
|
23
22
|
public appProxies: Map<string, AppProxy> = new Map();
|
24
23
|
public appStatus: Map<string, AppStatus> = new Map();
|
@@ -30,24 +29,28 @@ export class AppManager {
|
|
30
29
|
private appListeners: AppListeners;
|
31
30
|
public boxManager?: BoxManager;
|
32
31
|
|
32
|
+
private _prevSceneIndex: number | undefined;
|
33
|
+
private _prevFocused: string | undefined;
|
34
|
+
|
33
35
|
constructor(public windowManger: WindowManager) {
|
34
36
|
this.displayer = windowManger.displayer;
|
35
37
|
this.store.setContext({
|
36
38
|
getAttributes: () => this.attributes,
|
37
|
-
safeSetAttributes:
|
39
|
+
safeSetAttributes: attributes => this.safeSetAttributes(attributes),
|
38
40
|
safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),
|
39
41
|
});
|
40
|
-
this.cameraStore = new CameraStore();
|
41
42
|
this.mainViewProxy = new MainViewProxy(this);
|
42
|
-
this.viewManager = new ViewManager(this);
|
43
|
+
this.viewManager = new ViewManager(this.displayer);
|
43
44
|
this.appListeners = new AppListeners(this);
|
44
45
|
this.displayer.callbacks.on(this.eventName, this.displayerStateListener);
|
45
46
|
this.appListeners.addListeners();
|
46
47
|
|
47
|
-
this.refresher =
|
48
|
+
this.refresher = reconnectRefresher;
|
49
|
+
this.refresher.setRoom(this.room);
|
50
|
+
this.refresher.setContext({ emitter });
|
48
51
|
|
49
52
|
emitter.once("onCreated").then(() => this.onCreated());
|
50
|
-
|
53
|
+
emitter.on("onReconnected", () => this.onReconnected());
|
51
54
|
if (isPlayer(this.displayer)) {
|
52
55
|
emitter.on("seek", time => {
|
53
56
|
this.appProxies.forEach(appProxy => {
|
@@ -95,6 +98,24 @@ export class AppManager {
|
|
95
98
|
}
|
96
99
|
});
|
97
100
|
});
|
101
|
+
this.refresher?.add("mainViewIndex", () => {
|
102
|
+
return autorun(() => {
|
103
|
+
const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
|
104
|
+
if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {
|
105
|
+
callbacks.emit("mainViewSceneIndexChange", mainSceneIndex);
|
106
|
+
this._prevSceneIndex = mainSceneIndex;
|
107
|
+
}
|
108
|
+
});
|
109
|
+
});
|
110
|
+
this.refresher?.add("focusedChange", () => {
|
111
|
+
return autorun(() => {
|
112
|
+
const focused = get(this.attributes, "focus");
|
113
|
+
if (this._prevFocused !== focused) {
|
114
|
+
callbacks.emit("focusedChange", focused);
|
115
|
+
this._prevFocused = focused;
|
116
|
+
}
|
117
|
+
});
|
118
|
+
})
|
98
119
|
if (!this.attributes.apps || Object.keys(this.attributes.apps).length === 0) {
|
99
120
|
const mainScenePath = this.store.getMainViewScenePath();
|
100
121
|
if (!mainScenePath) return;
|
@@ -105,6 +126,7 @@ export class AppManager {
|
|
105
126
|
}
|
106
127
|
this.displayerWritableListener(!this.room?.isWritable);
|
107
128
|
this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
|
129
|
+
this._prevFocused = this.attributes.focus;
|
108
130
|
}
|
109
131
|
|
110
132
|
/**
|
@@ -116,11 +138,11 @@ export class AppManager {
|
|
116
138
|
public async attributesUpdateCallback(apps: any) {
|
117
139
|
if (apps && WindowManager.container) {
|
118
140
|
const appIds = Object.keys(apps);
|
119
|
-
const appsWithCreatedAt = appIds.map(appId =>
|
141
|
+
const appsWithCreatedAt = appIds.map(appId => {
|
120
142
|
return {
|
121
143
|
id: appId,
|
122
144
|
createdAt: apps[appId].createdAt,
|
123
|
-
}
|
145
|
+
};
|
124
146
|
});
|
125
147
|
for (const { id } of sortBy(appsWithCreatedAt, "createdAt")) {
|
126
148
|
if (!this.appProxies.has(id) && !this.appStatus.has(id)) {
|
@@ -185,15 +207,18 @@ export class AppManager {
|
|
185
207
|
mainView.disableCameraTransform = disableCameraTransform;
|
186
208
|
mainView.divElement = divElement;
|
187
209
|
if (!mainView.focusScenePath) {
|
188
|
-
this.
|
189
|
-
}
|
190
|
-
if (this.store.focus === undefined && mainView.mode !== ViewVisionMode.Writable) {
|
191
|
-
this.viewManager.switchMainViewToWriter();
|
210
|
+
this.setMainViewFocusPath();
|
192
211
|
}
|
193
|
-
this.mainViewProxy.addMainViewListener();
|
194
212
|
emitter.emit("mainViewMounted");
|
195
213
|
}
|
196
214
|
|
215
|
+
public setMainViewFocusPath() {
|
216
|
+
const scenePath = this.store.getMainViewScenePath();
|
217
|
+
if (scenePath) {
|
218
|
+
setViewFocusScenePath(this.mainView, scenePath);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
197
222
|
public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {
|
198
223
|
log("addApp", params);
|
199
224
|
const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);
|
@@ -279,7 +304,7 @@ export class AppManager {
|
|
279
304
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
280
305
|
};
|
281
306
|
|
282
|
-
|
307
|
+
public displayerWritableListener = (isReadonly: boolean) => {
|
283
308
|
const isWritable = !isReadonly;
|
284
309
|
const isManualWritable =
|
285
310
|
this.windowManger.readonly === undefined || this.windowManger.readonly === false;
|
@@ -292,10 +317,10 @@ export class AppManager {
|
|
292
317
|
appProxy.emitAppIsWritableChange();
|
293
318
|
});
|
294
319
|
if (isWritable === true) {
|
295
|
-
if (!this.store.focus) {
|
296
|
-
this.mainViewProxy.switchViewModeToWriter();
|
297
|
-
}
|
298
320
|
this.mainView.disableCameraTransform = false;
|
321
|
+
if (this.room && this.room.disableSerialization === true) {
|
322
|
+
this.room.disableSerialization = false;
|
323
|
+
}
|
299
324
|
} else {
|
300
325
|
this.mainView.disableCameraTransform = true;
|
301
326
|
}
|
@@ -344,15 +369,16 @@ export class AppManager {
|
|
344
369
|
await this._setMainViewScenePath(scenePath);
|
345
370
|
} else if (scenePathType === ScenePathType.Dir) {
|
346
371
|
const validScenePath = makeValidScenePath(this.displayer, scenePath);
|
347
|
-
|
372
|
+
if (validScenePath) {
|
373
|
+
await this._setMainViewScenePath(validScenePath);
|
374
|
+
}
|
348
375
|
}
|
349
376
|
}
|
350
377
|
}
|
351
378
|
|
352
379
|
private async _setMainViewScenePath(scenePath: string) {
|
353
380
|
this.safeSetAttributes({ _mainScenePath: scenePath });
|
354
|
-
|
355
|
-
setScenePath(this.room, scenePath);
|
381
|
+
this.setMainViewFocusPath();
|
356
382
|
this.store.setMainViewFocusPath(this.mainView);
|
357
383
|
this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
|
358
384
|
}
|
@@ -360,12 +386,20 @@ export class AppManager {
|
|
360
386
|
public async setMainViewSceneIndex(index: number) {
|
361
387
|
if (this.room) {
|
362
388
|
this.safeSetAttributes({ _mainSceneIndex: index });
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
389
|
+
const mainViewScenePath = this.store.getMainViewScenePath() as string;
|
390
|
+
if (mainViewScenePath) {
|
391
|
+
const sceneList = mainViewScenePath.split("/");
|
392
|
+
sceneList.pop();
|
393
|
+
let sceneDir = sceneList.join("/");
|
394
|
+
if (sceneDir === "") {
|
395
|
+
sceneDir = "/";
|
396
|
+
}
|
397
|
+
const scenePath = makeValidScenePath(this.displayer, sceneDir, index);
|
398
|
+
if (scenePath) {
|
399
|
+
this.store.setMainViewScenePath(scenePath);
|
400
|
+
this.setMainViewFocusPath();
|
401
|
+
}
|
402
|
+
}
|
369
403
|
}
|
370
404
|
}
|
371
405
|
|
@@ -431,7 +465,7 @@ export class AppManager {
|
|
431
465
|
}
|
432
466
|
}
|
433
467
|
|
434
|
-
public async
|
468
|
+
public async onReconnected() {
|
435
469
|
const appProxies = Array.from(this.appProxies.values());
|
436
470
|
const reconnected = appProxies.map(appProxy => {
|
437
471
|
return appProxy.onReconnected();
|
@@ -468,5 +502,6 @@ export class AppManager {
|
|
468
502
|
this.refresher?.destroy();
|
469
503
|
this.mainViewProxy.destroy();
|
470
504
|
callbacks.clearListeners();
|
505
|
+
this._prevSceneIndex = undefined;
|
471
506
|
}
|
472
507
|
}
|
package/src/AppProxy.ts
CHANGED
@@ -2,17 +2,12 @@ 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
|
6
|
-
import {
|
5
|
+
import { autorun } from "white-web-sdk";
|
6
|
+
import { emitter } from "./index";
|
7
7
|
import { Fields } from "./AttributesDelegate";
|
8
|
-
import { get } from "lodash";
|
8
|
+
import { debounce, get } from "lodash";
|
9
9
|
import { log } from "./Utils/log";
|
10
|
-
import {
|
11
|
-
notifyMainViewModeChange,
|
12
|
-
setScenePath,
|
13
|
-
setViewFocusScenePath,
|
14
|
-
setViewMode,
|
15
|
-
} from "./Utils/Common";
|
10
|
+
import { setScenePath, setViewFocusScenePath, getScenePath } from "./Utils/Common";
|
16
11
|
import type {
|
17
12
|
AppEmitterEvent,
|
18
13
|
AppInitState,
|
@@ -37,12 +32,11 @@ export class AppProxy extends Base {
|
|
37
32
|
private boxManager = this.manager.boxManager;
|
38
33
|
private appProxies = this.manager.appProxies;
|
39
34
|
private viewManager = this.manager.viewManager;
|
40
|
-
private cameraStore = this.manager.cameraStore;
|
41
35
|
private kind: string;
|
42
36
|
public isAddApp: boolean;
|
43
37
|
private status: "normal" | "destroyed" = "normal";
|
44
38
|
private stateKey: string;
|
45
|
-
private
|
39
|
+
private appResult?: NetlessApp<any>;
|
46
40
|
private appContext?: AppContext<any, any>;
|
47
41
|
|
48
42
|
constructor(
|
@@ -98,18 +92,24 @@ export class AppProxy extends Base {
|
|
98
92
|
|
99
93
|
public getFullScenePath(): string | undefined {
|
100
94
|
if (this.scenePath) {
|
101
|
-
return get(this.appAttributes, [Fields.FullPath], this.
|
95
|
+
return get(this.appAttributes, [Fields.FullPath], this.getFullScenePathFromScenes());
|
102
96
|
}
|
103
97
|
}
|
104
98
|
|
99
|
+
private getFullScenePathFromScenes() {
|
100
|
+
const sceneIndex = get(this.appAttributes, ["state", "SceneIndex"], 0);
|
101
|
+
const fullPath = getScenePath(this.manager.room, this.scenePath, sceneIndex);
|
102
|
+
if (fullPath) {
|
103
|
+
this.setFullPath(fullPath);
|
104
|
+
}
|
105
|
+
return fullPath;
|
106
|
+
}
|
107
|
+
|
105
108
|
public setFullPath(path: string) {
|
106
109
|
this.manager.safeUpdateAttributes(["apps", this.id, Fields.FullPath], path);
|
107
110
|
}
|
108
111
|
|
109
|
-
public async baseInsertApp(
|
110
|
-
skipUpdate = false,
|
111
|
-
focus?: boolean
|
112
|
-
): Promise<{ appId: string; app: NetlessApp }> {
|
112
|
+
public async baseInsertApp(skipUpdate = false): Promise<{ appId: string; app: NetlessApp }> {
|
113
113
|
const params = this.params;
|
114
114
|
if (!params.kind) {
|
115
115
|
throw new Error("[WindowManager]: kind require");
|
@@ -117,14 +117,17 @@ export class AppProxy extends Base {
|
|
117
117
|
const appImpl = await appRegister.appClasses.get(params.kind)?.();
|
118
118
|
const appParams = appRegister.registered.get(params.kind);
|
119
119
|
if (appImpl) {
|
120
|
-
await this.setupApp(
|
120
|
+
await this.setupApp(
|
121
|
+
this.id,
|
122
|
+
skipUpdate,
|
123
|
+
appImpl,
|
124
|
+
params.options,
|
125
|
+
appParams?.appOptions
|
126
|
+
);
|
121
127
|
} else {
|
122
128
|
throw new Error(`[WindowManager]: app load failed ${params.kind} ${params.src}`);
|
123
129
|
}
|
124
130
|
this.context.updateManagerRect();
|
125
|
-
if (focus) {
|
126
|
-
this.focusApp();
|
127
|
-
}
|
128
131
|
return {
|
129
132
|
appId: this.id,
|
130
133
|
app: appImpl,
|
@@ -133,7 +136,6 @@ export class AppProxy extends Base {
|
|
133
136
|
|
134
137
|
private focusApp() {
|
135
138
|
this.focusBox();
|
136
|
-
this.context.switchAppToWriter(this.id);
|
137
139
|
this.store.setMainViewFocusPath(this.manager.mainView);
|
138
140
|
}
|
139
141
|
|
@@ -171,7 +173,7 @@ export class AppProxy extends Base {
|
|
171
173
|
setTimeout(async () => {
|
172
174
|
// 延迟执行 setup, 防止初始化的属性没有更新成功
|
173
175
|
const result = await app.setup(context);
|
174
|
-
this.
|
176
|
+
this.appResult = result;
|
175
177
|
appRegister.notifyApp(app.kind, "created", { appId, result });
|
176
178
|
this.afterSetupApp(boxInitState);
|
177
179
|
this.fixMobileSize();
|
@@ -205,9 +207,6 @@ export class AppProxy extends Base {
|
|
205
207
|
|
206
208
|
private afterSetupApp(boxInitState: AppInitState | undefined): void {
|
207
209
|
if (boxInitState) {
|
208
|
-
if (boxInitState.focus && this.scenePath) {
|
209
|
-
this.context.switchAppToWriter(this.id);
|
210
|
-
}
|
211
210
|
if (!boxInitState?.x || !boxInitState.y) {
|
212
211
|
this.boxManager?.setBoxInitState(this.id);
|
213
212
|
}
|
@@ -226,29 +225,10 @@ export class AppProxy extends Base {
|
|
226
225
|
await this.destroy(true, false, true);
|
227
226
|
const params = this.params;
|
228
227
|
const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);
|
229
|
-
await appProxy.baseInsertApp(true
|
228
|
+
await appProxy.baseInsertApp(true);
|
230
229
|
this.boxManager?.updateBoxState(currentAppState);
|
231
230
|
}
|
232
231
|
|
233
|
-
public switchToWritable() {
|
234
|
-
appRegister.notifyApp(this.kind, "focus", { appId: this.id });
|
235
|
-
this.cameraStore.switchView(this.id, this.view, () => {
|
236
|
-
if (this.view) {
|
237
|
-
if (this.view.mode === ViewVisionMode.Writable) return;
|
238
|
-
try {
|
239
|
-
if (this.manager.mainView.mode === ViewVisionMode.Writable) {
|
240
|
-
this.store.setMainViewFocusPath(this.manager.mainView);
|
241
|
-
notifyMainViewModeChange(callbacks, ViewVisionMode.Freedom);
|
242
|
-
setViewMode(this.manager.mainView, ViewVisionMode.Freedom);
|
243
|
-
}
|
244
|
-
setViewMode(this.view, ViewVisionMode.Writable);
|
245
|
-
} catch (error) {
|
246
|
-
log("switch view failed", error);
|
247
|
-
}
|
248
|
-
}
|
249
|
-
});
|
250
|
-
}
|
251
|
-
|
252
232
|
public getAppInitState = (id: string) => {
|
253
233
|
const attrs = this.store.getAppState(id);
|
254
234
|
if (!attrs) return;
|
@@ -337,7 +317,7 @@ export class AppProxy extends Base {
|
|
337
317
|
}
|
338
318
|
});
|
339
319
|
});
|
340
|
-
this.manager.refresher?.add(this.stateKey,() => {
|
320
|
+
this.manager.refresher?.add(this.stateKey, () => {
|
341
321
|
return autorun(() => {
|
342
322
|
const appState = this.appAttributes?.state;
|
343
323
|
if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
|
@@ -345,8 +325,20 @@ export class AppProxy extends Base {
|
|
345
325
|
}
|
346
326
|
});
|
347
327
|
});
|
328
|
+
this.manager.refresher?.add(`${appId}-fullPath`, () => {
|
329
|
+
return autorun(() => {
|
330
|
+
const fullPath = this.appAttributes.fullPath;
|
331
|
+
this.setFocusScenePathHandler(fullPath);
|
332
|
+
});
|
333
|
+
});
|
348
334
|
};
|
349
335
|
|
336
|
+
private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
|
337
|
+
if (this.view && fullPath && fullPath !== this.view?.focusScenePath) {
|
338
|
+
setViewFocusScenePath(this.view, fullPath);
|
339
|
+
}
|
340
|
+
}, 50);
|
341
|
+
|
350
342
|
public setScenePath(): void {
|
351
343
|
if (!this.manager.canOperate) return;
|
352
344
|
const fullScenePath = this.getFullScenePath();
|
@@ -364,7 +356,6 @@ export class AppProxy extends Base {
|
|
364
356
|
|
365
357
|
private async createView(): Promise<View> {
|
366
358
|
const view = await this.viewManager.createView(this.id);
|
367
|
-
this.cameraStore.register(this.id, view);
|
368
359
|
this.setViewFocusScenePath();
|
369
360
|
return view;
|
370
361
|
}
|
@@ -388,12 +379,12 @@ export class AppProxy extends Base {
|
|
388
379
|
this.store.cleanAppAttributes(this.id);
|
389
380
|
}
|
390
381
|
this.appProxies.delete(this.id);
|
391
|
-
this.cameraStore.unregister(this.id, this.view);
|
392
382
|
|
393
383
|
this.viewManager.destroyView(this.id);
|
394
384
|
this.manager.appStatus.delete(this.id);
|
395
385
|
this.manager.refresher?.remove(this.id);
|
396
386
|
this.manager.refresher?.remove(this.stateKey);
|
387
|
+
this.manager.refresher?.remove(`${this.id}-fullPath`);
|
397
388
|
}
|
398
389
|
|
399
390
|
public close(): Promise<void> {
|
package/src/Base/Context.ts
CHANGED
package/src/BoxManager.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { AppAttributes,
|
1
|
+
import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
|
2
2
|
import { debounce, maxBy } from "lodash";
|
3
3
|
import {
|
4
4
|
TELE_BOX_MANAGER_EVENT,
|
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
TeleBoxCollector,
|
7
7
|
TeleBoxManager,
|
8
8
|
} from "@netless/telebox-insider";
|
9
|
-
import { WindowManager } from "./index";
|
9
|
+
import { emitter, WindowManager } from "./index";
|
10
10
|
import type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from "./index";
|
11
11
|
import type {
|
12
12
|
TeleBoxManagerUpdateConfig,
|
@@ -143,9 +143,13 @@ export class BoxManager {
|
|
143
143
|
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
144
144
|
});
|
145
145
|
this.teleBoxManager.events.on("z_index", box => {
|
146
|
-
console.log("on z_index", box.id, box.zIndex);
|
147
146
|
this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
|
148
147
|
});
|
148
|
+
emitter.on("playgroundSizeChange", this.playgroundSizeChangeListener);
|
149
|
+
}
|
150
|
+
|
151
|
+
private playgroundSizeChangeListener = () => {
|
152
|
+
this.updateManagerRect();
|
149
153
|
}
|
150
154
|
|
151
155
|
private get mainView() {
|
@@ -252,12 +256,8 @@ export class BoxManager {
|
|
252
256
|
}
|
253
257
|
|
254
258
|
public setCollectorContainer(container: HTMLElement) {
|
255
|
-
const styles = {
|
256
|
-
...DEFAULT_COLLECTOR_STYLE,
|
257
|
-
...this.createTeleBoxManagerConfig?.collectorStyles,
|
258
|
-
};
|
259
259
|
const collector = new TeleBoxCollector({
|
260
|
-
styles
|
260
|
+
styles: this.createTeleBoxManagerConfig?.collectorStyles,
|
261
261
|
}).mount(container);
|
262
262
|
this.teleBoxManager.setCollector(collector);
|
263
263
|
}
|
@@ -392,6 +392,7 @@ export class BoxManager {
|
|
392
392
|
}
|
393
393
|
|
394
394
|
public destroy() {
|
395
|
+
emitter.off("playgroundSizeChange", this.playgroundSizeChangeListener);
|
395
396
|
this.teleBoxManager.destroy();
|
396
397
|
}
|
397
398
|
}
|