@netless/window-manager 0.4.0-canary.8 → 0.4.1

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 +23 -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 +34 -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 +7 -8
  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 +28 -8
  45. package/src/AppManager.ts +244 -71
  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 +44 -14
  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 +152 -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 +5 -2
  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.13.16";
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>;
@@ -149,10 +147,17 @@ export type PublicEvent = {
149
147
  darkModeChange: boolean;
150
148
  prefersColorSchemeChange: TeleBoxColorScheme;
151
149
  cameraStateChange: CameraState;
150
+ mainViewScenePathChange: string;
151
+ mainViewSceneIndexChange: number;
152
+ focusedChange: string | undefined;
153
+ mainViewScenesLengthChange: number;
154
+ canRedoStepsChange: number;
155
+ canUndoStepsChange: number;
156
+ loadApp: LoadAppEvent;
152
157
  };
153
158
 
154
159
  export type MountParams = {
155
- room: Room;
160
+ room: Room | Player;
156
161
  container?: HTMLElement;
157
162
  /** 白板高宽比例, 默认为 9 / 16 */
158
163
  containerSizeRatio?: number;
@@ -183,6 +188,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
183
188
  private static isCreated = false;
184
189
 
185
190
  public version = __APP_VERSION__;
191
+ public dependencies = __APP_DEPENDENCIES__;
186
192
 
187
193
  public appListeners?: AppListeners;
188
194
 
@@ -201,6 +207,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
201
207
  constructor(context: InvisiblePluginContext) {
202
208
  super(context);
203
209
  WindowManager.displayer = context.displayer;
210
+ (window as any).NETLESS_DEPS = __APP_DEPENDENCIES__;
204
211
  }
205
212
 
206
213
  public static async mount(params: MountParams): Promise<WindowManager> {
@@ -212,16 +219,22 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
212
219
  const cursor = params.cursor;
213
220
  WindowManager.params = params;
214
221
 
215
- this.checkVersion();
222
+ checkVersion();
223
+ let manager: WindowManager | undefined = undefined;
216
224
  if (isRoom(room)) {
217
225
  if (room.phase !== RoomPhase.Connected) {
218
226
  throw new Error("[WindowManager]: Room only Connected can be mount");
219
227
  }
228
+ if (room.phase === RoomPhase.Connected && room.isWritable) {
229
+ // redo undo 需要设置这个属性
230
+ room.disableSerialization = false;
231
+ }
232
+ manager = await this.initManager(room);
220
233
  }
221
234
  if (WindowManager.isCreated) {
222
235
  throw new Error("[WindowManager]: Already created cannot be created again");
223
236
  }
224
- let manager = await this.initManager(room);
237
+
225
238
  this.debug = Boolean(debug);
226
239
  log("Already insert room", manager);
227
240
 
@@ -232,7 +245,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
232
245
  } else {
233
246
  await pRetry(
234
247
  async count => {
235
- manager = await this.initManager(room);
248
+ manager = (await room.getInvisiblePlugin(WindowManager.kind)) as WindowManager;
236
249
  if (!manager) {
237
250
  log(`manager is empty. retrying ${count}`);
238
251
  throw new Error();
@@ -242,16 +255,17 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
242
255
  );
243
256
  }
244
257
 
258
+ if (!manager) {
259
+ throw new Error("[WindowManager]: create manager failed");
260
+ }
261
+
245
262
  if (containerSizeRatio) {
246
263
  WindowManager.containerSizeRatio = containerSizeRatio;
247
264
  }
248
265
  await manager.ensureAttributes();
249
266
 
250
267
  manager.appManager = new AppManager(manager);
251
-
252
- if (cursor) {
253
- manager.cursorManager = new CursorManager(manager.appManager);
254
- }
268
+ manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor));
255
269
 
256
270
  if (params.container) {
257
271
  manager.bindContainer(params.container);
@@ -357,6 +371,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
357
371
  this.appManager?.refresh();
358
372
  this.appManager?.resetMaximized();
359
373
  this.appManager?.resetMinimized();
374
+ this.appManager?.displayerWritableListener(!this.room.isWritable);
360
375
  WindowManager.container = container;
361
376
  }
362
377
 
@@ -420,6 +435,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
420
435
  const appScenePath = appManager.store.getAppScenePath(appId);
421
436
  if (appScenePath && appScenePath === scenePath) {
422
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
+ }
423
444
  return;
424
445
  }
425
446
  }
@@ -427,11 +448,11 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
427
448
  if (scenePath && scenes && scenes.length > 0) {
428
449
  if (this.isDynamicPPT(scenes)) {
429
450
  isDynamicPPT = true;
430
- if (!this.displayer.entireScenes()[scenePath]) {
451
+ if (!entireScenes(this.displayer)[scenePath]) {
431
452
  this.room?.putScenes(scenePath, scenes);
432
453
  }
433
454
  } else {
434
- if (!this.displayer.entireScenes()[scenePath]) {
455
+ if (!entireScenes(this.displayer)[scenePath]) {
435
456
  this.room?.putScenes(scenePath, [{ name: scenes[0].name }]);
436
457
  }
437
458
  }
@@ -464,7 +485,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
464
485
  /**
465
486
  * 返回 mainView 的 ScenePath
466
487
  */
467
- public getMainViewScenePath(): string {
488
+ public getMainViewScenePath(): string | undefined {
468
489
  return this.appManager?.store.getMainViewScenePath();
469
490
  }
470
491
 
@@ -512,6 +533,35 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
512
533
  this.viewMode = mode;
513
534
  }
514
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
+
515
565
  public get mainView(): View {
516
566
  if (this.appManager) {
517
567
  return this.appManager.mainViewProxy.view;
@@ -560,6 +610,48 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
560
610
  }
561
611
  }
562
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
+
563
655
  /**
564
656
  * 查询所有的 App
565
657
  */
@@ -584,7 +676,14 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
584
676
  public moveCamera(
585
677
  camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }
586
678
  ): void {
679
+ const pureCamera = omit(camera, ["animationMode"]);
680
+ const mainViewCamera = { ...this.mainView.camera };
681
+ if (isEqual({ ...mainViewCamera, ...pureCamera }, mainViewCamera)) return;
587
682
  this.mainView.moveCamera(camera);
683
+ this.appManager?.dispatchInternalEvent(Events.MoveCamera, camera);
684
+ setTimeout(() => {
685
+ this.appManager?.mainViewProxy.setCameraAndSize();
686
+ }, 100);
588
687
  }
589
688
 
590
689
  public moveCameraToContain(
@@ -597,7 +696,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
597
696
  this.appManager?.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
598
697
  setTimeout(() => {
599
698
  this.appManager?.mainViewProxy.setCameraAndSize();
600
- }, 1000);
699
+ }, 100);
601
700
  }
602
701
 
603
702
  public convertToPointInWorld(point: Point): Point {
@@ -668,18 +767,38 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
668
767
  this.appManager?.boxManager?.setPrefersColorScheme(scheme);
669
768
  }
670
769
 
671
- private isDynamicPPT(scenes: SceneDefinition[]) {
672
- const sceneSrc = scenes[0]?.ppt?.src;
673
- 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
+ }
674
786
  }
675
787
 
676
- private static checkVersion() {
677
- const version = getVersionNumber(WhiteVersion);
678
- if (version < getVersionNumber(REQUIRE_VERSION)) {
679
- 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();
680
794
  }
681
795
  }
682
796
 
797
+ private isDynamicPPT(scenes: SceneDefinition[]) {
798
+ const sceneSrc = scenes[0]?.ppt?.src;
799
+ return sceneSrc?.startsWith("pptx://");
800
+ }
801
+
683
802
  private async ensureAttributes() {
684
803
  if (isNull(this.attributes)) {
685
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,7 +1,7 @@
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"
4
+ import { dependencies, peerDependencies, version, devDependencies } from "./package.json"
5
5
 
6
6
 
7
7
  export default defineConfig(({ mode }) => {
@@ -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
  },
@@ -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
- }