@netless/window-manager 0.4.0-canary.9 → 0.4.2

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.
Files changed (74) hide show
  1. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/.idea/window-manager.iml +12 -0
  5. package/.vscode/settings.json +1 -0
  6. package/CHANGELOG.md +43 -2
  7. package/README.md +3 -0
  8. package/dist/App/MagixEvent/index.d.ts +29 -0
  9. package/dist/App/Storage/index.d.ts +19 -6
  10. package/dist/App/Storage/typings.d.ts +1 -0
  11. package/dist/AppContext.d.ts +39 -17
  12. package/dist/AppListener.d.ts +2 -0
  13. package/dist/AppManager.d.ts +22 -8
  14. package/dist/AppProxy.d.ts +5 -5
  15. package/dist/AttributesDelegate.d.ts +2 -2
  16. package/dist/BoxManager.d.ts +6 -4
  17. package/dist/BuiltinApps.d.ts +0 -1
  18. package/dist/Cursor/Cursor.d.ts +10 -12
  19. package/dist/Cursor/index.d.ts +6 -16
  20. package/dist/Helper.d.ts +1 -0
  21. package/dist/Register/index.d.ts +5 -0
  22. package/dist/Register/storage.d.ts +5 -1
  23. package/dist/Utils/AppCreateQueue.d.ts +11 -0
  24. package/dist/Utils/Common.d.ts +4 -1
  25. package/dist/Utils/RoomHacker.d.ts +3 -3
  26. package/dist/View/MainView.d.ts +4 -3
  27. package/dist/constants.d.ts +5 -2
  28. package/dist/index.d.ts +32 -6
  29. package/dist/index.es.js +41 -1
  30. package/dist/index.es.js.map +1 -1
  31. package/dist/index.umd.js +41 -1
  32. package/dist/index.umd.js.map +1 -1
  33. package/dist/style.css +1 -1
  34. package/dist/typings.d.ts +2 -2
  35. package/docs/advanced.md +53 -0
  36. package/docs/api.md +79 -6
  37. package/docs/concept.md +9 -0
  38. package/docs/replay.md +40 -0
  39. package/package.json +8 -9
  40. package/src/App/MagixEvent/index.ts +68 -0
  41. package/src/App/Storage/index.ts +89 -43
  42. package/src/App/Storage/typings.ts +4 -2
  43. package/src/AppContext.ts +61 -24
  44. package/src/AppListener.ts +27 -8
  45. package/src/AppManager.ts +231 -70
  46. package/src/AppProxy.ts +40 -29
  47. package/src/AttributesDelegate.ts +2 -2
  48. package/src/BoxManager.ts +33 -19
  49. package/src/BuiltinApps.ts +0 -1
  50. package/src/ContainerResizeObserver.ts +3 -3
  51. package/src/Cursor/Cursor.svelte +25 -21
  52. package/src/Cursor/Cursor.ts +25 -38
  53. package/src/Cursor/icons.ts +2 -0
  54. package/src/Cursor/index.ts +45 -139
  55. package/src/Helper.ts +12 -1
  56. package/src/Register/index.ts +32 -17
  57. package/src/Register/loader.ts +28 -13
  58. package/src/Register/storage.ts +6 -1
  59. package/src/Utils/AppCreateQueue.ts +54 -0
  60. package/src/Utils/Common.ts +35 -2
  61. package/src/Utils/RoomHacker.ts +33 -18
  62. package/src/View/MainView.ts +19 -12
  63. package/src/View/ViewManager.ts +1 -2
  64. package/src/constants.ts +6 -2
  65. package/src/image/laser-pointer-cursor.svg +17 -0
  66. package/src/index.ts +150 -33
  67. package/src/shim.d.ts +2 -1
  68. package/src/style.css +6 -1
  69. package/src/typings.ts +2 -2
  70. package/vite.config.js +7 -4
  71. package/dist/Base/Context.d.ts +0 -12
  72. package/dist/Base/index.d.ts +0 -7
  73. package/src/Base/Context.ts +0 -45
  74. package/src/Base/index.ts +0 -10
@@ -1,5 +1,4 @@
1
1
  import { AnimationMode, reaction } from "white-web-sdk";
2
- import { Base } from "../Base";
3
2
  import { callbacks, emitter } from "../index";
4
3
  import { createView } from "./ViewManager";
5
4
  import { debounce, isEmpty, isEqual } from "lodash";
@@ -9,20 +8,20 @@ import { SideEffectManager } from "side-effect-manager";
9
8
  import type { Camera, Size, View } from "white-web-sdk";
10
9
  import type { AppManager } from "../AppManager";
11
10
 
12
- export class MainViewProxy extends Base {
11
+ export class MainViewProxy {
13
12
  private scale?: number;
14
13
  private started = false;
15
14
  private mainViewIsAddListener = false;
16
15
  private mainView: View;
17
- private viewId = "mainView";
16
+ private store = this.manager.store;
18
17
 
19
18
  private sideEffectManager = new SideEffectManager();
20
19
 
21
- constructor(manager: AppManager) {
22
- super(manager);
20
+ constructor(private manager: AppManager) {
23
21
  this.mainView = this.createMainView();
24
22
  this.moveCameraSizeByAttributes();
25
23
  emitter.once("mainViewMounted").then(() => {
24
+ this.addMainViewListener();
26
25
  setTimeout(() => {
27
26
  this.start();
28
27
  if (!this.mainViewCamera || !this.mainViewSize) {
@@ -61,15 +60,15 @@ export class MainViewProxy extends Base {
61
60
  }
62
61
 
63
62
  public setCameraAndSize(): void {
64
- this.store.setMainViewCamera({ ...this.mainView.camera, id: this.context.uid });
65
- this.store.setMainViewSize({ ...this.mainView.size, id: this.context.uid });
63
+ this.store.setMainViewCamera({ ...this.mainView.camera, id: this.manager.uid });
64
+ this.store.setMainViewSize({ ...this.mainView.size, id: this.manager.uid });
66
65
  }
67
66
 
68
67
  private cameraReaction = () => {
69
68
  return reaction(
70
69
  () => this.mainViewCamera,
71
70
  camera => {
72
- if (camera && camera.id !== this.context.uid) {
71
+ if (camera && camera.id !== this.manager.uid) {
73
72
  this.moveCameraToContian(this.mainViewSize);
74
73
  this.moveCamera(camera);
75
74
  }
@@ -104,9 +103,16 @@ export class MainViewProxy extends Base {
104
103
  return mainView;
105
104
  }
106
105
 
106
+ public onReconnect(): void {
107
+ const mainViewScenePath = this.store.getMainViewScenePath();
108
+ if (mainViewScenePath) {
109
+ setViewFocusScenePath(this.view, mainViewScenePath);
110
+ }
111
+ }
112
+
107
113
  private onCameraUpdatedByDevice = (camera: Camera) => {
108
- this.store.setMainViewCamera({ ...camera, id: this.context.uid });
109
- if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.context.uid })) {
114
+ this.store.setMainViewCamera({ ...camera, id: this.manager.uid });
115
+ if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.manager.uid })) {
110
116
  this.setMainViewSize(this.view.size);
111
117
  }
112
118
  };
@@ -134,11 +140,11 @@ export class MainViewProxy extends Base {
134
140
  public async mainViewClickHandler(): Promise<void> {
135
141
  if (!this.manager.canOperate) return;
136
142
  this.store.cleanFocus();
137
- this.context.blurFocusBox();
143
+ this.manager.boxManager?.blurAllBox();
138
144
  }
139
145
 
140
146
  public setMainViewSize = debounce(size => {
141
- this.store.setMainViewSize({ ...size, id: this.context.uid });
147
+ this.store.setMainViewSize({ ...size, id: this.manager.uid });
142
148
  }, 50);
143
149
 
144
150
  private addCameraListener() {
@@ -185,6 +191,7 @@ export class MainViewProxy extends Base {
185
191
  }
186
192
 
187
193
  public stop() {
194
+ this.removeMainViewListener();
188
195
  this.removeCameraListener();
189
196
  this.manager.refresher?.remove(Fields.MainViewCamera);
190
197
  this.manager.refresher?.remove(Fields.MainViewSize);
@@ -1,4 +1,4 @@
1
- import type { View , Displayer} from "white-web-sdk";
1
+ import type { View, Displayer } from "white-web-sdk";
2
2
 
3
3
  export class ViewManager {
4
4
  public views: Map<string, View> = new Map();
@@ -38,7 +38,6 @@ export class ViewManager {
38
38
  }
39
39
  }
40
40
 
41
-
42
41
  export const createView = (displayer: Displayer): View => {
43
42
  const view = displayer.views.createView();
44
43
  setDefaultCameraBound(view);
package/src/constants.ts CHANGED
@@ -10,7 +10,9 @@ export enum Events {
10
10
  SetMainViewScenePath = "SetMainViewScenePath",
11
11
  SetMainViewSceneIndex = "SetMainViewSceneIndex",
12
12
  SwitchViewsToFreedom = "SwitchViewsToFreedom",
13
- MoveCameraToContain = "MoveCameraToContain"
13
+ MoveCamera = "MoveCamera",
14
+ MoveCameraToContain = "MoveCameraToContain",
15
+ CursorMove = "CursorMove",
14
16
  }
15
17
 
16
18
  export const MagixEventName = "__WindowManger";
@@ -37,7 +39,7 @@ export enum CursorState {
37
39
  Normal = "normal",
38
40
  }
39
41
 
40
- export const REQUIRE_VERSION = "2.16.0";
42
+ export const REQUIRE_VERSION = "2.16.1";
41
43
 
42
44
  export const MIN_WIDTH = 340 / 720;
43
45
  export const MIN_HEIGHT = 340 / 720;
@@ -45,3 +47,5 @@ export const MIN_HEIGHT = 340 / 720;
45
47
  export const SET_SCENEPATH_DELAY = 100; // 设置 scenePath 的延迟事件
46
48
 
47
49
  export const DEFAULT_CONTAINER_RATIO = 9 / 16;
50
+
51
+ export const ROOT_DIR = "/";
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com -->
4
+ <title>编组 2</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs>
7
+ <filter x="-120.0%" y="-120.0%" width="340.0%" height="340.0%" filterUnits="objectBoundingBox" id="filter-1">
8
+ <feGaussianBlur stdDeviation="4" in="SourceGraphic"></feGaussianBlur>
9
+ </filter>
10
+ </defs>
11
+ <g id="页面1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
12
+ <g id="编组-2" transform="translate(9.000000, 9.000000)" fill="#FF0100">
13
+ <circle id="椭圆形" filter="url(#filter-1)" cx="5" cy="5" r="5"></circle>
14
+ <path d="M5,8 C6.65685425,8 8,6.65685425 8,5 C8,3.34314575 6.65685425,2 5,2 C3.34314575,2 2,3.34314575 2,5 C2,6.65685425 3.34314575,8 5,8 Z M5,6.28571429 C4.28991961,6.28571429 3.71428571,5.71008039 3.71428571,5 C3.71428571,4.28991961 4.28991961,3.71428571 5,3.71428571 C5.71008039,3.71428571 6.28571429,4.28991961 6.28571429,5 C6.28571429,5.71008039 5.71008039,6.28571429 5,6.28571429 Z" id="椭圆形" fill-rule="nonzero"></path>
15
+ </g>
16
+ </g>
17
+ </svg>
package/src/index.ts CHANGED
@@ -2,24 +2,26 @@ import Emittery from "emittery";
2
2
  import pRetry from "p-retry";
3
3
  import { AppManager } from "./AppManager";
4
4
  import { appRegister } from "./Register";
5
+ import { checkVersion, setupWrapper } from "./Helper";
5
6
  import { ContainerResizeObserver } from "./ContainerResizeObserver";
6
7
  import { createBoxManager } from "./BoxManager";
7
8
  import { CursorManager } from "./Cursor";
8
- import { DEFAULT_CONTAINER_RATIO, Events, REQUIRE_VERSION } from "./constants";
9
+ import { DEFAULT_CONTAINER_RATIO, Events } from "./constants";
9
10
  import { Fields } from "./AttributesDelegate";
10
11
  import { initDb } from "./Register/storage";
11
- import { isNull, isObject } from "lodash";
12
+ import { InvisiblePlugin, isPlayer, isRoom, RoomPhase, ViewMode } from "white-web-sdk";
13
+ import { isEqual, isNull, isObject, omit } from "lodash";
12
14
  import { log } from "./Utils/log";
13
15
  import { ReconnectRefresher } from "./ReconnectRefresher";
14
16
  import { replaceRoomFunction } from "./Utils/RoomHacker";
15
17
  import { setupBuiltin } from "./BuiltinApps";
16
- import { setupWrapper } from "./Helper";
17
18
  import "./style.css";
18
19
  import "@netless/telebox-insider/dist/style.css";
20
+ import type { LoadAppEvent } from "./Register";
19
21
  import {
20
22
  addEmitterOnceListener,
21
23
  ensureValidScenePath,
22
- getVersionNumber,
24
+ entireScenes,
23
25
  isValidScenePath,
24
26
  wait,
25
27
  } from "./Utils/Common";
@@ -29,17 +31,8 @@ import {
29
31
  AppManagerNotInitError,
30
32
  InvalidScenePath,
31
33
  ParamsInvalidError,
32
- WhiteWebSDKInvalidError,
33
34
  } from "./Utils/error";
34
- import type { Apps } from "./AttributesDelegate";
35
- import {
36
- InvisiblePlugin,
37
- isPlayer,
38
- isRoom,
39
- RoomPhase,
40
- ViewMode,
41
- WhiteVersion,
42
- } from "white-web-sdk";
35
+ import type { Apps, Position } from "./AttributesDelegate";
43
36
  import type {
44
37
  Displayer,
45
38
  SceneDefinition,
@@ -53,6 +46,7 @@ import type {
53
46
  Rectangle,
54
47
  ViewVisionMode,
55
48
  CameraState,
49
+ Player,
56
50
  } from "white-web-sdk";
57
51
  import type { AppListeners } from "./AppListener";
58
52
  import type { NetlessApp, RegisterParams } from "./typings";
@@ -124,6 +118,8 @@ export type AppInitState = {
124
118
  zIndex?: number;
125
119
  };
126
120
 
121
+ export type CursorMovePayload = { uid: string; state?: "leave"; position: Position };
122
+
127
123
  export type EmitterEvent = {
128
124
  onCreated: undefined;
129
125
  InitReplay: AppInitState;
@@ -138,6 +134,8 @@ export type EmitterEvent = {
138
134
  boxStateChange: string;
139
135
  playgroundSizeChange: DOMRect;
140
136
  onReconnected: void;
137
+ removeScenes: string;
138
+ cursorMove: CursorMovePayload;
141
139
  };
142
140
 
143
141
  export type EmitterType = Emittery<EmitterEvent>;
@@ -151,10 +149,15 @@ export type PublicEvent = {
151
149
  cameraStateChange: CameraState;
152
150
  mainViewScenePathChange: string;
153
151
  mainViewSceneIndexChange: number;
152
+ focusedChange: string | undefined;
153
+ mainViewScenesLengthChange: number;
154
+ canRedoStepsChange: number;
155
+ canUndoStepsChange: number;
156
+ loadApp: LoadAppEvent;
154
157
  };
155
158
 
156
159
  export type MountParams = {
157
- room: Room;
160
+ room: Room | Player;
158
161
  container?: HTMLElement;
159
162
  /** 白板高宽比例, 默认为 9 / 16 */
160
163
  containerSizeRatio?: number;
@@ -185,6 +188,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
185
188
  private static isCreated = false;
186
189
 
187
190
  public version = __APP_VERSION__;
191
+ public dependencies = __APP_DEPENDENCIES__;
188
192
 
189
193
  public appListeners?: AppListeners;
190
194
 
@@ -203,6 +207,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
203
207
  constructor(context: InvisiblePluginContext) {
204
208
  super(context);
205
209
  WindowManager.displayer = context.displayer;
210
+ (window as any).NETLESS_DEPS = __APP_DEPENDENCIES__;
206
211
  }
207
212
 
208
213
  public static async mount(params: MountParams): Promise<WindowManager> {
@@ -214,16 +219,22 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
214
219
  const cursor = params.cursor;
215
220
  WindowManager.params = params;
216
221
 
217
- this.checkVersion();
222
+ checkVersion();
223
+ let manager: WindowManager | undefined = undefined;
218
224
  if (isRoom(room)) {
219
225
  if (room.phase !== RoomPhase.Connected) {
220
226
  throw new Error("[WindowManager]: Room only Connected can be mount");
221
227
  }
228
+ if (room.phase === RoomPhase.Connected && room.isWritable) {
229
+ // redo undo 需要设置这个属性
230
+ room.disableSerialization = false;
231
+ }
232
+ manager = await this.initManager(room);
222
233
  }
223
234
  if (WindowManager.isCreated) {
224
235
  throw new Error("[WindowManager]: Already created cannot be created again");
225
236
  }
226
- let manager = await this.initManager(room);
237
+
227
238
  this.debug = Boolean(debug);
228
239
  log("Already insert room", manager);
229
240
 
@@ -234,7 +245,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
234
245
  } else {
235
246
  await pRetry(
236
247
  async count => {
237
- manager = await this.initManager(room);
248
+ manager = (await room.getInvisiblePlugin(WindowManager.kind)) as WindowManager;
238
249
  if (!manager) {
239
250
  log(`manager is empty. retrying ${count}`);
240
251
  throw new Error();
@@ -244,16 +255,17 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
244
255
  );
245
256
  }
246
257
 
258
+ if (!manager) {
259
+ throw new Error("[WindowManager]: create manager failed");
260
+ }
261
+
247
262
  if (containerSizeRatio) {
248
263
  WindowManager.containerSizeRatio = containerSizeRatio;
249
264
  }
250
265
  await manager.ensureAttributes();
251
266
 
252
267
  manager.appManager = new AppManager(manager);
253
-
254
- if (cursor) {
255
- manager.cursorManager = new CursorManager(manager.appManager);
256
- }
268
+ manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor));
257
269
 
258
270
  if (params.container) {
259
271
  manager.bindContainer(params.container);
@@ -359,6 +371,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
359
371
  this.appManager?.refresh();
360
372
  this.appManager?.resetMaximized();
361
373
  this.appManager?.resetMinimized();
374
+ this.appManager?.displayerWritableListener(!this.room.isWritable);
362
375
  WindowManager.container = container;
363
376
  }
364
377
 
@@ -422,6 +435,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
422
435
  const appScenePath = appManager.store.getAppScenePath(appId);
423
436
  if (appScenePath && appScenePath === scenePath) {
424
437
  console.warn(`[WindowManager]: ScenePath ${scenePath} Already opened`);
438
+ if (this.boxManager) {
439
+ const topBox = this.boxManager.getTopBox();
440
+ if (topBox) {
441
+ this.boxManager.setZIndex(appId, topBox.zIndex + 1, false);
442
+ }
443
+ }
425
444
  return;
426
445
  }
427
446
  }
@@ -429,11 +448,11 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
429
448
  if (scenePath && scenes && scenes.length > 0) {
430
449
  if (this.isDynamicPPT(scenes)) {
431
450
  isDynamicPPT = true;
432
- if (!this.displayer.entireScenes()[scenePath]) {
451
+ if (!entireScenes(this.displayer)[scenePath]) {
433
452
  this.room?.putScenes(scenePath, scenes);
434
453
  }
435
454
  } else {
436
- if (!this.displayer.entireScenes()[scenePath]) {
455
+ if (!entireScenes(this.displayer)[scenePath]) {
437
456
  this.room?.putScenes(scenePath, [{ name: scenes[0].name }]);
438
457
  }
439
458
  }
@@ -466,7 +485,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
466
485
  /**
467
486
  * 返回 mainView 的 ScenePath
468
487
  */
469
- public getMainViewScenePath(): string {
488
+ public getMainViewScenePath(): string | undefined {
470
489
  return this.appManager?.store.getMainViewScenePath();
471
490
  }
472
491
 
@@ -514,6 +533,35 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
514
533
  this.viewMode = mode;
515
534
  }
516
535
 
536
+ public setBoxState(boxState: TeleBoxState): void {
537
+ if (!this.canOperate) return;
538
+ switch (boxState) {
539
+ case "normal":
540
+ this.setMaximized(false);
541
+ this.setMinimized(false);
542
+ break;
543
+ case "maximized":
544
+ this.setMaximized(true);
545
+ this.setMinimized(false);
546
+ break;
547
+ case "minimized":
548
+ this.setMinimized(true);
549
+ break;
550
+ default:
551
+ break;
552
+ }
553
+ }
554
+
555
+ public setMaximized(maximized: boolean): void {
556
+ if (!this.canOperate) return;
557
+ this.boxManager?.setMaximized(maximized, false);
558
+ }
559
+
560
+ public setMinimized(minimized: boolean): void {
561
+ if (!this.canOperate) return;
562
+ this.boxManager?.setMinimized(minimized, false);
563
+ }
564
+
517
565
  public get mainView(): View {
518
566
  if (this.appManager) {
519
567
  return this.appManager.mainViewProxy.view;
@@ -562,6 +610,48 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
562
610
  }
563
611
  }
564
612
 
613
+ public get focused(): string | undefined {
614
+ return this.attributes.focus;
615
+ }
616
+
617
+ public get mainViewSceneIndex(): number {
618
+ return this.appManager?.store.getMainViewSceneIndex();
619
+ }
620
+
621
+ public get mainViewSceneDir(): string {
622
+ if (this.appManager) {
623
+ return this.appManager?.getMainViewSceneDir();
624
+ } else {
625
+ throw new AppManagerNotInitError();
626
+ }
627
+ }
628
+
629
+ public get topApp(): string | undefined {
630
+ return this.boxManager?.getTopBox()?.id;
631
+ }
632
+
633
+ public get mainViewScenesLength(): number {
634
+ return this.appManager?.mainViewScenesLength || 0;
635
+ }
636
+
637
+ public get canRedoSteps(): number {
638
+ const focused = this.focused;
639
+ if (focused) {
640
+ return this.appManager?.focusApp?.view?.canRedoSteps || 0;
641
+ } else {
642
+ return this.mainView.canRedoSteps;
643
+ }
644
+ }
645
+
646
+ public get canUndoSteps(): number {
647
+ const focused = this.focused;
648
+ if (focused) {
649
+ return this.appManager?.focusApp?.view?.canUndoSteps || 0;
650
+ } else {
651
+ return this.mainView.canUndoSteps;
652
+ }
653
+ }
654
+
565
655
  /**
566
656
  * 查询所有的 App
567
657
  */
@@ -586,7 +676,14 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
586
676
  public moveCamera(
587
677
  camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }
588
678
  ): void {
679
+ const pureCamera = omit(camera, ["animationMode"]);
680
+ const mainViewCamera = { ...this.mainView.camera };
681
+ if (isEqual({ ...mainViewCamera, ...pureCamera }, mainViewCamera)) return;
589
682
  this.mainView.moveCamera(camera);
683
+ this.appManager?.dispatchInternalEvent(Events.MoveCamera, camera);
684
+ setTimeout(() => {
685
+ this.appManager?.mainViewProxy.setCameraAndSize();
686
+ }, 500);
590
687
  }
591
688
 
592
689
  public moveCameraToContain(
@@ -599,7 +696,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
599
696
  this.appManager?.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
600
697
  setTimeout(() => {
601
698
  this.appManager?.mainViewProxy.setCameraAndSize();
602
- }, 1000);
699
+ }, 500);
603
700
  }
604
701
 
605
702
  public convertToPointInWorld(point: Point): Point {
@@ -670,18 +767,38 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
670
767
  this.appManager?.boxManager?.setPrefersColorScheme(scheme);
671
768
  }
672
769
 
673
- private isDynamicPPT(scenes: SceneDefinition[]) {
674
- const sceneSrc = scenes[0]?.ppt?.src;
675
- return sceneSrc?.startsWith("pptx://");
770
+ public cleanCurrentScene(): void {
771
+ const focused = this.focused;
772
+ if (focused) {
773
+ this.appManager?.focusApp?.view?.cleanCurrentScene();
774
+ } else {
775
+ this.mainView.cleanCurrentScene();
776
+ }
777
+ }
778
+
779
+ public redo(): number {
780
+ const focused = this.focused;
781
+ if (focused) {
782
+ return this.appManager?.focusApp?.view?.redo() || 0;
783
+ } else {
784
+ return this.mainView.redo();
785
+ }
676
786
  }
677
787
 
678
- private static checkVersion() {
679
- const version = getVersionNumber(WhiteVersion);
680
- if (version < getVersionNumber(REQUIRE_VERSION)) {
681
- throw new WhiteWebSDKInvalidError(REQUIRE_VERSION);
788
+ public undo(): number {
789
+ const focused = this.focused;
790
+ if (focused) {
791
+ return this.appManager?.focusApp?.view?.undo() || 0;
792
+ } else {
793
+ return this.mainView.undo();
682
794
  }
683
795
  }
684
796
 
797
+ private isDynamicPPT(scenes: SceneDefinition[]) {
798
+ const sceneSrc = scenes[0]?.ppt?.src;
799
+ return sceneSrc?.startsWith("pptx://");
800
+ }
801
+
685
802
  private async ensureAttributes() {
686
803
  if (isNull(this.attributes)) {
687
804
  await wait(50);
package/src/shim.d.ts CHANGED
@@ -7,4 +7,5 @@ declare module "*.svelte" {
7
7
 
8
8
  declare global {
9
9
  const __APP_VERSION__: string;
10
- }
10
+ const __APP_DEPENDENCIES__: Record<string, string>;
11
+ }
package/src/style.css CHANGED
@@ -122,7 +122,7 @@
122
122
  left: 0;
123
123
  top: 0;
124
124
  will-change: transform;
125
- transition: transform 0.05s;
125
+ transition: transform 0.1s;
126
126
  transform-origin: 0 0;
127
127
  user-select: none;
128
128
  }
@@ -153,6 +153,11 @@
153
153
  margin-top: 12px;
154
154
  }
155
155
 
156
+ .netless-window-manager-cursor-laserPointer-image {
157
+ margin-left: -22px;
158
+ margin-top: 3px;
159
+ }
160
+
156
161
  .netless-window-manager-cursor-name {
157
162
  width: 100%;
158
163
  height: 48px;
package/src/typings.ts CHANGED
@@ -12,7 +12,7 @@ import type {
12
12
  import type { AppContext } from "./AppContext";
13
13
  import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
14
14
 
15
- export interface NetlessApp<Attributes = any, SetupResult = any, AppOptions = any> {
15
+ export interface NetlessApp<Attributes = any, MagixEventPayloads = any, AppOptions = any, SetupResult = any> {
16
16
  kind: string;
17
17
  config?: {
18
18
  /** Box width relative to whiteboard. 0~1. Default 0.5. */
@@ -28,7 +28,7 @@ export interface NetlessApp<Attributes = any, SetupResult = any, AppOptions = an
28
28
  /** App only single instance. */
29
29
  singleton?: boolean;
30
30
  };
31
- setup: (context: AppContext<Attributes, AppOptions>) => SetupResult;
31
+ setup: (context: AppContext<Attributes, MagixEventPayloads, AppOptions>) => SetupResult;
32
32
  }
33
33
 
34
34
  export type AppEmitterEvent<T = any> = {
package/vite.config.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import path from "path";
2
2
  import { defineConfig } from "vite";
3
3
  import { svelte } from "@sveltejs/vite-plugin-svelte";
4
- import { dependencies ,peerDependencies, version } from "./package.json"
5
-
4
+ import { dependencies, peerDependencies, version, devDependencies } from "./package.json"
5
+ import { omit } from "lodash";
6
6
 
7
7
  export default defineConfig(({ mode }) => {
8
8
  const isProd = mode === "production";
@@ -10,6 +10,9 @@ export default defineConfig(({ mode }) => {
10
10
  return {
11
11
  define: {
12
12
  __APP_VERSION__: JSON.stringify(version),
13
+ __APP_DEPENDENCIES__: JSON.stringify({
14
+ dependencies, peerDependencies, devDependencies
15
+ }),
13
16
  },
14
17
  plugins: [
15
18
  svelte({
@@ -23,7 +26,7 @@ export default defineConfig(({ mode }) => {
23
26
  lib: {
24
27
  // eslint-disable-next-line no-undef
25
28
  entry: path.resolve(__dirname, "src/index.ts"),
26
- formats: ["es","umd"], // TODO cjs 版本待修复
29
+ formats: ["es", "umd"], // TODO cjs 版本待修复
27
30
  name: "WindowManager",
28
31
  fileName: "index"
29
32
  },
@@ -31,7 +34,7 @@ export default defineConfig(({ mode }) => {
31
34
  sourcemap: true,
32
35
  rollupOptions: {
33
36
  external: Object.keys({
34
- ...dependencies,
37
+ ...omit(dependencies, ["@netless/telebox-insider"]),
35
38
  ...peerDependencies,
36
39
  }),
37
40
  },
@@ -1,12 +0,0 @@
1
- import type { AppManager } from "../AppManager";
2
- export declare class Context {
3
- private manager;
4
- observerId: number;
5
- constructor(manager: AppManager);
6
- get uid(): string;
7
- findMember: (memberId: number) => import("white-web-sdk").RoomMember | undefined;
8
- findMemberByUid: (uid: string) => import("white-web-sdk").RoomMember | undefined;
9
- updateManagerRect(): void;
10
- blurFocusBox(): void;
11
- }
12
- export declare const createContext: (manager: AppManager) => Context;
@@ -1,7 +0,0 @@
1
- import type { AppManager } from "../AppManager";
2
- export declare class Base {
3
- manager: AppManager;
4
- store: import("../AttributesDelegate").AttributesDelegate;
5
- context: import("./Context").Context;
6
- constructor(manager: AppManager);
7
- }
@@ -1,45 +0,0 @@
1
- import { emitter } from "../index";
2
- import type { AppManager } from "../AppManager";
3
-
4
- export class Context {
5
- public observerId: number;
6
-
7
- constructor(private manager: AppManager) {
8
- this.observerId = manager.displayer.observerId;
9
-
10
- emitter.on("observerIdChange", id => {
11
- this.observerId = id;
12
- });
13
- };
14
-
15
- public get uid() {
16
- return this.manager.room?.uid || "";
17
- }
18
-
19
- public findMember = (memberId: number) => {
20
- const roomMembers = this.manager.room?.state.roomMembers;
21
- return roomMembers?.find(member => member.memberId === memberId);
22
- }
23
-
24
- public findMemberByUid = (uid: string) => {
25
- const roomMembers = this.manager.room?.state.roomMembers;
26
- return roomMembers?.find(member => member.payload?.uid === uid);
27
- }
28
-
29
- public updateManagerRect() {
30
- this.manager.boxManager?.updateManagerRect();
31
- }
32
-
33
- public blurFocusBox() {
34
- this.manager.boxManager?.blurAllBox();
35
- }
36
- }
37
-
38
- let context: Context;
39
-
40
- export const createContext = (manager: AppManager) => {
41
- if (!context) {
42
- context = new Context(manager);
43
- }
44
- return context;
45
- };
package/src/Base/index.ts DELETED
@@ -1,10 +0,0 @@
1
- import type { AppManager } from "../AppManager";
2
- import { store } from "../AttributesDelegate";
3
- import { createContext } from "./Context";
4
-
5
- export class Base {
6
- public store = store;
7
- public context = createContext(this.manager);
8
-
9
- constructor(public manager: AppManager) {}
10
- }