@netless/window-manager 0.3.15 → 0.3.16-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.
package/docs/api.md ADDED
@@ -0,0 +1,113 @@
1
+ # API
2
+
3
+ ## 目录
4
+ - [静态方法](#static-methods)
5
+ - [`mount`](#mount)
6
+ - [`register`](#register)
7
+ - [实例方法](#instance-methods)
8
+ - [`addApp`](#addApp)
9
+ - [`closeApp`](#closeApp)
10
+ - [实例属性](#prototypes)
11
+ - [事件回调](#events)
12
+
13
+ <h2 id="static-methods">静态方法</h2>
14
+
15
+ <h3 id="mount">WindowManager.mount</h3>
16
+
17
+ > 挂载 WindowManager
18
+
19
+ ```typescript
20
+ const manager = await WindowManager.mount(
21
+ room: room,
22
+ container: document.getElementById("container")
23
+ // 完整配置见下方
24
+ );
25
+ ```
26
+
27
+ 参数
28
+
29
+ | name | type | default | desc |
30
+ | ---------------------- | --------------------------------------- | ------- | ---------------------------- |
31
+ | room | [require] Room | | 房间实例 |
32
+ | container | [require] HTMLElement | | 房间挂载容器 |
33
+ | containerSizeRatio | [optional] number | 9 / 16 | 多窗口区域的高宽比,默认为 9 : 16 |
34
+ | chessboard | [optional] boolean | true | 多窗口区域以外的空间显示 PS 棋盘背景,默认 true |
35
+ | collectorContainer | [optional] HTMLElement | | 用于多窗口最小化图标挂载的 dom |
36
+ | collectorStyles | [optional] Partial{CSSStyleDeclaration} | | 配置 collector 的样式 |
37
+ | overwriteStyles | [optional] string | | 用于覆盖窗口的样式 |
38
+ | cursor | [optional] boolean | false | 开启光标同步 |
39
+ | disableCameraTransform | [optional] boolean | | 禁用主白板的相机移动 |
40
+ | prefersColorScheme | [optional] string | light | auto, light, dark |
41
+ | debug | [optional] boolean | false | 打印日志信息
42
+
43
+ <h3 id="register">WindowManager.register</h3>
44
+
45
+ > 注册 `APP` 到 `WindowManager`
46
+
47
+ ```typescript
48
+ WindowManager.register({
49
+ kind: "helloWorld",
50
+ src: NetlessApp,
51
+ appOptions: () => "appOptions",
52
+ addHooks: (emitter) => {
53
+ emitter.on("created", result => {
54
+ console.log("HelloWordResult", result);
55
+ });
56
+ emitter.on("focus", result => {
57
+ console.log("HelloWorld focus", result);
58
+ })
59
+ emitter.on("destroy", result => {
60
+ console.log("HelloWorld destroy", result);
61
+ })
62
+ }
63
+ })
64
+ ```
65
+
66
+
67
+ <h2 id="instance-methods">实例方法</h2>
68
+
69
+ <h3 id="addApp">addApp</h3>
70
+
71
+ > 添加 `app` 至白板
72
+
73
+ ```typescript
74
+ const appId = await manager.addApp({
75
+ kind: "helloWorld"
76
+ options: { // 可选配置
77
+ scenePath: "/hello-world"
78
+ }
79
+ })
80
+ ```
81
+ 具体参数请参考 `APP` 本身的要求
82
+
83
+ <h3 id="closeApp">closeApp</h3>
84
+
85
+ > 关闭已经打开的 `APP`
86
+
87
+ ```typescript
88
+ manager.closeApp(appId)
89
+ ```
90
+
91
+ <h2 id="prototypes">实例属性</h2>
92
+
93
+ | name | type | default | desc |
94
+ | ------------------ | ------- | ------- | ------ |
95
+ | mainView | View | | 主白板 |
96
+ | boxState | string | | 当前窗口状态 |
97
+ | darkMode | boolean | | 黑夜模式 |
98
+ | prefersColorScheme | string | | 颜色主题 |
99
+
100
+
101
+ <h2 id="events">事件回调</h2>
102
+
103
+ ```typescript
104
+ manager.callbacks.on(events, listener)
105
+ ```
106
+
107
+ | name | type | default | desc |
108
+ | ------------------------ | -------------- | ------- | -------------------------- |
109
+ | mainViewModeChange | ViewVisionMode | | |
110
+ | boxStateChange | string | | normal,minimized,maximized |
111
+ | darkModeChange | boolean | | |
112
+ | prefersColorSchemeChange | string | | auto,light,dark |
113
+ | cameraStateChange | CameraState | | |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "0.3.15",
3
+ "version": "0.3.16-canary.3",
4
4
  "description": "",
5
5
  "main": "dist/index.es.js",
6
6
  "module": "dist/index.es.js",
package/src/AppManager.ts CHANGED
@@ -395,6 +395,9 @@ export class AppManager {
395
395
  if (appProxy) {
396
396
  appProxy.destroy(false, true, payload.error);
397
397
  }
398
+ if (this.boxManager.maximized) {
399
+ this.boxManager.focusTopBox();
400
+ }
398
401
  break;
399
402
  }
400
403
  case "boxStateChange": {
package/src/BoxManager.ts CHANGED
@@ -268,8 +268,8 @@ export class BoxManager {
268
268
  this.teleBoxManager.update(appId, { x, y }, true);
269
269
  }
270
270
 
271
- public focusBox({ appId }: AppId): void {
272
- this.teleBoxManager.update(appId, { focus: true }, true);
271
+ public focusBox({ appId }: AppId, skipUpdate = true): void {
272
+ this.teleBoxManager.update(appId, { focus: true }, skipUpdate);
273
273
  }
274
274
 
275
275
  public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {
@@ -315,6 +315,16 @@ export class BoxManager {
315
315
  this.teleBoxManager.setMinimized(minimized, skipUpdate);
316
316
  }
317
317
 
318
+ public focusTopBox(): void {
319
+ const boxes = this.teleBoxManager.query();
320
+ if (boxes.length >= 1) {
321
+ const box = this.getTopBox();
322
+ if (box) {
323
+ this.focusBox({ appId: box.id }, false);
324
+ }
325
+ }
326
+ }
327
+
318
328
  public setReadonly(readonly: boolean) {
319
329
  this.teleBoxManager.setReadonly(readonly);
320
330
  }
package/src/MainView.ts CHANGED
@@ -24,8 +24,14 @@ export class MainViewProxy extends Base {
24
24
  emitter.once("mainViewMounted").then(() => {
25
25
  setTimeout(() => {
26
26
  this.start();
27
+ if (!this.mainViewCamera || !this.mainViewSize) {
28
+ this.setCameraAndSize();
29
+ }
27
30
  }, 200); // 等待 mainView 挂载完毕再进行监听,否则会触发不必要的 onSizeUpdated
28
31
  });
32
+ emitter.on("playgroundSizeChange", () => {
33
+ this.sizeChangeHandler(this.mainViewSize);
34
+ });
29
35
  }
30
36
 
31
37
  private get mainViewCamera() {
@@ -43,10 +49,9 @@ export class MainViewProxy extends Base {
43
49
 
44
50
  public start() {
45
51
  if (this.started) return;
52
+ this.sizeChangeHandler(this.mainViewSize);
46
53
  this.addCameraListener();
47
54
  this.manager.refresher?.add(Fields.MainViewCamera, this.cameraReaction);
48
- this.manager.refresher?.add(Fields.MainViewSize, this.sizeReaction);
49
- this.view.callbacks.on("onSizeUpdated", this.sizeListener);
50
55
  this.started = true;
51
56
  }
52
57
 
@@ -60,6 +65,7 @@ export class MainViewProxy extends Base {
60
65
  () => this.mainViewCamera,
61
66
  camera => {
62
67
  if (camera && camera.id !== this.context.uid) {
68
+ this.moveCameraToContian(this.mainViewSize);
63
69
  this.moveCamera(camera);
64
70
  }
65
71
  },
@@ -69,20 +75,12 @@ export class MainViewProxy extends Base {
69
75
  );
70
76
  };
71
77
 
72
- private sizeReaction = () => {
73
- return reaction(
74
- () => this.mainViewSize,
75
- size => {
76
- if (size && size.id !== this.context.uid) {
77
- this.moveCameraToContian(size);
78
- this.moveCamera(this.mainViewCamera);
79
- }
80
- },
81
- {
82
- fireImmediately: true,
83
- }
84
- );
85
- };
78
+ private sizeChangeHandler = debounce((size: Size) => {
79
+ if (size) {
80
+ this.moveCameraToContian(size);
81
+ this.moveCamera(this.mainViewCamera);
82
+ }
83
+ }, 30);
86
84
 
87
85
  public get view(): View {
88
86
  return this.mainView;
@@ -94,9 +92,6 @@ export class MainViewProxy extends Base {
94
92
 
95
93
  public createMainView(): View {
96
94
  const mainView = createView(this.manager.displayer);
97
- mainView.callbacks.on("onSizeUpdated", () => {
98
- this.context.updateManagerRect();
99
- });
100
95
  const mainViewScenePath = this.store.getMainViewScenePath();
101
96
  if (mainViewScenePath) {
102
97
  setViewFocusScenePath(mainView, mainViewScenePath);
@@ -107,9 +102,9 @@ export class MainViewProxy extends Base {
107
102
  return mainView;
108
103
  }
109
104
 
110
- private cameraListener = (camera: Camera) => {
105
+ private onCameraUpdatedByDevice = (camera: Camera) => {
111
106
  this.store.setMainViewCamera({ ...camera, id: this.context.uid });
112
- if (this.store.getMainViewSize()?.id !== this.context.uid) {
107
+ if (!isEqual(this.mainViewSize, {...this.mainView.size, id: this.context.uid})) {
113
108
  this.setMainViewSize(this.view.size);
114
109
  }
115
110
  };
@@ -141,28 +136,25 @@ export class MainViewProxy extends Base {
141
136
  this.context.blurFocusBox();
142
137
  }
143
138
 
144
- private sizeListener = (size: Size) => {
145
- this.setMainViewSize(size);
146
- callbacks.emit("cameraStateChange", this.cameraState);
147
- };
148
-
149
139
  public setMainViewSize = debounce(size => {
150
140
  this.store.setMainViewSize({ ...size, id: this.context.uid });
151
141
  }, 50);
152
142
 
153
143
  private addCameraListener() {
154
- this.view.callbacks.on("onCameraUpdatedByDevice", this.cameraListener);
155
- this.view.callbacks.on("onCameraUpdated", this.cameraStateChangeListener);
144
+ this.view.callbacks.on("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
145
+ this.view.callbacks.on("onCameraUpdated", this.onCameraOrSizeUpdated);
146
+ this.view.callbacks.on("onSizeUpdated", this.onCameraOrSizeUpdated);
156
147
  }
157
148
 
158
149
  private removeCameraListener() {
159
- this.view.callbacks.off("onCameraUpdatedByDevice", this.cameraListener);
160
- this.view.callbacks.off("onCameraUpdated", this.cameraStateChangeListener)
150
+ this.view.callbacks.off("onCameraUpdatedByDevice", this.onCameraUpdatedByDevice);
151
+ this.view.callbacks.off("onCameraUpdated", this.onCameraOrSizeUpdated);
152
+ this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
161
153
  }
162
154
 
163
- private cameraStateChangeListener = () => {
155
+ private onCameraOrSizeUpdated = () => {
164
156
  callbacks.emit("cameraStateChange", this.cameraState);
165
- }
157
+ };
166
158
 
167
159
  public switchViewModeToWriter(): void {
168
160
  if (!this.manager.canOperate) return;
@@ -206,7 +198,6 @@ export class MainViewProxy extends Base {
206
198
  this.removeCameraListener();
207
199
  this.manager.refresher?.remove(Fields.MainViewCamera);
208
200
  this.manager.refresher?.remove(Fields.MainViewSize);
209
- this.view.callbacks.off("onSizeUpdated", this.sizeListener);
210
201
  this.started = false;
211
202
  }
212
203
 
package/src/index.ts CHANGED
@@ -135,6 +135,7 @@ export type EmitterEvent = {
135
135
  mainViewMounted: undefined;
136
136
  observerIdChange: number;
137
137
  boxStateChange: string;
138
+ playgroundSizeChange: DOMRect;
138
139
  };
139
140
 
140
141
  export const emitter: Emittery<EmitterEvent> = new Emittery();
@@ -175,7 +176,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
175
176
  public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;
176
177
  private static isCreated = false;
177
178
 
178
- public version = "0.3.15";
179
+ public version = "0.3.16-canary.3";
179
180
 
180
181
  public appListeners?: AppListeners;
181
182
 
@@ -699,6 +700,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
699
700
  if (containerRect) {
700
701
  this.updateSizer(containerRect, sizer, wrapper);
701
702
  this.cursorManager?.updateContainerRect();
703
+ this.appManager?.boxManager.updateManagerRect();
704
+ emitter.emit("playgroundSizeChange", containerRect);
702
705
  }
703
706
  });
704
707