@netless/window-manager 1.0.0-canary.6 → 1.0.0-canary.60
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/README.md +30 -6
- package/dist/index.js +13539 -0
- package/dist/index.mjs +13536 -0
- package/dist/index.umd.js +13534 -46
- package/dist/{App → src/App}/AppContext.d.ts +16 -14
- package/dist/{App → src/App}/AppPageStateImpl.d.ts +0 -0
- package/dist/{App → src/App}/AppProxy.d.ts +30 -11
- package/dist/{App → src/App}/MagixEvent/index.d.ts +0 -0
- package/dist/src/App/WhiteboardView.d.ts +27 -0
- package/dist/{App → src/App}/index.d.ts +1 -0
- package/dist/src/App/type.d.ts +21 -0
- package/dist/{AppListener.d.ts → src/AppListener.d.ts} +2 -2
- package/dist/{AppManager.d.ts → src/AppManager.d.ts} +11 -6
- package/dist/{AttributesDelegate.d.ts → src/AttributesDelegate.d.ts} +5 -2
- package/dist/{BoxEmitter.d.ts → src/BoxEmitter.d.ts} +0 -0
- package/dist/{BoxManager.d.ts → src/BoxManager.d.ts} +12 -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 +4 -3
- package/dist/{Helper.d.ts → src/Helper.d.ts} +4 -8
- package/dist/{InternalEmitter.d.ts → src/InternalEmitter.d.ts} +1 -4
- package/dist/{Page → src/Page}/PageController.d.ts +2 -1
- 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} +0 -0
- package/dist/{RedoUndo.d.ts → src/RedoUndo.d.ts} +0 -0
- package/dist/{Register → src/Register}/index.d.ts +4 -2
- package/dist/{Register → src/Register}/loader.d.ts +1 -1
- package/dist/src/Register/storage.d.ts +11 -0
- package/dist/{Utils → src/Utils}/AppCreateQueue.d.ts +0 -0
- package/dist/{Utils → src/Utils}/Common.d.ts +0 -0
- package/dist/{Utils → src/Utils}/Reactive.d.ts +1 -1
- package/dist/{Utils → src/Utils}/RoomHacker.d.ts +0 -0
- package/dist/{Utils → src/Utils}/error.d.ts +1 -1
- package/dist/{Utils → src/Utils}/log.d.ts +0 -0
- package/dist/src/View/CameraSynchronizer.d.ts +20 -0
- package/dist/{View → src/View}/MainView.d.ts +18 -7
- package/dist/src/View/ScrollMode.d.ts +32 -0
- package/dist/{View → src/View}/ViewManager.d.ts +0 -0
- package/dist/src/View/ViewSync.d.ts +32 -0
- package/dist/{callback.d.ts → src/callback.d.ts} +13 -1
- package/dist/{constants.d.ts → src/constants.d.ts} +12 -5
- package/dist/src/image.d.ts +19 -0
- package/dist/{index.d.ts → src/index.d.ts} +66 -17
- package/dist/src/shim.d.ts +11 -0
- package/dist/src/storage.d.ts +7 -0
- package/dist/{typings.d.ts → src/typings.d.ts} +18 -8
- package/dist/style.css +810 -1
- package/docs/api.md +10 -0
- package/docs/app-context.md +155 -27
- package/docs/mirgrate-to-1.0.md +68 -0
- package/package.json +27 -22
- package/playwright.config.ts +29 -0
- package/pnpm-lock.yaml +3141 -4483
- package/src/App/AppContext.ts +81 -46
- package/src/App/AppProxy.ts +249 -139
- package/src/App/WhiteboardView.ts +38 -14
- package/src/App/index.ts +1 -0
- package/src/App/type.ts +22 -0
- package/src/AppListener.ts +21 -21
- package/src/AppManager.ts +84 -43
- package/src/AttributesDelegate.ts +6 -3
- package/src/BoxManager.ts +76 -38
- package/src/BuiltinApps.ts +9 -8
- package/src/Cursor/Cursor.svelte +6 -2
- package/src/Cursor/Cursor.ts +16 -5
- package/src/Cursor/icons.ts +6 -0
- package/src/Cursor/index.ts +13 -10
- package/src/Helper.ts +25 -7
- package/src/InternalEmitter.ts +1 -4
- package/src/Page/PageController.ts +2 -1
- package/src/PageState.ts +1 -1
- package/src/ReconnectRefresher.ts +6 -2
- package/src/Register/index.ts +36 -14
- package/src/Register/loader.ts +20 -9
- package/src/Register/storage.ts +26 -5
- package/src/Utils/Common.ts +3 -0
- package/src/Utils/Reactive.ts +29 -27
- package/src/Utils/RoomHacker.ts +3 -0
- package/src/Utils/error.ts +2 -2
- package/src/View/CameraSynchronizer.ts +52 -37
- package/src/View/MainView.ts +118 -76
- package/src/View/ScrollMode.ts +239 -0
- package/src/View/ViewSync.ts +139 -6
- package/src/callback.ts +9 -1
- package/src/constants.ts +11 -3
- package/src/image/pencil-eraser-1.svg +3 -0
- package/src/image/pencil-eraser-2.svg +3 -0
- package/src/image/pencil-eraser-3.svg +3 -0
- package/src/index.ts +202 -58
- package/src/storage.ts +15 -0
- package/src/style.css +18 -47
- package/src/typings.ts +21 -7
- package/vite.config.js +12 -7
- package/dist/App/AppViewSync.d.ts +0 -11
- package/dist/App/Storage/StorageEvent.d.ts +0 -8
- package/dist/App/Storage/index.d.ts +0 -39
- package/dist/App/Storage/typings.d.ts +0 -22
- package/dist/App/Storage/utils.d.ts +0 -5
- package/dist/App/WhiteboardView.d.ts +0 -21
- package/dist/Register/storage.d.ts +0 -8
- package/dist/View/CameraSynchronizer.d.ts +0 -17
- package/dist/View/ViewSync.d.ts +0 -7
- package/dist/index.cjs.js +0 -46
- package/dist/index.es.js +0 -16159
- package/src/App/AppViewSync.ts +0 -68
- package/src/App/Storage/StorageEvent.ts +0 -21
- package/src/App/Storage/index.ts +0 -295
- package/src/App/Storage/typings.ts +0 -23
- package/src/App/Storage/utils.ts +0 -17
package/src/App/AppProxy.ts
CHANGED
@@ -3,13 +3,13 @@ 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
7
|
import { autorun, reaction, toJS } from "white-web-sdk";
|
8
8
|
import { boxEmitter } from "../BoxEmitter";
|
9
|
-
import {
|
9
|
+
import { BoxManagerNotInitializeError } from "../Utils/error";
|
10
10
|
import { calculateNextIndex } from "../Page";
|
11
|
-
import { combine, Val } from "value-enhancer";
|
12
|
-
import { debounce, get } from "lodash";
|
11
|
+
import { combine, Val, ValManager } from "value-enhancer";
|
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,16 +25,17 @@ import {
|
|
25
25
|
} from "../Utils/Common";
|
26
26
|
import type {
|
27
27
|
AppEmitterEvent,
|
28
|
-
AppInitState,
|
29
28
|
BaseInsertParams,
|
30
29
|
setAppOptions,
|
31
30
|
AppListenerKeys,
|
32
31
|
} from "../index";
|
33
|
-
import type { SceneState, View, SceneDefinition,
|
32
|
+
import type { SceneState, View, SceneDefinition, MemberState} from "white-web-sdk";
|
34
33
|
import type { AppManager } from "../AppManager";
|
35
34
|
import type { NetlessApp } from "../typings";
|
36
|
-
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
35
|
+
import type { ReadonlyTeleBox, TeleBox, TeleBoxRect } from "@netless/telebox-insider";
|
37
36
|
import type { PageRemoveService, PageState } from "../Page";
|
37
|
+
import type { AppState } from "./type";
|
38
|
+
import { callbacks } from "../callback";
|
38
39
|
|
39
40
|
export type AppEmitter = Emittery<AppEmitterEvent>;
|
40
41
|
|
@@ -54,23 +55,25 @@ export class AppProxy implements PageRemoveService {
|
|
54
55
|
public uid = this.manager.uid;
|
55
56
|
|
56
57
|
public isAddApp: boolean;
|
57
|
-
|
58
|
+
public status: "normal" | "destroyed" = "normal";
|
58
59
|
private stateKey: string;
|
59
60
|
public _pageState: AppPageStateImpl;
|
60
|
-
private _prevFullPath: string | undefined;
|
61
61
|
|
62
|
-
public appResult?: NetlessApp
|
63
|
-
public appContext?: AppContext
|
62
|
+
public appResult?: NetlessApp;
|
63
|
+
public appContext?: AppContext;
|
64
64
|
|
65
|
-
|
65
|
+
public sideEffectManager = new SideEffectManager();
|
66
|
+
private valManager = new ValManager();
|
66
67
|
|
67
|
-
|
68
|
-
|
68
|
+
private fullPath$ = this.valManager.attach(new Val<string | undefined>(undefined));
|
69
|
+
private viewSync?: ViewSync;
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
public box$ = new Val<ReadonlyTeleBox | undefined>(undefined);
|
73
|
-
public view$ = new Val<View | undefined>(undefined);
|
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));
|
74
77
|
|
75
78
|
constructor(
|
76
79
|
private params: BaseInsertParams,
|
@@ -103,68 +106,107 @@ export class AppProxy implements PageRemoveService {
|
|
103
106
|
notifyPageStateChange: this.notifyPageStateChange,
|
104
107
|
});
|
105
108
|
this.sideEffectManager.add(() => () => this._pageState.destroy());
|
106
|
-
this.sideEffectManager.add(() =>
|
107
|
-
emitter.on("roomMembersChange", members => {
|
108
|
-
this.appEmitter.emit("roomMembersChange", members);
|
109
|
-
})
|
110
|
-
);
|
111
109
|
this.camera$.setValue(toJS(this.appAttributes.camera));
|
112
110
|
this.size$.setValue(toJS(this.appAttributes.size));
|
113
|
-
this.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
return this.manager.refresher.add(`${this.id}-size`, () => {
|
127
|
-
return reaction(
|
128
|
-
() => this.appAttributes?.size,
|
129
|
-
size => {
|
130
|
-
if (size && size.id !== this.uid) {
|
131
|
-
this.size$.setValue(toJS(size));
|
132
|
-
}
|
111
|
+
this.addCameraReaction();
|
112
|
+
this.addSizeReaction();
|
113
|
+
this.sideEffectManager.add(() =>
|
114
|
+
emitter.on("memberStateChange", this.onMemberStateChange)
|
115
|
+
);
|
116
|
+
this.sideEffectManager.add(() => [
|
117
|
+
this.syncCamera$.subscribe(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");
|
133
124
|
}
|
134
|
-
);
|
135
|
-
});
|
136
|
-
});
|
137
|
-
combine([this.box$, this.view$]).subscribe(([box, view]) => {
|
138
|
-
if (box && view) {
|
139
|
-
if (!this.camera$.value) {
|
140
|
-
this.storeCamera({
|
141
|
-
centerX: 0, centerY: 0, scale: 1, id: this.uid,
|
142
|
-
});
|
143
125
|
}
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
+
})
|
150
165
|
}
|
151
|
-
|
152
|
-
|
166
|
+
}),
|
167
|
+
this.manager.members$.reaction(members => {
|
168
|
+
this.appEmitter.emit("roomMembersChange", members);
|
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";
|
153
185
|
}
|
154
|
-
}
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
+
};
|
162
203
|
} else {
|
163
|
-
|
164
|
-
|
165
|
-
|
204
|
+
return {
|
205
|
+
width: width * 0.65,
|
206
|
+
height: height * 0.65,
|
207
|
+
};
|
166
208
|
}
|
167
|
-
}
|
209
|
+
}
|
168
210
|
}
|
169
211
|
|
170
212
|
public createAppDir() {
|
@@ -194,7 +236,7 @@ export class AppProxy implements PageRemoveService {
|
|
194
236
|
}
|
195
237
|
|
196
238
|
public get view(): View | undefined {
|
197
|
-
return this.
|
239
|
+
return this.view$.value;
|
198
240
|
}
|
199
241
|
|
200
242
|
public get viewIndex(): number | undefined {
|
@@ -270,13 +312,13 @@ export class AppProxy implements PageRemoveService {
|
|
270
312
|
) {
|
271
313
|
log("setupApp", appId, app, options);
|
272
314
|
if (!this.boxManager) {
|
273
|
-
throw new
|
315
|
+
throw new BoxManagerNotInitializeError();
|
274
316
|
}
|
275
|
-
const context = new AppContext(this.manager,
|
317
|
+
const context = new AppContext(this.manager, appId, this, appOptions);
|
276
318
|
this.appContext = context;
|
277
319
|
try {
|
278
320
|
emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
|
279
|
-
let boxInitState:
|
321
|
+
let boxInitState: AppState | undefined;
|
280
322
|
if (!skipUpdate) {
|
281
323
|
boxInitState = this.getAppInitState(appId);
|
282
324
|
this.boxManager?.updateBoxState(boxInitState);
|
@@ -286,10 +328,19 @@ export class AppProxy implements PageRemoveService {
|
|
286
328
|
this.setViewFocusScenePath();
|
287
329
|
setTimeout(async () => {
|
288
330
|
// 延迟执行 setup, 防止初始化的属性没有更新成功
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
331
|
+
try {
|
332
|
+
const result = await app.setup(context);
|
333
|
+
this.appResult = result;
|
334
|
+
appRegister.notifyApp(this.kind, "created", { appId, result });
|
335
|
+
this.fixMobileSize();
|
336
|
+
if (this.isAddApp) {
|
337
|
+
this.setupDone();
|
338
|
+
}
|
339
|
+
} catch (error) {
|
340
|
+
console.error(error);
|
341
|
+
this.setupFailed();
|
342
|
+
this.destroy(false, true, true);
|
343
|
+
}
|
293
344
|
}, SETUP_APP_DELAY);
|
294
345
|
});
|
295
346
|
const box = this.boxManager?.createBox({
|
@@ -298,11 +349,18 @@ export class AppProxy implements PageRemoveService {
|
|
298
349
|
options,
|
299
350
|
canOperate: this.manager.canOperate,
|
300
351
|
smartPosition: this.isAddApp,
|
301
|
-
});
|
352
|
+
}) as TeleBox;
|
353
|
+
const registerParams = appRegister.registered.get(this.kind);
|
354
|
+
if (registerParams?.contentStyles) {
|
355
|
+
box?.mountUserStyles(registerParams.contentStyles);
|
356
|
+
}
|
302
357
|
this.box$.setValue(box);
|
303
358
|
if (this.isAddApp && this.box) {
|
304
359
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
305
|
-
this.
|
360
|
+
this.store.updateAppState(appId, AppAttributes.Size, {
|
361
|
+
width: this.box.intrinsicWidth,
|
362
|
+
height: this.box.intrinsicHeight,
|
363
|
+
});
|
306
364
|
}
|
307
365
|
} catch (error: any) {
|
308
366
|
console.error(error);
|
@@ -314,12 +372,14 @@ export class AppProxy implements PageRemoveService {
|
|
314
372
|
private fixMobileSize() {
|
315
373
|
const box = this.boxManager?.getBox(this.id);
|
316
374
|
if (box) {
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
375
|
+
if (!box.minimized) {
|
376
|
+
this.boxManager?.resizeBox({
|
377
|
+
appId: this.id,
|
378
|
+
width: box.intrinsicWidth + 0.001,
|
379
|
+
height: box.intrinsicHeight + 0.001,
|
380
|
+
skipUpdate: true,
|
381
|
+
});
|
382
|
+
}
|
323
383
|
}
|
324
384
|
}
|
325
385
|
|
@@ -364,30 +424,18 @@ export class AppProxy implements PageRemoveService {
|
|
364
424
|
}
|
365
425
|
}
|
366
426
|
|
367
|
-
public getAppInitState = (id: string) => {
|
427
|
+
public getAppInitState = (id: string): AppState | undefined => {
|
368
428
|
const attrs = this.store.getAppState(id);
|
369
429
|
if (!attrs) return;
|
370
|
-
const position = attrs?.[AppAttributes.Position];
|
371
430
|
const focus = this.store.focus;
|
372
|
-
const size = attrs?.[AppAttributes.Size];
|
373
|
-
const sceneIndex = attrs?.[AppAttributes.SceneIndex];
|
374
431
|
const maximized = this.attributes?.["maximized"];
|
375
432
|
const minimized = this.attributes?.["minimized"];
|
376
|
-
|
377
|
-
|
378
|
-
if (position) {
|
379
|
-
payload = { ...payload, id: id, x: position.x, y: position.y };
|
380
|
-
}
|
433
|
+
let payload = { maximized, minimized, id } as AppState;
|
434
|
+
const state = omitBy(attrs, isUndefined);
|
381
435
|
if (focus === id) {
|
382
436
|
payload = { ...payload, focus: true };
|
383
437
|
}
|
384
|
-
|
385
|
-
payload = { ...payload, width: size.width, height: size.height };
|
386
|
-
}
|
387
|
-
if (sceneIndex) {
|
388
|
-
payload = { ...payload, sceneIndex };
|
389
|
-
}
|
390
|
-
return payload;
|
438
|
+
return Object.assign(payload, state);;
|
391
439
|
};
|
392
440
|
|
393
441
|
public emitAppSceneStateChange(sceneState: SceneState) {
|
@@ -444,32 +492,34 @@ export class AppProxy implements PageRemoveService {
|
|
444
492
|
}
|
445
493
|
|
446
494
|
private appAttributesUpdateListener = (appId: string) => {
|
447
|
-
this.
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
this.
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
495
|
+
this.sideEffectManager.add(() => [
|
496
|
+
this.manager.refresher.add(appId, () => {
|
497
|
+
return autorun(() => {
|
498
|
+
const attrs = this.manager.attributes[appId];
|
499
|
+
if (attrs) {
|
500
|
+
this.appEmitter.emit("attributesUpdate", attrs);
|
501
|
+
}
|
502
|
+
});
|
503
|
+
}),
|
504
|
+
this.manager.refresher.add(this.stateKey, () => {
|
505
|
+
return autorun(() => {
|
506
|
+
const appState = this.appAttributes?.state;
|
507
|
+
if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
|
508
|
+
this.boxManager?.setZIndex(appId, appState.zIndex);
|
509
|
+
}
|
510
|
+
});
|
511
|
+
}),
|
512
|
+
this.manager.refresher.add(`${appId}-fullPath`, () => {
|
513
|
+
return autorun(() => {
|
514
|
+
const fullPath = this.appAttributes?.fullPath;
|
515
|
+
this.setFocusScenePathHandler(fullPath);
|
516
|
+
if (this.fullPath$.value !== fullPath) {
|
517
|
+
this.notifyPageStateChange();
|
518
|
+
this.fullPath$.setValue(fullPath);
|
519
|
+
}
|
520
|
+
});
|
521
|
+
}),
|
522
|
+
]);
|
473
523
|
};
|
474
524
|
|
475
525
|
private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
|
@@ -487,6 +537,7 @@ export class AppProxy implements PageRemoveService {
|
|
487
537
|
}
|
488
538
|
|
489
539
|
public setViewFocusScenePath() {
|
540
|
+
if (this.status === "destroyed") return;
|
490
541
|
const fullPath = this.getFullScenePath();
|
491
542
|
if (fullPath && this.view) {
|
492
543
|
setViewFocusScenePath(this.view, fullPath);
|
@@ -546,6 +597,7 @@ export class AppProxy implements PageRemoveService {
|
|
546
597
|
const fullPath = this._pageState.getFullPath(index);
|
547
598
|
if (fullPath) {
|
548
599
|
this.setFullPath(fullPath);
|
600
|
+
setScenePath(this.manager.room, fullPath);
|
549
601
|
}
|
550
602
|
}
|
551
603
|
}
|
@@ -558,12 +610,22 @@ export class AppProxy implements PageRemoveService {
|
|
558
610
|
this.store.updateAppAttributes(this.id, Fields.Size, size);
|
559
611
|
};
|
560
612
|
|
561
|
-
public
|
613
|
+
public updateSize = (width: number, height: number) => {
|
614
|
+
const iSize = {
|
615
|
+
id: this.manager.uid,
|
616
|
+
width, height
|
617
|
+
}
|
618
|
+
this.store.updateAppAttributes(this.id, Fields.Size, iSize);
|
619
|
+
this.size$.setValue(iSize);
|
620
|
+
}
|
621
|
+
|
622
|
+
public moveCamera = (camera: Partial<ICamera>) => {
|
562
623
|
if (!this.camera$.value) {
|
563
624
|
return;
|
564
625
|
}
|
565
|
-
const nextCamera = { ...this.camera$.value, ...camera };
|
626
|
+
const nextCamera = { ...this.camera$.value, ...camera, id: this.uid };
|
566
627
|
this.storeCamera(nextCamera);
|
628
|
+
this.camera$.setValue(nextCamera);
|
567
629
|
};
|
568
630
|
|
569
631
|
public async destroy(
|
@@ -576,6 +638,7 @@ export class AppProxy implements PageRemoveService {
|
|
576
638
|
this.status = "destroyed";
|
577
639
|
try {
|
578
640
|
await appRegister.notifyApp(this.kind, "destroy", { appId: this.id });
|
641
|
+
callbacks.emit("appClose", { appId: this.id, kind: this.kind, error });
|
579
642
|
await this.appEmitter.emit("destroy", { error });
|
580
643
|
} catch (error) {
|
581
644
|
console.error("[WindowManager]: notifyApp error", error.message, error.stack);
|
@@ -596,13 +659,60 @@ export class AppProxy implements PageRemoveService {
|
|
596
659
|
|
597
660
|
this.viewManager.destroyView(this.id);
|
598
661
|
this.manager.appStatus.delete(this.id);
|
599
|
-
this.
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
this.
|
604
|
-
|
605
|
-
|
662
|
+
this.valManager.destroy();
|
663
|
+
}
|
664
|
+
|
665
|
+
private addCameraReaction = () => {
|
666
|
+
this.sideEffectManager.add(() =>
|
667
|
+
this.manager.refresher.add(`${this.id}-camera`, () =>
|
668
|
+
reaction(
|
669
|
+
() => this.appAttributes?.camera,
|
670
|
+
camera => {
|
671
|
+
if (camera) {
|
672
|
+
const rawCamera = toJS(camera);
|
673
|
+
if (!isEqual(rawCamera, this.camera$.value)) {
|
674
|
+
this.camera$.setValue(rawCamera);
|
675
|
+
}
|
676
|
+
}
|
677
|
+
}
|
678
|
+
)
|
679
|
+
)
|
680
|
+
, "camera");
|
681
|
+
}
|
682
|
+
|
683
|
+
private addSizeReaction = () => {
|
684
|
+
this.sideEffectManager.add(() =>
|
685
|
+
this.manager.refresher.add(`${this.id}-size`, () =>
|
686
|
+
reaction(
|
687
|
+
() => this.appAttributes?.size,
|
688
|
+
size => {
|
689
|
+
if (size) {
|
690
|
+
const rawSize = toJS(size);
|
691
|
+
if (!isEqual(rawSize, this.size$.value)) {
|
692
|
+
this.size$.setValue(rawSize);
|
693
|
+
}
|
694
|
+
}
|
695
|
+
}
|
696
|
+
)
|
697
|
+
)
|
698
|
+
, "size");
|
699
|
+
}
|
700
|
+
|
701
|
+
public onFocus = () => {
|
702
|
+
this.setScenePath();
|
703
|
+
}
|
704
|
+
|
705
|
+
// 异步值设置完成通知其他端创建 app
|
706
|
+
private setupDone = () => {
|
707
|
+
this.store.updateAppAttributes(this.id, "setup", true);
|
708
|
+
this.manager.dispatchInternalEvent(Events.InvokeAttributesUpdateCallback);
|
709
|
+
if (this.boxManager && this.box) {
|
710
|
+
this.boxManager.focusBox({ appId: this.id }, false);
|
711
|
+
}
|
712
|
+
}
|
713
|
+
|
714
|
+
private setupFailed = () => {
|
715
|
+
this.store.cleanAppAttributes(this.id);
|
606
716
|
}
|
607
717
|
|
608
718
|
public close(): Promise<void> {
|
@@ -1,36 +1,58 @@
|
|
1
1
|
import { putScenes } from "../Utils/Common";
|
2
2
|
import { Val } from "value-enhancer";
|
3
|
+
import { pick } from "lodash";
|
3
4
|
|
4
5
|
import type { ReadonlyVal } from "value-enhancer";
|
5
6
|
import type { AddPageParams, PageController, PageState } from "../Page";
|
6
7
|
import type { AppProxy } from "./AppProxy";
|
7
8
|
import type { AppContext } from "./AppContext";
|
8
|
-
import type { Camera } from "white-web-sdk";
|
9
|
+
import type { Camera, View } from "white-web-sdk";
|
10
|
+
import type { TeleBoxRect } from "@netless/telebox-insider";
|
11
|
+
import type { ICamera, ISize } from "../AttributesDelegate";
|
12
|
+
|
13
|
+
export type WhiteBoardViewCamera = Omit<ICamera, "id">;
|
14
|
+
export type WhiteBoardViewRect = Omit<ISize, "id">;
|
9
15
|
|
10
16
|
export class WhiteBoardView implements PageController {
|
11
17
|
public readonly pageState$: ReadonlyVal<PageState>;
|
18
|
+
public readonly baseCamera$: ReadonlyVal<WhiteBoardViewCamera>;
|
19
|
+
public readonly baseRect$: ReadonlyVal<WhiteBoardViewRect | undefined>;
|
12
20
|
|
13
21
|
constructor(
|
22
|
+
public view: View,
|
14
23
|
protected appContext: AppContext,
|
15
24
|
protected appProxy: AppProxy,
|
16
|
-
|
25
|
+
public ensureSize: (size: number) => void
|
17
26
|
) {
|
18
27
|
const pageState$ = new Val<PageState>(appProxy.pageState);
|
28
|
+
const baseRect$ = new Val<WhiteBoardViewRect | undefined>(appProxy.size$.value);
|
29
|
+
const pickCamera = (camera: Camera | ICamera) =>
|
30
|
+
pick(camera, ["centerX", "centerY", "scale"]);
|
31
|
+
const camera$ = new Val<WhiteBoardViewCamera>(pickCamera(this.view.camera));
|
32
|
+
this.baseRect$ = baseRect$;
|
19
33
|
this.pageState$ = pageState$;
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
34
|
+
this.baseCamera$ = camera$;
|
35
|
+
this.appProxy.sideEffectManager.add(() => [
|
36
|
+
appProxy.appEmitter.on("pageStateChange", pageState => pageState$.setValue(pageState)),
|
37
|
+
appProxy.camera$.subscribe(camera => {
|
38
|
+
if (camera) {
|
39
|
+
camera$.setValue(pickCamera(camera));
|
40
|
+
}
|
41
|
+
}),
|
42
|
+
appProxy.size$.subscribe(size => {
|
43
|
+
if (size) {
|
44
|
+
baseRect$.setValue(pick(size, ["width", "height"]));
|
45
|
+
}
|
46
|
+
}),
|
47
|
+
]);
|
48
|
+
view.disableCameraTransform = true;
|
27
49
|
}
|
28
50
|
|
29
51
|
public get pageState() {
|
30
52
|
return this.pageState$.value;
|
31
53
|
}
|
32
54
|
|
33
|
-
public moveCamera(camera:
|
55
|
+
public moveCamera(camera: Partial<WhiteBoardViewCamera>) {
|
34
56
|
this.appProxy.moveCamera(camera);
|
35
57
|
}
|
36
58
|
|
@@ -58,11 +80,13 @@ export class WhiteBoardView implements PageController {
|
|
58
80
|
const scene = params?.scene;
|
59
81
|
const scenePath = this.appProxy.scenePath;
|
60
82
|
if (!scenePath) return;
|
83
|
+
const scenes = Array.isArray(scene) ? scene : [scene || {}];
|
61
84
|
if (after) {
|
62
85
|
const nextIndex = this.pageState.index + 1;
|
63
|
-
|
86
|
+
|
87
|
+
putScenes(this.appContext.room, scenePath, scenes, nextIndex);
|
64
88
|
} else {
|
65
|
-
putScenes(this.appContext.room, scenePath,
|
89
|
+
putScenes(this.appContext.room, scenePath, scenes);
|
66
90
|
}
|
67
91
|
};
|
68
92
|
|
@@ -79,7 +103,7 @@ export class WhiteBoardView implements PageController {
|
|
79
103
|
return this.appProxy.removeSceneByIndex(needRemoveIndex);
|
80
104
|
};
|
81
105
|
|
82
|
-
public
|
83
|
-
this.
|
106
|
+
public setBaseRect(rect: Omit<TeleBoxRect, "x" | "y">) {
|
107
|
+
this.appProxy.updateSize(rect.width, rect.height);
|
84
108
|
}
|
85
109
|
}
|
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
|
+
}
|