@netless/window-manager 0.4.0-canary.1 → 0.4.0-canary.13
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/dist/App/MagixEvent/index.d.ts +29 -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 +0 -1
- package/dist/AppManager.d.ts +8 -7
- package/dist/AppProxy.d.ts +3 -3
- 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 +5 -2
- 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} +2 -4
- package/dist/View/ViewManager.d.ts +13 -0
- package/dist/constants.d.ts +1 -6
- package/dist/index.d.ts +14 -13
- 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 +6 -5
- package/src/App/MagixEvent/index.ts +68 -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 +65 -20
- package/src/AppListener.ts +1 -8
- package/src/AppManager.ts +68 -35
- package/src/AppProxy.ts +37 -46
- package/src/Base/Context.ts +0 -4
- package/src/BoxManager.ts +9 -7
- 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 +13 -5
- package/src/Utils/Common.ts +35 -13
- package/src/Utils/Reactive.ts +9 -3
- package/src/Utils/RoomHacker.ts +16 -0
- package/src/{MainView.ts → View/MainView.ts} +9 -25
- package/src/View/ViewManager.ts +53 -0
- package/src/constants.ts +1 -3
- package/src/index.ts +47 -86
- 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,18 +6,20 @@ import {
|
|
6
6
|
unlistenDisposed,
|
7
7
|
unlistenUpdated,
|
8
8
|
toJS
|
9
|
-
|
9
|
+
} from 'white-web-sdk';
|
10
10
|
import { BoxNotCreatedError } from './Utils/error';
|
11
|
-
import type { Room, SceneDefinition, View } from "white-web-sdk";
|
11
|
+
import type { Room, SceneDefinition, View, EventListener as WhiteEventListener } from "white-web-sdk";
|
12
12
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
13
13
|
import type Emittery from "emittery";
|
14
14
|
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,44 @@ 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> = (event, handler, options) => {
|
162
|
+
this.manager.displayer.addMagixEventListener(event, handler as WhiteEventListener, options);
|
163
|
+
return () => this.manager.displayer.removeMagixEventListener(event, handler as WhiteEventListener);
|
164
|
+
}
|
165
|
+
|
166
|
+
/** Remove a Magix event listener. */
|
167
|
+
public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(this.manager.displayer) as MagixEventRemoveListener<TMagixEventPayloads>
|
123
168
|
}
|
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;
|
@@ -65,16 +61,13 @@ export class AppListeners {
|
|
65
61
|
this.manager.room?.refreshViewSize();
|
66
62
|
};
|
67
63
|
|
68
|
-
private switchViewsToFreedomHandler = () => {
|
69
|
-
this.manager.viewManager.freedomAllViews();
|
70
|
-
};
|
71
|
-
|
72
64
|
private boxStateChangeHandler = (state: TeleBoxState) => {
|
73
65
|
callbacks.emit("boxStateChange", state);
|
74
66
|
}
|
75
67
|
|
76
68
|
private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {
|
77
69
|
setViewFocusScenePath(this.manager.mainView, nextScenePath);
|
70
|
+
callbacks.emit("mainViewScenePathChange", nextScenePath);
|
78
71
|
}
|
79
72
|
|
80
73
|
private moveCameraToContainHandler = (payload: any) => {
|
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,6 +29,9 @@ 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({
|
@@ -37,19 +39,18 @@ export class AppManager {
|
|
37
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
|
-
|
49
|
-
});
|
48
|
+
this.refresher = reconnectRefresher;
|
49
|
+
this.refresher.setRoom(this.room);
|
50
|
+
this.refresher.setContext({ emitter });
|
50
51
|
|
51
52
|
emitter.once("onCreated").then(() => this.onCreated());
|
52
|
-
|
53
|
+
emitter.on("onReconnected", () => this.onReconnected());
|
53
54
|
if (isPlayer(this.displayer)) {
|
54
55
|
emitter.on("seek", time => {
|
55
56
|
this.appProxies.forEach(appProxy => {
|
@@ -97,6 +98,24 @@ export class AppManager {
|
|
97
98
|
}
|
98
99
|
});
|
99
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
|
+
})
|
100
119
|
if (!this.attributes.apps || Object.keys(this.attributes.apps).length === 0) {
|
101
120
|
const mainScenePath = this.store.getMainViewScenePath();
|
102
121
|
if (!mainScenePath) return;
|
@@ -107,6 +126,7 @@ export class AppManager {
|
|
107
126
|
}
|
108
127
|
this.displayerWritableListener(!this.room?.isWritable);
|
109
128
|
this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
|
129
|
+
this._prevFocused = this.attributes.focus;
|
110
130
|
}
|
111
131
|
|
112
132
|
/**
|
@@ -187,15 +207,18 @@ export class AppManager {
|
|
187
207
|
mainView.disableCameraTransform = disableCameraTransform;
|
188
208
|
mainView.divElement = divElement;
|
189
209
|
if (!mainView.focusScenePath) {
|
190
|
-
this.
|
191
|
-
}
|
192
|
-
if (this.store.focus === undefined && mainView.mode !== ViewVisionMode.Writable) {
|
193
|
-
this.viewManager.switchMainViewToWriter();
|
210
|
+
this.setMainViewFocusPath();
|
194
211
|
}
|
195
|
-
this.mainViewProxy.addMainViewListener();
|
196
212
|
emitter.emit("mainViewMounted");
|
197
213
|
}
|
198
214
|
|
215
|
+
public setMainViewFocusPath() {
|
216
|
+
const scenePath = this.store.getMainViewScenePath();
|
217
|
+
if (scenePath) {
|
218
|
+
setViewFocusScenePath(this.mainView, scenePath);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
199
222
|
public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {
|
200
223
|
log("addApp", params);
|
201
224
|
const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);
|
@@ -281,7 +304,7 @@ export class AppManager {
|
|
281
304
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
282
305
|
};
|
283
306
|
|
284
|
-
|
307
|
+
public displayerWritableListener = (isReadonly: boolean) => {
|
285
308
|
const isWritable = !isReadonly;
|
286
309
|
const isManualWritable =
|
287
310
|
this.windowManger.readonly === undefined || this.windowManger.readonly === false;
|
@@ -294,10 +317,10 @@ export class AppManager {
|
|
294
317
|
appProxy.emitAppIsWritableChange();
|
295
318
|
});
|
296
319
|
if (isWritable === true) {
|
297
|
-
if (!this.store.focus) {
|
298
|
-
this.mainViewProxy.switchViewModeToWriter();
|
299
|
-
}
|
300
320
|
this.mainView.disableCameraTransform = false;
|
321
|
+
if (this.room && this.room.disableSerialization === true) {
|
322
|
+
this.room.disableSerialization = false;
|
323
|
+
}
|
301
324
|
} else {
|
302
325
|
this.mainView.disableCameraTransform = true;
|
303
326
|
}
|
@@ -346,15 +369,16 @@ export class AppManager {
|
|
346
369
|
await this._setMainViewScenePath(scenePath);
|
347
370
|
} else if (scenePathType === ScenePathType.Dir) {
|
348
371
|
const validScenePath = makeValidScenePath(this.displayer, scenePath);
|
349
|
-
|
372
|
+
if (validScenePath) {
|
373
|
+
await this._setMainViewScenePath(validScenePath);
|
374
|
+
}
|
350
375
|
}
|
351
376
|
}
|
352
377
|
}
|
353
378
|
|
354
379
|
private async _setMainViewScenePath(scenePath: string) {
|
355
380
|
this.safeSetAttributes({ _mainScenePath: scenePath });
|
356
|
-
|
357
|
-
setScenePath(this.room, scenePath);
|
381
|
+
this.setMainViewFocusPath();
|
358
382
|
this.store.setMainViewFocusPath(this.mainView);
|
359
383
|
this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
|
360
384
|
}
|
@@ -362,12 +386,20 @@ export class AppManager {
|
|
362
386
|
public async setMainViewSceneIndex(index: number) {
|
363
387
|
if (this.room) {
|
364
388
|
this.safeSetAttributes({ _mainSceneIndex: index });
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
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
|
+
}
|
371
403
|
}
|
372
404
|
}
|
373
405
|
|
@@ -433,7 +465,7 @@ export class AppManager {
|
|
433
465
|
}
|
434
466
|
}
|
435
467
|
|
436
|
-
public async
|
468
|
+
public async onReconnected() {
|
437
469
|
const appProxies = Array.from(this.appProxies.values());
|
438
470
|
const reconnected = appProxies.map(appProxy => {
|
439
471
|
return appProxy.onReconnected();
|
@@ -470,5 +502,6 @@ export class AppManager {
|
|
470
502
|
this.refresher?.destroy();
|
471
503
|
this.mainViewProxy.destroy();
|
472
504
|
callbacks.clearListeners();
|
505
|
+
this._prevSceneIndex = undefined;
|
473
506
|
}
|
474
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,7 +32,6 @@ 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";
|
@@ -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
|
|
@@ -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,
|
@@ -145,6 +145,11 @@ export class BoxManager {
|
|
145
145
|
this.teleBoxManager.events.on("z_index", box => {
|
146
146
|
this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
|
147
147
|
});
|
148
|
+
emitter.on("playgroundSizeChange", this.playgroundSizeChangeListener);
|
149
|
+
}
|
150
|
+
|
151
|
+
private playgroundSizeChangeListener = () => {
|
152
|
+
this.updateManagerRect();
|
148
153
|
}
|
149
154
|
|
150
155
|
private get mainView() {
|
@@ -251,12 +256,8 @@ export class BoxManager {
|
|
251
256
|
}
|
252
257
|
|
253
258
|
public setCollectorContainer(container: HTMLElement) {
|
254
|
-
const styles = {
|
255
|
-
...DEFAULT_COLLECTOR_STYLE,
|
256
|
-
...this.createTeleBoxManagerConfig?.collectorStyles,
|
257
|
-
};
|
258
259
|
const collector = new TeleBoxCollector({
|
259
|
-
styles
|
260
|
+
styles: this.createTeleBoxManagerConfig?.collectorStyles,
|
260
261
|
}).mount(container);
|
261
262
|
this.teleBoxManager.setCollector(collector);
|
262
263
|
}
|
@@ -391,6 +392,7 @@ export class BoxManager {
|
|
391
392
|
}
|
392
393
|
|
393
394
|
public destroy() {
|
395
|
+
emitter.off("playgroundSizeChange", this.playgroundSizeChangeListener);
|
394
396
|
this.teleBoxManager.destroy();
|
395
397
|
}
|
396
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
|
+
};
|