@netless/window-manager 1.0.0-canary.8 → 1.0.0
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/LICENSE.txt +21 -0
- package/README.md +90 -64
- package/README.zh-cn.md +224 -0
- package/dist/index.d.ts +1133 -39
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/{index.es.js → index.mjs} +8393 -5913
- package/dist/index.mjs.map +1 -0
- package/dist/style.css +1 -1
- package/docs/advanced.md +55 -55
- package/docs/api.md +124 -113
- package/docs/app-context.md +248 -209
- package/docs/basic.md +25 -26
- package/docs/camera.md +19 -20
- package/docs/cn/advanced.md +137 -0
- package/docs/cn/api.md +309 -0
- package/docs/cn/app-context.md +369 -0
- package/docs/cn/basic.md +64 -0
- package/docs/cn/camera.md +53 -0
- package/docs/cn/concept.md +9 -0
- package/docs/cn/custom-max-bar.md +31 -0
- package/docs/cn/develop-app.md +94 -0
- package/docs/cn/export-pdf.md +48 -0
- package/docs/cn/migrate.md +60 -0
- package/docs/cn/replay.md +40 -0
- package/docs/concept.md +6 -5
- package/docs/custom-max-bar.md +31 -0
- package/docs/develop-app.md +22 -19
- package/docs/export-pdf.md +48 -0
- package/docs/migrate.md +25 -27
- package/docs/quickstart.md +50 -0
- package/docs/replay.md +20 -20
- package/package.json +32 -22
- package/src/App/AppContext.ts +104 -71
- package/src/App/AppPageStateImpl.ts +6 -25
- package/src/App/AppProxy.ts +42 -147
- package/src/App/MagixEvent/index.ts +38 -38
- package/src/App/Storage/StorageEvent.ts +13 -13
- package/src/App/Storage/index.ts +269 -245
- package/src/App/Storage/typings.ts +4 -2
- package/src/App/Storage/utils.ts +3 -3
- package/src/App/index.ts +0 -1
- package/src/AppListener.ts +8 -8
- package/src/AppManager.ts +84 -75
- package/src/AttributesDelegate.ts +42 -22
- package/src/BoxEmitter.ts +12 -6
- package/src/BoxManager.ts +122 -106
- package/src/ContainerResizeObserver.ts +75 -0
- package/src/Cursor/Cursor.svelte +16 -5
- package/src/Cursor/Cursor.svelte.d.ts +21 -0
- package/src/Cursor/Cursor.ts +77 -13
- package/src/Cursor/icons.ts +6 -0
- package/src/Cursor/icons2.ts +66 -0
- package/src/Cursor/index.ts +127 -26
- package/src/Helper.ts +94 -14
- package/src/InternalEmitter.ts +2 -7
- package/src/Page/PageController.ts +1 -0
- package/src/Page/index.ts +1 -1
- package/src/PageState.ts +6 -5
- package/src/ReconnectRefresher.ts +9 -4
- package/src/RedoUndo.ts +3 -3
- package/src/Register/index.ts +22 -17
- package/src/Register/loader.ts +26 -22
- package/src/Register/storage.ts +13 -13
- package/src/Utils/Common.ts +18 -14
- package/src/Utils/Reactive.ts +26 -25
- package/src/Utils/RoomHacker.ts +4 -4
- package/src/Utils/error.ts +0 -1
- package/src/View/IframeBridge.ts +680 -0
- package/src/View/MainView.ts +114 -53
- package/src/callback.ts +21 -1
- package/src/constants.ts +0 -2
- 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 +224 -74
- package/src/style.css +27 -10
- package/src/typings.ts +20 -10
- package/.prettierignore +0 -7
- package/.prettierrc.json +0 -9
- package/CHANGELOG.md +0 -196
- package/__mocks__/white-web-sdk.ts +0 -50
- package/dist/App/AppContext.d.ts +0 -76
- package/dist/App/AppPageStateImpl.d.ts +0 -21
- package/dist/App/AppProxy.d.ts +0 -81
- package/dist/App/AppViewSync.d.ts +0 -11
- package/dist/App/MagixEvent/index.d.ts +0 -29
- 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 -22
- package/dist/App/index.d.ts +0 -3
- package/dist/AppListener.d.ts +0 -21
- package/dist/AppManager.d.ts +0 -107
- package/dist/AttributesDelegate.d.ts +0 -80
- package/dist/BoxEmitter.d.ts +0 -34
- package/dist/BoxManager.d.ts +0 -100
- package/dist/BuiltinApps.d.ts +0 -5
- package/dist/Cursor/Cursor.d.ts +0 -39
- package/dist/Cursor/icons.d.ts +0 -3
- package/dist/Cursor/index.d.ts +0 -46
- package/dist/Helper.d.ts +0 -17
- package/dist/InternalEmitter.d.ts +0 -39
- package/dist/Page/PageController.d.ts +0 -20
- package/dist/Page/index.d.ts +0 -3
- package/dist/PageState.d.ts +0 -9
- package/dist/ReconnectRefresher.d.ts +0 -24
- package/dist/RedoUndo.d.ts +0 -18
- package/dist/Register/index.d.ts +0 -28
- package/dist/Register/loader.d.ts +0 -4
- package/dist/Register/storage.d.ts +0 -8
- package/dist/Utils/AppCreateQueue.d.ts +0 -15
- package/dist/Utils/Common.d.ts +0 -23
- package/dist/Utils/Reactive.d.ts +0 -6
- package/dist/Utils/RoomHacker.d.ts +0 -3
- package/dist/Utils/error.d.ts +0 -27
- package/dist/Utils/log.d.ts +0 -1
- package/dist/View/CameraSynchronizer.d.ts +0 -17
- package/dist/View/MainView.d.ts +0 -48
- package/dist/View/ViewManager.d.ts +0 -13
- package/dist/View/ViewSync.d.ts +0 -7
- package/dist/callback.d.ts +0 -24
- package/dist/constants.d.ts +0 -49
- package/dist/index.cjs.js +0 -46
- package/dist/index.umd.js +0 -46
- package/dist/typings.d.ts +0 -82
- package/jest.config.js +0 -27
- package/pnpm-lock.yaml +0 -6302
- package/src/App/AppViewSync.ts +0 -68
- package/src/App/WhiteboardView.ts +0 -83
- package/src/View/CameraSynchronizer.ts +0 -73
- package/src/View/ViewSync.ts +0 -10
- package/vite.config.js +0 -51
- /package/docs/{qickstart.md → cn/quickstart.md} +0 -0
package/src/View/MainView.ts
CHANGED
@@ -1,68 +1,78 @@
|
|
1
|
+
import { AnimationMode, reaction, ViewMode } from "white-web-sdk";
|
1
2
|
import { callbacks } from "../callback";
|
2
|
-
import { CameraSynchronizer } from "./CameraSynchronizer";
|
3
3
|
import { createView } from "./ViewManager";
|
4
|
-
import { debounce, get, isEqual } from "lodash";
|
5
|
-
import {
|
6
|
-
import { Events } from "../constants";
|
4
|
+
import { debounce, get, isEmpty, isEqual } from "lodash";
|
5
|
+
import { internalEmitter } from "../InternalEmitter";
|
7
6
|
import { Fields } from "../AttributesDelegate";
|
8
|
-
import {
|
9
|
-
import { releaseView, setViewFocusScenePath } from "../Utils/Common";
|
7
|
+
import { setViewFocusScenePath } from "../Utils/Common";
|
10
8
|
import { SideEffectManager } from "side-effect-manager";
|
11
|
-
import type { Camera, Size, View } from "white-web-sdk";
|
9
|
+
import type { Camera, Room, Size, View } from "white-web-sdk";
|
12
10
|
import type { AppManager } from "../AppManager";
|
11
|
+
import { Events } from "../constants";
|
13
12
|
|
14
13
|
export class MainViewProxy {
|
14
|
+
/** Refresh the view's camera in an interval of 1.5s. */
|
15
|
+
public polling = false;
|
16
|
+
|
17
|
+
private scale?: number;
|
15
18
|
private started = false;
|
16
19
|
private mainViewIsAddListener = false;
|
17
20
|
private mainView: View;
|
18
21
|
private store = this.manager.store;
|
19
|
-
private
|
22
|
+
private viewMode = this.manager.windowManger.viewMode;
|
20
23
|
|
21
24
|
private sideEffectManager = new SideEffectManager();
|
22
25
|
|
23
26
|
constructor(private manager: AppManager) {
|
24
|
-
this.synchronizer = new CameraSynchronizer(camera =>
|
25
|
-
this.store.setMainViewCamera({ ...camera, id: this.manager.uid })
|
26
|
-
);
|
27
27
|
this.mainView = this.createMainView();
|
28
28
|
this.moveCameraSizeByAttributes();
|
29
|
-
|
29
|
+
internalEmitter.once("mainViewMounted").then(() => {
|
30
30
|
this.addMainViewListener();
|
31
31
|
this.start();
|
32
32
|
this.ensureCameraAndSize();
|
33
33
|
this.startListenWritableChange();
|
34
34
|
});
|
35
|
+
const playgroundSizeChangeListener = () => {
|
36
|
+
this.sizeChangeHandler(this.mainViewSize);
|
37
|
+
};
|
35
38
|
this.sideEffectManager.add(() => {
|
36
|
-
return
|
39
|
+
return internalEmitter.on("playgroundSizeChange", playgroundSizeChangeListener);
|
37
40
|
});
|
38
41
|
this.sideEffectManager.add(() => {
|
39
|
-
return
|
40
|
-
releaseView(this.mainView);
|
41
|
-
});
|
42
|
+
return internalEmitter.on("containerSizeRatioUpdate", this.onUpdateContainerSizeRatio);
|
42
43
|
});
|
43
|
-
const rect = this.manager.boxManager?.stageRect;
|
44
|
-
if (rect) {
|
45
|
-
this.synchronizer.setRect(rect);
|
46
|
-
}
|
47
44
|
this.sideEffectManager.add(() => {
|
48
|
-
return
|
49
|
-
this.
|
50
|
-
|
45
|
+
return internalEmitter.on("startReconnect", () => {
|
46
|
+
if (!this.didRelease) {
|
47
|
+
this.mainView.release();
|
48
|
+
}
|
51
49
|
});
|
52
50
|
});
|
51
|
+
this.sideEffectManager.setInterval(this.syncCamera, 1500);
|
53
52
|
}
|
54
53
|
|
54
|
+
// Guard function when the camera is not synced
|
55
|
+
private syncCamera = () => {
|
56
|
+
if (!this.polling || this.viewMode !== ViewMode.Broadcaster) return;
|
57
|
+
const { mainViewCamera } = this;
|
58
|
+
if (mainViewCamera && mainViewCamera.id !== this.manager.uid) {
|
59
|
+
this.moveCameraSizeByAttributes();
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
55
63
|
private startListenWritableChange = () => {
|
56
64
|
this.sideEffectManager.add(() => {
|
57
|
-
return
|
65
|
+
return internalEmitter.on("writableChange", isWritable => {
|
58
66
|
if (isWritable) {
|
59
67
|
this.ensureCameraAndSize();
|
60
68
|
}
|
69
|
+
if (this.manager.room) this.syncMainView(this.manager.room);
|
61
70
|
});
|
62
71
|
});
|
63
72
|
};
|
64
73
|
|
65
74
|
public ensureCameraAndSize() {
|
75
|
+
if (this.viewMode !== ViewMode.Broadcaster) return;
|
66
76
|
if (!this.mainViewCamera || !this.mainViewSize) {
|
67
77
|
this.manager.dispatchInternalEvent(Events.InitMainViewCamera);
|
68
78
|
this.setCameraAndSize();
|
@@ -82,28 +92,27 @@ export class MainViewProxy {
|
|
82
92
|
}
|
83
93
|
|
84
94
|
private moveCameraSizeByAttributes() {
|
85
|
-
this.
|
95
|
+
this.moveCameraToContian(this.mainViewSize);
|
96
|
+
this.moveCamera(this.mainViewCamera);
|
86
97
|
}
|
87
98
|
|
88
99
|
public start() {
|
89
|
-
if (this.started) return;
|
90
100
|
this.sizeChangeHandler(this.mainViewSize);
|
101
|
+
if (this.started) return;
|
91
102
|
this.addCameraListener();
|
92
103
|
this.addCameraReaction();
|
104
|
+
if (this.manager.room) this.syncMainView(this.manager.room);
|
93
105
|
this.started = true;
|
94
106
|
}
|
95
107
|
|
96
108
|
public addCameraReaction = () => {
|
97
|
-
this.manager.refresher
|
109
|
+
this.manager.refresher.add(Fields.MainViewCamera, this.cameraReaction);
|
98
110
|
};
|
99
111
|
|
100
112
|
public setCameraAndSize(): void {
|
101
|
-
const
|
102
|
-
|
103
|
-
|
104
|
-
const size = { ...stageSize, id: this.manager.uid };
|
105
|
-
this.store.setMainViewCameraAndSize(camera, size);
|
106
|
-
}
|
113
|
+
const camera = { ...this.mainView.camera, id: this.manager.uid };
|
114
|
+
const size = { ...this.mainView.size, id: this.manager.uid };
|
115
|
+
this.store.setMainViewCameraAndSize(camera, size);
|
107
116
|
}
|
108
117
|
|
109
118
|
private cameraReaction = () => {
|
@@ -111,7 +120,8 @@ export class MainViewProxy {
|
|
111
120
|
() => this.mainViewCamera,
|
112
121
|
camera => {
|
113
122
|
if (camera && camera.id !== this.manager.uid) {
|
114
|
-
this.
|
123
|
+
this.moveCameraToContian(this.mainViewSize);
|
124
|
+
this.moveCamera(camera);
|
115
125
|
}
|
116
126
|
},
|
117
127
|
{ fireImmediately: true }
|
@@ -120,16 +130,15 @@ export class MainViewProxy {
|
|
120
130
|
|
121
131
|
public sizeChangeHandler = debounce((size: Size) => {
|
122
132
|
if (size) {
|
123
|
-
|
133
|
+
this.moveCameraToContian(size);
|
134
|
+
this.moveCamera(this.mainViewCamera);
|
124
135
|
}
|
136
|
+
this.ensureMainViewSize();
|
125
137
|
}, 30);
|
126
138
|
|
127
139
|
public onUpdateContainerSizeRatio = () => {
|
128
140
|
const size = this.store.getMainViewSize();
|
129
141
|
this.sizeChangeHandler(size);
|
130
|
-
if (size.id === this.manager.uid) {
|
131
|
-
this.setCameraAndSize();
|
132
|
-
}
|
133
142
|
};
|
134
143
|
|
135
144
|
public get view(): View {
|
@@ -146,7 +155,6 @@ export class MainViewProxy {
|
|
146
155
|
if (mainViewScenePath) {
|
147
156
|
setViewFocusScenePath(mainView, mainViewScenePath);
|
148
157
|
}
|
149
|
-
this.synchronizer.setView(mainView);
|
150
158
|
return mainView;
|
151
159
|
}
|
152
160
|
|
@@ -169,30 +177,26 @@ export class MainViewProxy {
|
|
169
177
|
const divElement = this.mainView.divElement;
|
170
178
|
const disableCameraTransform = this.mainView.disableCameraTransform;
|
171
179
|
this.stop();
|
172
|
-
|
180
|
+
if (!this.didRelease) {
|
181
|
+
this.mainView.release();
|
182
|
+
}
|
173
183
|
this.removeMainViewListener();
|
174
184
|
this.mainView = this.createMainView();
|
175
185
|
this.mainView.disableCameraTransform = disableCameraTransform;
|
176
186
|
this.mainView.divElement = divElement;
|
177
187
|
this.addMainViewListener();
|
178
188
|
this.start();
|
189
|
+
callbacks.emit("onMainViewRebind", this.mainView);
|
179
190
|
}
|
180
191
|
|
181
192
|
private onCameraUpdatedByDevice = (camera: Camera) => {
|
182
|
-
this.
|
183
|
-
|
184
|
-
if (
|
185
|
-
this.setMainViewSize(size);
|
193
|
+
if (this.viewMode === ViewMode.Follower) return;
|
194
|
+
this.store.setMainViewCamera({ ...camera, id: this.manager.uid });
|
195
|
+
if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.manager.uid })) {
|
196
|
+
this.setMainViewSize(this.view.size);
|
186
197
|
}
|
187
198
|
};
|
188
199
|
|
189
|
-
private getStageSize(): Size | undefined {
|
190
|
-
const stage = this.manager.boxManager?.stageRect;
|
191
|
-
if (stage) {
|
192
|
-
return { width: stage.width, height: stage.height };
|
193
|
-
}
|
194
|
-
}
|
195
|
-
|
196
200
|
public addMainViewListener(): void {
|
197
201
|
if (this.mainViewIsAddListener) return;
|
198
202
|
if (this.view.divElement) {
|
@@ -236,17 +240,74 @@ export class MainViewProxy {
|
|
236
240
|
this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
|
237
241
|
}
|
238
242
|
|
243
|
+
private _syncMainViewTimer = 0;
|
239
244
|
private onCameraOrSizeUpdated = () => {
|
240
245
|
callbacks.emit("cameraStateChange", this.cameraState);
|
246
|
+
// sdk >= 2.16.43 的 syncMainView() 可以写入当前 main view 的 camera, 以修复复制粘贴元素的位置
|
247
|
+
// 注意到这个操作会发送信令,应当避免频繁调用
|
248
|
+
if (this.manager.room && (this.manager.room as any).syncMainView) {
|
249
|
+
clearTimeout(this._syncMainViewTimer);
|
250
|
+
this._syncMainViewTimer = setTimeout(this.syncMainView, 100, this.manager.room);
|
251
|
+
}
|
252
|
+
this.ensureMainViewSize();
|
241
253
|
};
|
242
254
|
|
255
|
+
private ensureMainViewSize() {
|
256
|
+
if (
|
257
|
+
(!this.mainViewSize ||
|
258
|
+
this.mainViewSize.width === 0 ||
|
259
|
+
this.mainViewSize.height === 0) &&
|
260
|
+
this.mainView.size.width > 0 &&
|
261
|
+
this.mainView.size.height > 0
|
262
|
+
) {
|
263
|
+
this.setMainViewSize(this.mainView.size);
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
private syncMainView = (room: Room) => {
|
268
|
+
if (room.isWritable) {
|
269
|
+
room.syncMainView(this.mainView);
|
270
|
+
}
|
271
|
+
};
|
272
|
+
|
273
|
+
public moveCameraToContian(size: Size): void {
|
274
|
+
if (!isEmpty(size)) {
|
275
|
+
this.view.moveCameraToContain({
|
276
|
+
width: size.width,
|
277
|
+
height: size.height,
|
278
|
+
originX: -size.width / 2,
|
279
|
+
originY: -size.height / 2,
|
280
|
+
animationMode: AnimationMode.Immediately,
|
281
|
+
});
|
282
|
+
this.scale = this.view.camera.scale;
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
public moveCamera(camera: Camera): void {
|
287
|
+
if (!isEmpty(camera)) {
|
288
|
+
if (isEqual(camera, this.view.camera)) return;
|
289
|
+
const { centerX, centerY, scale } = camera;
|
290
|
+
const needScale = scale * (this.scale || 1);
|
291
|
+
this.view.moveCamera({
|
292
|
+
centerX: centerX,
|
293
|
+
centerY: centerY,
|
294
|
+
scale: needScale,
|
295
|
+
animationMode: AnimationMode.Immediately,
|
296
|
+
});
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
243
300
|
public stop() {
|
244
301
|
this.removeCameraListener();
|
245
|
-
this.manager.refresher
|
246
|
-
this.manager.refresher
|
302
|
+
this.manager.refresher.remove(Fields.MainViewCamera);
|
303
|
+
this.manager.refresher.remove(Fields.MainViewSize);
|
247
304
|
this.started = false;
|
248
305
|
}
|
249
306
|
|
307
|
+
public setViewMode = (mode: ViewMode) => {
|
308
|
+
this.viewMode = mode;
|
309
|
+
};
|
310
|
+
|
250
311
|
public destroy() {
|
251
312
|
this.removeMainViewListener();
|
252
313
|
this.stop();
|
package/src/callback.ts
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
2
|
import type { TeleBoxColorScheme, TELE_BOX_STATE } from "@netless/telebox-insider";
|
3
|
-
import type { CameraState, SceneState, ViewVisionMode } from "white-web-sdk";
|
3
|
+
import type { CameraState, SceneState, View, ViewVisionMode } from "white-web-sdk";
|
4
4
|
import type { LoadAppEvent } from "./Register";
|
5
5
|
import type { PageState } from "./Page";
|
6
|
+
import type {
|
7
|
+
BoxClosePayload,
|
8
|
+
BoxFocusPayload,
|
9
|
+
BoxMovePayload,
|
10
|
+
BoxResizePayload,
|
11
|
+
BoxStateChangePayload,
|
12
|
+
} from "./BoxEmitter";
|
13
|
+
import type { AppPayload } from "./typings";
|
6
14
|
|
7
15
|
export type PublicEvent = {
|
8
16
|
mainViewModeChange: ViewVisionMode;
|
@@ -20,6 +28,18 @@ export type PublicEvent = {
|
|
20
28
|
ready: undefined; // 所有 APP 创建完毕时触发
|
21
29
|
sceneStateChange: SceneState;
|
22
30
|
pageStateChange: PageState;
|
31
|
+
fullscreenChange: boolean;
|
32
|
+
appsChange: string[]; // APP 列表变化时触发
|
33
|
+
onBoxMove: BoxMovePayload;
|
34
|
+
onBoxResize: BoxResizePayload;
|
35
|
+
onBoxFocus: BoxFocusPayload;
|
36
|
+
onBoxClose: BoxClosePayload;
|
37
|
+
onBoxStateChange: BoxStateChangePayload;
|
38
|
+
onMainViewMounted: View;
|
39
|
+
onMainViewRebind: View;
|
40
|
+
onAppViewMounted: AppPayload;
|
41
|
+
onAppSetup: string;
|
42
|
+
onAppScenePathChange: AppPayload;
|
23
43
|
};
|
24
44
|
|
25
45
|
export type CallbacksType = Emittery<PublicEvent>;
|
package/src/constants.ts
CHANGED