@netless/window-manager 0.4.55 → 0.4.57

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,369 +1,369 @@
1
1
  ## AppContext
2
2
 
3
- `AppContext` 是插件运行时传入的上下文
4
- 你可以通过此对象操作 APP ui, 获取当前房间的状态, 以及订阅状态的变化
5
-
6
- - [api](#api)
7
- - [view](#view)
8
- - [page](#page)
9
- - [storage](#storage)
10
- - [ui(box)](#box)
11
- - [events](#events)
3
+ `AppContext` is the context passed in when the plugin runs.
4
+ You can operate the ui of the APP through this object, get the status of the current room, and subscribe to the status change.
5
+
6
+ - [API](#api)
7
+ - [View](#view)
8
+ - [Page](#page)
9
+ - [Storage](#storage)
10
+ - [UI (box)](#box)
11
+ - [Events](#events)
12
12
  - [Advanced](#Advanced)
13
13
 
14
14
  <h2 id="api">API</h2>
15
15
 
16
16
  - **context.appId**
17
17
 
18
- 插入 `app` 时生成的唯一 ID
18
+ Unique ID generated when inserting `app`
19
19
 
20
- ```ts
21
- const appId = context.appId;
22
- ```
20
+ ```ts
21
+ const appId = context.appId;
22
+ ```
23
23
 
24
24
  - **context.isReplay**
25
25
 
26
- 类型: `boolean`
26
+ Type: `boolean`
27
27
 
28
- 当前是否回放模式
28
+ Whether the current playback mode
29
29
 
30
30
  - **context.getDisplayer()**
31
31
 
32
- 在默认情况下 `Displayer` 为白板的 `room` 实例
32
+ By default `Displayer` is the `room` instance of the whiteboard
33
33
 
34
- 回放时则为 `Player` 实例
34
+ A `Player` instance during playback
35
35
 
36
- ```ts
37
- const displayer = context.getDisplayer();
36
+ ```ts
37
+ const displayer = context.getDisplayer();
38
38
 
39
- assert(displayer, room); // 互动房间
40
- assert(displayer, player); // 回放房间
41
- ```
39
+ assert(displayer, room); // interactive room
40
+ assert(displayer, player); // playback room
41
+ ```
42
42
 
43
43
 
44
44
  - **context.getIsWritable()**
45
45
 
46
- 获取当前状态是否可写\
47
- 可以通过监听 `writableChange` 事件获取可写状态的改变
46
+ Get whether the current state is writable\
47
+ You can get the change of writable state by listening to `writableChange` event
48
48
 
49
- ```ts
50
- const isWritable = context.getIsWritable();
51
- ```
49
+ ```ts
50
+ const isWritable = context.getIsWritable();
51
+ ```
52
52
 
53
53
  - **context.getBox()**
54
54
 
55
- 获取当前 app box
55
+ Get the box of the current app
56
56
 
57
- ```ts
58
- const box = context.getBox();
57
+ ```ts
58
+ const box = context.getBox();
59
59
 
60
- box.$content; // box main element
61
- box.$footer;
62
- ```
60
+ box.$content; // main element of the box
61
+ box.$footer;
62
+ ```
63
63
 
64
- <h3 id="view">挂载白板</h3>
64
+ <h3 id="view">Mount whiteboard</h3>
65
65
 
66
- 当应用想要一个可以涂画的白板,可以使用以下接口
66
+ When the application wants a whiteboard that can be drawn on, the following interface can be used
67
67
 
68
68
  - **context.mountView()**
69
69
 
70
- 挂载白板到指定 dom
70
+ Mount the whiteboard to the specified dom
71
71
 
72
- ```ts
73
- context.mountView(element);
74
- ```
72
+ ```ts
73
+ context.mountView(element);
74
+ ```
75
75
 
76
- **注意** 在调用 `manager` `addApp` 时必须填写 `scenePath` 才可以使用 `view`
76
+ **Note** When calling `addApp` of `manager`, you must fill in `scenePath` to use `view`
77
77
  ```ts
78
78
  manager.addApp({
79
- kind: "xxx",
80
- options: { // 可选配置
81
- scenePath: "/example-path"
82
- }
79
+ kind: "xxx",
80
+ options: { // optional configuration
81
+ scenePath: "/example-path"
82
+ }
83
83
  })
84
84
  ```
85
85
 
86
86
  <h3 id="page">Page</h3>
87
87
 
88
- 白板有多页的概念, 可以通过以下接口添加,切换,以及删除
88
+ The whiteboard has the concept of multiple pages, which can be added, switched, and deleted through the following interfaces
89
89
 
90
90
  - **context.addPage()**
91
91
 
92
- 添加一页至 `view`
92
+ Add a page to `view`
93
93
 
94
- ```ts
95
- context.addPage() // 默认在最后添加一页
96
- context.addPage({ after: true }) // 在当前页后添加一页
97
- context.addPage({ scene: { name: "page2" } }) // 传入 page 信息
98
- ```
94
+ ```ts
95
+ context.addPage() // add a page at the end by default
96
+ context.addPage({ after: true }) // add a page after the current page
97
+ context.addPage({ scene: { name: "page2" } }) // pass in page information
98
+ ```
99
99
 
100
100
  - **context.nextPage()**
101
101
 
102
- 上一页
102
+ previous page
103
103
 
104
- ```ts
105
- context.nextPage();
106
- ```
104
+ ```ts
105
+ context.nextPage();
106
+ ```
107
107
 
108
108
  - **context.prevPage()**
109
109
 
110
- 下一页
110
+ next page
111
111
 
112
- ```ts
113
- context.prevPage();
114
- ```
112
+ ```ts
113
+ context.prevPage();
114
+ ```
115
115
  - **context.removePage()**
116
116
 
117
- 删除一页
117
+ delete a page
118
118
 
119
- ```ts
120
- context.removePage() // 默认删除当前页
121
- context.removePage(1) // 也可以指定 index 删除
122
- ```
119
+ ```ts
120
+ context.removePage() // delete the current page by default
121
+ context.removePage(1) // You can also specify index to delete
122
+ ```
123
123
 
124
124
  - **context.pageState**
125
125
 
126
- 获取当前所在的 `index` 和一共有多少页\
127
- 当想要监听 `pageState` 的变化时, 可以监听 `pageStateChange` 事件获取最新的 `pageState`
126
+ Get the current `index` and how many pages there are\
127
+ When you want to monitor the change of `pageState`, you can listen to the `pageStateChange` event to get the latest `pageState`
128
128
 
129
- ```ts
130
- context.pageState;
131
- // {
132
- // index: number,
133
- // length: number,
134
- // }
135
- ```
129
+ ```ts
130
+ context.pageState;
131
+ // {
132
+ // index: number,
133
+ // length: number,
134
+ // }
135
+ ```
136
136
 
137
137
  <h3 id="storage">storage</h3>
138
138
 
139
- 存储和同步状态,以及发送事件的一系列集合
139
+ Store and synchronize state, and send a collection of events
140
140
 
141
141
  - **context.storage**
142
142
 
143
- 默认创建的 storage 实例
143
+ Storage instance created by default
144
144
 
145
- ```ts
146
- context.storage
147
- ```
145
+ ```ts
146
+ context.storage
147
+ ```
148
148
 
149
149
  - **context.createStorage(namespace)**
150
150
 
151
- 同时你也可以创建多个 `storage` 实例
151
+ At the same time you can also create multiple `storage` instances
152
152
 
153
- 返回: `Storage<State>`
153
+ Returns: `Storage<State>`
154
154
 
155
- ```ts
156
- type State = { count: number };
157
- const defaultState = { count: 0 };
158
- const storage = context.createStorage<State>("store1", defaultState);
159
- ```
155
+ ```ts
156
+ type State = { count: number };
157
+ const defaultState = { count: 0 };
158
+ const storage = context.createStorage<State>("store1", defaultState);
159
+ ```
160
160
 
161
161
  - **storage.state**
162
162
 
163
- 类型: `State`\
164
- 默认值: `defaultState`
163
+ Type: `State`\
164
+ Default: `defaultState`
165
165
 
166
- 在所有客户端之间同步的状态,调用 `storage.setState()` 来改变它。
166
+ State synchronized between all clients, call `storage.setState()` to change it.
167
167
 
168
168
  - **storage.ensureState(partialState)**
169
169
 
170
- 确保 `storage.state` 包含某些初始值,类似于执行了:
170
+ Make sure `storage.state` contains some initial values, something like doing:
171
171
 
172
- ```js
173
- // 这段代码不能直接运行,因为 app.state 是只读的
174
- storage.state = { ...partialState, ...storage.state };
175
- ```
172
+ ```js
173
+ // This code cannot be run directly because app.state is read-only
174
+ storage.state = { ...partialState, ...storage.state };
175
+ ```
176
176
 
177
- **partialState**
177
+ **partialState**
178
178
 
179
- 类型: `Partial<State>`
179
+ Type: `Partial<State>`
180
180
 
181
- ```js
182
- storage.state; // { a: 1 }
183
- storage.ensureState({ a: 0, b: 0 });
184
- storage.state; // { a: 1, b: 0 }
185
- ```
181
+ ```js
182
+ storage.state; // { a: 1 }
183
+ storage.ensureState({ a: 0, b: 0 });
184
+ storage.state; // { a: 1, b: 0 }
185
+ ```
186
186
 
187
187
  - **storage.setState(partialState)**
188
188
 
189
- React `setState` 类似,更新 `storage.state` 并同步到所有客户端。
189
+ Similar to React's `setState`, update `storage.state` and sync to all clients.
190
190
 
191
- 当设置某个字段为 `undefined` 时,它会被从 `storage.state` 里删除。
191
+ When setting a field to `undefined`, it will be removed from `storage.state`.
192
192
 
193
- > - 状态同步所需的时间和网络状态与数据大小有关,建议只在 state 里存储必须的数据。
193
+ > The time required for state synchronization and the network state are related to the data size. It is recommended to only store necessary data in the state.
194
194
 
195
- **partialState**
195
+ **partialState**
196
196
 
197
- 类型: `Partial<State>`
197
+ Type: `Partial<State>`
198
198
 
199
- ```js
200
- storage.state; //=> { count: 0, a: 1 }
201
- storage.setState({ count: storage.state.count + 1, b: 2 });
202
- storage.state; //=> { count: 1, a: 1, b: 2 }
203
- ```
199
+ ```js
200
+ storage.state; //=> { count: 0, a: 1 }
201
+ storage.setState({ count: storage.state.count + 1, b: 2 });
202
+ storage.state; //=> { count: 1, a: 1, b: 2 }
203
+ ```
204
204
 
205
205
  - **storage.addStateChangedListener(listener)**
206
206
 
207
- 它在有人调用 `storage.setState()` 后触发 (包含当前 `storage`)
207
+ It fires after someone calls `storage.setState()` (including the current `storage`)
208
208
 
209
- 返回: `() => void`
209
+ return: `() => void`
210
210
 
211
- ```js
212
- const disposer = storage.addStateChangedListener(diff => {
213
- console.log("state changed", diff.oldValue, diff.newValue);
214
- disposer(); // remove listener by calling disposer
215
- });
216
- ```
211
+ ```js
212
+ const disposer = storage.addStateChangedListener(diff => {
213
+ console.log("state changed", diff.oldValue, diff.newValue);
214
+ disposer(); // remove listener by calling disposer
215
+ });
216
+ ```
217
217
 
218
218
  - **context.dispatchMagixEvent(event, payload)**
219
219
 
220
- 向其他客户端广播事件消息
220
+ Broadcast event messages to other clients
221
221
 
222
- ```js
223
- context.dispatchMagixEvent("click", { data: "data" });
224
- ```
222
+ ```js
223
+ context.dispatchMagixEvent("click", { data: "data" });
224
+ ```
225
225
 
226
226
  - **context.addMagixEventListener(event, listener)**
227
227
 
228
- 当接收来自其他客户端的消息时(当其他客户端调用'context.dispatchMagixEvent()`时), 它会被触发
228
+ It is triggered when receiving messages from other clients (when other clients call `context.dispatchMagixEvent()`)
229
229
 
230
- 返回: `() => void` a disposer function.
230
+ Returns: `() => void` a disposer function.
231
231
 
232
- ```js
233
- const disposer = context.addMagixEventListener("click", ({ payload }) => {
234
- console.log(payload.data);
235
- disposer();
236
- });
232
+ ```js
233
+ const disposer = context.addMagixEventListener("click", ({ payload }) => {
234
+ console.log(payload.data);
235
+ disposer();
236
+ });
237
237
 
238
- context.dispatchMagixEvent("click", { data: "data" });
239
- ```
238
+ context.dispatchMagixEvent("click", { data: "data" });
239
+ ```
240
240
 
241
241
  <h2>UI (box)</h2>
242
242
 
243
- box 是白板为所有应用默认创建的 UI
244
- 应用所有可以操作的 UI 部分都在 box 范围内
243
+ Box is the default UI created by whiteboard for all apps.
244
+ All operable UI parts of the application are within the bounds of the box.
245
245
 
246
246
  - **context.getBox()**
247
247
 
248
- 获取 box
249
- 返回类型: `ReadonlyTeleBox`
248
+ get box
249
+ Return type: `ReadonlyTeleBox`
250
250
 
251
251
  - **box.mountStyles()**
252
252
 
253
- 挂载样式到 `box`
254
- 参数: `string | HTMLStyleElement`
253
+ Mount styles to `box`
254
+ Parameters: `string | HTMLStyleElement`
255
255
 
256
- ```js
257
- const box = context.getBox();
258
- box.mountStyles(`
259
- .app-span {
260
- color: red;
261
- }
262
- `)
263
- ```
256
+ ```js
257
+ const box = context. getBox();
258
+ box. mountStyles(`
259
+ .app-span {
260
+ color: red;
261
+ }
262
+ `)
263
+ ```
264
264
 
265
265
  - **box.mountContent()**
266
266
 
267
- 挂载元素到 `box`
268
- 参数: `HTMLElement`
267
+ Mount element to `box`
268
+ Parameters: `HTMLElement`
269
269
 
270
- ```js
271
- const box = context.getBox();
272
- const content = document.createElement("div");
273
- box.mountContent(context);
274
- ```
270
+ ```js
271
+ const box = context. getBox();
272
+ const content = document. createElement("div");
273
+ box. mountContent(context);
274
+ ```
275
275
 
276
276
  - **box.mountFooter()**
277
277
 
278
- 挂载元素到 `box` `footer`
279
- 参数: `HTMLElement`
278
+ Mount element to `footer` of `box`
279
+ Parameters: `HTMLElement`
280
280
 
281
- ```js
282
- const box = context.getBox();
283
- const footer = document.createElement("div");
284
- box.mountFooter(context);
285
- ```
281
+ ```js
282
+ const box = context. getBox();
283
+ const footer = document. createElement("div");
284
+ box. mountFooter(context);
285
+ ```
286
286
 
287
287
  <h2 id="events">events</h2>
288
288
 
289
289
  - **destroy**
290
290
 
291
- app 被关闭时发送
291
+ Sent when the app is closed
292
292
 
293
- ```ts
294
- context.emitter.on("destroy", () => {
295
- // release your listeners
296
- });
297
- ```
293
+ ```ts
294
+ context.emitter.on("destroy", () => {
295
+ // release your listeners
296
+ });
297
+ ```
298
298
 
299
299
  - **writableChange**
300
300
 
301
- 白板可写状态切换时触发
301
+ Triggered when the whiteboard's writable state is switched
302
302
 
303
- ```ts
304
- context.emitter.on("writableChange", isWritable => {
305
- //
306
- });
307
- ```
303
+ ```ts
304
+ context.emitter.on("writableChange", isWritable => {
305
+ //
306
+ });
307
+ ```
308
308
 
309
309
  - **focus**
310
310
 
311
- 当前 app 获得焦点或者失去焦点时触发
311
+ Triggered when the current app gains or loses focus
312
312
 
313
- ```ts
314
- context.emitter.on("focus", focus => {
315
- //
316
- });
317
- ```
313
+ ```ts
314
+ context.emitter.on("focus", focus => {
315
+ //
316
+ });
317
+ ```
318
318
 
319
319
  - **pageStateChange**
320
320
 
321
- `PageState`
321
+ `PageState`
322
322
 
323
- ```ts
324
- type PateState {
325
- index: number;
326
- length: number;
327
- }
328
- ```
323
+ ```ts
324
+ type PateState {
325
+ index: number;
326
+ length: number;
327
+ }
328
+ ```
329
329
 
330
- 当前页数和总页数变化时触发
330
+ Triggered when the current page number and the total page number change
331
331
 
332
- ```ts
333
- context.emitter.on("pageStateChange", pageState => {
334
- // { index: 0, length: 1 }
335
- });
336
- ```
332
+ ```ts
333
+ context.emitter.on("pageStateChange", pageState => {
334
+ // { index: 0, length: 1 }
335
+ });
336
+ ```
337
337
  - **roomStageChange**
338
338
 
339
- 房间的状态变化时触发\
340
- 比如当教具切换时
339
+ Triggered when the state of the room changes\
340
+ For example, when teaching aids are switched
341
341
 
342
- ```js
343
- context.emitter.on("roomStageChange", stage => {
344
- if (state.memberState) {
345
- console.log("appliance change to", state.memberState.currentApplianceName);
346
- }
347
- });
348
- ```
349
-
350
- 或者是当前房间人数变化时
351
-
352
- ```js
342
+ ```js
353
343
  context.emitter.on("roomStageChange", stage => {
354
- if (state.roomMembers) {
355
- console.log("current room members change", state.roomMembers);
356
- }
357
- });
358
- ```
359
- 详细状态的介绍请参考 https://developer.netless.link/javascript-zh/home/business-state-management
344
+ if (state. memberState) {
345
+ console.log("appliance change to", state.memberState.currentApplianceName);
346
+ }
347
+ });
348
+ ```
349
+
350
+ or when the number of people in the current room changes
351
+
352
+ ```js
353
+ context.emitter.on("roomStageChange", stage => {
354
+ if (state. roomMembers) {
355
+ console.log("current room members change", state.roomMembers);
356
+ }
357
+ });
358
+ ```
359
+ For detailed status introduction, please refer to https://developer.netless.link/javascript-zh/home/business-state-management
360
360
 
361
361
  <h2 id="Advanced">Advanced</h2>
362
362
 
363
363
  - **context.getView()**
364
364
 
365
- 获取 `view` 实例
365
+ Get `view` instance
366
366
 
367
- ```ts
368
- const view = context.getView();
369
- ```
367
+ ```ts
368
+ const view = context.getView();
369
+ ```
package/docs/basic.md CHANGED
@@ -1,64 +1,63 @@
1
- # 基础教程
2
- `WindowManager` 内置了 `DocsViewer` `MediaPlayer` 用来播放 PPT 和音视频
1
+ # Basic Tutorial
2
+ `WindowManager` has built-in `DocsViewer` and `MediaPlayer` to play PPT and audio and video
3
3
 
4
- ## 打开动态/静态 PPT
4
+ ## Open dynamic/static PPT
5
5
  ```typescript
6
6
  import { BuiltinApps } from "@netless/window-manager";
7
7
 
8
8
  const appId = await manager.addApp({
9
- kind: BuiltinApps.DocsViewer,
10
- options: {
11
- scenePath: "/docs-viewer", // 定义 ppt 所在的 scenePath
12
- title: "docs1", // 可选
13
- scenes: [], // SceneDefinition[] 静态/动态 Scene 数据
14
- },
9
+ kind: BuiltinApps.DocsViewer,
10
+ options: {
11
+ scenePath: "/docs-viewer", // define the scenePath where the ppt is located
12
+ title: "docs1", // optional
13
+ scenes: [], // SceneDefinition[] static/dynamic Scene data
14
+ },
15
15
  });
16
16
  ```
17
17
 
18
- ## 打开音视频
18
+ ## Open audio and video
19
19
  ```typescript
20
20
  import { BuiltinApps } from "@netless/window-manager";
21
21
 
22
22
  const appId = await manager.addApp({
23
- kind: BuiltinApps.MediaPlayer,
24
- options: {
25
- title: "test.mp3", // 可选
26
- },
27
- attributes: {
28
- src: "xxxx", // 音视频 url
29
- },
23
+ kind: BuiltinApps.MediaPlayer,
24
+ options: {
25
+ title: "test.mp3", // optional
26
+ },
27
+ attributes: {
28
+ src: "xxxx", // audio and video url
29
+ },
30
30
  });
31
31
  ```
32
32
 
33
33
 
34
- ## 查询所有的 App
34
+ ## Query all apps
35
35
  ```typescript
36
36
  const apps = manager.queryAll();
37
37
  ```
38
38
 
39
- ## 查询单个 APP
39
+ ## Query a single APP
40
40
  ```typescript
41
41
  const app = manager.queryOne(appId);
42
- ```
42
+ ```
43
43
 
44
- ## 关闭 App
44
+ ## Close App
45
45
  ```typescript
46
46
  manager.closeApp(appId);
47
47
  ```
48
48
 
49
49
  ## events
50
50
 
51
- ### 窗口最小化最大化
51
+ ### Minimize and maximize the window
52
52
  ```typescript
53
53
  manager.emitter.on("boxStateChange", state => {
54
- // maximized | minimized | normal
54
+ // maximized | minimized | normal
55
55
  });
56
56
  ```
57
57
 
58
- ### 视角跟随模式
58
+ ### Camera follow mode
59
59
  ```typescript
60
60
  manager.emitter.on("broadcastChange", state => {
61
- // state: number | undefined
61
+ // state: number | undefined
62
62
  });
63
63
  ```
64
-