@netless/window-manager 0.4.33 → 0.4.36

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/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## 0.4.36 (2022-07-06)
2
+
3
+ - 修复: Slide 最小化状态下重新进入房间恢复正常无法恢复到正确的大小
4
+
5
+ ## 0.4.35 (2022-07-06)
6
+
7
+ - 优化: 降低发送鼠标移动事件的频率
8
+ - 修复: 在 `writable` 进行切换的时候 `mainView` 的 `disableCameraTransform` 丢失
9
+
10
+ ## 0.4.34 (2022-06-29)
11
+
12
+ - 修复: 重连之后 `app` 没有正确创建的问题
13
+ - 修复: `app` 创建之后初始化宽高没有同步的问题
14
+
15
+ ## 0.4.33 (2022-06-29)
16
+
17
+ - 修复: 多人同时调用 `WindowManager.mount` 有概率出现错误的问题
18
+ - 修复: 只读用户的重连刷新问题
19
+
1
20
  ## 0.4.32 (2022-06-10)
2
21
 
3
22
  - 功能: `WindowManager.mount` 添加 `applianceIcons` 选项配置光标使用的图片
package/README.md CHANGED
@@ -1,214 +1,240 @@
1
1
  # WindowManager
2
2
 
3
- - 目录
4
- - [概念](docs/concept.md)
3
+ [中文](./README.zh-cn.md)
4
+
5
+ `WindowManager` is a window management system based on `white-web-sdk` `InvisiblePlugin` implementation.
6
+
7
+ This application provides the following.
8
+
9
+ 1. provides `NetlessApp` plug-in `API` system
10
+ 2. support `APP` to open as a window
11
+ 3. support application synchronization in each end
12
+ 4. cursor synchronization
13
+ 5. view angle following
14
+
15
+ ## Content list
16
+ - [Install](#Install)
17
+ - [QuickStart](#QuickStart)
18
+ - [concept](docs/concept.md)
5
19
  - [references](docs/api.md)
6
- - [从白板迁移](docs/migrate.md)
7
- - [回放](docs/replay.md)
8
- - [进阶使用](docs/advanced.md)
9
- - [视角跟随](docs/advanced.md#view-mode)
10
- - [开发自定义 APP](docs/develop-app.md)
11
- ## MainView
20
+ - [migration from whiteboard](docs/migrate.md)
21
+ - [replay](docs/replay.md)
22
+ - [advanced use](docs/advanced.md)
23
+ - [view-follow](docs/advanced.md#view-mode)
24
+ - [Develop custom APP](docs/develop-app.md)
12
25
 
13
- `MainView` 也就是主白板, 是垫在所有窗口下面的主白板
26
+ ## Install
14
27
 
15
- 因为多窗口的原因,所以抽象出来一个主白板, 并且把以前部分对 `room` 的操作, 迁移到对 `mainView` 操作
28
+ pnpm
29
+ ```sh
30
+ $ pnpm install @netless/window-manager
31
+ ```
32
+ yarn
33
+ ```sh
34
+ $ yarn install @netless/window-manager
35
+ ```
16
36
 
17
- ### 快速开始
37
+ ## QuickStart
18
38
 
19
39
  ```javascript
20
- import { WhiteWebSdk } from "white-web-sdk";
40
+ import { White-WebSdk } from "white-web-sdk";
21
41
  import { WindowManager, BuiltinApps } from "@netless/window-manager";
22
42
  import "@netless/window-manager/dist/style.css";
23
43
 
24
44
  const sdk = new WhiteWebSdk({
25
45
  appIdentifier: "appIdentifier",
26
- useMobXState: true // 请确保打开这个选项
46
+ useMobXState: true // make sure this option is turned on
27
47
  });
28
48
 
29
49
  sdk.joinRoom({
30
50
  uuid: "room uuid",
31
51
  roomToken: "room token",
32
52
  invisiblePlugins: [WindowManager],
33
- useMultiViews: true, // 多窗口必须用开启 useMultiViews
34
- disableMagixEventDispatchLimit: true, // 请确保打开这个选项
53
+ useMultiViews: true, // Multi-window must be enabled with useMultiViews
54
+ disableMagixEventDispatchLimit: true, // Make sure this option is turned on
35
55
  }).then(async room => {
36
56
  const manager = await WindowManager.mount(
37
57
  room,
38
58
  container
39
- // 完整配置见下方
59
+ // See below for full configuration
40
60
  );
41
61
  });
42
62
  ```
43
63
 
44
- [mount 完整参数](docs/api.md#mount)
64
+ [mount full parameter](docs/api.md#mount)
65
+
66
+ > ``containerSizeRatio`` In order to ensure that the window is displayed at different resolutions, the whiteboard can only be synchronized in the same scale area
67
+
68
+
69
+ ## MainView
70
+
71
+ `MainView`, the main whiteboard, is the main whiteboard that sits underneath all windows.
45
72
 
73
+ Because of the multiple windows, we abstracted out a main whiteboard, and migrated some of the previous operations on `room` to `mainView` operations
46
74
 
47
- > `containerSizeRatio` 为了保证窗口在不同分辨率下显示效果, 白板在相同的比例区域才能进行同步
48
75
 
49
- > `chessboard` 当挂载的区域不完全符合比例时, 白板会在挂载的 dom 中划分一个符合比例的区域出来, 此时多出来的部分会默认显示为棋盘透明背景
50
76
 
51
77
  ### `collector`
52
78
 
53
- > `collector` 就是窗口最小化时的图标, 默认大小 `width: 40px;` `height: 40px;`
79
+ > `collector` is the icon when the window is minimized, default size `width: 40px;` `height: 40px;`
54
80
 
55
81
 
56
- ### 光标同步
82
+ ### Cursor synchronization
57
83
 
58
- > 原本的 `SDK` 中的 `cursorAdapter` 在多窗口中不可用, 如需要光标同步功能需要在 `manager` 中开启 `cursor` 选项
84
+ > The original `cursorAdapter` in `SDK` is not available in multi-window, if you need cursor synchronization, you need to enable `cursor` option in `manager`.
59
85
 
60
86
  ```typescript
61
87
  sdk.joinRoom({
62
- // cursorAdapter: cursorAdapter, 原本开启 sdk 中的 cursorAdapter 需要关闭
88
+ // cursorAdapter: cursorAdapter, the original cursorAdapter in sdk needs to be turned off
63
89
  userPayload: {
64
- userId: "用户 id",
65
- cursorName: "光标名称",
66
- avatar: "用户头像链接",
90
+ userId: "user id",
91
+ cursorName: "cursor name",
92
+ avatar: "User avatar link",
67
93
  },
68
94
  });
69
95
 
70
96
  WindowManager.mount({
71
- cursor: true, // 开启光标同步
97
+ cursor: true, // turn on cursor synchronization
72
98
  });
73
99
  ```
74
100
 
75
101
  ## APP
76
102
 
77
- 静态和动态 PPT 是作为 `App` 插入到白板, 并持久化到白板中
103
+ Static and dynamic PPTs are inserted into the whiteboard as `App`, and persisted to the whiteboard
78
104
 
79
- `App` 或会在页面刷新时自动创建出来, 不需要重复插入
105
+ `App` may be created automatically when the page is refreshed, no need to insert it repeatedly
80
106
 
81
- 如果 `App` 需要 `scenePath` 时,那么一个 `scenePath` 只能同时打开一个,要求为 `App` 实例唯一
107
+ If the `App` requires a `scenePath`, then a `scenePath` can only be opened at the same time, requiring a unique `App` instance
82
108
 
83
- ### 添加静态/动态 PPT 到白板上
109
+ ### Add static/dynamic PPT to whiteboard
84
110
 
85
111
  ```javascript
86
112
  const appId = await manager.addApp({
87
113
  kind: BuiltinApps.DocsViewer,
88
114
  options: {
89
115
  scenePath: "/docs-viewer",
90
- title: "docs1", // 可选
91
- scenes: [], // SceneDefinition[] 静态/动态 Scene 数据
116
+ title: "docs1", // optional
117
+ scenes: [], // SceneDefinition[] Static/Dynamic Scene data
92
118
  },
93
119
  });
94
120
  ```
95
121
 
96
- ### 添加音视频到白板
122
+ ### Add audio and video to the whiteboard
97
123
 
98
124
  ```javascript
99
125
  const appId = await manager.addApp({
100
126
  kind: BuiltinApps.MediaPlayer,
101
127
  options: {
102
- title: "test.mp3", // 可选
128
+ title: "test.mp3", // optional
103
129
  },
104
130
  attributes: {
105
- src: "xxxx", // 音视频 url
131
+ src: "xxxx", // audio/video url
106
132
  },
107
133
  });
108
134
  ```
109
135
 
110
- ### 设置跟随模式
136
+ ### Set follow mode
111
137
 
112
- 只有广播端也就是老师需要设置跟随模式, 其他端的主白板都会跟随广播端的视角
138
+ Only the broadcast side, i.e. the teacher, needs to set the follow mode, the other side of the main whiteboard will follow the view of the broadcast side
113
139
 
114
- > 注意 `manager` `setViewMode` 不能和 `room.setViewMode` 同时使用
140
+ > Note that `manager`'s `setViewMode` cannot be used at the same time as `room.setViewMode`.
115
141
 
116
142
  ```javascript
117
- manager.setViewMode("broadcaster"); // 开启跟随模式
118
- manager.setViewMode("freedom"); // 关闭跟随模式
143
+ manager.setViewMode("broadcaster"); // turn on follow mode
144
+ manager.setViewMode("freedom"); // turn off follow mode
119
145
  ```
120
146
 
121
- 获取当前的 `broadcaster` ID
147
+ Get the current `broadcaster` ID
122
148
  ```javascript
123
149
  manager.broadcaster
124
150
  ```
125
151
 
126
- ### 设置所有 `app` `readonly`
152
+ ### Set `readonly` for all `app`s
127
153
 
128
154
  ```javascript
129
- manager.setReadonly(true); // 所有窗口变成 readonly 状态
130
- manager.setReadonly(false); // 解锁设置的 readonly, 注意如果当前白板的 isWritable false 以白板的状态为最高优先级
155
+ manager.setReadonly(true); // all windows become readonly
156
+ manager.setReadonly(false); // unlock the readonly setting, note that if the current whiteboard isWritable is false, the whiteboard's state is the highest priority
131
157
  ```
132
158
 
133
- ### 切换 `mainView` 为可写状态
159
+ ### Toggle `mainView` to writable state
134
160
 
135
161
  ```javascript
136
162
  manager.switchMainViewToWriter();
137
163
  ```
138
164
 
139
- ### 切换 `mainView` `scenePath`
165
+ ### Switch `mainView` `scenePath`
140
166
 
141
- 切换主白板的 `ScenePath` 并把主白板设置为可写状态
167
+ Switch the `ScenePath` of the main whiteboard and set the main whiteboard to writable state
142
168
 
143
169
  ```javascript
144
170
  manager.setMainViewScenePath(scenePath);
145
171
  ```
146
172
 
147
- ### 切换 `mainView` `sceneIndex`
173
+ ### toggle `mainView` `sceneIndex`
148
174
 
149
- 切换主白板的 `SceneIndex` 并把主白板设置为可写状态
175
+ Toggles the `SceneIndex` of the main whiteboard and sets the main whiteboard to writable state
150
176
 
151
177
  ```javascript
152
178
  manager.setMainViewSceneIndex(sceneIndex);
153
179
  ```
154
180
 
155
- ### 获取 `mainView` `scenePath`
181
+ ### Get the `mainView` `scenePath`
156
182
 
157
183
  ```javascript
158
184
  manager.getMainViewScenePath();
159
185
  ```
160
186
 
161
- ### 获取 `mainView` `sceneIndex`
187
+ ### Get `mainView` `sceneIndex`
162
188
 
163
189
  ```javascript
164
190
  manager.getMainViewSceneIndex();
165
191
  ```
166
192
 
167
- ### 监听 `mainView` `mode`
193
+ ### Listen to the `mainView` `mode`
168
194
 
169
195
  ```javascript
170
196
  manager.emitter.on("mainViewModeChange", mode => {
171
- // mode 类型为 ViewVisionMode
197
+ // mode type is ViewVisionMode
172
198
  });
173
199
  ```
174
200
 
175
- ### 监听窗口最大化最小化
201
+ ### Listening for window maximization and minimization
176
202
 
177
203
  ```javascript
178
204
  manager.emitter.on("boxStateChange", state => {
179
205
  if (state === "maximized") {
180
- // 最大化
206
+ // maximize
181
207
  }
182
208
  if (state === "minimized") {
183
- // 最小化
209
+ // minimized
184
210
  }
185
211
  if (state === "normal") {
186
- // 恢复正常
212
+ // return to normal
187
213
  }
188
214
  });
189
215
  ```
190
216
 
191
- ### 监听 `broadcaster` 变化
217
+ ### Listening for `broadcaster` changes
192
218
  ```javascript
193
219
  manager.emitter.on("broadcastChange", id => {
194
- // broadcast id 进行了改变
220
+ // broadcast id changed
195
221
  })
196
222
 
197
223
  ```
198
224
 
199
- ### 关闭 `App`
225
+ ### Close the `App`
200
226
 
201
227
  ```javascript
202
228
  manager.closeApp(appId);
203
229
  ```
204
230
 
205
- ## 手动销毁 `WindowManager`
231
+ ## Manually destroy `WindowManager`
206
232
 
207
233
  ```javascript
208
234
  manager.destroy();
209
235
  ```
210
236
 
211
- ## 开发流程
237
+ ## Development process
212
238
 
213
239
  ```bash
214
240
  pnpm install
@@ -0,0 +1,223 @@
1
+ # WindowManager
2
+
3
+ - 目录
4
+ - [概念](docs/concept.md)
5
+ - [references](docs/api.md)
6
+ - [从白板迁移](docs/migrate.md)
7
+ - [回放](docs/replay.md)
8
+ - [进阶使用](docs/advanced.md)
9
+ - [视角跟随](docs/advanced.md#view-mode)
10
+ - [开发自定义 APP](docs/develop-app.md)
11
+ ## MainView
12
+
13
+ `MainView` 也就是主白板, 是垫在所有窗口下面的主白板
14
+
15
+ 因为多窗口的原因,所以抽象出来一个主白板, 并且把以前部分对 `room` 的操作, 迁移到对 `mainView` 操作
16
+
17
+ ### 快速开始
18
+
19
+ ```javascript
20
+ import { WhiteWebSdk } from "white-web-sdk";
21
+ import { WindowManager, BuiltinApps } from "@netless/window-manager";
22
+ import "@netless/window-manager/dist/style.css";
23
+
24
+ const sdk = new WhiteWebSdk({
25
+ appIdentifier: "appIdentifier",
26
+ useMobXState: true // 请确保打开这个选项
27
+ });
28
+
29
+ sdk.joinRoom({
30
+ uuid: "room uuid",
31
+ roomToken: "room token",
32
+ invisiblePlugins: [WindowManager],
33
+ useMultiViews: true, // 多窗口必须用开启 useMultiViews
34
+ disableMagixEventDispatchLimit: true, // 请确保打开这个选项
35
+ }).then(async room => {
36
+ const manager = await WindowManager.mount(
37
+ room,
38
+ container
39
+ // 完整配置见下方
40
+ );
41
+ });
42
+ ```
43
+
44
+ [mount 完整参数](docs/api.md#mount)
45
+
46
+
47
+ > `containerSizeRatio` 为了保证窗口在不同分辨率下显示效果, 白板在相同的比例区域才能进行同步
48
+
49
+ > `chessboard` 当挂载的区域不完全符合比例时, 白板会在挂载的 dom 中划分一个符合比例的区域出来, 此时多出来的部分会默认显示为棋盘透明背景
50
+
51
+ ### `collector`
52
+
53
+ > `collector` 就是窗口最小化时的图标, 默认大小 `width: 40px;` `height: 40px;`
54
+
55
+
56
+ ### 光标同步
57
+
58
+ > 原本的 `SDK` 中的 `cursorAdapter` 在多窗口中不可用, 如需要光标同步功能需要在 `manager` 中开启 `cursor` 选项
59
+
60
+ ```typescript
61
+ sdk.joinRoom({
62
+ // cursorAdapter: cursorAdapter, 原本开启 sdk 中的 cursorAdapter 需要关闭
63
+ userPayload: {
64
+ userId: "用户 id",
65
+ cursorName: "光标名称",
66
+ avatar: "用户头像链接",
67
+ },
68
+ });
69
+
70
+ WindowManager.mount({
71
+ cursor: true, // 开启光标同步
72
+ });
73
+ ```
74
+
75
+ ## APP
76
+
77
+ 静态和动态 PPT 是作为 `App` 插入到白板, 并持久化到白板中
78
+
79
+ `App` 或会在页面刷新时自动创建出来, 不需要重复插入
80
+
81
+ 如果 `App` 需要 `scenePath` 时,那么一个 `scenePath` 只能同时打开一个,要求为 `App` 实例唯一
82
+
83
+ ### 添加静态/动态 PPT 到白板上
84
+
85
+ ```javascript
86
+ const appId = await manager.addApp({
87
+ kind: BuiltinApps.DocsViewer,
88
+ options: {
89
+ scenePath: "/docs-viewer",
90
+ title: "docs1", // 可选
91
+ scenes: [], // SceneDefinition[] 静态/动态 Scene 数据
92
+ },
93
+ });
94
+ ```
95
+
96
+ ### 添加音视频到白板
97
+
98
+ ```javascript
99
+ const appId = await manager.addApp({
100
+ kind: BuiltinApps.MediaPlayer,
101
+ options: {
102
+ title: "test.mp3", // 可选
103
+ },
104
+ attributes: {
105
+ src: "xxxx", // 音视频 url
106
+ },
107
+ });
108
+ ```
109
+
110
+ ### 设置跟随模式
111
+
112
+ 只有广播端也就是老师需要设置跟随模式, 其他端的主白板都会跟随广播端的视角
113
+
114
+ > 注意 `manager` 的 `setViewMode` 不能和 `room.setViewMode` 同时使用
115
+
116
+ ```javascript
117
+ manager.setViewMode("broadcaster"); // 开启跟随模式
118
+ manager.setViewMode("freedom"); // 关闭跟随模式
119
+ ```
120
+
121
+ 获取当前的 `broadcaster` ID
122
+ ```javascript
123
+ manager.broadcaster
124
+ ```
125
+
126
+ ### 设置所有 `app` 的 `readonly`
127
+
128
+ ```javascript
129
+ manager.setReadonly(true); // 所有窗口变成 readonly 状态
130
+ manager.setReadonly(false); // 解锁设置的 readonly, 注意如果当前白板的 isWritable 为 false 以白板的状态为最高优先级
131
+ ```
132
+
133
+ ### 切换 `mainView` 为可写状态
134
+
135
+ ```javascript
136
+ manager.switchMainViewToWriter();
137
+ ```
138
+
139
+ ### 切换 `mainView` `scenePath`
140
+
141
+ 切换主白板的 `ScenePath` 并把主白板设置为可写状态
142
+
143
+ ```javascript
144
+ manager.setMainViewScenePath(scenePath);
145
+ ```
146
+
147
+ ### 切换 `mainView` `sceneIndex`
148
+
149
+ 切换主白板的 `SceneIndex` 并把主白板设置为可写状态
150
+
151
+ ```javascript
152
+ manager.setMainViewSceneIndex(sceneIndex);
153
+ ```
154
+
155
+ ### 获取 `mainView` `scenePath`
156
+
157
+ ```javascript
158
+ manager.getMainViewScenePath();
159
+ ```
160
+
161
+ ### 获取 `mainView` `sceneIndex`
162
+
163
+ ```javascript
164
+ manager.getMainViewSceneIndex();
165
+ ```
166
+
167
+ ### 监听 `mainView` 的 `mode`
168
+
169
+ ```javascript
170
+ manager.emitter.on("mainViewModeChange", mode => {
171
+ // mode 类型为 ViewVisionMode
172
+ });
173
+ ```
174
+
175
+ ### 监听窗口最大化最小化
176
+
177
+ ```javascript
178
+ manager.emitter.on("boxStateChange", state => {
179
+ if (state === "maximized") {
180
+ // 最大化
181
+ }
182
+ if (state === "minimized") {
183
+ // 最小化
184
+ }
185
+ if (state === "normal") {
186
+ // 恢复正常
187
+ }
188
+ });
189
+ ```
190
+
191
+ ### 监听 `broadcaster` 变化
192
+ ```javascript
193
+ manager.emitter.on("broadcastChange", id => {
194
+ // broadcast id 进行了改变
195
+ })
196
+
197
+ ```
198
+
199
+ ### 关闭 `App`
200
+
201
+ ```javascript
202
+ manager.closeApp(appId);
203
+ ```
204
+
205
+ ## 手动销毁 `WindowManager`
206
+
207
+ ```javascript
208
+ manager.destroy();
209
+ ```
210
+
211
+ ## 开发流程
212
+
213
+ ```bash
214
+ pnpm install
215
+
216
+ pnpm build
217
+
218
+ cd example
219
+
220
+ pnpm install
221
+
222
+ pnpm dev
223
+ ```