@netless/window-manager 1.0.0-canary.2 → 1.0.0-canary.5
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/__mocks__/white-web-sdk.ts +10 -1
- package/dist/App/AppContext.d.ts +1 -1
- package/dist/App/AppProxy.d.ts +12 -1
- package/dist/App/AppViewSync.d.ts +11 -0
- package/dist/App/{WhiteBoardView.d.ts → WhiteboardView.d.ts} +6 -1
- package/dist/App/index.d.ts +1 -1
- package/dist/AppManager.d.ts +1 -1
- package/dist/AttributesDelegate.d.ts +6 -14
- package/dist/BoxManager.d.ts +1 -1
- package/dist/ReconnectRefresher.d.ts +1 -1
- package/dist/Utils/Common.d.ts +1 -0
- package/dist/View/CameraSynchronizer.d.ts +4 -4
- package/dist/View/ViewSync.d.ts +7 -0
- package/dist/index.cjs.js +12 -12
- package/dist/index.d.ts +3 -1
- package/dist/index.es.js +360 -201
- package/dist/index.umd.js +12 -12
- package/dist/style.css +1 -1
- package/docs/app-context.md +98 -64
- package/docs/develop-app.md +2 -5
- package/package.json +2 -2
- package/pnpm-lock.yaml +9 -5
- package/src/App/AppContext.ts +12 -4
- package/src/App/AppProxy.ts +76 -12
- package/src/App/AppViewSync.ts +69 -0
- package/src/App/{WhiteBoardView.ts → WhiteboardView.ts} +18 -1
- package/src/App/index.ts +1 -1
- package/src/AppManager.ts +1 -1
- package/src/AttributesDelegate.ts +14 -17
- package/src/BoxManager.ts +3 -2
- package/src/ReconnectRefresher.ts +1 -0
- package/src/Utils/Common.ts +6 -0
- package/src/View/CameraSynchronizer.ts +14 -8
- package/src/View/MainView.ts +9 -13
- package/src/View/ViewSync.ts +10 -0
- package/src/index.ts +3 -1
- package/src/style.css +9 -0
package/src/App/AppProxy.ts
CHANGED
@@ -3,12 +3,18 @@ import { AppAttributes, AppEvents, Events, SETUP_APP_DELAY } from "../constants"
|
|
3
3
|
import { AppContext } from "./AppContext";
|
4
4
|
import { AppPageStateImpl } from "./AppPageStateImpl";
|
5
5
|
import { appRegister } from "../Register";
|
6
|
-
import {
|
6
|
+
import { AppViewSync } from "./AppViewSync";
|
7
|
+
import { autorun, reaction, toJS } from "white-web-sdk";
|
8
|
+
import { boxEmitter } from "../BoxEmitter";
|
7
9
|
import { BoxManagerNotFoundError } from "../Utils/error";
|
10
|
+
import { calculateNextIndex } from "../Page";
|
11
|
+
import { combine, Val } from "value-enhancer";
|
8
12
|
import { debounce, get } from "lodash";
|
9
13
|
import { emitter } from "../InternalEmitter";
|
10
14
|
import { Fields } from "../AttributesDelegate";
|
11
15
|
import { log } from "../Utils/log";
|
16
|
+
import { SideEffectManager } from "side-effect-manager";
|
17
|
+
import type { ICamera, ISize } from "../AttributesDelegate";
|
12
18
|
import {
|
13
19
|
entireScenes,
|
14
20
|
getScenePath,
|
@@ -24,14 +30,11 @@ import type {
|
|
24
30
|
setAppOptions,
|
25
31
|
AppListenerKeys,
|
26
32
|
} from "../index";
|
27
|
-
import type { SceneState, View, SceneDefinition } from "white-web-sdk";
|
33
|
+
import type { SceneState, View, SceneDefinition, Camera } from "white-web-sdk";
|
28
34
|
import type { AppManager } from "../AppManager";
|
29
35
|
import type { NetlessApp } from "../typings";
|
30
36
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
31
37
|
import type { PageRemoveService, PageState } from "../Page";
|
32
|
-
import { calculateNextIndex } from "../Page";
|
33
|
-
import { boxEmitter } from "../BoxEmitter";
|
34
|
-
import { SideEffectManager } from "side-effect-manager";
|
35
38
|
|
36
39
|
export type AppEmitter = Emittery<AppEmitterEvent>;
|
37
40
|
|
@@ -48,6 +51,7 @@ export class AppProxy implements PageRemoveService {
|
|
48
51
|
private appProxies = this.manager.appProxies;
|
49
52
|
private viewManager = this.manager.viewManager;
|
50
53
|
private store = this.manager.store;
|
54
|
+
public uid = this.manager.uid;
|
51
55
|
|
52
56
|
public isAddApp: boolean;
|
53
57
|
private status: "normal" | "destroyed" = "normal";
|
@@ -60,6 +64,14 @@ export class AppProxy implements PageRemoveService {
|
|
60
64
|
|
61
65
|
private sideEffectManager = new SideEffectManager();
|
62
66
|
|
67
|
+
public camera$ = new Val<ICamera | undefined>(undefined);
|
68
|
+
public size$ = new Val<ISize | undefined>(undefined);
|
69
|
+
|
70
|
+
private appViewSync?: AppViewSync;
|
71
|
+
|
72
|
+
public box$ = new Val<ReadonlyTeleBox | undefined>(undefined);
|
73
|
+
public view$ = new Val<View | undefined>(undefined);
|
74
|
+
|
63
75
|
constructor(
|
64
76
|
private params: BaseInsertParams,
|
65
77
|
private manager: AppManager,
|
@@ -90,14 +102,45 @@ export class AppProxy implements PageRemoveService {
|
|
90
102
|
view: this.view,
|
91
103
|
notifyPageStateChange: this.notifyPageStateChange,
|
92
104
|
});
|
105
|
+
this.sideEffectManager.add(() => () => this._pageState.destroy());
|
106
|
+
this.sideEffectManager.add(() =>
|
107
|
+
emitter.on("roomMembersChange", members => {
|
108
|
+
this.appEmitter.emit("roomMembersChange", members);
|
109
|
+
})
|
110
|
+
);
|
111
|
+
this.camera$.setValue(toJS(this.appAttributes.camera));
|
112
|
+
this.size$.setValue(toJS(this.appAttributes.size));
|
93
113
|
this.sideEffectManager.add(() => {
|
94
|
-
return () =>
|
114
|
+
return this.manager.refresher.add(`${this.id}-camera`, () => {
|
115
|
+
return reaction(
|
116
|
+
() => this.appAttributes?.camera,
|
117
|
+
camera => {
|
118
|
+
if (camera && camera.id !== this.uid) {
|
119
|
+
this.camera$.setValue(toJS(camera));
|
120
|
+
}
|
121
|
+
}
|
122
|
+
);
|
123
|
+
});
|
95
124
|
});
|
96
125
|
this.sideEffectManager.add(() => {
|
97
|
-
return
|
98
|
-
|
126
|
+
return this.manager.refresher.add(`${this.id}-size`, () => {
|
127
|
+
return reaction(
|
128
|
+
() => this.appAttributes?.size,
|
129
|
+
size => {
|
130
|
+
if (size && size.id !== this.uid) {
|
131
|
+
this.size$.setValue(toJS(size));
|
132
|
+
}
|
133
|
+
}
|
134
|
+
);
|
99
135
|
});
|
100
136
|
});
|
137
|
+
combine([this.box$, this.view$]).subscribe(([box, view]) => {
|
138
|
+
if (box && view) {
|
139
|
+
const appViewSync = new AppViewSync(this);
|
140
|
+
this.appViewSync = appViewSync;
|
141
|
+
this.sideEffectManager.add(() => () => appViewSync.destroy());
|
142
|
+
}
|
143
|
+
});
|
101
144
|
}
|
102
145
|
|
103
146
|
public createAppDir() {
|
@@ -162,7 +205,7 @@ export class AppProxy implements PageRemoveService {
|
|
162
205
|
}
|
163
206
|
|
164
207
|
public setFullPath(path: string) {
|
165
|
-
this.
|
208
|
+
this.store.updateAppAttributes(this.id, Fields.FullPath, path);
|
166
209
|
}
|
167
210
|
|
168
211
|
public async baseInsertApp(skipUpdate = false): Promise<{ appId: string; app: NetlessApp }> {
|
@@ -191,7 +234,7 @@ export class AppProxy implements PageRemoveService {
|
|
191
234
|
}
|
192
235
|
|
193
236
|
public get box(): ReadonlyTeleBox | undefined {
|
194
|
-
return this.
|
237
|
+
return this.box$.value;
|
195
238
|
}
|
196
239
|
|
197
240
|
private async setupApp(
|
@@ -225,13 +268,14 @@ export class AppProxy implements PageRemoveService {
|
|
225
268
|
this.fixMobileSize();
|
226
269
|
}, SETUP_APP_DELAY);
|
227
270
|
});
|
228
|
-
this.boxManager?.createBox({
|
271
|
+
const box = this.boxManager?.createBox({
|
229
272
|
appId: appId,
|
230
273
|
app,
|
231
274
|
options,
|
232
275
|
canOperate: this.manager.canOperate,
|
233
276
|
smartPosition: this.isAddApp,
|
234
277
|
});
|
278
|
+
this.box$.setValue(box);
|
235
279
|
if (this.isAddApp && this.box) {
|
236
280
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
237
281
|
this.boxManager.focusBox({ appId }, false);
|
@@ -428,6 +472,7 @@ export class AppProxy implements PageRemoveService {
|
|
428
472
|
|
429
473
|
private createView(): View {
|
430
474
|
const view = this.viewManager.createView(this.id);
|
475
|
+
this.view$.setValue(view);
|
431
476
|
this.setViewFocusScenePath();
|
432
477
|
return view;
|
433
478
|
}
|
@@ -481,6 +526,22 @@ export class AppProxy implements PageRemoveService {
|
|
481
526
|
}
|
482
527
|
}
|
483
528
|
|
529
|
+
public storeCamera = (camera: ICamera) => {
|
530
|
+
this.store.updateAppAttributes(this.id, Fields.Camera, camera);
|
531
|
+
};
|
532
|
+
|
533
|
+
public storeSize = (size: ISize) => {
|
534
|
+
this.store.updateAppAttributes(this.id, Fields.Size, size);
|
535
|
+
};
|
536
|
+
|
537
|
+
public moveCamera = (camera: Camera) => {
|
538
|
+
if (!this.camera$.value) {
|
539
|
+
return;
|
540
|
+
}
|
541
|
+
const nextCamera = { ...this.camera$.value, ...camera };
|
542
|
+
this.storeCamera(nextCamera);
|
543
|
+
};
|
544
|
+
|
484
545
|
public async destroy(
|
485
546
|
needCloseBox: boolean,
|
486
547
|
cleanAttrs: boolean,
|
@@ -496,6 +557,7 @@ export class AppProxy implements PageRemoveService {
|
|
496
557
|
console.error("[WindowManager]: notifyApp error", error.message, error.stack);
|
497
558
|
}
|
498
559
|
this.appEmitter.clearListeners();
|
560
|
+
this.sideEffectManager.flushAll();
|
499
561
|
emitter.emit(`destroy-${this.id}` as any, { error });
|
500
562
|
if (needCloseBox) {
|
501
563
|
this.boxManager?.closeBox(this.id, skipUpdate);
|
@@ -514,7 +576,9 @@ export class AppProxy implements PageRemoveService {
|
|
514
576
|
this.manager.refresher?.remove(this.stateKey);
|
515
577
|
this.manager.refresher?.remove(`${this.id}-fullPath`);
|
516
578
|
this._prevFullPath = undefined;
|
517
|
-
this.
|
579
|
+
this.camera$.destroy();
|
580
|
+
this.size$.destroy();
|
581
|
+
this.box$.destroy();
|
518
582
|
}
|
519
583
|
|
520
584
|
public close(): Promise<void> {
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import { CameraSynchronizer } from "../View/CameraSynchronizer";
|
2
|
+
import { SideEffectManager } from "side-effect-manager";
|
3
|
+
import type { Camera, View } from "white-web-sdk";
|
4
|
+
import type { AppProxy } from "./AppProxy";
|
5
|
+
import { isEqual } from "lodash";
|
6
|
+
|
7
|
+
export class AppViewSync {
|
8
|
+
private sem = new SideEffectManager();
|
9
|
+
private synchronizer: CameraSynchronizer;
|
10
|
+
|
11
|
+
constructor(private appProxy: AppProxy) {
|
12
|
+
this.synchronizer = new CameraSynchronizer((camera: Camera) => {
|
13
|
+
this.appProxy.storeCamera({
|
14
|
+
id: this.appProxy.uid,
|
15
|
+
...camera,
|
16
|
+
});
|
17
|
+
});
|
18
|
+
this.bindView(appProxy.view);
|
19
|
+
this.sem.add(() => this.appProxy.camera$.subscribe(camera => {
|
20
|
+
const size = this.appProxy.size$.value;
|
21
|
+
if (camera && size) {
|
22
|
+
this.synchronizer.onRemoteUpdate(camera, size);
|
23
|
+
}
|
24
|
+
}));
|
25
|
+
const box = this.appProxy.box;
|
26
|
+
if (box && box.contentStageRect) {
|
27
|
+
this.synchronizer.setRect(box.contentStageRect);
|
28
|
+
this.sem.add(() =>
|
29
|
+
box._contentStageRect$.subscribe(rect => {
|
30
|
+
if (rect) {
|
31
|
+
this.synchronizer.setRect(rect);
|
32
|
+
}
|
33
|
+
}),
|
34
|
+
);
|
35
|
+
if (!this.appProxy.size$.value) {
|
36
|
+
this.appProxy.storeSize({
|
37
|
+
id: this.appProxy.uid,
|
38
|
+
width: box.contentStageRect.width,
|
39
|
+
height: box.contentStageRect.height,
|
40
|
+
});
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
public bindView = (view?: View) => {
|
46
|
+
if (!view) return;
|
47
|
+
this.synchronizer.setView(view);
|
48
|
+
this.sem.add(() => {
|
49
|
+
view.callbacks.on("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
|
50
|
+
return () =>
|
51
|
+
view.callbacks.off("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
|
52
|
+
});
|
53
|
+
};
|
54
|
+
|
55
|
+
private onCameraUpdatedByDevice = (camera: Camera) => {
|
56
|
+
this.synchronizer.onLocalCameraUpdate(camera);
|
57
|
+
const stage = this.appProxy.box?.contentStageRect;
|
58
|
+
if (stage) {
|
59
|
+
const size = { width: stage.width, height: stage.height, id: this.appProxy.uid };
|
60
|
+
if (!isEqual(size, this.appProxy.size$.value)) {
|
61
|
+
this.appProxy.storeSize(size);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
};
|
65
|
+
|
66
|
+
public destroy() {
|
67
|
+
this.sem.flushAll();
|
68
|
+
}
|
69
|
+
}
|
@@ -5,11 +5,16 @@ import type { ReadonlyVal } from "value-enhancer";
|
|
5
5
|
import type { AddPageParams, PageController, PageState } from "../Page";
|
6
6
|
import type { AppProxy } from "./AppProxy";
|
7
7
|
import type { AppContext } from "./AppContext";
|
8
|
+
import type { Camera } from "white-web-sdk";
|
8
9
|
|
9
10
|
export class WhiteBoardView implements PageController {
|
10
11
|
public readonly pageState$: ReadonlyVal<PageState>;
|
11
12
|
|
12
|
-
constructor(
|
13
|
+
constructor(
|
14
|
+
protected appContext: AppContext,
|
15
|
+
protected appProxy: AppProxy,
|
16
|
+
private removeViewWrapper: () => void
|
17
|
+
) {
|
13
18
|
const pageState$ = new Val<PageState>(appProxy.pageState);
|
14
19
|
this.pageState$ = pageState$;
|
15
20
|
appProxy.appEmitter.on("pageStateChange", pageState => {
|
@@ -17,10 +22,18 @@ export class WhiteBoardView implements PageController {
|
|
17
22
|
});
|
18
23
|
}
|
19
24
|
|
25
|
+
public get view() {
|
26
|
+
return this.appContext.view;
|
27
|
+
}
|
28
|
+
|
20
29
|
public get pageState() {
|
21
30
|
return this.pageState$.value;
|
22
31
|
}
|
23
32
|
|
33
|
+
public moveCamera(camera: Camera) {
|
34
|
+
this.appProxy.moveCamera(camera);
|
35
|
+
}
|
36
|
+
|
24
37
|
public nextPage = async (): Promise<boolean> => {
|
25
38
|
const nextIndex = this.pageState.index + 1;
|
26
39
|
return this.jumpPage(nextIndex);
|
@@ -65,4 +78,8 @@ export class WhiteBoardView implements PageController {
|
|
65
78
|
}
|
66
79
|
return this.appProxy.removeSceneByIndex(needRemoveIndex);
|
67
80
|
};
|
81
|
+
|
82
|
+
public destroy() {
|
83
|
+
this.removeViewWrapper();
|
84
|
+
}
|
68
85
|
}
|
package/src/App/index.ts
CHANGED
package/src/AppManager.ts
CHANGED
@@ -56,7 +56,7 @@ export class AppManager {
|
|
56
56
|
public appStatus: Map<string, AppStatus> = new Map();
|
57
57
|
public store = store;
|
58
58
|
public mainViewProxy: MainViewProxy;
|
59
|
-
public refresher
|
59
|
+
public refresher: ReconnectRefresher;
|
60
60
|
public isReplay = this.windowManger.isReplay;
|
61
61
|
public mainViewScenesLength = 0;
|
62
62
|
|
@@ -18,6 +18,8 @@ export enum Fields {
|
|
18
18
|
CursorState = "cursorState",
|
19
19
|
FullPath = "fullPath",
|
20
20
|
Registered = "registered",
|
21
|
+
Camera = "camera",
|
22
|
+
Size = "size",
|
21
23
|
}
|
22
24
|
|
23
25
|
export type Apps = {
|
@@ -39,9 +41,13 @@ export type StoreContext = {
|
|
39
41
|
safeSetAttributes: (attributes: any) => void;
|
40
42
|
}
|
41
43
|
|
42
|
-
export type ICamera = Camera & {
|
44
|
+
export type ICamera = Camera & {
|
45
|
+
id: string; // room uid
|
46
|
+
};
|
43
47
|
|
44
|
-
export type ISize = Size & {
|
48
|
+
export type ISize = Size & {
|
49
|
+
id: string; // room uid
|
50
|
+
};
|
45
51
|
|
46
52
|
export class AttributesDelegate {
|
47
53
|
|
@@ -108,6 +114,10 @@ export class AttributesDelegate {
|
|
108
114
|
}
|
109
115
|
}
|
110
116
|
|
117
|
+
public updateAppAttributes(appId: string, key: string, value: any) {
|
118
|
+
this.context.safeUpdateAttributes([Fields.Apps, appId, key], value);
|
119
|
+
}
|
120
|
+
|
111
121
|
public cleanAppAttributes(id: string) {
|
112
122
|
this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
|
113
123
|
this.context.safeSetAttributes({ [id]: undefined });
|
@@ -149,11 +159,11 @@ export class AttributesDelegate {
|
|
149
159
|
this.context.safeSetAttributes({ _mainSceneIndex: index });
|
150
160
|
}
|
151
161
|
|
152
|
-
public getMainViewCamera():
|
162
|
+
public getMainViewCamera(): ICamera {
|
153
163
|
return get(this.attributes, [Fields.MainViewCamera]);
|
154
164
|
}
|
155
165
|
|
156
|
-
public getMainViewSize():
|
166
|
+
public getMainViewSize(): ISize {
|
157
167
|
return get(this.attributes, [Fields.MainViewSize]);
|
158
168
|
}
|
159
169
|
|
@@ -214,19 +224,6 @@ export class AttributesDelegate {
|
|
214
224
|
}
|
215
225
|
}
|
216
226
|
|
217
|
-
export type MainViewSize = {
|
218
|
-
id: string;
|
219
|
-
width: number;
|
220
|
-
height: number;
|
221
|
-
};
|
222
|
-
|
223
|
-
export type MainViewCamera = {
|
224
|
-
id: string;
|
225
|
-
centerX: number;
|
226
|
-
centerY: number;
|
227
|
-
scale: number;
|
228
|
-
};
|
229
|
-
|
230
227
|
export type Cursors = {
|
231
228
|
[key: string]: Cursor;
|
232
229
|
};
|
package/src/BoxManager.ts
CHANGED
@@ -214,7 +214,7 @@ export class BoxManager {
|
|
214
214
|
return this.teleBoxManager.stageRect;
|
215
215
|
}
|
216
216
|
|
217
|
-
public createBox(params: CreateBoxParams):
|
217
|
+
public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
|
218
218
|
if (!this.teleBoxManager) return;
|
219
219
|
let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
|
220
220
|
const { width, height } = params.app.config ?? {};
|
@@ -237,8 +237,9 @@ export class BoxManager {
|
|
237
237
|
height,
|
238
238
|
id: params.appId,
|
239
239
|
};
|
240
|
-
this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
240
|
+
const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
241
241
|
this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
|
242
|
+
return box;
|
242
243
|
}
|
243
244
|
|
244
245
|
public setupBoxManager(
|
package/src/Utils/Common.ts
CHANGED
@@ -30,6 +30,12 @@ export const setViewSceneIndex = (view: View, index: number) => {
|
|
30
30
|
}
|
31
31
|
};
|
32
32
|
|
33
|
+
export const releaseView = (view: View) => {
|
34
|
+
if (!(view as any).didRelease) {
|
35
|
+
view.release();
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
33
39
|
export const setScenePath = (room: Room | undefined, scenePath: string) => {
|
34
40
|
if (room && room.isWritable) {
|
35
41
|
if (room.state.sceneState.scenePath !== scenePath) {
|
@@ -2,13 +2,13 @@ import { AnimationMode } from "white-web-sdk";
|
|
2
2
|
import { delay, throttle } from "lodash";
|
3
3
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
4
4
|
import type { Camera, View, Size } from "white-web-sdk";
|
5
|
-
import type {
|
5
|
+
import type { ISize } from "../AttributesDelegate";
|
6
6
|
|
7
7
|
export type SaveCamera = (camera: Camera) => void;
|
8
8
|
|
9
9
|
export class CameraSynchronizer {
|
10
10
|
protected remoteCamera?: Camera;
|
11
|
-
protected remoteSize?:
|
11
|
+
protected remoteSize?: ISize;
|
12
12
|
protected rect?: TeleBoxRect;
|
13
13
|
protected view?: View;
|
14
14
|
|
@@ -26,7 +26,7 @@ export class CameraSynchronizer {
|
|
26
26
|
}
|
27
27
|
|
28
28
|
// 远端 Camera 或者 size 更新
|
29
|
-
public onRemoteUpdate = throttle((camera: Camera, size:
|
29
|
+
public onRemoteUpdate = throttle((camera: Camera, size: ISize) => {
|
30
30
|
this.remoteCamera = camera;
|
31
31
|
this.remoteSize = size;
|
32
32
|
if (this.remoteSize && this.rect) {
|
@@ -37,27 +37,33 @@ export class CameraSynchronizer {
|
|
37
37
|
scale = this.rect.height / size.height;
|
38
38
|
}
|
39
39
|
const nextScale = camera.scale * scale;
|
40
|
-
const moveCamera = () =>
|
40
|
+
const moveCamera = () => this.view?.moveCamera({
|
41
41
|
centerX: camera.centerX,
|
42
42
|
centerY: camera.centerY,
|
43
43
|
scale: nextScale,
|
44
44
|
animationMode: AnimationMode.Immediately,
|
45
45
|
});
|
46
46
|
// TODO 直接调用 moveCamera 依然会出现 camera 错误的情况,这里暂时加一个 delay 保证 camera 是对的, 后续需要 SDK 进行修改
|
47
|
-
delay(moveCamera,
|
47
|
+
delay(moveCamera, 50);
|
48
48
|
}
|
49
49
|
}, 50);
|
50
50
|
|
51
51
|
|
52
52
|
public onLocalCameraUpdate(camera: Camera) {
|
53
53
|
this.saveCamera(camera);
|
54
|
+
this.remoteCamera = camera;
|
54
55
|
}
|
55
56
|
|
56
57
|
// 本地 Size 更新, 先匹配 camera 到新的 size 然后再发送 camera 数据到远端
|
57
|
-
public onLocalSizeUpdate(size: Size) {
|
58
|
+
public onLocalSizeUpdate = (size: Size) => {
|
58
59
|
if (this.rect && this.view) {
|
59
|
-
|
60
|
-
|
60
|
+
let scale: number;
|
61
|
+
if (size.width < size.height) {
|
62
|
+
scale = this.rect.width / size.width;
|
63
|
+
} else {
|
64
|
+
scale = this.rect.height / size.height;
|
65
|
+
}
|
66
|
+
const nextScale = this.view.camera.scale / scale;
|
61
67
|
this.view.moveCamera({
|
62
68
|
scale: nextScale,
|
63
69
|
animationMode: AnimationMode.Immediately
|
package/src/View/MainView.ts
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
import { reaction } from "white-web-sdk";
|
2
1
|
import { callbacks } from "../callback";
|
2
|
+
import { CameraSynchronizer } from "./CameraSynchronizer";
|
3
3
|
import { createView } from "./ViewManager";
|
4
4
|
import { debounce, get, isEqual } from "lodash";
|
5
5
|
import { emitter } from "../InternalEmitter";
|
6
6
|
import { Events } from "../constants";
|
7
7
|
import { Fields } from "../AttributesDelegate";
|
8
|
-
import {
|
8
|
+
import { reaction } from "white-web-sdk";
|
9
|
+
import { releaseView, setViewFocusScenePath } from "../Utils/Common";
|
9
10
|
import { SideEffectManager } from "side-effect-manager";
|
10
11
|
import type { Camera, Size, View } from "white-web-sdk";
|
11
12
|
import type { AppManager } from "../AppManager";
|
12
|
-
import { CameraSynchronizer } from "./CameraSynchronizer";
|
13
13
|
|
14
14
|
export class MainViewProxy {
|
15
15
|
private started = false;
|
@@ -21,8 +21,8 @@ export class MainViewProxy {
|
|
21
21
|
private sideEffectManager = new SideEffectManager();
|
22
22
|
|
23
23
|
constructor(private manager: AppManager) {
|
24
|
-
this.synchronizer = new CameraSynchronizer(
|
25
|
-
|
24
|
+
this.synchronizer = new CameraSynchronizer(camera =>
|
25
|
+
this.store.setMainViewCamera({ ...camera, id: this.manager.uid })
|
26
26
|
);
|
27
27
|
this.mainView = this.createMainView();
|
28
28
|
this.moveCameraSizeByAttributes();
|
@@ -37,9 +37,7 @@ export class MainViewProxy {
|
|
37
37
|
});
|
38
38
|
this.sideEffectManager.add(() => {
|
39
39
|
return emitter.on("startReconnect", () => {
|
40
|
-
|
41
|
-
this.mainView.release();
|
42
|
-
}
|
40
|
+
releaseView(this.mainView);
|
43
41
|
});
|
44
42
|
});
|
45
43
|
const rect = this.manager.boxManager?.stageRect;
|
@@ -49,7 +47,7 @@ export class MainViewProxy {
|
|
49
47
|
this.sideEffectManager.add(() => {
|
50
48
|
return emitter.on("playgroundSizeChange", rect => {
|
51
49
|
this.synchronizer.setRect(rect);
|
52
|
-
this.synchronizer.onLocalSizeUpdate(rect);
|
50
|
+
// this.synchronizer.onLocalSizeUpdate(rect);
|
53
51
|
});
|
54
52
|
});
|
55
53
|
}
|
@@ -122,7 +120,7 @@ export class MainViewProxy {
|
|
122
120
|
|
123
121
|
public sizeChangeHandler = debounce((size: Size) => {
|
124
122
|
if (size) {
|
125
|
-
this.synchronizer.onLocalSizeUpdate(size);
|
123
|
+
// this.synchronizer.onLocalSizeUpdate(size);
|
126
124
|
}
|
127
125
|
}, 30);
|
128
126
|
|
@@ -171,9 +169,7 @@ export class MainViewProxy {
|
|
171
169
|
const divElement = this.mainView.divElement;
|
172
170
|
const disableCameraTransform = this.mainView.disableCameraTransform;
|
173
171
|
this.stop();
|
174
|
-
|
175
|
-
this.mainView.release();
|
176
|
-
}
|
172
|
+
releaseView(this.mainView);
|
177
173
|
this.removeMainViewListener();
|
178
174
|
this.mainView = this.createMainView();
|
179
175
|
this.mainView.disableCameraTransform = disableCameraTransform;
|
package/src/index.ts
CHANGED
@@ -29,7 +29,7 @@ import {
|
|
29
29
|
} from "./Utils/Common";
|
30
30
|
import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
|
31
31
|
import * as Errors from "./Utils/error";
|
32
|
-
import type { Apps, Position } from "./AttributesDelegate";
|
32
|
+
import type { Apps, Position , ICamera, ISize } from "./AttributesDelegate";
|
33
33
|
import type {
|
34
34
|
Displayer,
|
35
35
|
SceneDefinition,
|
@@ -104,6 +104,8 @@ export type AppSyncAttributes = {
|
|
104
104
|
isDynamicPPT?: boolean;
|
105
105
|
fullPath?: string;
|
106
106
|
createdAt?: number;
|
107
|
+
camera?: ICamera;
|
108
|
+
size?: ISize;
|
107
109
|
};
|
108
110
|
|
109
111
|
export type AppInitState = {
|