@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/App/AppContext.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { BoxNotCreatedError } from "../Utils/error";
|
2
|
+
import { putScenes } from "../Utils/Common";
|
2
3
|
import { Storage } from "./Storage";
|
3
4
|
import {
|
4
5
|
autorun,
|
@@ -13,12 +14,12 @@ import type {
|
|
13
14
|
Room,
|
14
15
|
SceneDefinition,
|
15
16
|
View,
|
16
|
-
EventListener as WhiteEventListener
|
17
|
+
EventListener as WhiteEventListener,
|
17
18
|
} from "white-web-sdk";
|
18
19
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
19
20
|
import type Emittery from "emittery";
|
20
21
|
import type { BoxManager } from "../BoxManager";
|
21
|
-
import type { AppEmitterEvent
|
22
|
+
import type { AppEmitterEvent } from "../index";
|
22
23
|
import type { AppManager } from "../AppManager";
|
23
24
|
import type { AppProxy } from "./AppProxy";
|
24
25
|
import type {
|
@@ -26,12 +27,13 @@ import type {
|
|
26
27
|
MagixEventDispatcher,
|
27
28
|
MagixEventRemoveListener,
|
28
29
|
} from "./MagixEvent";
|
29
|
-
import {
|
30
|
-
import {
|
31
|
-
import {
|
32
|
-
import { isNumber } from "lodash";
|
30
|
+
import type { AddPageParams, PageController, PageState } from "../Page";
|
31
|
+
import { internalEmitter } from "../InternalEmitter";
|
32
|
+
import { callbacks } from "../callback";
|
33
33
|
|
34
|
-
export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any>
|
34
|
+
export class AppContext<TAttributes extends {} = any, TMagixEventPayloads = any, TAppOptions = any>
|
35
|
+
implements PageController
|
36
|
+
{
|
35
37
|
public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
|
36
38
|
public readonly mobxUtils = {
|
37
39
|
autorun,
|
@@ -48,8 +50,6 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
48
50
|
private store = this.manager.store;
|
49
51
|
public readonly isAddApp: boolean;
|
50
52
|
public readonly isReplay = this.manager.isReplay;
|
51
|
-
private whiteBoardView?: WhiteBoardView;
|
52
|
-
public _viewWrapper?: HTMLElement;
|
53
53
|
|
54
54
|
constructor(
|
55
55
|
private manager: AppManager,
|
@@ -62,13 +62,9 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
62
62
|
this.isAddApp = appProxy.isAddApp;
|
63
63
|
}
|
64
64
|
|
65
|
-
public
|
65
|
+
public getDisplayer = () => {
|
66
66
|
return this.manager.displayer;
|
67
|
-
}
|
68
|
-
|
69
|
-
public get destroyed() {
|
70
|
-
return this.appProxy.status === "destroyed";
|
71
|
-
}
|
67
|
+
};
|
72
68
|
|
73
69
|
/** @deprecated Use context.storage.state instead. */
|
74
70
|
public getAttributes = (): TAttributes | undefined => {
|
@@ -84,57 +80,33 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
84
80
|
}
|
85
81
|
};
|
86
82
|
|
87
|
-
public
|
83
|
+
public getView = (): View | undefined => {
|
88
84
|
return this.appProxy.view;
|
89
85
|
};
|
90
86
|
|
91
|
-
public
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
this._viewWrapper = viewWrapper;
|
101
|
-
viewWrapper.className = "window-manager-view-wrapper";
|
102
|
-
this.box.$content.parentElement?.appendChild(viewWrapper);
|
103
|
-
const removeViewWrapper = () => {
|
104
|
-
this.box.$content.parentElement?.removeChild(viewWrapper);
|
105
|
-
this._viewWrapper = undefined;
|
87
|
+
public mountView = (dom: HTMLElement): void => {
|
88
|
+
const view = this.getView();
|
89
|
+
if (view) {
|
90
|
+
view.divElement = dom as HTMLDivElement;
|
91
|
+
setTimeout(() => {
|
92
|
+
// 渲染需要时间,延迟 refresh
|
93
|
+
this.getRoom()?.refreshViewSize();
|
94
|
+
callbacks.emit("onAppViewMounted", { appId: this.appId, view });
|
95
|
+
}, 1000);
|
106
96
|
}
|
107
|
-
|
108
|
-
if (this.isAddApp) {
|
109
|
-
this.ensurePageSize(size);
|
110
|
-
}
|
111
|
-
this.whiteBoardView = new WhiteBoardView(view, this, this.appProxy, removeViewWrapper, this.ensurePageSize);
|
112
|
-
return this.whiteBoardView;
|
113
|
-
}
|
114
|
-
|
115
|
-
private ensurePageSize = (size?: number) => {
|
116
|
-
if (!isNumber(size)) return;
|
117
|
-
if (!this.appProxy.scenePath) return;
|
118
|
-
if (this.appProxy.pageState.length >= size) return;
|
119
|
-
if (size <= 0 || size >= MAX_PAGE_SIZE) {
|
120
|
-
throw Error(`[WindowManager]: size ${size} muse be in range [1, ${MAX_PAGE_SIZE}]`);
|
121
|
-
}
|
122
|
-
const needInsert = size - this.appProxy.pageState.length;
|
123
|
-
const scenes = new Array(needInsert).fill({});
|
124
|
-
this.room?.putScenes(this.appProxy.scenePath, scenes);
|
125
|
-
}
|
97
|
+
};
|
126
98
|
|
127
99
|
public getInitScenePath = () => {
|
128
100
|
return this.manager.getAppInitPath(this.appId);
|
129
101
|
};
|
130
102
|
|
131
103
|
/** Get App writable status. */
|
132
|
-
public
|
104
|
+
public getIsWritable = (): boolean => {
|
133
105
|
return this.manager.canOperate;
|
134
106
|
};
|
135
107
|
|
136
108
|
/** Get the App Window UI box. */
|
137
|
-
public
|
109
|
+
public getBox = (): ReadonlyTeleBox => {
|
138
110
|
const box = this.boxManager.getBox(this.appId);
|
139
111
|
if (box) {
|
140
112
|
return box;
|
@@ -143,25 +115,10 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
143
115
|
}
|
144
116
|
};
|
145
117
|
|
146
|
-
public
|
118
|
+
public getRoom = (): Room | undefined => {
|
147
119
|
return this.manager.room;
|
148
120
|
};
|
149
121
|
|
150
|
-
public get members() {
|
151
|
-
return this.manager.members;
|
152
|
-
}
|
153
|
-
|
154
|
-
public get memberState(): Member {
|
155
|
-
const self = findMemberByUid(this.room, this.manager.uid);
|
156
|
-
if (!self) {
|
157
|
-
throw new Error(`Member ${this.manager.uid} not found.`);
|
158
|
-
}
|
159
|
-
return {
|
160
|
-
uid: this.manager.uid,
|
161
|
-
...self,
|
162
|
-
}
|
163
|
-
}
|
164
|
-
|
165
122
|
/** @deprecated Use context.storage.setState instead. */
|
166
123
|
public setAttributes = (attributes: TAttributes) => {
|
167
124
|
this.manager.safeSetAttributes({ [this.appId]: attributes });
|
@@ -174,12 +131,11 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
174
131
|
}
|
175
132
|
};
|
176
133
|
|
177
|
-
/** @deprecated Use Pages api instead. */
|
178
134
|
public setScenePath = async (scenePath: string): Promise<void> => {
|
179
135
|
if (!this.appProxy.box) return;
|
180
136
|
this.appProxy.setFullPath(scenePath);
|
181
137
|
// 兼容 15 版本 SDK 的切页
|
182
|
-
this.
|
138
|
+
this.getRoom()?.setScenePath(scenePath);
|
183
139
|
};
|
184
140
|
|
185
141
|
/** Get the local App options. */
|
@@ -205,7 +161,10 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
205
161
|
* @param defaultState Default state for initial storage creation.
|
206
162
|
* @returns
|
207
163
|
*/
|
208
|
-
public createStorage = <TState
|
164
|
+
public createStorage = <TState extends {}>(
|
165
|
+
storeId: string,
|
166
|
+
defaultState?: TState
|
167
|
+
): Storage<TState> => {
|
209
168
|
const storage = new Storage(this, storeId, defaultState);
|
210
169
|
this.emitter.on("destroy", () => {
|
211
170
|
storage.destroy();
|
@@ -243,4 +202,78 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
|
|
243
202
|
public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(
|
244
203
|
this.manager.displayer
|
245
204
|
) as MagixEventRemoveListener<TMagixEventPayloads>;
|
205
|
+
|
206
|
+
/** PageController */
|
207
|
+
public nextPage = async (): Promise<boolean> => {
|
208
|
+
const nextIndex = this.pageState.index + 1;
|
209
|
+
if (nextIndex > this.pageState.length - 1) {
|
210
|
+
console.warn("[WindowManager] nextPage: index out of range");
|
211
|
+
return false;
|
212
|
+
}
|
213
|
+
this.appProxy.setSceneIndex(nextIndex);
|
214
|
+
return true;
|
215
|
+
};
|
216
|
+
|
217
|
+
public jumpPage = async (index: number): Promise<boolean> => {
|
218
|
+
if (!(0 <= index && index < this.pageState.length)) {
|
219
|
+
console.warn("[WindowManager] nextPage: index out of range");
|
220
|
+
return false;
|
221
|
+
}
|
222
|
+
this.appProxy.setSceneIndex(index);
|
223
|
+
return true;
|
224
|
+
};
|
225
|
+
|
226
|
+
public prevPage = async (): Promise<boolean> => {
|
227
|
+
const nextIndex = this.pageState.index - 1;
|
228
|
+
if (nextIndex < 0) {
|
229
|
+
console.warn("[WindowManager] prevPage: index out of range");
|
230
|
+
return false;
|
231
|
+
}
|
232
|
+
this.appProxy.setSceneIndex(nextIndex);
|
233
|
+
return true;
|
234
|
+
};
|
235
|
+
|
236
|
+
public addPage = async (params?: AddPageParams) => {
|
237
|
+
const after = params?.after;
|
238
|
+
const scene = params?.scene;
|
239
|
+
const scenePath = this.appProxy.scenePath;
|
240
|
+
if (!scenePath) return;
|
241
|
+
if (after) {
|
242
|
+
const nextIndex = this.pageState.index + 1;
|
243
|
+
putScenes(this.manager.room, scenePath, [scene || {}], nextIndex);
|
244
|
+
} else {
|
245
|
+
putScenes(this.manager.room, scenePath, [scene || {}]);
|
246
|
+
}
|
247
|
+
};
|
248
|
+
|
249
|
+
public removePage = async (index?: number): Promise<boolean> => {
|
250
|
+
const needRemoveIndex = index === undefined ? this.pageState.index : index;
|
251
|
+
if (this.pageState.length === 1) {
|
252
|
+
console.warn(`[WindowManager]: can not remove the last page`);
|
253
|
+
return false;
|
254
|
+
}
|
255
|
+
if (needRemoveIndex < 0 || needRemoveIndex >= this.pageState.length) {
|
256
|
+
console.warn(`[WindowManager]: page index ${index} out of range`);
|
257
|
+
return false;
|
258
|
+
}
|
259
|
+
return this.appProxy.removeSceneByIndex(needRemoveIndex);
|
260
|
+
};
|
261
|
+
|
262
|
+
public get pageState(): PageState {
|
263
|
+
return this.appProxy.pageState;
|
264
|
+
}
|
265
|
+
|
266
|
+
public get kind(): string {
|
267
|
+
return this.appProxy.kind;
|
268
|
+
}
|
269
|
+
|
270
|
+
/** Dispatch a local event to `manager.onAppEvent()`. */
|
271
|
+
public dispatchAppEvent(type: string, value?: any): void {
|
272
|
+
internalEmitter.emit(`custom-${this.kind}` as any, {
|
273
|
+
kind: this.kind,
|
274
|
+
appId: this.appId,
|
275
|
+
type,
|
276
|
+
value,
|
277
|
+
});
|
278
|
+
}
|
246
279
|
}
|
@@ -9,15 +9,11 @@ export type AppPageStateParams = {
|
|
9
9
|
};
|
10
10
|
|
11
11
|
export class AppPageStateImpl {
|
12
|
-
|
13
|
-
private scenePath?: string;
|
14
|
-
private view?: View;
|
12
|
+
private sceneNode: ScenesCallbacksNode | null = null;
|
15
13
|
|
16
14
|
constructor(private params: AppPageStateParams) {
|
17
15
|
const { displayer, scenePath } = this.params;
|
18
|
-
this.view = this.params.view;
|
19
16
|
if (scenePath) {
|
20
|
-
this.scenePath = scenePath;
|
21
17
|
this.sceneNode = displayer.createScenesCallback(scenePath, {
|
22
18
|
onAddScene: this.onSceneChange,
|
23
19
|
onRemoveScene: this.onSceneChange,
|
@@ -25,39 +21,24 @@ export class AppPageStateImpl {
|
|
25
21
|
}
|
26
22
|
}
|
27
23
|
|
28
|
-
|
29
|
-
this.
|
30
|
-
if (this.sceneNode) {
|
31
|
-
this.sceneNode.dispose();
|
32
|
-
}
|
33
|
-
this.sceneNode = this.params.displayer.createScenesCallback(scenePath, {
|
34
|
-
onAddScene: this.onSceneChange,
|
35
|
-
onRemoveScene: this.onSceneChange,
|
36
|
-
});
|
37
|
-
return this.sceneNode;
|
38
|
-
}
|
39
|
-
|
40
|
-
public setView(view: View) {
|
41
|
-
this.view = view;
|
42
|
-
}
|
43
|
-
|
44
|
-
private onSceneChange = () => {
|
24
|
+
private onSceneChange = (node: ScenesCallbacksNode) => {
|
25
|
+
this.sceneNode = node;
|
45
26
|
this.params.notifyPageStateChange();
|
46
27
|
};
|
47
28
|
|
48
29
|
public getFullPath(index: number) {
|
49
30
|
const scenes = this.sceneNode?.scenes;
|
50
|
-
if (this.scenePath && scenes) {
|
31
|
+
if (this.params.scenePath && scenes) {
|
51
32
|
const name = scenes[index];
|
52
33
|
if (name) {
|
53
|
-
return `${this.scenePath}/${name}`;
|
34
|
+
return `${this.params.scenePath}/${name}`;
|
54
35
|
}
|
55
36
|
}
|
56
37
|
}
|
57
38
|
|
58
39
|
public toObject(): PageState {
|
59
40
|
return {
|
60
|
-
index: this.view?.focusSceneIndex || 0,
|
41
|
+
index: this.params.view?.focusSceneIndex || 0,
|
61
42
|
length: this.sceneNode?.scenes.length || 0,
|
62
43
|
};
|
63
44
|
}
|