@netless/window-manager 1.0.0-canary.9 → 1.0.0
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/LICENSE.txt +21 -0
- package/README.md +90 -64
- package/README.zh-cn.md +224 -0
- package/dist/index.d.ts +1133 -40
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/{index.es.js → index.mjs} +9480 -6984
- package/dist/index.mjs.map +1 -0
- package/dist/style.css +1 -1
- package/docs/advanced.md +55 -55
- package/docs/api.md +124 -113
- package/docs/app-context.md +248 -209
- package/docs/basic.md +25 -26
- package/docs/camera.md +19 -20
- package/docs/cn/advanced.md +137 -0
- package/docs/cn/api.md +309 -0
- package/docs/cn/app-context.md +369 -0
- package/docs/cn/basic.md +64 -0
- package/docs/cn/camera.md +53 -0
- package/docs/cn/concept.md +9 -0
- package/docs/cn/custom-max-bar.md +31 -0
- package/docs/cn/develop-app.md +94 -0
- package/docs/cn/export-pdf.md +48 -0
- package/docs/cn/migrate.md +60 -0
- package/docs/cn/replay.md +40 -0
- package/docs/concept.md +6 -5
- package/docs/custom-max-bar.md +31 -0
- package/docs/develop-app.md +22 -19
- package/docs/export-pdf.md +48 -0
- package/docs/migrate.md +25 -27
- package/docs/quickstart.md +50 -0
- package/docs/replay.md +20 -20
- package/package.json +32 -22
- package/src/App/AppContext.ts +105 -73
- package/src/App/AppPageStateImpl.ts +6 -25
- package/src/App/AppProxy.ts +41 -166
- package/src/App/MagixEvent/index.ts +38 -38
- package/src/App/Storage/StorageEvent.ts +13 -13
- package/src/App/Storage/index.ts +269 -245
- package/src/App/Storage/typings.ts +4 -2
- package/src/App/Storage/utils.ts +3 -3
- package/src/App/index.ts +0 -1
- package/src/AppListener.ts +8 -8
- package/src/AppManager.ts +88 -77
- package/src/AttributesDelegate.ts +42 -22
- package/src/BoxEmitter.ts +12 -6
- package/src/BoxManager.ts +128 -108
- package/src/ContainerResizeObserver.ts +75 -0
- package/src/Cursor/Cursor.svelte +16 -5
- package/src/Cursor/Cursor.svelte.d.ts +21 -0
- package/src/Cursor/Cursor.ts +77 -13
- package/src/Cursor/icons.ts +6 -0
- package/src/Cursor/icons2.ts +66 -0
- package/src/Cursor/index.ts +127 -26
- package/src/Helper.ts +94 -14
- package/src/InternalEmitter.ts +2 -7
- package/src/Page/index.ts +1 -1
- package/src/PageState.ts +6 -5
- package/src/ReconnectRefresher.ts +9 -4
- package/src/RedoUndo.ts +3 -3
- package/src/Register/index.ts +22 -17
- package/src/Register/loader.ts +26 -22
- package/src/Register/storage.ts +13 -13
- package/src/Utils/Common.ts +18 -14
- package/src/Utils/Reactive.ts +26 -25
- package/src/Utils/RoomHacker.ts +4 -4
- package/src/Utils/error.ts +0 -1
- package/src/View/IframeBridge.ts +680 -0
- package/src/View/MainView.ts +127 -53
- package/src/callback.ts +21 -1
- package/src/constants.ts +0 -2
- package/src/image/pencil-eraser-1.svg +3 -0
- package/src/image/pencil-eraser-2.svg +3 -0
- package/src/image/pencil-eraser-3.svg +3 -0
- package/src/index.ts +220 -83
- package/src/style.css +27 -10
- package/src/typings.ts +20 -10
- package/.prettierignore +0 -7
- package/.prettierrc.json +0 -9
- package/CHANGELOG.md +0 -196
- package/__mocks__/white-web-sdk.ts +0 -50
- package/dist/App/AppContext.d.ts +0 -76
- package/dist/App/AppPageStateImpl.d.ts +0 -21
- package/dist/App/AppProxy.d.ts +0 -86
- package/dist/App/AppViewSync.d.ts +0 -11
- package/dist/App/MagixEvent/index.d.ts +0 -29
- package/dist/App/Storage/StorageEvent.d.ts +0 -8
- package/dist/App/Storage/index.d.ts +0 -39
- package/dist/App/Storage/typings.d.ts +0 -22
- package/dist/App/Storage/utils.d.ts +0 -5
- package/dist/App/WhiteboardView.d.ts +0 -22
- package/dist/App/index.d.ts +0 -3
- package/dist/AppListener.d.ts +0 -21
- package/dist/AppManager.d.ts +0 -107
- package/dist/AttributesDelegate.d.ts +0 -80
- package/dist/BoxEmitter.d.ts +0 -34
- package/dist/BoxManager.d.ts +0 -99
- package/dist/BuiltinApps.d.ts +0 -5
- package/dist/Cursor/Cursor.d.ts +0 -39
- package/dist/Cursor/icons.d.ts +0 -3
- package/dist/Cursor/index.d.ts +0 -46
- package/dist/Helper.d.ts +0 -17
- package/dist/InternalEmitter.d.ts +0 -39
- package/dist/Page/PageController.d.ts +0 -21
- package/dist/Page/index.d.ts +0 -3
- package/dist/PageState.d.ts +0 -9
- package/dist/ReconnectRefresher.d.ts +0 -24
- package/dist/RedoUndo.d.ts +0 -18
- package/dist/Register/index.d.ts +0 -28
- package/dist/Register/loader.d.ts +0 -4
- package/dist/Register/storage.d.ts +0 -8
- package/dist/Utils/AppCreateQueue.d.ts +0 -15
- package/dist/Utils/Common.d.ts +0 -23
- package/dist/Utils/Reactive.d.ts +0 -6
- package/dist/Utils/RoomHacker.d.ts +0 -3
- package/dist/Utils/error.d.ts +0 -27
- package/dist/Utils/log.d.ts +0 -1
- package/dist/View/CameraSynchronizer.d.ts +0 -16
- package/dist/View/MainView.d.ts +0 -47
- package/dist/View/ViewManager.d.ts +0 -13
- package/dist/callback.d.ts +0 -24
- package/dist/constants.d.ts +0 -49
- package/dist/index.cjs.js +0 -46
- package/dist/index.umd.js +0 -46
- package/dist/typings.d.ts +0 -82
- package/jest.config.js +0 -27
- package/pnpm-lock.yaml +0 -6302
- package/src/App/AppViewSync.ts +0 -68
- package/src/App/WhiteboardView.ts +0 -83
- package/src/View/CameraSynchronizer.ts +0 -56
- package/vite.config.js +0 -51
- /package/docs/{qickstart.md → cn/quickstart.md} +0 -0
package/docs/app-context.md
CHANGED
@@ -1,330 +1,369 @@
|
|
1
1
|
## AppContext
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
- [
|
8
|
-
- [
|
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)
|
9
12
|
- [Advanced](#Advanced)
|
10
13
|
|
11
14
|
<h2 id="api">API</h2>
|
12
15
|
|
13
16
|
- **context.appId**
|
14
17
|
|
15
|
-
|
18
|
+
Unique ID generated when inserting `app`
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
```ts
|
21
|
+
const appId = context.appId;
|
22
|
+
```
|
20
23
|
|
21
24
|
- **context.isReplay**
|
22
25
|
|
23
|
-
|
26
|
+
Type: `boolean`
|
24
27
|
|
25
|
-
|
28
|
+
Whether the current playback mode
|
26
29
|
|
27
|
-
- **context.
|
30
|
+
- **context.getDisplayer()**
|
28
31
|
|
29
|
-
|
32
|
+
By default `Displayer` is the `room` instance of the whiteboard
|
30
33
|
|
31
|
-
|
34
|
+
A `Player` instance during playback
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
```ts
|
37
|
+
const displayer = context.getDisplayer();
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
+
assert(displayer, room); // interactive room
|
40
|
+
assert(displayer, player); // playback room
|
41
|
+
```
|
39
42
|
|
40
43
|
|
41
|
-
- **context.
|
44
|
+
- **context.getIsWritable()**
|
42
45
|
|
43
|
-
|
44
|
-
|
46
|
+
Get whether the current state is writable\
|
47
|
+
You can get the change of writable state by listening to `writableChange` event
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
```ts
|
50
|
+
const isWritable = context.getIsWritable();
|
51
|
+
```
|
49
52
|
|
50
|
-
- **context.
|
53
|
+
- **context.getBox()**
|
51
54
|
|
52
|
-
|
55
|
+
Get the box of the current app
|
53
56
|
|
54
|
-
|
57
|
+
```ts
|
58
|
+
const box = context.getBox();
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
box.$content; // main element of the box
|
61
|
+
box.$footer;
|
62
|
+
```
|
58
63
|
|
59
|
-
|
60
|
-
box.$footer;
|
61
|
-
```
|
64
|
+
<h3 id="view">Mount whiteboard</h3>
|
62
65
|
|
63
|
-
|
66
|
+
When the application wants a whiteboard that can be drawn on, the following interface can be used
|
64
67
|
|
65
|
-
|
68
|
+
- **context.mountView()**
|
66
69
|
|
67
|
-
|
70
|
+
Mount the whiteboard to the specified dom
|
68
71
|
|
69
|
-
|
72
|
+
```ts
|
73
|
+
context.mountView(element);
|
74
|
+
```
|
70
75
|
|
71
|
-
|
76
|
+
**Note** When calling `addApp` of `manager`, you must fill in `scenePath` to use `view`
|
77
|
+
```ts
|
78
|
+
manager.addApp({
|
79
|
+
kind: "xxx",
|
80
|
+
options: { // optional configuration
|
81
|
+
scenePath: "/example-path"
|
82
|
+
}
|
83
|
+
})
|
84
|
+
```
|
72
85
|
|
73
|
-
|
74
|
-
const view = context.createWhiteBoardView();
|
75
|
-
```
|
86
|
+
<h3 id="page">Page</h3>
|
76
87
|
|
77
|
-
|
78
|
-
const view = context.createWhiteBoardView(10); // 生成带有 10 页的白板
|
79
|
-
```
|
88
|
+
The whiteboard has the concept of multiple pages, which can be added, switched, and deleted through the following interfaces
|
80
89
|
|
81
|
-
- **
|
90
|
+
- **context.addPage()**
|
82
91
|
|
83
|
-
|
92
|
+
Add a page to `view`
|
84
93
|
|
85
|
-
|
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
|
+
```
|
86
99
|
|
87
|
-
|
100
|
+
- **context.nextPage()**
|
88
101
|
|
89
|
-
|
102
|
+
previous page
|
90
103
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
context.addPage({ after: true }) // 在当前页后添加一页
|
95
|
-
context.addPage({ scene: { name: "page2" } }) // 传入 page 信息
|
96
|
-
```
|
104
|
+
```ts
|
105
|
+
context.nextPage();
|
106
|
+
```
|
97
107
|
|
98
|
-
|
108
|
+
- **context.prevPage()**
|
99
109
|
|
100
|
-
|
110
|
+
next page
|
101
111
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
112
|
+
```ts
|
113
|
+
context.prevPage();
|
114
|
+
```
|
115
|
+
- **context.removePage()**
|
106
116
|
|
107
|
-
|
117
|
+
delete a page
|
108
118
|
|
109
|
-
|
119
|
+
```ts
|
120
|
+
context.removePage() // delete the current page by default
|
121
|
+
context.removePage(1) // You can also specify index to delete
|
122
|
+
```
|
110
123
|
|
111
|
-
|
112
|
-
const view = context.createWhiteBoardView();
|
113
|
-
view.prevPage();
|
114
|
-
```
|
115
|
-
- **removePage()**
|
124
|
+
- **context.pageState**
|
116
125
|
|
117
|
-
|
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`
|
118
128
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
类型: `PageState`
|
128
|
-
|
129
|
-
```ts
|
130
|
-
type PageState {
|
131
|
-
index: number
|
132
|
-
length: number
|
133
|
-
}
|
134
|
-
```
|
135
|
-
|
136
|
-
```ts
|
137
|
-
const view = context.createWhiteBoardView();
|
138
|
-
view.pageState // PageState
|
139
|
-
```
|
140
|
-
|
141
|
-
- **pageState$**
|
142
|
-
|
143
|
-
订阅 `pageState` 的变化
|
144
|
-
|
145
|
-
```ts
|
146
|
-
const view = context.createWhiteBoardView();
|
147
|
-
view.pageState$.subscribe(pageState => {
|
148
|
-
console.log("pageStateChange", pageState)
|
149
|
-
})
|
150
|
-
```
|
129
|
+
```ts
|
130
|
+
context.pageState;
|
131
|
+
// {
|
132
|
+
// index: number,
|
133
|
+
// length: number,
|
134
|
+
// }
|
135
|
+
```
|
151
136
|
|
152
137
|
<h3 id="storage">storage</h3>
|
153
138
|
|
154
|
-
|
139
|
+
Store and synchronize state, and send a collection of events
|
155
140
|
|
156
141
|
- **context.storage**
|
157
142
|
|
158
|
-
|
143
|
+
Storage instance created by default
|
159
144
|
|
160
|
-
|
161
|
-
|
162
|
-
|
145
|
+
```ts
|
146
|
+
context.storage
|
147
|
+
```
|
163
148
|
|
164
149
|
- **context.createStorage(namespace)**
|
165
150
|
|
166
|
-
|
151
|
+
At the same time you can also create multiple `storage` instances
|
167
152
|
|
168
|
-
|
153
|
+
Returns: `Storage<State>`
|
169
154
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
155
|
+
```ts
|
156
|
+
type State = { count: number };
|
157
|
+
const defaultState = { count: 0 };
|
158
|
+
const storage = context.createStorage<State>("store1", defaultState);
|
159
|
+
```
|
175
160
|
|
176
161
|
- **storage.state**
|
177
162
|
|
178
|
-
|
179
|
-
|
163
|
+
Type: `State`\
|
164
|
+
Default: `defaultState`
|
180
165
|
|
181
|
-
|
166
|
+
State synchronized between all clients, call `storage.setState()` to change it.
|
182
167
|
|
183
168
|
- **storage.ensureState(partialState)**
|
184
169
|
|
185
|
-
|
170
|
+
Make sure `storage.state` contains some initial values, something like doing:
|
186
171
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
172
|
+
```js
|
173
|
+
// This code cannot be run directly because app.state is read-only
|
174
|
+
storage.state = { ...partialState, ...storage.state };
|
175
|
+
```
|
191
176
|
|
192
|
-
|
177
|
+
**partialState**
|
193
178
|
|
194
|
-
|
179
|
+
Type: `Partial<State>`
|
195
180
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
181
|
+
```js
|
182
|
+
storage.state; // { a: 1 }
|
183
|
+
storage.ensureState({ a: 0, b: 0 });
|
184
|
+
storage.state; // { a: 1, b: 0 }
|
185
|
+
```
|
201
186
|
|
202
187
|
- **storage.setState(partialState)**
|
203
188
|
|
204
|
-
|
189
|
+
Similar to React's `setState`, update `storage.state` and sync to all clients.
|
205
190
|
|
206
|
-
|
191
|
+
When setting a field to `undefined`, it will be removed from `storage.state`.
|
207
192
|
|
208
|
-
|
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.
|
209
194
|
|
210
|
-
|
195
|
+
**partialState**
|
211
196
|
|
212
|
-
|
197
|
+
Type: `Partial<State>`
|
213
198
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
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
|
+
```
|
219
204
|
|
220
205
|
- **storage.addStateChangedListener(listener)**
|
221
206
|
|
222
|
-
|
207
|
+
It fires after someone calls `storage.setState()` (including the current `storage`)
|
223
208
|
|
224
|
-
|
209
|
+
return: `() => void`
|
225
210
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
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
|
+
```
|
232
217
|
|
233
218
|
- **context.dispatchMagixEvent(event, payload)**
|
234
219
|
|
235
|
-
|
220
|
+
Broadcast event messages to other clients
|
236
221
|
|
237
|
-
|
238
|
-
|
239
|
-
|
222
|
+
```js
|
223
|
+
context.dispatchMagixEvent("click", { data: "data" });
|
224
|
+
```
|
240
225
|
|
241
226
|
- **context.addMagixEventListener(event, listener)**
|
242
227
|
|
243
|
-
|
228
|
+
It is triggered when receiving messages from other clients (when other clients call `context.dispatchMagixEvent()`)
|
229
|
+
|
230
|
+
Returns: `() => void` a disposer function.
|
231
|
+
|
232
|
+
```js
|
233
|
+
const disposer = context.addMagixEventListener("click", ({ payload }) => {
|
234
|
+
console.log(payload.data);
|
235
|
+
disposer();
|
236
|
+
});
|
237
|
+
|
238
|
+
context.dispatchMagixEvent("click", { data: "data" });
|
239
|
+
```
|
240
|
+
|
241
|
+
<h2>UI (box)</h2>
|
242
|
+
|
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
|
+
|
246
|
+
- **context.getBox()**
|
244
247
|
|
245
|
-
|
248
|
+
get box
|
249
|
+
Return type: `ReadonlyTeleBox`
|
246
250
|
|
247
|
-
|
248
|
-
const disposer = context.addMagixEventListener("click", ({ payload }) => {
|
249
|
-
console.log(payload.data);
|
250
|
-
disposer();
|
251
|
-
});
|
251
|
+
- **box.mountStyles()**
|
252
252
|
|
253
|
-
|
254
|
-
|
253
|
+
Mount styles to `box`
|
254
|
+
Parameters: `string | HTMLStyleElement`
|
255
|
+
|
256
|
+
```js
|
257
|
+
const box = context. getBox();
|
258
|
+
box. mountStyles(`
|
259
|
+
.app-span {
|
260
|
+
color: red;
|
261
|
+
}
|
262
|
+
`)
|
263
|
+
```
|
264
|
+
|
265
|
+
- **box.mountContent()**
|
266
|
+
|
267
|
+
Mount element to `box`
|
268
|
+
Parameters: `HTMLElement`
|
269
|
+
|
270
|
+
```js
|
271
|
+
const box = context. getBox();
|
272
|
+
const content = document. createElement("div");
|
273
|
+
box. mountContent(context);
|
274
|
+
```
|
275
|
+
|
276
|
+
- **box.mountFooter()**
|
277
|
+
|
278
|
+
Mount element to `footer` of `box`
|
279
|
+
Parameters: `HTMLElement`
|
280
|
+
|
281
|
+
```js
|
282
|
+
const box = context. getBox();
|
283
|
+
const footer = document. createElement("div");
|
284
|
+
box. mountFooter(context);
|
285
|
+
```
|
255
286
|
|
256
287
|
<h2 id="events">events</h2>
|
257
288
|
|
258
289
|
- **destroy**
|
259
290
|
|
260
|
-
|
291
|
+
Sent when the app is closed
|
261
292
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
293
|
+
```ts
|
294
|
+
context.emitter.on("destroy", () => {
|
295
|
+
// release your listeners
|
296
|
+
});
|
297
|
+
```
|
267
298
|
|
268
299
|
- **writableChange**
|
269
300
|
|
270
|
-
|
301
|
+
Triggered when the whiteboard's writable state is switched
|
271
302
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
303
|
+
```ts
|
304
|
+
context.emitter.on("writableChange", isWritable => {
|
305
|
+
//
|
306
|
+
});
|
307
|
+
```
|
277
308
|
|
278
309
|
- **focus**
|
279
310
|
|
280
|
-
|
281
|
-
|
282
|
-
```ts
|
283
|
-
context.emitter.on("focus", focus => {
|
284
|
-
//
|
285
|
-
});
|
286
|
-
```
|
311
|
+
Triggered when the current app gains or loses focus
|
287
312
|
|
288
|
-
|
313
|
+
```ts
|
314
|
+
context.emitter.on("focus", focus => {
|
315
|
+
//
|
316
|
+
});
|
317
|
+
```
|
289
318
|
|
290
|
-
- **
|
319
|
+
- **pageStateChange**
|
291
320
|
|
292
|
-
|
321
|
+
`PageState`
|
293
322
|
|
294
|
-
|
295
|
-
|
296
|
-
|
323
|
+
```ts
|
324
|
+
type PateState {
|
325
|
+
index: number;
|
326
|
+
length: number;
|
327
|
+
}
|
328
|
+
```
|
297
329
|
|
298
|
-
|
330
|
+
Triggered when the current page number and the total page number change
|
299
331
|
|
300
|
-
|
332
|
+
```ts
|
333
|
+
context.emitter.on("pageStateChange", pageState => {
|
334
|
+
// { index: 0, length: 1 }
|
335
|
+
});
|
336
|
+
```
|
337
|
+
- **roomStageChange**
|
301
338
|
|
302
|
-
|
339
|
+
Triggered when the state of the room changes\
|
340
|
+
For example, when teaching aids are switched
|
303
341
|
|
304
|
-
|
342
|
+
```js
|
343
|
+
context.emitter.on("roomStageChange", stage => {
|
344
|
+
if (state. memberState) {
|
345
|
+
console.log("appliance change to", state.memberState.currentApplianceName);
|
346
|
+
}
|
347
|
+
});
|
348
|
+
```
|
305
349
|
|
306
|
-
|
307
|
-
在这个区域中的内容, `WindowManager` 会确保所有的端都可以看到
|
350
|
+
or when the number of people in the current room changes
|
308
351
|
|
309
|
-
|
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
|
310
360
|
|
311
|
-
|
312
|
-
interface TeleboxRect {
|
313
|
-
readonly x: number;
|
314
|
-
readonly y: number;
|
315
|
-
readonly width: number;
|
316
|
-
readonly height: number;
|
317
|
-
}
|
318
|
-
```
|
361
|
+
<h2 id="Advanced">Advanced</h2>
|
319
362
|
|
320
|
-
|
321
|
-
box.contentStageRect
|
322
|
-
```
|
363
|
+
- **context.getView()**
|
323
364
|
|
324
|
-
|
365
|
+
Get `view` instance
|
325
366
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
});
|
330
|
-
```
|
367
|
+
```ts
|
368
|
+
const view = context.getView();
|
369
|
+
```
|
package/docs/basic.md
CHANGED
@@ -1,64 +1,63 @@
|
|
1
|
-
#
|
2
|
-
`WindowManager`
|
1
|
+
# Basic Tutorial
|
2
|
+
`WindowManager` has built-in `DocsViewer` and `MediaPlayer` to play PPT and audio and video
|
3
3
|
|
4
|
-
##
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
##
|
34
|
+
## Query all apps
|
35
35
|
```typescript
|
36
36
|
const apps = manager.queryAll();
|
37
37
|
```
|
38
38
|
|
39
|
-
##
|
39
|
+
## Query a single APP
|
40
40
|
```typescript
|
41
41
|
const app = manager.queryOne(appId);
|
42
|
-
```
|
42
|
+
```
|
43
43
|
|
44
|
-
##
|
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
|
-
|
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
|
-
|
61
|
+
// state: number | undefined
|
62
62
|
});
|
63
63
|
```
|
64
|
-
|