@netless/window-manager 1.0.0-canary.3 → 1.0.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/__mocks__/white-web-sdk.ts +10 -1
- package/dist/index.cjs.js +120 -12
- package/dist/index.es.js +2243 -950
- package/dist/index.umd.js +120 -12
- package/dist/{App → src/App}/AppContext.d.ts +12 -8
- package/dist/{App → src/App}/AppPageStateImpl.d.ts +0 -0
- package/dist/{App → src/App}/AppProxy.d.ts +36 -7
- package/dist/{App → src/App}/MagixEvent/index.d.ts +0 -0
- package/dist/{App → src/App}/Storage/StorageEvent.d.ts +0 -0
- package/dist/{App → src/App}/Storage/index.d.ts +0 -0
- package/dist/{App → src/App}/Storage/typings.d.ts +0 -0
- package/dist/{App → src/App}/Storage/utils.d.ts +0 -0
- package/dist/src/App/WhiteboardView.d.ts +27 -0
- package/dist/{App → src/App}/index.d.ts +2 -1
- package/dist/src/App/type.d.ts +21 -0
- package/dist/{AppListener.d.ts → src/AppListener.d.ts} +0 -2
- package/dist/{AppManager.d.ts → src/AppManager.d.ts} +7 -6
- package/dist/{AttributesDelegate.d.ts → src/AttributesDelegate.d.ts} +11 -16
- package/dist/{BoxEmitter.d.ts → src/BoxEmitter.d.ts} +0 -0
- package/dist/{BoxManager.d.ts → src/BoxManager.d.ts} +8 -6
- package/dist/{BuiltinApps.d.ts → src/BuiltinApps.d.ts} +3 -0
- package/dist/{Cursor → src/Cursor}/Cursor.d.ts +0 -0
- package/dist/{Cursor → src/Cursor}/icons.d.ts +0 -0
- package/dist/{Cursor → src/Cursor}/index.d.ts +3 -3
- package/dist/{Helper.d.ts → src/Helper.d.ts} +4 -8
- package/dist/{InternalEmitter.d.ts → src/InternalEmitter.d.ts} +3 -4
- package/dist/{Page → src/Page}/PageController.d.ts +1 -0
- package/dist/{Page → src/Page}/index.d.ts +0 -0
- package/dist/{PageState.d.ts → src/PageState.d.ts} +0 -0
- package/dist/{ReconnectRefresher.d.ts → src/ReconnectRefresher.d.ts} +1 -1
- package/dist/{RedoUndo.d.ts → src/RedoUndo.d.ts} +0 -0
- package/dist/{Register → src/Register}/index.d.ts +0 -0
- package/dist/{Register → src/Register}/loader.d.ts +0 -0
- package/dist/{Register → src/Register}/storage.d.ts +0 -0
- package/dist/{Utils → src/Utils}/AppCreateQueue.d.ts +0 -0
- package/dist/{Utils → src/Utils}/Common.d.ts +1 -0
- package/dist/{Utils → src/Utils}/Reactive.d.ts +0 -0
- package/dist/{Utils → src/Utils}/RoomHacker.d.ts +0 -0
- package/dist/{Utils → src/Utils}/error.d.ts +0 -0
- package/dist/{Utils → src/Utils}/log.d.ts +0 -0
- package/dist/src/View/CameraSynchronizer.d.ts +18 -0
- package/dist/{View → src/View}/MainView.d.ts +18 -7
- package/dist/{View → src/View}/ViewManager.d.ts +0 -0
- package/dist/src/View/ViewSync.d.ts +24 -0
- package/dist/{callback.d.ts → src/callback.d.ts} +5 -0
- package/dist/{constants.d.ts → src/constants.d.ts} +8 -5
- package/dist/src/image.d.ts +19 -0
- package/dist/{index.d.ts → src/index.d.ts} +36 -13
- package/dist/src/shim.d.ts +11 -0
- package/dist/{typings.d.ts → src/typings.d.ts} +6 -0
- package/dist/style.css +1 -1
- package/docs/app-context.md +157 -25
- package/docs/mirgrate-to-1.0.md +28 -0
- package/package.json +12 -7
- package/playwright.config.ts +28 -0
- package/pnpm-lock.yaml +517 -35
- package/src/App/AppContext.ts +50 -28
- package/src/App/AppProxy.ts +264 -80
- package/src/App/{WhiteBoardView.ts → WhiteboardView.ts} +38 -7
- package/src/App/index.ts +2 -1
- package/src/App/type.ts +22 -0
- package/src/AppListener.ts +5 -21
- package/src/AppManager.ts +56 -43
- package/src/AttributesDelegate.ts +19 -19
- package/src/BoxManager.ts +54 -40
- package/src/BuiltinApps.ts +5 -0
- package/src/Cursor/Cursor.ts +6 -2
- package/src/Cursor/index.ts +5 -7
- package/src/Helper.ts +25 -7
- package/src/InternalEmitter.ts +3 -4
- package/src/Page/PageController.ts +1 -0
- package/src/PageState.ts +1 -1
- package/src/ReconnectRefresher.ts +7 -2
- package/src/Utils/Common.ts +9 -0
- package/src/Utils/Reactive.ts +27 -26
- package/src/Utils/RoomHacker.ts +3 -0
- package/src/View/CameraSynchronizer.ts +37 -34
- package/src/View/MainView.ts +108 -81
- package/src/View/ViewSync.ts +110 -0
- package/src/callback.ts +1 -0
- package/src/constants.ts +6 -3
- package/src/index.ts +126 -56
- package/src/style.css +2 -45
- package/src/typings.ts +6 -0
- package/vite.config.js +5 -3
- package/dist/App/WhiteBoardView.d.ts +0 -18
- package/dist/View/CameraSynchronizer.d.ts +0 -17
package/src/App/AppContext.ts
CHANGED
@@ -17,7 +17,6 @@ import type {
|
|
17
17
|
} from "white-web-sdk";
|
18
18
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
19
19
|
import type Emittery from "emittery";
|
20
|
-
import type { BoxManager } from "../BoxManager";
|
21
20
|
import type { AppEmitterEvent, Member } from "../index";
|
22
21
|
import type { AppManager } from "../AppManager";
|
23
22
|
import type { AppProxy } from "./AppProxy";
|
@@ -26,11 +25,15 @@ import type {
|
|
26
25
|
MagixEventDispatcher,
|
27
26
|
MagixEventRemoveListener,
|
28
27
|
} from "./MagixEvent";
|
29
|
-
import { WhiteBoardView } from "./
|
28
|
+
import { WhiteBoardView } from "./WhiteboardView";
|
30
29
|
import { findMemberByUid } from "../Helper";
|
31
30
|
import { MAX_PAGE_SIZE } from "../constants";
|
32
|
-
import {
|
33
|
-
|
31
|
+
import { isBoolean, isNumber } from "lodash";
|
32
|
+
|
33
|
+
export type CreateWhiteBoardViewParams = {
|
34
|
+
size?: number;
|
35
|
+
syncCamera?: boolean;
|
36
|
+
}
|
34
37
|
|
35
38
|
export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {
|
36
39
|
public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
|
@@ -49,11 +52,11 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
49
52
|
private store = this.manager.store;
|
50
53
|
public readonly isAddApp: boolean;
|
51
54
|
public readonly isReplay = this.manager.isReplay;
|
52
|
-
|
55
|
+
public whiteBoardView?: WhiteBoardView;
|
56
|
+
public _viewWrapper?: HTMLElement;
|
53
57
|
|
54
58
|
constructor(
|
55
59
|
private manager: AppManager,
|
56
|
-
private boxManager: BoxManager,
|
57
60
|
public appId: string,
|
58
61
|
private appProxy: AppProxy,
|
59
62
|
private appOptions?: TAppOptions | (() => TAppOptions)
|
@@ -62,9 +65,13 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
62
65
|
this.isAddApp = appProxy.isAddApp;
|
63
66
|
}
|
64
67
|
|
65
|
-
public get displayer(){
|
68
|
+
public get displayer() {
|
66
69
|
return this.manager.displayer;
|
67
|
-
}
|
70
|
+
}
|
71
|
+
|
72
|
+
public get destroyed() {
|
73
|
+
return this.appProxy.status === "destroyed";
|
74
|
+
}
|
68
75
|
|
69
76
|
/** @deprecated Use context.storage.state instead. */
|
70
77
|
public getAttributes = (): TAttributes | undefined => {
|
@@ -84,7 +91,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
84
91
|
return this.appProxy.view;
|
85
92
|
};
|
86
93
|
|
87
|
-
public createWhiteBoardView = (
|
94
|
+
public createWhiteBoardView = (params?: CreateWhiteBoardViewParams): WhiteBoardView => {
|
88
95
|
if (this.whiteBoardView) {
|
89
96
|
return this.whiteBoardView;
|
90
97
|
}
|
@@ -92,21 +99,39 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
92
99
|
if (!view) {
|
93
100
|
view = this.appProxy.createAppDir();
|
94
101
|
}
|
102
|
+
if (params) {
|
103
|
+
if (isBoolean(params.syncCamera)) {
|
104
|
+
this.appProxy.syncCamera$.setValue(params.syncCamera);
|
105
|
+
}
|
106
|
+
}
|
95
107
|
const viewWrapper = document.createElement("div");
|
108
|
+
this._viewWrapper = viewWrapper;
|
96
109
|
viewWrapper.className = "window-manager-view-wrapper";
|
97
|
-
this.box.$
|
98
|
-
|
99
|
-
|
100
|
-
}
|
101
|
-
view.divElement = viewWrapper
|
110
|
+
this.box.$main.appendChild(viewWrapper);
|
111
|
+
view.divElement = viewWrapper;
|
112
|
+
this.appProxy.fireMemberStateChange();
|
102
113
|
if (this.isAddApp) {
|
103
|
-
this.
|
114
|
+
this.ensurePageSize(params?.size);
|
104
115
|
}
|
105
|
-
this.whiteBoardView = new WhiteBoardView(this, this.appProxy,
|
116
|
+
this.whiteBoardView = new WhiteBoardView(view, this, this.appProxy, this.ensurePageSize);
|
117
|
+
this.appProxy.sideEffectManager.add(() => [
|
118
|
+
this.box._stageRect$.subscribe(rect => {
|
119
|
+
viewWrapper.style.left = `${rect.x}px`;
|
120
|
+
viewWrapper.style.top = `${rect.y}px`;
|
121
|
+
viewWrapper.style.width = `${rect.width}px`;
|
122
|
+
viewWrapper.style.height = `${rect.height}px`;
|
123
|
+
}),
|
124
|
+
() => {
|
125
|
+
return () => {
|
126
|
+
this.whiteBoardView = undefined;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
]);
|
130
|
+
this.appProxy.whiteBoardViewCreated$.setValue(true);
|
106
131
|
return this.whiteBoardView;
|
107
132
|
}
|
108
133
|
|
109
|
-
private
|
134
|
+
private ensurePageSize = (size?: number) => {
|
110
135
|
if (!isNumber(size)) return;
|
111
136
|
if (!this.appProxy.scenePath) return;
|
112
137
|
if (this.appProxy.pageState.length >= size) return;
|
@@ -114,25 +139,22 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
114
139
|
throw Error(`[WindowManager]: size ${size} muse be in range [1, ${MAX_PAGE_SIZE}]`);
|
115
140
|
}
|
116
141
|
const needInsert = size - this.appProxy.pageState.length;
|
117
|
-
const
|
118
|
-
|
119
|
-
return { name: `${startPageNumber + index + 1}` };
|
120
|
-
});
|
121
|
-
putScenes(this.room, this.appProxy.scenePath, scenes);
|
142
|
+
const scenes = new Array(needInsert).fill({});
|
143
|
+
this.room?.putScenes(this.appProxy.scenePath, scenes);
|
122
144
|
}
|
123
145
|
|
124
146
|
public getInitScenePath = () => {
|
125
|
-
return this.
|
147
|
+
return this.appProxy.scenePath;
|
126
148
|
};
|
127
149
|
|
128
150
|
/** Get App writable status. */
|
129
151
|
public get isWritable(): boolean {
|
130
|
-
return this.manager.canOperate;
|
152
|
+
return this.manager.canOperate && !this.destroyed;
|
131
153
|
};
|
132
154
|
|
133
155
|
/** Get the App Window UI box. */
|
134
156
|
public get box(): ReadonlyTeleBox {
|
135
|
-
const box = this.
|
157
|
+
const box = this.appProxy.box$.value;
|
136
158
|
if (box) {
|
137
159
|
return box;
|
138
160
|
} else {
|
@@ -144,11 +166,11 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
144
166
|
return this.manager.room;
|
145
167
|
};
|
146
168
|
|
147
|
-
public get members() {
|
148
|
-
return this.manager.members;
|
169
|
+
public get members(): Member[] {
|
170
|
+
return this.manager.members$.value;
|
149
171
|
}
|
150
172
|
|
151
|
-
public get
|
173
|
+
public get currentMember(): Member {
|
152
174
|
const self = findMemberByUid(this.room, this.manager.uid);
|
153
175
|
if (!self) {
|
154
176
|
throw new Error(`Member ${this.manager.uid} not found.`);
|
package/src/App/AppProxy.ts
CHANGED
@@ -3,12 +3,18 @@ import { AppAttributes, AppEvents, Events, SETUP_APP_DELAY } from "../constants"
|
|
3
3
|
import { AppContext } from "./AppContext";
|
4
4
|
import { AppPageStateImpl } from "./AppPageStateImpl";
|
5
5
|
import { appRegister } from "../Register";
|
6
|
-
import {
|
6
|
+
import { ViewSync } from "../View/ViewSync"
|
7
|
+
import { autorun, reaction, toJS } from "white-web-sdk";
|
8
|
+
import { boxEmitter } from "../BoxEmitter";
|
7
9
|
import { BoxManagerNotFoundError } from "../Utils/error";
|
8
|
-
import {
|
10
|
+
import { calculateNextIndex } from "../Page";
|
11
|
+
import { combine, Val, ValManager } from "value-enhancer";
|
12
|
+
import { debounce, get, isEqual, isUndefined, omitBy } from "lodash";
|
9
13
|
import { emitter } from "../InternalEmitter";
|
10
14
|
import { Fields } from "../AttributesDelegate";
|
11
15
|
import { log } from "../Utils/log";
|
16
|
+
import { SideEffectManager } from "side-effect-manager";
|
17
|
+
import type { ICamera, ISize } from "../AttributesDelegate";
|
12
18
|
import {
|
13
19
|
entireScenes,
|
14
20
|
getScenePath,
|
@@ -19,19 +25,17 @@ import {
|
|
19
25
|
} from "../Utils/Common";
|
20
26
|
import type {
|
21
27
|
AppEmitterEvent,
|
22
|
-
AppInitState,
|
23
28
|
BaseInsertParams,
|
24
29
|
setAppOptions,
|
25
30
|
AppListenerKeys,
|
26
31
|
} from "../index";
|
27
|
-
import type { SceneState, View, SceneDefinition
|
32
|
+
import type { SceneState, View, SceneDefinition, MemberState} from "white-web-sdk";
|
28
33
|
import type { AppManager } from "../AppManager";
|
29
34
|
import type { NetlessApp } from "../typings";
|
30
|
-
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
35
|
+
import type { ReadonlyTeleBox, TeleBox, TeleBoxRect } from "@netless/telebox-insider";
|
31
36
|
import type { PageRemoveService, PageState } from "../Page";
|
32
|
-
import {
|
33
|
-
import {
|
34
|
-
import { SideEffectManager } from "side-effect-manager";
|
37
|
+
import type { AppState } from "./type";
|
38
|
+
import { callbacks } from "../callback";
|
35
39
|
|
36
40
|
export type AppEmitter = Emittery<AppEmitterEvent>;
|
37
41
|
|
@@ -48,17 +52,28 @@ export class AppProxy implements PageRemoveService {
|
|
48
52
|
private appProxies = this.manager.appProxies;
|
49
53
|
private viewManager = this.manager.viewManager;
|
50
54
|
private store = this.manager.store;
|
55
|
+
public uid = this.manager.uid;
|
51
56
|
|
52
57
|
public isAddApp: boolean;
|
53
|
-
|
58
|
+
public status: "normal" | "destroyed" = "normal";
|
54
59
|
private stateKey: string;
|
55
60
|
public _pageState: AppPageStateImpl;
|
56
|
-
private _prevFullPath: string | undefined;
|
57
61
|
|
58
|
-
public appResult?: NetlessApp
|
59
|
-
public appContext?: AppContext
|
62
|
+
public appResult?: NetlessApp;
|
63
|
+
public appContext?: AppContext;
|
64
|
+
|
65
|
+
public sideEffectManager = new SideEffectManager();
|
66
|
+
private valManager = new ValManager();
|
60
67
|
|
61
|
-
private
|
68
|
+
private fullPath$ = this.valManager.attach(new Val<string | undefined>(undefined));
|
69
|
+
private viewSync?: ViewSync;
|
70
|
+
|
71
|
+
public camera$ = this.valManager.attach(new Val<ICamera | undefined>(undefined));
|
72
|
+
public size$ = this.valManager.attach(new Val<ISize | undefined>(undefined));
|
73
|
+
public box$ = this.valManager.attach(new Val<ReadonlyTeleBox | undefined>(undefined));
|
74
|
+
public view$ = this.valManager.attach(new Val<View | undefined>(undefined));
|
75
|
+
public syncCamera$ = this.valManager.attach(new Val<boolean>(true));
|
76
|
+
public whiteBoardViewCreated$ = this.valManager.attach(new Val<boolean>(false));
|
62
77
|
|
63
78
|
constructor(
|
64
79
|
private params: BaseInsertParams,
|
@@ -90,14 +105,108 @@ export class AppProxy implements PageRemoveService {
|
|
90
105
|
view: this.view,
|
91
106
|
notifyPageStateChange: this.notifyPageStateChange,
|
92
107
|
});
|
93
|
-
this.sideEffectManager.add(() =>
|
94
|
-
|
95
|
-
|
96
|
-
this.
|
97
|
-
|
108
|
+
this.sideEffectManager.add(() => () => this._pageState.destroy());
|
109
|
+
this.camera$.setValue(toJS(this.appAttributes.camera));
|
110
|
+
this.size$.setValue(toJS(this.appAttributes.size));
|
111
|
+
this.addCameraReaction();
|
112
|
+
this.addSizeReaction();
|
113
|
+
this.sideEffectManager.add(() =>
|
114
|
+
emitter.on("memberStateChange", this.onMemberStateChange)
|
115
|
+
);
|
116
|
+
this.sideEffectManager.add(() => [
|
117
|
+
this.syncCamera$.reaction(syncCamera => {
|
118
|
+
if (!syncCamera) {
|
119
|
+
if (this.viewSync) {
|
120
|
+
this.viewSync.destroy();
|
121
|
+
this.viewSync = undefined;
|
122
|
+
this.sideEffectManager.flush("camera");
|
123
|
+
this.sideEffectManager.flush("size");
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}),
|
127
|
+
this.whiteBoardViewCreated$.reaction(created => {
|
128
|
+
if (created && this.box) {
|
129
|
+
if (!this.syncCamera$.value) return;
|
130
|
+
combine([this.box$, this.view$]).subscribe(([box, view]) => {
|
131
|
+
if (box && view) {
|
132
|
+
if (!this.camera$.value) {
|
133
|
+
this.storeCamera({
|
134
|
+
centerX: null,
|
135
|
+
centerY: null,
|
136
|
+
scale: 1,
|
137
|
+
id: this.uid,
|
138
|
+
});
|
139
|
+
this.camera$.setValue(toJS(this.appAttributes.camera));
|
140
|
+
}
|
141
|
+
if (!this.size$.value && box.stageRect) {
|
142
|
+
const initialRect = this.computedInitialRect(box.stageRect);
|
143
|
+
const width = initialRect?.width || box.stageRect.width;
|
144
|
+
const height = initialRect?.height || box.stageRect.height;
|
145
|
+
this.storeSize({
|
146
|
+
id: this.uid,
|
147
|
+
width,
|
148
|
+
height,
|
149
|
+
});
|
150
|
+
this.size$.setValue(toJS(this.appAttributes.size));
|
151
|
+
}
|
152
|
+
this.viewSync = new ViewSync({
|
153
|
+
uid: this.uid,
|
154
|
+
view$: this.view$,
|
155
|
+
camera$: this.camera$,
|
156
|
+
size$: this.size$,
|
157
|
+
stageRect$: box._stageRect$,
|
158
|
+
storeCamera: this.storeCamera,
|
159
|
+
storeSize: this.storeSize
|
160
|
+
});
|
161
|
+
this.sideEffectManager.add(() => () => this.viewSync?.destroy());
|
162
|
+
this.whiteBoardViewCreated$.destroy();
|
163
|
+
}
|
164
|
+
})
|
165
|
+
}
|
166
|
+
}),
|
167
|
+
this.manager.members$.reaction(members => {
|
98
168
|
this.appEmitter.emit("roomMembersChange", members);
|
99
|
-
})
|
100
|
-
|
169
|
+
}),
|
170
|
+
]);
|
171
|
+
}
|
172
|
+
|
173
|
+
public fireMemberStateChange = () => {
|
174
|
+
if (this.manager.room) {
|
175
|
+
this.onMemberStateChange(this.manager.room.state.memberState);
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
private onMemberStateChange = (memberState: MemberState) => {
|
180
|
+
// clicker 教具把事件穿透给下层
|
181
|
+
const needPointerEventsNone = memberState.currentApplianceName === "clicker";
|
182
|
+
if (needPointerEventsNone) {
|
183
|
+
if (this.appContext?._viewWrapper) {
|
184
|
+
this.appContext._viewWrapper.style.pointerEvents = "none";
|
185
|
+
}
|
186
|
+
} else {
|
187
|
+
if (this.appContext?._viewWrapper) {
|
188
|
+
this.appContext._viewWrapper.style.pointerEvents = "auto";
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
private computedInitialRect = (boxRect: TeleBoxRect) => {
|
194
|
+
const managerRect = this.manager.boxManager?.stageRect;
|
195
|
+
if (managerRect) {
|
196
|
+
const { width, height } = managerRect;
|
197
|
+
const boxRatio = boxRect.height / boxRect.width;
|
198
|
+
if (height < 480) {
|
199
|
+
return {
|
200
|
+
width: 480 / boxRatio,
|
201
|
+
height: 480,
|
202
|
+
};
|
203
|
+
} else {
|
204
|
+
return {
|
205
|
+
width: width * 0.65,
|
206
|
+
height: height * 0.65,
|
207
|
+
};
|
208
|
+
}
|
209
|
+
}
|
101
210
|
}
|
102
211
|
|
103
212
|
public createAppDir() {
|
@@ -127,7 +236,7 @@ export class AppProxy implements PageRemoveService {
|
|
127
236
|
}
|
128
237
|
|
129
238
|
public get view(): View | undefined {
|
130
|
-
return this.
|
239
|
+
return this.view$.value;
|
131
240
|
}
|
132
241
|
|
133
242
|
public get viewIndex(): number | undefined {
|
@@ -162,7 +271,7 @@ export class AppProxy implements PageRemoveService {
|
|
162
271
|
}
|
163
272
|
|
164
273
|
public setFullPath(path: string) {
|
165
|
-
this.
|
274
|
+
this.store.updateAppAttributes(this.id, Fields.FullPath, path);
|
166
275
|
}
|
167
276
|
|
168
277
|
public async baseInsertApp(skipUpdate = false): Promise<{ appId: string; app: NetlessApp }> {
|
@@ -191,7 +300,7 @@ export class AppProxy implements PageRemoveService {
|
|
191
300
|
}
|
192
301
|
|
193
302
|
public get box(): ReadonlyTeleBox | undefined {
|
194
|
-
return this.
|
303
|
+
return this.box$.value;
|
195
304
|
}
|
196
305
|
|
197
306
|
private async setupApp(
|
@@ -205,11 +314,11 @@ export class AppProxy implements PageRemoveService {
|
|
205
314
|
if (!this.boxManager) {
|
206
315
|
throw new BoxManagerNotFoundError();
|
207
316
|
}
|
208
|
-
const context = new AppContext(this.manager,
|
317
|
+
const context = new AppContext(this.manager, appId, this, appOptions);
|
209
318
|
this.appContext = context;
|
210
319
|
try {
|
211
320
|
emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
|
212
|
-
let boxInitState:
|
321
|
+
let boxInitState: AppState | undefined;
|
213
322
|
if (!skipUpdate) {
|
214
323
|
boxInitState = this.getAppInitState(appId);
|
215
324
|
this.boxManager?.updateBoxState(boxInitState);
|
@@ -223,17 +332,27 @@ export class AppProxy implements PageRemoveService {
|
|
223
332
|
this.appResult = result;
|
224
333
|
appRegister.notifyApp(this.kind, "created", { appId, result });
|
225
334
|
this.fixMobileSize();
|
335
|
+
this.setupDone();
|
226
336
|
}, SETUP_APP_DELAY);
|
227
337
|
});
|
228
|
-
this.boxManager?.createBox({
|
338
|
+
const box = this.boxManager?.createBox({
|
229
339
|
appId: appId,
|
230
340
|
app,
|
231
341
|
options,
|
232
342
|
canOperate: this.manager.canOperate,
|
233
343
|
smartPosition: this.isAddApp,
|
234
|
-
});
|
344
|
+
}) as TeleBox;
|
345
|
+
const registerParams = appRegister.registered.get(this.kind);
|
346
|
+
if (registerParams?.contentStyles) {
|
347
|
+
box?.mountUserStyles(registerParams.contentStyles);
|
348
|
+
}
|
349
|
+
this.box$.setValue(box);
|
235
350
|
if (this.isAddApp && this.box) {
|
236
351
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
352
|
+
this.store.updateAppState(appId, AppAttributes.Size, {
|
353
|
+
width: this.box.intrinsicWidth,
|
354
|
+
height: this.box.intrinsicHeight,
|
355
|
+
});
|
237
356
|
this.boxManager.focusBox({ appId }, false);
|
238
357
|
}
|
239
358
|
} catch (error: any) {
|
@@ -246,12 +365,14 @@ export class AppProxy implements PageRemoveService {
|
|
246
365
|
private fixMobileSize() {
|
247
366
|
const box = this.boxManager?.getBox(this.id);
|
248
367
|
if (box) {
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
368
|
+
if (!box.minimized) {
|
369
|
+
this.boxManager?.resizeBox({
|
370
|
+
appId: this.id,
|
371
|
+
width: box.intrinsicWidth + 0.001,
|
372
|
+
height: box.intrinsicHeight + 0.001,
|
373
|
+
skipUpdate: true,
|
374
|
+
});
|
375
|
+
}
|
255
376
|
}
|
256
377
|
}
|
257
378
|
|
@@ -296,30 +417,18 @@ export class AppProxy implements PageRemoveService {
|
|
296
417
|
}
|
297
418
|
}
|
298
419
|
|
299
|
-
public getAppInitState = (id: string) => {
|
420
|
+
public getAppInitState = (id: string): AppState | undefined => {
|
300
421
|
const attrs = this.store.getAppState(id);
|
301
422
|
if (!attrs) return;
|
302
|
-
const position = attrs?.[AppAttributes.Position];
|
303
423
|
const focus = this.store.focus;
|
304
|
-
const size = attrs?.[AppAttributes.Size];
|
305
|
-
const sceneIndex = attrs?.[AppAttributes.SceneIndex];
|
306
424
|
const maximized = this.attributes?.["maximized"];
|
307
425
|
const minimized = this.attributes?.["minimized"];
|
308
|
-
|
309
|
-
|
310
|
-
if (position) {
|
311
|
-
payload = { ...payload, id: id, x: position.x, y: position.y };
|
312
|
-
}
|
426
|
+
let payload = { maximized, minimized, id } as AppState;
|
427
|
+
const state = omitBy(attrs, isUndefined);
|
313
428
|
if (focus === id) {
|
314
429
|
payload = { ...payload, focus: true };
|
315
430
|
}
|
316
|
-
|
317
|
-
payload = { ...payload, width: size.width, height: size.height };
|
318
|
-
}
|
319
|
-
if (sceneIndex) {
|
320
|
-
payload = { ...payload, sceneIndex };
|
321
|
-
}
|
322
|
-
return payload;
|
431
|
+
return Object.assign(payload, state);;
|
323
432
|
};
|
324
433
|
|
325
434
|
public emitAppSceneStateChange(sceneState: SceneState) {
|
@@ -376,32 +485,34 @@ export class AppProxy implements PageRemoveService {
|
|
376
485
|
}
|
377
486
|
|
378
487
|
private appAttributesUpdateListener = (appId: string) => {
|
379
|
-
this.
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
this.
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
488
|
+
this.sideEffectManager.add(() => [
|
489
|
+
this.manager.refresher.add(appId, () => {
|
490
|
+
return autorun(() => {
|
491
|
+
const attrs = this.manager.attributes[appId];
|
492
|
+
if (attrs) {
|
493
|
+
this.appEmitter.emit("attributesUpdate", attrs);
|
494
|
+
}
|
495
|
+
});
|
496
|
+
}),
|
497
|
+
this.manager.refresher.add(this.stateKey, () => {
|
498
|
+
return autorun(() => {
|
499
|
+
const appState = this.appAttributes?.state;
|
500
|
+
if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
|
501
|
+
this.boxManager?.setZIndex(appId, appState.zIndex);
|
502
|
+
}
|
503
|
+
});
|
504
|
+
}),
|
505
|
+
this.manager.refresher.add(`${appId}-fullPath`, () => {
|
506
|
+
return autorun(() => {
|
507
|
+
const fullPath = this.appAttributes?.fullPath;
|
508
|
+
this.setFocusScenePathHandler(fullPath);
|
509
|
+
if (this.fullPath$.value !== fullPath) {
|
510
|
+
this.notifyPageStateChange();
|
511
|
+
this.fullPath$.setValue(fullPath);
|
512
|
+
}
|
513
|
+
});
|
514
|
+
}),
|
515
|
+
]);
|
405
516
|
};
|
406
517
|
|
407
518
|
private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
|
@@ -419,6 +530,7 @@ export class AppProxy implements PageRemoveService {
|
|
419
530
|
}
|
420
531
|
|
421
532
|
public setViewFocusScenePath() {
|
533
|
+
if (this.status === "destroyed") return;
|
422
534
|
const fullPath = this.getFullScenePath();
|
423
535
|
if (fullPath && this.view) {
|
424
536
|
setViewFocusScenePath(this.view, fullPath);
|
@@ -428,6 +540,7 @@ export class AppProxy implements PageRemoveService {
|
|
428
540
|
|
429
541
|
private createView(): View {
|
430
542
|
const view = this.viewManager.createView(this.id);
|
543
|
+
this.view$.setValue(view);
|
431
544
|
this.setViewFocusScenePath();
|
432
545
|
return view;
|
433
546
|
}
|
@@ -477,10 +590,37 @@ export class AppProxy implements PageRemoveService {
|
|
477
590
|
const fullPath = this._pageState.getFullPath(index);
|
478
591
|
if (fullPath) {
|
479
592
|
this.setFullPath(fullPath);
|
593
|
+
setScenePath(this.manager.room, fullPath);
|
480
594
|
}
|
481
595
|
}
|
482
596
|
}
|
483
597
|
|
598
|
+
public storeCamera = (camera: ICamera) => {
|
599
|
+
this.store.updateAppAttributes(this.id, Fields.Camera, camera);
|
600
|
+
};
|
601
|
+
|
602
|
+
public storeSize = (size: ISize) => {
|
603
|
+
this.store.updateAppAttributes(this.id, Fields.Size, size);
|
604
|
+
};
|
605
|
+
|
606
|
+
public updateSize = (width: number, height: number) => {
|
607
|
+
const iSize = {
|
608
|
+
id: this.manager.uid,
|
609
|
+
width, height
|
610
|
+
}
|
611
|
+
this.store.updateAppAttributes(this.id, Fields.Size, iSize);
|
612
|
+
this.size$.setValue(iSize);
|
613
|
+
}
|
614
|
+
|
615
|
+
public moveCamera = (camera: Partial<ICamera>) => {
|
616
|
+
if (!this.camera$.value) {
|
617
|
+
return;
|
618
|
+
}
|
619
|
+
const nextCamera = { ...this.camera$.value, ...camera, id: this.uid };
|
620
|
+
this.storeCamera(nextCamera);
|
621
|
+
this.camera$.setValue(nextCamera);
|
622
|
+
};
|
623
|
+
|
484
624
|
public async destroy(
|
485
625
|
needCloseBox: boolean,
|
486
626
|
cleanAttrs: boolean,
|
@@ -491,11 +631,13 @@ export class AppProxy implements PageRemoveService {
|
|
491
631
|
this.status = "destroyed";
|
492
632
|
try {
|
493
633
|
await appRegister.notifyApp(this.kind, "destroy", { appId: this.id });
|
634
|
+
callbacks.emit("appClose", { appId: this.id, kind: this.kind, error });
|
494
635
|
await this.appEmitter.emit("destroy", { error });
|
495
636
|
} catch (error) {
|
496
637
|
console.error("[WindowManager]: notifyApp error", error.message, error.stack);
|
497
638
|
}
|
498
639
|
this.appEmitter.clearListeners();
|
640
|
+
this.sideEffectManager.flushAll();
|
499
641
|
emitter.emit(`destroy-${this.id}` as any, { error });
|
500
642
|
if (needCloseBox) {
|
501
643
|
this.boxManager?.closeBox(this.id, skipUpdate);
|
@@ -510,11 +652,53 @@ export class AppProxy implements PageRemoveService {
|
|
510
652
|
|
511
653
|
this.viewManager.destroyView(this.id);
|
512
654
|
this.manager.appStatus.delete(this.id);
|
513
|
-
this.
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
this.sideEffectManager.
|
655
|
+
this.valManager.destroy();
|
656
|
+
}
|
657
|
+
|
658
|
+
private addCameraReaction = () => {
|
659
|
+
this.sideEffectManager.add(() =>
|
660
|
+
this.manager.refresher.add(`${this.id}-camera`, () =>
|
661
|
+
reaction(
|
662
|
+
() => this.appAttributes?.camera,
|
663
|
+
camera => {
|
664
|
+
if (camera) {
|
665
|
+
const rawCamera = toJS(camera);
|
666
|
+
if (!isEqual(rawCamera, this.camera$.value)) {
|
667
|
+
this.camera$.setValue(rawCamera);
|
668
|
+
}
|
669
|
+
}
|
670
|
+
}
|
671
|
+
)
|
672
|
+
)
|
673
|
+
, "camera");
|
674
|
+
}
|
675
|
+
|
676
|
+
private addSizeReaction = () => {
|
677
|
+
this.sideEffectManager.add(() =>
|
678
|
+
this.manager.refresher.add(`${this.id}-size`, () =>
|
679
|
+
reaction(
|
680
|
+
() => this.appAttributes?.size,
|
681
|
+
size => {
|
682
|
+
if (size) {
|
683
|
+
const rawSize = toJS(size);
|
684
|
+
if (!isEqual(rawSize, this.size$.value)) {
|
685
|
+
this.size$.setValue(rawSize);
|
686
|
+
}
|
687
|
+
}
|
688
|
+
}
|
689
|
+
)
|
690
|
+
)
|
691
|
+
, "size");
|
692
|
+
}
|
693
|
+
|
694
|
+
public onFocus = () => {
|
695
|
+
this.setScenePath();
|
696
|
+
}
|
697
|
+
|
698
|
+
// 异步值设置完成通知其他端创建 app
|
699
|
+
private setupDone = () => {
|
700
|
+
this.store.updateAppAttributes(this.id, "setup", true);
|
701
|
+
this.manager.dispatchInternalEvent(Events.InvokeAttributesUpdateCallback);
|
518
702
|
}
|
519
703
|
|
520
704
|
public close(): Promise<void> {
|