@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/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,
|
@@ -12,13 +14,15 @@ import type {
|
|
12
14
|
TeleBoxColorScheme,
|
13
15
|
TeleBoxRect,
|
14
16
|
TeleBoxConfig,
|
17
|
+
TeleBoxFullscreen,
|
18
|
+
TeleBoxManagerThemeConfig,
|
15
19
|
} from "@netless/telebox-insider";
|
16
20
|
import type Emittery from "emittery";
|
17
21
|
import type { NetlessApp } from "./typings";
|
18
22
|
import type { View } from "white-web-sdk";
|
19
23
|
import type { CallbacksType } from "./callback";
|
20
24
|
import type { EmitterType } from "./InternalEmitter";
|
21
|
-
import {
|
25
|
+
import type { AppState } from "./App/type";
|
22
26
|
|
23
27
|
export { TELE_BOX_STATE };
|
24
28
|
|
@@ -47,11 +51,16 @@ export type CreateTeleBoxManagerConfig = {
|
|
47
51
|
collectorStyles?: Partial<CSSStyleDeclaration>;
|
48
52
|
prefersColorScheme?: TeleBoxColorScheme;
|
49
53
|
stageRatio?: number;
|
54
|
+
containerStyle?: string;
|
55
|
+
stageStyle?: string;
|
56
|
+
fullscreen?: TeleBoxFullscreen;
|
57
|
+
defaultBoxBodyStyle?: string | null;
|
58
|
+
defaultBoxStageStyle?: string | null;
|
59
|
+
theme?: TeleBoxManagerThemeConfig;
|
50
60
|
};
|
51
61
|
|
52
62
|
export type BoxManagerContext = {
|
53
63
|
safeSetAttributes: (attributes: any) => void;
|
54
|
-
getMainView: () => View;
|
55
64
|
updateAppState: (appId: string, field: AppAttributes, value: any) => void;
|
56
65
|
emitter: EmitterType;
|
57
66
|
boxEmitter: BoxEmitterType;
|
@@ -72,7 +81,6 @@ export const createBoxManager = (
|
|
72
81
|
return new BoxManager(
|
73
82
|
{
|
74
83
|
safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
|
75
|
-
getMainView: () => manager.mainView,
|
76
84
|
updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
|
77
85
|
canOperate: () => manager.canOperate,
|
78
86
|
notifyContainerRectUpdate: (rect: TeleBoxRect) =>
|
@@ -81,7 +89,7 @@ export const createBoxManager = (
|
|
81
89
|
setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
|
82
90
|
callbacks,
|
83
91
|
emitter,
|
84
|
-
boxEmitter
|
92
|
+
boxEmitter,
|
85
93
|
},
|
86
94
|
options
|
87
95
|
);
|
@@ -100,17 +108,17 @@ export class BoxManager {
|
|
100
108
|
this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
|
101
109
|
this.sideEffectManager.add(() => [
|
102
110
|
// 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
|
103
|
-
this.teleBoxManager.
|
111
|
+
this.teleBoxManager.onValChanged("state", state => {
|
104
112
|
callbacks.emit("boxStateChange", state);
|
105
113
|
emitter.emit("boxStateChange", state);
|
106
114
|
}),
|
107
|
-
this.teleBoxManager.
|
115
|
+
this.teleBoxManager.onValChanged("darkMode", darkMode => {
|
108
116
|
callbacks.emit("darkModeChange", darkMode);
|
109
117
|
}),
|
110
|
-
this.teleBoxManager.
|
118
|
+
this.teleBoxManager.onValChanged("prefersColorScheme", colorScheme => {
|
111
119
|
callbacks.emit("prefersColorSchemeChange", colorScheme);
|
112
120
|
}),
|
113
|
-
this.teleBoxManager.
|
121
|
+
this.teleBoxManager.onValChanged("minimized", (minimized, skipUpdate) => {
|
114
122
|
if (skipUpdate) {
|
115
123
|
return;
|
116
124
|
}
|
@@ -126,7 +134,7 @@ export class BoxManager {
|
|
126
134
|
}
|
127
135
|
}
|
128
136
|
}),
|
129
|
-
this.teleBoxManager.
|
137
|
+
this.teleBoxManager.onValChanged("maximized", (maximized, skipUpdate) => {
|
130
138
|
if (skipUpdate) {
|
131
139
|
return;
|
132
140
|
}
|
@@ -140,7 +148,11 @@ export class BoxManager {
|
|
140
148
|
this.teleBoxManager.events.on(
|
141
149
|
"intrinsic_move",
|
142
150
|
debounce((box: ReadonlyTeleBox): void => {
|
143
|
-
boxEmitter.emit("move", {
|
151
|
+
boxEmitter.emit("move", {
|
152
|
+
appId: box.id,
|
153
|
+
x: box.intrinsicX,
|
154
|
+
y: box.intrinsicY,
|
155
|
+
});
|
144
156
|
}, 50)
|
145
157
|
),
|
146
158
|
this.teleBoxManager.events.on(
|
@@ -165,23 +177,15 @@ export class BoxManager {
|
|
165
177
|
this.teleBoxManager.events.on("z_index", box => {
|
166
178
|
this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
|
167
179
|
}),
|
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
180
|
emitter.on("containerSizeRatioUpdate", ratio => {
|
176
181
|
this.teleBoxManager._stageRatio$.setValue(ratio);
|
177
182
|
}),
|
183
|
+
this.teleBoxManager._fullscreen$.reaction(fullscreen => {
|
184
|
+
callbacks.emit("fullscreenChange", fullscreen);
|
185
|
+
}),
|
178
186
|
]);
|
179
187
|
}
|
180
188
|
|
181
|
-
private get mainView() {
|
182
|
-
return this.context.getMainView();
|
183
|
-
}
|
184
|
-
|
185
189
|
private get canOperate() {
|
186
190
|
return this.context.canOperate();
|
187
191
|
}
|
@@ -214,9 +218,14 @@ export class BoxManager {
|
|
214
218
|
return this.teleBoxManager.stageRect;
|
215
219
|
}
|
216
220
|
|
221
|
+
public get stageRect$() {
|
222
|
+
return this.teleBoxManager._stageRect$;
|
223
|
+
}
|
224
|
+
|
217
225
|
public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
|
218
226
|
if (!this.teleBoxManager) return;
|
219
|
-
|
227
|
+
// eslint-disable-next-line prefer-const
|
228
|
+
let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT, enableShadowDOM = true } = params.app.config ?? {};
|
220
229
|
const { width, height } = params.app.config ?? {};
|
221
230
|
const title = params.options?.title || params.appId;
|
222
231
|
const rect = this.teleBoxManager.rootRect;
|
@@ -236,6 +245,7 @@ export class BoxManager {
|
|
236
245
|
width,
|
237
246
|
height,
|
238
247
|
id: params.appId,
|
248
|
+
enableShadowDOM,
|
239
249
|
};
|
240
250
|
const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
|
241
251
|
this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
|
@@ -246,13 +256,37 @@ export class BoxManager {
|
|
246
256
|
createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
|
247
257
|
): TeleBoxManager {
|
248
258
|
const root = WindowManager.playground;
|
249
|
-
const initManagerState: TeleBoxManagerConfig = {
|
259
|
+
const initManagerState: Writeable<TeleBoxManagerConfig> = {
|
250
260
|
stageRatio: createTeleBoxManagerConfig?.stageRatio,
|
251
261
|
root: root,
|
252
262
|
fence: false,
|
253
263
|
prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
|
254
264
|
};
|
255
265
|
|
266
|
+
if (createTeleBoxManagerConfig?.containerStyle) {
|
267
|
+
initManagerState.containerStyle = createTeleBoxManagerConfig.containerStyle;
|
268
|
+
}
|
269
|
+
|
270
|
+
if (createTeleBoxManagerConfig?.stageStyle) {
|
271
|
+
initManagerState.stageStyle = createTeleBoxManagerConfig.stageStyle;
|
272
|
+
}
|
273
|
+
|
274
|
+
if (createTeleBoxManagerConfig?.fullscreen) {
|
275
|
+
initManagerState.fullscreen = createTeleBoxManagerConfig.fullscreen;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (createTeleBoxManagerConfig?.defaultBoxBodyStyle !== undefined) {
|
279
|
+
initManagerState.defaultBoxBodyStyle = createTeleBoxManagerConfig.defaultBoxBodyStyle;
|
280
|
+
}
|
281
|
+
|
282
|
+
if (createTeleBoxManagerConfig?.defaultBoxStageStyle !== undefined) {
|
283
|
+
initManagerState.defaultBoxStageStyle = createTeleBoxManagerConfig.defaultBoxStageStyle;
|
284
|
+
}
|
285
|
+
|
286
|
+
if (createTeleBoxManagerConfig?.theme) {
|
287
|
+
initManagerState.theme = createTeleBoxManagerConfig.theme;
|
288
|
+
}
|
289
|
+
|
256
290
|
const manager = new TeleBoxManager(initManagerState);
|
257
291
|
if (this.teleBoxManager) {
|
258
292
|
this.teleBoxManager.destroy();
|
@@ -290,21 +324,19 @@ export class BoxManager {
|
|
290
324
|
return this.teleBoxManager.topBox;
|
291
325
|
}
|
292
326
|
|
293
|
-
public updateBoxState(state?:
|
327
|
+
public updateBoxState(state?: AppState): void {
|
294
328
|
if (!state) return;
|
295
329
|
const box = this.getBox(state.id);
|
296
330
|
if (box) {
|
297
|
-
|
298
|
-
box.
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
true
|
307
|
-
);
|
331
|
+
if (state.size) {
|
332
|
+
box._intrinsicSize$.setValue(state.size, true);
|
333
|
+
}
|
334
|
+
if (state.position && state.position.x !== undefined && state.position.y !== undefined) {
|
335
|
+
box._intrinsicCoord$.setValue({ x: state.position.x, y: state.position.y }, true);
|
336
|
+
}
|
337
|
+
if (state.zIndex) {
|
338
|
+
box._zIndex$.setValue(state.zIndex, true);
|
339
|
+
}
|
308
340
|
setTimeout(() => {
|
309
341
|
if (state.focus) {
|
310
342
|
this.teleBoxManager.focusBox(box.id, true);
|
@@ -321,7 +353,10 @@ export class BoxManager {
|
|
321
353
|
}
|
322
354
|
|
323
355
|
public moveBox({ appId, x, y }: MoveBoxParams): void {
|
324
|
-
this.
|
356
|
+
const box = this.getBox(appId);
|
357
|
+
if (box) {
|
358
|
+
box._intrinsicCoord$.setValue({ x, y }, true);
|
359
|
+
}
|
325
360
|
}
|
326
361
|
|
327
362
|
public focusBox({ appId }: AppId, skipUpdate = true): void {
|
@@ -329,7 +364,10 @@ export class BoxManager {
|
|
329
364
|
}
|
330
365
|
|
331
366
|
public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {
|
332
|
-
this.
|
367
|
+
const box = this.getBox(appId);
|
368
|
+
if (box) {
|
369
|
+
box._intrinsicSize$.setValue({ width, height }, skipUpdate);
|
370
|
+
}
|
333
371
|
}
|
334
372
|
|
335
373
|
public setBoxMinSize(params: SetBoxMinSizeParams): void {
|
package/src/BuiltinApps.ts
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
import AppDocsViewer from "@netless/app-docs-viewer";
|
2
|
-
import
|
2
|
+
import Plyr from "@netless/app-plyr";
|
3
3
|
import { WindowManager } from "./index";
|
4
4
|
|
5
5
|
export const setupBuiltin = () => {
|
6
|
-
if (WindowManager.debug) {
|
7
|
-
setOptions({ verbose: true });
|
8
|
-
}
|
9
|
-
|
10
6
|
WindowManager.register({
|
11
7
|
kind: AppDocsViewer.kind,
|
12
8
|
src: AppDocsViewer,
|
13
9
|
});
|
14
10
|
WindowManager.register({
|
15
|
-
kind:
|
16
|
-
src:
|
11
|
+
kind: Plyr.kind,
|
12
|
+
src: Plyr,
|
17
13
|
});
|
18
14
|
};
|
19
15
|
|
20
16
|
export const BuiltinApps = {
|
21
17
|
DocsViewer: AppDocsViewer.kind as string,
|
22
|
-
MediaPlayer:
|
18
|
+
MediaPlayer: Plyr.kind as string,
|
23
19
|
};
|
20
|
+
|
21
|
+
export const BuiltinAppsMap = {
|
22
|
+
[BuiltinApps.DocsViewer]: AppDocsViewer,
|
23
|
+
[BuiltinApps.MediaPlayer]: Plyr,
|
24
|
+
}
|
package/src/Cursor/Cursor.svelte
CHANGED
@@ -15,12 +15,16 @@
|
|
15
15
|
export let color: string;
|
16
16
|
export let cursorTagBackgroundColor: string;
|
17
17
|
export let opacity: number;
|
18
|
+
export let pencilEraserSize: number;
|
18
19
|
|
19
20
|
$: hasName = !isEmpty(cursorName);
|
20
21
|
$: hasTagName = !isEmpty(tagName);
|
21
22
|
$: hasAvatar = !isEmpty(avatar);
|
22
23
|
$: display = visible ? "initial" : "none";
|
23
24
|
$: isLaserPointer = appliance === ApplianceNames.laserPointer;
|
25
|
+
$: isLaserPointerPencilEraser = isLaserPointer || appliance === ApplianceNames.pencilEraser;
|
26
|
+
$: offset = isLaserPointerPencilEraser ? "netless-window-manager-laserPointer-pencilEraser-offset" : "";
|
27
|
+
$: pencilEraserSize3ImageOffset = pencilEraserSize === 3 ? "netless-window-manager-pencilEraser-3-offset" : "";
|
24
28
|
|
25
29
|
const computedAvatarStyle = () => {
|
26
30
|
return Object.entries({
|
@@ -40,7 +44,7 @@
|
|
40
44
|
style="transform: translateX({x}px) translateY({y}px);display: {display}"
|
41
45
|
>
|
42
46
|
{#if !isLaserPointer}
|
43
|
-
<div class="netless-window-manager-cursor-name">
|
47
|
+
<div class="netless-window-manager-cursor-name {offset} {pencilEraserSize3ImageOffset}">
|
44
48
|
<div
|
45
49
|
class={theme}
|
46
50
|
style="background-color: {backgroundColor};color: {color};opacity: {opacity}"
|
@@ -63,6 +67,6 @@
|
|
63
67
|
</div>
|
64
68
|
{/if}
|
65
69
|
<div class="cursor-image-wrapper">
|
66
|
-
<img class="netless-window-manager-cursor-{appliance}-image" {src} alt={appliance} />
|
70
|
+
<img class="netless-window-manager-cursor-{appliance}-image {pencilEraserSize3ImageOffset}" {src} alt={appliance} />
|
67
71
|
</div>
|
68
72
|
</div>
|
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;
|
@@ -30,7 +31,7 @@ export class Cursor {
|
|
30
31
|
|
31
32
|
public move = (position: Position) => {
|
32
33
|
if (position.type === "main") {
|
33
|
-
const rect = this.
|
34
|
+
const rect = this.manager.boxManager?.stageRect;
|
34
35
|
if (this.component && rect) {
|
35
36
|
this.autoHidden();
|
36
37
|
this.moveCursor(position, rect, this.manager.mainView);
|
@@ -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 });
|
@@ -153,13 +157,20 @@ export class Cursor {
|
|
153
157
|
cursorTagBackgroundColor: this.memberCursorTagBackgroundColor,
|
154
158
|
opacity: this.memberOpacity,
|
155
159
|
tagName: this.memberTagName,
|
160
|
+
pencilEraserSize: this.member?.memberState.pencilEraserSize,
|
156
161
|
};
|
157
162
|
}
|
158
163
|
|
159
164
|
private getIcon() {
|
160
165
|
if (this.member) {
|
161
166
|
const icons = this.cursorManager.applianceIcons;
|
162
|
-
|
167
|
+
let applianceSrc;
|
168
|
+
if (this.memberApplianceName === ApplianceNames.pencilEraser) {
|
169
|
+
const size = this.member?.memberState.pencilEraserSize || 1;
|
170
|
+
applianceSrc = icons[`${this.memberApplianceName}${size}`];
|
171
|
+
} else {
|
172
|
+
applianceSrc = icons[this.memberApplianceName || ApplianceNames.shape];
|
173
|
+
}
|
163
174
|
return applianceSrc || icons[ApplianceNames.shape];
|
164
175
|
}
|
165
176
|
}
|
package/src/Cursor/icons.ts
CHANGED
@@ -5,6 +5,9 @@ import eraser from "../image/eraser-cursor.png";
|
|
5
5
|
import shape from "../image/shape-cursor.svg";
|
6
6
|
import text from "../image/text-cursor.svg";
|
7
7
|
import laser from "../image/laser-pointer-cursor.svg";
|
8
|
+
import pencilEraser1 from "../image/pencil-eraser-1.svg";
|
9
|
+
import pencilEraser2 from "../image/pencil-eraser-2.svg";
|
10
|
+
import pencilEraser3 from "../image/pencil-eraser-3.svg";
|
8
11
|
|
9
12
|
export const ApplianceMap: {
|
10
13
|
[key: string]: string;
|
@@ -15,4 +18,7 @@ export const ApplianceMap: {
|
|
15
18
|
[ApplianceNames.shape]: shape,
|
16
19
|
[ApplianceNames.text]: text,
|
17
20
|
[ApplianceNames.laserPointer]: laser,
|
21
|
+
["pencilEraser1"]: pencilEraser1,
|
22
|
+
["pencilEraser2"]: pencilEraser2,
|
23
|
+
["pencilEraser3"]: pencilEraser3,
|
18
24
|
};
|
package/src/Cursor/index.ts
CHANGED
@@ -5,11 +5,12 @@ 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";
|
12
12
|
import { ApplianceMap } from "./icons";
|
13
|
+
import { findMemberByUid } from "../Helper";
|
13
14
|
|
14
15
|
export type EventType = {
|
15
16
|
type: PositionType;
|
@@ -23,8 +24,8 @@ export type MoveCursorParams = {
|
|
23
24
|
};
|
24
25
|
|
25
26
|
export class CursorManager {
|
26
|
-
public
|
27
|
-
public
|
27
|
+
public wrapperRect?: TeleBoxRect;
|
28
|
+
public playgroundRect?: DOMRect;
|
28
29
|
public cursorInstances: Map<string, Cursor> = new Map();
|
29
30
|
public roomMembers?: readonly RoomMember[];
|
30
31
|
private mainViewElement?: HTMLDivElement;
|
@@ -32,9 +33,13 @@ export class CursorManager {
|
|
32
33
|
private store = this.manager.store;
|
33
34
|
public applianceIcons: ApplianceIcons = ApplianceMap;
|
34
35
|
|
36
|
+
public get playground$() {
|
37
|
+
return this.manager.windowManger.playground$;
|
38
|
+
}
|
39
|
+
|
35
40
|
constructor(private manager: AppManager, private enableCursor: boolean, applianceIcons?: ApplianceIcons) {
|
36
41
|
this.roomMembers = this.manager.room?.state.roomMembers;
|
37
|
-
const playground =
|
42
|
+
const playground = this.playground$.value;
|
38
43
|
if (playground) {
|
39
44
|
this.setupWrapper(playground);
|
40
45
|
}
|
@@ -65,7 +70,7 @@ export class CursorManager {
|
|
65
70
|
private initCursorInstance = (uid: string) => {
|
66
71
|
let cursorInstance = this.cursorInstances.get(uid);
|
67
72
|
if (!cursorInstance) {
|
68
|
-
cursorInstance = new Cursor(this.manager, uid, this,
|
73
|
+
cursorInstance = new Cursor(this.manager, uid, this, this.playground$.value);
|
69
74
|
this.cursorInstances.set(uid, cursorInstance);
|
70
75
|
}
|
71
76
|
return cursorInstance;
|
@@ -89,8 +94,7 @@ export class CursorManager {
|
|
89
94
|
wrapper.removeEventListener("pointerleave", this.mouseLeaveListener);
|
90
95
|
};
|
91
96
|
});
|
92
|
-
|
93
|
-
this.wrapperRect = wrapper.getBoundingClientRect();
|
97
|
+
this.updateContainerRect();
|
94
98
|
}
|
95
99
|
|
96
100
|
public setMainViewDivElement(div: HTMLDivElement) {
|
@@ -110,10 +114,11 @@ export class CursorManager {
|
|
110
114
|
if (!event.isPrimary) return;
|
111
115
|
}
|
112
116
|
this.updateCursor(this.getType(event), event.clientX, event.clientY);
|
113
|
-
},
|
117
|
+
}, 48);
|
114
118
|
|
115
119
|
private updateCursor(event: EventType, clientX: number, clientY: number) {
|
116
|
-
|
120
|
+
const self = findMemberByUid(this.manager.room, this.manager.uid);
|
121
|
+
if (this.wrapperRect && this.manager.canOperate && this.canMoveCursor(self)) {
|
117
122
|
const view = event.type === "main" ? this.manager.mainView : this.focusView;
|
118
123
|
const point = this.getPoint(view, clientX, clientY);
|
119
124
|
if (point) {
|
@@ -168,8 +173,8 @@ export class CursorManager {
|
|
168
173
|
};
|
169
174
|
|
170
175
|
public updateContainerRect() {
|
171
|
-
this.
|
172
|
-
this.
|
176
|
+
this.wrapperRect = this.manager.boxManager?.stageRect;
|
177
|
+
this.playgroundRect = WindowManager.playground?.getBoundingClientRect();
|
173
178
|
}
|
174
179
|
|
175
180
|
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,6 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
2
|
import type { TeleBoxRect } from "@netless/telebox-insider";
|
3
|
-
import type {
|
4
|
-
import type { Member } from "./Helper";
|
3
|
+
import type { CursorMovePayload } from "./index";
|
5
4
|
import type { MemberState } from "white-web-sdk";
|
6
5
|
|
7
6
|
export type RemoveSceneParams = {
|
@@ -11,7 +10,6 @@ export type RemoveSceneParams = {
|
|
11
10
|
|
12
11
|
export type EmitterEvent = {
|
13
12
|
onCreated: undefined;
|
14
|
-
InitReplay: AppInitState;
|
15
13
|
error: Error;
|
16
14
|
seekStart: undefined;
|
17
15
|
seek: number;
|
@@ -31,7 +29,6 @@ export type EmitterEvent = {
|
|
31
29
|
changePageState: undefined;
|
32
30
|
writableChange: boolean;
|
33
31
|
containerSizeRatioUpdate: number;
|
34
|
-
roomMembersChange: Member[];
|
35
32
|
memberStateChange: MemberState;
|
36
33
|
};
|
37
34
|
|
@@ -2,17 +2,19 @@ import type { SceneDefinition } from "white-web-sdk";
|
|
2
2
|
|
3
3
|
export type AddPageParams = {
|
4
4
|
after?: boolean;
|
5
|
-
scene?: SceneDefinition;
|
5
|
+
scene?: SceneDefinition | SceneDefinition[];
|
6
6
|
};
|
7
7
|
|
8
8
|
export type PageState = {
|
9
9
|
index: number;
|
10
10
|
length: number;
|
11
|
+
pages: string[];
|
11
12
|
};
|
12
13
|
|
13
14
|
export interface PageController {
|
14
15
|
nextPage: () => Promise<boolean>;
|
15
16
|
prevPage: () => Promise<boolean>;
|
17
|
+
jumpPage: (index: number) => Promise<boolean>;
|
16
18
|
addPage: (params?: AddPageParams) => Promise<void>;
|
17
19
|
removePage: (index: number) => Promise<boolean>;
|
18
20
|
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
|
|
@@ -18,11 +18,18 @@ export class PageStateImpl {
|
|
18
18
|
return this.manager?.mainViewScenesLength || 0;
|
19
19
|
}
|
20
20
|
|
21
|
+
public getPages() {
|
22
|
+
return this.manager.callbacksNode?.scenes.map(sceneName => {
|
23
|
+
return `${this.manager.callbacksNode?.path}${sceneName}`;
|
24
|
+
}) || [];
|
25
|
+
}
|
26
|
+
|
21
27
|
public toObject(): PageState {
|
22
28
|
const index = this.index >= this.length ? this.length - 1 : this.index;
|
23
29
|
return {
|
24
30
|
index,
|
25
31
|
length: this.length,
|
32
|
+
pages: this.getPages(),
|
26
33
|
};
|
27
34
|
}
|
28
35
|
}
|
@@ -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");
|
@@ -79,7 +83,7 @@ export class ReconnectRefresher {
|
|
79
83
|
this._onReconnected();
|
80
84
|
}
|
81
85
|
|
82
|
-
public add(id: string, func: any) {
|
86
|
+
public add(id: string, func: any): () => void {
|
83
87
|
const disposer = this.disposers.get(id);
|
84
88
|
if (disposer && isFunction(disposer)) {
|
85
89
|
disposer();
|