@netless/window-manager 0.4.0-canary.1 → 0.4.0-canary.10

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 (62) hide show
  1. package/dist/App/Storage/StorageEvent.d.ts +8 -0
  2. package/dist/App/Storage/index.d.ts +26 -0
  3. package/dist/App/Storage/typings.d.ts +21 -0
  4. package/dist/App/Storage/utils.d.ts +5 -0
  5. package/dist/AppContext.d.ts +3 -1
  6. package/dist/AppListener.d.ts +0 -1
  7. package/dist/AppManager.d.ts +7 -7
  8. package/dist/AppProxy.d.ts +2 -3
  9. package/dist/Base/Context.d.ts +0 -1
  10. package/dist/BoxManager.d.ts +2 -1
  11. package/dist/BuiltinApps.d.ts +6 -0
  12. package/dist/ContainerResizeObserver.d.ts +10 -0
  13. package/dist/Cursor/Cursor.d.ts +2 -3
  14. package/dist/Cursor/index.d.ts +7 -4
  15. package/dist/Helper.d.ts +6 -0
  16. package/dist/ReconnectRefresher.d.ts +5 -2
  17. package/dist/Utils/Common.d.ts +3 -1
  18. package/dist/Utils/Reactive.d.ts +1 -1
  19. package/dist/{MainView.d.ts → View/MainView.d.ts} +2 -4
  20. package/dist/View/ViewManager.d.ts +13 -0
  21. package/dist/constants.d.ts +1 -6
  22. package/dist/index.d.ts +13 -13
  23. package/dist/index.es.js +1 -1
  24. package/dist/index.es.js.map +1 -1
  25. package/dist/index.umd.js +1 -1
  26. package/dist/index.umd.js.map +1 -1
  27. package/dist/style.css +1 -1
  28. package/dist/typings.d.ts +1 -0
  29. package/package.json +5 -4
  30. package/src/App/Storage/StorageEvent.ts +21 -0
  31. package/src/App/Storage/index.ts +243 -0
  32. package/src/App/Storage/typings.ts +21 -0
  33. package/src/App/Storage/utils.ts +17 -0
  34. package/src/AppContext.ts +10 -2
  35. package/src/AppListener.ts +1 -8
  36. package/src/AppManager.ts +54 -35
  37. package/src/AppProxy.ts +14 -36
  38. package/src/Base/Context.ts +0 -4
  39. package/src/BoxManager.ts +9 -7
  40. package/src/BuiltinApps.ts +24 -0
  41. package/src/ContainerResizeObserver.ts +62 -0
  42. package/src/Cursor/Cursor.ts +23 -34
  43. package/src/Cursor/index.ts +70 -41
  44. package/src/Helper.ts +30 -0
  45. package/src/ReconnectRefresher.ts +13 -5
  46. package/src/Utils/Common.ts +35 -13
  47. package/src/Utils/Reactive.ts +9 -3
  48. package/src/Utils/RoomHacker.ts +15 -0
  49. package/src/{MainView.ts → View/MainView.ts} +9 -25
  50. package/src/View/ViewManager.ts +53 -0
  51. package/src/constants.ts +1 -3
  52. package/src/index.ts +46 -86
  53. package/src/shim.d.ts +4 -0
  54. package/src/style.css +6 -0
  55. package/src/typings.ts +1 -0
  56. package/vite.config.js +4 -1
  57. package/dist/Utils/CameraStore.d.ts +0 -15
  58. package/dist/ViewManager.d.ts +0 -29
  59. package/dist/sdk.d.ts +0 -14
  60. package/src/Utils/CameraStore.ts +0 -72
  61. package/src/sdk.ts +0 -39
  62. package/src/viewManager.ts +0 -177
@@ -1,7 +1,7 @@
1
- import { appRegister } from '../Register';
2
- import { debounce } from 'lodash';
3
- import { emitter } from '../index';
4
- import { v4 } from 'uuid';
1
+ import { appRegister } from "../Register";
2
+ import { debounce } from "lodash";
3
+ import { emitter } from "../index";
4
+ import { v4 } from "uuid";
5
5
  import type { PublicEvent } from "../index";
6
6
  import type { Displayer, ViewVisionMode, Room, View } from "white-web-sdk";
7
7
  import type Emittery from "emittery";
@@ -26,7 +26,21 @@ export const setScenePath = (room: Room | undefined, scenePath: string) => {
26
26
  room.setScenePath(scenePath);
27
27
  }
28
28
  }
29
- }
29
+ };
30
+
31
+ export const getScenePath = (
32
+ room: Room | undefined,
33
+ dir: string | undefined,
34
+ index: number
35
+ ): string | undefined => {
36
+ if (room && dir) {
37
+ const scenes = entireScenes(room);
38
+ const scene = scenes[dir]?.[index];
39
+ if (scene) {
40
+ return `${dir}/${scene.name}`;
41
+ }
42
+ }
43
+ };
30
44
 
31
45
  export const setViewMode = (view: View, mode: ViewVisionMode) => {
32
46
  if (!(view as any).didRelease && view.mode !== mode) {
@@ -44,7 +58,7 @@ export const emitError = (error: Error) => {
44
58
 
45
59
  export const addEmitterOnceListener = (event: any, listener: any) => {
46
60
  emitter.once(event).then(listener);
47
- }
61
+ };
48
62
 
49
63
  export const notifyMainViewModeChange = debounce(
50
64
  (callbacks: Emittery<PublicEvent>, mode: ViewVisionMode) => {
@@ -53,9 +67,10 @@ export const notifyMainViewModeChange = debounce(
53
67
  200
54
68
  );
55
69
 
56
- export const makeValidScenePath = (displayer: Displayer, scenePath: string) => {
57
- const scenes = displayer.entireScenes()[scenePath];
58
- const firstSceneName = scenes[0].name;
70
+ export const makeValidScenePath = (displayer: Displayer, scenePath: string, index = 0) => {
71
+ const scenes = entireScenes(displayer)[scenePath];
72
+ if (!scenes) return;
73
+ const firstSceneName = scenes[index].name;
59
74
  if (scenePath === "/") {
60
75
  return `/${firstSceneName}`;
61
76
  } else {
@@ -63,9 +78,13 @@ export const makeValidScenePath = (displayer: Displayer, scenePath: string) => {
63
78
  }
64
79
  };
65
80
 
81
+ export const entireScenes = (displayer: Displayer) => {
82
+ return displayer.entireScenes();
83
+ };
84
+
66
85
  export const isValidScenePath = (scenePath: string) => {
67
86
  return scenePath.startsWith("/");
68
- }
87
+ };
69
88
 
70
89
  export const ensureValidScenePath = (scenePath: string) => {
71
90
  if (scenePath.endsWith("/")) {
@@ -73,11 +92,14 @@ export const ensureValidScenePath = (scenePath: string) => {
73
92
  } else {
74
93
  return scenePath;
75
94
  }
76
- }
95
+ };
77
96
 
78
97
  export const getVersionNumber = (version: string) => {
79
- const versionString = version.split(".").map(s => s.padStart(2, "0")).join("");
98
+ const versionString = version
99
+ .split(".")
100
+ .map(s => s.padStart(2, "0"))
101
+ .join("");
80
102
  return parseInt(versionString);
81
103
  };
82
104
 
83
- export const wait = (time: number) => new Promise((resolve) => setTimeout(resolve, time));
105
+ export const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time));
@@ -1,5 +1,6 @@
1
1
  import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from "white-web-sdk";
2
2
  import type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from "white-web-sdk";
3
+ import { isObject } from "lodash";
3
4
 
4
5
  // 兼容 13 和 14 版本 SDK
5
6
  export const onObjectByEvent = (event: UpdateEventKind) => {
@@ -30,7 +31,8 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
30
31
 
31
32
  export const safeListenPropsUpdated = <T>(
32
33
  getProps: () => T,
33
- callback: AkkoObjectUpdatedListener<T>
34
+ callback: AkkoObjectUpdatedListener<T>,
35
+ onDestroyed?: (props: unknown) => void
34
36
  ) => {
35
37
  let disposeListenUpdated: (() => void) | null = null;
36
38
  const disposeReaction = reaction(
@@ -41,8 +43,12 @@ export const safeListenPropsUpdated = <T>(
41
43
  disposeListenUpdated = null;
42
44
  }
43
45
  const props = getProps();
44
- disposeListenUpdated = () => unlistenUpdated(props, callback);
45
- listenUpdated(props, callback);
46
+ if (isObject(props)) {
47
+ disposeListenUpdated = () => unlistenUpdated(props, callback);
48
+ listenUpdated(props, callback);
49
+ } else {
50
+ onDestroyed?.(props);
51
+ }
46
52
  },
47
53
  { fireImmediately: true }
48
54
  );
@@ -29,6 +29,18 @@ export const replaceRoomFunction = (room: Room, manager: WindowManager) => {
29
29
  },
30
30
  });
31
31
 
32
+ Object.defineProperty(room, "canUndoSteps", {
33
+ get() {
34
+ return manager.mainView.canUndoSteps;
35
+ }
36
+ });
37
+
38
+ Object.defineProperty(room, "canRedoSteps", {
39
+ get() {
40
+ return manager.mainView.canRedoSteps;
41
+ }
42
+ });
43
+
32
44
  room.moveCamera = (camera: Camera) => manager.mainView.moveCamera(camera);
33
45
  room.moveCameraToContain = (...args) => manager.moveCameraToContain(...args);
34
46
  room.convertToPointInWorld = (...args) => manager.mainView.convertToPointInWorld(...args);
@@ -36,6 +48,9 @@ export const replaceRoomFunction = (room: Room, manager: WindowManager) => {
36
48
  room.scenePreview = (...args) => manager.mainView.scenePreview(...args);
37
49
  room.fillSceneSnapshot = (...args) => manager.mainView.fillSceneSnapshot(...args);
38
50
  room.generateScreenshot = (...args) => manager.mainView.generateScreenshot(...args);
51
+ room.setMemberState = (...args) => manager.mainView.setMemberState(...args);
52
+ room.redo = () => manager.mainView.redo();
53
+ room.undo = () => manager.mainView.undo();
39
54
  }
40
55
 
41
56
  };
@@ -1,17 +1,16 @@
1
- import { AnimationMode, reaction, ViewVisionMode } from "white-web-sdk";
2
- import { Base } from "./Base";
3
- import { callbacks, emitter } from "./index";
1
+ import { AnimationMode, reaction } from "white-web-sdk";
2
+ import { Base } from "../Base";
3
+ import { callbacks, emitter } from "../index";
4
4
  import { createView } from "./ViewManager";
5
5
  import { debounce, isEmpty, isEqual } from "lodash";
6
- import { Fields } from "./AttributesDelegate";
7
- import { notifyMainViewModeChange, setViewFocusScenePath, setViewMode } from "./Utils/Common";
6
+ import { Fields } from "../AttributesDelegate";
7
+ import { setViewFocusScenePath } from "../Utils/Common";
8
8
  import { SideEffectManager } from "side-effect-manager";
9
9
  import type { Camera, Size, View } from "white-web-sdk";
10
- import type { AppManager } from "./AppManager";
10
+ import type { AppManager } from "../AppManager";
11
11
 
12
12
  export class MainViewProxy extends Base {
13
13
  private scale?: number;
14
- private cameraStore = this.manager.cameraStore;
15
14
  private started = false;
16
15
  private mainViewIsAddListener = false;
17
16
  private mainView: View;
@@ -23,8 +22,8 @@ export class MainViewProxy extends Base {
23
22
  super(manager);
24
23
  this.mainView = this.createMainView();
25
24
  this.moveCameraSizeByAttributes();
26
- this.cameraStore.register(this.viewId, this.mainView);
27
25
  emitter.once("mainViewMounted").then(() => {
26
+ this.addMainViewListener();
28
27
  setTimeout(() => {
29
28
  this.start();
30
29
  if (!this.mainViewCamera || !this.mainViewSize) {
@@ -34,7 +33,7 @@ export class MainViewProxy extends Base {
34
33
  });
35
34
  const playgroundSizeChangeListener = () => {
36
35
  this.sizeChangeHandler(this.mainViewSize);
37
- }
36
+ };
38
37
  this.sideEffectManager.add(() => {
39
38
  emitter.on("playgroundSizeChange", playgroundSizeChangeListener);
40
39
  return () => emitter.off("playgroundSizeChange", playgroundSizeChangeListener);
@@ -103,9 +102,6 @@ export class MainViewProxy extends Base {
103
102
  if (mainViewScenePath) {
104
103
  setViewFocusScenePath(mainView, mainViewScenePath);
105
104
  }
106
- if (!this.store.focus) {
107
- this.switchViewModeToWriter();
108
- }
109
105
  return mainView;
110
106
  }
111
107
 
@@ -138,7 +134,6 @@ export class MainViewProxy extends Base {
138
134
 
139
135
  public async mainViewClickHandler(): Promise<void> {
140
136
  if (!this.manager.canOperate) return;
141
- if (this.view.mode === ViewVisionMode.Writable) return;
142
137
  this.store.cleanFocus();
143
138
  this.context.blurFocusBox();
144
139
  }
@@ -163,17 +158,6 @@ export class MainViewProxy extends Base {
163
158
  callbacks.emit("cameraStateChange", this.cameraState);
164
159
  };
165
160
 
166
- public switchViewModeToWriter(): void {
167
- if (!this.manager.canOperate) return;
168
- if (this.view) {
169
- if (this.view.mode === ViewVisionMode.Writable) return;
170
- this.cameraStore.switchView(this.viewId, this.mainView, () => {
171
- notifyMainViewModeChange(callbacks, ViewVisionMode.Writable);
172
- setViewMode(this.view, ViewVisionMode.Writable);
173
- });
174
- }
175
- }
176
-
177
161
  public moveCameraToContian(size: Size): void {
178
162
  if (!isEmpty(size)) {
179
163
  this.view.moveCameraToContain({
@@ -202,6 +186,7 @@ export class MainViewProxy extends Base {
202
186
  }
203
187
 
204
188
  public stop() {
189
+ this.removeMainViewListener();
205
190
  this.removeCameraListener();
206
191
  this.manager.refresher?.remove(Fields.MainViewCamera);
207
192
  this.manager.refresher?.remove(Fields.MainViewSize);
@@ -210,7 +195,6 @@ export class MainViewProxy extends Base {
210
195
 
211
196
  public destroy() {
212
197
  this.stop();
213
- this.cameraStore.unregister(this.viewId, this.mainView);
214
198
  this.sideEffectManager.flushAll();
215
199
  }
216
200
  }
@@ -0,0 +1,53 @@
1
+ import type { View , Displayer} from "white-web-sdk";
2
+
3
+ export class ViewManager {
4
+ public views: Map<string, View> = new Map();
5
+
6
+ constructor(private displayer: Displayer) {}
7
+
8
+ public createView(id: string): View {
9
+ const view = createView(this.displayer);
10
+ this.views.set(id, view);
11
+ return view;
12
+ }
13
+
14
+ public getView(id: string): View | undefined {
15
+ return this.views.get(id);
16
+ }
17
+
18
+ public destroyView(id: string): void {
19
+ const view = this.views.get(id);
20
+ if (view) {
21
+ view.release();
22
+ this.views.delete(id);
23
+ }
24
+ }
25
+
26
+ public setViewScenePath(id: string, scenePath: string): void {
27
+ const view = this.views.get(id);
28
+ if (view) {
29
+ view.focusScenePath = scenePath;
30
+ }
31
+ }
32
+
33
+ public destroy() {
34
+ this.views.forEach(view => {
35
+ view.release();
36
+ });
37
+ this.views.clear();
38
+ }
39
+ }
40
+
41
+
42
+ export const createView = (displayer: Displayer): View => {
43
+ const view = displayer.views.createView();
44
+ setDefaultCameraBound(view);
45
+ return view;
46
+ };
47
+
48
+ export const setDefaultCameraBound = (view: View) => {
49
+ view.setCameraBound({
50
+ maxContentMode: () => 10,
51
+ minContentMode: () => 0.1,
52
+ });
53
+ };
package/src/constants.ts CHANGED
@@ -37,13 +37,11 @@ export enum CursorState {
37
37
  Normal = "normal",
38
38
  }
39
39
 
40
- export const REQUIRE_VERSION = "2.13.16";
40
+ export const REQUIRE_VERSION = "2.16.0";
41
41
 
42
42
  export const MIN_WIDTH = 340 / 720;
43
43
  export const MIN_HEIGHT = 340 / 720;
44
44
 
45
45
  export const SET_SCENEPATH_DELAY = 100; // 设置 scenePath 的延迟事件
46
46
 
47
- export const DEFAULT_COLLECTOR_STYLE = { right: "10px", bottom: "15px", position: "absolute" };
48
-
49
47
  export const DEFAULT_CONTAINER_RATIO = 9 / 16;
package/src/index.ts CHANGED
@@ -1,9 +1,8 @@
1
- import AppDocsViewer from "@netless/app-docs-viewer";
2
- import AppMediaPlayer, { setOptions } from "@netless/app-media-player";
3
1
  import Emittery from "emittery";
4
2
  import pRetry from "p-retry";
5
3
  import { AppManager } from "./AppManager";
6
4
  import { appRegister } from "./Register";
5
+ import { ContainerResizeObserver } from "./ContainerResizeObserver";
7
6
  import { createBoxManager } from "./BoxManager";
8
7
  import { CursorManager } from "./Cursor";
9
8
  import { DEFAULT_CONTAINER_RATIO, Events, REQUIRE_VERSION } from "./constants";
@@ -11,9 +10,10 @@ import { Fields } from "./AttributesDelegate";
11
10
  import { initDb } from "./Register/storage";
12
11
  import { isNull, isObject } from "lodash";
13
12
  import { log } from "./Utils/log";
13
+ import { ReconnectRefresher } from "./ReconnectRefresher";
14
14
  import { replaceRoomFunction } from "./Utils/RoomHacker";
15
- import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
16
- import { setupWrapper } from "./ViewManager";
15
+ import { setupBuiltin } from "./BuiltinApps";
16
+ import { setupWrapper } from "./Helper";
17
17
  import "./style.css";
18
18
  import "@netless/telebox-insider/dist/style.css";
19
19
  import {
@@ -59,8 +59,6 @@ import type { NetlessApp, RegisterParams } from "./typings";
59
59
  import type { TeleBoxColorScheme, TeleBoxState } from "@netless/telebox-insider";
60
60
  import type { AppProxy } from "./AppProxy";
61
61
 
62
- const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
63
-
64
62
  export type WindowMangerAttributes = {
65
63
  modelValue?: string;
66
64
  boxState: TELE_BOX_STATE;
@@ -81,14 +79,14 @@ export type AddAppOptions = {
81
79
 
82
80
  export type setAppOptions = AddAppOptions & { appOptions?: any };
83
81
 
84
- export type AddAppParams = {
82
+ export type AddAppParams<TAttributes = any> = {
85
83
  kind: string;
86
84
  // app 地址(本地 app 不需要传)
87
85
  src?: string;
88
86
  // 窗口配置
89
87
  options?: AddAppOptions;
90
88
  // 初始化 attributes
91
- attributes?: any;
89
+ attributes?: TAttributes;
92
90
  };
93
91
 
94
92
  export type BaseInsertParams = {
@@ -139,6 +137,7 @@ export type EmitterEvent = {
139
137
  observerIdChange: number;
140
138
  boxStateChange: string;
141
139
  playgroundSizeChange: DOMRect;
140
+ onReconnected: void;
142
141
  };
143
142
 
144
143
  export type EmitterType = Emittery<EmitterEvent>;
@@ -150,6 +149,8 @@ export type PublicEvent = {
150
149
  darkModeChange: boolean;
151
150
  prefersColorSchemeChange: TeleBoxColorScheme;
152
151
  cameraStateChange: CameraState;
152
+ mainViewScenePathChange: string;
153
+ mainViewSceneIndexChange: number;
153
154
  };
154
155
 
155
156
  export type MountParams = {
@@ -171,6 +172,8 @@ export type MountParams = {
171
172
  export type CallbacksType = Emittery<PublicEvent>;
172
173
  export const callbacks: CallbacksType = new Emittery();
173
174
 
175
+ export const reconnectRefresher = new ReconnectRefresher({ emitter });
176
+
174
177
  export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
175
178
  public static kind = "WindowManager";
176
179
  public static displayer: Displayer;
@@ -181,7 +184,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
181
184
  public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;
182
185
  private static isCreated = false;
183
186
 
184
- public version = "0.4.0-canary.1";
187
+ public version = __APP_VERSION__;
185
188
 
186
189
  public appListeners?: AppListeners;
187
190
 
@@ -195,6 +198,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
195
198
  private boxManager?: BoxManager;
196
199
  private static params?: MountParams;
197
200
 
201
+ private containerResizeObserver?: ContainerResizeObserver;
202
+
198
203
  constructor(context: InvisiblePluginContext) {
199
204
  super(context);
200
205
  WindowManager.displayer = context.displayer;
@@ -214,15 +219,16 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
214
219
  if (room.phase !== RoomPhase.Connected) {
215
220
  throw new Error("[WindowManager]: Room only Connected can be mount");
216
221
  }
222
+ if (room.phase === RoomPhase.Connected) {
223
+ // redo undo 需要设置这个属性
224
+ room.disableSerialization = false;
225
+ }
217
226
  }
218
227
  if (WindowManager.isCreated) {
219
228
  throw new Error("[WindowManager]: Already created cannot be created again");
220
229
  }
221
230
  let manager = await this.initManager(room);
222
231
  this.debug = Boolean(debug);
223
- if (this.debug) {
224
- setOptions({ verbose: true });
225
- }
226
232
  log("Already insert room", manager);
227
233
 
228
234
  if (isRoom(this.displayer)) {
@@ -254,7 +260,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
254
260
  }
255
261
 
256
262
  if (params.container) {
257
- manager.bindContainer(params.container, params.collectorContainer);
263
+ manager.bindContainer(params.container);
258
264
  }
259
265
 
260
266
  replaceRoomFunction(room, manager);
@@ -316,12 +322,17 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
316
322
  style.textContent = overwriteStyles;
317
323
  playground.appendChild(style);
318
324
  }
319
- manager.observePlaygroundSize(playground, sizer, wrapper);
325
+ manager.containerResizeObserver = ContainerResizeObserver.create(
326
+ playground,
327
+ sizer,
328
+ wrapper,
329
+ emitter
330
+ );
320
331
  WindowManager.wrapper = wrapper;
321
332
  return mainViewElement;
322
333
  }
323
334
 
324
- public bindContainer(container: HTMLElement, collectorContainer?: HTMLElement) {
335
+ public bindContainer(container: HTMLElement) {
325
336
  if (WindowManager.isCreated && WindowManager.container) {
326
337
  if (WindowManager.container.firstChild) {
327
338
  container.appendChild(WindowManager.container.firstChild);
@@ -336,7 +347,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
336
347
  params.overwriteStyles
337
348
  );
338
349
  const boxManager = createBoxManager(this, callbacks, emitter, {
339
- collectorContainer: collectorContainer,
350
+ collectorContainer: params.collectorContainer,
340
351
  collectorStyles: params.collectorStyles,
341
352
  prefersColorScheme: params.prefersColorScheme,
342
353
  });
@@ -355,6 +366,16 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
355
366
  WindowManager.container = container;
356
367
  }
357
368
 
369
+ public bindCollectorContainer(container: HTMLElement) {
370
+ if (WindowManager.isCreated && this.boxManager) {
371
+ this.boxManager.setCollectorContainer(container);
372
+ } else {
373
+ if (WindowManager.params) {
374
+ WindowManager.params.collectorContainer = container;
375
+ }
376
+ }
377
+ }
378
+
358
379
  /**
359
380
  * 注册插件
360
381
  */
@@ -364,21 +385,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
364
385
  return appRegister.register(params);
365
386
  }
366
387
 
367
- public static setCollectorContainer(container: HTMLElement) {
368
- const manager = this.displayer.getInvisiblePlugin(this.kind) as WindowManager;
369
- if (this.isCreated && manager) {
370
- manager.boxManager?.setCollectorContainer(container);
371
- } else {
372
- if (this.params) {
373
- this.params.collectorContainer = container;
374
- }
375
- }
376
- }
377
-
378
388
  /**
379
389
  * 创建一个 app 至白板
380
390
  */
381
- public async addApp(params: AddAppParams): Promise<string | undefined> {
391
+ public async addApp<T = any>(params: AddAppParams<T>): Promise<string | undefined> {
382
392
  if (this.appManager) {
383
393
  if (!params.kind || typeof params.kind !== "string") {
384
394
  throw new ParamsInvalidError();
@@ -475,10 +485,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
475
485
  * 设置所有 app 的 readonly 模式
476
486
  */
477
487
  public setReadonly(readonly: boolean): void {
478
- if (this.room?.isWritable) {
479
- this.readonly = readonly;
480
- this.appManager?.boxManager?.setReadonly(readonly);
481
- }
488
+ this.readonly = readonly;
489
+ this.boxManager?.setReadonly(readonly);
482
490
  }
483
491
 
484
492
  /**
@@ -558,6 +566,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
558
566
  }
559
567
  }
560
568
 
569
+ public get focused(): string | undefined {
570
+ return this.attributes.focus;
571
+ }
572
+
561
573
  /**
562
574
  * 查询所有的 App
563
575
  */
@@ -698,62 +710,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
698
710
  }
699
711
  }
700
712
  }
701
-
702
- private containerResizeObserver?: ResizeObserver;
703
-
704
- private observePlaygroundSize(
705
- container: HTMLElement,
706
- sizer: HTMLElement,
707
- wrapper: HTMLDivElement
708
- ) {
709
- this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
710
-
711
- this.containerResizeObserver = new ResizeObserver(entries => {
712
- const containerRect = entries[0]?.contentRect;
713
- if (containerRect) {
714
- this.updateSizer(containerRect, sizer, wrapper);
715
- this.cursorManager?.updateContainerRect();
716
- this.boxManager?.updateManagerRect();
717
- emitter.emit("playgroundSizeChange", containerRect);
718
- }
719
- });
720
-
721
- this.containerResizeObserver.observe(container);
722
- }
723
-
724
- private updateSizer(
725
- { width, height }: DOMRectReadOnly,
726
- sizer: HTMLElement,
727
- wrapper: HTMLDivElement
728
- ) {
729
- if (width && height) {
730
- if (height / width > WindowManager.containerSizeRatio) {
731
- height = width * WindowManager.containerSizeRatio;
732
- sizer.classList.toggle("netless-window-manager-sizer-horizontal", true);
733
- } else {
734
- width = height / WindowManager.containerSizeRatio;
735
- sizer.classList.toggle("netless-window-manager-sizer-horizontal", false);
736
- }
737
- wrapper.style.width = `${width}px`;
738
- wrapper.style.height = `${height}px`;
739
- }
740
- }
741
713
  }
742
714
 
743
- WindowManager.register({
744
- kind: AppDocsViewer.kind,
745
- src: AppDocsViewer,
746
- });
747
- WindowManager.register({
748
- kind: AppMediaPlayer.kind,
749
- src: AppMediaPlayer,
750
- });
751
-
752
- export const BuiltinApps = {
753
- DocsViewer: AppDocsViewer.kind as string,
754
- MediaPlayer: AppMediaPlayer.kind as string,
755
- };
715
+ setupBuiltin();
756
716
 
757
717
  export * from "./typings";
758
718
 
759
- export { WhiteWindowSDK } from "./sdk";
719
+ export { BuiltinApps } from "./BuiltinApps";
package/src/shim.d.ts CHANGED
@@ -4,3 +4,7 @@ declare module "*.svelte" {
4
4
  const app: SvelteComponent;
5
5
  export default app;
6
6
  }
7
+
8
+ declare global {
9
+ const __APP_VERSION__: string;
10
+ }
package/src/style.css CHANGED
@@ -167,3 +167,9 @@
167
167
  display: flex;
168
168
  justify-content: center;
169
169
  }
170
+
171
+ .telebox-collector {
172
+ position: absolute;
173
+ right: 10px;
174
+ bottom: 15px;
175
+ }
package/src/typings.ts CHANGED
@@ -76,3 +76,4 @@ export type AppListenerKeys = keyof AppEmitterEvent;
76
76
  export type { AppContext } from "./AppContext";
77
77
  export type { ReadonlyTeleBox, TeleBoxRect };
78
78
  export type { SceneState, SceneDefinition, View, AnimationMode, Displayer, Room, Player };
79
+ export type { Storage, StorageStateChangedEvent, StorageStateChangedListener } from "./App/Storage";
package/vite.config.js CHANGED
@@ -1,13 +1,16 @@
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 } from "./package.json"
4
+ import { dependencies ,peerDependencies, version } from "./package.json"
5
5
 
6
6
 
7
7
  export default defineConfig(({ mode }) => {
8
8
  const isProd = mode === "production";
9
9
 
10
10
  return {
11
+ define: {
12
+ __APP_VERSION__: JSON.stringify(version),
13
+ },
11
14
  plugins: [
12
15
  svelte({
13
16
  emitCss: false,
@@ -1,15 +0,0 @@
1
- import type { Camera, View } from "white-web-sdk";
2
- export declare class CameraStore {
3
- private cameras;
4
- private listeners;
5
- setCamera(id: string, camera: Camera): void;
6
- getCamera(id: string): Camera | undefined;
7
- deleteCamera(id: string): void;
8
- recoverCamera(id: string, view?: View): void;
9
- register(id: string, view: View): void;
10
- unregister(id: string, view?: View): void;
11
- private onListener;
12
- private offListener;
13
- switchView(id: string, view: View | undefined, callback: () => void): Promise<void>;
14
- private getOrCreateListener;
15
- }
@@ -1,29 +0,0 @@
1
- import { Base } from "./Base";
2
- import type { View, Displayer } from "white-web-sdk";
3
- import type { AppManager } from "./AppManager";
4
- export declare class ViewManager extends Base {
5
- private views;
6
- private timer?;
7
- private appTimer?;
8
- private mainViewProxy;
9
- private displayer;
10
- constructor(manager: AppManager);
11
- get currentScenePath(): string;
12
- get mainView(): View;
13
- createView(appId: string): View;
14
- destroyView(appId: string): void;
15
- private releaseView;
16
- getView(appId: string): View | undefined;
17
- switchMainViewToWriter(): Promise<boolean> | undefined;
18
- freedomAllViews(): void;
19
- switchAppToWriter(id: string): void;
20
- destroy(): void;
21
- }
22
- export declare const createView: (displayer: Displayer) => View;
23
- export declare const setDefaultCameraBound: (view: View) => void;
24
- export declare const setupWrapper: (root: HTMLElement) => {
25
- playground: HTMLDivElement;
26
- wrapper: HTMLDivElement;
27
- sizer: HTMLDivElement;
28
- mainViewElement: HTMLDivElement;
29
- };