@netless/window-manager 1.0.0-canary.3 → 1.0.0-canary.32

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 (87) hide show
  1. package/__mocks__/white-web-sdk.ts +10 -1
  2. package/dist/index.cjs.js +120 -12
  3. package/dist/index.es.js +2284 -954
  4. package/dist/index.umd.js +120 -12
  5. package/dist/{App → src/App}/AppContext.d.ts +12 -8
  6. package/dist/{App → src/App}/AppPageStateImpl.d.ts +0 -0
  7. package/dist/{App → src/App}/AppProxy.d.ts +36 -7
  8. package/dist/{App → src/App}/MagixEvent/index.d.ts +0 -0
  9. package/dist/{App → src/App}/Storage/StorageEvent.d.ts +0 -0
  10. package/dist/{App → src/App}/Storage/index.d.ts +0 -0
  11. package/dist/{App → src/App}/Storage/typings.d.ts +0 -0
  12. package/dist/{App → src/App}/Storage/utils.d.ts +0 -0
  13. package/dist/src/App/WhiteboardView.d.ts +27 -0
  14. package/dist/{App → src/App}/index.d.ts +2 -1
  15. package/dist/src/App/type.d.ts +21 -0
  16. package/dist/{AppListener.d.ts → src/AppListener.d.ts} +0 -2
  17. package/dist/{AppManager.d.ts → src/AppManager.d.ts} +7 -6
  18. package/dist/{AttributesDelegate.d.ts → src/AttributesDelegate.d.ts} +11 -16
  19. package/dist/{BoxEmitter.d.ts → src/BoxEmitter.d.ts} +0 -0
  20. package/dist/{BoxManager.d.ts → src/BoxManager.d.ts} +10 -7
  21. package/dist/{BuiltinApps.d.ts → src/BuiltinApps.d.ts} +3 -0
  22. package/dist/{Cursor → src/Cursor}/Cursor.d.ts +0 -0
  23. package/dist/{Cursor → src/Cursor}/icons.d.ts +0 -0
  24. package/dist/{Cursor → src/Cursor}/index.d.ts +3 -3
  25. package/dist/{Helper.d.ts → src/Helper.d.ts} +4 -8
  26. package/dist/{InternalEmitter.d.ts → src/InternalEmitter.d.ts} +3 -4
  27. package/dist/{Page → src/Page}/PageController.d.ts +1 -0
  28. package/dist/{Page → src/Page}/index.d.ts +0 -0
  29. package/dist/{PageState.d.ts → src/PageState.d.ts} +0 -0
  30. package/dist/{ReconnectRefresher.d.ts → src/ReconnectRefresher.d.ts} +1 -1
  31. package/dist/{RedoUndo.d.ts → src/RedoUndo.d.ts} +0 -0
  32. package/dist/{Register → src/Register}/index.d.ts +0 -0
  33. package/dist/{Register → src/Register}/loader.d.ts +0 -0
  34. package/dist/{Register → src/Register}/storage.d.ts +0 -0
  35. package/dist/{Utils → src/Utils}/AppCreateQueue.d.ts +0 -0
  36. package/dist/{Utils → src/Utils}/Common.d.ts +1 -0
  37. package/dist/{Utils → src/Utils}/Reactive.d.ts +0 -0
  38. package/dist/{Utils → src/Utils}/RoomHacker.d.ts +0 -0
  39. package/dist/{Utils → src/Utils}/error.d.ts +0 -0
  40. package/dist/{Utils → src/Utils}/log.d.ts +0 -0
  41. package/dist/src/View/CameraSynchronizer.d.ts +18 -0
  42. package/dist/{View → src/View}/MainView.d.ts +18 -7
  43. package/dist/{View → src/View}/ViewManager.d.ts +0 -0
  44. package/dist/src/View/ViewSync.d.ts +24 -0
  45. package/dist/{callback.d.ts → src/callback.d.ts} +5 -0
  46. package/dist/{constants.d.ts → src/constants.d.ts} +8 -5
  47. package/dist/src/image.d.ts +19 -0
  48. package/dist/{index.d.ts → src/index.d.ts} +40 -14
  49. package/dist/src/shim.d.ts +11 -0
  50. package/dist/{typings.d.ts → src/typings.d.ts} +8 -2
  51. package/dist/style.css +1 -1
  52. package/docs/app-context.md +157 -25
  53. package/docs/mirgrate-to-1.0.md +28 -0
  54. package/package.json +12 -7
  55. package/playwright.config.ts +29 -0
  56. package/pnpm-lock.yaml +517 -35
  57. package/src/App/AppContext.ts +50 -28
  58. package/src/App/AppProxy.ts +266 -80
  59. package/src/App/{WhiteBoardView.ts → WhiteboardView.ts} +38 -7
  60. package/src/App/index.ts +2 -1
  61. package/src/App/type.ts +22 -0
  62. package/src/AppListener.ts +5 -21
  63. package/src/AppManager.ts +56 -43
  64. package/src/AttributesDelegate.ts +19 -19
  65. package/src/BoxManager.ts +60 -40
  66. package/src/BuiltinApps.ts +5 -0
  67. package/src/Cursor/Cursor.ts +7 -3
  68. package/src/Cursor/index.ts +7 -8
  69. package/src/Helper.ts +25 -7
  70. package/src/InternalEmitter.ts +3 -4
  71. package/src/Page/PageController.ts +1 -0
  72. package/src/PageState.ts +1 -1
  73. package/src/ReconnectRefresher.ts +7 -2
  74. package/src/Utils/Common.ts +9 -0
  75. package/src/Utils/Reactive.ts +27 -26
  76. package/src/Utils/RoomHacker.ts +3 -0
  77. package/src/View/CameraSynchronizer.ts +37 -34
  78. package/src/View/MainView.ts +108 -81
  79. package/src/View/ViewSync.ts +110 -0
  80. package/src/callback.ts +1 -0
  81. package/src/constants.ts +6 -3
  82. package/src/index.ts +141 -57
  83. package/src/style.css +3 -46
  84. package/src/typings.ts +8 -2
  85. package/vite.config.js +5 -3
  86. package/dist/App/WhiteBoardView.d.ts +0 -18
  87. package/dist/View/CameraSynchronizer.d.ts +0 -17
package/src/BoxManager.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
2
2
  import { debounce } from "lodash";
3
+ import { SideEffectManager } from "side-effect-manager";
3
4
  import { TELE_BOX_STATE, TeleBoxManager } from "@netless/telebox-insider";
4
5
  import { WindowManager } from "./index";
6
+ import type { Writeable } from "./typings";
5
7
  import type { BoxEmitterType } from "./BoxEmitter";
6
- import type { AddAppOptions, AppInitState } from "./index";
8
+ import type { AddAppOptions } from "./index";
7
9
  import type {
8
10
  TeleBoxManagerUpdateConfig,
9
11
  TeleBoxManagerCreateConfig,
@@ -12,13 +14,14 @@ import type {
12
14
  TeleBoxColorScheme,
13
15
  TeleBoxRect,
14
16
  TeleBoxConfig,
17
+ TeleBoxFullscreen
15
18
  } from "@netless/telebox-insider";
16
19
  import type Emittery from "emittery";
17
20
  import type { NetlessApp } from "./typings";
18
21
  import type { View } from "white-web-sdk";
19
22
  import type { CallbacksType } from "./callback";
20
23
  import type { EmitterType } from "./InternalEmitter";
21
- import { SideEffectManager } from "side-effect-manager";
24
+ import type { AppState } from "./App/type";
22
25
 
23
26
  export { TELE_BOX_STATE };
24
27
 
@@ -47,11 +50,13 @@ export type CreateTeleBoxManagerConfig = {
47
50
  collectorStyles?: Partial<CSSStyleDeclaration>;
48
51
  prefersColorScheme?: TeleBoxColorScheme;
49
52
  stageRatio?: number;
53
+ containerStyle?: string;
54
+ stageStyle?: string;
55
+ fullscreen?: TeleBoxFullscreen;
50
56
  };
51
57
 
52
58
  export type BoxManagerContext = {
53
59
  safeSetAttributes: (attributes: any) => void;
54
- getMainView: () => View;
55
60
  updateAppState: (appId: string, field: AppAttributes, value: any) => void;
56
61
  emitter: EmitterType;
57
62
  boxEmitter: BoxEmitterType;
@@ -72,7 +77,6 @@ export const createBoxManager = (
72
77
  return new BoxManager(
73
78
  {
74
79
  safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),
75
- getMainView: () => manager.mainView,
76
80
  updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),
77
81
  canOperate: () => manager.canOperate,
78
82
  notifyContainerRectUpdate: (rect: TeleBoxRect) =>
@@ -81,7 +85,7 @@ export const createBoxManager = (
81
85
  setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
82
86
  callbacks,
83
87
  emitter,
84
- boxEmitter
88
+ boxEmitter,
85
89
  },
86
90
  options
87
91
  );
@@ -100,17 +104,17 @@ export class BoxManager {
100
104
  this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
101
105
  this.sideEffectManager.add(() => [
102
106
  // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
103
- this.teleBoxManager._state$.reaction(state => {
107
+ this.teleBoxManager.onValChanged("state", state => {
104
108
  callbacks.emit("boxStateChange", state);
105
109
  emitter.emit("boxStateChange", state);
106
110
  }),
107
- this.teleBoxManager._darkMode$.reaction(darkMode => {
111
+ this.teleBoxManager.onValChanged("darkMode", darkMode => {
108
112
  callbacks.emit("darkModeChange", darkMode);
109
113
  }),
110
- this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
114
+ this.teleBoxManager.onValChanged("prefersColorScheme", colorScheme => {
111
115
  callbacks.emit("prefersColorSchemeChange", colorScheme);
112
116
  }),
113
- this.teleBoxManager._minimized$.reaction((minimized, skipUpdate) => {
117
+ this.teleBoxManager.onValChanged("minimized", (minimized, skipUpdate) => {
114
118
  if (skipUpdate) {
115
119
  return;
116
120
  }
@@ -126,7 +130,7 @@ export class BoxManager {
126
130
  }
127
131
  }
128
132
  }),
129
- this.teleBoxManager._maximized$.reaction((maximized, skipUpdate) => {
133
+ this.teleBoxManager.onValChanged("maximized", (maximized, skipUpdate) => {
130
134
  if (skipUpdate) {
131
135
  return;
132
136
  }
@@ -140,7 +144,11 @@ export class BoxManager {
140
144
  this.teleBoxManager.events.on(
141
145
  "intrinsic_move",
142
146
  debounce((box: ReadonlyTeleBox): void => {
143
- boxEmitter.emit("move", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });
147
+ boxEmitter.emit("move", {
148
+ appId: box.id,
149
+ x: box.intrinsicX,
150
+ y: box.intrinsicY,
151
+ });
144
152
  }, 50)
145
153
  ),
146
154
  this.teleBoxManager.events.on(
@@ -165,23 +173,12 @@ export class BoxManager {
165
173
  this.teleBoxManager.events.on("z_index", box => {
166
174
  this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
167
175
  }),
168
- this.teleBoxManager._stageRect$.subscribe(stage => {
169
- emitter.emit("playgroundSizeChange", stage);
170
- this.context.notifyContainerRectUpdate(stage);
171
- }),
172
- emitter.on("writableChange", isWritable => {
173
- this.teleBoxManager.setHighlightStage(isWritable);
174
- }),
175
176
  emitter.on("containerSizeRatioUpdate", ratio => {
176
177
  this.teleBoxManager._stageRatio$.setValue(ratio);
177
178
  }),
178
179
  ]);
179
180
  }
180
181
 
181
- private get mainView() {
182
- return this.context.getMainView();
183
- }
184
-
185
182
  private get canOperate() {
186
183
  return this.context.canOperate();
187
184
  }
@@ -214,9 +211,14 @@ export class BoxManager {
214
211
  return this.teleBoxManager.stageRect;
215
212
  }
216
213
 
217
- public createBox(params: CreateBoxParams): void {
214
+ public get stageRect$() {
215
+ return this.teleBoxManager._stageRect$;
216
+ }
217
+
218
+ public createBox(params: CreateBoxParams): ReadonlyTeleBox | undefined {
218
219
  if (!this.teleBoxManager) return;
219
- let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
220
+ // eslint-disable-next-line prefer-const
221
+ let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT, enableShadowDOM = true } = params.app.config ?? {};
220
222
  const { width, height } = params.app.config ?? {};
221
223
  const title = params.options?.title || params.appId;
222
224
  const rect = this.teleBoxManager.rootRect;
@@ -236,22 +238,36 @@ export class BoxManager {
236
238
  width,
237
239
  height,
238
240
  id: params.appId,
241
+ enableShadowDOM,
239
242
  };
240
- this.teleBoxManager.create(createBoxConfig, params.smartPosition);
243
+ const box = this.teleBoxManager.create(createBoxConfig, params.smartPosition);
241
244
  this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);
245
+ return box;
242
246
  }
243
247
 
244
248
  public setupBoxManager(
245
249
  createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig
246
250
  ): TeleBoxManager {
247
251
  const root = WindowManager.playground;
248
- const initManagerState: TeleBoxManagerConfig = {
252
+ const initManagerState: Writeable<TeleBoxManagerConfig> = {
249
253
  stageRatio: createTeleBoxManagerConfig?.stageRatio,
250
254
  root: root,
251
255
  fence: false,
252
256
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
253
257
  };
254
258
 
259
+ if (createTeleBoxManagerConfig?.containerStyle) {
260
+ initManagerState.containerStyle = createTeleBoxManagerConfig.containerStyle;
261
+ }
262
+
263
+ if (createTeleBoxManagerConfig?.stageStyle) {
264
+ initManagerState.stageStyle = createTeleBoxManagerConfig.stageStyle;
265
+ }
266
+
267
+ if (createTeleBoxManagerConfig?.fullscreen) {
268
+ initManagerState.fullscreen = createTeleBoxManagerConfig.fullscreen;
269
+ }
270
+
255
271
  const manager = new TeleBoxManager(initManagerState);
256
272
  if (this.teleBoxManager) {
257
273
  this.teleBoxManager.destroy();
@@ -289,21 +305,19 @@ export class BoxManager {
289
305
  return this.teleBoxManager.topBox;
290
306
  }
291
307
 
292
- public updateBoxState(state?: AppInitState): void {
308
+ public updateBoxState(state?: AppState): void {
293
309
  if (!state) return;
294
310
  const box = this.getBox(state.id);
295
311
  if (box) {
296
- this.teleBoxManager.update(
297
- box.id,
298
- {
299
- x: state.x,
300
- y: state.y,
301
- width: state.width || 0.5,
302
- height: state.height || 0.5,
303
- zIndex: state.zIndex,
304
- },
305
- true
306
- );
312
+ if (state.size) {
313
+ box._intrinsicSize$.setValue(state.size, true);
314
+ }
315
+ if (state.position) {
316
+ box._intrinsicCoord$.setValue(state.position, true);
317
+ }
318
+ if (state.zIndex) {
319
+ box._zIndex$.setValue(state.zIndex, true);
320
+ }
307
321
  setTimeout(() => {
308
322
  if (state.focus) {
309
323
  this.teleBoxManager.focusBox(box.id, true);
@@ -320,7 +334,10 @@ export class BoxManager {
320
334
  }
321
335
 
322
336
  public moveBox({ appId, x, y }: MoveBoxParams): void {
323
- this.teleBoxManager.update(appId, { x, y }, true);
337
+ const box = this.getBox(appId);
338
+ if (box) {
339
+ box._intrinsicCoord$.setValue({ x, y}, true);
340
+ }
324
341
  }
325
342
 
326
343
  public focusBox({ appId }: AppId, skipUpdate = true): void {
@@ -328,7 +345,10 @@ export class BoxManager {
328
345
  }
329
346
 
330
347
  public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {
331
- this.teleBoxManager.update(appId, { width, height }, skipUpdate);
348
+ const box = this.getBox(appId);
349
+ if (box) {
350
+ box._intrinsicSize$.setValue({ width, height }, skipUpdate);
351
+ }
332
352
  }
333
353
 
334
354
  public setBoxMinSize(params: SetBoxMinSizeParams): void {
@@ -21,3 +21,8 @@ export const BuiltinApps = {
21
21
  DocsViewer: AppDocsViewer.kind as string,
22
22
  MediaPlayer: AppMediaPlayer.kind as string,
23
23
  };
24
+
25
+ export const BuiltinAppsMap = {
26
+ [BuiltinApps.DocsViewer]: AppDocsViewer,
27
+ [BuiltinApps.MediaPlayer]: AppMediaPlayer,
28
+ }
@@ -7,6 +7,7 @@ import type { RoomMember } from "white-web-sdk";
7
7
  import type { CursorManager } from "./index";
8
8
  import type { SvelteComponent } from "svelte";
9
9
  import type { AppManager } from "../AppManager";
10
+ import type { TeleBoxRect } from "@netless/telebox-insider";
10
11
 
11
12
  export type Payload = {
12
13
  [key: string]: any;
@@ -30,7 +31,7 @@ export class Cursor {
30
31
 
31
32
  public move = (position: Position) => {
32
33
  if (position.type === "main") {
33
- const rect = this.cursorManager.wrapperRect;
34
+ const rect = this.manager.boxManager?.stageRect;
34
35
  if (this.component && rect) {
35
36
  this.autoHidden();
36
37
  this.moveCursor(position, rect, this.manager.mainView);
@@ -50,18 +51,21 @@ export class Cursor {
50
51
  this.hide();
51
52
  };
52
53
 
53
- private moveCursor(cursor: Position, rect: DOMRect, view: any) {
54
+ private moveCursor(cursor: Position, rect: TeleBoxRect, view: any) {
54
55
  const { x, y, type } = cursor;
55
56
  const point = view?.screen.convertPointToScreen(x, y);
56
57
  if (point) {
57
58
  let translateX = point.x - 2;
58
59
  let translateY = point.y - 18;
59
60
  if (type === "app") {
60
- const wrapperRect = this.cursorManager.wrapperRect;
61
+ const wrapperRect = this.cursorManager.playgroundRect;
61
62
  if (wrapperRect) {
62
63
  translateX = translateX + rect.x - wrapperRect.x;
63
64
  translateY = translateY + rect.y - wrapperRect.y;
64
65
  }
66
+ } else {
67
+ translateX = translateX + rect.x;
68
+ translateY = translateY + rect.y;
65
69
  }
66
70
  if (point.x < 0 || point.x > rect.width || point.y < 0 || point.y > rect.height) {
67
71
  this.component?.$set({ visible: false, x: translateX, y: translateY });
@@ -5,7 +5,7 @@ import { emitter } from "../InternalEmitter";
5
5
  import { SideEffectManager } from "side-effect-manager";
6
6
  import { throttle } from "lodash";
7
7
  import { WindowManager } from "../index";
8
- import type { CursorMovePayload , ApplianceIcons} from "../index";
8
+ import type { CursorMovePayload , ApplianceIcons, TeleBoxRect } from "../index";
9
9
  import type { PositionType } from "../AttributesDelegate";
10
10
  import type { Point, RoomMember, View } from "white-web-sdk";
11
11
  import type { AppManager } from "../AppManager";
@@ -23,8 +23,8 @@ export type MoveCursorParams = {
23
23
  };
24
24
 
25
25
  export class CursorManager {
26
- public containerRect?: DOMRect;
27
- public wrapperRect?: DOMRect;
26
+ public wrapperRect?: TeleBoxRect;
27
+ public playgroundRect?: DOMRect;
28
28
  public cursorInstances: Map<string, Cursor> = new Map();
29
29
  public roomMembers?: readonly RoomMember[];
30
30
  private mainViewElement?: HTMLDivElement;
@@ -89,8 +89,7 @@ export class CursorManager {
89
89
  wrapper.removeEventListener("pointerleave", this.mouseLeaveListener);
90
90
  };
91
91
  });
92
-
93
- this.wrapperRect = wrapper.getBoundingClientRect();
92
+ this.updateContainerRect();
94
93
  }
95
94
 
96
95
  public setMainViewDivElement(div: HTMLDivElement) {
@@ -110,7 +109,7 @@ export class CursorManager {
110
109
  if (!event.isPrimary) return;
111
110
  }
112
111
  this.updateCursor(this.getType(event), event.clientX, event.clientY);
113
- }, 16);
112
+ }, 48);
114
113
 
115
114
  private updateCursor(event: EventType, clientX: number, clientY: number) {
116
115
  if (this.wrapperRect && this.manager.canOperate) {
@@ -168,8 +167,8 @@ export class CursorManager {
168
167
  };
169
168
 
170
169
  public updateContainerRect() {
171
- this.containerRect = WindowManager.container?.getBoundingClientRect();
172
- this.wrapperRect = WindowManager.playground?.getBoundingClientRect();
170
+ this.wrapperRect = this.manager.boxManager?.stageRect;
171
+ this.playgroundRect = WindowManager.playground?.getBoundingClientRect();
173
172
  }
174
173
 
175
174
  public deleteCursor(uid: string) {
package/src/Helper.ts CHANGED
@@ -1,11 +1,14 @@
1
- import { getVersionNumber } from "./Utils/Common";
1
+ import { getVersionNumber, wait } from "./Utils/Common";
2
+ import { log } from "./Utils/log";
2
3
  import { REQUIRE_VERSION } from "./constants";
3
- import { WhiteVersion } from "white-web-sdk";
4
+ import { toJS, WhiteVersion } from "white-web-sdk";
4
5
  import { WhiteWebSDKInvalidError } from "./Utils/error";
5
- import type { Room , RoomMember} from "white-web-sdk";
6
+ import { WindowManager } from "./index";
7
+ import type { Room, RoomMember } from "white-web-sdk";
6
8
 
7
9
  export const setupWrapper = (
8
- root: HTMLElement
10
+ root: HTMLElement,
11
+ target: HTMLElement
9
12
  ): {
10
13
  playground: HTMLDivElement;
11
14
  mainViewElement: HTMLDivElement;
@@ -15,7 +18,7 @@ export const setupWrapper = (
15
18
 
16
19
  const mainViewElement = document.createElement("div");
17
20
  mainViewElement.className = "netless-window-manager-main-view";
18
- playground.appendChild(mainViewElement);
21
+ target.appendChild(mainViewElement);
19
22
  root.appendChild(playground);
20
23
 
21
24
  return { playground, mainViewElement };
@@ -38,6 +41,21 @@ export type Member = RoomMember & { uid: string };
38
41
  export const serializeRoomMembers = (members: readonly RoomMember[]) => {
39
42
  return members.map(member => ({
40
43
  uid: member.payload?.uid || "",
41
- ...member,
44
+ ...toJS(member),
42
45
  }));
43
- }
46
+ };
47
+
48
+ export const createInvisiblePlugin = async (room: Room) => {
49
+ try {
50
+ const manager = (await room.createInvisiblePlugin(WindowManager, {})) as WindowManager;
51
+ return manager;
52
+ } catch (error) {
53
+ // 如果有两个用户同时调用 WindowManager.mount 有概率出现这个错误
54
+ if (error.message === `invisible plugin "WindowManager" exits`) {
55
+ await wait(200);
56
+ return room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
57
+ } else {
58
+ log("createInvisiblePlugin failed", error);
59
+ }
60
+ }
61
+ };
@@ -1,7 +1,7 @@
1
1
  import Emittery from "emittery";
2
2
  import type { TeleBoxRect } from "@netless/telebox-insider";
3
- import type { AppInitState, CursorMovePayload } from "./index";
4
- import type { Member } from "./Helper";
3
+ import type { CursorMovePayload } from "./index";
4
+ import type { MemberState } from "white-web-sdk";
5
5
 
6
6
  export type RemoveSceneParams = {
7
7
  scenePath: string;
@@ -10,7 +10,6 @@ export type RemoveSceneParams = {
10
10
 
11
11
  export type EmitterEvent = {
12
12
  onCreated: undefined;
13
- InitReplay: AppInitState;
14
13
  error: Error;
15
14
  seekStart: undefined;
16
15
  seek: number;
@@ -30,7 +29,7 @@ export type EmitterEvent = {
30
29
  changePageState: undefined;
31
30
  writableChange: boolean;
32
31
  containerSizeRatioUpdate: number;
33
- roomMembersChange: Member[];
32
+ memberStateChange: MemberState;
34
33
  };
35
34
 
36
35
  export type EmitterType = Emittery<EmitterEvent>;
@@ -13,6 +13,7 @@ export type PageState = {
13
13
  export interface PageController {
14
14
  nextPage: () => Promise<boolean>;
15
15
  prevPage: () => Promise<boolean>;
16
+ jumpPage: (index: number) => Promise<boolean>;
16
17
  addPage: (params?: AddPageParams) => Promise<void>;
17
18
  removePage: (index: number) => Promise<boolean>;
18
19
  pageState: PageState;
package/src/PageState.ts CHANGED
@@ -6,7 +6,7 @@ import type { PageState } from "./Page";
6
6
  export class PageStateImpl {
7
7
  constructor(private manager: AppManager) {
8
8
  emitter.on("changePageState", () => {
9
- callbacks.emit("pageStateChange", this.toObject());
9
+ callbacks.emit("pageStateChange", this.toObject());
10
10
  });
11
11
  }
12
12
 
@@ -46,14 +46,18 @@ export class ReconnectRefresher {
46
46
  this.ctx.emitter.emit("startReconnect");
47
47
  }
48
48
  if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
49
- this.room?.dispatchMagixEvent(EnsureReconnectEvent, {});
49
+ if (this.room?.isWritable) {
50
+ this.room?.dispatchMagixEvent(EnsureReconnectEvent, {});
51
+ } else {
52
+ this.onReconnected();
53
+ }
50
54
  }
51
55
  this.phase = phase;
52
56
  };
53
57
 
54
58
  private onReconnected = debounce(() => {
55
59
  this._onReconnected();
56
- }, 3000);
60
+ }, 1000);
57
61
 
58
62
  private _onReconnected = () => {
59
63
  log("onReconnected refresh reactors");
@@ -88,6 +92,7 @@ export class ReconnectRefresher {
88
92
  this.reactors.set(id, func);
89
93
  this.disposers.set(id, func());
90
94
  }
95
+ return () => this.remove(id);
91
96
  }
92
97
 
93
98
  public remove(id: string) {
@@ -17,6 +17,9 @@ export const genAppId = async (kind: string) => {
17
17
  };
18
18
 
19
19
  export const setViewFocusScenePath = (view: View, focusScenePath: string) => {
20
+ if ((view as any).didRelease) {
21
+ return;
22
+ }
20
23
  if (view.focusScenePath !== focusScenePath) {
21
24
  view.focusScenePath = focusScenePath;
22
25
  return view;
@@ -30,6 +33,12 @@ export const setViewSceneIndex = (view: View, index: number) => {
30
33
  }
31
34
  };
32
35
 
36
+ export const releaseView = (view: View) => {
37
+ if (!(view as any).didRelease) {
38
+ view.release();
39
+ }
40
+ }
41
+
33
42
  export const setScenePath = (room: Room | undefined, scenePath: string) => {
34
43
  if (room && room.isWritable) {
35
44
  if (room.state.sceneState.scenePath !== scenePath) {
@@ -1,6 +1,6 @@
1
- import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from "white-web-sdk";
2
- import type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from "white-web-sdk";
3
1
  import { isObject } from "lodash";
2
+ import { listenUpdated, reaction, unlistenUpdated, UpdateEventKind } from "white-web-sdk";
3
+ import type { AkkoObjectUpdatedProperty, AkkoObjectUpdatedListener } from "white-web-sdk";
4
4
 
5
5
  // 兼容 13 和 14 版本 SDK
6
6
  export const onObjectByEvent = (event: UpdateEventKind) => {
@@ -12,7 +12,7 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
12
12
  if (kinds.includes(event)) {
13
13
  func();
14
14
  }
15
- }
15
+ };
16
16
  listenUpdated(object, listener);
17
17
  func();
18
18
  return () => unlistenUpdated(object, listener);
@@ -21,43 +21,44 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
21
21
  () => object,
22
22
  () => {
23
23
  func();
24
- }, {
24
+ },
25
+ {
25
26
  fireImmediately: true,
26
27
  }
27
- )
28
+ );
28
29
  }
29
- }
30
- }
30
+ };
31
+ };
31
32
 
32
33
  export const safeListenPropsUpdated = <T>(
33
34
  getProps: () => T,
34
35
  callback: AkkoObjectUpdatedListener<T>,
35
36
  onDestroyed?: (props: unknown) => void
36
- ) => {
37
+ ) => {
37
38
  let disposeListenUpdated: (() => void) | null = null;
38
39
  const disposeReaction = reaction(
39
- getProps,
40
- () => {
41
- if (disposeListenUpdated) {
42
- disposeListenUpdated();
43
- disposeListenUpdated = null;
44
- }
45
- const props = getProps();
46
- if (isObject(props)) {
47
- disposeListenUpdated = () => unlistenUpdated(props, callback);
48
- listenUpdated(props, callback);
49
- } else {
50
- onDestroyed?.(props);
51
- }
52
- },
53
- { fireImmediately: true }
40
+ getProps,
41
+ () => {
42
+ if (disposeListenUpdated) {
43
+ disposeListenUpdated();
44
+ disposeListenUpdated = null;
45
+ }
46
+ const props = getProps();
47
+ if (isObject(props)) {
48
+ disposeListenUpdated = () => unlistenUpdated(props, callback);
49
+ listenUpdated(props, callback);
50
+ } else {
51
+ onDestroyed?.(props);
52
+ }
53
+ },
54
+ { fireImmediately: true }
54
55
  );
55
56
 
56
57
  return () => {
57
- disposeListenUpdated?.();
58
- disposeReaction();
58
+ disposeListenUpdated?.();
59
+ disposeReaction();
59
60
  };
60
- }
61
+ };
61
62
 
62
63
  export const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);
63
64
  export const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);
@@ -56,6 +56,9 @@ export const replaceRoomFunction = (room: Room | Player, manager: WindowManager)
56
56
  room.lockImages = (...args) => manager.lockImages(...args);
57
57
 
58
58
  delegateRemoveScenes(room, manager);
59
+ if (!(room as any).dynamicPpt.slideStateAdapter.pptHandler) {
60
+ (room as any).dynamicPpt.slideStateAdapter.pptHandler = manager.createPPTHandler();
61
+ }
59
62
  }
60
63
  };
61
64