@netless/window-manager 1.0.0-canary.7 → 1.0.0-canary.71
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 +13625 -0
- package/dist/index.mjs +13622 -0
- package/dist/index.umd.js +13620 -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} +12 -7
- 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 +3 -1
- package/dist/{Page → src/Page}/index.d.ts +0 -0
- package/dist/{PageState.d.ts → src/PageState.d.ts} +1 -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 +4 -1
- package/dist/{Utils → src/Utils}/log.d.ts +0 -0
- package/dist/src/View/CameraSynchronizer.d.ts +21 -0
- package/dist/{View → src/View}/MainView.d.ts +25 -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} +12 -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} +63 -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} +21 -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/src/App/AppContext.ts +81 -46
- package/src/App/AppPageStateImpl.ts +3 -0
- package/src/App/AppProxy.ts +249 -141
- package/src/App/WhiteboardView.ts +37 -14
- package/src/App/index.ts +1 -0
- package/src/App/type.ts +22 -0
- package/src/AppListener.ts +27 -21
- package/src/AppManager.ts +96 -50
- 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 +15 -4
- package/src/Cursor/icons.ts +6 -0
- package/src/Cursor/index.ts +16 -11
- package/src/Helper.ts +25 -7
- package/src/InternalEmitter.ts +1 -4
- package/src/Page/PageController.ts +3 -1
- package/src/PageState.ts +8 -1
- package/src/ReconnectRefresher.ts +7 -3
- 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 +6 -2
- package/src/View/CameraSynchronizer.ts +55 -36
- package/src/View/MainView.ts +163 -77
- package/src/View/ScrollMode.ts +240 -0
- package/src/View/ViewSync.ts +138 -6
- package/src/callback.ts +8 -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 +197 -60
- package/src/storage.ts +15 -0
- package/src/style.css +18 -47
- package/src/typings.ts +24 -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 -16161
- package/pnpm-lock.yaml +0 -6302
- 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,70 +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
|
-
this.camera$.setValue(toJS(this.appAttributes.camera));
|
144
125
|
}
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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
|
+
})
|
152
165
|
}
|
153
|
-
|
154
|
-
|
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";
|
155
185
|
}
|
156
|
-
}
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
+
};
|
164
203
|
} else {
|
165
|
-
|
166
|
-
|
167
|
-
|
204
|
+
return {
|
205
|
+
width: width * 0.65,
|
206
|
+
height: height * 0.65,
|
207
|
+
};
|
168
208
|
}
|
169
|
-
}
|
209
|
+
}
|
170
210
|
}
|
171
211
|
|
172
212
|
public createAppDir() {
|
@@ -196,7 +236,7 @@ export class AppProxy implements PageRemoveService {
|
|
196
236
|
}
|
197
237
|
|
198
238
|
public get view(): View | undefined {
|
199
|
-
return this.
|
239
|
+
return this.view$.value;
|
200
240
|
}
|
201
241
|
|
202
242
|
public get viewIndex(): number | undefined {
|
@@ -272,13 +312,13 @@ export class AppProxy implements PageRemoveService {
|
|
272
312
|
) {
|
273
313
|
log("setupApp", appId, app, options);
|
274
314
|
if (!this.boxManager) {
|
275
|
-
throw new
|
315
|
+
throw new BoxManagerNotInitializeError();
|
276
316
|
}
|
277
|
-
const context = new AppContext(this.manager,
|
317
|
+
const context = new AppContext(this.manager, appId, this, appOptions);
|
278
318
|
this.appContext = context;
|
279
319
|
try {
|
280
320
|
emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
|
281
|
-
let boxInitState:
|
321
|
+
let boxInitState: AppState | undefined;
|
282
322
|
if (!skipUpdate) {
|
283
323
|
boxInitState = this.getAppInitState(appId);
|
284
324
|
this.boxManager?.updateBoxState(boxInitState);
|
@@ -288,10 +328,19 @@ export class AppProxy implements PageRemoveService {
|
|
288
328
|
this.setViewFocusScenePath();
|
289
329
|
setTimeout(async () => {
|
290
330
|
// 延迟执行 setup, 防止初始化的属性没有更新成功
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
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
|
+
}
|
295
344
|
}, SETUP_APP_DELAY);
|
296
345
|
});
|
297
346
|
const box = this.boxManager?.createBox({
|
@@ -300,11 +349,18 @@ export class AppProxy implements PageRemoveService {
|
|
300
349
|
options,
|
301
350
|
canOperate: this.manager.canOperate,
|
302
351
|
smartPosition: this.isAddApp,
|
303
|
-
});
|
352
|
+
}) as TeleBox;
|
353
|
+
const registerParams = appRegister.registered.get(this.kind);
|
354
|
+
if (registerParams?.contentStyles) {
|
355
|
+
box?.mountUserStyles(registerParams.contentStyles);
|
356
|
+
}
|
304
357
|
this.box$.setValue(box);
|
305
358
|
if (this.isAddApp && this.box) {
|
306
359
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
307
|
-
this.
|
360
|
+
this.store.updateAppState(appId, AppAttributes.Size, {
|
361
|
+
width: this.box.intrinsicWidth,
|
362
|
+
height: this.box.intrinsicHeight,
|
363
|
+
});
|
308
364
|
}
|
309
365
|
} catch (error: any) {
|
310
366
|
console.error(error);
|
@@ -316,12 +372,14 @@ export class AppProxy implements PageRemoveService {
|
|
316
372
|
private fixMobileSize() {
|
317
373
|
const box = this.boxManager?.getBox(this.id);
|
318
374
|
if (box) {
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
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
|
+
}
|
325
383
|
}
|
326
384
|
}
|
327
385
|
|
@@ -366,30 +424,18 @@ export class AppProxy implements PageRemoveService {
|
|
366
424
|
}
|
367
425
|
}
|
368
426
|
|
369
|
-
public getAppInitState = (id: string) => {
|
427
|
+
public getAppInitState = (id: string): AppState | undefined => {
|
370
428
|
const attrs = this.store.getAppState(id);
|
371
429
|
if (!attrs) return;
|
372
|
-
const position = attrs?.[AppAttributes.Position];
|
373
430
|
const focus = this.store.focus;
|
374
|
-
const size = attrs?.[AppAttributes.Size];
|
375
|
-
const sceneIndex = attrs?.[AppAttributes.SceneIndex];
|
376
431
|
const maximized = this.attributes?.["maximized"];
|
377
432
|
const minimized = this.attributes?.["minimized"];
|
378
|
-
|
379
|
-
|
380
|
-
if (position) {
|
381
|
-
payload = { ...payload, id: id, x: position.x, y: position.y };
|
382
|
-
}
|
433
|
+
let payload = { maximized, minimized, id } as AppState;
|
434
|
+
const state = omitBy(attrs, isUndefined);
|
383
435
|
if (focus === id) {
|
384
436
|
payload = { ...payload, focus: true };
|
385
437
|
}
|
386
|
-
|
387
|
-
payload = { ...payload, width: size.width, height: size.height };
|
388
|
-
}
|
389
|
-
if (sceneIndex) {
|
390
|
-
payload = { ...payload, sceneIndex };
|
391
|
-
}
|
392
|
-
return payload;
|
438
|
+
return Object.assign(payload, state);;
|
393
439
|
};
|
394
440
|
|
395
441
|
public emitAppSceneStateChange(sceneState: SceneState) {
|
@@ -446,32 +492,34 @@ export class AppProxy implements PageRemoveService {
|
|
446
492
|
}
|
447
493
|
|
448
494
|
private appAttributesUpdateListener = (appId: string) => {
|
449
|
-
this.
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
this.
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
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
|
+
]);
|
475
523
|
};
|
476
524
|
|
477
525
|
private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {
|
@@ -489,6 +537,7 @@ export class AppProxy implements PageRemoveService {
|
|
489
537
|
}
|
490
538
|
|
491
539
|
public setViewFocusScenePath() {
|
540
|
+
if (this.status === "destroyed") return;
|
492
541
|
const fullPath = this.getFullScenePath();
|
493
542
|
if (fullPath && this.view) {
|
494
543
|
setViewFocusScenePath(this.view, fullPath);
|
@@ -548,6 +597,7 @@ export class AppProxy implements PageRemoveService {
|
|
548
597
|
const fullPath = this._pageState.getFullPath(index);
|
549
598
|
if (fullPath) {
|
550
599
|
this.setFullPath(fullPath);
|
600
|
+
setScenePath(this.manager.room, fullPath);
|
551
601
|
}
|
552
602
|
}
|
553
603
|
}
|
@@ -560,12 +610,22 @@ export class AppProxy implements PageRemoveService {
|
|
560
610
|
this.store.updateAppAttributes(this.id, Fields.Size, size);
|
561
611
|
};
|
562
612
|
|
563
|
-
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>) => {
|
564
623
|
if (!this.camera$.value) {
|
565
624
|
return;
|
566
625
|
}
|
567
|
-
const nextCamera = { ...this.camera$.value, ...camera };
|
626
|
+
const nextCamera = { ...this.camera$.value, ...camera, id: this.uid };
|
568
627
|
this.storeCamera(nextCamera);
|
628
|
+
this.camera$.setValue(nextCamera);
|
569
629
|
};
|
570
630
|
|
571
631
|
public async destroy(
|
@@ -578,6 +638,7 @@ export class AppProxy implements PageRemoveService {
|
|
578
638
|
this.status = "destroyed";
|
579
639
|
try {
|
580
640
|
await appRegister.notifyApp(this.kind, "destroy", { appId: this.id });
|
641
|
+
callbacks.emit("appClose", { appId: this.id, kind: this.kind, error });
|
581
642
|
await this.appEmitter.emit("destroy", { error });
|
582
643
|
} catch (error) {
|
583
644
|
console.error("[WindowManager]: notifyApp error", error.message, error.stack);
|
@@ -598,13 +659,60 @@ export class AppProxy implements PageRemoveService {
|
|
598
659
|
|
599
660
|
this.viewManager.destroyView(this.id);
|
600
661
|
this.manager.appStatus.delete(this.id);
|
601
|
-
this.
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
this.
|
606
|
-
|
607
|
-
|
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);
|
608
716
|
}
|
609
717
|
|
610
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 camera$: 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.camera$ = 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,12 @@ 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
|
-
putScenes(this.appContext.room, scenePath,
|
86
|
+
putScenes(this.appContext.room, scenePath, scenes, nextIndex);
|
64
87
|
} else {
|
65
|
-
putScenes(this.appContext.room, scenePath,
|
88
|
+
putScenes(this.appContext.room, scenePath, scenes);
|
66
89
|
}
|
67
90
|
};
|
68
91
|
|
@@ -79,7 +102,7 @@ export class WhiteBoardView implements PageController {
|
|
79
102
|
return this.appProxy.removeSceneByIndex(needRemoveIndex);
|
80
103
|
};
|
81
104
|
|
82
|
-
public
|
83
|
-
this.
|
105
|
+
public setBaseRect(rect: Omit<TeleBoxRect, "x" | "y">) {
|
106
|
+
this.appProxy.updateSize(rect.width, rect.height);
|
84
107
|
}
|
85
108
|
}
|
package/src/App/index.ts
CHANGED