@netless/window-manager 1.0.13-test.2 → 1.0.13-test.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/dist/index.d.ts +33 -1
- package/dist/index.js +14 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +552 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/AppListener.ts +1 -20
- package/src/AppManager.ts +29 -4
- package/src/AttributesDelegate.ts +7 -5
- package/src/ContainerResizeObserver.ts +15 -4
- package/src/InternalEmitter.ts +1 -0
- package/src/Utils/Common.ts +0 -1
- package/src/Utils/Reactive.ts +2 -2
- package/src/Utils/RoomHacker.ts +18 -1
- package/src/Utils/log.ts +37 -0
- package/src/View/MainView.ts +124 -12
- package/src/index.ts +451 -3
package/package.json
CHANGED
package/src/AppListener.ts
CHANGED
|
@@ -47,18 +47,10 @@ export class AppListeners {
|
|
|
47
47
|
break;
|
|
48
48
|
}
|
|
49
49
|
case Events.SetMainViewScenePath: {
|
|
50
|
-
console.log("[window-manager] mainMagixEventListener
|
|
50
|
+
console.log("[window-manager] mainMagixEventListener " + JSON.stringify(data.payload));
|
|
51
51
|
this.setMainViewScenePathHandler(data.payload);
|
|
52
52
|
break;
|
|
53
53
|
}
|
|
54
|
-
// case Events.MoveCamera: {
|
|
55
|
-
// this.moveCameraHandler(data.payload);
|
|
56
|
-
// break;
|
|
57
|
-
// }
|
|
58
|
-
// case Events.MoveCameraToContain: {
|
|
59
|
-
// this.moveCameraToContainHandler(data.payload);
|
|
60
|
-
// break;
|
|
61
|
-
// }
|
|
62
54
|
case Events.CursorMove: {
|
|
63
55
|
this.cursorMoveHandler(data.payload);
|
|
64
56
|
break;
|
|
@@ -103,17 +95,6 @@ export class AppListeners {
|
|
|
103
95
|
callbacks.emit("mainViewScenePathChange", nextScenePath);
|
|
104
96
|
};
|
|
105
97
|
|
|
106
|
-
// private moveCameraHandler = (
|
|
107
|
-
// payload: Camera & { animationMode?: AnimationMode | undefined }
|
|
108
|
-
// ) => {
|
|
109
|
-
// if (isEqual(omit(payload, ["animationMode"]), { ...this.manager.mainView.camera })) return;
|
|
110
|
-
// this.manager.mainView.moveCamera(payload);
|
|
111
|
-
// };
|
|
112
|
-
|
|
113
|
-
// private moveCameraToContainHandler = (payload: any) => {
|
|
114
|
-
// this.manager.mainView.moveCameraToContain(payload);
|
|
115
|
-
// };
|
|
116
|
-
|
|
117
98
|
private cursorMoveHandler = (payload: any) => {
|
|
118
99
|
internalEmitter.emit("cursorMove", payload);
|
|
119
100
|
};
|
package/src/AppManager.ts
CHANGED
|
@@ -51,7 +51,6 @@ import type {
|
|
|
51
51
|
} from "./BoxEmitter";
|
|
52
52
|
import { getExtendClass } from "./Utils/extendClass";
|
|
53
53
|
import type { TeleBoxState } from "@netless/telebox-insider";
|
|
54
|
-
import { getAttribute } from "video.js/dist/types/utils/dom";
|
|
55
54
|
|
|
56
55
|
export class AppManager {
|
|
57
56
|
static readonly kind = "AppManager";
|
|
@@ -147,6 +146,7 @@ export class AppManager {
|
|
|
147
146
|
const { scenePath } = params;
|
|
148
147
|
// 如果移除根目录就把 scenePath 设置为初始值
|
|
149
148
|
if (scenePath === ROOT_DIR) {
|
|
149
|
+
console.log("[window-manager] onRemoveScenes ROOT_DIR");
|
|
150
150
|
await this.onRootDirRemoved();
|
|
151
151
|
this.dispatchInternalEvent(Events.RootDirRemoved);
|
|
152
152
|
return;
|
|
@@ -159,6 +159,7 @@ export class AppManager {
|
|
|
159
159
|
sceneName = this.callbacksNode?.scenes[nextIndex];
|
|
160
160
|
}
|
|
161
161
|
if (sceneName) {
|
|
162
|
+
console.log(`[window-manager] onRemoveScenes setMainViewScenePath ${ROOT_DIR}${sceneName}`);
|
|
162
163
|
this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
|
|
163
164
|
}
|
|
164
165
|
await this.setMainViewSceneIndex(nextIndex);
|
|
@@ -710,6 +711,31 @@ export class AppManager {
|
|
|
710
711
|
}
|
|
711
712
|
internalEmitter.emit("mainViewMounted");
|
|
712
713
|
callbacks.emit("onMainViewMounted", mainView);
|
|
714
|
+
const hasRoot = this.hasRoot(mainView.divElement);
|
|
715
|
+
const rect = this.getRectByDivElement(mainView.divElement);
|
|
716
|
+
let log = `[window-manager] bindMainView hasRoot:${hasRoot}, rect:${JSON.stringify(rect)}, outerHeight:${window.outerHeight}, outerWidth:${window.outerWidth}`;
|
|
717
|
+
const visualViewport = window.visualViewport;
|
|
718
|
+
if (visualViewport) {
|
|
719
|
+
log += `, visualViewportWidth:${visualViewport.width}, visualViewportHeight:${visualViewport.height}, visualViewportOffsetLeft:${visualViewport.offsetLeft}, visualViewportOffsetTop:${visualViewport.offsetTop}`;
|
|
720
|
+
}
|
|
721
|
+
console.log(log);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
private hasRoot(divElement: HTMLDivElement){
|
|
725
|
+
let current = divElement;
|
|
726
|
+
while (current) {
|
|
727
|
+
if (current.parentElement === document.body) {
|
|
728
|
+
return true;
|
|
729
|
+
}
|
|
730
|
+
current = current.parentElement as HTMLDivElement;
|
|
731
|
+
}
|
|
732
|
+
return false;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
private getRectByDivElement(divElement: HTMLDivElement){
|
|
736
|
+
// 获取当前divElement的矩形区域
|
|
737
|
+
const rect = divElement.getBoundingClientRect();
|
|
738
|
+
return rect;
|
|
713
739
|
}
|
|
714
740
|
|
|
715
741
|
public setMainViewFocusPath(scenePath?: string) {
|
|
@@ -854,7 +880,7 @@ export class AppManager {
|
|
|
854
880
|
private async _setMainViewScenePath(scenePath: string) {
|
|
855
881
|
const success = this.setMainViewFocusPath(scenePath);
|
|
856
882
|
if (success) {
|
|
857
|
-
console.log("[window-manager] _setMainViewScenePath
|
|
883
|
+
console.log("[window-manager] _setMainViewScenePath " + scenePath);
|
|
858
884
|
this.safeSetAttributes({ _mainScenePath: scenePath });
|
|
859
885
|
this.store.setMainViewFocusPath(this.mainView);
|
|
860
886
|
this.updateSceneIndex();
|
|
@@ -871,7 +897,7 @@ export class AppManager {
|
|
|
871
897
|
const pageName = scenePath.replace(sceneDir, "").replace("/", "");
|
|
872
898
|
const index = scenes.findIndex(scene => scene.name === pageName);
|
|
873
899
|
if (isInteger(index) && index >= 0) {
|
|
874
|
-
console.log("[window-manager] updateSceneIndex
|
|
900
|
+
console.log("[window-manager] updateSceneIndex " + index);
|
|
875
901
|
this.safeSetAttributes({ _mainSceneIndex: index });
|
|
876
902
|
}
|
|
877
903
|
}
|
|
@@ -897,7 +923,6 @@ export class AppManager {
|
|
|
897
923
|
}
|
|
898
924
|
|
|
899
925
|
private dispatchSetMainViewScenePath(scenePath: string): void {
|
|
900
|
-
console.log("[window-manager] dispatchSetMainViewScenePath====>", JSON.stringify(scenePath));
|
|
901
926
|
this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });
|
|
902
927
|
callbacks.emit("mainViewScenePathChange", scenePath);
|
|
903
928
|
// 兼容 15 的 SDK, 需要 room 的当前 ScenePath
|
|
@@ -7,6 +7,7 @@ import type { Cursor } from "./Cursor/Cursor";
|
|
|
7
7
|
import { getExtendClass } from "./Utils/extendClass";
|
|
8
8
|
import type { ExtendClass } from "./Utils/extendClass";
|
|
9
9
|
import type { NotMinimizedBoxState, TeleBoxState } from "@netless/telebox-insider";
|
|
10
|
+
import { LocalConsole } from "./Utils/log";
|
|
10
11
|
|
|
11
12
|
export enum Fields {
|
|
12
13
|
Apps = "apps",
|
|
@@ -54,6 +55,7 @@ export type ISize = Size & { id: string };
|
|
|
54
55
|
|
|
55
56
|
export class AttributesDelegate {
|
|
56
57
|
static readonly kind = "AttributesDelegate";
|
|
58
|
+
private setMainViewCameraConsole = new LocalConsole("setMainViewCamera", 30);
|
|
57
59
|
constructor(private context: StoreContext) {}
|
|
58
60
|
|
|
59
61
|
public setContext(context: StoreContext) {
|
|
@@ -194,12 +196,12 @@ export class AttributesDelegate {
|
|
|
194
196
|
}
|
|
195
197
|
|
|
196
198
|
public setMainViewScenePath(scenePath: string) {
|
|
197
|
-
console.log("[window-manager] setMainViewScenePath
|
|
199
|
+
console.log("[window-manager] setMainViewScenePath " + scenePath);
|
|
198
200
|
this.context.safeSetAttributes({ _mainScenePath: scenePath });
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
public setMainViewSceneIndex(index: number) {
|
|
202
|
-
console.log("[window-manager] setMainViewSceneIndex
|
|
204
|
+
console.log("[window-manager] setMainViewSceneIndex " + index);
|
|
203
205
|
this.context.safeSetAttributes({ _mainSceneIndex: index });
|
|
204
206
|
}
|
|
205
207
|
|
|
@@ -212,19 +214,19 @@ export class AttributesDelegate {
|
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
public setMainViewCamera(camera: ICamera) {
|
|
215
|
-
|
|
217
|
+
this.setMainViewCameraConsole.log(JSON.stringify(camera));
|
|
216
218
|
this.context.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });
|
|
217
219
|
}
|
|
218
220
|
|
|
219
221
|
public setMainViewSize(size: ISize) {
|
|
220
222
|
if (size.width === 0 || size.height === 0) return;
|
|
221
|
-
console.log("[window-manager] setMainViewSize
|
|
223
|
+
console.log("[window-manager] setMainViewSize size:" + JSON.stringify(size));
|
|
222
224
|
this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
public setMainViewCameraAndSize(camera: ICamera, size: ISize) {
|
|
226
228
|
if (size.width === 0 || size.height === 0) return;
|
|
227
|
-
console.log("[window-manager] setMainViewCameraAndSize
|
|
229
|
+
console.log("[window-manager] setMainViewCameraAndSize camera:" + JSON.stringify(camera) + ", size:" + JSON.stringify(size));
|
|
228
230
|
this.context.safeSetAttributes({
|
|
229
231
|
[Fields.MainViewCamera]: { ...camera },
|
|
230
232
|
[Fields.MainViewSize]: { ...size },
|
|
@@ -3,12 +3,15 @@ import { isFunction } from "lodash";
|
|
|
3
3
|
import { WindowManager } from "./index";
|
|
4
4
|
import type { EmitterType } from "./InternalEmitter";
|
|
5
5
|
import type { UnsubscribeFn } from "emittery";
|
|
6
|
+
import { LocalConsole } from "./Utils/log";
|
|
6
7
|
|
|
7
8
|
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
|
|
8
9
|
|
|
9
10
|
export class ContainerResizeObserver {
|
|
10
11
|
private containerResizeObserver?: ResizeObserver;
|
|
11
12
|
private disposer?: UnsubscribeFn;
|
|
13
|
+
|
|
14
|
+
private updateSizerLocalConsole = new LocalConsole("updateSizer", 30);
|
|
12
15
|
|
|
13
16
|
constructor(private emitter: EmitterType) {}
|
|
14
17
|
|
|
@@ -28,19 +31,19 @@ export class ContainerResizeObserver {
|
|
|
28
31
|
sizer: HTMLElement,
|
|
29
32
|
wrapper: HTMLDivElement
|
|
30
33
|
) {
|
|
31
|
-
this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
|
|
34
|
+
this.updateSizer(container.getBoundingClientRect(), sizer, wrapper, 'observePlaygroundSize');
|
|
32
35
|
|
|
33
36
|
this.containerResizeObserver = new ResizeObserver(entries => {
|
|
34
37
|
const containerRect = entries[0]?.contentRect;
|
|
35
38
|
if (containerRect) {
|
|
36
|
-
this.updateSizer(containerRect, sizer, wrapper);
|
|
39
|
+
this.updateSizer(containerRect, sizer, wrapper, 'containerResizeObserver');
|
|
37
40
|
this.emitter.emit("playgroundSizeChange", containerRect);
|
|
38
41
|
}
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
this.disposer = this.emitter.on("containerSizeRatioUpdate", () => {
|
|
42
45
|
const containerRect = container.getBoundingClientRect();
|
|
43
|
-
this.updateSizer(containerRect, sizer, wrapper);
|
|
46
|
+
this.updateSizer(containerRect, sizer, wrapper, 'containerSizeRatioUpdate');
|
|
44
47
|
this.emitter.emit("playgroundSizeChange", containerRect);
|
|
45
48
|
});
|
|
46
49
|
|
|
@@ -50,7 +53,8 @@ export class ContainerResizeObserver {
|
|
|
50
53
|
public updateSizer(
|
|
51
54
|
{ width, height }: DOMRectReadOnly,
|
|
52
55
|
sizer: HTMLElement,
|
|
53
|
-
wrapper: HTMLDivElement
|
|
56
|
+
wrapper: HTMLDivElement,
|
|
57
|
+
origin?: string
|
|
54
58
|
) {
|
|
55
59
|
if (width && height) {
|
|
56
60
|
if (height / width > WindowManager.containerSizeRatio) {
|
|
@@ -62,6 +66,13 @@ export class ContainerResizeObserver {
|
|
|
62
66
|
}
|
|
63
67
|
wrapper.style.width = `${width}px`;
|
|
64
68
|
wrapper.style.height = `${height}px`;
|
|
69
|
+
const wrapperRect = wrapper.getBoundingClientRect();
|
|
70
|
+
this.updateSizerLocalConsole.log(`from ${origin}, traget size: ${JSON.stringify({ width, height })}, wrapperRect: ${wrapperRect.width} ${wrapperRect.height}`);
|
|
71
|
+
this.emitter.emit("wrapperRectChange", {
|
|
72
|
+
width: wrapperRect.width,
|
|
73
|
+
height: wrapperRect.height,
|
|
74
|
+
origin,
|
|
75
|
+
});
|
|
65
76
|
}
|
|
66
77
|
}
|
|
67
78
|
|
package/src/InternalEmitter.ts
CHANGED
|
@@ -29,6 +29,7 @@ export type EmitterEvent = {
|
|
|
29
29
|
changePageState: undefined;
|
|
30
30
|
writableChange: boolean;
|
|
31
31
|
containerSizeRatioUpdate: number;
|
|
32
|
+
wrapperRectChange: { width: number; height: number; origin?: string };
|
|
32
33
|
boxesStatusChange: Map<string, TeleBoxState>;
|
|
33
34
|
lastNotMinimizedBoxesStatusChange: Map<string, NotMinimizedBoxState>;
|
|
34
35
|
};
|
package/src/Utils/Common.ts
CHANGED
|
@@ -34,7 +34,6 @@ export const setScenePath = (room: Room | undefined, scenePath: string) => {
|
|
|
34
34
|
if (room && room.isWritable) {
|
|
35
35
|
if (room.state.sceneState.scenePath !== scenePath) {
|
|
36
36
|
const nextScenePath = scenePath === "/" ? "" : scenePath;
|
|
37
|
-
console.log("[window-manager] real setScenePath for current room====>", nextScenePath);
|
|
38
37
|
room.setScenePath(nextScenePath);
|
|
39
38
|
}
|
|
40
39
|
}
|
package/src/Utils/Reactive.ts
CHANGED
|
@@ -30,8 +30,8 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
|
30
30
|
};
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
export const safeListenPropsUpdated = <T
|
|
34
|
-
getProps: () => T,
|
|
33
|
+
export const safeListenPropsUpdated = <T extends Record<string, unknown>>(
|
|
34
|
+
getProps: () => T | null | undefined,
|
|
35
35
|
callback: AkkoObjectUpdatedListener<T>,
|
|
36
36
|
onDestroyed?: (props: unknown) => void
|
|
37
37
|
) => {
|
package/src/Utils/RoomHacker.ts
CHANGED
|
@@ -35,8 +35,25 @@ export const replaceRoomFunction = (room: Room | Player, manager: WindowManager)
|
|
|
35
35
|
});
|
|
36
36
|
const _scalePptToFit = room.scalePptToFit;
|
|
37
37
|
room.scalePptToFit = (...args) => {
|
|
38
|
-
console.log("[window-manager] scalePptToFit====>", JSON.stringify(args));
|
|
39
38
|
_scalePptToFit.call(room, ...args);
|
|
39
|
+
if (manager.appManager?.mainViewProxy) {
|
|
40
|
+
manager.appManager.mainViewProxy.setCameraAndSize();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const _putScenes = room.putScenes;
|
|
44
|
+
room.putScenes = (...args) => {
|
|
45
|
+
const [path, scenes] = args;
|
|
46
|
+
const currentScenePath = manager.mainView.focusScenePath;
|
|
47
|
+
if (currentScenePath && path && scenes) {
|
|
48
|
+
console.log("[window-manager] putScenes " + JSON.stringify(args));
|
|
49
|
+
for (const scene of scenes) {
|
|
50
|
+
if (`${path}${scene.name}` === currentScenePath) {
|
|
51
|
+
console.error(`[window-manager] putScenes: scene name can not be the same as the current scene path: ${currentScenePath}`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return _putScenes.call(room, ...args);
|
|
40
57
|
};
|
|
41
58
|
room.moveCamera = (camera: Camera) => manager.moveCamera(camera);
|
|
42
59
|
room.moveCameraToContain = (...args) => manager.moveCameraToContain(...args);
|
package/src/Utils/log.ts
CHANGED
|
@@ -5,3 +5,40 @@ export const log = (...args: any[]): void => {
|
|
|
5
5
|
console.log(`[WindowManager]:`, ...args);
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 按 `[window-manager][tagName]` 前缀输出。
|
|
11
|
+
* 若传入 `debounceTime`(毫秒):窗口内多次 `log` 不立即输出,只在连续停止调用满 `debounceTime` 后输出**最后一次**的参数(尾部 debounce)。
|
|
12
|
+
*/
|
|
13
|
+
export class LocalConsole {
|
|
14
|
+
private pendingArgs: unknown[] | null = null;
|
|
15
|
+
private flushTimer: ReturnType<typeof setTimeout> | null = null;
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
private readonly name: string,
|
|
19
|
+
private readonly debounceTime?: number,
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
private flush(): void {
|
|
23
|
+
this.flushTimer = null;
|
|
24
|
+
const args = this.pendingArgs;
|
|
25
|
+
this.pendingArgs = null;
|
|
26
|
+
if (args === null) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
console.log(`[window-manager][${this.name}]: ${args.join(", ")}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
log(...args: unknown[]): void {
|
|
33
|
+
const ms = this.debounceTime;
|
|
34
|
+
if (ms != null && ms > 0) {
|
|
35
|
+
this.pendingArgs = args;
|
|
36
|
+
if (this.flushTimer != null) {
|
|
37
|
+
clearTimeout(this.flushTimer);
|
|
38
|
+
}
|
|
39
|
+
this.flushTimer = setTimeout(() => this.flush(), ms);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log(`[window-manager][${this.name}]: ${args.join(", ")}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/View/MainView.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { SideEffectManager } from "side-effect-manager";
|
|
|
9
9
|
import type { Camera, Room, Size, View } from "white-web-sdk";
|
|
10
10
|
import type { AppManager } from "../AppManager";
|
|
11
11
|
import { Events } from "../constants";
|
|
12
|
+
import { LocalConsole } from "../Utils/log";
|
|
12
13
|
|
|
13
14
|
export class MainViewProxy {
|
|
14
15
|
/** Refresh the view's camera in an interval of 1.5s. */
|
|
@@ -17,12 +18,19 @@ export class MainViewProxy {
|
|
|
17
18
|
private scale?: number;
|
|
18
19
|
private started = false;
|
|
19
20
|
private mainViewIsAddListener = false;
|
|
21
|
+
private isForcingMainViewDivElement = false;
|
|
22
|
+
private wrapperRectWorkaroundFrame = 0;
|
|
23
|
+
private pendingWrapperRectChange?: { width: number; height: number; origin?: string };
|
|
20
24
|
private mainView: View;
|
|
21
25
|
private store = this.manager.store;
|
|
22
26
|
private viewMode = this.manager.windowManger.viewMode;
|
|
23
27
|
|
|
24
28
|
private sideEffectManager = new SideEffectManager();
|
|
25
29
|
|
|
30
|
+
private playgroundSizeChangeListenerLocalConsole = new LocalConsole("playgroundSizeChangeListener", 30);
|
|
31
|
+
private sizeUpdatedLocalConsole = new LocalConsole("sizeUpdated", 30);
|
|
32
|
+
private cameraUpdatedLocalConsole = new LocalConsole("cameraUpdated", 30);
|
|
33
|
+
|
|
26
34
|
constructor(private manager: AppManager) {
|
|
27
35
|
this.mainView = this.createMainView();
|
|
28
36
|
this.moveCameraSizeByAttributes();
|
|
@@ -33,7 +41,15 @@ export class MainViewProxy {
|
|
|
33
41
|
this.startListenWritableChange();
|
|
34
42
|
});
|
|
35
43
|
const playgroundSizeChangeListener = () => {
|
|
36
|
-
|
|
44
|
+
this.playgroundSizeChangeListenerLocalConsole.log(
|
|
45
|
+
JSON.stringify(this.mainView.camera),
|
|
46
|
+
JSON.stringify(this.mainView.size),
|
|
47
|
+
JSON.stringify(this.mainViewSize),
|
|
48
|
+
JSON.stringify(this.mainViewCamera),
|
|
49
|
+
window.outerHeight, window.outerWidth,
|
|
50
|
+
window.visualViewport?.width ?? "null", window.visualViewport?.height ?? "null",
|
|
51
|
+
window.visualViewport?.offsetLeft ?? "null", window.visualViewport?.offsetTop ?? "null",
|
|
52
|
+
);
|
|
37
53
|
this.sizeChangeHandler(this.mainViewSize);
|
|
38
54
|
};
|
|
39
55
|
this.sideEffectManager.add(() => {
|
|
@@ -42,6 +58,9 @@ export class MainViewProxy {
|
|
|
42
58
|
this.sideEffectManager.add(() => {
|
|
43
59
|
return internalEmitter.on("containerSizeRatioUpdate", this.onUpdateContainerSizeRatio);
|
|
44
60
|
});
|
|
61
|
+
this.sideEffectManager.add(() => {
|
|
62
|
+
return internalEmitter.on("wrapperRectChange", this.onWrapperRectChange);
|
|
63
|
+
});
|
|
45
64
|
this.sideEffectManager.add(() => {
|
|
46
65
|
return internalEmitter.on("startReconnect", () => {
|
|
47
66
|
if (!this.didRelease) {
|
|
@@ -97,14 +116,92 @@ export class MainViewProxy {
|
|
|
97
116
|
this.moveCamera(this.mainViewCamera);
|
|
98
117
|
}
|
|
99
118
|
|
|
119
|
+
private onWrapperRectChange = (payload: { width: number; height: number; origin?: string }) => {
|
|
120
|
+
this.pendingWrapperRectChange = payload;
|
|
121
|
+
if (this.wrapperRectWorkaroundFrame) {
|
|
122
|
+
cancelAnimationFrame(this.wrapperRectWorkaroundFrame);
|
|
123
|
+
}
|
|
124
|
+
this.wrapperRectWorkaroundFrame = requestAnimationFrame(this.runWrapperRectWorkaround);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
private runWrapperRectWorkaround = () => {
|
|
128
|
+
this.wrapperRectWorkaroundFrame = 0;
|
|
129
|
+
const payload = this.pendingWrapperRectChange;
|
|
130
|
+
const element = this.mainView.divElement;
|
|
131
|
+
this.pendingWrapperRectChange = undefined;
|
|
132
|
+
if (!payload || !element) return;
|
|
133
|
+
|
|
134
|
+
const rect = element.getBoundingClientRect();
|
|
135
|
+
const observedSize = { width: rect.width, height: rect.height };
|
|
136
|
+
const wrapperMatchesDom =
|
|
137
|
+
Math.abs(payload.width - observedSize.width) <= 0.5 &&
|
|
138
|
+
Math.abs(payload.height - observedSize.height) <= 0.5;
|
|
139
|
+
const viewIsStale =
|
|
140
|
+
Math.abs(this.mainView.size.width - observedSize.width) > 0.5 ||
|
|
141
|
+
Math.abs(this.mainView.size.height - observedSize.height) > 0.5;
|
|
142
|
+
|
|
143
|
+
if (wrapperMatchesDom && viewIsStale) {
|
|
144
|
+
this.forceSyncMainViewDivElement(
|
|
145
|
+
`wrapperRectChange:${payload.origin || "unknown"}`,
|
|
146
|
+
observedSize,
|
|
147
|
+
element
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
private forceSyncMainViewDivElement(
|
|
153
|
+
reason: string,
|
|
154
|
+
observedSize: Pick<Size, "width" | "height">,
|
|
155
|
+
element: HTMLDivElement
|
|
156
|
+
) {
|
|
157
|
+
const { width: viewWidth, height: viewHeight } = this.mainView.size;
|
|
158
|
+
if (
|
|
159
|
+
Math.abs(viewWidth - observedSize.width) <= 0.5 &&
|
|
160
|
+
Math.abs(viewHeight - observedSize.height) <= 0.5
|
|
161
|
+
) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (this.isForcingMainViewDivElement) {
|
|
165
|
+
console.log("[window-manager] skipForceSyncMainViewDivElement " + JSON.stringify({
|
|
166
|
+
reason,
|
|
167
|
+
observedSize,
|
|
168
|
+
viewSize: this.mainView.size,
|
|
169
|
+
}));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
this.isForcingMainViewDivElement = true;
|
|
173
|
+
console.log("[window-manager] forceSyncMainViewDivElement " + JSON.stringify({
|
|
174
|
+
reason,
|
|
175
|
+
observedSize,
|
|
176
|
+
viewSize: this.mainView.size,
|
|
177
|
+
mainViewSize: this.mainViewSize,
|
|
178
|
+
mainViewCamera: this.mainViewCamera,
|
|
179
|
+
}));
|
|
180
|
+
this.mainView.divElement = null;
|
|
181
|
+
this.mainView.divElement = element;
|
|
182
|
+
queueMicrotask(() => {
|
|
183
|
+
const rect = element.getBoundingClientRect();
|
|
184
|
+
console.log("[window-manager] forceSyncMainViewDivElementResult " + JSON.stringify({
|
|
185
|
+
reason,
|
|
186
|
+
viewSize: this.mainView.size,
|
|
187
|
+
rect: { width: rect.width, height: rect.height },
|
|
188
|
+
}));
|
|
189
|
+
this.isForcingMainViewDivElement = false;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
100
193
|
public start() {
|
|
101
|
-
console.log("[window-manager] start
|
|
194
|
+
console.log("[window-manager] start attributes size:" + JSON.stringify(this.mainViewSize));
|
|
102
195
|
this.sizeChangeHandler(this.mainViewSize);
|
|
103
196
|
if (this.started) return;
|
|
104
197
|
this.addCameraListener();
|
|
105
198
|
this.addCameraReaction();
|
|
106
199
|
if (this.manager.room) this.syncMainView(this.manager.room);
|
|
107
200
|
this.started = true;
|
|
201
|
+
if(this.mainView.focusScenePath) {
|
|
202
|
+
this.manager.windowManger.onMainViewScenePathChangeHandler(this.mainView.focusScenePath);
|
|
203
|
+
}
|
|
204
|
+
console.log("[window-manager] start end mainView size:" + JSON.stringify(this.mainView.size));
|
|
108
205
|
}
|
|
109
206
|
|
|
110
207
|
public addCameraReaction = () => {
|
|
@@ -122,7 +219,7 @@ export class MainViewProxy {
|
|
|
122
219
|
() => this.mainViewCamera,
|
|
123
220
|
camera => {
|
|
124
221
|
if (camera && camera.id !== this.manager.uid) {
|
|
125
|
-
console.log("[window-manager] cameraReaction
|
|
222
|
+
console.log("[window-manager] cameraReaction " + JSON.stringify(camera) + JSON.stringify(this.mainViewSize));
|
|
126
223
|
this.moveCameraToContian(this.mainViewSize);
|
|
127
224
|
this.moveCamera(camera);
|
|
128
225
|
}
|
|
@@ -135,14 +232,15 @@ export class MainViewProxy {
|
|
|
135
232
|
if (size) {
|
|
136
233
|
this.moveCameraToContian(size);
|
|
137
234
|
this.moveCamera(this.mainViewCamera);
|
|
138
|
-
console.log("[window-manager] sizeChangeHandler
|
|
235
|
+
console.log("[window-manager] sizeChangeHandler current size and camera" + JSON.stringify(size) + JSON.stringify(this.mainViewCamera) +
|
|
236
|
+
JSON.stringify(this.mainView.camera) + JSON.stringify(this.mainView.size));
|
|
139
237
|
}
|
|
140
238
|
this.ensureMainViewSize();
|
|
141
239
|
}, 30);
|
|
142
240
|
|
|
143
241
|
public onUpdateContainerSizeRatio = () => {
|
|
144
242
|
const size = this.store.getMainViewSize();
|
|
145
|
-
console.log("[window-manager] onUpdateContainerSizeRatio
|
|
243
|
+
console.log("[window-manager] onUpdateContainerSizeRatio " + JSON.stringify(size));
|
|
146
244
|
this.sizeChangeHandler(size);
|
|
147
245
|
};
|
|
148
246
|
|
|
@@ -235,18 +333,18 @@ export class MainViewProxy {
|
|
|
235
333
|
|
|
236
334
|
private addCameraListener() {
|
|
237
335
|
this.view.callbacks.on("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
|
|
238
|
-
this.view.callbacks.on("onCameraUpdated", this.
|
|
239
|
-
this.view.callbacks.on("onSizeUpdated", this.
|
|
336
|
+
this.view.callbacks.on("onCameraUpdated", this.onCameraUpdated);
|
|
337
|
+
this.view.callbacks.on("onSizeUpdated", this.onSizeUpdated);
|
|
240
338
|
}
|
|
241
339
|
|
|
242
340
|
private removeCameraListener() {
|
|
243
341
|
this.view.callbacks.off("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
|
|
244
|
-
this.view.callbacks.off("onCameraUpdated", this.
|
|
245
|
-
this.view.callbacks.off("onSizeUpdated", this.
|
|
342
|
+
this.view.callbacks.off("onCameraUpdated", this.onCameraUpdated);
|
|
343
|
+
this.view.callbacks.off("onSizeUpdated", this.onSizeUpdated);
|
|
246
344
|
}
|
|
247
345
|
|
|
248
346
|
private _syncMainViewTimer = 0;
|
|
249
|
-
private
|
|
347
|
+
private handleCameraOrSizeUpdated = () => {
|
|
250
348
|
callbacks.emit("cameraStateChange", this.cameraState);
|
|
251
349
|
// sdk >= 2.16.43 的 syncMainView() 可以写入当前 main view 的 camera, 以修复复制粘贴元素的位置
|
|
252
350
|
// 注意到这个操作会发送信令,应当避免频繁调用
|
|
@@ -254,10 +352,19 @@ export class MainViewProxy {
|
|
|
254
352
|
clearTimeout(this._syncMainViewTimer);
|
|
255
353
|
this._syncMainViewTimer = setTimeout(this.syncMainView, 100, this.manager.room);
|
|
256
354
|
}
|
|
257
|
-
console.log("[window-manager] onCameraOrSizeUpdated====>", JSON.stringify(this.cameraState));
|
|
258
355
|
this.ensureMainViewSize();
|
|
259
356
|
};
|
|
260
357
|
|
|
358
|
+
private onCameraUpdated = (camera: Camera) => {
|
|
359
|
+
this.cameraUpdatedLocalConsole.log(JSON.stringify(camera));
|
|
360
|
+
this.handleCameraOrSizeUpdated();
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
private onSizeUpdated = (size: Size) => {
|
|
364
|
+
this.sizeUpdatedLocalConsole.log(JSON.stringify(size));
|
|
365
|
+
this.handleCameraOrSizeUpdated();
|
|
366
|
+
};
|
|
367
|
+
|
|
261
368
|
private ensureMainViewSize() {
|
|
262
369
|
if (
|
|
263
370
|
(!this.mainViewSize ||
|
|
@@ -272,7 +379,7 @@ export class MainViewProxy {
|
|
|
272
379
|
|
|
273
380
|
private syncMainView = (room: Room) => {
|
|
274
381
|
if (room.isWritable) {
|
|
275
|
-
console.log("[window-manager] syncMainView
|
|
382
|
+
console.log("[window-manager] syncMainView ");
|
|
276
383
|
room.syncMainView(this.mainView);
|
|
277
384
|
}
|
|
278
385
|
};
|
|
@@ -316,6 +423,11 @@ export class MainViewProxy {
|
|
|
316
423
|
};
|
|
317
424
|
|
|
318
425
|
public destroy() {
|
|
426
|
+
console.log("[window-manager] destroy ");
|
|
427
|
+
if (this.wrapperRectWorkaroundFrame) {
|
|
428
|
+
cancelAnimationFrame(this.wrapperRectWorkaroundFrame);
|
|
429
|
+
this.wrapperRectWorkaroundFrame = 0;
|
|
430
|
+
}
|
|
319
431
|
this.removeMainViewListener();
|
|
320
432
|
this.stop();
|
|
321
433
|
this.sideEffectManager.flushAll();
|