@netless/window-manager 0.4.0-canary.2 → 0.4.0-canary.20
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 +6 -5
- 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 +141 -63
- package/src/AppProxy.ts +50 -52
- 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 +33 -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 +1 -1
- 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,17 +2,22 @@ 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";
|
@@ -20,7 +25,6 @@ import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "
|
|
20
25
|
|
21
26
|
export class AppManager {
|
22
27
|
public displayer: Displayer;
|
23
|
-
public cameraStore: CameraStore;
|
24
28
|
public viewManager: ViewManager;
|
25
29
|
public appProxies: Map<string, AppProxy> = new Map();
|
26
30
|
public appStatus: Map<string, AppStatus> = new Map();
|
@@ -32,6 +36,9 @@ export class AppManager {
|
|
32
36
|
private appListeners: AppListeners;
|
33
37
|
public boxManager?: BoxManager;
|
34
38
|
|
39
|
+
private _prevSceneIndex: number | undefined;
|
40
|
+
private _prevFocused: string | undefined;
|
41
|
+
|
35
42
|
constructor(public windowManger: WindowManager) {
|
36
43
|
this.displayer = windowManger.displayer;
|
37
44
|
this.store.setContext({
|
@@ -39,9 +46,8 @@ export class AppManager {
|
|
39
46
|
safeSetAttributes: attributes => this.safeSetAttributes(attributes),
|
40
47
|
safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),
|
41
48
|
});
|
42
|
-
this.cameraStore = new CameraStore();
|
43
49
|
this.mainViewProxy = new MainViewProxy(this);
|
44
|
-
this.viewManager = new ViewManager(this);
|
50
|
+
this.viewManager = new ViewManager(this.displayer);
|
45
51
|
this.appListeners = new AppListeners(this);
|
46
52
|
this.displayer.callbacks.on(this.eventName, this.displayerStateListener);
|
47
53
|
this.appListeners.addListeners();
|
@@ -61,6 +67,48 @@ export class AppManager {
|
|
61
67
|
this.onAppDelete(this.attributes.apps);
|
62
68
|
});
|
63
69
|
}
|
70
|
+
emitter.on("removeScenes", scenePath => {
|
71
|
+
if (scenePath === "/") {
|
72
|
+
this.setMainViewScenePath("/");
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
const mainViewScenePath = this.store.getMainViewScenePath();
|
76
|
+
if (this.room && mainViewScenePath) {
|
77
|
+
if (mainViewScenePath === scenePath) {
|
78
|
+
this.setMainViewScenePath("/");
|
79
|
+
}
|
80
|
+
}
|
81
|
+
});
|
82
|
+
}
|
83
|
+
|
84
|
+
private get eventName() {
|
85
|
+
return isRoom(this.displayer) ? "onRoomStateChanged" : "onPlayerStateChanged";
|
86
|
+
}
|
87
|
+
|
88
|
+
public get attributes() {
|
89
|
+
return this.windowManger.attributes;
|
90
|
+
}
|
91
|
+
|
92
|
+
public get canOperate() {
|
93
|
+
return this.windowManger.canOperate;
|
94
|
+
}
|
95
|
+
|
96
|
+
public get room() {
|
97
|
+
return isRoom(this.displayer) ? (this.displayer as Room) : undefined;
|
98
|
+
}
|
99
|
+
|
100
|
+
public get mainView() {
|
101
|
+
return this.mainViewProxy.view;
|
102
|
+
}
|
103
|
+
|
104
|
+
public get focusApp() {
|
105
|
+
if (this.store.focus) {
|
106
|
+
return this.appProxies.get(this.store.focus);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
public get uid() {
|
111
|
+
return this.room?.uid || "";
|
64
112
|
}
|
65
113
|
|
66
114
|
private async onCreated() {
|
@@ -99,6 +147,25 @@ export class AppManager {
|
|
99
147
|
}
|
100
148
|
});
|
101
149
|
});
|
150
|
+
this.refresher?.add("mainViewIndex", () => {
|
151
|
+
return autorun(() => {
|
152
|
+
const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
|
153
|
+
if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {
|
154
|
+
callbacks.emit("mainViewSceneIndexChange", mainSceneIndex);
|
155
|
+
this._prevSceneIndex = mainSceneIndex;
|
156
|
+
}
|
157
|
+
});
|
158
|
+
});
|
159
|
+
this.refresher?.add("focusedChange", () => {
|
160
|
+
return autorun(() => {
|
161
|
+
const focused = get(this.attributes, "focus");
|
162
|
+
if (this._prevFocused !== focused) {
|
163
|
+
this.boxManager?.focusBox({ appId: focused });
|
164
|
+
callbacks.emit("focusedChange", focused);
|
165
|
+
this._prevFocused = focused;
|
166
|
+
}
|
167
|
+
});
|
168
|
+
});
|
102
169
|
if (!this.attributes.apps || Object.keys(this.attributes.apps).length === 0) {
|
103
170
|
const mainScenePath = this.store.getMainViewScenePath();
|
104
171
|
if (!mainScenePath) return;
|
@@ -109,6 +176,7 @@ export class AppManager {
|
|
109
176
|
}
|
110
177
|
this.displayerWritableListener(!this.room?.isWritable);
|
111
178
|
this.displayer.callbacks.on("onEnableWriteNowChanged", this.displayerWritableListener);
|
179
|
+
this._prevFocused = this.attributes.focus;
|
112
180
|
}
|
113
181
|
|
114
182
|
/**
|
@@ -189,15 +257,19 @@ export class AppManager {
|
|
189
257
|
mainView.disableCameraTransform = disableCameraTransform;
|
190
258
|
mainView.divElement = divElement;
|
191
259
|
if (!mainView.focusScenePath) {
|
192
|
-
this.
|
193
|
-
}
|
194
|
-
if (this.store.focus === undefined && mainView.mode !== ViewVisionMode.Writable) {
|
195
|
-
this.viewManager.switchMainViewToWriter();
|
260
|
+
this.setMainViewFocusPath();
|
196
261
|
}
|
197
|
-
this.mainViewProxy.addMainViewListener();
|
198
262
|
emitter.emit("mainViewMounted");
|
199
263
|
}
|
200
264
|
|
265
|
+
public setMainViewFocusPath(scenePath?: string) {
|
266
|
+
const focusScenePath = scenePath || this.store.getMainViewScenePath();
|
267
|
+
if (focusScenePath) {
|
268
|
+
const view = setViewFocusScenePath(this.mainView, focusScenePath);
|
269
|
+
return view?.focusScenePath === focusScenePath;
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
201
273
|
public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {
|
202
274
|
log("addApp", params);
|
203
275
|
const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);
|
@@ -273,17 +345,13 @@ export class AppManager {
|
|
273
345
|
}
|
274
346
|
});
|
275
347
|
}
|
276
|
-
if (state.roomMembers) {
|
277
|
-
this.windowManger.cursorManager?.setRoomMembers(state.roomMembers);
|
278
|
-
this.windowManger.cursorManager?.cleanMemberAttributes(state.roomMembers);
|
279
|
-
}
|
280
348
|
this.appProxies.forEach(appProxy => {
|
281
349
|
appProxy.appEmitter.emit("roomStateChange", state);
|
282
350
|
});
|
283
351
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
284
352
|
};
|
285
353
|
|
286
|
-
|
354
|
+
public displayerWritableListener = (isReadonly: boolean) => {
|
287
355
|
const isWritable = !isReadonly;
|
288
356
|
const isManualWritable =
|
289
357
|
this.windowManger.readonly === undefined || this.windowManger.readonly === false;
|
@@ -296,41 +364,15 @@ export class AppManager {
|
|
296
364
|
appProxy.emitAppIsWritableChange();
|
297
365
|
});
|
298
366
|
if (isWritable === true) {
|
299
|
-
if (!this.store.focus) {
|
300
|
-
this.mainViewProxy.switchViewModeToWriter();
|
301
|
-
}
|
302
367
|
this.mainView.disableCameraTransform = false;
|
368
|
+
if (this.room && this.room.disableSerialization === true) {
|
369
|
+
this.room.disableSerialization = false;
|
370
|
+
}
|
303
371
|
} else {
|
304
372
|
this.mainView.disableCameraTransform = true;
|
305
373
|
}
|
306
374
|
};
|
307
375
|
|
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
376
|
public safeSetAttributes(attributes: any) {
|
335
377
|
this.windowManger.safeSetAttributes(attributes);
|
336
378
|
}
|
@@ -348,28 +390,57 @@ export class AppManager {
|
|
348
390
|
await this._setMainViewScenePath(scenePath);
|
349
391
|
} else if (scenePathType === ScenePathType.Dir) {
|
350
392
|
const validScenePath = makeValidScenePath(this.displayer, scenePath);
|
351
|
-
|
393
|
+
if (validScenePath) {
|
394
|
+
await this._setMainViewScenePath(validScenePath);
|
395
|
+
}
|
352
396
|
}
|
353
397
|
}
|
354
398
|
}
|
355
399
|
|
356
400
|
private async _setMainViewScenePath(scenePath: string) {
|
357
|
-
this.
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
401
|
+
const success = this.setMainViewFocusPath(scenePath);
|
402
|
+
if (success) {
|
403
|
+
this.safeSetAttributes({ _mainScenePath: scenePath });
|
404
|
+
this.store.setMainViewFocusPath(this.mainView);
|
405
|
+
this.updateSceneIndex();
|
406
|
+
this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
|
407
|
+
}
|
362
408
|
}
|
363
409
|
|
410
|
+
private updateSceneIndex = () => {
|
411
|
+
const scenePath = this.store.getMainViewScenePath() as string;
|
412
|
+
const sceneDir = parseSceneDir(scenePath);
|
413
|
+
const scenes = entireScenes(this.displayer)[sceneDir];
|
414
|
+
if (scenes.length) {
|
415
|
+
// "/ppt3/1" -> "1"
|
416
|
+
const pageName = scenePath.replace(sceneDir, "").replace("/", "");
|
417
|
+
const index = scenes.findIndex(scene => scene.name === pageName);
|
418
|
+
if (isInteger(index) && index >= 0) {
|
419
|
+
this.safeSetAttributes({ _mainSceneIndex: index });
|
420
|
+
}
|
421
|
+
}
|
422
|
+
};
|
423
|
+
|
364
424
|
public async setMainViewSceneIndex(index: number) {
|
365
425
|
if (this.room) {
|
366
|
-
this.
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
426
|
+
if (this.store.getMainViewSceneIndex() === index) return;
|
427
|
+
const mainViewScenePath = this.store.getMainViewScenePath() as string;
|
428
|
+
if (mainViewScenePath) {
|
429
|
+
const sceneDir = parseSceneDir(mainViewScenePath);
|
430
|
+
const scenePath = makeValidScenePath(this.displayer, sceneDir, index);
|
431
|
+
if (scenePath) {
|
432
|
+
const success = this.setMainViewFocusPath(scenePath);
|
433
|
+
if (success) {
|
434
|
+
this.store.setMainViewScenePath(scenePath);
|
435
|
+
this.safeSetAttributes({ _mainSceneIndex: index });
|
436
|
+
this.dispatchInternalEvent(Events.SetMainViewScenePath, {
|
437
|
+
nextScenePath: scenePath,
|
438
|
+
});
|
439
|
+
}
|
440
|
+
} else {
|
441
|
+
throw new Error(`[WindowManager]: ${sceneDir}: ${index} not valid index`);
|
442
|
+
}
|
443
|
+
}
|
373
444
|
}
|
374
445
|
}
|
375
446
|
|
@@ -440,6 +511,7 @@ export class AppManager {
|
|
440
511
|
const reconnected = appProxies.map(appProxy => {
|
441
512
|
return appProxy.onReconnected();
|
442
513
|
});
|
514
|
+
this.mainViewProxy.onReconnect();
|
443
515
|
await Promise.all(reconnected);
|
444
516
|
}
|
445
517
|
|
@@ -456,6 +528,11 @@ export class AppManager {
|
|
456
528
|
});
|
457
529
|
}
|
458
530
|
|
531
|
+
public findMemberByUid = (uid: string) => {
|
532
|
+
const roomMembers = this.room?.state.roomMembers;
|
533
|
+
return roomMembers?.find(member => member.payload?.uid === uid);
|
534
|
+
};
|
535
|
+
|
459
536
|
public destroy() {
|
460
537
|
this.displayer.callbacks.off(this.eventName, this.displayerStateListener);
|
461
538
|
this.displayer.callbacks.off("onEnableWriteNowChanged", this.displayerWritableListener);
|
@@ -472,5 +549,6 @@ export class AppManager {
|
|
472
549
|
this.refresher?.destroy();
|
473
550
|
this.mainViewProxy.destroy();
|
474
551
|
callbacks.clearListeners();
|
552
|
+
this._prevSceneIndex = undefined;
|
475
553
|
}
|
476
554
|
}
|