@netless/window-manager 1.0.0-canary.4 → 1.0.0-canary.42

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 (90) hide show
  1. package/dist/index.cjs.js +115 -34
  2. package/dist/index.es.js +7280 -9721
  3. package/dist/index.umd.js +115 -34
  4. package/dist/{App → src/App}/AppContext.d.ts +12 -7
  5. package/dist/{App → src/App}/AppPageStateImpl.d.ts +0 -0
  6. package/dist/{App → src/App}/AppProxy.d.ts +29 -11
  7. package/dist/{App → src/App}/MagixEvent/index.d.ts +0 -0
  8. package/dist/{App → src/App}/Storage/StorageEvent.d.ts +0 -0
  9. package/dist/{App → src/App}/Storage/index.d.ts +0 -0
  10. package/dist/{App → src/App}/Storage/typings.d.ts +0 -0
  11. package/dist/{App → src/App}/Storage/utils.d.ts +0 -0
  12. package/dist/src/App/WhiteboardView.d.ts +27 -0
  13. package/dist/{App → src/App}/index.d.ts +1 -0
  14. package/dist/src/App/type.d.ts +21 -0
  15. package/dist/{AppListener.d.ts → src/AppListener.d.ts} +2 -2
  16. package/dist/{AppManager.d.ts → src/AppManager.d.ts} +6 -5
  17. package/dist/{AttributesDelegate.d.ts → src/AttributesDelegate.d.ts} +5 -2
  18. package/dist/{BoxEmitter.d.ts → src/BoxEmitter.d.ts} +0 -0
  19. package/dist/{BoxManager.d.ts → src/BoxManager.d.ts} +12 -6
  20. package/dist/{BuiltinApps.d.ts → src/BuiltinApps.d.ts} +3 -0
  21. package/dist/{Cursor → src/Cursor}/Cursor.d.ts +0 -0
  22. package/dist/{Cursor → src/Cursor}/icons.d.ts +0 -0
  23. package/dist/{Cursor → src/Cursor}/index.d.ts +3 -3
  24. package/dist/{Helper.d.ts → src/Helper.d.ts} +4 -8
  25. package/dist/{InternalEmitter.d.ts → src/InternalEmitter.d.ts} +3 -4
  26. package/dist/{Page → src/Page}/PageController.d.ts +1 -0
  27. package/dist/{Page → src/Page}/index.d.ts +0 -0
  28. package/dist/{PageState.d.ts → src/PageState.d.ts} +0 -0
  29. package/dist/{ReconnectRefresher.d.ts → src/ReconnectRefresher.d.ts} +0 -0
  30. package/dist/{RedoUndo.d.ts → src/RedoUndo.d.ts} +0 -0
  31. package/dist/{Register → src/Register}/index.d.ts +0 -0
  32. package/dist/{Register → src/Register}/loader.d.ts +0 -0
  33. package/dist/{Register → src/Register}/storage.d.ts +0 -0
  34. package/dist/{Utils → src/Utils}/AppCreateQueue.d.ts +0 -0
  35. package/dist/{Utils → src/Utils}/Common.d.ts +0 -0
  36. package/dist/{Utils → src/Utils}/Reactive.d.ts +0 -0
  37. package/dist/{Utils → src/Utils}/RoomHacker.d.ts +0 -0
  38. package/dist/{Utils → src/Utils}/error.d.ts +1 -1
  39. package/dist/{Utils → src/Utils}/log.d.ts +0 -0
  40. package/dist/src/View/CameraSynchronizer.d.ts +19 -0
  41. package/dist/{View → src/View}/MainView.d.ts +18 -7
  42. package/dist/{View → src/View}/ViewManager.d.ts +0 -0
  43. package/dist/src/View/ViewSync.d.ts +24 -0
  44. package/dist/{callback.d.ts → src/callback.d.ts} +10 -1
  45. package/dist/{constants.d.ts → src/constants.d.ts} +10 -5
  46. package/dist/src/image.d.ts +19 -0
  47. package/dist/{index.d.ts → src/index.d.ts} +45 -13
  48. package/dist/src/shim.d.ts +11 -0
  49. package/dist/{typings.d.ts → src/typings.d.ts} +8 -2
  50. package/dist/style.css +1 -1
  51. package/docs/app-context.md +155 -27
  52. package/docs/mirgrate-to-1.0.md +39 -0
  53. package/package.json +23 -19
  54. package/playwright.config.ts +29 -0
  55. package/pnpm-lock.yaml +3078 -4412
  56. package/src/App/AppContext.ts +60 -28
  57. package/src/App/AppProxy.ts +235 -113
  58. package/src/App/WhiteboardView.ts +34 -12
  59. package/src/App/index.ts +1 -0
  60. package/src/App/type.ts +22 -0
  61. package/src/AppListener.ts +30 -21
  62. package/src/AppManager.ts +65 -43
  63. package/src/AttributesDelegate.ts +6 -3
  64. package/src/BoxManager.ts +76 -38
  65. package/src/BuiltinApps.ts +9 -8
  66. package/src/Cursor/Cursor.ts +7 -3
  67. package/src/Cursor/index.ts +7 -8
  68. package/src/Helper.ts +25 -7
  69. package/src/InternalEmitter.ts +3 -4
  70. package/src/Page/PageController.ts +1 -0
  71. package/src/PageState.ts +1 -1
  72. package/src/ReconnectRefresher.ts +6 -2
  73. package/src/Utils/Common.ts +3 -0
  74. package/src/Utils/Reactive.ts +27 -26
  75. package/src/Utils/RoomHacker.ts +3 -0
  76. package/src/Utils/error.ts +2 -2
  77. package/src/View/CameraSynchronizer.ts +41 -39
  78. package/src/View/MainView.ts +116 -75
  79. package/src/View/ViewSync.ts +103 -6
  80. package/src/callback.ts +6 -1
  81. package/src/constants.ts +8 -3
  82. package/src/index.ts +186 -58
  83. package/src/style.css +3 -46
  84. package/src/typings.ts +8 -2
  85. package/vite.config.js +8 -4
  86. package/dist/App/AppViewSync.d.ts +0 -11
  87. package/dist/App/WhiteboardView.d.ts +0 -21
  88. package/dist/View/CameraSynchronizer.d.ts +0 -17
  89. package/dist/View/ViewSync.d.ts +0 -7
  90. package/src/App/AppViewSync.ts +0 -69
package/src/index.ts CHANGED
@@ -2,21 +2,20 @@ import pRetry from "p-retry";
2
2
  import { AppManager } from "./AppManager";
3
3
  import { appRegister } from "./Register";
4
4
  import { callbacks } from "./callback";
5
- import { checkVersion, setupWrapper } from "./Helper";
5
+ import { checkVersion, createInvisiblePlugin, setupWrapper } from "./Helper";
6
6
  import { createBoxManager } from "./BoxManager";
7
7
  import { CursorManager } from "./Cursor";
8
8
  import { DEFAULT_CONTAINER_RATIO, Events, INIT_DIR, ROOT_DIR } from "./constants";
9
9
  import { emitter } from "./InternalEmitter";
10
10
  import { Fields } from "./AttributesDelegate";
11
11
  import { initDb } from "./Register/storage";
12
- import { InvisiblePlugin, isPlayer, isRoom, RoomPhase, ViewMode } from "white-web-sdk";
13
- import { isEqual, isNull, isObject, omit, isNumber } from "lodash";
12
+ import { AnimationMode, InvisiblePlugin, isPlayer, isRoom, RoomPhase, ViewMode } from "white-web-sdk";
13
+ import { isEqual, isNull, isObject, isNumber } from "lodash";
14
14
  import { log } from "./Utils/log";
15
15
  import { PageStateImpl } from "./PageState";
16
16
  import { ReconnectRefresher } from "./ReconnectRefresher";
17
17
  import { replaceRoomFunction } from "./Utils/RoomHacker";
18
18
  import { setupBuiltin } from "./BuiltinApps";
19
- import "video.js/dist/video-js.css";
20
19
  import "./style.css";
21
20
  import "@netless/telebox-insider/dist/style.css";
22
21
  import {
@@ -27,6 +26,8 @@ import {
27
26
  putScenes,
28
27
  wait,
29
28
  } from "./Utils/Common";
29
+ import { boxEmitter } from "./BoxEmitter";
30
+ import { Val } from "value-enhancer";
30
31
  import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
31
32
  import * as Errors from "./Utils/error";
32
33
  import type { Apps, Position , ICamera, ISize } from "./AttributesDelegate";
@@ -37,23 +38,22 @@ import type {
37
38
  Room,
38
39
  InvisiblePluginContext,
39
40
  Camera,
40
- AnimationMode,
41
41
  CameraBound,
42
42
  Point,
43
- Rectangle,
44
43
  CameraState,
45
44
  Player,
46
45
  ImageInformation,
47
46
  SceneState,
47
+ Size
48
48
  } from "white-web-sdk";
49
49
  import type { AppListeners } from "./AppListener";
50
50
  import type { ApplianceIcons, NetlessApp, RegisterParams } from "./typings";
51
- import type { TeleBoxColorScheme, TeleBoxState } from "@netless/telebox-insider";
51
+ import type { TeleBoxColorScheme, TeleBoxFullscreen, TeleBoxManager, TeleBoxManagerThemeConfig, TeleBoxState } from "@netless/telebox-insider";
52
52
  import type { AppProxy } from "./App";
53
53
  import type { PublicEvent } from "./callback";
54
54
  import type Emittery from "emittery";
55
55
  import type { PageController, AddPageParams, PageState } from "./Page";
56
- import { boxEmitter } from "./BoxEmitter";
56
+ import { computedMinScale } from "./View/CameraSynchronizer";
57
57
 
58
58
  export type WindowMangerAttributes = {
59
59
  modelValue?: string;
@@ -106,6 +106,7 @@ export type AppSyncAttributes = {
106
106
  createdAt?: number;
107
107
  camera?: ICamera;
108
108
  size?: ISize;
109
+ setup: boolean;
109
110
  };
110
111
 
111
112
  export type AppInitState = {
@@ -120,6 +121,11 @@ export type AppInitState = {
120
121
  sceneIndex?: number;
121
122
  boxState?: TeleBoxState; // 兼容旧版 telebox
122
123
  zIndex?: number;
124
+ visible?: boolean;
125
+ stageRatio?: number;
126
+ resizable?: boolean;
127
+ draggable?: boolean;
128
+ ratio?: number;
123
129
  };
124
130
 
125
131
  export type CursorMovePayload = { uid: string; state?: "leave"; position: Position };
@@ -129,16 +135,25 @@ export type MountParams = {
129
135
  container?: HTMLElement;
130
136
  /** 白板高宽比例, 默认为 9 / 16 */
131
137
  containerSizeRatio?: number;
132
- /** 显示 PS 透明背景,默认 true */
138
+ /** @deprecated */
133
139
  chessboard?: boolean;
134
140
  collectorContainer?: HTMLElement;
135
141
  collectorStyles?: Partial<CSSStyleDeclaration>;
136
142
  overwriteStyles?: string;
143
+ containerStyle?: string;
144
+ stageStyle?: string;
137
145
  cursor?: boolean;
138
146
  debug?: boolean;
139
147
  disableCameraTransform?: boolean;
140
148
  prefersColorScheme?: TeleBoxColorScheme;
141
149
  applianceIcons?: ApplianceIcons;
150
+ fullscreen?: TeleBoxFullscreen;
151
+ /** Custom `style` attribute value for content area of all boxes. Can be overwritten by box. */
152
+ defaultBoxBodyStyle?: string | null;
153
+ /** Custom `style` attribute value for stage area of all boxes. Can be overwritten by box. */
154
+ defaultBoxStageStyle?: string | null;
155
+ /** Theme variable */
156
+ theme?: TeleBoxManagerThemeConfig;
142
157
  };
143
158
 
144
159
  export const reconnectRefresher = new ReconnectRefresher({ emitter });
@@ -162,12 +177,15 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
162
177
  public appManager?: AppManager;
163
178
  public cursorManager?: CursorManager;
164
179
  public viewMode = ViewMode.Broadcaster;
180
+ public viewMode$ = new Val<ViewMode>(ViewMode.Broadcaster);
165
181
  public isReplay = isPlayer(this.displayer);
166
182
  private _pageState?: PageStateImpl;
167
183
 
168
184
  private boxManager?: BoxManager;
169
185
  private static params?: MountParams;
170
186
 
187
+ private cameraUpdating = 0;
188
+
171
189
  public containerSizeRatio = WindowManager.containerSizeRatio;
172
190
 
173
191
  constructor(context: InvisiblePluginContext) {
@@ -179,7 +197,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
179
197
  public static async mount(params: MountParams): Promise<WindowManager> {
180
198
  const room = params.room;
181
199
  WindowManager.container = params.container;
182
- const containerSizeRatio = params.containerSizeRatio;
200
+
183
201
  const debug = params.debug;
184
202
 
185
203
  const cursor = params.cursor;
@@ -225,22 +243,24 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
225
243
  throw new Error("[WindowManager]: create manager failed");
226
244
  }
227
245
 
228
- if (containerSizeRatio) {
229
- WindowManager.containerSizeRatio = containerSizeRatio;
246
+ if (params.containerSizeRatio) {
247
+ WindowManager.containerSizeRatio = params.containerSizeRatio;
230
248
  }
249
+ manager.containerSizeRatio = WindowManager.containerSizeRatio;
231
250
  await manager.ensureAttributes();
232
251
 
233
252
  manager.appManager = new AppManager(manager);
234
253
  manager._pageState = new PageStateImpl(manager.appManager);
235
254
  manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor), params.applianceIcons);
236
- if (containerSizeRatio) {
237
- manager.containerSizeRatio = containerSizeRatio;
238
- }
255
+
239
256
  manager.boxManager = createBoxManager(manager, callbacks, emitter, boxEmitter, {
240
257
  collectorContainer: params.collectorContainer,
241
258
  collectorStyles: params.collectorStyles,
242
259
  prefersColorScheme: params.prefersColorScheme,
243
- stageRatio: params.containerSizeRatio,
260
+ stageRatio: WindowManager.containerSizeRatio,
261
+ containerStyle: params.containerStyle,
262
+ stageStyle: params.stageStyle,
263
+ fullscreen: params.fullscreen,
244
264
  });
245
265
  manager.appManager?.setBoxManager(manager.boxManager);
246
266
  if (params.container) {
@@ -259,8 +279,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
259
279
  return manager;
260
280
  }
261
281
 
262
- private static async initManager(room: Room): Promise<WindowManager> {
263
- let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
282
+ private static async initManager(room: Room): Promise<WindowManager | undefined> {
283
+ let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager | undefined;
264
284
  if (!manager) {
265
285
  if (isRoom(room)) {
266
286
  if (room.isWritable === false) {
@@ -269,18 +289,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
269
289
  } catch (error) {
270
290
  throw new Error("[WindowManger]: room must be switched to be writable");
271
291
  }
272
- manager = (await room.createInvisiblePlugin(
273
- WindowManager,
274
- {}
275
- )) as WindowManager;
276
- manager.ensureAttributes();
292
+ manager = await createInvisiblePlugin(room);
293
+ manager?.ensureAttributes();
277
294
  await wait(500);
278
295
  await room.setWritable(false);
279
296
  } else {
280
- manager = (await room.createInvisiblePlugin(
281
- WindowManager,
282
- {}
283
- )) as WindowManager;
297
+ manager = await createInvisiblePlugin(room);
284
298
  }
285
299
  }
286
300
  }
@@ -289,12 +303,13 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
289
303
 
290
304
  private static initContainer(
291
305
  container: HTMLElement,
306
+ target: HTMLElement,
292
307
  overwriteStyles: string | undefined
293
308
  ) {
294
309
  if (!WindowManager.container) {
295
310
  WindowManager.container = container;
296
311
  }
297
- const { playground, mainViewElement } = setupWrapper(container);
312
+ const { playground, mainViewElement } = setupWrapper(container, target);
298
313
  WindowManager.playground = playground;
299
314
  if (overwriteStyles) {
300
315
  const style = document.createElement("style");
@@ -317,10 +332,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
317
332
  container.appendChild(WindowManager.container.firstChild);
318
333
  }
319
334
  } else {
320
- if (WindowManager.params) {
335
+ const teleboxContainer = this.boxManager?.teleBoxManager.$stage;
336
+ if (WindowManager.params && teleboxContainer) {
321
337
  const params = WindowManager.params;
322
338
  const mainViewElement = WindowManager.initContainer(
323
339
  container,
340
+ teleboxContainer,
324
341
  params.overwriteStyles
325
342
  );
326
343
  if (this.boxManager && WindowManager.playground) {
@@ -330,6 +347,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
330
347
  if (WindowManager.playground) {
331
348
  this.cursorManager?.setupWrapper(WindowManager.playground);
332
349
  }
350
+
333
351
  }
334
352
  }
335
353
  emitter.emit("updateManagerRect");
@@ -504,6 +522,18 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
504
522
  }
505
523
  }
506
524
 
525
+ public async jumpPage(index: number): Promise<boolean> {
526
+ if (!this.appManager) {
527
+ return false;
528
+ }
529
+ if (index < 0 || index >= this.pageState.length) {
530
+ console.warn(`[WindowManager]: index ${index} out of range`);
531
+ return false;
532
+ }
533
+ await this.appManager.setMainViewSceneIndex(index);
534
+ return true;
535
+ }
536
+
507
537
  public async addPage(params?: AddPageParams): Promise<void> {
508
538
  if (this.appManager) {
509
539
  const after = params?.after;
@@ -580,16 +610,19 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
580
610
  * 设置 ViewMode
581
611
  */
582
612
  public setViewMode(mode: ViewMode): void {
613
+ log("setViewMode", mode);
614
+ const mainViewProxy = this.appManager?.mainViewProxy;
583
615
  if (mode === ViewMode.Broadcaster) {
584
616
  if (this.canOperate) {
585
- this.appManager?.mainViewProxy.setCameraAndSize();
617
+ mainViewProxy?.storeCurrentCamera();
586
618
  }
587
- this.appManager?.mainViewProxy.start();
619
+ mainViewProxy?.start();
588
620
  }
589
621
  if (mode === ViewMode.Freedom) {
590
- this.appManager?.mainViewProxy.stop();
622
+ mainViewProxy?.stop();
591
623
  }
592
624
  this.viewMode = mode;
625
+ this.viewMode$.setValue(mode);
593
626
  }
594
627
 
595
628
  public setBoxState(boxState: TeleBoxState): void {
@@ -637,6 +670,22 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
637
670
  }
638
671
  }
639
672
 
673
+ public get baseCamera() {
674
+ if (this.appManager) {
675
+ return this.appManager.mainViewProxy.camera$.value;
676
+ } else {
677
+ throw new Errors.AppManagerNotInitError();
678
+ }
679
+ }
680
+
681
+ public get baseSize() {
682
+ if (this.appManager) {
683
+ return this.appManager.mainViewProxy.size$.value;
684
+ } else {
685
+ throw new Errors.AppManagerNotInitError();
686
+ }
687
+ }
688
+
640
689
  public get cameraState(): CameraState {
641
690
  if (this.appManager) {
642
691
  return this.appManager.mainViewProxy.cameraState;
@@ -669,6 +718,14 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
669
718
  }
670
719
  }
671
720
 
721
+ public get fullscreen(): TeleBoxFullscreen | undefined {
722
+ if (this.appManager) {
723
+ return this.appManager.boxManager?.teleBoxManager.fullscreen;
724
+ } else {
725
+ throw new Errors.AppManagerNotInitError();
726
+ }
727
+ }
728
+
672
729
  public get focused(): string | undefined {
673
730
  return this.attributes.focus;
674
731
  }
@@ -722,6 +779,13 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
722
779
  }
723
780
  }
724
781
 
782
+ public get teleboxManager(): TeleBoxManager {
783
+ if (!this.boxManager) {
784
+ throw new Errors.BoxManagerNotInitializeError();
785
+ }
786
+ return this.boxManager.teleBoxManager;
787
+ }
788
+
725
789
  /**
726
790
  * 查询所有的 App
727
791
  */
@@ -743,31 +807,52 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
743
807
  return this.appManager?.closeApp(appId);
744
808
  }
745
809
 
746
- public moveCamera(
747
- camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }
748
- ): void {
749
- const pureCamera = omit(camera, ["animationMode"]);
810
+ public moveCamera = (camera: Partial<Camera> & { animationMode?: AnimationMode } ): void => {
750
811
  const mainViewCamera = { ...this.mainView.camera };
751
- if (isEqual({ ...mainViewCamera, ...pureCamera }, mainViewCamera)) return;
752
- this.mainView.moveCamera(camera);
753
- this.appManager?.dispatchInternalEvent(Events.MoveCamera, camera);
754
- setTimeout(() => {
755
- this.appManager?.mainViewProxy.setCameraAndSize();
756
- }, 500);
757
- }
758
-
759
- public moveCameraToContain(
760
- rectangle: Rectangle &
761
- Readonly<{
762
- animationMode?: AnimationMode;
763
- }>
764
- ): void {
765
- this.mainView.moveCameraToContain(rectangle);
766
- this.appManager?.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
767
- setTimeout(() => {
768
- this.appManager?.mainViewProxy.setCameraAndSize();
769
- }, 500);
770
- }
812
+ const nextCamera = { ...mainViewCamera, ...camera };
813
+ if (isEqual(nextCamera, mainViewCamera)) return;
814
+ if (!this.appManager) return;
815
+ if (camera.animationMode === AnimationMode.Immediately) {
816
+ this.appManager.mainViewProxy.storeCamera({
817
+ id: this.appManager.uid,
818
+ ...nextCamera
819
+ });
820
+ } else {
821
+ const remoteCamera = this.appManager.mainViewProxy.size$.value;
822
+ const currentSize = this.boxManager?.stageRect;
823
+ let nextScale;
824
+ if (camera.scale && remoteCamera && currentSize) {
825
+ nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
826
+ }
827
+ if (nextScale) {
828
+ this.mainView.moveCamera({
829
+ ...camera,
830
+ scale: nextScale,
831
+ });
832
+ } else {
833
+ this.mainView.moveCamera(camera);
834
+ }
835
+ this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
836
+ const onCameraUpdated = () => {
837
+ if (this.cameraUpdating) {
838
+ clearTimeout(this.cameraUpdating);
839
+ }
840
+ this.cameraUpdating = setTimeout(() => {
841
+ this.mainView.callbacks.off("onCameraUpdated", onCameraUpdated);
842
+ clearTimeout(this.cameraUpdating);
843
+ this.cameraUpdating = 0;
844
+ if (!this.appManager) return;
845
+ this.appManager.mainViewProxy.storeCamera({
846
+ id: this.appManager.uid,
847
+ ...nextCamera
848
+ });
849
+ }, 50);
850
+ }
851
+ this.mainView.callbacks.off("onCameraUpdated", onCameraUpdated);
852
+ this.mainView.callbacks.on("onCameraUpdated", onCameraUpdated);
853
+
854
+ }
855
+ };
771
856
 
772
857
  public convertToPointInWorld(point: Point): Point {
773
858
  return this.mainView.convertToPointInWorld(point);
@@ -835,6 +920,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
835
920
  this.appManager?.boxManager?.setPrefersColorScheme(scheme);
836
921
  }
837
922
 
923
+ public setFullscreen(fullscreen: TeleBoxFullscreen): void {
924
+ this.appManager?.boxManager?.teleBoxManager.setFullscreen(fullscreen);
925
+ }
926
+
838
927
  public cleanCurrentScene(): void {
839
928
  this.focusedView?.cleanCurrentScene();
840
929
  }
@@ -894,7 +983,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
894
983
  if (WindowManager.container) {
895
984
  this.bindContainer(WindowManager.container);
896
985
  }
897
- this.appManager?.refresher?.refresh();
986
+ this.appManager?.refresher.refresh();
898
987
  }
899
988
 
900
989
  public setContainerSizeRatio(ratio: number) {
@@ -906,6 +995,44 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
906
995
  emitter.emit("containerSizeRatioUpdate", ratio);
907
996
  }
908
997
 
998
+ public setContainerStyle(style: string) {
999
+ this.boxManager?.teleBoxManager.setContainerStyle(style);
1000
+ }
1001
+
1002
+ public setStageStyle(style: string) {
1003
+ this.boxManager?.teleBoxManager.setStageStyle(style);
1004
+ }
1005
+
1006
+ public setBaseSize(size: Size) {
1007
+ this.appManager?.mainViewProxy.setMainViewSize(size);
1008
+ setTimeout(() => {
1009
+ if (!this.appManager || !this.appManager.mainViewProxy.camera$.value) return;
1010
+ this.appManager.mainViewProxy.storeCamera({
1011
+ ...this.appManager.mainViewProxy.camera$.value,
1012
+ id: this.appManager.uid,
1013
+ scale: 1
1014
+ });
1015
+ }, 500);
1016
+ }
1017
+
1018
+ public createPPTHandler() {
1019
+ return {
1020
+ onPageJumpTo: (_pptUUID: string, index: number) => {
1021
+ this.appManager?.focusApp?.appContext?.whiteBoardView?.jumpPage(index);
1022
+ },
1023
+ onPageToNext: () => {
1024
+ if (this.focused) {
1025
+ this.appManager?.focusApp?.appContext?.whiteBoardView?.nextPage();
1026
+ }
1027
+ },
1028
+ onPageToPrev: () => {
1029
+ if (this.focused) {
1030
+ this.appManager?.focusApp?.appContext?.whiteBoardView?.prevPage();
1031
+ }
1032
+ }
1033
+ }
1034
+ }
1035
+
909
1036
  private isDynamicPPT(scenes: SceneDefinition[]) {
910
1037
  const sceneSrc = scenes[0]?.ppt?.src;
911
1038
  return sceneSrc?.startsWith("pptx://");
@@ -939,5 +1066,6 @@ setupBuiltin();
939
1066
 
940
1067
  export * from "./typings";
941
1068
 
942
- export { BuiltinApps } from "./BuiltinApps";
1069
+ export { BuiltinApps, BuiltinAppsMap } from "./BuiltinApps";
943
1070
  export type { PublicEvent } from "./callback";
1071
+ export type { Member } from "./Helper";
package/src/style.css CHANGED
@@ -7,48 +7,9 @@
7
7
  user-select: none;
8
8
  }
9
9
 
10
- .netless-window-manager-sizer {
11
- position: absolute;
12
- top: 0;
13
- left: 0;
14
- width: 100%;
15
- height: 100%;
16
- z-index: 1;
17
- overflow: hidden;
18
- display: flex;
19
- }
20
-
21
- .netless-window-manager-sizer-horizontal {
22
- flex-direction: column;
23
- }
24
-
25
- .netless-window-manager-sizer::before,
26
- .netless-window-manager-sizer::after {
27
- flex: 1;
28
- content: "";
29
- display: block;
30
- }
31
-
32
- .netless-window-manager-chess-sizer::before,
33
- .netless-window-manager-chess-sizer::after {
34
- background-image: linear-gradient(45deg, #b0b0b0 25%, transparent 25%),
35
- linear-gradient(-45deg, #b0b0b0 25%, transparent 25%),
36
- linear-gradient(45deg, transparent 75%, #b0b0b0 75%),
37
- linear-gradient(-45deg, transparent 75%, #b0b0b0 75%);
38
- background-color: #fff;
39
- background-size: 20px 20px;
40
- background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
41
- }
42
-
43
- .netless-window-manager-wrapper {
44
- position: relative;
45
- z-index: 1;
46
- width: 100%;
47
- height: 100%;
48
- overflow: hidden;
49
- }
50
10
 
51
11
  .netless-window-manager-main-view {
12
+ position: absolute;
52
13
  width: 100%;
53
14
  height: 100%;
54
15
  }
@@ -122,7 +83,7 @@
122
83
  left: 0;
123
84
  top: 0;
124
85
  will-change: transform;
125
- transition: transform 0.1s;
86
+ transition: transform 0.12s;
126
87
  transform-origin: 0 0;
127
88
  user-select: none;
128
89
  }
@@ -180,10 +141,6 @@
180
141
  }
181
142
 
182
143
  .window-manager-view-wrapper {
183
- z-index: 5000;
184
- width: 100%;
185
- height: 100%;
186
144
  position: absolute;
187
- left: 0;
188
- top: 0;
145
+ z-index: 10;
189
146
  }
package/src/typings.ts CHANGED
@@ -11,7 +11,7 @@ import type {
11
11
  View,
12
12
  } from "white-web-sdk";
13
13
  import type { AppContext } from "./App";
14
- import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
14
+ import type { ReadonlyTeleBox, TeleBoxRect, TeleBoxFullscreen } from "@netless/telebox-insider";
15
15
  import type { PageState } from "./Page";
16
16
  import type { Member } from "./Helper";
17
17
 
@@ -30,6 +30,9 @@ export interface NetlessApp<Attributes = any, MagixEventPayloads = any, AppOptio
30
30
 
31
31
  /** App only single instance. */
32
32
  singleton?: boolean;
33
+
34
+ /** App box enableShadowDom. Default true */
35
+ enableShadowDOM?: boolean;
33
36
  };
34
37
  setup: (context: AppContext<Attributes, MagixEventPayloads, AppOptions>) => SetupResult;
35
38
  }
@@ -74,15 +77,18 @@ export type RegisterParams<AppOptions = any, SetupResult = any, Attributes = any
74
77
  addHooks?: (emitter: Emittery<RegisterEvents<SetupResult>>) => void;
75
78
  /** dynamic load app package name */
76
79
  name?: string;
80
+ contentStyles?: string;
77
81
  };
78
82
 
79
83
  export type AppListenerKeys = keyof AppEmitterEvent;
80
84
 
81
85
  export type ApplianceIcons = Partial<Record<ApplianceNames, string>>;
82
86
 
87
+ export type Writeable<T> = { -readonly [P in keyof T]: T[P] };
88
+
83
89
  export type { AppContext } from "./App/AppContext";
84
90
  export type { WhiteBoardView } from "./App";
85
- export type { ReadonlyTeleBox, TeleBoxRect };
91
+ export type { ReadonlyTeleBox, TeleBoxRect, TeleBoxFullscreen };
86
92
  export type { SceneState, SceneDefinition, View, AnimationMode, Displayer, Room, Player };
87
93
  export type { Storage, StorageStateChangedEvent, StorageStateChangedListener } from "./App/Storage";
88
94
  export * from "./Page";
package/vite.config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import path from "path";
2
+ import dts from 'vite-plugin-dts'
2
3
  import { defineConfig } from 'vitest/config'
3
4
  import { svelte } from "@sveltejs/vite-plugin-svelte";
4
5
  import { dependencies, peerDependencies, version, devDependencies } from "./package.json"
@@ -14,7 +15,9 @@ export default defineConfig(({ mode }) => {
14
15
  inline: [
15
16
  "@juggle/resize-observer"
16
17
  ]
17
- }
18
+ },
19
+ setupFiles: "./test/setup.ts",
20
+ include: ["test/**/*.test.ts"],
18
21
  },
19
22
  define: {
20
23
  __APP_VERSION__: JSON.stringify(version),
@@ -28,7 +31,8 @@ export default defineConfig(({ mode }) => {
28
31
  experimental: {
29
32
  useVitePreprocess: true,
30
33
  },
31
- })
34
+ }),
35
+ dts()
32
36
  ],
33
37
  build: {
34
38
  lib: {
@@ -45,7 +49,7 @@ export default defineConfig(({ mode }) => {
45
49
  ...peerDependencies,
46
50
  }),
47
51
  },
48
- minify: isProd,
52
+ minify: isProd
49
53
  },
50
54
  };
51
- });
55
+ })
@@ -1,11 +0,0 @@
1
- import type { View } from "white-web-sdk";
2
- import type { AppProxy } from "./AppProxy";
3
- export declare class AppViewSync {
4
- private appProxy;
5
- private sem;
6
- private synchronizer;
7
- constructor(appProxy: AppProxy);
8
- bindView: (view?: View | undefined) => void;
9
- private onCameraUpdatedByDevice;
10
- destroy(): void;
11
- }
@@ -1,21 +0,0 @@
1
- import type { ReadonlyVal } from "value-enhancer";
2
- import type { AddPageParams, PageController, PageState } from "../Page";
3
- import type { AppProxy } from "./AppProxy";
4
- import type { AppContext } from "./AppContext";
5
- import type { Camera } from "white-web-sdk";
6
- export declare class WhiteBoardView implements PageController {
7
- protected appContext: AppContext;
8
- protected appProxy: AppProxy;
9
- private removeViewWrapper;
10
- readonly pageState$: ReadonlyVal<PageState>;
11
- constructor(appContext: AppContext, appProxy: AppProxy, removeViewWrapper: () => void);
12
- get view(): import("white-web-sdk").View | undefined;
13
- get pageState(): PageState;
14
- moveCamera(camera: Camera): void;
15
- nextPage: () => Promise<boolean>;
16
- prevPage: () => Promise<boolean>;
17
- jumpPage: (index: number) => Promise<boolean>;
18
- addPage: (params?: AddPageParams | undefined) => Promise<void>;
19
- removePage: (index?: number | undefined) => Promise<boolean>;
20
- destroy(): void;
21
- }
@@ -1,17 +0,0 @@
1
- import type { TeleBoxRect } from "@netless/telebox-insider";
2
- import type { Camera, View, Size } from "white-web-sdk";
3
- import type { ISize } from "../AttributesDelegate";
4
- export declare type SaveCamera = (camera: Camera) => void;
5
- export declare class CameraSynchronizer {
6
- protected saveCamera: SaveCamera;
7
- protected remoteCamera?: Camera;
8
- protected remoteSize?: ISize;
9
- protected rect?: TeleBoxRect;
10
- protected view?: View;
11
- constructor(saveCamera: SaveCamera);
12
- setRect(rect: TeleBoxRect): void;
13
- setView(view: View): void;
14
- onRemoteUpdate: import("lodash").DebouncedFunc<(camera: Camera, size: ISize) => void>;
15
- onLocalCameraUpdate(camera: Camera): void;
16
- onLocalSizeUpdate: (size: Size) => void;
17
- }
@@ -1,7 +0,0 @@
1
- import type { Camera, Size } from "white-web-sdk";
2
- export interface ViewSync {
3
- readonly camera: Camera;
4
- readonly size: Size;
5
- setCamera: (camera: Camera) => void;
6
- setSize: (size: Size) => void;
7
- }