@netless/window-manager 0.4.0-canary.0 → 0.4.0-canary.4
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/AppListener.d.ts +1 -0
- package/dist/AppManager.d.ts +2 -2
- package/dist/AppProxy.d.ts +1 -1
- package/dist/Cursor/Cursor.d.ts +2 -3
- package/dist/Cursor/index.d.ts +7 -4
- package/dist/MainView.d.ts +1 -0
- package/dist/ReconnectRefresher.d.ts +8 -3
- package/dist/constants.d.ts +2 -1
- package/dist/index.d.ts +8 -6
- 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/package.json +3 -2
- package/src/AppListener.ts +8 -0
- package/src/AppManager.ts +13 -10
- package/src/AppProxy.ts +2 -2
- package/src/BoxManager.ts +0 -1
- package/src/Cursor/Cursor.ts +23 -34
- package/src/Cursor/index.ts +70 -41
- package/src/MainView.ts +11 -3
- package/src/ReconnectRefresher.ts +16 -4
- package/src/constants.ts +1 -0
- package/src/index.ts +55 -49
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@netless/window-manager",
|
3
|
-
"version": "0.4.0-canary.
|
3
|
+
"version": "0.4.0-canary.4",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.es.js",
|
6
6
|
"module": "dist/index.es.js",
|
@@ -22,12 +22,13 @@
|
|
22
22
|
},
|
23
23
|
"dependencies": {
|
24
24
|
"@juggle/resize-observer": "^3.3.1",
|
25
|
-
"@netless/app-docs-viewer": "0.
|
25
|
+
"@netless/app-docs-viewer": "0.2.0",
|
26
26
|
"@netless/app-media-player": "0.1.0-beta.5",
|
27
27
|
"@netless/telebox-insider": "0.2.17",
|
28
28
|
"emittery": "^0.9.2",
|
29
29
|
"lodash": "^4.17.21",
|
30
30
|
"p-retry": "^4.6.1",
|
31
|
+
"side-effect-manager": "^0.1.5",
|
31
32
|
"uuid": "^7.0.3",
|
32
33
|
"video.js": ">=7"
|
33
34
|
},
|
package/src/AppListener.ts
CHANGED
@@ -46,6 +46,10 @@ export class AppListeners {
|
|
46
46
|
this.setMainViewScenePathHandler(data.payload);
|
47
47
|
break;
|
48
48
|
}
|
49
|
+
case Events.MoveCameraToContain: {
|
50
|
+
this.moveCameraToContainHandler(data.payload);
|
51
|
+
break;
|
52
|
+
}
|
49
53
|
default:
|
50
54
|
break;
|
51
55
|
}
|
@@ -72,4 +76,8 @@ export class AppListeners {
|
|
72
76
|
private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {
|
73
77
|
setViewFocusScenePath(this.manager.mainView, nextScenePath);
|
74
78
|
}
|
79
|
+
|
80
|
+
private moveCameraToContainHandler = (payload: any) => {
|
81
|
+
this.manager.mainView.moveCameraToContain(payload);
|
82
|
+
}
|
75
83
|
}
|
package/src/AppManager.ts
CHANGED
@@ -1,21 +1,22 @@
|
|
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 { store } from "./AttributesDelegate";
|
7
5
|
import { autorun, isPlayer, isRoom, ScenePathType, ViewVisionMode } from "white-web-sdk";
|
8
|
-
import { callbacks, emitter, WindowManager } from "./index";
|
6
|
+
import { callbacks, emitter, WindowManager, reconnectRefresher } from "./index";
|
9
7
|
import { CameraStore } from "./Utils/CameraStore";
|
10
8
|
import { genAppId, makeValidScenePath, setScenePath } from "./Utils/Common";
|
11
9
|
import { log } from "./Utils/log";
|
12
10
|
import { MainViewProxy } from "./MainView";
|
13
11
|
import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
|
14
|
-
import {
|
12
|
+
import { sortBy } from "lodash";
|
13
|
+
import { store } from "./AttributesDelegate";
|
15
14
|
import { ViewManager } from "./ViewManager";
|
15
|
+
import type { ReconnectRefresher } from "./ReconnectRefresher";
|
16
16
|
import type { BoxManager } from "./BoxManager";
|
17
17
|
import type { Displayer, DisplayerState, Room } from "white-web-sdk";
|
18
18
|
import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "./index";
|
19
|
+
|
19
20
|
export class AppManager {
|
20
21
|
public displayer: Displayer;
|
21
22
|
public cameraStore: CameraStore;
|
@@ -34,7 +35,7 @@ export class AppManager {
|
|
34
35
|
this.displayer = windowManger.displayer;
|
35
36
|
this.store.setContext({
|
36
37
|
getAttributes: () => this.attributes,
|
37
|
-
safeSetAttributes:
|
38
|
+
safeSetAttributes: attributes => this.safeSetAttributes(attributes),
|
38
39
|
safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),
|
39
40
|
});
|
40
41
|
this.cameraStore = new CameraStore();
|
@@ -44,10 +45,12 @@ export class AppManager {
|
|
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 => {
|
@@ -116,11 +119,11 @@ export class AppManager {
|
|
116
119
|
public async attributesUpdateCallback(apps: any) {
|
117
120
|
if (apps && WindowManager.container) {
|
118
121
|
const appIds = Object.keys(apps);
|
119
|
-
const appsWithCreatedAt = appIds.map(appId =>
|
122
|
+
const appsWithCreatedAt = appIds.map(appId => {
|
120
123
|
return {
|
121
124
|
id: appId,
|
122
125
|
createdAt: apps[appId].createdAt,
|
123
|
-
}
|
126
|
+
};
|
124
127
|
});
|
125
128
|
for (const { id } of sortBy(appsWithCreatedAt, "createdAt")) {
|
126
129
|
if (!this.appProxies.has(id) && !this.appStatus.has(id)) {
|
@@ -431,7 +434,7 @@ export class AppManager {
|
|
431
434
|
}
|
432
435
|
}
|
433
436
|
|
434
|
-
public async
|
437
|
+
public async onReconnected() {
|
435
438
|
const appProxies = Array.from(this.appProxies.values());
|
436
439
|
const reconnected = appProxies.map(appProxy => {
|
437
440
|
return appProxy.onReconnected();
|
package/src/AppProxy.ts
CHANGED
@@ -42,7 +42,7 @@ export class AppProxy extends Base {
|
|
42
42
|
public isAddApp: boolean;
|
43
43
|
private status: "normal" | "destroyed" = "normal";
|
44
44
|
private stateKey: string;
|
45
|
-
private
|
45
|
+
private appResult?: NetlessApp<any>;
|
46
46
|
private appContext?: AppContext<any, any>;
|
47
47
|
|
48
48
|
constructor(
|
@@ -171,7 +171,7 @@ export class AppProxy extends Base {
|
|
171
171
|
setTimeout(async () => {
|
172
172
|
// 延迟执行 setup, 防止初始化的属性没有更新成功
|
173
173
|
const result = await app.setup(context);
|
174
|
-
this.
|
174
|
+
this.appResult = result;
|
175
175
|
appRegister.notifyApp(app.kind, "created", { appId, result });
|
176
176
|
this.afterSetupApp(boxInitState);
|
177
177
|
this.fixMobileSize();
|
package/src/BoxManager.ts
CHANGED
@@ -143,7 +143,6 @@ 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
|
});
|
149
148
|
}
|
package/src/Cursor/Cursor.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import App from './Cursor.svelte';
|
2
|
-
import pRetry from 'p-retry';
|
3
2
|
import { ApplianceMap } from './icons';
|
4
|
-
import { ApplianceNames
|
3
|
+
import { ApplianceNames } from 'white-web-sdk';
|
5
4
|
import { CursorState } from '../constants';
|
6
5
|
import { Fields } from '../AttributesDelegate';
|
7
6
|
import { get, omit } from 'lodash';
|
@@ -19,54 +18,44 @@ export type Payload = {
|
|
19
18
|
|
20
19
|
export class Cursor extends Base {
|
21
20
|
private member?: RoomMember;
|
22
|
-
private disposer: any;
|
23
21
|
private timer?: number;
|
24
22
|
private component?: SvelteComponent;
|
25
23
|
|
26
24
|
constructor(
|
27
25
|
manager: AppManager,
|
26
|
+
addCursorChangeListener: (uid: string, callback: (position: Position, state: CursorState) => void) => void,
|
28
27
|
private cursors: any,
|
29
28
|
private memberId: string,
|
30
29
|
private cursorManager: CursorManager,
|
31
|
-
private wrapper?: HTMLElement
|
30
|
+
private wrapper?: HTMLElement,
|
32
31
|
) {
|
33
32
|
super(manager);
|
34
33
|
this.setMember();
|
35
34
|
this.createCursor();
|
36
|
-
|
37
|
-
this.disposer && this.disposer();
|
38
|
-
if (!this.cursorPosition) {
|
39
|
-
console.warn(`${memberId} not exist`);
|
40
|
-
}
|
41
|
-
this.startReaction();
|
42
|
-
}, { retries: 3 });
|
35
|
+
addCursorChangeListener(this.memberId, this.onCursorChange);
|
43
36
|
this.autoHidden();
|
44
37
|
}
|
45
38
|
|
46
|
-
private
|
47
|
-
|
48
|
-
const
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
const rect = this.cursorManager.wrapperRect;
|
53
|
-
if (this.component && rect) {
|
54
|
-
this.autoHidden();
|
55
|
-
this.moveCursor(cursor, rect, this.manager.mainView);
|
56
|
-
}
|
57
|
-
} else {
|
58
|
-
const focusView = this.cursorManager.focusView;
|
59
|
-
const viewRect = focusView?.divElement?.getBoundingClientRect();
|
60
|
-
const viewCamera = focusView?.camera;
|
61
|
-
if (focusView && viewRect && viewCamera && this.component) {
|
62
|
-
this.autoHidden();
|
63
|
-
this.moveCursor(cursor, viewRect, focusView);
|
64
|
-
}
|
39
|
+
private onCursorChange = (position: Position, state: CursorState) => {
|
40
|
+
if (position.type === "main") {
|
41
|
+
const rect = this.cursorManager.wrapperRect;
|
42
|
+
if (this.component && rect) {
|
43
|
+
this.autoHidden();
|
44
|
+
this.moveCursor(position, rect, this.manager.mainView);
|
65
45
|
}
|
66
|
-
|
67
|
-
|
46
|
+
} else {
|
47
|
+
const focusView = this.cursorManager.focusView;
|
48
|
+
// TODO 可以存一个当前 focusView 的 Rect 这样只有 focus 切换的时候才调用 getBoundingClientRect
|
49
|
+
const viewRect = focusView?.divElement?.getBoundingClientRect();
|
50
|
+
const viewCamera = focusView?.camera;
|
51
|
+
if (focusView && viewRect && viewCamera && this.component) {
|
52
|
+
this.autoHidden();
|
53
|
+
this.moveCursor(position, viewRect, focusView);
|
68
54
|
}
|
69
|
-
}
|
55
|
+
}
|
56
|
+
if (state && state === CursorState.Leave) {
|
57
|
+
this.hide();
|
58
|
+
}
|
70
59
|
}
|
71
60
|
|
72
61
|
private moveCursor(cursor: Position, rect: DOMRect, view: any) {
|
@@ -196,10 +185,10 @@ export class Cursor extends Base {
|
|
196
185
|
}
|
197
186
|
|
198
187
|
public destroy() {
|
199
|
-
this.disposer && this.disposer();
|
200
188
|
if (this.component) {
|
201
189
|
this.component.$destroy();
|
202
190
|
}
|
191
|
+
this.manager.refresher?.remove(this.memberId);
|
203
192
|
this.cursorManager.cursorInstances.delete(this.memberId);
|
204
193
|
}
|
205
194
|
|
package/src/Cursor/index.ts
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import {
|
8
|
-
import
|
1
|
+
import { autorun } from "white-web-sdk";
|
2
|
+
import { Base } from "../Base";
|
3
|
+
import { compact, debounce, get, uniq } from "lodash";
|
4
|
+
import { Cursor } from "./Cursor";
|
5
|
+
import { CursorState } from "../constants";
|
6
|
+
import { emitter, WindowManager } from "../index";
|
7
|
+
import { Fields } from "../AttributesDelegate";
|
8
|
+
import { onObjectInserted } from "../Utils/Reactive";
|
9
|
+
import { SideEffectManager } from "side-effect-manager";
|
10
|
+
import type { PositionType, Position } from "../AttributesDelegate";
|
9
11
|
import type { Point, RoomMember, View } from "white-web-sdk";
|
10
12
|
import type { AppManager } from "../AppManager";
|
11
13
|
|
@@ -18,32 +20,42 @@ export type MoveCursorParams = {
|
|
18
20
|
uid: string;
|
19
21
|
x: number;
|
20
22
|
y: number;
|
21
|
-
}
|
23
|
+
};
|
22
24
|
export class CursorManager extends Base {
|
23
25
|
public containerRect?: DOMRect;
|
24
26
|
public wrapperRect?: DOMRect;
|
25
27
|
public cursorInstances: Map<string, Cursor> = new Map();
|
26
28
|
public roomMembers?: readonly RoomMember[];
|
27
29
|
private mainViewElement?: HTMLDivElement;
|
30
|
+
private sideEffectManager = new SideEffectManager();
|
28
31
|
|
29
32
|
constructor(private appManager: AppManager) {
|
30
33
|
super(appManager);
|
31
34
|
this.roomMembers = this.appManager.room?.state.roomMembers;
|
32
35
|
const wrapper = WindowManager.wrapper;
|
33
36
|
if (wrapper) {
|
34
|
-
|
37
|
+
this.setupWrapper(wrapper);
|
35
38
|
}
|
39
|
+
emitter.on("onReconnected", () => {
|
40
|
+
this.onReconnect();
|
41
|
+
});
|
36
42
|
}
|
37
43
|
|
38
44
|
public setupWrapper(wrapper: HTMLElement) {
|
39
45
|
if (this.manager.refresher?.hasReactor("cursors")) {
|
40
46
|
this.destroy();
|
41
47
|
}
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
48
|
+
this.sideEffectManager.add(() => {
|
49
|
+
wrapper.addEventListener("pointerenter", this.mouseMoveListener);
|
50
|
+
wrapper.addEventListener("pointermove", this.mouseMoveListener);
|
51
|
+
wrapper.addEventListener("pointerleave", this.mouseLeaveListener);
|
52
|
+
return () => {
|
53
|
+
wrapper.removeEventListener("pointerenter", this.mouseMoveListener);
|
54
|
+
wrapper.removeEventListener("pointermove", this.mouseMoveListener);
|
55
|
+
wrapper.removeEventListener("pointerleave", this.mouseLeaveListener);
|
56
|
+
};
|
57
|
+
});
|
58
|
+
|
47
59
|
this.initCursorAttributes();
|
48
60
|
this.wrapperRect = wrapper.getBoundingClientRect();
|
49
61
|
this.startReaction(wrapper);
|
@@ -58,27 +70,25 @@ export class CursorManager extends Base {
|
|
58
70
|
return onObjectInserted(this.cursors, () => {
|
59
71
|
this.handleRoomMembersChange(wrapper);
|
60
72
|
});
|
61
|
-
})
|
73
|
+
});
|
62
74
|
}
|
63
75
|
|
64
76
|
private getUids = (members: readonly RoomMember[] | undefined) => {
|
65
77
|
return compact(uniq(members?.map(member => member.payload?.uid)));
|
66
|
-
}
|
78
|
+
};
|
67
79
|
|
68
80
|
private handleRoomMembersChange = debounce((wrapper: HTMLElement) => {
|
69
81
|
const uids = this.getUids(this.roomMembers);
|
70
82
|
const cursors = Object.keys(this.cursors);
|
71
83
|
if (uids?.length) {
|
72
84
|
cursors.map(uid => {
|
73
|
-
if (
|
74
|
-
uids.includes(uid) &&
|
75
|
-
!this.cursorInstances.has(uid)
|
76
|
-
) {
|
85
|
+
if (uids.includes(uid) && !this.cursorInstances.has(uid)) {
|
77
86
|
if (uid === this.context.uid) {
|
78
87
|
return;
|
79
88
|
}
|
80
89
|
const component = new Cursor(
|
81
90
|
this.appManager,
|
91
|
+
this.addCursorChangeListener,
|
82
92
|
this.cursors,
|
83
93
|
uid,
|
84
94
|
this,
|
@@ -86,7 +96,7 @@ export class CursorManager extends Base {
|
|
86
96
|
);
|
87
97
|
this.cursorInstances.set(uid, component);
|
88
98
|
}
|
89
|
-
})
|
99
|
+
});
|
90
100
|
}
|
91
101
|
}, 100);
|
92
102
|
|
@@ -106,13 +116,6 @@ export class CursorManager extends Base {
|
|
106
116
|
this.updateCursor(this.getType(event), event.clientX, event.clientY);
|
107
117
|
}, 5);
|
108
118
|
|
109
|
-
private touchMoveListener = debounce((event: TouchEvent) => {
|
110
|
-
if (event.touches.length === 1) {
|
111
|
-
const touchEvent = event.touches[0];
|
112
|
-
this.updateCursor(this.getType(touchEvent), touchEvent.clientX, touchEvent.clientY);
|
113
|
-
}
|
114
|
-
}, 5);
|
115
|
-
|
116
119
|
private updateCursor(event: EventType, clientX: number, clientY: number) {
|
117
120
|
if (this.wrapperRect && this.manager.canOperate) {
|
118
121
|
const view = event.type === "main" ? this.appManager.mainView : this.focusView;
|
@@ -128,7 +131,11 @@ export class CursorManager extends Base {
|
|
128
131
|
}
|
129
132
|
}
|
130
133
|
|
131
|
-
private getPoint = (
|
134
|
+
private getPoint = (
|
135
|
+
view: View | undefined,
|
136
|
+
clientX: number,
|
137
|
+
clientY: number
|
138
|
+
): Point | undefined => {
|
132
139
|
const rect = view?.divElement?.getBoundingClientRect();
|
133
140
|
if (rect) {
|
134
141
|
const point = view?.convertToPointInWorld({
|
@@ -137,7 +144,7 @@ export class CursorManager extends Base {
|
|
137
144
|
});
|
138
145
|
return point;
|
139
146
|
}
|
140
|
-
}
|
147
|
+
};
|
141
148
|
|
142
149
|
/**
|
143
150
|
* 因为窗口内框在不同分辨率下的大小不一样,所以这里通过来鼠标事件的 target 来判断是在主白板还是在 APP 中
|
@@ -147,7 +154,7 @@ export class CursorManager extends Base {
|
|
147
154
|
const focusApp = this.appManager.focusApp;
|
148
155
|
switch (target.parentElement) {
|
149
156
|
case this.mainViewElement: {
|
150
|
-
return { type: "main" };
|
157
|
+
return { type: "main" };
|
151
158
|
}
|
152
159
|
case focusApp?.view?.divElement: {
|
153
160
|
return { type: "app" };
|
@@ -224,19 +231,41 @@ export class CursorManager extends Base {
|
|
224
231
|
});
|
225
232
|
}
|
226
233
|
|
227
|
-
public
|
228
|
-
const wrapper = WindowManager.wrapper;
|
229
|
-
if (wrapper) {
|
230
|
-
wrapper.removeEventListener("mousemove", this.mouseMoveListener);
|
231
|
-
wrapper.removeEventListener("touchstart", this.touchMoveListener);
|
232
|
-
wrapper.removeEventListener("touchmove", this.touchMoveListener);
|
233
|
-
wrapper.removeEventListener("mouseleave", this.mouseLeaveListener);
|
234
|
-
wrapper.removeEventListener("touchend", this.mouseLeaveListener);
|
235
|
-
}
|
234
|
+
public onReconnect() {
|
236
235
|
if (this.cursorInstances.size) {
|
237
236
|
this.cursorInstances.forEach(cursor => cursor.destroy());
|
238
237
|
this.cursorInstances.clear();
|
239
238
|
}
|
239
|
+
this.roomMembers = this.appManager.room?.state.roomMembers;
|
240
|
+
if (WindowManager.wrapper) {
|
241
|
+
this.handleRoomMembersChange(WindowManager.wrapper);
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
public addCursorChangeListener = (
|
246
|
+
uid: string,
|
247
|
+
callback: (position: Position, state: CursorState) => void
|
248
|
+
) => {
|
249
|
+
this.manager.refresher?.add(uid, () => {
|
250
|
+
const disposer = autorun(() => {
|
251
|
+
const position = get(this.cursors, [uid, Fields.Position]);
|
252
|
+
const state = get(this.cursors, [uid, Fields.CursorState]);
|
253
|
+
if (position) {
|
254
|
+
callback(position, state);
|
255
|
+
}
|
256
|
+
});
|
257
|
+
return disposer;
|
258
|
+
});
|
259
|
+
};
|
260
|
+
|
261
|
+
public destroy() {
|
262
|
+
this.sideEffectManager.flushAll();
|
263
|
+
if (this.cursorInstances.size) {
|
264
|
+
this.cursorInstances.forEach(cursor => {
|
265
|
+
cursor.destroy();
|
266
|
+
});
|
267
|
+
this.cursorInstances.clear();
|
268
|
+
}
|
240
269
|
this.manager.refresher?.remove("cursors");
|
241
270
|
}
|
242
271
|
}
|
package/src/MainView.ts
CHANGED
@@ -5,6 +5,7 @@ import { createView } from "./ViewManager";
|
|
5
5
|
import { debounce, isEmpty, isEqual } from "lodash";
|
6
6
|
import { Fields } from "./AttributesDelegate";
|
7
7
|
import { notifyMainViewModeChange, setViewFocusScenePath, setViewMode } from "./Utils/Common";
|
8
|
+
import { SideEffectManager } from "side-effect-manager";
|
8
9
|
import type { Camera, Size, View } from "white-web-sdk";
|
9
10
|
import type { AppManager } from "./AppManager";
|
10
11
|
|
@@ -16,6 +17,8 @@ export class MainViewProxy extends Base {
|
|
16
17
|
private mainView: View;
|
17
18
|
private viewId = "mainView";
|
18
19
|
|
20
|
+
private sideEffectManager = new SideEffectManager();
|
21
|
+
|
19
22
|
constructor(manager: AppManager) {
|
20
23
|
super(manager);
|
21
24
|
this.mainView = this.createMainView();
|
@@ -29,8 +32,12 @@ export class MainViewProxy extends Base {
|
|
29
32
|
}
|
30
33
|
}, 200); // 等待 mainView 挂载完毕再进行监听,否则会触发不必要的 onSizeUpdated
|
31
34
|
});
|
32
|
-
|
35
|
+
const playgroundSizeChangeListener = () => {
|
33
36
|
this.sizeChangeHandler(this.mainViewSize);
|
37
|
+
}
|
38
|
+
this.sideEffectManager.add(() => {
|
39
|
+
emitter.on("playgroundSizeChange", playgroundSizeChangeListener);
|
40
|
+
return () => emitter.off("playgroundSizeChange", playgroundSizeChangeListener);
|
34
41
|
});
|
35
42
|
}
|
36
43
|
|
@@ -75,7 +82,7 @@ export class MainViewProxy extends Base {
|
|
75
82
|
);
|
76
83
|
};
|
77
84
|
|
78
|
-
private sizeChangeHandler =
|
85
|
+
private sizeChangeHandler = debounce((size: Size) => {
|
79
86
|
if (size) {
|
80
87
|
this.moveCameraToContian(size);
|
81
88
|
this.moveCamera(this.mainViewCamera);
|
@@ -104,7 +111,7 @@ export class MainViewProxy extends Base {
|
|
104
111
|
|
105
112
|
private onCameraUpdatedByDevice = (camera: Camera) => {
|
106
113
|
this.store.setMainViewCamera({ ...camera, id: this.context.uid });
|
107
|
-
if (!isEqual(this.mainViewSize, {...this.mainView.size, id: this.context.uid})) {
|
114
|
+
if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.context.uid })) {
|
108
115
|
this.setMainViewSize(this.view.size);
|
109
116
|
}
|
110
117
|
};
|
@@ -204,5 +211,6 @@ export class MainViewProxy extends Base {
|
|
204
211
|
public destroy() {
|
205
212
|
this.stop();
|
206
213
|
this.cameraStore.unregister(this.viewId, this.mainView);
|
214
|
+
this.sideEffectManager.flushAll();
|
207
215
|
}
|
208
216
|
}
|
@@ -1,8 +1,13 @@
|
|
1
|
-
import {
|
1
|
+
import { debounce, isFunction } from "lodash";
|
2
|
+
import { emitter } from "./index";
|
2
3
|
import { log } from "./Utils/log";
|
3
4
|
import { RoomPhase } from "white-web-sdk";
|
4
5
|
import type { Room } from "white-web-sdk";
|
5
|
-
import type {
|
6
|
+
import type { EmitterType } from "./index";
|
7
|
+
|
8
|
+
export type ReconnectRefresherContext = {
|
9
|
+
emitter: EmitterType;
|
10
|
+
};
|
6
11
|
|
7
12
|
// 白板重连之后会刷新所有的对象,导致 listener 失效, 所以这里在重连之后重新对所有对象进行监听
|
8
13
|
export class ReconnectRefresher {
|
@@ -11,12 +16,19 @@ export class ReconnectRefresher {
|
|
11
16
|
private reactors: Map<string, any> = new Map();
|
12
17
|
private disposers: Map<string, any> = new Map();
|
13
18
|
|
14
|
-
constructor(
|
19
|
+
constructor(private ctx: ReconnectRefresherContext) {}
|
20
|
+
|
21
|
+
public setRoom(room: Room | undefined) {
|
15
22
|
this.room = room;
|
16
23
|
this.phase = room?.phase;
|
24
|
+
room?.callbacks.off("onPhaseChanged", this.onPhaseChanged);
|
17
25
|
room?.callbacks.on("onPhaseChanged", this.onPhaseChanged);
|
18
26
|
}
|
19
27
|
|
28
|
+
public setContext(ctx: ReconnectRefresherContext) {
|
29
|
+
this.ctx = ctx;
|
30
|
+
}
|
31
|
+
|
20
32
|
private onPhaseChanged = (phase: RoomPhase) => {
|
21
33
|
if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
|
22
34
|
this.onReconnected();
|
@@ -32,7 +44,7 @@ export class ReconnectRefresher {
|
|
32
44
|
this.disposers.set(id, func());
|
33
45
|
}
|
34
46
|
});
|
35
|
-
this.
|
47
|
+
this.ctx.emitter.emit("onReconnected", undefined);
|
36
48
|
}, 3000);
|
37
49
|
|
38
50
|
private releaseDisposers() {
|
package/src/constants.ts
CHANGED
@@ -10,6 +10,7 @@ export enum Events {
|
|
10
10
|
SetMainViewScenePath = "SetMainViewScenePath",
|
11
11
|
SetMainViewSceneIndex = "SetMainViewSceneIndex",
|
12
12
|
SwitchViewsToFreedom = "SwitchViewsToFreedom",
|
13
|
+
MoveCameraToContain = "MoveCameraToContain"
|
13
14
|
}
|
14
15
|
|
15
16
|
export const MagixEventName = "__WindowManger";
|