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

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 +7269 -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} +44 -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 +173 -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, debounce } 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,6 +177,7 @@ 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
 
@@ -179,7 +195,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
179
195
  public static async mount(params: MountParams): Promise<WindowManager> {
180
196
  const room = params.room;
181
197
  WindowManager.container = params.container;
182
- const containerSizeRatio = params.containerSizeRatio;
198
+
183
199
  const debug = params.debug;
184
200
 
185
201
  const cursor = params.cursor;
@@ -225,22 +241,24 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
225
241
  throw new Error("[WindowManager]: create manager failed");
226
242
  }
227
243
 
228
- if (containerSizeRatio) {
229
- WindowManager.containerSizeRatio = containerSizeRatio;
244
+ if (params.containerSizeRatio) {
245
+ WindowManager.containerSizeRatio = params.containerSizeRatio;
230
246
  }
247
+ manager.containerSizeRatio = WindowManager.containerSizeRatio;
231
248
  await manager.ensureAttributes();
232
249
 
233
250
  manager.appManager = new AppManager(manager);
234
251
  manager._pageState = new PageStateImpl(manager.appManager);
235
252
  manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor), params.applianceIcons);
236
- if (containerSizeRatio) {
237
- manager.containerSizeRatio = containerSizeRatio;
238
- }
253
+
239
254
  manager.boxManager = createBoxManager(manager, callbacks, emitter, boxEmitter, {
240
255
  collectorContainer: params.collectorContainer,
241
256
  collectorStyles: params.collectorStyles,
242
257
  prefersColorScheme: params.prefersColorScheme,
243
- stageRatio: params.containerSizeRatio,
258
+ stageRatio: WindowManager.containerSizeRatio,
259
+ containerStyle: params.containerStyle,
260
+ stageStyle: params.stageStyle,
261
+ fullscreen: params.fullscreen,
244
262
  });
245
263
  manager.appManager?.setBoxManager(manager.boxManager);
246
264
  if (params.container) {
@@ -259,8 +277,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
259
277
  return manager;
260
278
  }
261
279
 
262
- private static async initManager(room: Room): Promise<WindowManager> {
263
- let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
280
+ private static async initManager(room: Room): Promise<WindowManager | undefined> {
281
+ let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager | undefined;
264
282
  if (!manager) {
265
283
  if (isRoom(room)) {
266
284
  if (room.isWritable === false) {
@@ -269,18 +287,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
269
287
  } catch (error) {
270
288
  throw new Error("[WindowManger]: room must be switched to be writable");
271
289
  }
272
- manager = (await room.createInvisiblePlugin(
273
- WindowManager,
274
- {}
275
- )) as WindowManager;
276
- manager.ensureAttributes();
290
+ manager = await createInvisiblePlugin(room);
291
+ manager?.ensureAttributes();
277
292
  await wait(500);
278
293
  await room.setWritable(false);
279
294
  } else {
280
- manager = (await room.createInvisiblePlugin(
281
- WindowManager,
282
- {}
283
- )) as WindowManager;
295
+ manager = await createInvisiblePlugin(room);
284
296
  }
285
297
  }
286
298
  }
@@ -289,12 +301,13 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
289
301
 
290
302
  private static initContainer(
291
303
  container: HTMLElement,
304
+ target: HTMLElement,
292
305
  overwriteStyles: string | undefined
293
306
  ) {
294
307
  if (!WindowManager.container) {
295
308
  WindowManager.container = container;
296
309
  }
297
- const { playground, mainViewElement } = setupWrapper(container);
310
+ const { playground, mainViewElement } = setupWrapper(container, target);
298
311
  WindowManager.playground = playground;
299
312
  if (overwriteStyles) {
300
313
  const style = document.createElement("style");
@@ -317,10 +330,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
317
330
  container.appendChild(WindowManager.container.firstChild);
318
331
  }
319
332
  } else {
320
- if (WindowManager.params) {
333
+ const teleboxContainer = this.boxManager?.teleBoxManager.$stage;
334
+ if (WindowManager.params && teleboxContainer) {
321
335
  const params = WindowManager.params;
322
336
  const mainViewElement = WindowManager.initContainer(
323
337
  container,
338
+ teleboxContainer,
324
339
  params.overwriteStyles
325
340
  );
326
341
  if (this.boxManager && WindowManager.playground) {
@@ -330,6 +345,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
330
345
  if (WindowManager.playground) {
331
346
  this.cursorManager?.setupWrapper(WindowManager.playground);
332
347
  }
348
+
333
349
  }
334
350
  }
335
351
  emitter.emit("updateManagerRect");
@@ -504,6 +520,18 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
504
520
  }
505
521
  }
506
522
 
523
+ public async jumpPage(index: number): Promise<boolean> {
524
+ if (!this.appManager) {
525
+ return false;
526
+ }
527
+ if (index < 0 || index >= this.pageState.length) {
528
+ console.warn(`[WindowManager]: index ${index} out of range`);
529
+ return false;
530
+ }
531
+ await this.appManager.setMainViewSceneIndex(index);
532
+ return true;
533
+ }
534
+
507
535
  public async addPage(params?: AddPageParams): Promise<void> {
508
536
  if (this.appManager) {
509
537
  const after = params?.after;
@@ -580,16 +608,19 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
580
608
  * 设置 ViewMode
581
609
  */
582
610
  public setViewMode(mode: ViewMode): void {
611
+ log("setViewMode", mode);
612
+ const mainViewProxy = this.appManager?.mainViewProxy;
583
613
  if (mode === ViewMode.Broadcaster) {
584
614
  if (this.canOperate) {
585
- this.appManager?.mainViewProxy.setCameraAndSize();
615
+ mainViewProxy?.storeCurrentCamera();
586
616
  }
587
- this.appManager?.mainViewProxy.start();
617
+ mainViewProxy?.start();
588
618
  }
589
619
  if (mode === ViewMode.Freedom) {
590
- this.appManager?.mainViewProxy.stop();
620
+ mainViewProxy?.stop();
591
621
  }
592
622
  this.viewMode = mode;
623
+ this.viewMode$.setValue(mode);
593
624
  }
594
625
 
595
626
  public setBoxState(boxState: TeleBoxState): void {
@@ -637,6 +668,22 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
637
668
  }
638
669
  }
639
670
 
671
+ public get baseCamera() {
672
+ if (this.appManager) {
673
+ return this.appManager.mainViewProxy.camera$.value;
674
+ } else {
675
+ throw new Errors.AppManagerNotInitError();
676
+ }
677
+ }
678
+
679
+ public get baseSize() {
680
+ if (this.appManager) {
681
+ return this.appManager.mainViewProxy.size$.value;
682
+ } else {
683
+ throw new Errors.AppManagerNotInitError();
684
+ }
685
+ }
686
+
640
687
  public get cameraState(): CameraState {
641
688
  if (this.appManager) {
642
689
  return this.appManager.mainViewProxy.cameraState;
@@ -669,6 +716,14 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
669
716
  }
670
717
  }
671
718
 
719
+ public get fullscreen(): TeleBoxFullscreen | undefined {
720
+ if (this.appManager) {
721
+ return this.appManager.boxManager?.teleBoxManager.fullscreen;
722
+ } else {
723
+ throw new Errors.AppManagerNotInitError();
724
+ }
725
+ }
726
+
672
727
  public get focused(): string | undefined {
673
728
  return this.attributes.focus;
674
729
  }
@@ -722,6 +777,13 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
722
777
  }
723
778
  }
724
779
 
780
+ public get teleboxManager(): TeleBoxManager {
781
+ if (!this.boxManager) {
782
+ throw new Errors.BoxManagerNotInitializeError();
783
+ }
784
+ return this.boxManager.teleBoxManager;
785
+ }
786
+
725
787
  /**
726
788
  * 查询所有的 App
727
789
  */
@@ -743,31 +805,41 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
743
805
  return this.appManager?.closeApp(appId);
744
806
  }
745
807
 
746
- public moveCamera(
747
- camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }
748
- ): void {
749
- const pureCamera = omit(camera, ["animationMode"]);
808
+ public moveCamera = debounce((camera: Partial<Camera> & { animationMode?: AnimationMode } ): void => {
750
809
  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
- }
810
+ const nextCamera = { ...mainViewCamera, ...camera };
811
+ if (isEqual(nextCamera, mainViewCamera)) return;
812
+ if (!this.appManager) return;
813
+ if (camera.animationMode === AnimationMode.Immediately) {
814
+ this.appManager.mainViewProxy.storeCamera({
815
+ id: this.appManager.uid,
816
+ ...nextCamera
817
+ });
818
+ } else {
819
+ const remoteCamera = this.appManager.mainViewProxy.size$.value;
820
+ const currentSize = this.boxManager?.stageRect;
821
+ let nextScale;
822
+ if (camera.scale && remoteCamera && currentSize) {
823
+ nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
824
+ }
825
+ if (nextScale) {
826
+ this.mainView.moveCamera({
827
+ ...camera,
828
+ scale: nextScale,
829
+ });
830
+ } else {
831
+ this.mainView.moveCamera(camera);
832
+ }
833
+ this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
834
+ setTimeout(() => {
835
+ if (!this.appManager) return;
836
+ this.appManager.mainViewProxy.storeCamera({
837
+ id: this.appManager.uid,
838
+ ...nextCamera
839
+ });
840
+ }, 200);
841
+ }
842
+ }, 200);
771
843
 
772
844
  public convertToPointInWorld(point: Point): Point {
773
845
  return this.mainView.convertToPointInWorld(point);
@@ -835,6 +907,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
835
907
  this.appManager?.boxManager?.setPrefersColorScheme(scheme);
836
908
  }
837
909
 
910
+ public setFullscreen(fullscreen: TeleBoxFullscreen): void {
911
+ this.appManager?.boxManager?.teleBoxManager.setFullscreen(fullscreen);
912
+ }
913
+
838
914
  public cleanCurrentScene(): void {
839
915
  this.focusedView?.cleanCurrentScene();
840
916
  }
@@ -894,7 +970,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
894
970
  if (WindowManager.container) {
895
971
  this.bindContainer(WindowManager.container);
896
972
  }
897
- this.appManager?.refresher?.refresh();
973
+ this.appManager?.refresher.refresh();
898
974
  }
899
975
 
900
976
  public setContainerSizeRatio(ratio: number) {
@@ -906,6 +982,44 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
906
982
  emitter.emit("containerSizeRatioUpdate", ratio);
907
983
  }
908
984
 
985
+ public setContainerStyle(style: string) {
986
+ this.boxManager?.teleBoxManager.setContainerStyle(style);
987
+ }
988
+
989
+ public setStageStyle(style: string) {
990
+ this.boxManager?.teleBoxManager.setStageStyle(style);
991
+ }
992
+
993
+ public setBaseSize(size: Size) {
994
+ this.appManager?.mainViewProxy.setMainViewSize(size);
995
+ setTimeout(() => {
996
+ if (!this.appManager || !this.appManager.mainViewProxy.camera$.value) return;
997
+ this.appManager.mainViewProxy.storeCamera({
998
+ ...this.appManager.mainViewProxy.camera$.value,
999
+ id: this.appManager.uid,
1000
+ scale: 1
1001
+ });
1002
+ }, 500);
1003
+ }
1004
+
1005
+ public createPPTHandler() {
1006
+ return {
1007
+ onPageJumpTo: (_pptUUID: string, index: number) => {
1008
+ this.appManager?.focusApp?.appContext?.whiteBoardView?.jumpPage(index);
1009
+ },
1010
+ onPageToNext: () => {
1011
+ if (this.focused) {
1012
+ this.appManager?.focusApp?.appContext?.whiteBoardView?.nextPage();
1013
+ }
1014
+ },
1015
+ onPageToPrev: () => {
1016
+ if (this.focused) {
1017
+ this.appManager?.focusApp?.appContext?.whiteBoardView?.prevPage();
1018
+ }
1019
+ }
1020
+ }
1021
+ }
1022
+
909
1023
  private isDynamicPPT(scenes: SceneDefinition[]) {
910
1024
  const sceneSrc = scenes[0]?.ppt?.src;
911
1025
  return sceneSrc?.startsWith("pptx://");
@@ -939,5 +1053,6 @@ setupBuiltin();
939
1053
 
940
1054
  export * from "./typings";
941
1055
 
942
- export { BuiltinApps } from "./BuiltinApps";
1056
+ export { BuiltinApps, BuiltinAppsMap } from "./BuiltinApps";
943
1057
  export type { PublicEvent } from "./callback";
1058
+ 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
- }