@netless/window-manager 1.0.0-canary.19 → 1.0.0-canary.21
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/AppProxy.d.ts +3 -2
- package/dist/App/index.d.ts +1 -0
- package/dist/App/type.d.ts +21 -0
- package/dist/BoxManager.d.ts +4 -3
- package/dist/Cursor/index.d.ts +0 -1
- package/dist/InternalEmitter.d.ts +1 -2
- package/dist/constants.d.ts +6 -2
- package/dist/index.cjs.js +12 -12
- package/dist/index.d.ts +5 -0
- package/dist/index.es.js +119 -54
- package/dist/index.umd.js +12 -12
- package/package.json +1 -1
- package/src/App/AppProxy.ts +81 -19
- package/src/App/index.ts +1 -0
- package/src/App/type.ts +22 -0
- package/src/AppManager.ts +5 -1
- package/src/BoxManager.ts +8 -7
- package/src/Cursor/index.ts +0 -2
- package/src/InternalEmitter.ts +1 -2
- package/src/Utils/Reactive.ts +27 -26
- package/src/View/ViewSync.ts +7 -13
- package/src/constants.ts +5 -1
- package/src/index.ts +5 -0
package/package.json
CHANGED
package/src/App/AppProxy.ts
CHANGED
@@ -9,7 +9,7 @@ import { boxEmitter } from "../BoxEmitter";
|
|
9
9
|
import { BoxManagerNotFoundError } from "../Utils/error";
|
10
10
|
import { calculateNextIndex } from "../Page";
|
11
11
|
import { combine, Val, ValManager } from "value-enhancer";
|
12
|
-
import { debounce, get, isEqual } from "lodash";
|
12
|
+
import { debounce, get, isEqual, isUndefined, omitBy } from "lodash";
|
13
13
|
import { emitter } from "../InternalEmitter";
|
14
14
|
import { Fields } from "../AttributesDelegate";
|
15
15
|
import { log } from "../Utils/log";
|
@@ -25,7 +25,6 @@ import {
|
|
25
25
|
} from "../Utils/Common";
|
26
26
|
import type {
|
27
27
|
AppEmitterEvent,
|
28
|
-
AppInitState,
|
29
28
|
BaseInsertParams,
|
30
29
|
setAppOptions,
|
31
30
|
AppListenerKeys,
|
@@ -35,6 +34,7 @@ import type { AppManager } from "../AppManager";
|
|
35
34
|
import type { NetlessApp } from "../typings";
|
36
35
|
import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
|
37
36
|
import type { PageRemoveService, PageState } from "../Page";
|
37
|
+
import type { AppState } from "./type";
|
38
38
|
|
39
39
|
export type AppEmitter = Emittery<AppEmitterEvent>;
|
40
40
|
|
@@ -151,6 +151,62 @@ export class AppProxy implements PageRemoveService {
|
|
151
151
|
this.sideEffectManager.add(() =>
|
152
152
|
emitter.on("memberStateChange", this.onMemberStateChange)
|
153
153
|
);
|
154
|
+
this.box$.subscribe(box => {
|
155
|
+
if (!box) return;
|
156
|
+
this.sideEffectManager.add(() => [
|
157
|
+
createValSync(
|
158
|
+
() => this.appAttributes?.state.visible,
|
159
|
+
box._visible$,
|
160
|
+
),
|
161
|
+
createValSync(
|
162
|
+
() => this.appAttributes?.state.ratio,
|
163
|
+
box._ratio$,
|
164
|
+
),
|
165
|
+
createValSync(
|
166
|
+
() => this.appAttributes?.state.stageRatio,
|
167
|
+
box._stageRatio$,
|
168
|
+
),
|
169
|
+
createValSync(
|
170
|
+
() => this.appAttributes?.state.draggable,
|
171
|
+
box._draggable$,
|
172
|
+
),
|
173
|
+
createValSync(
|
174
|
+
() => this.appAttributes?.state.resizable,
|
175
|
+
box._resizable$,
|
176
|
+
),
|
177
|
+
box._visible$.reaction((visible, skipUpdate) => {
|
178
|
+
if (skipUpdate) {
|
179
|
+
return;
|
180
|
+
}
|
181
|
+
this.store.updateAppState(this.id, AppAttributes.Visible, visible);
|
182
|
+
}),
|
183
|
+
box._ratio$.reaction((ratio, skipUpdate) => {
|
184
|
+
console.log("ratio change", ratio, skipUpdate);
|
185
|
+
if (skipUpdate) {
|
186
|
+
return;
|
187
|
+
}
|
188
|
+
this.store.updateAppState(this.id, AppAttributes.Ratio, ratio);
|
189
|
+
}),
|
190
|
+
box._stageRatio$.reaction((stageRatio, skipUpdate) => {
|
191
|
+
if (skipUpdate) {
|
192
|
+
return;
|
193
|
+
}
|
194
|
+
this.store.updateAppState(this.id, AppAttributes.StageRatio, stageRatio);
|
195
|
+
}),
|
196
|
+
box._draggable$.reaction((draggable, skipUpdate) => {
|
197
|
+
if (skipUpdate) {
|
198
|
+
return;
|
199
|
+
}
|
200
|
+
this.store.updateAppState(this.id, AppAttributes.Draggable, draggable);
|
201
|
+
}),
|
202
|
+
box._resizable$.reaction((resizable, skipUpdate) => {
|
203
|
+
if (skipUpdate) {
|
204
|
+
return;
|
205
|
+
}
|
206
|
+
this.store.updateAppState(this.id, AppAttributes.Resizable, resizable);
|
207
|
+
}),
|
208
|
+
])
|
209
|
+
});
|
154
210
|
}
|
155
211
|
|
156
212
|
public fireMemberStateChange = () => {
|
@@ -301,7 +357,7 @@ export class AppProxy implements PageRemoveService {
|
|
301
357
|
this.appContext = context;
|
302
358
|
try {
|
303
359
|
emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
|
304
|
-
let boxInitState:
|
360
|
+
let boxInitState: AppState | undefined;
|
305
361
|
if (!skipUpdate) {
|
306
362
|
boxInitState = this.getAppInitState(appId);
|
307
363
|
this.boxManager?.updateBoxState(boxInitState);
|
@@ -327,6 +383,11 @@ export class AppProxy implements PageRemoveService {
|
|
327
383
|
this.box$.setValue(box);
|
328
384
|
if (this.isAddApp && this.box) {
|
329
385
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
386
|
+
this.store.updateAppState(appId, AppAttributes.Visible, this.box.visible);
|
387
|
+
this.store.updateAppState(appId, AppAttributes.Ratio, this.box.ratio);
|
388
|
+
this.store.updateAppState(appId, AppAttributes.StageRatio, this.box.stageRatio);
|
389
|
+
this.store.updateAppState(appId, AppAttributes.Draggable, this.box.draggable);
|
390
|
+
this.store.updateAppState(appId, AppAttributes.Resizable, this.box.resizable);
|
330
391
|
this.boxManager.focusBox({ appId }, false);
|
331
392
|
}
|
332
393
|
} catch (error: any) {
|
@@ -391,30 +452,18 @@ export class AppProxy implements PageRemoveService {
|
|
391
452
|
}
|
392
453
|
}
|
393
454
|
|
394
|
-
public getAppInitState = (id: string) => {
|
455
|
+
public getAppInitState = (id: string): AppState | undefined => {
|
395
456
|
const attrs = this.store.getAppState(id);
|
396
457
|
if (!attrs) return;
|
397
|
-
const position = attrs?.[AppAttributes.Position];
|
398
458
|
const focus = this.store.focus;
|
399
|
-
const size = attrs?.[AppAttributes.Size];
|
400
|
-
const sceneIndex = attrs?.[AppAttributes.SceneIndex];
|
401
459
|
const maximized = this.attributes?.["maximized"];
|
402
460
|
const minimized = this.attributes?.["minimized"];
|
403
|
-
|
404
|
-
|
405
|
-
if (position) {
|
406
|
-
payload = { ...payload, id: id, x: position.x, y: position.y };
|
407
|
-
}
|
461
|
+
let payload = { maximized, minimized, id } as AppState;
|
462
|
+
const state = omitBy(attrs, isUndefined);
|
408
463
|
if (focus === id) {
|
409
464
|
payload = { ...payload, focus: true };
|
410
465
|
}
|
411
|
-
|
412
|
-
payload = { ...payload, width: size.width, height: size.height };
|
413
|
-
}
|
414
|
-
if (sceneIndex) {
|
415
|
-
payload = { ...payload, sceneIndex };
|
416
|
-
}
|
417
|
-
return payload;
|
466
|
+
return Object.assign(payload, state);;
|
418
467
|
};
|
419
468
|
|
420
469
|
public emitAppSceneStateChange(sceneState: SceneState) {
|
@@ -686,3 +735,16 @@ export class AppProxy implements PageRemoveService {
|
|
686
735
|
return this.destroy(true, true, false);
|
687
736
|
}
|
688
737
|
}
|
738
|
+
|
739
|
+
|
740
|
+
const createValSync = (expr: any, Val: Val): (() => void) => {
|
741
|
+
return reaction(
|
742
|
+
expr,
|
743
|
+
val => {
|
744
|
+
if (Val.value !== val && val !== undefined) {
|
745
|
+
Val.setValue(val, true);
|
746
|
+
}
|
747
|
+
},
|
748
|
+
{ fireImmediately: true }
|
749
|
+
);
|
750
|
+
};
|
package/src/App/index.ts
CHANGED
package/src/App/type.ts
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
export type AppState = {
|
3
|
+
id: string;
|
4
|
+
focus?: boolean;
|
5
|
+
SceneIndex?: number;
|
6
|
+
draggable?: boolean;
|
7
|
+
position?: {
|
8
|
+
x: number;
|
9
|
+
y: number;
|
10
|
+
}
|
11
|
+
ratio?: number;
|
12
|
+
resizable?: boolean;
|
13
|
+
size?: {
|
14
|
+
width: number;
|
15
|
+
height: number;
|
16
|
+
}
|
17
|
+
stageRatio?: number;
|
18
|
+
visible?: boolean;
|
19
|
+
zIndex?: number;
|
20
|
+
maximized: boolean | null;
|
21
|
+
minimized: boolean | null;
|
22
|
+
}
|
package/src/AppManager.ts
CHANGED
@@ -30,6 +30,7 @@ import {
|
|
30
30
|
removeScenes,
|
31
31
|
setScenePath,
|
32
32
|
setViewFocusScenePath,
|
33
|
+
wait,
|
33
34
|
} from "./Utils/Common";
|
34
35
|
import type { ReconnectRefresher } from "./ReconnectRefresher";
|
35
36
|
import type { BoxManager } from "./BoxManager";
|
@@ -568,7 +569,10 @@ export class AppManager {
|
|
568
569
|
public bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean) {
|
569
570
|
const mainView = this.mainViewProxy.view;
|
570
571
|
mainView.disableCameraTransform = disableCameraTransform;
|
571
|
-
mainView
|
572
|
+
// 延迟挂载 mainView 的 dom, 避免因为同步 camera 的闪动
|
573
|
+
wait(30).then(() => {
|
574
|
+
mainView.divElement = divElement;
|
575
|
+
});
|
572
576
|
if (!mainView.focusScenePath) {
|
573
577
|
this.setMainViewFocusPath();
|
574
578
|
}
|
package/src/BoxManager.ts
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
|
2
2
|
import { debounce } from "lodash";
|
3
|
+
import { SideEffectManager } from "side-effect-manager";
|
3
4
|
import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
|
4
5
|
import { WindowManager } from "./index";
|
5
6
|
import type { BoxEmitterType } from "./BoxEmitter";
|
6
|
-
import type { AddAppOptions
|
7
|
+
import type { AddAppOptions } from "./index";
|
7
8
|
import type {
|
8
9
|
TeleBoxManagerUpdateConfig,
|
9
10
|
TeleBoxManagerCreateConfig,
|
@@ -18,7 +19,7 @@ import type { NetlessApp } from "./typings";
|
|
18
19
|
import type { View } from "white-web-sdk";
|
19
20
|
import type { CallbacksType } from "./callback";
|
20
21
|
import type { EmitterType } from "./InternalEmitter";
|
21
|
-
import {
|
22
|
+
import type { AppState } from "./App/type";
|
22
23
|
|
23
24
|
export { TELE_BOX_STATE };
|
24
25
|
|
@@ -294,17 +295,17 @@ export class BoxManager {
|
|
294
295
|
return this.teleBoxManager.topBox;
|
295
296
|
}
|
296
297
|
|
297
|
-
public updateBoxState(state?:
|
298
|
+
public updateBoxState(state?: AppState): void {
|
298
299
|
if (!state) return;
|
299
300
|
const box = this.getBox(state.id);
|
300
301
|
if (box) {
|
301
302
|
this.teleBoxManager.update(
|
302
303
|
box.id,
|
303
304
|
{
|
304
|
-
x: state.x,
|
305
|
-
y: state.y,
|
306
|
-
width: state.width || 0.5,
|
307
|
-
height: state.height || 0.5,
|
305
|
+
x: state.position?.x,
|
306
|
+
y: state.position?.y,
|
307
|
+
width: state.size?.width || 0.5,
|
308
|
+
height: state.size?.height || 0.5,
|
308
309
|
zIndex: state.zIndex,
|
309
310
|
},
|
310
311
|
true
|
package/src/Cursor/index.ts
CHANGED
@@ -23,7 +23,6 @@ export type MoveCursorParams = {
|
|
23
23
|
};
|
24
24
|
|
25
25
|
export class CursorManager {
|
26
|
-
public containerRect?: DOMRect;
|
27
26
|
public wrapperRect?: DOMRect;
|
28
27
|
public cursorInstances: Map<string, Cursor> = new Map();
|
29
28
|
public roomMembers?: readonly RoomMember[];
|
@@ -168,7 +167,6 @@ export class CursorManager {
|
|
168
167
|
};
|
169
168
|
|
170
169
|
public updateContainerRect() {
|
171
|
-
this.containerRect = WindowManager.container?.getBoundingClientRect();
|
172
170
|
this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
|
173
171
|
}
|
174
172
|
|
package/src/InternalEmitter.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
2
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
3
|
-
import type {
|
3
|
+
import type { CursorMovePayload } from "./index";
|
4
4
|
import type { Member } from "./Helper";
|
5
5
|
import type { MemberState } from "white-web-sdk";
|
6
6
|
|
@@ -11,7 +11,6 @@ export type RemoveSceneParams = {
|
|
11
11
|
|
12
12
|
export type EmitterEvent = {
|
13
13
|
onCreated: undefined;
|
14
|
-
InitReplay: AppInitState;
|
15
14
|
error: Error;
|
16
15
|
seekStart: undefined;
|
17
16
|
seek: number;
|
package/src/Utils/Reactive.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from "white-web-sdk";
|
2
|
-
import type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from "white-web-sdk";
|
3
1
|
import { isObject } from "lodash";
|
2
|
+
import { listenUpdated, reaction, unlistenUpdated, UpdateEventKind } from "white-web-sdk";
|
3
|
+
import type { AkkoObjectUpdatedProperty, AkkoObjectUpdatedListener } from "white-web-sdk";
|
4
4
|
|
5
5
|
// 兼容 13 和 14 版本 SDK
|
6
6
|
export const onObjectByEvent = (event: UpdateEventKind) => {
|
@@ -12,7 +12,7 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
12
12
|
if (kinds.includes(event)) {
|
13
13
|
func();
|
14
14
|
}
|
15
|
-
}
|
15
|
+
};
|
16
16
|
listenUpdated(object, listener);
|
17
17
|
func();
|
18
18
|
return () => unlistenUpdated(object, listener);
|
@@ -21,43 +21,44 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
21
21
|
() => object,
|
22
22
|
() => {
|
23
23
|
func();
|
24
|
-
},
|
24
|
+
},
|
25
|
+
{
|
25
26
|
fireImmediately: true,
|
26
27
|
}
|
27
|
-
)
|
28
|
+
);
|
28
29
|
}
|
29
|
-
}
|
30
|
-
}
|
30
|
+
};
|
31
|
+
};
|
31
32
|
|
32
33
|
export const safeListenPropsUpdated = <T>(
|
33
34
|
getProps: () => T,
|
34
35
|
callback: AkkoObjectUpdatedListener<T>,
|
35
36
|
onDestroyed?: (props: unknown) => void
|
36
|
-
|
37
|
+
) => {
|
37
38
|
let disposeListenUpdated: (() => void) | null = null;
|
38
39
|
const disposeReaction = reaction(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
getProps,
|
41
|
+
() => {
|
42
|
+
if (disposeListenUpdated) {
|
43
|
+
disposeListenUpdated();
|
44
|
+
disposeListenUpdated = null;
|
45
|
+
}
|
46
|
+
const props = getProps();
|
47
|
+
if (isObject(props)) {
|
48
|
+
disposeListenUpdated = () => unlistenUpdated(props, callback);
|
49
|
+
listenUpdated(props, callback);
|
50
|
+
} else {
|
51
|
+
onDestroyed?.(props);
|
52
|
+
}
|
53
|
+
},
|
54
|
+
{ fireImmediately: true }
|
54
55
|
);
|
55
56
|
|
56
57
|
return () => {
|
57
|
-
|
58
|
-
|
58
|
+
disposeListenUpdated?.();
|
59
|
+
disposeReaction();
|
59
60
|
};
|
60
|
-
}
|
61
|
+
};
|
61
62
|
|
62
63
|
export const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);
|
63
64
|
export const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);
|
package/src/View/ViewSync.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { AnimationMode, ViewMode } from "white-web-sdk";
|
1
|
+
import { AnimationMode, toJS, ViewMode } from "white-web-sdk";
|
2
2
|
import { CameraSynchronizer } from "./CameraSynchronizer";
|
3
3
|
import { combine } from "value-enhancer";
|
4
4
|
import { isEqual } from "lodash";
|
@@ -42,7 +42,7 @@ export class ViewSync {
|
|
42
42
|
}
|
43
43
|
});
|
44
44
|
this.bindView(this.context.view$.value);
|
45
|
-
this.sem.add(() =>
|
45
|
+
this.sem.add(() => [
|
46
46
|
this.context.view$.subscribe(view => {
|
47
47
|
const currentCamera = this.context.camera$.value;
|
48
48
|
if (currentCamera && this.context.size$.value) {
|
@@ -54,30 +54,24 @@ export class ViewSync {
|
|
54
54
|
}
|
55
55
|
|
56
56
|
this.bindView(view);
|
57
|
-
})
|
58
|
-
);
|
59
|
-
this.sem.add(() =>
|
57
|
+
}),
|
60
58
|
this.context.camera$.subscribe((camera, skipUpdate) => {
|
61
59
|
const size = this.context.size$.value;
|
62
60
|
if (camera && size && !skipUpdate) {
|
63
61
|
this.synchronizer.onRemoteUpdate(camera, size);
|
64
62
|
}
|
65
|
-
})
|
66
|
-
);
|
67
|
-
this.sem.add(() =>
|
63
|
+
}),
|
68
64
|
this.context.size$.subscribe(size => {
|
69
65
|
if (size) {
|
70
66
|
this.synchronizer.onRemoteSizeUpdate(size);
|
71
67
|
}
|
72
|
-
})
|
73
|
-
);
|
74
|
-
this.sem.add(() =>
|
68
|
+
}),
|
75
69
|
this.context.stageRect$.reaction(rect => {
|
76
70
|
if (rect) {
|
77
71
|
this.synchronizer.setRect(rect);
|
78
72
|
}
|
79
73
|
})
|
80
|
-
);
|
74
|
+
]);
|
81
75
|
const camera$size$ = combine([this.context.camera$, this.context.size$]);
|
82
76
|
camera$size$.reaction(([camera, size]) => {
|
83
77
|
if (camera && size) {
|
@@ -99,7 +93,7 @@ export class ViewSync {
|
|
99
93
|
};
|
100
94
|
|
101
95
|
private onCameraUpdatedByDevice = (camera: Camera) => {
|
102
|
-
this.synchronizer.onLocalCameraUpdate(Object.assign(camera, { id: this.context.uid }));
|
96
|
+
this.synchronizer.onLocalCameraUpdate(Object.assign(toJS(camera), { id: this.context.uid }));
|
103
97
|
const stage = this.context.stageRect$.value;
|
104
98
|
if (stage) {
|
105
99
|
const size = { width: stage.width, height: stage.height, id: this.context.uid };
|
package/src/constants.ts
CHANGED
@@ -5,7 +5,6 @@ export enum Events {
|
|
5
5
|
AppBoxStateChange = "AppBoxStateChange",
|
6
6
|
GetAttributes = "GetAttributes",
|
7
7
|
UpdateWindowManagerWrapper = "UpdateWindowManagerWrapper",
|
8
|
-
InitReplay = "InitReplay",
|
9
8
|
WindowCreated = "WindowCreated",
|
10
9
|
SetMainViewScenePath = "SetMainViewScenePath",
|
11
10
|
SetMainViewSceneIndex = "SetMainViewSceneIndex",
|
@@ -27,6 +26,11 @@ export enum AppAttributes {
|
|
27
26
|
Position = "position",
|
28
27
|
SceneIndex = "SceneIndex",
|
29
28
|
ZIndex = "zIndex",
|
29
|
+
Visible = "visible",
|
30
|
+
Ratio = "ratio",
|
31
|
+
StageRatio = "stageRatio",
|
32
|
+
Draggable = "draggable",
|
33
|
+
Resizable = "resizable",
|
30
34
|
}
|
31
35
|
|
32
36
|
export enum AppEvents {
|
package/src/index.ts
CHANGED
@@ -121,6 +121,11 @@ export type AppInitState = {
|
|
121
121
|
sceneIndex?: number;
|
122
122
|
boxState?: TeleBoxState; // 兼容旧版 telebox
|
123
123
|
zIndex?: number;
|
124
|
+
visible?: boolean;
|
125
|
+
stageRatio?: number;
|
126
|
+
resizable?: boolean;
|
127
|
+
draggable?: boolean;
|
128
|
+
ratio?: number;
|
124
129
|
};
|
125
130
|
|
126
131
|
export type CursorMovePayload = { uid: string; state?: "leave"; position: Position };
|