@netless/window-manager 0.4.0-canary.3 → 0.4.0-canary.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/window-manager.iml +12 -0
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +32 -1
- package/README.md +2 -0
- package/dist/App/MagixEvent/index.d.ts +29 -0
- package/dist/App/Storage/StorageEvent.d.ts +8 -0
- package/dist/App/Storage/index.d.ts +39 -0
- package/dist/App/Storage/typings.d.ts +22 -0
- package/dist/App/Storage/utils.d.ts +5 -0
- package/dist/AppContext.d.ts +40 -16
- package/dist/AppListener.d.ts +1 -1
- package/dist/AppManager.d.ts +26 -12
- package/dist/AppProxy.d.ts +7 -8
- package/dist/AttributesDelegate.d.ts +2 -2
- package/dist/BoxManager.d.ts +6 -3
- package/dist/BuiltinApps.d.ts +5 -0
- package/dist/ContainerResizeObserver.d.ts +10 -0
- package/dist/Cursor/Cursor.d.ts +10 -12
- package/dist/Cursor/index.d.ts +6 -16
- package/dist/Helper.d.ts +7 -0
- package/dist/ReconnectRefresher.d.ts +0 -1
- package/dist/Register/storage.d.ts +5 -1
- package/dist/Utils/AppCreateQueue.d.ts +11 -0
- package/dist/Utils/Common.d.ts +7 -2
- package/dist/Utils/Reactive.d.ts +1 -1
- package/dist/Utils/RoomHacker.d.ts +3 -3
- package/dist/{MainView.d.ts → View/MainView.d.ts} +5 -6
- package/dist/View/ViewManager.d.ts +13 -0
- package/dist/constants.d.ts +4 -7
- package/dist/index.d.ts +36 -14
- package/dist/index.es.js +41 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +41 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/typings.d.ts +3 -2
- package/docs/api.md +69 -6
- package/docs/concept.md +9 -0
- package/docs/replay.md +40 -0
- package/package.json +7 -6
- package/src/App/MagixEvent/index.ts +68 -0
- package/src/App/Storage/StorageEvent.ts +21 -0
- package/src/App/Storage/index.ts +289 -0
- package/src/App/Storage/typings.ts +23 -0
- package/src/App/Storage/utils.ts +17 -0
- package/src/AppContext.ts +69 -24
- package/src/AppListener.ts +15 -14
- package/src/AppManager.ts +261 -83
- package/src/AppProxy.ts +53 -64
- package/src/AttributesDelegate.ts +2 -2
- package/src/BoxManager.ts +40 -24
- package/src/BuiltinApps.ts +23 -0
- package/src/ContainerResizeObserver.ts +62 -0
- package/src/Cursor/Cursor.svelte +25 -21
- package/src/Cursor/Cursor.ts +25 -38
- package/src/Cursor/icons.ts +2 -0
- package/src/Cursor/index.ts +45 -139
- package/src/Helper.ts +41 -0
- package/src/ReconnectRefresher.ts +0 -5
- package/src/Register/index.ts +25 -16
- package/src/Register/loader.ts +2 -2
- package/src/Register/storage.ts +6 -1
- package/src/Utils/AppCreateQueue.ts +54 -0
- package/src/Utils/Common.ts +69 -14
- package/src/Utils/Reactive.ts +9 -3
- package/src/Utils/RoomHacker.ts +44 -14
- package/src/{MainView.ts → View/MainView.ts} +25 -36
- package/src/View/ViewManager.ts +52 -0
- package/src/constants.ts +5 -4
- package/src/image/laser-pointer-cursor.svg +17 -0
- package/src/index.ts +158 -99
- package/src/shim.d.ts +5 -0
- package/src/style.css +7 -1
- package/src/typings.ts +3 -2
- package/vite.config.js +8 -2
- package/dist/Base/Context.d.ts +0 -13
- package/dist/Base/index.d.ts +0 -7
- package/dist/Utils/CameraStore.d.ts +0 -15
- package/dist/ViewManager.d.ts +0 -29
- package/dist/sdk.d.ts +0 -14
- package/src/Base/Context.ts +0 -49
- package/src/Base/index.ts +0 -10
- package/src/Utils/CameraStore.ts +0 -72
- package/src/sdk.ts +0 -39
- package/src/viewManager.ts +0 -177
package/src/AppProxy.ts
CHANGED
@@ -2,17 +2,13 @@ import Emittery from "emittery";
|
|
2
2
|
import { AppAttributes, AppEvents, Events } from "./constants";
|
3
3
|
import { AppContext } from "./AppContext";
|
4
4
|
import { appRegister } from "./Register";
|
5
|
-
import { autorun
|
6
|
-
import {
|
5
|
+
import { autorun } from "white-web-sdk";
|
6
|
+
import { BoxManagerNotFoundError } from "./Utils/error";
|
7
|
+
import { debounce, get } from "lodash";
|
8
|
+
import { emitter } from "./index";
|
7
9
|
import { Fields } from "./AttributesDelegate";
|
8
|
-
import {
|
10
|
+
import { entireScenes, getScenePath, removeScenes, setScenePath, setViewFocusScenePath } from "./Utils/Common";
|
9
11
|
import { log } from "./Utils/log";
|
10
|
-
import {
|
11
|
-
notifyMainViewModeChange,
|
12
|
-
setScenePath,
|
13
|
-
setViewFocusScenePath,
|
14
|
-
setViewMode,
|
15
|
-
} from "./Utils/Common";
|
16
12
|
import type {
|
17
13
|
AppEmitterEvent,
|
18
14
|
AppInitState,
|
@@ -24,10 +20,9 @@ import type { SceneState, View, SceneDefinition } from "white-web-sdk";
|
|
24
20
|
import type { AppManager } from "./AppManager";
|
25
21
|
import type { NetlessApp } from "./typings";
|
26
22
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
27
|
-
import { Base } from "./Base";
|
28
|
-
import { BoxManagerNotFoundError } from "./Utils/error";
|
29
23
|
|
30
|
-
export class AppProxy
|
24
|
+
export class AppProxy {
|
25
|
+
public kind: string;
|
31
26
|
public id: string;
|
32
27
|
public scenePath?: string;
|
33
28
|
public appEmitter: Emittery<AppEmitterEvent>;
|
@@ -37,8 +32,8 @@ export class AppProxy extends Base {
|
|
37
32
|
private boxManager = this.manager.boxManager;
|
38
33
|
private appProxies = this.manager.appProxies;
|
39
34
|
private viewManager = this.manager.viewManager;
|
40
|
-
private
|
41
|
-
|
35
|
+
private store = this.manager.store;
|
36
|
+
|
42
37
|
public isAddApp: boolean;
|
43
38
|
private status: "normal" | "destroyed" = "normal";
|
44
39
|
private stateKey: string;
|
@@ -47,11 +42,10 @@ export class AppProxy extends Base {
|
|
47
42
|
|
48
43
|
constructor(
|
49
44
|
private params: BaseInsertParams,
|
50
|
-
manager: AppManager,
|
45
|
+
private manager: AppManager,
|
51
46
|
appId: string,
|
52
47
|
isAddApp: boolean
|
53
48
|
) {
|
54
|
-
super(manager);
|
55
49
|
this.kind = params.kind;
|
56
50
|
this.id = appId;
|
57
51
|
this.stateKey = `${this.id}_state`;
|
@@ -73,7 +67,7 @@ export class AppProxy extends Base {
|
|
73
67
|
if (options) {
|
74
68
|
this.scenePath = options.scenePath;
|
75
69
|
if (this.appAttributes?.isDynamicPPT && this.scenePath) {
|
76
|
-
this.scenes = this.manager.displayer
|
70
|
+
this.scenes = entireScenes(this.manager.displayer)[this.scenePath];
|
77
71
|
} else {
|
78
72
|
this.scenes = options.scenes;
|
79
73
|
}
|
@@ -98,18 +92,24 @@ export class AppProxy extends Base {
|
|
98
92
|
|
99
93
|
public getFullScenePath(): string | undefined {
|
100
94
|
if (this.scenePath) {
|
101
|
-
return get(this.appAttributes, [Fields.FullPath], this.
|
95
|
+
return get(this.appAttributes, [Fields.FullPath], this.getFullScenePathFromScenes());
|
102
96
|
}
|
103
97
|
}
|
104
98
|
|
99
|
+
private getFullScenePathFromScenes() {
|
100
|
+
const sceneIndex = get(this.appAttributes, ["state", "SceneIndex"], 0);
|
101
|
+
const fullPath = getScenePath(this.manager.room, this.scenePath, sceneIndex);
|
102
|
+
if (fullPath) {
|
103
|
+
this.setFullPath(fullPath);
|
104
|
+
}
|
105
|
+
return fullPath;
|
106
|
+
}
|
107
|
+
|
105
108
|
public setFullPath(path: string) {
|
106
109
|
this.manager.safeUpdateAttributes(["apps", this.id, Fields.FullPath], path);
|
107
110
|
}
|
108
111
|
|
109
|
-
public async baseInsertApp(
|
110
|
-
skipUpdate = false,
|
111
|
-
focus?: boolean
|
112
|
-
): Promise<{ appId: string; app: NetlessApp }> {
|
112
|
+
public async baseInsertApp(skipUpdate = false): Promise<{ appId: string; app: NetlessApp }> {
|
113
113
|
const params = this.params;
|
114
114
|
if (!params.kind) {
|
115
115
|
throw new Error("[WindowManager]: kind require");
|
@@ -117,34 +117,27 @@ export class AppProxy extends Base {
|
|
117
117
|
const appImpl = await appRegister.appClasses.get(params.kind)?.();
|
118
118
|
const appParams = appRegister.registered.get(params.kind);
|
119
119
|
if (appImpl) {
|
120
|
-
await this.setupApp(
|
120
|
+
await this.setupApp(
|
121
|
+
this.id,
|
122
|
+
skipUpdate,
|
123
|
+
appImpl,
|
124
|
+
params.options,
|
125
|
+
appParams?.appOptions
|
126
|
+
);
|
121
127
|
} else {
|
122
128
|
throw new Error(`[WindowManager]: app load failed ${params.kind} ${params.src}`);
|
123
129
|
}
|
124
|
-
this.
|
125
|
-
if (focus) {
|
126
|
-
this.focusApp();
|
127
|
-
}
|
130
|
+
this.boxManager?.updateManagerRect();
|
128
131
|
return {
|
129
132
|
appId: this.id,
|
130
133
|
app: appImpl,
|
131
134
|
};
|
132
135
|
}
|
133
136
|
|
134
|
-
private focusApp() {
|
135
|
-
this.focusBox();
|
136
|
-
this.context.switchAppToWriter(this.id);
|
137
|
-
this.store.setMainViewFocusPath(this.manager.mainView);
|
138
|
-
}
|
139
|
-
|
140
137
|
public get box(): ReadonlyTeleBox | undefined {
|
141
138
|
return this.boxManager?.getBox(this.id);
|
142
139
|
}
|
143
140
|
|
144
|
-
public focusBox() {
|
145
|
-
this.boxManager?.focusBox({ appId: this.id });
|
146
|
-
}
|
147
|
-
|
148
141
|
private async setupApp(
|
149
142
|
appId: string,
|
150
143
|
skipUpdate: boolean,
|
@@ -172,7 +165,7 @@ export class AppProxy extends Base {
|
|
172
165
|
// 延迟执行 setup, 防止初始化的属性没有更新成功
|
173
166
|
const result = await app.setup(context);
|
174
167
|
this.appResult = result;
|
175
|
-
appRegister.notifyApp(
|
168
|
+
appRegister.notifyApp(this.kind, "created", { appId, result });
|
176
169
|
this.afterSetupApp(boxInitState);
|
177
170
|
this.fixMobileSize();
|
178
171
|
}, 50);
|
@@ -184,6 +177,10 @@ export class AppProxy extends Base {
|
|
184
177
|
canOperate: this.manager.canOperate,
|
185
178
|
smartPosition: this.isAddApp,
|
186
179
|
});
|
180
|
+
if (this.isAddApp && this.box) {
|
181
|
+
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
182
|
+
this.boxManager.focusBox({ appId }, false);
|
183
|
+
}
|
187
184
|
} catch (error: any) {
|
188
185
|
console.error(error);
|
189
186
|
throw new Error(`[WindowManager]: app setup error: ${error.message}`);
|
@@ -205,9 +202,6 @@ export class AppProxy extends Base {
|
|
205
202
|
|
206
203
|
private afterSetupApp(boxInitState: AppInitState | undefined): void {
|
207
204
|
if (boxInitState) {
|
208
|
-
if (boxInitState.focus && this.scenePath) {
|
209
|
-
this.context.switchAppToWriter(this.id);
|
210
|
-
}
|
211
205
|
if (!boxInitState?.x || !boxInitState.y) {
|
212
206
|
this.boxManager?.setBoxInitState(this.id);
|
213
207
|
}
|
@@ -226,29 +220,10 @@ export class AppProxy extends Base {
|
|
226
220
|
await this.destroy(true, false, true);
|
227
221
|
const params = this.params;
|
228
222
|
const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);
|
229
|
-
await appProxy.baseInsertApp(true
|
223
|
+
await appProxy.baseInsertApp(true);
|
230
224
|
this.boxManager?.updateBoxState(currentAppState);
|
231
225
|
}
|
232
226
|
|
233
|
-
public switchToWritable() {
|
234
|
-
appRegister.notifyApp(this.kind, "focus", { appId: this.id });
|
235
|
-
this.cameraStore.switchView(this.id, this.view, () => {
|
236
|
-
if (this.view) {
|
237
|
-
if (this.view.mode === ViewVisionMode.Writable) return;
|
238
|
-
try {
|
239
|
-
if (this.manager.mainView.mode === ViewVisionMode.Writable) {
|
240
|
-
this.store.setMainViewFocusPath(this.manager.mainView);
|
241
|
-
notifyMainViewModeChange(callbacks, ViewVisionMode.Freedom);
|
242
|
-
setViewMode(this.manager.mainView, ViewVisionMode.Freedom);
|
243
|
-
}
|
244
|
-
setViewMode(this.view, ViewVisionMode.Writable);
|
245
|
-
} catch (error) {
|
246
|
-
log("switch view failed", error);
|
247
|
-
}
|
248
|
-
}
|
249
|
-
});
|
250
|
-
}
|
251
|
-
|
252
227
|
public getAppInitState = (id: string) => {
|
253
228
|
const attrs = this.store.getAppState(id);
|
254
229
|
if (!attrs) return;
|
@@ -337,7 +312,7 @@ export class AppProxy extends Base {
|
|
337
312
|
}
|
338
313
|
});
|
339
314
|
});
|
340
|
-
this.manager.refresher?.add(this.stateKey,() => {
|
315
|
+
this.manager.refresher?.add(this.stateKey, () => {
|
341
316
|
return autorun(() => {
|
342
317
|
const appState = this.appAttributes?.state;
|
343
318
|
if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
|
@@ -345,8 +320,20 @@ export class AppProxy extends Base {
|
|
345
320
|
}
|
346
321
|
});
|
347
322
|
});
|
323
|
+
this.manager.refresher?.add(`${appId}-fullPath`, () => {
|
324
|
+
return autorun(() => {
|
325
|
+
const fullPath = this.appAttributes?.fullPath;
|
326
|
+
this.setFocusScenePathHandler(fullPath);
|
327
|
+
});
|
328
|
+
});
|
348
329
|
};
|
349
330
|
|
331
|
+
private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
|
332
|
+
if (this.view && fullPath && fullPath !== this.view?.focusScenePath) {
|
333
|
+
setViewFocusScenePath(this.view, fullPath);
|
334
|
+
}
|
335
|
+
}, 50);
|
336
|
+
|
350
337
|
public setScenePath(): void {
|
351
338
|
if (!this.manager.canOperate) return;
|
352
339
|
const fullScenePath = this.getFullScenePath();
|
@@ -364,7 +351,6 @@ export class AppProxy extends Base {
|
|
364
351
|
|
365
352
|
private async createView(): Promise<View> {
|
366
353
|
const view = await this.viewManager.createView(this.id);
|
367
|
-
this.cameraStore.register(this.id, view);
|
368
354
|
this.setViewFocusScenePath();
|
369
355
|
return view;
|
370
356
|
}
|
@@ -386,14 +372,17 @@ export class AppProxy extends Base {
|
|
386
372
|
}
|
387
373
|
if (cleanAttrs) {
|
388
374
|
this.store.cleanAppAttributes(this.id);
|
375
|
+
if (this.scenePath) {
|
376
|
+
removeScenes(this.manager.room, this.scenePath);
|
377
|
+
}
|
389
378
|
}
|
390
379
|
this.appProxies.delete(this.id);
|
391
|
-
this.cameraStore.unregister(this.id, this.view);
|
392
380
|
|
393
381
|
this.viewManager.destroyView(this.id);
|
394
382
|
this.manager.appStatus.delete(this.id);
|
395
383
|
this.manager.refresher?.remove(this.id);
|
396
384
|
this.manager.refresher?.remove(this.stateKey);
|
385
|
+
this.manager.refresher?.remove(`${this.id}-fullPath`);
|
397
386
|
}
|
398
387
|
|
399
388
|
public close(): Promise<void> {
|
@@ -123,7 +123,7 @@ export class AttributesDelegate {
|
|
123
123
|
return this.getAppAttributes(id)?.options?.scenePath;
|
124
124
|
}
|
125
125
|
|
126
|
-
public getMainViewScenePath() {
|
126
|
+
public getMainViewScenePath(): string | undefined {
|
127
127
|
return this.attributes["_mainScenePath"];
|
128
128
|
}
|
129
129
|
|
@@ -159,7 +159,7 @@ export class AttributesDelegate {
|
|
159
159
|
this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
|
160
160
|
}
|
161
161
|
|
162
|
-
public setAppFocus(appId: string, focus: boolean) {
|
162
|
+
public setAppFocus = (appId: string, focus: boolean) => {
|
163
163
|
if (focus) {
|
164
164
|
this.context.safeSetAttributes({ [Fields.Focus]: appId });
|
165
165
|
} else {
|
package/src/BoxManager.ts
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
import { AppAttributes,
|
2
|
-
import { debounce
|
1
|
+
import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
|
2
|
+
import { debounce } from "lodash";
|
3
|
+
import { emitter, WindowManager } from "./index";
|
3
4
|
import {
|
4
|
-
TELE_BOX_MANAGER_EVENT,
|
5
5
|
TELE_BOX_STATE,
|
6
6
|
TeleBoxCollector,
|
7
7
|
TeleBoxManager,
|
8
8
|
} from "@netless/telebox-insider";
|
9
|
-
import { WindowManager } from "./index";
|
10
9
|
import type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from "./index";
|
11
10
|
import type {
|
12
11
|
TeleBoxManagerUpdateConfig,
|
@@ -15,6 +14,7 @@ import type {
|
|
15
14
|
TeleBoxManagerConfig,
|
16
15
|
TeleBoxColorScheme,
|
17
16
|
TeleBoxRect,
|
17
|
+
TeleBoxConfig,
|
18
18
|
} from "@netless/telebox-insider";
|
19
19
|
import type Emittery from "emittery";
|
20
20
|
import type { NetlessApp } from "./typings";
|
@@ -57,6 +57,7 @@ export type BoxManagerContext = {
|
|
57
57
|
canOperate: () => boolean;
|
58
58
|
notifyContainerRectUpdate: (rect: TeleBoxRect) => void;
|
59
59
|
cleanFocus: () => void;
|
60
|
+
setAppFocus: (appId: string) => void;
|
60
61
|
};
|
61
62
|
|
62
63
|
export const createBoxManager = (
|
@@ -74,6 +75,7 @@ export const createBoxManager = (
|
|
74
75
|
notifyContainerRectUpdate: (rect: TeleBoxRect) =>
|
75
76
|
manager.appManager?.notifyContainerRectUpdate(rect),
|
76
77
|
cleanFocus: () => manager.appManager?.store.cleanFocus(),
|
78
|
+
setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
|
77
79
|
callbacks,
|
78
80
|
emitter,
|
79
81
|
},
|
@@ -90,17 +92,32 @@ export class BoxManager {
|
|
90
92
|
) {
|
91
93
|
const { emitter, callbacks } = context;
|
92
94
|
this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
|
96
|
+
// 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
|
97
|
+
this.teleBoxManager._state$.reaction(state => {
|
98
|
+
callbacks.emit("boxStateChange", state);
|
99
|
+
emitter.emit("boxStateChange", state);
|
100
|
+
});
|
101
|
+
|
102
|
+
this.teleBoxManager._darkMode$.reaction(darkMode => {
|
103
|
+
callbacks.emit("darkModeChange", darkMode);
|
98
104
|
});
|
105
|
+
this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
|
106
|
+
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
107
|
+
});
|
108
|
+
|
109
|
+
// events.on 的值则会根据 skipUpdate 来决定是否触发回调
|
99
110
|
this.teleBoxManager.events.on("minimized", minimized => {
|
100
111
|
this.context.safeSetAttributes({ minimized });
|
101
112
|
if (minimized) {
|
102
113
|
this.context.cleanFocus();
|
103
114
|
this.blurAllBox();
|
115
|
+
} else {
|
116
|
+
const topBox = this.getTopBox();
|
117
|
+
if (topBox) {
|
118
|
+
this.context.setAppFocus(topBox.id);
|
119
|
+
this.focusBox({ appId: topBox.id }, false);
|
120
|
+
}
|
104
121
|
}
|
105
122
|
});
|
106
123
|
this.teleBoxManager.events.on("maximized", maximized => {
|
@@ -136,17 +153,16 @@ export class BoxManager {
|
|
136
153
|
}
|
137
154
|
}
|
138
155
|
});
|
139
|
-
this.teleBoxManager.events.on("dark_mode", darkMode => {
|
140
|
-
callbacks.emit("darkModeChange", darkMode);
|
141
|
-
});
|
142
|
-
this.teleBoxManager.events.on("prefers_color_scheme", colorScheme => {
|
143
|
-
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
144
|
-
});
|
145
156
|
this.teleBoxManager.events.on("z_index", box => {
|
146
157
|
this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
|
147
158
|
});
|
159
|
+
emitter.on("playgroundSizeChange", this.playgroundSizeChangeListener);
|
148
160
|
}
|
149
161
|
|
162
|
+
private playgroundSizeChangeListener = () => {
|
163
|
+
this.updateManagerRect();
|
164
|
+
};
|
165
|
+
|
150
166
|
private get mainView() {
|
151
167
|
return this.context.getMainView();
|
152
168
|
}
|
@@ -251,12 +267,8 @@ export class BoxManager {
|
|
251
267
|
}
|
252
268
|
|
253
269
|
public setCollectorContainer(container: HTMLElement) {
|
254
|
-
const styles = {
|
255
|
-
...DEFAULT_COLLECTOR_STYLE,
|
256
|
-
...this.createTeleBoxManagerConfig?.collectorStyles,
|
257
|
-
};
|
258
270
|
const collector = new TeleBoxCollector({
|
259
|
-
styles
|
271
|
+
styles: this.createTeleBoxManagerConfig?.collectorStyles,
|
260
272
|
}).mount(container);
|
261
273
|
this.teleBoxManager.setCollector(collector);
|
262
274
|
}
|
@@ -280,8 +292,7 @@ export class BoxManager {
|
|
280
292
|
}
|
281
293
|
|
282
294
|
public getTopBox(): ReadonlyTeleBox | undefined {
|
283
|
-
|
284
|
-
return maxBy(boxes, "zIndex");
|
295
|
+
return this.teleBoxManager.topBox;
|
285
296
|
}
|
286
297
|
|
287
298
|
public updateBoxState(state?: AppInitState): void {
|
@@ -358,9 +369,9 @@ export class BoxManager {
|
|
358
369
|
this.teleBoxManager.updateAll(config);
|
359
370
|
}
|
360
371
|
|
361
|
-
public setMaximized(maximized: boolean) {
|
372
|
+
public setMaximized(maximized: boolean, skipUpdate = true): void {
|
362
373
|
if (maximized !== this.maximized) {
|
363
|
-
this.teleBoxManager.setMaximized(maximized,
|
374
|
+
this.teleBoxManager.setMaximized(maximized, skipUpdate);
|
364
375
|
}
|
365
376
|
}
|
366
377
|
|
@@ -378,6 +389,10 @@ export class BoxManager {
|
|
378
389
|
}
|
379
390
|
}
|
380
391
|
|
392
|
+
public updateBox(id: string, payload: TeleBoxConfig, skipUpdate = true): void {
|
393
|
+
this.teleBoxManager.update(id, payload, skipUpdate);
|
394
|
+
}
|
395
|
+
|
381
396
|
public setReadonly(readonly: boolean) {
|
382
397
|
this.teleBoxManager.setReadonly(readonly);
|
383
398
|
}
|
@@ -391,6 +406,7 @@ export class BoxManager {
|
|
391
406
|
}
|
392
407
|
|
393
408
|
public destroy() {
|
409
|
+
emitter.off("playgroundSizeChange", this.playgroundSizeChangeListener);
|
394
410
|
this.teleBoxManager.destroy();
|
395
411
|
}
|
396
412
|
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import AppDocsViewer from "@netless/app-docs-viewer";
|
2
|
+
import AppMediaPlayer, { setOptions } from "@netless/app-media-player";
|
3
|
+
import { WindowManager } from "./index";
|
4
|
+
|
5
|
+
export const setupBuiltin = () => {
|
6
|
+
if (WindowManager.debug) {
|
7
|
+
setOptions({ verbose: true });
|
8
|
+
}
|
9
|
+
|
10
|
+
WindowManager.register({
|
11
|
+
kind: AppDocsViewer.kind,
|
12
|
+
src: AppDocsViewer,
|
13
|
+
});
|
14
|
+
WindowManager.register({
|
15
|
+
kind: AppMediaPlayer.kind,
|
16
|
+
src: AppMediaPlayer,
|
17
|
+
});
|
18
|
+
};
|
19
|
+
|
20
|
+
export const BuiltinApps = {
|
21
|
+
DocsViewer: AppDocsViewer.kind as string,
|
22
|
+
MediaPlayer: AppMediaPlayer.kind as string,
|
23
|
+
};
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
|
2
|
+
import { WindowManager } from "./index";
|
3
|
+
import type { EmitterType } from "./index";
|
4
|
+
|
5
|
+
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
|
6
|
+
|
7
|
+
export class ContainerResizeObserver {
|
8
|
+
private containerResizeObserver?: ResizeObserver;
|
9
|
+
|
10
|
+
constructor(private emitter: EmitterType) {}
|
11
|
+
|
12
|
+
public static create(
|
13
|
+
container: HTMLElement,
|
14
|
+
sizer: HTMLElement,
|
15
|
+
wrapper: HTMLDivElement,
|
16
|
+
emitter: EmitterType
|
17
|
+
) {
|
18
|
+
const containerResizeObserver = new ContainerResizeObserver(emitter);
|
19
|
+
containerResizeObserver.observePlaygroundSize(container, sizer, wrapper);
|
20
|
+
return containerResizeObserver;
|
21
|
+
}
|
22
|
+
|
23
|
+
public observePlaygroundSize(
|
24
|
+
container: HTMLElement,
|
25
|
+
sizer: HTMLElement,
|
26
|
+
wrapper: HTMLDivElement
|
27
|
+
) {
|
28
|
+
this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
|
29
|
+
|
30
|
+
this.containerResizeObserver = new ResizeObserver(entries => {
|
31
|
+
const containerRect = entries[0]?.contentRect;
|
32
|
+
if (containerRect) {
|
33
|
+
this.updateSizer(containerRect, sizer, wrapper);
|
34
|
+
this.emitter.emit("playgroundSizeChange", containerRect);
|
35
|
+
}
|
36
|
+
});
|
37
|
+
|
38
|
+
this.containerResizeObserver.observe(container);
|
39
|
+
}
|
40
|
+
|
41
|
+
private updateSizer(
|
42
|
+
{ width, height }: DOMRectReadOnly,
|
43
|
+
sizer: HTMLElement,
|
44
|
+
wrapper: HTMLDivElement
|
45
|
+
) {
|
46
|
+
if (width && height) {
|
47
|
+
if (height / width > WindowManager.containerSizeRatio) {
|
48
|
+
height = width * WindowManager.containerSizeRatio;
|
49
|
+
sizer.classList.toggle("netless-window-manager-sizer-horizontal", true);
|
50
|
+
} else {
|
51
|
+
width = height / WindowManager.containerSizeRatio;
|
52
|
+
sizer.classList.toggle("netless-window-manager-sizer-horizontal", false);
|
53
|
+
}
|
54
|
+
wrapper.style.width = `${width}px`;
|
55
|
+
wrapper.style.height = `${height}px`;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
public disconnect() {
|
60
|
+
this.containerResizeObserver?.disconnect();
|
61
|
+
}
|
62
|
+
}
|
package/src/Cursor/Cursor.svelte
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
<script lang="ts">
|
2
2
|
import { isEmpty } from "lodash";
|
3
|
+
import { ApplianceNames } from "white-web-sdk";
|
3
4
|
|
4
5
|
export let cursorName: string;
|
5
6
|
export let tagName: string;
|
@@ -19,6 +20,7 @@
|
|
19
20
|
$: hasTagName = !isEmpty(tagName);
|
20
21
|
$: hasAvatar = !isEmpty(avatar);
|
21
22
|
$: display = visible ? "initial" : "none";
|
23
|
+
$: isLaserPointer = appliance === ApplianceNames.laserPointer;
|
22
24
|
|
23
25
|
const computedAvatarStyle = () => {
|
24
26
|
return Object.entries({
|
@@ -36,28 +38,30 @@
|
|
36
38
|
<div
|
37
39
|
class="netless-window-manager-cursor-mid"
|
38
40
|
style="transform: translateX({x}px) translateY({y}px);display: {display}"
|
39
|
-
>
|
40
|
-
|
41
|
-
<div
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
{
|
57
|
-
|
58
|
-
|
41
|
+
>
|
42
|
+
{#if !isLaserPointer}
|
43
|
+
<div class="netless-window-manager-cursor-name">
|
44
|
+
<div
|
45
|
+
class={theme}
|
46
|
+
style="background-color: {backgroundColor};color: {color};opacity: {opacity}"
|
47
|
+
>
|
48
|
+
{#if hasAvatar}
|
49
|
+
<img
|
50
|
+
class="netless-window-manager-cursor-selector-avatar"
|
51
|
+
style={computedAvatarStyle()}
|
52
|
+
src={avatar}
|
53
|
+
alt="avatar"
|
54
|
+
/>
|
55
|
+
{/if}
|
56
|
+
<span style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;max-width: 80px">{cursorName}</span>
|
57
|
+
{#if hasTagName}
|
58
|
+
<span class="netless-window-manager-cursor-tag-name" style="background-color: {cursorTagBackgroundColor}">
|
59
|
+
{tagName}
|
60
|
+
</span>
|
61
|
+
{/if}
|
62
|
+
</div>
|
59
63
|
</div>
|
60
|
-
|
64
|
+
{/if}
|
61
65
|
<div class="cursor-image-wrapper">
|
62
66
|
<img class="netless-window-manager-cursor-{appliance}-image" {src} alt={appliance} />
|
63
67
|
</div>
|