@netless/window-manager 0.4.0-canary.2 → 0.4.0-canary.23
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/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/window-manager.iml +12 -0
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +29 -1
- package/README.md +1 -0
- 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 +39 -0
- package/dist/App/Storage/typings.d.ts +22 -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 +15 -11
- package/dist/AppProxy.d.ts +7 -6
- package/dist/AttributesDelegate.d.ts +2 -2
- package/dist/BoxManager.d.ts +6 -3
- package/dist/BuiltinApps.d.ts +5 -0
- package/dist/ContainerResizeObserver.d.ts +10 -0
- package/dist/Cursor/Cursor.d.ts +8 -11
- package/dist/Cursor/index.d.ts +5 -16
- package/dist/Helper.d.ts +6 -0
- package/dist/ReconnectRefresher.d.ts +0 -1
- package/dist/Register/storage.d.ts +5 -1
- package/dist/Utils/Common.d.ts +7 -2
- package/dist/Utils/Reactive.d.ts +1 -1
- package/dist/Utils/RoomHacker.d.ts +1 -1
- package/dist/{MainView.d.ts → View/MainView.d.ts} +5 -6
- package/dist/View/ViewManager.d.ts +13 -0
- package/dist/constants.d.ts +3 -7
- package/dist/index.d.ts +25 -10
- package/dist/index.es.js +41 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +41 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/typings.d.ts +3 -2
- package/docs/api.md +36 -6
- package/docs/concept.md +9 -0
- package/package.json +7 -6
- package/src/App/MagixEvent/index.ts +68 -0
- package/src/App/Storage/StorageEvent.ts +21 -0
- package/src/App/Storage/index.ts +289 -0
- package/src/App/Storage/typings.ts +23 -0
- package/src/App/Storage/utils.ts +17 -0
- package/src/AppContext.ts +66 -24
- package/src/AppListener.ts +15 -14
- package/src/AppManager.ts +146 -63
- package/src/AppProxy.ts +52 -53
- package/src/AttributesDelegate.ts +2 -2
- package/src/BoxManager.ts +40 -24
- package/src/BuiltinApps.ts +23 -0
- package/src/ContainerResizeObserver.ts +62 -0
- package/src/Cursor/Cursor.ts +22 -36
- package/src/Cursor/index.ts +39 -139
- package/src/Helper.ts +30 -0
- package/src/ReconnectRefresher.ts +0 -5
- package/src/Register/index.ts +25 -16
- package/src/Register/loader.ts +2 -2
- package/src/Register/storage.ts +6 -1
- package/src/Utils/Common.ts +66 -13
- package/src/Utils/Reactive.ts +9 -3
- package/src/Utils/RoomHacker.ts +42 -13
- package/src/{MainView.ts → View/MainView.ts} +25 -36
- package/src/View/ViewManager.ts +52 -0
- package/src/constants.ts +3 -4
- package/src/index.ts +96 -72
- package/src/shim.d.ts +5 -0
- package/src/style.css +7 -1
- package/src/typings.ts +3 -2
- package/vite.config.js +8 -2
- package/dist/Base/Context.d.ts +0 -13
- package/dist/Base/index.d.ts +0 -7
- package/dist/Utils/CameraStore.d.ts +0 -15
- package/dist/ViewManager.d.ts +0 -29
- package/dist/sdk.d.ts +0 -14
- package/src/Base/Context.ts +0 -49
- package/src/Base/index.ts +0 -10
- 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,45 +41,45 @@ 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
|
-
|
60
|
-
if (appProxy) {
|
61
|
-
return appProxy.scenes;
|
62
|
-
}
|
62
|
+
return this.appProxy.scenes;
|
63
63
|
} else {
|
64
64
|
return appAttr?.options["scenes"];
|
65
65
|
}
|
66
66
|
}
|
67
67
|
|
68
|
-
public getView(): View | undefined {
|
68
|
+
public getView = (): View | undefined => {
|
69
69
|
return this.appProxy.view;
|
70
70
|
}
|
71
71
|
|
72
|
-
public getInitScenePath() {
|
72
|
+
public getInitScenePath = () => {
|
73
73
|
return this.manager.getAppInitPath(this.appId);
|
74
74
|
}
|
75
75
|
|
76
|
-
|
76
|
+
/** Get App writable status. */
|
77
|
+
public getIsWritable = (): boolean => {
|
77
78
|
return this.manager.canOperate;
|
78
79
|
}
|
79
80
|
|
80
|
-
|
81
|
+
/** Get the App Window UI box. */
|
82
|
+
public getBox = (): ReadonlyTeleBox => {
|
81
83
|
const box = this.boxManager.getBox(this.appId);
|
82
84
|
if (box) {
|
83
85
|
return box;
|
@@ -86,27 +88,30 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
|
|
86
88
|
}
|
87
89
|
}
|
88
90
|
|
89
|
-
public getRoom(): Room | undefined {
|
91
|
+
public getRoom = (): Room | undefined => {
|
90
92
|
return this.manager.room;
|
91
93
|
}
|
92
94
|
|
93
|
-
|
95
|
+
/** @deprecated Use context.storage.setState instead. */
|
96
|
+
public setAttributes = (attributes: TAttributes) => {
|
94
97
|
this.manager.safeSetAttributes({ [this.appId]: attributes });
|
95
98
|
}
|
96
99
|
|
97
|
-
|
100
|
+
/** @deprecated Use context.storage.setState instead. */
|
101
|
+
public updateAttributes = (keys: string[], value: any) => {
|
98
102
|
if (this.manager.attributes[this.appId]) {
|
99
103
|
this.manager.safeUpdateAttributes([this.appId, ...keys], value);
|
100
104
|
}
|
101
105
|
}
|
102
106
|
|
103
|
-
public async
|
107
|
+
public setScenePath = async (scenePath: string): Promise<void> => {
|
104
108
|
if (!this.appProxy.box) return;
|
105
109
|
this.appProxy.setFullPath(scenePath);
|
106
|
-
|
110
|
+
// 兼容 15 版本 SDK 的切页
|
111
|
+
this.getRoom()?.setScenePath(scenePath);
|
107
112
|
}
|
108
113
|
|
109
|
-
public mountView(dom: HTMLDivElement): void {
|
114
|
+
public mountView = (dom: HTMLDivElement): void => {
|
110
115
|
const view = this.getView();
|
111
116
|
if (view) {
|
112
117
|
view.divElement = dom;
|
@@ -117,7 +122,44 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
|
|
117
122
|
}
|
118
123
|
}
|
119
124
|
|
120
|
-
|
121
|
-
|
125
|
+
/** Get the local App options. */
|
126
|
+
public getAppOptions = (): TAppOptions | undefined => {
|
127
|
+
return typeof this.appOptions === 'function' ? (this.appOptions as () => TAppOptions)() : this.appOptions
|
122
128
|
}
|
129
|
+
|
130
|
+
private _storage?: Storage<TAttributes>
|
131
|
+
|
132
|
+
/** Main Storage for attributes. */
|
133
|
+
public get storage(): Storage<TAttributes> {
|
134
|
+
if (!this._storage) {
|
135
|
+
this._storage = new Storage(this);
|
136
|
+
}
|
137
|
+
return this._storage;
|
138
|
+
}
|
139
|
+
|
140
|
+
/**
|
141
|
+
* Create separated storages for flexible state management.
|
142
|
+
* @param storeId Namespace for the storage. Storages of the same namespace share the same data.
|
143
|
+
* @param defaultState Default state for initial storage creation.
|
144
|
+
* @returns
|
145
|
+
*/
|
146
|
+
public createStorage = <TState>(storeId: string, defaultState?: TState): Storage<TState> => {
|
147
|
+
const storage = new Storage(this, storeId, defaultState);
|
148
|
+
this.emitter.on("destroy", () => {
|
149
|
+
storage.destroy();
|
150
|
+
});
|
151
|
+
return storage;
|
152
|
+
}
|
153
|
+
|
154
|
+
/** Dispatch events to other clients (and self). */
|
155
|
+
public dispatchMagixEvent: MagixEventDispatcher<TMagixEventPayloads> = (this.manager.displayer as Room).dispatchMagixEvent.bind(this.manager.displayer)
|
156
|
+
|
157
|
+
/** Listen to events from others clients (and self messages). */
|
158
|
+
public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = (event, handler, options) => {
|
159
|
+
this.manager.displayer.addMagixEventListener(event, handler as WhiteEventListener, options);
|
160
|
+
return () => this.manager.displayer.removeMagixEventListener(event, handler as WhiteEventListener);
|
161
|
+
}
|
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
@@ -1,9 +1,9 @@
|
|
1
|
-
import { callbacks } from
|
2
|
-
import { Events, MagixEventName } from
|
1
|
+
import { callbacks, emitter } from "./index";
|
2
|
+
import { Events, MagixEventName } from "./constants";
|
3
|
+
import { setViewFocusScenePath } from "./Utils/Common";
|
3
4
|
import type { Event } from "white-web-sdk";
|
4
5
|
import type { AppManager } from "./AppManager";
|
5
6
|
import type { TeleBoxState } from "@netless/telebox-insider";
|
6
|
-
import { setViewFocusScenePath } from './Utils/Common';
|
7
7
|
|
8
8
|
export class AppListeners {
|
9
9
|
private displayer = this.manager.displayer;
|
@@ -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;
|
@@ -50,6 +46,10 @@ export class AppListeners {
|
|
50
46
|
this.moveCameraToContainHandler(data.payload);
|
51
47
|
break;
|
52
48
|
}
|
49
|
+
case Events.CursorMove: {
|
50
|
+
this.cursorMoveHandler(data.payload);
|
51
|
+
break;
|
52
|
+
}
|
53
53
|
default:
|
54
54
|
break;
|
55
55
|
}
|
@@ -65,19 +65,20 @@ export class AppListeners {
|
|
65
65
|
this.manager.room?.refreshViewSize();
|
66
66
|
};
|
67
67
|
|
68
|
-
private switchViewsToFreedomHandler = () => {
|
69
|
-
this.manager.viewManager.freedomAllViews();
|
70
|
-
};
|
71
|
-
|
72
68
|
private boxStateChangeHandler = (state: TeleBoxState) => {
|
73
69
|
callbacks.emit("boxStateChange", state);
|
74
|
-
}
|
70
|
+
};
|
75
71
|
|
76
72
|
private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {
|
77
73
|
setViewFocusScenePath(this.manager.mainView, nextScenePath);
|
78
|
-
|
74
|
+
callbacks.emit("mainViewScenePathChange", nextScenePath);
|
75
|
+
};
|
79
76
|
|
80
77
|
private moveCameraToContainHandler = (payload: any) => {
|
81
78
|
this.manager.mainView.moveCameraToContain(payload);
|
82
|
-
}
|
79
|
+
};
|
80
|
+
|
81
|
+
private cursorMoveHandler = (payload: any) => {
|
82
|
+
emitter.emit("cursorMove", payload);
|
83
|
+
};
|
83
84
|
}
|
package/src/AppManager.ts
CHANGED
@@ -2,25 +2,30 @@ import pRetry from "p-retry";
|
|
2
2
|
import { AppAttributes, AppStatus, Events, MagixEventName } from "./constants";
|
3
3
|
import { AppListeners } from "./AppListener";
|
4
4
|
import { AppProxy } from "./AppProxy";
|
5
|
-
import { autorun, isPlayer, isRoom, ScenePathType
|
6
|
-
import { callbacks, emitter, WindowManager } from "./index";
|
7
|
-
import {
|
8
|
-
|
5
|
+
import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
|
6
|
+
import { callbacks, emitter, WindowManager, reconnectRefresher } from "./index";
|
7
|
+
import {
|
8
|
+
entireScenes,
|
9
|
+
genAppId,
|
10
|
+
makeValidScenePath,
|
11
|
+
parseSceneDir,
|
12
|
+
setScenePath,
|
13
|
+
setViewFocusScenePath,
|
14
|
+
} from "./Utils/Common";
|
9
15
|
import { log } from "./Utils/log";
|
10
|
-
import { MainViewProxy } from "./MainView";
|
16
|
+
import { MainViewProxy } from "./View/MainView";
|
11
17
|
import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
|
12
|
-
import {
|
13
|
-
import { sortBy } from "lodash";
|
18
|
+
import { get, isInteger, sortBy } from "lodash";
|
14
19
|
import { store } from "./AttributesDelegate";
|
15
|
-
import { ViewManager } from "./ViewManager";
|
20
|
+
import { ViewManager } from "./View/ViewManager";
|
16
21
|
import type { ReconnectRefresher } from "./ReconnectRefresher";
|
17
22
|
import type { BoxManager } from "./BoxManager";
|
18
23
|
import type { Displayer, DisplayerState, Room } from "white-web-sdk";
|
19
24
|
import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "./index";
|
25
|
+
import { appRegister } from "./Register";
|
20
26
|
|
21
27
|
export class AppManager {
|
22
28
|
public displayer: Displayer;
|
23
|
-
public cameraStore: CameraStore;
|
24
29
|
public viewManager: ViewManager;
|
25
30
|
public appProxies: Map<string, AppProxy> = new Map();
|
26
31
|
public appStatus: Map<string, AppStatus> = new Map();
|
@@ -32,6 +37,9 @@ export class AppManager {
|
|
32
37
|
private appListeners: AppListeners;
|
33
38
|
public boxManager?: BoxManager;
|
34
39
|
|
40
|
+
private _prevSceneIndex: number | undefined;
|
41
|
+
private _prevFocused: string | undefined;
|
42
|
+
|
35
43
|
constructor(public windowManger: WindowManager) {
|
36
44
|
this.displayer = windowManger.displayer;
|
37
45
|
this.store.setContext({
|
@@ -39,9 +47,8 @@ export class AppManager {
|
|
39
47
|
safeSetAttributes: attributes => this.safeSetAttributes(attributes),
|
40
48
|
safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),
|
41
49
|
});
|
42
|
-
this.cameraStore = new CameraStore();
|
43
50
|
this.mainViewProxy = new MainViewProxy(this);
|
44
|
-
this.viewManager = new ViewManager(this);
|
51
|
+
this.viewManager = new ViewManager(this.displayer);
|
45
52
|
this.appListeners = new AppListeners(this);
|
46
53
|
this.displayer.callbacks.on(this.eventName, this.displayerStateListener);
|
47
54
|
this.appListeners.addListeners();
|
@@ -61,6 +68,48 @@ export class AppManager {
|
|
61
68
|
this.onAppDelete(this.attributes.apps);
|
62
69
|
});
|
63
70
|
}
|
71
|
+
emitter.on("removeScenes", scenePath => {
|
72
|
+
if (scenePath === "/") {
|
73
|
+
this.setMainViewScenePath("/");
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
const mainViewScenePath = this.store.getMainViewScenePath();
|
77
|
+
if (this.room && mainViewScenePath) {
|
78
|
+
if (mainViewScenePath === scenePath) {
|
79
|
+
this.setMainViewScenePath("/");
|
80
|
+
}
|
81
|
+
}
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
private get eventName() {
|
86
|
+
return isRoom(this.displayer) ? "onRoomStateChanged" : "onPlayerStateChanged";
|
87
|
+
}
|
88
|
+
|
89
|
+
public get attributes() {
|
90
|
+
return this.windowManger.attributes;
|
91
|
+
}
|
92
|
+
|
93
|
+
public get canOperate() {
|
94
|
+
return this.windowManger.canOperate;
|
95
|
+
}
|
96
|
+
|
97
|
+
public get room() {
|
98
|
+
return isRoom(this.displayer) ? (this.displayer as Room) : undefined;
|
99
|
+
}
|
100
|
+
|
101
|
+
public get mainView() {
|
102
|
+
return this.mainViewProxy.view;
|
103
|
+
}
|
104
|
+
|
105
|
+
public get focusApp() {
|
106
|
+
if (this.store.focus) {
|
107
|
+
return this.appProxies.get(this.store.focus);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
public get uid() {
|
112
|
+
return this.room?.uid || "";
|
64
113
|
}
|
65
114
|
|
66
115
|
private async onCreated() {
|
@@ -99,6 +148,25 @@ export class AppManager {
|
|
99
148
|
}
|
100
149
|
});
|
101
150
|
});
|
151
|
+
this.refresher?.add("mainViewIndex", () => {
|
152
|
+
return autorun(() => {
|
153
|
+
const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
|
154
|
+
if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {
|
155
|
+
callbacks.emit("mainViewSceneIndexChange", mainSceneIndex);
|
156
|
+
this._prevSceneIndex = mainSceneIndex;
|
157
|
+
}
|
158
|
+
});
|
159
|
+
});
|
160
|
+
this.refresher?.add("focusedChange", () => {
|
161
|
+
return autorun(() => {
|
162
|
+
const focused = get(this.attributes, "focus");
|
163
|
+
if (this._prevFocused !== focused) {
|
164
|
+
this.boxManager?.focusBox({ appId: focused });
|
165
|
+
callbacks.emit("focusedChange", focused);
|
166
|
+
this._prevFocused = focused;
|
167
|
+
}
|
168
|
+
});
|
169
|
+
});
|
102
170
|
if (!this.attributes.apps || Object.keys(this.attributes.apps).length === 0) {
|
103
171
|
const mainScenePath = this.store.getMainViewScenePath();
|
104
172
|
if (!mainScenePath) return;
|
@@ -109,6 +177,7 @@ export class AppManager {
|
|
109
177
|
}
|
110
178
|
this.displayerWritableListener(!this.room?.isWritable);
|
111
179
|
this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
|
180
|
+
this._prevFocused = this.attributes.focus;
|
112
181
|
}
|
113
182
|
|
114
183
|
/**
|
@@ -189,15 +258,19 @@ export class AppManager {
|
|
189
258
|
mainView.disableCameraTransform = disableCameraTransform;
|
190
259
|
mainView.divElement = divElement;
|
191
260
|
if (!mainView.focusScenePath) {
|
192
|
-
this.
|
193
|
-
}
|
194
|
-
if (this.store.focus === undefined && mainView.mode !== ViewVisionMode.Writable) {
|
195
|
-
this.viewManager.switchMainViewToWriter();
|
261
|
+
this.setMainViewFocusPath();
|
196
262
|
}
|
197
|
-
this.mainViewProxy.addMainViewListener();
|
198
263
|
emitter.emit("mainViewMounted");
|
199
264
|
}
|
200
265
|
|
266
|
+
public setMainViewFocusPath(scenePath?: string) {
|
267
|
+
const focusScenePath = scenePath || this.store.getMainViewScenePath();
|
268
|
+
if (focusScenePath) {
|
269
|
+
const view = setViewFocusScenePath(this.mainView, focusScenePath);
|
270
|
+
return view?.focusScenePath === focusScenePath;
|
271
|
+
}
|
272
|
+
}
|
273
|
+
|
201
274
|
public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {
|
202
275
|
log("addApp", params);
|
203
276
|
const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);
|
@@ -273,17 +346,13 @@ export class AppManager {
|
|
273
346
|
}
|
274
347
|
});
|
275
348
|
}
|
276
|
-
if (state.roomMembers) {
|
277
|
-
this.windowManger.cursorManager?.setRoomMembers(state.roomMembers);
|
278
|
-
this.windowManger.cursorManager?.cleanMemberAttributes(state.roomMembers);
|
279
|
-
}
|
280
349
|
this.appProxies.forEach(appProxy => {
|
281
350
|
appProxy.appEmitter.emit("roomStateChange", state);
|
282
351
|
});
|
283
352
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
284
353
|
};
|
285
354
|
|
286
|
-
|
355
|
+
public displayerWritableListener = (isReadonly: boolean) => {
|
287
356
|
const isWritable = !isReadonly;
|
288
357
|
const isManualWritable =
|
289
358
|
this.windowManger.readonly === undefined || this.windowManger.readonly === false;
|
@@ -296,41 +365,15 @@ export class AppManager {
|
|
296
365
|
appProxy.emitAppIsWritableChange();
|
297
366
|
});
|
298
367
|
if (isWritable === true) {
|
299
|
-
if (!this.store.focus) {
|
300
|
-
this.mainViewProxy.switchViewModeToWriter();
|
301
|
-
}
|
302
368
|
this.mainView.disableCameraTransform = false;
|
369
|
+
if (this.room && this.room.disableSerialization === true) {
|
370
|
+
this.room.disableSerialization = false;
|
371
|
+
}
|
303
372
|
} else {
|
304
373
|
this.mainView.disableCameraTransform = true;
|
305
374
|
}
|
306
375
|
};
|
307
376
|
|
308
|
-
private get eventName() {
|
309
|
-
return isRoom(this.displayer) ? "onRoomStateChanged" : "onPlayerStateChanged";
|
310
|
-
}
|
311
|
-
|
312
|
-
public get attributes() {
|
313
|
-
return this.windowManger.attributes;
|
314
|
-
}
|
315
|
-
|
316
|
-
public get canOperate() {
|
317
|
-
return this.windowManger.canOperate;
|
318
|
-
}
|
319
|
-
|
320
|
-
public get room() {
|
321
|
-
return isRoom(this.displayer) ? (this.displayer as Room) : undefined;
|
322
|
-
}
|
323
|
-
|
324
|
-
public get mainView() {
|
325
|
-
return this.mainViewProxy.view;
|
326
|
-
}
|
327
|
-
|
328
|
-
public get focusApp() {
|
329
|
-
if (this.store.focus) {
|
330
|
-
return this.appProxies.get(this.store.focus);
|
331
|
-
}
|
332
|
-
}
|
333
|
-
|
334
377
|
public safeSetAttributes(attributes: any) {
|
335
378
|
this.windowManger.safeSetAttributes(attributes);
|
336
379
|
}
|
@@ -348,28 +391,57 @@ export class AppManager {
|
|
348
391
|
await this._setMainViewScenePath(scenePath);
|
349
392
|
} else if (scenePathType === ScenePathType.Dir) {
|
350
393
|
const validScenePath = makeValidScenePath(this.displayer, scenePath);
|
351
|
-
|
394
|
+
if (validScenePath) {
|
395
|
+
await this._setMainViewScenePath(validScenePath);
|
396
|
+
}
|
352
397
|
}
|
353
398
|
}
|
354
399
|
}
|
355
400
|
|
356
401
|
private async _setMainViewScenePath(scenePath: string) {
|
357
|
-
this.
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
402
|
+
const success = this.setMainViewFocusPath(scenePath);
|
403
|
+
if (success) {
|
404
|
+
this.safeSetAttributes({ _mainScenePath: scenePath });
|
405
|
+
this.store.setMainViewFocusPath(this.mainView);
|
406
|
+
this.updateSceneIndex();
|
407
|
+
this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
|
408
|
+
}
|
362
409
|
}
|
363
410
|
|
411
|
+
private updateSceneIndex = () => {
|
412
|
+
const scenePath = this.store.getMainViewScenePath() as string;
|
413
|
+
const sceneDir = parseSceneDir(scenePath);
|
414
|
+
const scenes = entireScenes(this.displayer)[sceneDir];
|
415
|
+
if (scenes.length) {
|
416
|
+
// "/ppt3/1" -> "1"
|
417
|
+
const pageName = scenePath.replace(sceneDir, "").replace("/", "");
|
418
|
+
const index = scenes.findIndex(scene => scene.name === pageName);
|
419
|
+
if (isInteger(index) && index >= 0) {
|
420
|
+
this.safeSetAttributes({ _mainSceneIndex: index });
|
421
|
+
}
|
422
|
+
}
|
423
|
+
};
|
424
|
+
|
364
425
|
public async setMainViewSceneIndex(index: number) {
|
365
426
|
if (this.room) {
|
366
|
-
this.
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
427
|
+
if (this.store.getMainViewSceneIndex() === index) return;
|
428
|
+
const mainViewScenePath = this.store.getMainViewScenePath() as string;
|
429
|
+
if (mainViewScenePath) {
|
430
|
+
const sceneDir = parseSceneDir(mainViewScenePath);
|
431
|
+
const scenePath = makeValidScenePath(this.displayer, sceneDir, index);
|
432
|
+
if (scenePath) {
|
433
|
+
const success = this.setMainViewFocusPath(scenePath);
|
434
|
+
if (success) {
|
435
|
+
this.store.setMainViewScenePath(scenePath);
|
436
|
+
this.safeSetAttributes({ _mainSceneIndex: index });
|
437
|
+
this.dispatchInternalEvent(Events.SetMainViewScenePath, {
|
438
|
+
nextScenePath: scenePath,
|
439
|
+
});
|
440
|
+
}
|
441
|
+
} else {
|
442
|
+
throw new Error(`[WindowManager]: ${sceneDir}: ${index} not valid index`);
|
443
|
+
}
|
444
|
+
}
|
373
445
|
}
|
374
446
|
}
|
375
447
|
|
@@ -398,6 +470,10 @@ export class AppManager {
|
|
398
470
|
}
|
399
471
|
case "focus": {
|
400
472
|
this.windowManger.safeSetAttributes({ focus: payload.appId });
|
473
|
+
const appProxy = this.appProxies.get(payload.appId);
|
474
|
+
if (appProxy) {
|
475
|
+
appRegister.notifyApp(appProxy.kind, "focus", { appId: payload.appId });
|
476
|
+
}
|
401
477
|
break;
|
402
478
|
}
|
403
479
|
case "resize": {
|
@@ -440,6 +516,7 @@ export class AppManager {
|
|
440
516
|
const reconnected = appProxies.map(appProxy => {
|
441
517
|
return appProxy.onReconnected();
|
442
518
|
});
|
519
|
+
this.mainViewProxy.onReconnect();
|
443
520
|
await Promise.all(reconnected);
|
444
521
|
}
|
445
522
|
|
@@ -456,6 +533,11 @@ export class AppManager {
|
|
456
533
|
});
|
457
534
|
}
|
458
535
|
|
536
|
+
public findMemberByUid = (uid: string) => {
|
537
|
+
const roomMembers = this.room?.state.roomMembers;
|
538
|
+
return roomMembers?.find(member => member.payload?.uid === uid);
|
539
|
+
};
|
540
|
+
|
459
541
|
public destroy() {
|
460
542
|
this.displayer.callbacks.off(this.eventName, this.displayerStateListener);
|
461
543
|
this.displayer.callbacks.off("onEnableWriteNowChanged", this.displayerWritableListener);
|
@@ -472,5 +554,6 @@ export class AppManager {
|
|
472
554
|
this.refresher?.destroy();
|
473
555
|
this.mainViewProxy.destroy();
|
474
556
|
callbacks.clearListeners();
|
557
|
+
this._prevSceneIndex = undefined;
|
475
558
|
}
|
476
559
|
}
|