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

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.
@@ -1,5 +1,4 @@
1
1
  import { BoxNotCreatedError } from "../Utils/error";
2
- import { putScenes } from "../Utils/Common";
3
2
  import { Storage } from "./Storage";
4
3
  import {
5
4
  autorun,
@@ -19,7 +18,7 @@ import type {
19
18
  import type { ReadonlyTeleBox } from "@netless/telebox-insider";
20
19
  import type Emittery from "emittery";
21
20
  import type { BoxManager } from "../BoxManager";
22
- import type { AppEmitterEvent } from "../index";
21
+ import type { AppEmitterEvent, Member } from "../index";
23
22
  import type { AppManager } from "../AppManager";
24
23
  import type { AppProxy } from "./AppProxy";
25
24
  import type {
@@ -27,11 +26,13 @@ import type {
27
26
  MagixEventDispatcher,
28
27
  MagixEventRemoveListener,
29
28
  } from "./MagixEvent";
30
- import type { AddPageParams, PageController, PageState } from "../Page";
29
+ import { WhiteBoardView } from "./WhiteBoardView";
30
+ import { findMemberByUid } from "../Helper";
31
+ import { MAX_PAGE_SIZE } from "../constants";
32
+ import { putScenes } from "../Utils/Common";
33
+ import { isNumber } from "lodash";
31
34
 
32
- export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any>
33
- implements PageController
34
- {
35
+ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {
35
36
  public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
36
37
  public readonly mobxUtils = {
37
38
  autorun,
@@ -48,6 +49,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
48
49
  private store = this.manager.store;
49
50
  public readonly isAddApp: boolean;
50
51
  public readonly isReplay = this.manager.isReplay;
52
+ private whiteBoardView?: WhiteBoardView;
51
53
 
52
54
  constructor(
53
55
  private manager: AppManager,
@@ -60,7 +62,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
60
62
  this.isAddApp = appProxy.isAddApp;
61
63
  }
62
64
 
63
- public getDisplayer = () => {
65
+ public get displayer(){
64
66
  return this.manager.displayer;
65
67
  };
66
68
 
@@ -78,32 +80,58 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
78
80
  }
79
81
  };
80
82
 
81
- public getView = (): View | undefined => {
83
+ public get view(): View | undefined {
82
84
  return this.appProxy.view;
83
85
  };
84
86
 
85
- public mountView = (dom: HTMLElement): void => {
86
- const view = this.getView();
87
- if (view) {
88
- view.divElement = dom as HTMLDivElement;
89
- setTimeout(() => {
90
- // 渲染需要时间,延迟 refresh
91
- this.getRoom()?.refreshViewSize();
92
- }, 1000);
87
+ public createWhiteBoardView = (size?: number): WhiteBoardView => {
88
+ if (this.whiteBoardView) {
89
+ return this.whiteBoardView;
93
90
  }
94
- };
91
+ let view = this.view;
92
+ if (!view) {
93
+ view = this.appProxy.createAppDir();
94
+ }
95
+ const viewWrapper = document.createElement("div");
96
+ viewWrapper.className = "window-manager-view-wrapper";
97
+ this.box.$content.parentElement?.appendChild(viewWrapper);
98
+ const removeViewWrapper = () => {
99
+ this.box.$content.parentElement?.removeChild(viewWrapper);
100
+ }
101
+ view.divElement = viewWrapper
102
+ if (this.isAddApp) {
103
+ this.initPageSize(size);
104
+ }
105
+ this.whiteBoardView = new WhiteBoardView(this, this.appProxy, removeViewWrapper);
106
+ return this.whiteBoardView;
107
+ }
108
+
109
+ private initPageSize = (size?: number) => {
110
+ if (!isNumber(size)) return;
111
+ if (!this.appProxy.scenePath) return;
112
+ if (this.appProxy.pageState.length >= size) return;
113
+ if (size <= 0 || size >= MAX_PAGE_SIZE) {
114
+ throw Error(`[WindowManager]: size ${size} muse be in range [1, ${MAX_PAGE_SIZE}]`);
115
+ }
116
+ const needInsert = size - this.appProxy.pageState.length;
117
+ const startPageNumber = this.appProxy.pageState.length;
118
+ const scenes = new Array(needInsert).fill({}).map((_, index) => {
119
+ return { name: `${startPageNumber + index + 1}` };
120
+ });
121
+ putScenes(this.room, this.appProxy.scenePath, scenes);
122
+ }
95
123
 
96
124
  public getInitScenePath = () => {
97
125
  return this.manager.getAppInitPath(this.appId);
98
126
  };
99
127
 
100
128
  /** Get App writable status. */
101
- public getIsWritable = (): boolean => {
129
+ public get isWritable(): boolean {
102
130
  return this.manager.canOperate;
103
131
  };
104
132
 
105
133
  /** Get the App Window UI box. */
106
- public getBox = (): ReadonlyTeleBox => {
134
+ public get box(): ReadonlyTeleBox {
107
135
  const box = this.boxManager.getBox(this.appId);
108
136
  if (box) {
109
137
  return box;
@@ -112,10 +140,25 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
112
140
  }
113
141
  };
114
142
 
115
- public getRoom = (): Room | undefined => {
143
+ public get room(): Room | undefined {
116
144
  return this.manager.room;
117
145
  };
118
146
 
147
+ public get members() {
148
+ return this.manager.members;
149
+ }
150
+
151
+ public get memberState(): Member {
152
+ const self = findMemberByUid(this.room, this.manager.uid);
153
+ if (!self) {
154
+ throw new Error(`Member ${this.manager.uid} not found.`);
155
+ }
156
+ return {
157
+ uid: this.manager.uid,
158
+ ...self,
159
+ }
160
+ }
161
+
119
162
  /** @deprecated Use context.storage.setState instead. */
120
163
  public setAttributes = (attributes: TAttributes) => {
121
164
  this.manager.safeSetAttributes({ [this.appId]: attributes });
@@ -128,11 +171,12 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
128
171
  }
129
172
  };
130
173
 
174
+ /** @deprecated Use Pages api instead. */
131
175
  public setScenePath = async (scenePath: string): Promise<void> => {
132
176
  if (!this.appProxy.box) return;
133
177
  this.appProxy.setFullPath(scenePath);
134
178
  // 兼容 15 版本 SDK 的切页
135
- this.getRoom()?.setScenePath(scenePath);
179
+ this.room?.setScenePath(scenePath);
136
180
  };
137
181
 
138
182
  /** Get the local App options. */
@@ -196,55 +240,4 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
196
240
  public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(
197
241
  this.manager.displayer
198
242
  ) as MagixEventRemoveListener<TMagixEventPayloads>;
199
-
200
- /** PageController */
201
- public nextPage = async (): Promise<boolean> => {
202
- const nextIndex = this.pageState.index + 1;
203
- if (nextIndex > this.pageState.length - 1) {
204
- console.warn("[WindowManager] nextPage: index out of range");
205
- return false;
206
- }
207
- this.appProxy.setSceneIndex(nextIndex);
208
- return true;
209
- };
210
-
211
- public prevPage = async (): Promise<boolean> => {
212
- const nextIndex = this.pageState.index - 1;
213
- if (nextIndex < 0) {
214
- console.warn("[WindowManager] prevPage: index out of range");
215
- return false;
216
- }
217
- this.appProxy.setSceneIndex(nextIndex);
218
- return true;
219
- };
220
-
221
- public addPage = async (params?: AddPageParams) => {
222
- const after = params?.after;
223
- const scene = params?.scene;
224
- const scenePath = this.appProxy.scenePath;
225
- if (!scenePath) return;
226
- if (after) {
227
- const nextIndex = this.pageState.index + 1;
228
- putScenes(this.manager.room, scenePath, [scene || {}], nextIndex);
229
- } else {
230
- putScenes(this.manager.room, scenePath, [scene || {}]);
231
- }
232
- };
233
-
234
- public removePage = async (index?: number): Promise<boolean> => {
235
- const needRemoveIndex = index === undefined ? this.pageState.index : index;
236
- if (this.pageState.length === 1) {
237
- console.warn(`[WindowManager]: can not remove the last page`);
238
- return false;
239
- }
240
- if (needRemoveIndex < 0 || needRemoveIndex >= this.pageState.length) {
241
- console.warn(`[WindowManager]: page index ${index} out of range`);
242
- return false;
243
- }
244
- return this.appProxy.removeSceneByIndex(needRemoveIndex);;
245
- }
246
-
247
- public get pageState(): PageState {
248
- return this.appProxy.pageState;
249
- }
250
243
  }
@@ -9,11 +9,15 @@ export type AppPageStateParams = {
9
9
  };
10
10
 
11
11
  export class AppPageStateImpl {
12
- private sceneNode: ScenesCallbacksNode | null = null;
12
+ public sceneNode: ScenesCallbacksNode | null = null;
13
+ private scenePath?: string;
14
+ private view?: View;
13
15
 
14
16
  constructor(private params: AppPageStateParams) {
15
17
  const { displayer, scenePath } = this.params;
18
+ this.view = this.params.view;
16
19
  if (scenePath) {
20
+ this.scenePath = scenePath;
17
21
  this.sceneNode = displayer.createScenesCallback(scenePath, {
18
22
  onAddScene: this.onSceneChange,
19
23
  onRemoveScene: this.onSceneChange,
@@ -21,24 +25,39 @@ export class AppPageStateImpl {
21
25
  }
22
26
  }
23
27
 
24
- private onSceneChange = (node: ScenesCallbacksNode) => {
25
- this.sceneNode = node;
28
+ public createSceneNode = (scenePath: string) => {
29
+ this.scenePath = scenePath;
30
+ if (this.sceneNode) {
31
+ this.sceneNode.dispose();
32
+ }
33
+ this.sceneNode = this.params.displayer.createScenesCallback(scenePath, {
34
+ onAddScene: this.onSceneChange,
35
+ onRemoveScene: this.onSceneChange,
36
+ });
37
+ return this.sceneNode;
38
+ }
39
+
40
+ public setView(view: View) {
41
+ this.view = view;
42
+ }
43
+
44
+ private onSceneChange = () => {
26
45
  this.params.notifyPageStateChange();
27
46
  };
28
47
 
29
48
  public getFullPath(index: number) {
30
49
  const scenes = this.sceneNode?.scenes;
31
- if (this.params.scenePath && scenes) {
50
+ if (this.scenePath && scenes) {
32
51
  const name = scenes[index];
33
52
  if (name) {
34
- return `${this.params.scenePath}/${name}`;
53
+ return `${this.scenePath}/${name}`;
35
54
  }
36
55
  }
37
56
  }
38
57
 
39
58
  public toObject(): PageState {
40
59
  return {
41
- index: this.params.view?.focusSceneIndex || 0,
60
+ index: this.view?.focusSceneIndex || 0,
42
61
  length: this.sceneNode?.scenes.length || 0,
43
62
  };
44
63
  }
@@ -12,6 +12,7 @@ import { log } from "../Utils/log";
12
12
  import {
13
13
  entireScenes,
14
14
  getScenePath,
15
+ putScenes,
15
16
  removeScenes,
16
17
  setScenePath,
17
18
  setViewFocusScenePath,
@@ -30,6 +31,7 @@ import type { ReadonlyTeleBox } from "@netless/telebox-insider";
30
31
  import type { PageRemoveService, PageState } from "../Page";
31
32
  import { calculateNextIndex } from "../Page";
32
33
  import { boxEmitter } from "../BoxEmitter";
34
+ import { SideEffectManager } from "side-effect-manager";
33
35
 
34
36
  export type AppEmitter = Emittery<AppEmitterEvent>;
35
37
 
@@ -37,6 +39,7 @@ export class AppProxy implements PageRemoveService {
37
39
  public kind: string;
38
40
  public id: string;
39
41
  public scenePath?: string;
42
+ private appScenePath: string;
40
43
  public appEmitter: AppEmitter;
41
44
  public scenes?: SceneDefinition[];
42
45
 
@@ -49,12 +52,14 @@ export class AppProxy implements PageRemoveService {
49
52
  public isAddApp: boolean;
50
53
  private status: "normal" | "destroyed" = "normal";
51
54
  private stateKey: string;
52
- private _pageState: AppPageStateImpl;
55
+ public _pageState: AppPageStateImpl;
53
56
  private _prevFullPath: string | undefined;
54
57
 
55
58
  public appResult?: NetlessApp<any>;
56
59
  public appContext?: AppContext<any, any>;
57
60
 
61
+ private sideEffectManager = new SideEffectManager();
62
+
58
63
  constructor(
59
64
  private params: BaseInsertParams,
60
65
  private manager: AppManager,
@@ -63,6 +68,7 @@ export class AppProxy implements PageRemoveService {
63
68
  ) {
64
69
  this.kind = params.kind;
65
70
  this.id = appId;
71
+ this.appScenePath = `/${this.id}-app-dir`;
66
72
  this.stateKey = `${this.id}_state`;
67
73
  this.appProxies.set(this.id, this);
68
74
  this.appEmitter = new Emittery();
@@ -75,12 +81,37 @@ export class AppProxy implements PageRemoveService {
75
81
  // 只有传入了 scenePath 的 App 才会创建 View
76
82
  this.createView();
77
83
  }
84
+ if (!this.scenePath) {
85
+ this.scenePath = this.appScenePath;
86
+ }
78
87
  this._pageState = new AppPageStateImpl({
79
88
  displayer: this.manager.displayer,
80
89
  scenePath: this.scenePath,
81
90
  view: this.view,
82
91
  notifyPageStateChange: this.notifyPageStateChange,
83
92
  });
93
+ this.sideEffectManager.add(() => {
94
+ return () => this._pageState.destroy();
95
+ });
96
+ this.sideEffectManager.add(() => {
97
+ return emitter.on("roomMembersChange", members => {
98
+ this.appEmitter.emit("roomMembersChange", members);
99
+ });
100
+ });
101
+ }
102
+
103
+ public createAppDir() {
104
+ const scenePath = this.scenePath || this.appScenePath;
105
+ const sceneNode = this._pageState.createSceneNode(scenePath);
106
+ if (!sceneNode) {
107
+ putScenes(this.manager.room, scenePath, [{ name: "1" }]);
108
+ this._pageState.createSceneNode(scenePath);
109
+ this.setSceneIndex(0);
110
+ }
111
+ this.scenes = entireScenes(this.manager.displayer)[scenePath];
112
+ const view = this.createView();
113
+ this._pageState.setView(view);
114
+ return view;
84
115
  }
85
116
 
86
117
  private initScenes() {
@@ -395,14 +426,16 @@ export class AppProxy implements PageRemoveService {
395
426
  return fullPath;
396
427
  }
397
428
 
398
- private async createView(): Promise<View> {
399
- const view = await this.viewManager.createView(this.id);
429
+ private createView(): View {
430
+ const view = this.viewManager.createView(this.id);
400
431
  this.setViewFocusScenePath();
401
432
  return view;
402
433
  }
403
434
 
404
435
  public notifyPageStateChange = debounce(() => {
405
- this.appEmitter.emit("pageStateChange", this.pageState);
436
+ if (this.pageState) {
437
+ this.appEmitter.emit("pageStateChange", this.pageState);
438
+ }
406
439
  }, 50);
407
440
 
408
441
  public get pageState(): PageState {
@@ -412,7 +445,7 @@ export class AppProxy implements PageRemoveService {
412
445
  // PageRemoveService
413
446
  public async removeSceneByIndex(index: number) {
414
447
  const scenePath = this._pageState.getFullPath(index);
415
- if (scenePath) {
448
+ if (scenePath && this.pageState) {
416
449
  const nextIndex = calculateNextIndex(index, this.pageState);
417
450
  // 只修改 focus path 不修改 FullPath
418
451
  this.setSceneIndexWithoutSync(nextIndex);
@@ -474,7 +507,6 @@ export class AppProxy implements PageRemoveService {
474
507
  }
475
508
  }
476
509
  this.appProxies.delete(this.id);
477
- this._pageState.destroy();
478
510
 
479
511
  this.viewManager.destroyView(this.id);
480
512
  this.manager.appStatus.delete(this.id);
@@ -482,6 +514,7 @@ export class AppProxy implements PageRemoveService {
482
514
  this.manager.refresher?.remove(this.stateKey);
483
515
  this.manager.refresher?.remove(`${this.id}-fullPath`);
484
516
  this._prevFullPath = undefined;
517
+ this.sideEffectManager.flushAll();
485
518
  }
486
519
 
487
520
  public close(): Promise<void> {
@@ -37,7 +37,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
37
37
  this._state = {} as TState;
38
38
  const rawState = this._getRawState(this._state);
39
39
 
40
- if (this._context.getIsWritable()) {
40
+ if (this._context.isWritable) {
41
41
  if (this.id === null) {
42
42
  if (context.isAddApp && defaultState) {
43
43
  this.setState(defaultState);
@@ -115,7 +115,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
115
115
  return;
116
116
  }
117
117
 
118
- if (!this._context.getIsWritable()) {
118
+ if (!this._context.isWritable) {
119
119
  console.error(new Error(`Cannot setState on Storage "${this.id}" without writable access`), state);
120
120
  return;
121
121
  }
@@ -165,7 +165,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
165
165
  return;
166
166
  }
167
167
 
168
- if (!this._context.getIsWritable()) {
168
+ if (!this._context.isWritable) {
169
169
  console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
170
170
  return;
171
171
  }
@@ -181,7 +181,7 @@ export class Storage<TState extends Record<string, any> = any> implements Storag
181
181
  throw new Error(`Cannot delete main Storage`);
182
182
  }
183
183
 
184
- if (!this._context.getIsWritable()) {
184
+ if (!this._context.isWritable) {
185
185
  console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
186
186
  return;
187
187
  }
@@ -0,0 +1,76 @@
1
+ import { putScenes } from "../Utils/Common";
2
+ import { Val } from "value-enhancer";
3
+
4
+ import type { ReadonlyVal } from "value-enhancer";
5
+ import type { AddPageParams, PageController, PageState } from "../Page";
6
+ import type { AppProxy } from "./AppProxy";
7
+ import type { AppContext } from "./AppContext";
8
+
9
+ export class WhiteBoardView implements PageController {
10
+ public readonly pageState$: ReadonlyVal<PageState>;
11
+
12
+ constructor(
13
+ protected appContext: AppContext,
14
+ protected appProxy: AppProxy,
15
+ private removeViewWrapper: () => void,
16
+ ) {
17
+ const pageState$ = new Val<PageState>(appProxy.pageState);
18
+ this.pageState$ = pageState$;
19
+ appProxy.appEmitter.on("pageStateChange", pageState => {
20
+ pageState$.setValue(pageState);
21
+ });
22
+ }
23
+
24
+ public get pageState() {
25
+ return this.pageState$.value;
26
+ }
27
+
28
+ public nextPage = async (): Promise<boolean> => {
29
+ const nextIndex = this.pageState.index + 1;
30
+ return this.jumpPage(nextIndex);
31
+ };
32
+
33
+ public prevPage = async (): Promise<boolean> => {
34
+ const nextIndex = this.pageState.index - 1;
35
+ return this.jumpPage(nextIndex);
36
+ };
37
+
38
+ public jumpPage = async (index: number): Promise<boolean> => {
39
+ if (index < 0 || index >= this.pageState.length) {
40
+ console.warn(`[WindowManager]: index ${index} out of range`);
41
+ return false;
42
+ }
43
+ this.appProxy.setSceneIndex(index);
44
+ return true;
45
+ };
46
+
47
+ public addPage = async (params?: AddPageParams) => {
48
+ const after = params?.after;
49
+ const scene = params?.scene;
50
+ const scenePath = this.appProxy.scenePath;
51
+ if (!scenePath) return;
52
+ if (after) {
53
+ const nextIndex = this.pageState.index + 1;
54
+ putScenes(this.appContext.room, scenePath, [scene || {}], nextIndex);
55
+ } else {
56
+ putScenes(this.appContext.room, scenePath, [scene || {}]);
57
+ }
58
+ };
59
+
60
+ public removePage = async (index?: number): Promise<boolean> => {
61
+ const needRemoveIndex = index === undefined ? this.pageState.index : index;
62
+ if (this.pageState.length === 1) {
63
+ console.warn(`[WindowManager]: can not remove the last page`);
64
+ return false;
65
+ }
66
+ if (needRemoveIndex < 0 || needRemoveIndex >= this.pageState.length) {
67
+ console.warn(`[WindowManager]: page index ${index} out of range`);
68
+ return false;
69
+ }
70
+ return this.appProxy.removeSceneByIndex(needRemoveIndex);
71
+ };
72
+
73
+ public destroy() {
74
+ this.removeViewWrapper();
75
+ }
76
+ }
package/src/App/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./AppProxy";
2
2
  export * from "./AppContext";
3
+ export * from "./WhiteBoardView";
package/src/AppManager.ts CHANGED
@@ -15,6 +15,7 @@ import { MainViewProxy } from "./View/MainView";
15
15
  import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
16
16
  import { reconnectRefresher, WindowManager } from "./index";
17
17
  import { RedoUndo } from "./RedoUndo";
18
+ import { serializeRoomMembers } from "./Helper";
18
19
  import { SideEffectManager } from "side-effect-manager";
19
20
  import { ViewManager } from "./View/ViewManager";
20
21
  import type { SyncRegisterAppPayload } from "./Register";
@@ -46,7 +47,7 @@ import type {
46
47
  BoxResizePayload,
47
48
  BoxStateChangePayload,
48
49
  } from "./BoxEmitter";
49
-
50
+ import type { Member } from "./Helper";
50
51
 
51
52
  export class AppManager {
52
53
  public displayer: Displayer;
@@ -299,6 +300,10 @@ export class AppManager {
299
300
  return this.room?.uid || "";
300
301
  }
301
302
 
303
+ public get members(): Member[] {
304
+ return serializeRoomMembers(this.displayer.state.roomMembers);
305
+ }
306
+
302
307
  public getMainViewSceneDir() {
303
308
  const scenePath = this.store.getMainViewScenePath();
304
309
  if (scenePath) {
@@ -660,6 +665,9 @@ export class AppManager {
660
665
  this.appProxies.forEach(appProxy => {
661
666
  appProxy.appEmitter.emit("roomStateChange", state);
662
667
  });
668
+ if (state.roomMembers) {
669
+ emitter.emit("roomMembersChange", this.members);
670
+ }
663
671
  emitter.emit("observerIdChange", this.displayer.observerId);
664
672
  };
665
673
 
package/src/BoxManager.ts CHANGED
@@ -210,6 +210,10 @@ export class BoxManager {
210
210
  return this.teleBoxManager.boxes.length;
211
211
  }
212
212
 
213
+ public get stageRect() {
214
+ return this.teleBoxManager.stageRect;
215
+ }
216
+
213
217
  public createBox(params: CreateBoxParams): void {
214
218
  if (!this.teleBoxManager) return;
215
219
  let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};
@@ -242,7 +246,7 @@ export class BoxManager {
242
246
  ): TeleBoxManager {
243
247
  const root = WindowManager.playground;
244
248
  const initManagerState: TeleBoxManagerConfig = {
245
- stageRatio: 3 / 4,
249
+ stageRatio: createTeleBoxManagerConfig?.stageRatio,
246
250
  root: root,
247
251
  fence: false,
248
252
  prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,
@@ -390,6 +394,10 @@ export class BoxManager {
390
394
  this.teleBoxManager._root$.setValue(root);
391
395
  }
392
396
 
397
+ public setCollector(collector: HTMLElement) {
398
+ this.teleBoxManager.collector.set$collector(collector);
399
+ }
400
+
393
401
  public destroy() {
394
402
  this.sideEffectManager.flushAll();
395
403
  this.teleBoxManager.destroy();
package/src/Helper.ts CHANGED
@@ -2,7 +2,7 @@ import { getVersionNumber } from "./Utils/Common";
2
2
  import { REQUIRE_VERSION } from "./constants";
3
3
  import { WhiteVersion } from "white-web-sdk";
4
4
  import { WhiteWebSDKInvalidError } from "./Utils/error";
5
- import type { Room } from "white-web-sdk";
5
+ import type { Room , RoomMember} from "white-web-sdk";
6
6
 
7
7
  export const setupWrapper = (
8
8
  root: HTMLElement
@@ -32,3 +32,12 @@ export const findMemberByUid = (room: Room | undefined, uid: string) => {
32
32
  const roomMembers = room?.state.roomMembers;
33
33
  return roomMembers?.find(member => member.payload?.uid === uid);
34
34
  };
35
+
36
+ export type Member = RoomMember & { uid: string };
37
+
38
+ export const serializeRoomMembers = (members: readonly RoomMember[]) => {
39
+ return members.map(member => ({
40
+ uid: member.payload?.uid || "",
41
+ ...member,
42
+ }));
43
+ }
@@ -1,6 +1,7 @@
1
1
  import Emittery from "emittery";
2
2
  import type { TeleBoxRect } from "@netless/telebox-insider";
3
3
  import type { AppInitState, CursorMovePayload } from "./index";
4
+ import type { Member } from "./Helper";
4
5
 
5
6
  export type RemoveSceneParams = {
6
7
  scenePath: string;
@@ -29,6 +30,7 @@ export type EmitterEvent = {
29
30
  changePageState: undefined;
30
31
  writableChange: boolean;
31
32
  containerSizeRatioUpdate: number;
33
+ roomMembersChange: Member[];
32
34
  };
33
35
 
34
36
  export type EmitterType = Emittery<EmitterEvent>;
@@ -42,7 +42,7 @@ export class MainViewProxy {
42
42
  }
43
43
  });
44
44
  });
45
- const rect = this.manager.boxManager?.teleBoxManager.stageRect;
45
+ const rect = this.manager.boxManager?.stageRect;
46
46
  if (rect) {
47
47
  this.synchronizer.setRect(rect);
48
48
  }
@@ -191,7 +191,7 @@ export class MainViewProxy {
191
191
  };
192
192
 
193
193
  private getStageSize(): Size | undefined {
194
- const stage = this.manager.boxManager?.teleBoxManager.stageRect;
194
+ const stage = this.manager.boxManager?.stageRect;
195
195
  if (stage) {
196
196
  return { width: stage.width, height: stage.height };
197
197
  }
package/src/constants.ts CHANGED
@@ -57,3 +57,5 @@ export const ROOT_DIR = "/";
57
57
  export const INIT_DIR = "/init";
58
58
 
59
59
  export const SETUP_APP_DELAY = 50;
60
+
61
+ export const MAX_PAGE_SIZE = 500;
package/src/index.ts CHANGED
@@ -340,7 +340,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
340
340
 
341
341
  public bindCollectorContainer(container: HTMLElement) {
342
342
  if (WindowManager.isCreated && this.boxManager) {
343
- this.boxManager.teleBoxManager.collector.set$collector(container)
343
+ this.boxManager.setCollector(container);
344
344
  } else {
345
345
  if (WindowManager.params) {
346
346
  WindowManager.params.collectorContainer = container;
package/src/style.css CHANGED
@@ -178,3 +178,12 @@
178
178
  right: 10px;
179
179
  bottom: 15px;
180
180
  }
181
+
182
+ .window-manager-view-wrapper {
183
+ z-index: 5000;
184
+ width: 100%;
185
+ height: 100%;
186
+ position: absolute;
187
+ left: 0;
188
+ top: 0;
189
+ }