@netless/window-manager 0.4.32 → 1.0.0-canary.2
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/App/AppContext.d.ts +14 -15
- package/dist/App/AppPageStateImpl.d.ts +6 -2
- package/dist/App/AppProxy.d.ts +5 -2
- package/dist/App/WhiteBoardView.d.ts +16 -0
- package/dist/App/index.d.ts +1 -0
- package/dist/AppManager.d.ts +2 -0
- package/dist/BoxManager.d.ts +7 -5
- package/dist/Helper.d.ts +12 -4
- package/dist/InternalEmitter.d.ts +4 -1
- package/dist/View/CameraSynchronizer.d.ts +17 -0
- package/dist/View/MainView.d.ts +4 -5
- package/dist/constants.d.ts +1 -0
- package/dist/index.cjs.js +21 -22
- package/dist/index.d.ts +0 -2
- package/dist/index.es.js +2186 -1970
- package/dist/index.umd.js +21 -22
- package/dist/style.css +1 -1
- package/dist/typings.d.ts +4 -0
- package/package.json +4 -3
- package/pnpm-lock.yaml +86 -97
- package/src/App/AppContext.ts +58 -73
- package/src/App/AppPageStateImpl.ts +25 -6
- package/src/App/AppProxy.ts +39 -15
- package/src/App/Storage/index.ts +4 -4
- package/src/App/WhiteBoardView.ts +68 -0
- package/src/App/index.ts +1 -0
- package/src/AppManager.ts +9 -1
- package/src/BoxManager.ts +102 -107
- package/src/Cursor/index.ts +5 -5
- package/src/Helper.ts +12 -16
- package/src/InternalEmitter.ts +8 -4
- package/src/View/CameraSynchronizer.ts +67 -0
- package/src/View/MainView.ts +45 -53
- package/src/constants.ts +2 -0
- package/src/index.ts +13 -33
- package/src/typings.ts +4 -0
- package/vite.config.js +0 -1
- package/dist/ContainerResizeObserver.d.ts +0 -11
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.es.js.map +0 -1
- package/dist/index.umd.js.map +0 -1
- package/src/ContainerResizeObserver.ts +0 -73
package/src/App/AppProxy.ts
CHANGED
@@ -12,6 +12,7 @@ import { log } from "../Utils/log";
|
|
12
12
|
import {
|
13
13
|
entireScenes,
|
14
14
|
getScenePath,
|
15
|
+
putScenes,
|
15
16
|
removeScenes,
|
16
17
|
setScenePath,
|
17
18
|
setViewFocusScenePath,
|
@@ -30,6 +31,7 @@ import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
|
30
31
|
import type { PageRemoveService, PageState } from "../Page";
|
31
32
|
import { calculateNextIndex } from "../Page";
|
32
33
|
import { boxEmitter } from "../BoxEmitter";
|
34
|
+
import { SideEffectManager } from "side-effect-manager";
|
33
35
|
|
34
36
|
export type AppEmitter = Emittery<AppEmitterEvent>;
|
35
37
|
|
@@ -37,6 +39,7 @@ export class AppProxy implements PageRemoveService {
|
|
37
39
|
public kind: string;
|
38
40
|
public id: string;
|
39
41
|
public scenePath?: string;
|
42
|
+
private appScenePath: string;
|
40
43
|
public appEmitter: AppEmitter;
|
41
44
|
public scenes?: SceneDefinition[];
|
42
45
|
|
@@ -49,12 +52,14 @@ export class AppProxy implements PageRemoveService {
|
|
49
52
|
public isAddApp: boolean;
|
50
53
|
private status: "normal" | "destroyed" = "normal";
|
51
54
|
private stateKey: string;
|
52
|
-
|
55
|
+
public _pageState: AppPageStateImpl;
|
53
56
|
private _prevFullPath: string | undefined;
|
54
57
|
|
55
58
|
public appResult?: NetlessApp<any>;
|
56
59
|
public appContext?: AppContext<any, any>;
|
57
60
|
|
61
|
+
private sideEffectManager = new SideEffectManager();
|
62
|
+
|
58
63
|
constructor(
|
59
64
|
private params: BaseInsertParams,
|
60
65
|
private manager: AppManager,
|
@@ -63,6 +68,7 @@ export class AppProxy implements PageRemoveService {
|
|
63
68
|
) {
|
64
69
|
this.kind = params.kind;
|
65
70
|
this.id = appId;
|
71
|
+
this.appScenePath = `/${this.id}-app-dir`;
|
66
72
|
this.stateKey = `${this.id}_state`;
|
67
73
|
this.appProxies.set(this.id, this);
|
68
74
|
this.appEmitter = new Emittery();
|
@@ -75,12 +81,37 @@ export class AppProxy implements PageRemoveService {
|
|
75
81
|
// 只有传入了 scenePath 的 App 才会创建 View
|
76
82
|
this.createView();
|
77
83
|
}
|
84
|
+
if (!this.scenePath) {
|
85
|
+
this.scenePath = this.appScenePath;
|
86
|
+
}
|
78
87
|
this._pageState = new AppPageStateImpl({
|
79
88
|
displayer: this.manager.displayer,
|
80
89
|
scenePath: this.scenePath,
|
81
90
|
view: this.view,
|
82
91
|
notifyPageStateChange: this.notifyPageStateChange,
|
83
92
|
});
|
93
|
+
this.sideEffectManager.add(() => {
|
94
|
+
return () => this._pageState.destroy();
|
95
|
+
});
|
96
|
+
this.sideEffectManager.add(() => {
|
97
|
+
return emitter.on("roomMembersChange", members => {
|
98
|
+
this.appEmitter.emit("roomMembersChange", members);
|
99
|
+
});
|
100
|
+
});
|
101
|
+
}
|
102
|
+
|
103
|
+
public createAppDir() {
|
104
|
+
const scenePath = this.scenePath || this.appScenePath;
|
105
|
+
const sceneNode = this._pageState.createSceneNode(scenePath);
|
106
|
+
if (!sceneNode) {
|
107
|
+
putScenes(this.manager.room, scenePath, [{ name: "1" }]);
|
108
|
+
this._pageState.createSceneNode(scenePath);
|
109
|
+
this.setSceneIndex(0);
|
110
|
+
}
|
111
|
+
this.scenes = entireScenes(this.manager.displayer)[scenePath];
|
112
|
+
const view = this.createView();
|
113
|
+
this._pageState.setView(view);
|
114
|
+
return view;
|
84
115
|
}
|
85
116
|
|
86
117
|
private initScenes() {
|
@@ -191,7 +222,6 @@ export class AppProxy implements PageRemoveService {
|
|
191
222
|
const result = await app.setup(context);
|
192
223
|
this.appResult = result;
|
193
224
|
appRegister.notifyApp(this.kind, "created", { appId, result });
|
194
|
-
this.afterSetupApp(boxInitState);
|
195
225
|
this.fixMobileSize();
|
196
226
|
}, SETUP_APP_DELAY);
|
197
227
|
});
|
@@ -225,14 +255,6 @@ export class AppProxy implements PageRemoveService {
|
|
225
255
|
}
|
226
256
|
}
|
227
257
|
|
228
|
-
private afterSetupApp(boxInitState: AppInitState | undefined): void {
|
229
|
-
if (boxInitState) {
|
230
|
-
if (!boxInitState?.x || !boxInitState.y) {
|
231
|
-
this.boxManager?.setBoxInitState(this.id);
|
232
|
-
}
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
258
|
public async onSeek(time: number) {
|
237
259
|
this.appEmitter.emit("seek", time).catch(err => {
|
238
260
|
console.log(`[WindowManager]: emit seek error: ${err.message}`);
|
@@ -404,14 +426,16 @@ export class AppProxy implements PageRemoveService {
|
|
404
426
|
return fullPath;
|
405
427
|
}
|
406
428
|
|
407
|
-
private
|
408
|
-
const view =
|
429
|
+
private createView(): View {
|
430
|
+
const view = this.viewManager.createView(this.id);
|
409
431
|
this.setViewFocusScenePath();
|
410
432
|
return view;
|
411
433
|
}
|
412
434
|
|
413
435
|
public notifyPageStateChange = debounce(() => {
|
414
|
-
|
436
|
+
if (this.pageState) {
|
437
|
+
this.appEmitter.emit("pageStateChange", this.pageState);
|
438
|
+
}
|
415
439
|
}, 50);
|
416
440
|
|
417
441
|
public get pageState(): PageState {
|
@@ -421,7 +445,7 @@ export class AppProxy implements PageRemoveService {
|
|
421
445
|
// PageRemoveService
|
422
446
|
public async removeSceneByIndex(index: number) {
|
423
447
|
const scenePath = this._pageState.getFullPath(index);
|
424
|
-
if (scenePath) {
|
448
|
+
if (scenePath && this.pageState) {
|
425
449
|
const nextIndex = calculateNextIndex(index, this.pageState);
|
426
450
|
// 只修改 focus path 不修改 FullPath
|
427
451
|
this.setSceneIndexWithoutSync(nextIndex);
|
@@ -483,7 +507,6 @@ export class AppProxy implements PageRemoveService {
|
|
483
507
|
}
|
484
508
|
}
|
485
509
|
this.appProxies.delete(this.id);
|
486
|
-
this._pageState.destroy();
|
487
510
|
|
488
511
|
this.viewManager.destroyView(this.id);
|
489
512
|
this.manager.appStatus.delete(this.id);
|
@@ -491,6 +514,7 @@ export class AppProxy implements PageRemoveService {
|
|
491
514
|
this.manager.refresher?.remove(this.stateKey);
|
492
515
|
this.manager.refresher?.remove(`${this.id}-fullPath`);
|
493
516
|
this._prevFullPath = undefined;
|
517
|
+
this.sideEffectManager.flushAll();
|
494
518
|
}
|
495
519
|
|
496
520
|
public close(): Promise<void> {
|
package/src/App/Storage/index.ts
CHANGED
@@ -37,7 +37,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
37
37
|
this._state = {} as TState;
|
38
38
|
const rawState = this._getRawState(this._state);
|
39
39
|
|
40
|
-
if (this._context.
|
40
|
+
if (this._context.isWritable) {
|
41
41
|
if (this.id === null) {
|
42
42
|
if (context.isAddApp && defaultState) {
|
43
43
|
this.setState(defaultState);
|
@@ -115,7 +115,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
115
115
|
return;
|
116
116
|
}
|
117
117
|
|
118
|
-
if (!this._context.
|
118
|
+
if (!this._context.isWritable) {
|
119
119
|
console.error(new Error(`Cannot setState on Storage "${this.id}" without writable access`), state);
|
120
120
|
return;
|
121
121
|
}
|
@@ -165,7 +165,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
165
165
|
return;
|
166
166
|
}
|
167
167
|
|
168
|
-
if (!this._context.
|
168
|
+
if (!this._context.isWritable) {
|
169
169
|
console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
|
170
170
|
return;
|
171
171
|
}
|
@@ -181,7 +181,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
|
|
181
181
|
throw new Error(`Cannot delete main Storage`);
|
182
182
|
}
|
183
183
|
|
184
|
-
if (!this._context.
|
184
|
+
if (!this._context.isWritable) {
|
185
185
|
console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
|
186
186
|
return;
|
187
187
|
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { putScenes } from "../Utils/Common";
|
2
|
+
import { Val } from "value-enhancer";
|
3
|
+
|
4
|
+
import type { ReadonlyVal } from "value-enhancer";
|
5
|
+
import type { AddPageParams, PageController, PageState } from "../Page";
|
6
|
+
import type { AppProxy } from "./AppProxy";
|
7
|
+
import type { AppContext } from "./AppContext";
|
8
|
+
|
9
|
+
export class WhiteBoardView implements PageController {
|
10
|
+
public readonly pageState$: ReadonlyVal<PageState>;
|
11
|
+
|
12
|
+
constructor(protected appContext: AppContext, protected appProxy: AppProxy) {
|
13
|
+
const pageState$ = new Val<PageState>(appProxy.pageState);
|
14
|
+
this.pageState$ = pageState$;
|
15
|
+
appProxy.appEmitter.on("pageStateChange", pageState => {
|
16
|
+
pageState$.setValue(pageState);
|
17
|
+
});
|
18
|
+
}
|
19
|
+
|
20
|
+
public get pageState() {
|
21
|
+
return this.pageState$.value;
|
22
|
+
}
|
23
|
+
|
24
|
+
public nextPage = async (): Promise<boolean> => {
|
25
|
+
const nextIndex = this.pageState.index + 1;
|
26
|
+
return this.jumpPage(nextIndex);
|
27
|
+
};
|
28
|
+
|
29
|
+
public prevPage = async (): Promise<boolean> => {
|
30
|
+
const nextIndex = this.pageState.index - 1;
|
31
|
+
return this.jumpPage(nextIndex);
|
32
|
+
};
|
33
|
+
|
34
|
+
public jumpPage = async (index: number): Promise<boolean> => {
|
35
|
+
if (index < 0 || index >= this.pageState.length) {
|
36
|
+
console.warn(`[WindowManager]: index ${index} out of range`);
|
37
|
+
return false;
|
38
|
+
}
|
39
|
+
this.appProxy.setSceneIndex(index);
|
40
|
+
return true;
|
41
|
+
};
|
42
|
+
|
43
|
+
public addPage = async (params?: AddPageParams) => {
|
44
|
+
const after = params?.after;
|
45
|
+
const scene = params?.scene;
|
46
|
+
const scenePath = this.appProxy.scenePath;
|
47
|
+
if (!scenePath) return;
|
48
|
+
if (after) {
|
49
|
+
const nextIndex = this.pageState.index + 1;
|
50
|
+
putScenes(this.appContext.room, scenePath, [scene || {}], nextIndex);
|
51
|
+
} else {
|
52
|
+
putScenes(this.appContext.room, scenePath, [scene || {}]);
|
53
|
+
}
|
54
|
+
};
|
55
|
+
|
56
|
+
public removePage = async (index?: number): Promise<boolean> => {
|
57
|
+
const needRemoveIndex = index === undefined ? this.pageState.index : index;
|
58
|
+
if (this.pageState.length === 1) {
|
59
|
+
console.warn(`[WindowManager]: can not remove the last page`);
|
60
|
+
return false;
|
61
|
+
}
|
62
|
+
if (needRemoveIndex < 0 || needRemoveIndex >= this.pageState.length) {
|
63
|
+
console.warn(`[WindowManager]: page index ${index} out of range`);
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
return this.appProxy.removeSceneByIndex(needRemoveIndex);
|
67
|
+
};
|
68
|
+
}
|
package/src/App/index.ts
CHANGED
package/src/AppManager.ts
CHANGED
@@ -15,6 +15,7 @@ import { MainViewProxy } from "./View/MainView";
|
|
15
15
|
import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
|
16
16
|
import { reconnectRefresher, WindowManager } from "./index";
|
17
17
|
import { RedoUndo } from "./RedoUndo";
|
18
|
+
import { serializeRoomMembers } from "./Helper";
|
18
19
|
import { SideEffectManager } from "side-effect-manager";
|
19
20
|
import { ViewManager } from "./View/ViewManager";
|
20
21
|
import type { SyncRegisterAppPayload } from "./Register";
|
@@ -46,7 +47,7 @@ import type {
|
|
46
47
|
BoxResizePayload,
|
47
48
|
BoxStateChangePayload,
|
48
49
|
} from "./BoxEmitter";
|
49
|
-
|
50
|
+
import type { Member } from "./Helper";
|
50
51
|
|
51
52
|
export class AppManager {
|
52
53
|
public displayer: Displayer;
|
@@ -299,6 +300,10 @@ export class AppManager {
|
|
299
300
|
return this.room?.uid || "";
|
300
301
|
}
|
301
302
|
|
303
|
+
public get members(): Member[] {
|
304
|
+
return serializeRoomMembers(this.displayer.state.roomMembers);
|
305
|
+
}
|
306
|
+
|
302
307
|
public getMainViewSceneDir() {
|
303
308
|
const scenePath = this.store.getMainViewScenePath();
|
304
309
|
if (scenePath) {
|
@@ -660,6 +665,9 @@ export class AppManager {
|
|
660
665
|
this.appProxies.forEach(appProxy => {
|
661
666
|
appProxy.appEmitter.emit("roomStateChange", state);
|
662
667
|
});
|
668
|
+
if (state.roomMembers) {
|
669
|
+
emitter.emit("roomMembersChange", this.members);
|
670
|
+
}
|
663
671
|
emitter.emit("observerIdChange", this.displayer.observerId);
|
664
672
|
};
|
665
673
|
|
package/src/BoxManager.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
|
2
2
|
import { debounce } from "lodash";
|
3
|
-
import { TELE_BOX_STATE,
|
3
|
+
import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
|
4
4
|
import { WindowManager } from "./index";
|
5
5
|
import type { BoxEmitterType } from "./BoxEmitter";
|
6
6
|
import type { AddAppOptions, AppInitState } from "./index";
|
@@ -18,6 +18,7 @@ import type { NetlessApp } from "./typings";
|
|
18
18
|
import type { View } from "white-web-sdk";
|
19
19
|
import type { CallbacksType } from "./callback";
|
20
20
|
import type { EmitterType } from "./InternalEmitter";
|
21
|
+
import { SideEffectManager } from "side-effect-manager";
|
21
22
|
|
22
23
|
export { TELE_BOX_STATE };
|
23
24
|
|
@@ -45,6 +46,7 @@ export type CreateTeleBoxManagerConfig = {
|
|
45
46
|
collectorContainer?: HTMLElement;
|
46
47
|
collectorStyles?: Partial<CSSStyleDeclaration>;
|
47
48
|
prefersColorScheme?: TeleBoxColorScheme;
|
49
|
+
stageRatio?: number;
|
48
50
|
};
|
49
51
|
|
50
52
|
export type BoxManagerContext = {
|
@@ -87,79 +89,93 @@ export const createBoxManager = (
|
|
87
89
|
|
88
90
|
export class BoxManager {
|
89
91
|
public teleBoxManager: TeleBoxManager;
|
92
|
+
protected sideEffectManager: SideEffectManager;
|
90
93
|
|
91
94
|
constructor(
|
92
95
|
private context: BoxManagerContext,
|
93
|
-
|
96
|
+
createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
|
94
97
|
) {
|
98
|
+
this.sideEffectManager = new SideEffectManager();
|
95
99
|
const { emitter, callbacks, boxEmitter } = context;
|
96
100
|
this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
this.teleBoxManager.events.on("minimized", minimized => {
|
113
|
-
this.context.safeSetAttributes({ minimized });
|
114
|
-
if (minimized) {
|
115
|
-
this.context.cleanFocus();
|
116
|
-
this.blurAllBox();
|
117
|
-
} else {
|
118
|
-
const topBox = this.getTopBox();
|
119
|
-
if (topBox) {
|
120
|
-
this.context.setAppFocus(topBox.id);
|
121
|
-
this.focusBox({ appId: topBox.id }, false);
|
101
|
+
this.sideEffectManager.add(() => [
|
102
|
+
// 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
|
103
|
+
this.teleBoxManager._state$.reaction(state => {
|
104
|
+
callbacks.emit("boxStateChange", state);
|
105
|
+
emitter.emit("boxStateChange", state);
|
106
|
+
}),
|
107
|
+
this.teleBoxManager._darkMode$.reaction(darkMode => {
|
108
|
+
callbacks.emit("darkModeChange", darkMode);
|
109
|
+
}),
|
110
|
+
this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
|
111
|
+
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
112
|
+
}),
|
113
|
+
this.teleBoxManager._minimized$.reaction((minimized, skipUpdate) => {
|
114
|
+
if (skipUpdate) {
|
115
|
+
return;
|
122
116
|
}
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
});
|
128
|
-
this.teleBoxManager.events.on("removed", boxes => {
|
129
|
-
boxes.forEach(box => {
|
130
|
-
boxEmitter.emit("close", { appId: box.id });
|
131
|
-
});
|
132
|
-
});
|
133
|
-
this.teleBoxManager.events.on(
|
134
|
-
"intrinsic_move",
|
135
|
-
debounce((box: ReadonlyTeleBox): void => {
|
136
|
-
boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
|
137
|
-
}, 50)
|
138
|
-
);
|
139
|
-
this.teleBoxManager.events.on(
|
140
|
-
"intrinsic_resize",
|
141
|
-
debounce((box: ReadonlyTeleBox): void => {
|
142
|
-
boxEmitter.emit("resize", {
|
143
|
-
appId: box.id,
|
144
|
-
width: box.intrinsicWidth,
|
145
|
-
height: box.intrinsicHeight,
|
146
|
-
});
|
147
|
-
}, 200)
|
148
|
-
);
|
149
|
-
this.teleBoxManager.events.on("focused", box => {
|
150
|
-
if (box) {
|
151
|
-
if (this.canOperate) {
|
152
|
-
boxEmitter.emit("focus", { appId: box.id });
|
117
|
+
this.context.safeSetAttributes({ minimized });
|
118
|
+
if (minimized) {
|
119
|
+
this.context.cleanFocus();
|
120
|
+
this.blurAllBox();
|
153
121
|
} else {
|
154
|
-
this.
|
122
|
+
const topBox = this.getTopBox();
|
123
|
+
if (topBox) {
|
124
|
+
this.context.setAppFocus(topBox.id);
|
125
|
+
this.focusBox({ appId: topBox.id }, false);
|
126
|
+
}
|
155
127
|
}
|
156
|
-
}
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
128
|
+
}),
|
129
|
+
this.teleBoxManager._maximized$.reaction((maximized, skipUpdate) => {
|
130
|
+
if (skipUpdate) {
|
131
|
+
return;
|
132
|
+
}
|
133
|
+
this.context.safeSetAttributes({ maximized });
|
134
|
+
}),
|
135
|
+
this.teleBoxManager.events.on("removed", boxes => {
|
136
|
+
boxes.forEach(box => {
|
137
|
+
boxEmitter.emit("close", { appId: box.id });
|
138
|
+
});
|
139
|
+
}),
|
140
|
+
this.teleBoxManager.events.on(
|
141
|
+
"intrinsic_move",
|
142
|
+
debounce((box: ReadonlyTeleBox): void => {
|
143
|
+
boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
|
144
|
+
}, 50)
|
145
|
+
),
|
146
|
+
this.teleBoxManager.events.on(
|
147
|
+
"intrinsic_resize",
|
148
|
+
debounce((box: ReadonlyTeleBox): void => {
|
149
|
+
boxEmitter.emit("resize", {
|
150
|
+
appId: box.id,
|
151
|
+
width: box.intrinsicWidth,
|
152
|
+
height: box.intrinsicHeight,
|
153
|
+
});
|
154
|
+
}, 200)
|
155
|
+
),
|
156
|
+
this.teleBoxManager.events.on("focused", box => {
|
157
|
+
if (box) {
|
158
|
+
if (this.canOperate) {
|
159
|
+
boxEmitter.emit("focus", { appId: box.id });
|
160
|
+
} else {
|
161
|
+
this.teleBoxManager.blurBox(box.id);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}),
|
165
|
+
this.teleBoxManager.events.on("z_index", box => {
|
166
|
+
this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
|
167
|
+
}),
|
168
|
+
this.teleBoxManager._stageRect$.subscribe(stage => {
|
169
|
+
emitter.emit("playgroundSizeChange", stage);
|
170
|
+
this.context.notifyContainerRectUpdate(stage);
|
171
|
+
}),
|
172
|
+
emitter.on("writableChange", isWritable => {
|
173
|
+
this.teleBoxManager.setHighlightStage(isWritable);
|
174
|
+
}),
|
175
|
+
emitter.on("containerSizeRatioUpdate", ratio => {
|
176
|
+
this.teleBoxManager._stageRatio$.setValue(ratio);
|
177
|
+
}),
|
178
|
+
]);
|
163
179
|
}
|
164
180
|
|
165
181
|
private get mainView() {
|
@@ -194,12 +210,16 @@ export class BoxManager {
|
|
194
210
|
return this.teleBoxManager.boxes.length;
|
195
211
|
}
|
196
212
|
|
213
|
+
public get stageRect() {
|
214
|
+
return this.teleBoxManager.stageRect;
|
215
|
+
}
|
216
|
+
|
197
217
|
public createBox(params: CreateBoxParams): void {
|
198
218
|
if (!this.teleBoxManager) return;
|
199
219
|
let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
|
200
220
|
const { width, height } = params.app.config ?? {};
|
201
221
|
const title = params.options?.title || params.appId;
|
202
|
-
const rect = this.teleBoxManager.
|
222
|
+
const rect = this.teleBoxManager.rootRect;
|
203
223
|
|
204
224
|
if (minwidth > 1) {
|
205
225
|
minwidth = minwidth / rect.width;
|
@@ -221,34 +241,13 @@ export class BoxManager {
|
|
221
241
|
this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
|
222
242
|
}
|
223
243
|
|
224
|
-
public setBoxInitState(appId: string): void {
|
225
|
-
const box = this.teleBoxManager.queryOne({ id: appId });
|
226
|
-
if (box) {
|
227
|
-
if (box.state === TELE_BOX_STATE.Maximized) {
|
228
|
-
this.context.boxEmitter.emit("resize", {
|
229
|
-
appId: appId,
|
230
|
-
x: box.x,
|
231
|
-
y: box.y,
|
232
|
-
width: box.intrinsicWidth,
|
233
|
-
height: box.intrinsicHeight,
|
234
|
-
});
|
235
|
-
}
|
236
|
-
}
|
237
|
-
}
|
238
|
-
|
239
244
|
public setupBoxManager(
|
240
245
|
createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
|
241
246
|
): TeleBoxManager {
|
242
|
-
const root = WindowManager.
|
243
|
-
const rect = root.getBoundingClientRect();
|
247
|
+
const root = WindowManager.playground;
|
244
248
|
const initManagerState: TeleBoxManagerConfig = {
|
249
|
+
stageRatio: createTeleBoxManagerConfig?.stageRatio,
|
245
250
|
root: root,
|
246
|
-
containerRect: {
|
247
|
-
x: 0,
|
248
|
-
y: 0,
|
249
|
-
width: rect.width,
|
250
|
-
height: rect.height,
|
251
|
-
},
|
252
251
|
fence: false,
|
253
252
|
prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
|
254
253
|
};
|
@@ -258,20 +257,16 @@ export class BoxManager {
|
|
258
257
|
this.teleBoxManager.destroy();
|
259
258
|
}
|
260
259
|
this.teleBoxManager = manager;
|
261
|
-
const container = createTeleBoxManagerConfig?.collectorContainer
|
260
|
+
const container = createTeleBoxManagerConfig?.collectorContainer;
|
262
261
|
if (container) {
|
263
|
-
this.
|
262
|
+
this.teleBoxManager.collector.set$collector(container);
|
263
|
+
}
|
264
|
+
if (createTeleBoxManagerConfig?.collectorStyles) {
|
265
|
+
this.teleBoxManager.collector.setStyles(createTeleBoxManagerConfig.collectorStyles);
|
264
266
|
}
|
265
267
|
return manager;
|
266
268
|
}
|
267
269
|
|
268
|
-
public setCollectorContainer(container: HTMLElement) {
|
269
|
-
const collector = new TeleBoxCollector({
|
270
|
-
styles: this.createTeleBoxManagerConfig?.collectorStyles,
|
271
|
-
}).mount(container);
|
272
|
-
this.teleBoxManager.setCollector(collector);
|
273
|
-
}
|
274
|
-
|
275
270
|
public getBox(appId: string): ReadonlyTeleBox | undefined {
|
276
271
|
return this.teleBoxManager.queryOne({ id: appId });
|
277
272
|
}
|
@@ -324,15 +319,6 @@ export class BoxManager {
|
|
324
319
|
}
|
325
320
|
}
|
326
321
|
|
327
|
-
public updateManagerRect(): void {
|
328
|
-
const rect = this.mainView.divElement?.getBoundingClientRect();
|
329
|
-
if (rect && rect.width > 0 && rect.height > 0) {
|
330
|
-
const containerRect = { x: 0, y: 0, width: rect.width, height: rect.height };
|
331
|
-
this.teleBoxManager.setContainerRect(containerRect);
|
332
|
-
this.context.notifyContainerRectUpdate(this.teleBoxManager.containerRect);
|
333
|
-
}
|
334
|
-
}
|
335
|
-
|
336
322
|
public moveBox({ appId, x, y }: MoveBoxParams): void {
|
337
323
|
this.teleBoxManager.update(appId, { x, y }, true);
|
338
324
|
}
|
@@ -404,7 +390,16 @@ export class BoxManager {
|
|
404
390
|
this.teleBoxManager.update(id, { zIndex }, skipUpdate);
|
405
391
|
}
|
406
392
|
|
393
|
+
public setRoot(root: HTMLElement) {
|
394
|
+
this.teleBoxManager._root$.setValue(root);
|
395
|
+
}
|
396
|
+
|
397
|
+
public setCollector(collector: HTMLElement) {
|
398
|
+
this.teleBoxManager.collector.set$collector(collector);
|
399
|
+
}
|
400
|
+
|
407
401
|
public destroy() {
|
402
|
+
this.sideEffectManager.flushAll();
|
408
403
|
this.teleBoxManager.destroy();
|
409
404
|
}
|
410
405
|
}
|
package/src/Cursor/index.ts
CHANGED
@@ -34,9 +34,9 @@ export class CursorManager {
|
|
34
34
|
|
35
35
|
constructor(private manager: AppManager, private enableCursor: boolean, applianceIcons?: ApplianceIcons) {
|
36
36
|
this.roomMembers = this.manager.room?.state.roomMembers;
|
37
|
-
const
|
38
|
-
if (
|
39
|
-
this.setupWrapper(
|
37
|
+
const playground = WindowManager.playground;
|
38
|
+
if (playground) {
|
39
|
+
this.setupWrapper(playground);
|
40
40
|
}
|
41
41
|
this.sideEffectManager.add(() => {
|
42
42
|
return emitter.on("cursorMove", this.onCursorMove);
|
@@ -65,7 +65,7 @@ export class CursorManager {
|
|
65
65
|
private initCursorInstance = (uid: string) => {
|
66
66
|
let cursorInstance = this.cursorInstances.get(uid);
|
67
67
|
if (!cursorInstance) {
|
68
|
-
cursorInstance = new Cursor(this.manager, uid, this, WindowManager.
|
68
|
+
cursorInstance = new Cursor(this.manager, uid, this, WindowManager.playground);
|
69
69
|
this.cursorInstances.set(uid, cursorInstance);
|
70
70
|
}
|
71
71
|
return cursorInstance;
|
@@ -169,7 +169,7 @@ export class CursorManager {
|
|
169
169
|
|
170
170
|
public updateContainerRect() {
|
171
171
|
this.containerRect = WindowManager.container?.getBoundingClientRect();
|
172
|
-
this.wrapperRect = WindowManager.
|
172
|
+
this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
|
173
173
|
}
|
174
174
|
|
175
175
|
public deleteCursor(uid: string) {
|
package/src/Helper.ts
CHANGED
@@ -2,36 +2,23 @@ import { getVersionNumber } from "./Utils/Common";
|
|
2
2
|
import { REQUIRE_VERSION } from "./constants";
|
3
3
|
import { WhiteVersion } from "white-web-sdk";
|
4
4
|
import { WhiteWebSDKInvalidError } from "./Utils/error";
|
5
|
-
import {
|
6
|
-
import type { Room } from "white-web-sdk";
|
5
|
+
import type { Room , RoomMember} from "white-web-sdk";
|
7
6
|
|
8
7
|
export const setupWrapper = (
|
9
8
|
root: HTMLElement
|
10
9
|
): {
|
11
10
|
playground: HTMLDivElement;
|
12
|
-
wrapper: HTMLDivElement;
|
13
|
-
sizer: HTMLDivElement;
|
14
11
|
mainViewElement: HTMLDivElement;
|
15
12
|
} => {
|
16
13
|
const playground = document.createElement("div");
|
17
14
|
playground.className = "netless-window-manager-playground";
|
18
15
|
|
19
|
-
const sizer = document.createElement("div");
|
20
|
-
sizer.className = "netless-window-manager-sizer";
|
21
|
-
|
22
|
-
const wrapper = document.createElement("div");
|
23
|
-
wrapper.className = "netless-window-manager-wrapper";
|
24
|
-
|
25
16
|
const mainViewElement = document.createElement("div");
|
26
17
|
mainViewElement.className = "netless-window-manager-main-view";
|
27
|
-
|
28
|
-
playground.appendChild(sizer);
|
29
|
-
sizer.appendChild(wrapper);
|
30
|
-
wrapper.appendChild(mainViewElement);
|
18
|
+
playground.appendChild(mainViewElement);
|
31
19
|
root.appendChild(playground);
|
32
|
-
WindowManager.wrapper = wrapper;
|
33
20
|
|
34
|
-
return { playground,
|
21
|
+
return { playground, mainViewElement };
|
35
22
|
};
|
36
23
|
|
37
24
|
export const checkVersion = () => {
|
@@ -45,3 +32,12 @@ export const findMemberByUid = (room: Room | undefined, uid: string) => {
|
|
45
32
|
const roomMembers = room?.state.roomMembers;
|
46
33
|
return roomMembers?.find(member => member.payload?.uid === uid);
|
47
34
|
};
|
35
|
+
|
36
|
+
export type Member = RoomMember & { uid: string };
|
37
|
+
|
38
|
+
export const serializeRoomMembers = (members: readonly RoomMember[]) => {
|
39
|
+
return members.map(member => ({
|
40
|
+
uid: member.payload?.uid || "",
|
41
|
+
...member,
|
42
|
+
}));
|
43
|
+
}
|