@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/BoxManager.ts
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
|
2
2
|
import { debounce } from "lodash";
|
3
|
+
import { SideEffectManager } from "side-effect-manager";
|
3
4
|
import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
|
4
5
|
import { WindowManager } from "./index";
|
6
|
+
import type { Writeable } from "./typings";
|
5
7
|
import type { BoxEmitterType } from "./BoxEmitter";
|
6
|
-
import type { AddAppOptions
|
8
|
+
import type { AddAppOptions } from "./index";
|
7
9
|
import type {
|
8
10
|
TeleBoxManagerUpdateConfig,
|
9
11
|
TeleBoxManagerCreateConfig,
|
@@ -18,7 +20,7 @@ import type { NetlessApp } from "./typings";
|
|
18
20
|
import type { View } from "white-web-sdk";
|
19
21
|
import type { CallbacksType } from "./callback";
|
20
22
|
import type { EmitterType } from "./InternalEmitter";
|
21
|
-
import {
|
23
|
+
import type { AppState } from "./App/type";
|
22
24
|
|
23
25
|
export { TELE_BOX_STATE };
|
24
26
|
|
@@ -47,11 +49,12 @@ export type CreateTeleBoxManagerConfig = {
|
|
47
49
|
collectorStyles?: Partial<CSSStyleDeclaration>;
|
48
50
|
prefersColorScheme?: TeleBoxColorScheme;
|
49
51
|
stageRatio?: number;
|
52
|
+
containerStyle?: string;
|
53
|
+
stageStyle?: string;
|
50
54
|
};
|
51
55
|
|
52
56
|
export type BoxManagerContext = {
|
53
57
|
safeSetAttributes: (attributes: any) => void;
|
54
|
-
getMainView: () => View;
|
55
58
|
updateAppState: (appId: string, field: AppAttributes, value: any) => void;
|
56
59
|
emitter: EmitterType;
|
57
60
|
boxEmitter: BoxEmitterType;
|
@@ -72,7 +75,6 @@ export const createBoxManager = (
|
|
72
75
|
return new BoxManager(
|
73
76
|
{
|
74
77
|
safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
|
75
|
-
getMainView: () => manager.mainView,
|
76
78
|
updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
|
77
79
|
canOperate: () => manager.canOperate,
|
78
80
|
notifyContainerRectUpdate: (rect: TeleBoxRect) =>
|
@@ -81,7 +83,7 @@ export const createBoxManager = (
|
|
81
83
|
setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
|
82
84
|
callbacks,
|
83
85
|
emitter,
|
84
|
-
boxEmitter
|
86
|
+
boxEmitter,
|
85
87
|
},
|
86
88
|
options
|
87
89
|
);
|
@@ -100,17 +102,17 @@ export class BoxManager {
|
|
100
102
|
this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
|
101
103
|
this.sideEffectManager.add(() => [
|
102
104
|
// 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
|
103
|
-
this.teleBoxManager.
|
105
|
+
this.teleBoxManager.onValChanged("state", state => {
|
104
106
|
callbacks.emit("boxStateChange", state);
|
105
107
|
emitter.emit("boxStateChange", state);
|
106
108
|
}),
|
107
|
-
this.teleBoxManager.
|
109
|
+
this.teleBoxManager.onValChanged("darkMode", darkMode => {
|
108
110
|
callbacks.emit("darkModeChange", darkMode);
|
109
111
|
}),
|
110
|
-
this.teleBoxManager.
|
112
|
+
this.teleBoxManager.onValChanged("prefersColorScheme", colorScheme => {
|
111
113
|
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
112
114
|
}),
|
113
|
-
this.teleBoxManager.
|
115
|
+
this.teleBoxManager.onValChanged("minimized", (minimized, skipUpdate) => {
|
114
116
|
if (skipUpdate) {
|
115
117
|
return;
|
116
118
|
}
|
@@ -126,7 +128,7 @@ export class BoxManager {
|
|
126
128
|
}
|
127
129
|
}
|
128
130
|
}),
|
129
|
-
this.teleBoxManager.
|
131
|
+
this.teleBoxManager.onValChanged("maximized", (maximized, skipUpdate) => {
|
130
132
|
if (skipUpdate) {
|
131
133
|
return;
|
132
134
|
}
|
@@ -140,7 +142,11 @@ export class BoxManager {
|
|
140
142
|
this.teleBoxManager.events.on(
|
141
143
|
"intrinsic_move",
|
142
144
|
debounce((box: ReadonlyTeleBox): void => {
|
143
|
-
boxEmitter.emit("move", {
|
145
|
+
boxEmitter.emit("move", {
|
146
|
+
appId: box.id,
|
147
|
+
x: box.intrinsicX,
|
148
|
+
y: box.intrinsicY,
|
149
|
+
});
|
144
150
|
}, 50)
|
145
151
|
),
|
146
152
|
this.teleBoxManager.events.on(
|
@@ -165,23 +171,12 @@ export class BoxManager {
|
|
165
171
|
this.teleBoxManager.events.on("z_index", box => {
|
166
172
|
this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
|
167
173
|
}),
|
168
|
-
this.teleBoxManager._stageRect$.subscribe(stage => {
|
169
|
-
emitter.emit("playgroundSizeChange", stage);
|
170
|
-
this.context.notifyContainerRectUpdate(stage);
|
171
|
-
}),
|
172
|
-
emitter.on("writableChange", isWritable => {
|
173
|
-
this.teleBoxManager.setHighlightStage(isWritable);
|
174
|
-
}),
|
175
174
|
emitter.on("containerSizeRatioUpdate", ratio => {
|
176
175
|
this.teleBoxManager._stageRatio$.setValue(ratio);
|
177
176
|
}),
|
178
177
|
]);
|
179
178
|
}
|
180
179
|
|
181
|
-
private get mainView() {
|
182
|
-
return this.context.getMainView();
|
183
|
-
}
|
184
|
-
|
185
180
|
private get canOperate() {
|
186
181
|
return this.context.canOperate();
|
187
182
|
}
|
@@ -214,9 +209,14 @@ export class BoxManager {
|
|
214
209
|
return this.teleBoxManager.stageRect;
|
215
210
|
}
|
216
211
|
|
217
|
-
public
|
212
|
+
public get stageRect$() {
|
213
|
+
return this.teleBoxManager._stageRect$;
|
214
|
+
}
|
215
|
+
|
216
|
+
public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
|
218
217
|
if (!this.teleBoxManager) return;
|
219
|
-
|
218
|
+
// eslint-disable-next-line prefer-const
|
219
|
+
let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT, enableShadowDOM = true } = params.app.config ?? {};
|
220
220
|
const { width, height } = params.app.config ?? {};
|
221
221
|
const title = params.options?.title || params.appId;
|
222
222
|
const rect = this.teleBoxManager.rootRect;
|
@@ -236,22 +236,32 @@ export class BoxManager {
|
|
236
236
|
width,
|
237
237
|
height,
|
238
238
|
id: params.appId,
|
239
|
+
enableShadowDOM,
|
239
240
|
};
|
240
|
-
this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
241
|
+
const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
241
242
|
this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
|
243
|
+
return box;
|
242
244
|
}
|
243
245
|
|
244
246
|
public setupBoxManager(
|
245
247
|
createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
|
246
248
|
): TeleBoxManager {
|
247
249
|
const root = WindowManager.playground;
|
248
|
-
const initManagerState: TeleBoxManagerConfig = {
|
250
|
+
const initManagerState: Writeable<TeleBoxManagerConfig> = {
|
249
251
|
stageRatio: createTeleBoxManagerConfig?.stageRatio,
|
250
252
|
root: root,
|
251
253
|
fence: false,
|
252
254
|
prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
|
253
255
|
};
|
254
256
|
|
257
|
+
if (createTeleBoxManagerConfig?.containerStyle) {
|
258
|
+
initManagerState.containerStyle = createTeleBoxManagerConfig.containerStyle;
|
259
|
+
}
|
260
|
+
|
261
|
+
if (createTeleBoxManagerConfig?.stageStyle) {
|
262
|
+
initManagerState.stageStyle = createTeleBoxManagerConfig.stageStyle;
|
263
|
+
}
|
264
|
+
|
255
265
|
const manager = new TeleBoxManager(initManagerState);
|
256
266
|
if (this.teleBoxManager) {
|
257
267
|
this.teleBoxManager.destroy();
|
@@ -289,21 +299,19 @@ export class BoxManager {
|
|
289
299
|
return this.teleBoxManager.topBox;
|
290
300
|
}
|
291
301
|
|
292
|
-
public updateBoxState(state?:
|
302
|
+
public updateBoxState(state?: AppState): void {
|
293
303
|
if (!state) return;
|
294
304
|
const box = this.getBox(state.id);
|
295
305
|
if (box) {
|
296
|
-
|
297
|
-
box.
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
true
|
306
|
-
);
|
306
|
+
if (state.size) {
|
307
|
+
box._intrinsicSize$.setValue(state.size, true);
|
308
|
+
}
|
309
|
+
if (state.position) {
|
310
|
+
box._intrinsicCoord$.setValue(state.position, true);
|
311
|
+
}
|
312
|
+
if (state.zIndex) {
|
313
|
+
box._zIndex$.setValue(state.zIndex, true);
|
314
|
+
}
|
307
315
|
setTimeout(() => {
|
308
316
|
if (state.focus) {
|
309
317
|
this.teleBoxManager.focusBox(box.id, true);
|
@@ -320,7 +328,10 @@ export class BoxManager {
|
|
320
328
|
}
|
321
329
|
|
322
330
|
public moveBox({ appId, x, y }: MoveBoxParams): void {
|
323
|
-
this.
|
331
|
+
const box = this.getBox(appId);
|
332
|
+
if (box) {
|
333
|
+
box._intrinsicCoord$.setValue({ x, y}, true);
|
334
|
+
}
|
324
335
|
}
|
325
336
|
|
326
337
|
public focusBox({ appId }: AppId, skipUpdate = true): void {
|
@@ -328,7 +339,10 @@ export class BoxManager {
|
|
328
339
|
}
|
329
340
|
|
330
341
|
public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {
|
331
|
-
this.
|
342
|
+
const box = this.getBox(appId);
|
343
|
+
if (box) {
|
344
|
+
box._intrinsicSize$.setValue({ width, height }, skipUpdate);
|
345
|
+
}
|
332
346
|
}
|
333
347
|
|
334
348
|
public setBoxMinSize(params: SetBoxMinSizeParams): void {
|
package/src/BuiltinApps.ts
CHANGED
package/src/Cursor/Cursor.ts
CHANGED
@@ -7,6 +7,7 @@ import type { RoomMember } from "white-web-sdk";
|
|
7
7
|
import type { CursorManager } from "./index";
|
8
8
|
import type { SvelteComponent } from "svelte";
|
9
9
|
import type { AppManager } from "../AppManager";
|
10
|
+
import type { TeleBoxRect } from "@netless/telebox-insider";
|
10
11
|
|
11
12
|
export type Payload = {
|
12
13
|
[key: string]: any;
|
@@ -50,18 +51,21 @@ export class Cursor {
|
|
50
51
|
this.hide();
|
51
52
|
};
|
52
53
|
|
53
|
-
private moveCursor(cursor: Position, rect:
|
54
|
+
private moveCursor(cursor: Position, rect: TeleBoxRect, view: any) {
|
54
55
|
const { x, y, type } = cursor;
|
55
56
|
const point = view?.screen.convertPointToScreen(x, y);
|
56
57
|
if (point) {
|
57
58
|
let translateX = point.x - 2;
|
58
59
|
let translateY = point.y - 18;
|
59
60
|
if (type === "app") {
|
60
|
-
const wrapperRect = this.cursorManager.
|
61
|
+
const wrapperRect = this.cursorManager.playgroundRect;
|
61
62
|
if (wrapperRect) {
|
62
63
|
translateX = translateX + rect.x - wrapperRect.x;
|
63
64
|
translateY = translateY + rect.y - wrapperRect.y;
|
64
65
|
}
|
66
|
+
} else {
|
67
|
+
translateX = translateX + rect.x;
|
68
|
+
translateY = translateY + rect.y;
|
65
69
|
}
|
66
70
|
if (point.x < 0 || point.x > rect.width || point.y < 0 || point.y > rect.height) {
|
67
71
|
this.component?.$set({ visible: false, x: translateX, y: translateY });
|
package/src/Cursor/index.ts
CHANGED
@@ -5,7 +5,7 @@ import { emitter } from "../InternalEmitter";
|
|
5
5
|
import { SideEffectManager } from "side-effect-manager";
|
6
6
|
import { throttle } from "lodash";
|
7
7
|
import { WindowManager } from "../index";
|
8
|
-
import type { CursorMovePayload , ApplianceIcons} from "../index";
|
8
|
+
import type { CursorMovePayload , ApplianceIcons, TeleBoxRect } from "../index";
|
9
9
|
import type { PositionType } from "../AttributesDelegate";
|
10
10
|
import type { Point, RoomMember, View } from "white-web-sdk";
|
11
11
|
import type { AppManager } from "../AppManager";
|
@@ -23,8 +23,8 @@ export type MoveCursorParams = {
|
|
23
23
|
};
|
24
24
|
|
25
25
|
export class CursorManager {
|
26
|
-
public
|
27
|
-
public
|
26
|
+
public wrapperRect?: TeleBoxRect;
|
27
|
+
public playgroundRect?: DOMRect;
|
28
28
|
public cursorInstances: Map<string, Cursor> = new Map();
|
29
29
|
public roomMembers?: readonly RoomMember[];
|
30
30
|
private mainViewElement?: HTMLDivElement;
|
@@ -89,8 +89,6 @@ export class CursorManager {
|
|
89
89
|
wrapper.removeEventListener("pointerleave", this.mouseLeaveListener);
|
90
90
|
};
|
91
91
|
});
|
92
|
-
|
93
|
-
this.wrapperRect = wrapper.getBoundingClientRect();
|
94
92
|
}
|
95
93
|
|
96
94
|
public setMainViewDivElement(div: HTMLDivElement) {
|
@@ -168,8 +166,8 @@ export class CursorManager {
|
|
168
166
|
};
|
169
167
|
|
170
168
|
public updateContainerRect() {
|
171
|
-
this.
|
172
|
-
this.
|
169
|
+
this.wrapperRect = this.manager.boxManager?.teleBoxManager.stageRect;
|
170
|
+
this.playgroundRect = WindowManager.playground?.getBoundingClientRect();
|
173
171
|
}
|
174
172
|
|
175
173
|
public deleteCursor(uid: string) {
|
package/src/Helper.ts
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
import { getVersionNumber } from "./Utils/Common";
|
1
|
+
import { getVersionNumber, wait } from "./Utils/Common";
|
2
|
+
import { log } from "./Utils/log";
|
2
3
|
import { REQUIRE_VERSION } from "./constants";
|
3
|
-
import { WhiteVersion } from "white-web-sdk";
|
4
|
+
import { toJS, WhiteVersion } from "white-web-sdk";
|
4
5
|
import { WhiteWebSDKInvalidError } from "./Utils/error";
|
5
|
-
import
|
6
|
+
import { WindowManager } from "./index";
|
7
|
+
import type { Room, RoomMember } from "white-web-sdk";
|
6
8
|
|
7
9
|
export const setupWrapper = (
|
8
|
-
root: HTMLElement
|
10
|
+
root: HTMLElement,
|
11
|
+
target: HTMLElement
|
9
12
|
): {
|
10
13
|
playground: HTMLDivElement;
|
11
14
|
mainViewElement: HTMLDivElement;
|
@@ -15,7 +18,7 @@ export const setupWrapper = (
|
|
15
18
|
|
16
19
|
const mainViewElement = document.createElement("div");
|
17
20
|
mainViewElement.className = "netless-window-manager-main-view";
|
18
|
-
|
21
|
+
target.appendChild(mainViewElement);
|
19
22
|
root.appendChild(playground);
|
20
23
|
|
21
24
|
return { playground, mainViewElement };
|
@@ -38,6 +41,21 @@ export type Member = RoomMember & { uid: string };
|
|
38
41
|
export const serializeRoomMembers = (members: readonly RoomMember[]) => {
|
39
42
|
return members.map(member => ({
|
40
43
|
uid: member.payload?.uid || "",
|
41
|
-
...member,
|
44
|
+
...toJS(member),
|
42
45
|
}));
|
43
|
-
}
|
46
|
+
};
|
47
|
+
|
48
|
+
export const createInvisiblePlugin = async (room: Room) => {
|
49
|
+
try {
|
50
|
+
const manager = (await room.createInvisiblePlugin(WindowManager, {})) as WindowManager;
|
51
|
+
return manager;
|
52
|
+
} catch (error) {
|
53
|
+
// 如果有两个用户同时调用 WindowManager.mount 有概率出现这个错误
|
54
|
+
if (error.message === `invisible plugin "WindowManager" exits`) {
|
55
|
+
await wait(200);
|
56
|
+
return room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
|
57
|
+
} else {
|
58
|
+
log("createInvisiblePlugin failed", error);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
};
|
package/src/InternalEmitter.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
2
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
3
|
-
import type {
|
4
|
-
import type {
|
3
|
+
import type { CursorMovePayload } from "./index";
|
4
|
+
import type { MemberState } from "white-web-sdk";
|
5
5
|
|
6
6
|
export type RemoveSceneParams = {
|
7
7
|
scenePath: string;
|
@@ -10,7 +10,6 @@ export type RemoveSceneParams = {
|
|
10
10
|
|
11
11
|
export type EmitterEvent = {
|
12
12
|
onCreated: undefined;
|
13
|
-
InitReplay: AppInitState;
|
14
13
|
error: Error;
|
15
14
|
seekStart: undefined;
|
16
15
|
seek: number;
|
@@ -30,7 +29,7 @@ export type EmitterEvent = {
|
|
30
29
|
changePageState: undefined;
|
31
30
|
writableChange: boolean;
|
32
31
|
containerSizeRatioUpdate: number;
|
33
|
-
|
32
|
+
memberStateChange: MemberState;
|
34
33
|
};
|
35
34
|
|
36
35
|
export type EmitterType = Emittery<EmitterEvent>;
|
@@ -13,6 +13,7 @@ export type PageState = {
|
|
13
13
|
export interface PageController {
|
14
14
|
nextPage: () => Promise<boolean>;
|
15
15
|
prevPage: () => Promise<boolean>;
|
16
|
+
jumpPage: (index: number) => Promise<boolean>;
|
16
17
|
addPage: (params?: AddPageParams) => Promise<void>;
|
17
18
|
removePage: (index: number) => Promise<boolean>;
|
18
19
|
pageState: PageState;
|
package/src/PageState.ts
CHANGED
@@ -6,7 +6,7 @@ import type { PageState } from "./Page";
|
|
6
6
|
export class PageStateImpl {
|
7
7
|
constructor(private manager: AppManager) {
|
8
8
|
emitter.on("changePageState", () => {
|
9
|
-
|
9
|
+
callbacks.emit("pageStateChange", this.toObject());
|
10
10
|
});
|
11
11
|
}
|
12
12
|
|
@@ -46,14 +46,18 @@ export class ReconnectRefresher {
|
|
46
46
|
this.ctx.emitter.emit("startReconnect");
|
47
47
|
}
|
48
48
|
if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
|
49
|
-
this.room?.
|
49
|
+
if (this.room?.isWritable) {
|
50
|
+
this.room?.dispatchMagixEvent(EnsureReconnectEvent, {});
|
51
|
+
} else {
|
52
|
+
this.onReconnected();
|
53
|
+
}
|
50
54
|
}
|
51
55
|
this.phase = phase;
|
52
56
|
};
|
53
57
|
|
54
58
|
private onReconnected = debounce(() => {
|
55
59
|
this._onReconnected();
|
56
|
-
},
|
60
|
+
}, 1000);
|
57
61
|
|
58
62
|
private _onReconnected = () => {
|
59
63
|
log("onReconnected refresh reactors");
|
@@ -88,6 +92,7 @@ export class ReconnectRefresher {
|
|
88
92
|
this.reactors.set(id, func);
|
89
93
|
this.disposers.set(id, func());
|
90
94
|
}
|
95
|
+
return () => this.remove(id);
|
91
96
|
}
|
92
97
|
|
93
98
|
public remove(id: string) {
|
package/src/Utils/Common.ts
CHANGED
@@ -17,6 +17,9 @@ export const genAppId = async (kind: string) => {
|
|
17
17
|
};
|
18
18
|
|
19
19
|
export const setViewFocusScenePath = (view: View, focusScenePath: string) => {
|
20
|
+
if ((view as any).didRelease) {
|
21
|
+
return;
|
22
|
+
}
|
20
23
|
if (view.focusScenePath !== focusScenePath) {
|
21
24
|
view.focusScenePath = focusScenePath;
|
22
25
|
return view;
|
@@ -30,6 +33,12 @@ export const setViewSceneIndex = (view: View, index: number) => {
|
|
30
33
|
}
|
31
34
|
};
|
32
35
|
|
36
|
+
export const releaseView = (view: View) => {
|
37
|
+
if (!(view as any).didRelease) {
|
38
|
+
view.release();
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
33
42
|
export const setScenePath = (room: Room | undefined, scenePath: string) => {
|
34
43
|
if (room && room.isWritable) {
|
35
44
|
if (room.state.sceneState.scenePath !== scenePath) {
|
package/src/Utils/Reactive.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from "white-web-sdk";
|
2
|
-
import type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from "white-web-sdk";
|
3
1
|
import { isObject } from "lodash";
|
2
|
+
import { listenUpdated, reaction, unlistenUpdated, UpdateEventKind } from "white-web-sdk";
|
3
|
+
import type { AkkoObjectUpdatedProperty, AkkoObjectUpdatedListener } from "white-web-sdk";
|
4
4
|
|
5
5
|
// 兼容 13 和 14 版本 SDK
|
6
6
|
export const onObjectByEvent = (event: UpdateEventKind) => {
|
@@ -12,7 +12,7 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
12
12
|
if (kinds.includes(event)) {
|
13
13
|
func();
|
14
14
|
}
|
15
|
-
}
|
15
|
+
};
|
16
16
|
listenUpdated(object, listener);
|
17
17
|
func();
|
18
18
|
return () => unlistenUpdated(object, listener);
|
@@ -21,43 +21,44 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
|
|
21
21
|
() => object,
|
22
22
|
() => {
|
23
23
|
func();
|
24
|
-
},
|
24
|
+
},
|
25
|
+
{
|
25
26
|
fireImmediately: true,
|
26
27
|
}
|
27
|
-
)
|
28
|
+
);
|
28
29
|
}
|
29
|
-
}
|
30
|
-
}
|
30
|
+
};
|
31
|
+
};
|
31
32
|
|
32
33
|
export const safeListenPropsUpdated = <T>(
|
33
34
|
getProps: () => T,
|
34
35
|
callback: AkkoObjectUpdatedListener<T>,
|
35
36
|
onDestroyed?: (props: unknown) => void
|
36
|
-
|
37
|
+
) => {
|
37
38
|
let disposeListenUpdated: (() => void) | null = null;
|
38
39
|
const disposeReaction = reaction(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
getProps,
|
41
|
+
() => {
|
42
|
+
if (disposeListenUpdated) {
|
43
|
+
disposeListenUpdated();
|
44
|
+
disposeListenUpdated = null;
|
45
|
+
}
|
46
|
+
const props = getProps();
|
47
|
+
if (isObject(props)) {
|
48
|
+
disposeListenUpdated = () => unlistenUpdated(props, callback);
|
49
|
+
listenUpdated(props, callback);
|
50
|
+
} else {
|
51
|
+
onDestroyed?.(props);
|
52
|
+
}
|
53
|
+
},
|
54
|
+
{ fireImmediately: true }
|
54
55
|
);
|
55
56
|
|
56
57
|
return () => {
|
57
|
-
|
58
|
-
|
58
|
+
disposeListenUpdated?.();
|
59
|
+
disposeReaction();
|
59
60
|
};
|
60
|
-
}
|
61
|
+
};
|
61
62
|
|
62
63
|
export const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);
|
63
64
|
export const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);
|
package/src/Utils/RoomHacker.ts
CHANGED
@@ -56,6 +56,9 @@ export const replaceRoomFunction = (room: Room | Player, manager: WindowManager)
|
|
56
56
|
room.lockImages = (...args) => manager.lockImages(...args);
|
57
57
|
|
58
58
|
delegateRemoveScenes(room, manager);
|
59
|
+
if (!(room as any).dynamicPpt.slideStateAdapter.pptHandler) {
|
60
|
+
(room as any).dynamicPpt.slideStateAdapter.pptHandler = manager.createPPTHandler();
|
61
|
+
}
|
59
62
|
}
|
60
63
|
};
|
61
64
|
|
@@ -1,20 +1,20 @@
|
|
1
1
|
import { AnimationMode } from "white-web-sdk";
|
2
|
-
import {
|
2
|
+
import { isEqual, pick, throttle } from "lodash";
|
3
3
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
4
|
-
import type { Camera, View
|
5
|
-
import type {
|
4
|
+
import type { Camera, View } from "white-web-sdk";
|
5
|
+
import type { ICamera, ISize } from "../AttributesDelegate";
|
6
6
|
|
7
|
-
export type SaveCamera = (camera:
|
7
|
+
export type SaveCamera = (camera: ICamera) => void;
|
8
8
|
|
9
9
|
export class CameraSynchronizer {
|
10
|
-
|
11
|
-
|
10
|
+
public remoteCamera?: ICamera;
|
11
|
+
public remoteSize?: ISize;
|
12
12
|
protected rect?: TeleBoxRect;
|
13
13
|
protected view?: View;
|
14
14
|
|
15
15
|
constructor(protected saveCamera: SaveCamera) {}
|
16
16
|
|
17
|
-
public setRect(rect: TeleBoxRect) {
|
17
|
+
public setRect = (rect: TeleBoxRect) => {
|
18
18
|
this.rect = rect;
|
19
19
|
if (this.remoteCamera && this.remoteSize) {
|
20
20
|
this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
|
@@ -26,42 +26,45 @@ export class CameraSynchronizer {
|
|
26
26
|
}
|
27
27
|
|
28
28
|
// 远端 Camera 或者 size 更新
|
29
|
-
public onRemoteUpdate = throttle((camera:
|
29
|
+
public onRemoteUpdate = throttle((camera: ICamera, size: ISize) => {
|
30
30
|
this.remoteCamera = camera;
|
31
31
|
this.remoteSize = size;
|
32
32
|
if (this.remoteSize && this.rect) {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
}
|
37
|
-
scale = this.rect.height / size.height;
|
38
|
-
}
|
39
|
-
const nextScale = camera.scale * scale;
|
40
|
-
const moveCamera = () => this.view?.moveCamera({
|
41
|
-
centerX: camera.centerX,
|
42
|
-
centerY: camera.centerY,
|
33
|
+
const wScale = this.rect.width / size.width;
|
34
|
+
const hScale = this.rect.height / size.height;
|
35
|
+
const nextScale = camera.scale * Math.min(wScale, hScale);
|
36
|
+
const config: Partial<Camera> & { animationMode: AnimationMode } = {
|
43
37
|
scale: nextScale,
|
44
|
-
animationMode: AnimationMode.
|
45
|
-
}
|
46
|
-
|
47
|
-
|
38
|
+
animationMode: AnimationMode.Continuous,
|
39
|
+
}
|
40
|
+
if (camera.centerX !== null) {
|
41
|
+
config.centerX = camera.centerX;
|
42
|
+
}
|
43
|
+
if (camera.centerY !== null) {
|
44
|
+
config.centerY = camera.centerY;
|
45
|
+
}
|
46
|
+
this.moveCamera(config);
|
48
47
|
}
|
49
|
-
},
|
48
|
+
}, 10);
|
50
49
|
|
50
|
+
public onRemoteSizeUpdate(size: ISize) {
|
51
|
+
this.remoteSize = size;
|
52
|
+
const needMoveCamera = !isEqual(pick(this.rect, ["width", "height"]), pick(size, ["width", "height"]));
|
53
|
+
if (this.rect && this.remoteCamera && needMoveCamera) {
|
54
|
+
const scale = this.rect.width / size.width;
|
55
|
+
const nextScale = this.remoteCamera.scale * scale;
|
56
|
+
this.moveCamera({
|
57
|
+
scale: nextScale,
|
58
|
+
})
|
59
|
+
}
|
60
|
+
}
|
51
61
|
|
52
|
-
public onLocalCameraUpdate(camera:
|
62
|
+
public onLocalCameraUpdate(camera: ICamera) {
|
53
63
|
this.saveCamera(camera);
|
64
|
+
this.remoteCamera = camera;
|
54
65
|
}
|
55
66
|
|
56
|
-
|
57
|
-
|
58
|
-
if (this.rect && this.view) {
|
59
|
-
const scale = this.rect.width / size.width;
|
60
|
-
const nextScale = this.view.camera.scale * scale;
|
61
|
-
this.view.moveCamera({
|
62
|
-
scale: nextScale,
|
63
|
-
animationMode: AnimationMode.Immediately
|
64
|
-
});
|
65
|
-
}
|
67
|
+
private moveCamera(camera: Partial<Camera>) {
|
68
|
+
this.view?.moveCamera({ ...camera, animationMode: AnimationMode.Continuous });
|
66
69
|
}
|
67
70
|
}
|