@netless/window-manager 0.3.17 → 0.4.0-canary.10
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 +10 -0
- package/README.md +4 -43
- package/dist/App/Storage/StorageEvent.d.ts +8 -0
- package/dist/App/Storage/index.d.ts +26 -0
- package/dist/App/Storage/typings.d.ts +21 -0
- package/dist/App/Storage/utils.d.ts +5 -0
- package/dist/AppContext.d.ts +6 -3
- package/dist/AppListener.d.ts +2 -2
- package/dist/AppManager.d.ts +17 -14
- package/dist/AppProxy.d.ts +5 -3
- package/dist/AttributesDelegate.d.ts +19 -11
- package/dist/Base/Context.d.ts +0 -1
- package/dist/Base/index.d.ts +1 -2
- package/dist/BoxManager.d.ts +25 -8
- package/dist/BuiltinApps.d.ts +6 -0
- package/dist/ContainerResizeObserver.d.ts +10 -0
- package/dist/Cursor/Cursor.d.ts +2 -3
- package/dist/Cursor/index.d.ts +9 -5
- package/dist/Helper.d.ts +6 -0
- package/dist/ReconnectRefresher.d.ts +9 -3
- package/dist/Utils/Common.d.ts +3 -1
- package/dist/Utils/Reactive.d.ts +1 -1
- package/dist/Utils/RoomHacker.d.ts +2 -2
- package/dist/Utils/error.d.ts +3 -0
- package/dist/{MainView.d.ts → View/MainView.d.ts} +3 -4
- package/dist/View/ViewManager.d.ts +13 -0
- package/dist/constants.d.ts +3 -7
- package/dist/index.d.ts +24 -27
- 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/dist/style.css +1 -1
- package/dist/typings.d.ts +1 -0
- package/docs/api.md +17 -0
- package/docs/migrate.md +42 -0
- package/package.json +6 -4
- package/src/App/Storage/StorageEvent.ts +21 -0
- package/src/App/Storage/index.ts +243 -0
- package/src/App/Storage/typings.ts +21 -0
- package/src/App/Storage/utils.ts +17 -0
- package/src/AppContext.ts +12 -4
- package/src/AppListener.ts +15 -11
- package/src/AppManager.ts +132 -95
- package/src/AppProxy.ts +49 -52
- package/src/AttributesDelegate.ts +76 -49
- package/src/Base/Context.ts +2 -6
- package/src/Base/index.ts +2 -2
- package/src/BoxManager.ts +95 -35
- package/src/BuiltinApps.ts +24 -0
- package/src/ContainerResizeObserver.ts +62 -0
- package/src/Cursor/Cursor.ts +35 -39
- package/src/Cursor/index.ts +79 -43
- package/src/Helper.ts +30 -0
- package/src/ReconnectRefresher.ts +25 -10
- package/src/Utils/Common.ts +35 -13
- package/src/Utils/Reactive.ts +9 -3
- package/src/Utils/RoomHacker.ts +20 -5
- package/src/Utils/error.ts +6 -1
- package/src/{MainView.ts → View/MainView.ts} +19 -27
- package/src/View/ViewManager.ts +53 -0
- package/src/constants.ts +2 -3
- package/src/index.ts +143 -171
- package/src/shim.d.ts +4 -0
- package/src/style.css +7 -1
- package/src/typings.ts +1 -0
- package/vite.config.js +4 -1
- package/dist/Utils/CameraStore.d.ts +0 -15
- package/dist/ViewManager.d.ts +0 -29
- package/dist/sdk.d.ts +0 -14
- package/src/Utils/CameraStore.ts +0 -72
- package/src/sdk.ts +0 -39
- package/src/viewManager.ts +0 -177
@@ -1,27 +1,29 @@
|
|
1
|
-
import { AnimationMode, reaction
|
2
|
-
import { Base } from "
|
3
|
-
import { callbacks, emitter } from "
|
1
|
+
import { AnimationMode, reaction } from "white-web-sdk";
|
2
|
+
import { Base } from "../Base";
|
3
|
+
import { callbacks, emitter } from "../index";
|
4
4
|
import { createView } from "./ViewManager";
|
5
5
|
import { debounce, isEmpty, isEqual } from "lodash";
|
6
|
-
import { Fields } from "
|
7
|
-
import {
|
6
|
+
import { Fields } from "../AttributesDelegate";
|
7
|
+
import { setViewFocusScenePath } from "../Utils/Common";
|
8
|
+
import { SideEffectManager } from "side-effect-manager";
|
8
9
|
import type { Camera, Size, View } from "white-web-sdk";
|
9
|
-
import type { AppManager } from "
|
10
|
+
import type { AppManager } from "../AppManager";
|
10
11
|
|
11
12
|
export class MainViewProxy extends Base {
|
12
13
|
private scale?: number;
|
13
|
-
private cameraStore = this.manager.cameraStore;
|
14
14
|
private started = false;
|
15
15
|
private mainViewIsAddListener = false;
|
16
16
|
private mainView: View;
|
17
17
|
private viewId = "mainView";
|
18
18
|
|
19
|
+
private sideEffectManager = new SideEffectManager();
|
20
|
+
|
19
21
|
constructor(manager: AppManager) {
|
20
22
|
super(manager);
|
21
23
|
this.mainView = this.createMainView();
|
22
24
|
this.moveCameraSizeByAttributes();
|
23
|
-
this.cameraStore.register(this.viewId, this.mainView);
|
24
25
|
emitter.once("mainViewMounted").then(() => {
|
26
|
+
this.addMainViewListener();
|
25
27
|
setTimeout(() => {
|
26
28
|
this.start();
|
27
29
|
if (!this.mainViewCamera || !this.mainViewSize) {
|
@@ -29,8 +31,12 @@ export class MainViewProxy extends Base {
|
|
29
31
|
}
|
30
32
|
}, 200); // 等待 mainView 挂载完毕再进行监听,否则会触发不必要的 onSizeUpdated
|
31
33
|
});
|
32
|
-
|
34
|
+
const playgroundSizeChangeListener = () => {
|
33
35
|
this.sizeChangeHandler(this.mainViewSize);
|
36
|
+
};
|
37
|
+
this.sideEffectManager.add(() => {
|
38
|
+
emitter.on("playgroundSizeChange", playgroundSizeChangeListener);
|
39
|
+
return () => emitter.off("playgroundSizeChange", playgroundSizeChangeListener);
|
34
40
|
});
|
35
41
|
}
|
36
42
|
|
@@ -75,7 +81,7 @@ export class MainViewProxy extends Base {
|
|
75
81
|
);
|
76
82
|
};
|
77
83
|
|
78
|
-
private sizeChangeHandler =
|
84
|
+
private sizeChangeHandler = debounce((size: Size) => {
|
79
85
|
if (size) {
|
80
86
|
this.moveCameraToContian(size);
|
81
87
|
this.moveCamera(this.mainViewCamera);
|
@@ -96,15 +102,12 @@ export class MainViewProxy extends Base {
|
|
96
102
|
if (mainViewScenePath) {
|
97
103
|
setViewFocusScenePath(mainView, mainViewScenePath);
|
98
104
|
}
|
99
|
-
if (!this.store.focus) {
|
100
|
-
this.switchViewModeToWriter();
|
101
|
-
}
|
102
105
|
return mainView;
|
103
106
|
}
|
104
107
|
|
105
108
|
private onCameraUpdatedByDevice = (camera: Camera) => {
|
106
109
|
this.store.setMainViewCamera({ ...camera, id: this.context.uid });
|
107
|
-
if (!isEqual(this.mainViewSize, {...this.mainView.size, id: this.context.uid})) {
|
110
|
+
if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.context.uid })) {
|
108
111
|
this.setMainViewSize(this.view.size);
|
109
112
|
}
|
110
113
|
};
|
@@ -131,7 +134,6 @@ export class MainViewProxy extends Base {
|
|
131
134
|
|
132
135
|
public async mainViewClickHandler(): Promise<void> {
|
133
136
|
if (!this.manager.canOperate) return;
|
134
|
-
if (this.view.mode === ViewVisionMode.Writable) return;
|
135
137
|
this.store.cleanFocus();
|
136
138
|
this.context.blurFocusBox();
|
137
139
|
}
|
@@ -156,17 +158,6 @@ export class MainViewProxy extends Base {
|
|
156
158
|
callbacks.emit("cameraStateChange", this.cameraState);
|
157
159
|
};
|
158
160
|
|
159
|
-
public switchViewModeToWriter(): void {
|
160
|
-
if (!this.manager.canOperate) return;
|
161
|
-
if (this.view) {
|
162
|
-
if (this.view.mode === ViewVisionMode.Writable) return;
|
163
|
-
this.cameraStore.switchView(this.viewId, this.mainView, () => {
|
164
|
-
notifyMainViewModeChange(callbacks, ViewVisionMode.Writable);
|
165
|
-
setViewMode(this.view, ViewVisionMode.Writable);
|
166
|
-
});
|
167
|
-
}
|
168
|
-
}
|
169
|
-
|
170
161
|
public moveCameraToContian(size: Size): void {
|
171
162
|
if (!isEmpty(size)) {
|
172
163
|
this.view.moveCameraToContain({
|
@@ -195,6 +186,7 @@ export class MainViewProxy extends Base {
|
|
195
186
|
}
|
196
187
|
|
197
188
|
public stop() {
|
189
|
+
this.removeMainViewListener();
|
198
190
|
this.removeCameraListener();
|
199
191
|
this.manager.refresher?.remove(Fields.MainViewCamera);
|
200
192
|
this.manager.refresher?.remove(Fields.MainViewSize);
|
@@ -203,6 +195,6 @@ export class MainViewProxy extends Base {
|
|
203
195
|
|
204
196
|
public destroy() {
|
205
197
|
this.stop();
|
206
|
-
this.
|
198
|
+
this.sideEffectManager.flushAll();
|
207
199
|
}
|
208
200
|
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import type { View , Displayer} from "white-web-sdk";
|
2
|
+
|
3
|
+
export class ViewManager {
|
4
|
+
public views: Map<string, View> = new Map();
|
5
|
+
|
6
|
+
constructor(private displayer: Displayer) {}
|
7
|
+
|
8
|
+
public createView(id: string): View {
|
9
|
+
const view = createView(this.displayer);
|
10
|
+
this.views.set(id, view);
|
11
|
+
return view;
|
12
|
+
}
|
13
|
+
|
14
|
+
public getView(id: string): View | undefined {
|
15
|
+
return this.views.get(id);
|
16
|
+
}
|
17
|
+
|
18
|
+
public destroyView(id: string): void {
|
19
|
+
const view = this.views.get(id);
|
20
|
+
if (view) {
|
21
|
+
view.release();
|
22
|
+
this.views.delete(id);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
public setViewScenePath(id: string, scenePath: string): void {
|
27
|
+
const view = this.views.get(id);
|
28
|
+
if (view) {
|
29
|
+
view.focusScenePath = scenePath;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
public destroy() {
|
34
|
+
this.views.forEach(view => {
|
35
|
+
view.release();
|
36
|
+
});
|
37
|
+
this.views.clear();
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
export const createView = (displayer: Displayer): View => {
|
43
|
+
const view = displayer.views.createView();
|
44
|
+
setDefaultCameraBound(view);
|
45
|
+
return view;
|
46
|
+
};
|
47
|
+
|
48
|
+
export const setDefaultCameraBound = (view: View) => {
|
49
|
+
view.setCameraBound({
|
50
|
+
maxContentMode: () => 10,
|
51
|
+
minContentMode: () => 0.1,
|
52
|
+
});
|
53
|
+
};
|
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";
|
@@ -36,13 +37,11 @@ export enum CursorState {
|
|
36
37
|
Normal = "normal",
|
37
38
|
}
|
38
39
|
|
39
|
-
export const REQUIRE_VERSION = "2.
|
40
|
+
export const REQUIRE_VERSION = "2.16.0";
|
40
41
|
|
41
42
|
export const MIN_WIDTH = 340 / 720;
|
42
43
|
export const MIN_HEIGHT = 340 / 720;
|
43
44
|
|
44
45
|
export const SET_SCENEPATH_DELAY = 100; // 设置 scenePath 的延迟事件
|
45
46
|
|
46
|
-
export const DEFAULT_COLLECTOR_STYLE = { right: "10px", bottom: "15px", position: "absolute" };
|
47
|
-
|
48
47
|
export const DEFAULT_CONTAINER_RATIO = 9 / 16;
|
package/src/index.ts
CHANGED
@@ -1,18 +1,19 @@
|
|
1
|
-
import AppDocsViewer from "@netless/app-docs-viewer";
|
2
|
-
import AppMediaPlayer, { setOptions } from "@netless/app-media-player";
|
3
1
|
import Emittery from "emittery";
|
4
2
|
import pRetry from "p-retry";
|
5
3
|
import { AppManager } from "./AppManager";
|
6
4
|
import { appRegister } from "./Register";
|
5
|
+
import { ContainerResizeObserver } from "./ContainerResizeObserver";
|
6
|
+
import { createBoxManager } from "./BoxManager";
|
7
7
|
import { CursorManager } from "./Cursor";
|
8
|
-
import { DEFAULT_CONTAINER_RATIO, REQUIRE_VERSION } from "./constants";
|
8
|
+
import { DEFAULT_CONTAINER_RATIO, Events, REQUIRE_VERSION } from "./constants";
|
9
9
|
import { Fields } from "./AttributesDelegate";
|
10
10
|
import { initDb } from "./Register/storage";
|
11
11
|
import { isNull, isObject } from "lodash";
|
12
12
|
import { log } from "./Utils/log";
|
13
|
+
import { ReconnectRefresher } from "./ReconnectRefresher";
|
13
14
|
import { replaceRoomFunction } from "./Utils/RoomHacker";
|
14
|
-
import {
|
15
|
-
import { setupWrapper } from "./
|
15
|
+
import { setupBuiltin } from "./BuiltinApps";
|
16
|
+
import { setupWrapper } from "./Helper";
|
16
17
|
import "./style.css";
|
17
18
|
import "@netless/telebox-insider/dist/style.css";
|
18
19
|
import {
|
@@ -22,7 +23,7 @@ import {
|
|
22
23
|
isValidScenePath,
|
23
24
|
wait,
|
24
25
|
} from "./Utils/Common";
|
25
|
-
import type { TELE_BOX_STATE } from "./BoxManager";
|
26
|
+
import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
|
26
27
|
import {
|
27
28
|
AppCreateError,
|
28
29
|
AppManagerNotInitError,
|
@@ -58,8 +59,6 @@ import type { NetlessApp, RegisterParams } from "./typings";
|
|
58
59
|
import type { TeleBoxColorScheme, TeleBoxState } from "@netless/telebox-insider";
|
59
60
|
import type { AppProxy } from "./AppProxy";
|
60
61
|
|
61
|
-
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
|
62
|
-
|
63
62
|
export type WindowMangerAttributes = {
|
64
63
|
modelValue?: string;
|
65
64
|
boxState: TELE_BOX_STATE;
|
@@ -80,14 +79,14 @@ export type AddAppOptions = {
|
|
80
79
|
|
81
80
|
export type setAppOptions = AddAppOptions & { appOptions?: any };
|
82
81
|
|
83
|
-
export type AddAppParams = {
|
82
|
+
export type AddAppParams<TAttributes = any> = {
|
84
83
|
kind: string;
|
85
84
|
// app 地址(本地 app 不需要传)
|
86
85
|
src?: string;
|
87
86
|
// 窗口配置
|
88
87
|
options?: AddAppOptions;
|
89
88
|
// 初始化 attributes
|
90
|
-
attributes?:
|
89
|
+
attributes?: TAttributes;
|
91
90
|
};
|
92
91
|
|
93
92
|
export type BaseInsertParams = {
|
@@ -108,6 +107,7 @@ export type AppSyncAttributes = {
|
|
108
107
|
state?: any;
|
109
108
|
isDynamicPPT?: boolean;
|
110
109
|
fullPath?: string;
|
110
|
+
createdAt?: number;
|
111
111
|
};
|
112
112
|
|
113
113
|
export type AppInitState = {
|
@@ -137,9 +137,11 @@ export type EmitterEvent = {
|
|
137
137
|
observerIdChange: number;
|
138
138
|
boxStateChange: string;
|
139
139
|
playgroundSizeChange: DOMRect;
|
140
|
+
onReconnected: void;
|
140
141
|
};
|
141
142
|
|
142
|
-
export
|
143
|
+
export type EmitterType = Emittery<EmitterEvent>;
|
144
|
+
export const emitter: EmitterType = new Emittery();
|
143
145
|
|
144
146
|
export type PublicEvent = {
|
145
147
|
mainViewModeChange: ViewVisionMode;
|
@@ -147,11 +149,13 @@ export type PublicEvent = {
|
|
147
149
|
darkModeChange: boolean;
|
148
150
|
prefersColorSchemeChange: TeleBoxColorScheme;
|
149
151
|
cameraStateChange: CameraState;
|
152
|
+
mainViewScenePathChange: string;
|
153
|
+
mainViewSceneIndexChange: number;
|
150
154
|
};
|
151
155
|
|
152
156
|
export type MountParams = {
|
153
157
|
room: Room;
|
154
|
-
container
|
158
|
+
container?: HTMLElement;
|
155
159
|
/** 白板高宽比例, 默认为 9 / 16 */
|
156
160
|
containerSizeRatio?: number;
|
157
161
|
/** 显示 PS 透明背景,默认 true */
|
@@ -165,7 +169,10 @@ export type MountParams = {
|
|
165
169
|
prefersColorScheme?: TeleBoxColorScheme;
|
166
170
|
};
|
167
171
|
|
168
|
-
export
|
172
|
+
export type CallbacksType = Emittery<PublicEvent>;
|
173
|
+
export const callbacks: CallbacksType = new Emittery();
|
174
|
+
|
175
|
+
export const reconnectRefresher = new ReconnectRefresher({ emitter });
|
169
176
|
|
170
177
|
export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
171
178
|
public static kind = "WindowManager";
|
@@ -177,7 +184,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
177
184
|
public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;
|
178
185
|
private static isCreated = false;
|
179
186
|
|
180
|
-
public version =
|
187
|
+
public version = __APP_VERSION__;
|
181
188
|
|
182
189
|
public appListeners?: AppListeners;
|
183
190
|
|
@@ -188,93 +195,40 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
188
195
|
public viewMode = ViewMode.Broadcaster;
|
189
196
|
public isReplay = isPlayer(this.displayer);
|
190
197
|
|
198
|
+
private boxManager?: BoxManager;
|
199
|
+
private static params?: MountParams;
|
200
|
+
|
201
|
+
private containerResizeObserver?: ContainerResizeObserver;
|
202
|
+
|
191
203
|
constructor(context: InvisiblePluginContext) {
|
192
204
|
super(context);
|
205
|
+
WindowManager.displayer = context.displayer;
|
193
206
|
}
|
194
207
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
options?: {
|
204
|
-
chessboard: boolean;
|
205
|
-
containerSizeRatio: number;
|
206
|
-
collectorStyles?: Partial<CSSStyleDeclaration>;
|
207
|
-
debug?: boolean;
|
208
|
-
overwriteStyles?: string;
|
209
|
-
}
|
210
|
-
): Promise<WindowManager>;
|
211
|
-
|
212
|
-
public static async mount(params: MountParams): Promise<WindowManager>;
|
213
|
-
|
214
|
-
public static async mount(
|
215
|
-
params: MountParams | Room,
|
216
|
-
container?: HTMLElement,
|
217
|
-
collectorContainer?: HTMLElement,
|
218
|
-
options?: {
|
219
|
-
chessboard?: boolean;
|
220
|
-
containerSizeRatio: number;
|
221
|
-
collectorStyles?: Partial<CSSStyleDeclaration>;
|
222
|
-
debug?: boolean;
|
223
|
-
overwriteStyles?: string;
|
224
|
-
disableCameraTransform?: boolean;
|
225
|
-
}
|
226
|
-
): Promise<WindowManager> {
|
227
|
-
let room: Room;
|
228
|
-
let containerSizeRatio: number | undefined;
|
229
|
-
let collectorStyles: Partial<CSSStyleDeclaration> | undefined;
|
230
|
-
let debug: boolean | undefined;
|
231
|
-
let chessboard = true;
|
232
|
-
let overwriteStyles: string | undefined;
|
233
|
-
let cursor: boolean | undefined;
|
234
|
-
let disableCameraTransform = false;
|
235
|
-
let prefersColorScheme: TeleBoxColorScheme | undefined = "light";
|
236
|
-
if ("room" in params) {
|
237
|
-
room = params.room;
|
238
|
-
container = params.container;
|
239
|
-
collectorContainer = params.collectorContainer;
|
240
|
-
containerSizeRatio = params.containerSizeRatio;
|
241
|
-
collectorStyles = params.collectorStyles;
|
242
|
-
debug = params.debug;
|
243
|
-
if (params.chessboard != null) {
|
244
|
-
chessboard = params.chessboard;
|
245
|
-
}
|
246
|
-
overwriteStyles = params.overwriteStyles;
|
247
|
-
cursor = params.cursor;
|
248
|
-
disableCameraTransform = Boolean(params?.disableCameraTransform);
|
249
|
-
prefersColorScheme = params.prefersColorScheme;
|
250
|
-
} else {
|
251
|
-
room = params;
|
252
|
-
containerSizeRatio = options?.containerSizeRatio;
|
253
|
-
collectorStyles = options?.collectorStyles;
|
254
|
-
debug = options?.debug;
|
255
|
-
if (options?.chessboard != null) {
|
256
|
-
chessboard = options.chessboard;
|
257
|
-
}
|
258
|
-
overwriteStyles = options?.overwriteStyles;
|
259
|
-
}
|
208
|
+
public static async mount(params: MountParams): Promise<WindowManager> {
|
209
|
+
const room = params.room;
|
210
|
+
WindowManager.container = params.container;
|
211
|
+
const containerSizeRatio = params.containerSizeRatio;
|
212
|
+
const debug = params.debug;
|
213
|
+
|
214
|
+
const cursor = params.cursor;
|
215
|
+
WindowManager.params = params;
|
260
216
|
|
261
217
|
this.checkVersion();
|
262
218
|
if (isRoom(room)) {
|
263
219
|
if (room.phase !== RoomPhase.Connected) {
|
264
220
|
throw new Error("[WindowManager]: Room only Connected can be mount");
|
265
221
|
}
|
266
|
-
|
267
|
-
|
268
|
-
|
222
|
+
if (room.phase === RoomPhase.Connected) {
|
223
|
+
// redo undo 需要设置这个属性
|
224
|
+
room.disableSerialization = false;
|
225
|
+
}
|
269
226
|
}
|
270
227
|
if (WindowManager.isCreated) {
|
271
228
|
throw new Error("[WindowManager]: Already created cannot be created again");
|
272
229
|
}
|
273
230
|
let manager = await this.initManager(room);
|
274
231
|
this.debug = Boolean(debug);
|
275
|
-
if (this.debug) {
|
276
|
-
setOptions({ verbose: true });
|
277
|
-
}
|
278
232
|
log("Already insert room", manager);
|
279
233
|
|
280
234
|
if (isRoom(this.displayer)) {
|
@@ -297,29 +251,19 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
297
251
|
if (containerSizeRatio) {
|
298
252
|
WindowManager.containerSizeRatio = containerSizeRatio;
|
299
253
|
}
|
300
|
-
WindowManager.container = container;
|
301
|
-
const { playground, wrapper, sizer, mainViewElement } = setupWrapper(container);
|
302
|
-
WindowManager.playground = playground;
|
303
|
-
if (chessboard) {
|
304
|
-
sizer.classList.add("netless-window-manager-chess-sizer");
|
305
|
-
}
|
306
|
-
if (overwriteStyles) {
|
307
|
-
const style = document.createElement("style");
|
308
|
-
style.textContent = overwriteStyles;
|
309
|
-
playground.appendChild(style);
|
310
|
-
}
|
311
254
|
await manager.ensureAttributes();
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
prefersColorScheme: prefersColorScheme,
|
316
|
-
});
|
317
|
-
manager.observePlaygroundSize(playground, sizer, wrapper);
|
255
|
+
|
256
|
+
manager.appManager = new AppManager(manager);
|
257
|
+
|
318
258
|
if (cursor) {
|
319
259
|
manager.cursorManager = new CursorManager(manager.appManager);
|
320
260
|
}
|
321
|
-
|
322
|
-
|
261
|
+
|
262
|
+
if (params.container) {
|
263
|
+
manager.bindContainer(params.container);
|
264
|
+
}
|
265
|
+
|
266
|
+
replaceRoomFunction(room, manager);
|
323
267
|
emitter.emit("onCreated");
|
324
268
|
WindowManager.isCreated = true;
|
325
269
|
try {
|
@@ -359,6 +303,79 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
359
303
|
return manager;
|
360
304
|
}
|
361
305
|
|
306
|
+
private static initContainer(
|
307
|
+
manager: WindowManager,
|
308
|
+
container: HTMLElement,
|
309
|
+
chessboard: boolean | undefined,
|
310
|
+
overwriteStyles: string | undefined
|
311
|
+
) {
|
312
|
+
if (!WindowManager.container) {
|
313
|
+
WindowManager.container = container;
|
314
|
+
}
|
315
|
+
const { playground, wrapper, sizer, mainViewElement } = setupWrapper(container);
|
316
|
+
WindowManager.playground = playground;
|
317
|
+
if (chessboard) {
|
318
|
+
sizer.classList.add("netless-window-manager-chess-sizer");
|
319
|
+
}
|
320
|
+
if (overwriteStyles) {
|
321
|
+
const style = document.createElement("style");
|
322
|
+
style.textContent = overwriteStyles;
|
323
|
+
playground.appendChild(style);
|
324
|
+
}
|
325
|
+
manager.containerResizeObserver = ContainerResizeObserver.create(
|
326
|
+
playground,
|
327
|
+
sizer,
|
328
|
+
wrapper,
|
329
|
+
emitter
|
330
|
+
);
|
331
|
+
WindowManager.wrapper = wrapper;
|
332
|
+
return mainViewElement;
|
333
|
+
}
|
334
|
+
|
335
|
+
public bindContainer(container: HTMLElement) {
|
336
|
+
if (WindowManager.isCreated && WindowManager.container) {
|
337
|
+
if (WindowManager.container.firstChild) {
|
338
|
+
container.appendChild(WindowManager.container.firstChild);
|
339
|
+
}
|
340
|
+
} else {
|
341
|
+
if (WindowManager.params) {
|
342
|
+
const params = WindowManager.params;
|
343
|
+
const mainViewElement = WindowManager.initContainer(
|
344
|
+
this,
|
345
|
+
container,
|
346
|
+
params.chessboard,
|
347
|
+
params.overwriteStyles
|
348
|
+
);
|
349
|
+
const boxManager = createBoxManager(this, callbacks, emitter, {
|
350
|
+
collectorContainer: params.collectorContainer,
|
351
|
+
collectorStyles: params.collectorStyles,
|
352
|
+
prefersColorScheme: params.prefersColorScheme,
|
353
|
+
});
|
354
|
+
this.boxManager = boxManager;
|
355
|
+
this.appManager?.setBoxManager(boxManager);
|
356
|
+
this.bindMainView(mainViewElement, params.disableCameraTransform);
|
357
|
+
if (WindowManager.wrapper) {
|
358
|
+
this.cursorManager?.setupWrapper(WindowManager.wrapper);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
}
|
362
|
+
this.boxManager?.updateManagerRect();
|
363
|
+
this.appManager?.refresh();
|
364
|
+
this.appManager?.resetMaximized();
|
365
|
+
this.appManager?.resetMinimized();
|
366
|
+
WindowManager.container = container;
|
367
|
+
}
|
368
|
+
|
369
|
+
public bindCollectorContainer(container: HTMLElement) {
|
370
|
+
if (WindowManager.isCreated && this.boxManager) {
|
371
|
+
this.boxManager.setCollectorContainer(container);
|
372
|
+
} else {
|
373
|
+
if (WindowManager.params) {
|
374
|
+
WindowManager.params.collectorContainer = container;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
362
379
|
/**
|
363
380
|
* 注册插件
|
364
381
|
*/
|
@@ -371,7 +388,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
371
388
|
/**
|
372
389
|
* 创建一个 app 至白板
|
373
390
|
*/
|
374
|
-
public async addApp(params: AddAppParams): Promise<string | undefined> {
|
391
|
+
public async addApp<T = any>(params: AddAppParams<T>): Promise<string | undefined> {
|
375
392
|
if (this.appManager) {
|
376
393
|
if (!params.kind || typeof params.kind !== "string") {
|
377
394
|
throw new ParamsInvalidError();
|
@@ -468,10 +485,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
468
485
|
* 设置所有 app 的 readonly 模式
|
469
486
|
*/
|
470
487
|
public setReadonly(readonly: boolean): void {
|
471
|
-
|
472
|
-
|
473
|
-
this.appManager?.boxManager.setReadonly(readonly);
|
474
|
-
}
|
488
|
+
this.readonly = readonly;
|
489
|
+
this.boxManager?.setReadonly(readonly);
|
475
490
|
}
|
476
491
|
|
477
492
|
/**
|
@@ -531,26 +546,30 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
531
546
|
return this.appManager?.store.apps();
|
532
547
|
}
|
533
548
|
|
534
|
-
public get boxState(): TeleBoxState {
|
549
|
+
public get boxState(): TeleBoxState | undefined {
|
535
550
|
if (this.appManager) {
|
536
|
-
return this.appManager.boxManager
|
551
|
+
return this.appManager.boxManager?.boxState;
|
537
552
|
} else {
|
538
553
|
throw new AppManagerNotInitError();
|
539
554
|
}
|
540
555
|
}
|
541
556
|
|
542
557
|
public get darkMode(): boolean {
|
543
|
-
return Boolean(this.appManager?.boxManager
|
558
|
+
return Boolean(this.appManager?.boxManager?.darkMode);
|
544
559
|
}
|
545
560
|
|
546
|
-
public get prefersColorScheme(): TeleBoxColorScheme {
|
561
|
+
public get prefersColorScheme(): TeleBoxColorScheme | undefined {
|
547
562
|
if (this.appManager) {
|
548
|
-
return this.appManager.boxManager
|
563
|
+
return this.appManager.boxManager?.prefersColorScheme;
|
549
564
|
} else {
|
550
565
|
throw new AppManagerNotInitError();
|
551
566
|
}
|
552
567
|
}
|
553
568
|
|
569
|
+
public get focused(): string | undefined {
|
570
|
+
return this.attributes.focus;
|
571
|
+
}
|
572
|
+
|
554
573
|
/**
|
555
574
|
* 查询所有的 App
|
556
575
|
*/
|
@@ -585,6 +604,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
585
604
|
}>
|
586
605
|
): void {
|
587
606
|
this.mainView.moveCameraToContain(rectangle);
|
607
|
+
this.appManager?.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
|
608
|
+
setTimeout(() => {
|
609
|
+
this.appManager?.mainViewProxy.setCameraAndSize();
|
610
|
+
}, 1000);
|
588
611
|
}
|
589
612
|
|
590
613
|
public convertToPointInWorld(point: Point): Point {
|
@@ -613,12 +636,13 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
613
636
|
if (WindowManager.playground) {
|
614
637
|
WindowManager.playground.parentNode?.removeChild(WindowManager.playground);
|
615
638
|
}
|
639
|
+
WindowManager.params = undefined;
|
616
640
|
log("Destroyed");
|
617
641
|
}
|
618
642
|
|
619
|
-
private bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean) {
|
643
|
+
private bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean | undefined) {
|
620
644
|
if (this.appManager) {
|
621
|
-
this.appManager.bindMainView(divElement, disableCameraTransform);
|
645
|
+
this.appManager.bindMainView(divElement, Boolean(disableCameraTransform));
|
622
646
|
this.cursorManager?.setMainViewDivElement(divElement);
|
623
647
|
}
|
624
648
|
}
|
@@ -651,7 +675,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
651
675
|
}
|
652
676
|
|
653
677
|
public setPrefersColorScheme(scheme: TeleBoxColorScheme): void {
|
654
|
-
this.appManager?.boxManager
|
678
|
+
this.appManager?.boxManager?.setPrefersColorScheme(scheme);
|
655
679
|
}
|
656
680
|
|
657
681
|
private isDynamicPPT(scenes: SceneDefinition[]) {
|
@@ -686,62 +710,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
|
|
686
710
|
}
|
687
711
|
}
|
688
712
|
}
|
689
|
-
|
690
|
-
private containerResizeObserver?: ResizeObserver;
|
691
|
-
|
692
|
-
private observePlaygroundSize(
|
693
|
-
container: HTMLElement,
|
694
|
-
sizer: HTMLElement,
|
695
|
-
wrapper: HTMLDivElement
|
696
|
-
) {
|
697
|
-
this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
|
698
|
-
|
699
|
-
this.containerResizeObserver = new ResizeObserver(entries => {
|
700
|
-
const containerRect = entries[0]?.contentRect;
|
701
|
-
if (containerRect) {
|
702
|
-
this.updateSizer(containerRect, sizer, wrapper);
|
703
|
-
this.cursorManager?.updateContainerRect();
|
704
|
-
this.appManager?.boxManager.updateManagerRect();
|
705
|
-
emitter.emit("playgroundSizeChange", containerRect);
|
706
|
-
}
|
707
|
-
});
|
708
|
-
|
709
|
-
this.containerResizeObserver.observe(container);
|
710
|
-
}
|
711
|
-
|
712
|
-
private updateSizer(
|
713
|
-
{ width, height }: DOMRectReadOnly,
|
714
|
-
sizer: HTMLElement,
|
715
|
-
wrapper: HTMLDivElement
|
716
|
-
) {
|
717
|
-
if (width && height) {
|
718
|
-
if (height / width > WindowManager.containerSizeRatio) {
|
719
|
-
height = width * WindowManager.containerSizeRatio;
|
720
|
-
sizer.classList.toggle("netless-window-manager-sizer-horizontal", true);
|
721
|
-
} else {
|
722
|
-
width = height / WindowManager.containerSizeRatio;
|
723
|
-
sizer.classList.toggle("netless-window-manager-sizer-horizontal", false);
|
724
|
-
}
|
725
|
-
wrapper.style.width = `${width}px`;
|
726
|
-
wrapper.style.height = `${height}px`;
|
727
|
-
}
|
728
|
-
}
|
729
713
|
}
|
730
714
|
|
731
|
-
|
732
|
-
kind: AppDocsViewer.kind,
|
733
|
-
src: AppDocsViewer,
|
734
|
-
});
|
735
|
-
WindowManager.register({
|
736
|
-
kind: AppMediaPlayer.kind,
|
737
|
-
src: AppMediaPlayer,
|
738
|
-
});
|
739
|
-
|
740
|
-
export const BuiltinApps = {
|
741
|
-
DocsViewer: AppDocsViewer.kind as string,
|
742
|
-
MediaPlayer: AppMediaPlayer.kind as string,
|
743
|
-
};
|
715
|
+
setupBuiltin();
|
744
716
|
|
745
717
|
export * from "./typings";
|
746
718
|
|
747
|
-
export {
|
719
|
+
export { BuiltinApps } from "./BuiltinApps";
|