@netless/window-manager 1.0.0-canary.3 → 1.0.0-canary.32
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 +2284 -954
- 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} +10 -7
- 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} +40 -14
- package/dist/src/shim.d.ts +11 -0
- package/dist/{typings.d.ts → src/typings.d.ts} +8 -2
- 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 +29 -0
- package/pnpm-lock.yaml +517 -35
- package/src/App/AppContext.ts +50 -28
- package/src/App/AppProxy.ts +266 -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 +60 -40
- package/src/BuiltinApps.ts +5 -0
- package/src/Cursor/Cursor.ts +7 -3
- package/src/Cursor/index.ts +7 -8
- 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 +141 -57
- package/src/style.css +3 -46
- package/src/typings.ts +8 -2
- 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,29 @@ export class AppProxy implements PageRemoveService {
|
|
223
332
|
this.appResult = result;
|
224
333
|
appRegister.notifyApp(this.kind, "created", { appId, result });
|
225
334
|
this.fixMobileSize();
|
335
|
+
if (this.isAddApp) {
|
336
|
+
this.setupDone();
|
337
|
+
}
|
226
338
|
}, SETUP_APP_DELAY);
|
227
339
|
});
|
228
|
-
this.boxManager?.createBox({
|
340
|
+
const box = this.boxManager?.createBox({
|
229
341
|
appId: appId,
|
230
342
|
app,
|
231
343
|
options,
|
232
344
|
canOperate: this.manager.canOperate,
|
233
345
|
smartPosition: this.isAddApp,
|
234
|
-
});
|
346
|
+
}) as TeleBox;
|
347
|
+
const registerParams = appRegister.registered.get(this.kind);
|
348
|
+
if (registerParams?.contentStyles) {
|
349
|
+
box?.mountUserStyles(registerParams.contentStyles);
|
350
|
+
}
|
351
|
+
this.box$.setValue(box);
|
235
352
|
if (this.isAddApp && this.box) {
|
236
353
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
354
|
+
this.store.updateAppState(appId, AppAttributes.Size, {
|
355
|
+
width: this.box.intrinsicWidth,
|
356
|
+
height: this.box.intrinsicHeight,
|
357
|
+
});
|
237
358
|
this.boxManager.focusBox({ appId }, false);
|
238
359
|
}
|
239
360
|
} catch (error: any) {
|
@@ -246,12 +367,14 @@ export class AppProxy implements PageRemoveService {
|
|
246
367
|
private fixMobileSize() {
|
247
368
|
const box = this.boxManager?.getBox(this.id);
|
248
369
|
if (box) {
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
370
|
+
if (!box.minimized) {
|
371
|
+
this.boxManager?.resizeBox({
|
372
|
+
appId: this.id,
|
373
|
+
width: box.intrinsicWidth + 0.001,
|
374
|
+
height: box.intrinsicHeight + 0.001,
|
375
|
+
skipUpdate: true,
|
376
|
+
});
|
377
|
+
}
|
255
378
|
}
|
256
379
|
}
|
257
380
|
|
@@ -296,30 +419,18 @@ export class AppProxy implements PageRemoveService {
|
|
296
419
|
}
|
297
420
|
}
|
298
421
|
|
299
|
-
public getAppInitState = (id: string) => {
|
422
|
+
public getAppInitState = (id: string): AppState | undefined => {
|
300
423
|
const attrs = this.store.getAppState(id);
|
301
424
|
if (!attrs) return;
|
302
|
-
const position = attrs?.[AppAttributes.Position];
|
303
425
|
const focus = this.store.focus;
|
304
|
-
const size = attrs?.[AppAttributes.Size];
|
305
|
-
const sceneIndex = attrs?.[AppAttributes.SceneIndex];
|
306
426
|
const maximized = this.attributes?.["maximized"];
|
307
427
|
const minimized = this.attributes?.["minimized"];
|
308
|
-
|
309
|
-
|
310
|
-
if (position) {
|
311
|
-
payload = { ...payload, id: id, x: position.x, y: position.y };
|
312
|
-
}
|
428
|
+
let payload = { maximized, minimized, id } as AppState;
|
429
|
+
const state = omitBy(attrs, isUndefined);
|
313
430
|
if (focus === id) {
|
314
431
|
payload = { ...payload, focus: true };
|
315
432
|
}
|
316
|
-
|
317
|
-
payload = { ...payload, width: size.width, height: size.height };
|
318
|
-
}
|
319
|
-
if (sceneIndex) {
|
320
|
-
payload = { ...payload, sceneIndex };
|
321
|
-
}
|
322
|
-
return payload;
|
433
|
+
return Object.assign(payload, state);;
|
323
434
|
};
|
324
435
|
|
325
436
|
public emitAppSceneStateChange(sceneState: SceneState) {
|
@@ -376,32 +487,34 @@ export class AppProxy implements PageRemoveService {
|
|
376
487
|
}
|
377
488
|
|
378
489
|
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
|
-
|
490
|
+
this.sideEffectManager.add(() => [
|
491
|
+
this.manager.refresher.add(appId, () => {
|
492
|
+
return autorun(() => {
|
493
|
+
const attrs = this.manager.attributes[appId];
|
494
|
+
if (attrs) {
|
495
|
+
this.appEmitter.emit("attributesUpdate", attrs);
|
496
|
+
}
|
497
|
+
});
|
498
|
+
}),
|
499
|
+
this.manager.refresher.add(this.stateKey, () => {
|
500
|
+
return autorun(() => {
|
501
|
+
const appState = this.appAttributes?.state;
|
502
|
+
if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
|
503
|
+
this.boxManager?.setZIndex(appId, appState.zIndex);
|
504
|
+
}
|
505
|
+
});
|
506
|
+
}),
|
507
|
+
this.manager.refresher.add(`${appId}-fullPath`, () => {
|
508
|
+
return autorun(() => {
|
509
|
+
const fullPath = this.appAttributes?.fullPath;
|
510
|
+
this.setFocusScenePathHandler(fullPath);
|
511
|
+
if (this.fullPath$.value !== fullPath) {
|
512
|
+
this.notifyPageStateChange();
|
513
|
+
this.fullPath$.setValue(fullPath);
|
514
|
+
}
|
515
|
+
});
|
516
|
+
}),
|
517
|
+
]);
|
405
518
|
};
|
406
519
|
|
407
520
|
private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
|
@@ -419,6 +532,7 @@ export class AppProxy implements PageRemoveService {
|
|
419
532
|
}
|
420
533
|
|
421
534
|
public setViewFocusScenePath() {
|
535
|
+
if (this.status === "destroyed") return;
|
422
536
|
const fullPath = this.getFullScenePath();
|
423
537
|
if (fullPath && this.view) {
|
424
538
|
setViewFocusScenePath(this.view, fullPath);
|
@@ -428,6 +542,7 @@ export class AppProxy implements PageRemoveService {
|
|
428
542
|
|
429
543
|
private createView(): View {
|
430
544
|
const view = this.viewManager.createView(this.id);
|
545
|
+
this.view$.setValue(view);
|
431
546
|
this.setViewFocusScenePath();
|
432
547
|
return view;
|
433
548
|
}
|
@@ -477,10 +592,37 @@ export class AppProxy implements PageRemoveService {
|
|
477
592
|
const fullPath = this._pageState.getFullPath(index);
|
478
593
|
if (fullPath) {
|
479
594
|
this.setFullPath(fullPath);
|
595
|
+
setScenePath(this.manager.room, fullPath);
|
480
596
|
}
|
481
597
|
}
|
482
598
|
}
|
483
599
|
|
600
|
+
public storeCamera = (camera: ICamera) => {
|
601
|
+
this.store.updateAppAttributes(this.id, Fields.Camera, camera);
|
602
|
+
};
|
603
|
+
|
604
|
+
public storeSize = (size: ISize) => {
|
605
|
+
this.store.updateAppAttributes(this.id, Fields.Size, size);
|
606
|
+
};
|
607
|
+
|
608
|
+
public updateSize = (width: number, height: number) => {
|
609
|
+
const iSize = {
|
610
|
+
id: this.manager.uid,
|
611
|
+
width, height
|
612
|
+
}
|
613
|
+
this.store.updateAppAttributes(this.id, Fields.Size, iSize);
|
614
|
+
this.size$.setValue(iSize);
|
615
|
+
}
|
616
|
+
|
617
|
+
public moveCamera = (camera: Partial<ICamera>) => {
|
618
|
+
if (!this.camera$.value) {
|
619
|
+
return;
|
620
|
+
}
|
621
|
+
const nextCamera = { ...this.camera$.value, ...camera, id: this.uid };
|
622
|
+
this.storeCamera(nextCamera);
|
623
|
+
this.camera$.setValue(nextCamera);
|
624
|
+
};
|
625
|
+
|
484
626
|
public async destroy(
|
485
627
|
needCloseBox: boolean,
|
486
628
|
cleanAttrs: boolean,
|
@@ -491,11 +633,13 @@ export class AppProxy implements PageRemoveService {
|
|
491
633
|
this.status = "destroyed";
|
492
634
|
try {
|
493
635
|
await appRegister.notifyApp(this.kind, "destroy", { appId: this.id });
|
636
|
+
callbacks.emit("appClose", { appId: this.id, kind: this.kind, error });
|
494
637
|
await this.appEmitter.emit("destroy", { error });
|
495
638
|
} catch (error) {
|
496
639
|
console.error("[WindowManager]: notifyApp error", error.message, error.stack);
|
497
640
|
}
|
498
641
|
this.appEmitter.clearListeners();
|
642
|
+
this.sideEffectManager.flushAll();
|
499
643
|
emitter.emit(`destroy-${this.id}` as any, { error });
|
500
644
|
if (needCloseBox) {
|
501
645
|
this.boxManager?.closeBox(this.id, skipUpdate);
|
@@ -510,11 +654,53 @@ export class AppProxy implements PageRemoveService {
|
|
510
654
|
|
511
655
|
this.viewManager.destroyView(this.id);
|
512
656
|
this.manager.appStatus.delete(this.id);
|
513
|
-
this.
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
this.sideEffectManager.
|
657
|
+
this.valManager.destroy();
|
658
|
+
}
|
659
|
+
|
660
|
+
private addCameraReaction = () => {
|
661
|
+
this.sideEffectManager.add(() =>
|
662
|
+
this.manager.refresher.add(`${this.id}-camera`, () =>
|
663
|
+
reaction(
|
664
|
+
() => this.appAttributes?.camera,
|
665
|
+
camera => {
|
666
|
+
if (camera) {
|
667
|
+
const rawCamera = toJS(camera);
|
668
|
+
if (!isEqual(rawCamera, this.camera$.value)) {
|
669
|
+
this.camera$.setValue(rawCamera);
|
670
|
+
}
|
671
|
+
}
|
672
|
+
}
|
673
|
+
)
|
674
|
+
)
|
675
|
+
, "camera");
|
676
|
+
}
|
677
|
+
|
678
|
+
private addSizeReaction = () => {
|
679
|
+
this.sideEffectManager.add(() =>
|
680
|
+
this.manager.refresher.add(`${this.id}-size`, () =>
|
681
|
+
reaction(
|
682
|
+
() => this.appAttributes?.size,
|
683
|
+
size => {
|
684
|
+
if (size) {
|
685
|
+
const rawSize = toJS(size);
|
686
|
+
if (!isEqual(rawSize, this.size$.value)) {
|
687
|
+
this.size$.setValue(rawSize);
|
688
|
+
}
|
689
|
+
}
|
690
|
+
}
|
691
|
+
)
|
692
|
+
)
|
693
|
+
, "size");
|
694
|
+
}
|
695
|
+
|
696
|
+
public onFocus = () => {
|
697
|
+
this.setScenePath();
|
698
|
+
}
|
699
|
+
|
700
|
+
// 异步值设置完成通知其他端创建 app
|
701
|
+
private setupDone = () => {
|
702
|
+
this.store.updateAppAttributes(this.id, "setup", true);
|
703
|
+
this.manager.dispatchInternalEvent(Events.InvokeAttributesUpdateCallback);
|
518
704
|
}
|
519
705
|
|
520
706
|
public close(): Promise<void> {
|