@netless/window-manager 0.4.31 → 0.4.34
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 +14 -0
- package/dist/Cursor/index.d.ts +3 -1
- package/dist/Helper.d.ts +2 -0
- package/dist/index.cjs.js +12 -12
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.es.js +54 -26
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +12 -12
- package/dist/index.umd.js.map +1 -1
- package/dist/typings.d.ts +2 -1
- package/docs/api.md +1 -1
- package/docs/app-context.md +127 -36
- package/docs/develop-app.md +1 -1
- package/package.json +1 -1
- package/src/App/AppProxy.ts +4 -0
- package/src/AppManager.ts +1 -0
- package/src/Cursor/Cursor.ts +3 -3
- package/src/Cursor/index.ts +8 -2
- package/src/Helper.ts +17 -1
- package/src/ReconnectRefresher.ts +9 -3
- package/src/index.ts +24 -35
- package/src/typings.ts +3 -0
package/dist/typings.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import type Emittery from "emittery";
|
2
|
-
import type { AnimationMode, Displayer, DisplayerState, Player, Room, SceneDefinition, SceneState, View } from "white-web-sdk";
|
2
|
+
import type { AnimationMode, ApplianceNames, Displayer, DisplayerState, Player, Room, SceneDefinition, SceneState, View } from "white-web-sdk";
|
3
3
|
import type { AppContext } from "./App";
|
4
4
|
import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
|
5
5
|
import type { PageState } from "./Page";
|
@@ -69,6 +69,7 @@ export declare type RegisterParams<AppOptions = any, SetupResult = any, Attribut
|
|
69
69
|
name?: string;
|
70
70
|
};
|
71
71
|
export declare type AppListenerKeys = keyof AppEmitterEvent;
|
72
|
+
export declare type ApplianceIcons = Partial<Record<ApplianceNames, string>>;
|
72
73
|
export type { AppContext } from "./App/AppContext";
|
73
74
|
export type { ReadonlyTeleBox, TeleBoxRect };
|
74
75
|
export type { SceneState, SceneDefinition, View, AnimationMode, Displayer, Room, Player };
|
package/docs/api.md
CHANGED
@@ -64,7 +64,7 @@ const manager = await WindowManager.mount(
|
|
64
64
|
| disableCameraTransform | [optional] boolean | | 禁用主白板的相机移动 |
|
65
65
|
| prefersColorScheme | [optional] string | light | auto, light, dark |
|
66
66
|
| debug | [optional] boolean | false | 打印日志信息
|
67
|
-
|
67
|
+
| applianceIcons | [optional] {ApplianceNames, string} | | 配置光标使用的教具图片 |
|
68
68
|
|
69
69
|
<h3 id="register">WindowManager.register</h3>
|
70
70
|
|
package/docs/app-context.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
## AppContext
|
2
2
|
|
3
|
-
-
|
3
|
+
- [api](#api)
|
4
4
|
- [view](#view)
|
5
5
|
- [page](#page)
|
6
6
|
- [storage](#storage)
|
7
|
-
-
|
7
|
+
- [events](#events)
|
8
|
+
- [Advanced](#Advanced)
|
8
9
|
|
9
10
|
<h2 id="api">API</h2>
|
10
11
|
|
@@ -16,6 +17,12 @@
|
|
16
17
|
const appId = context.appId;
|
17
18
|
```
|
18
19
|
|
20
|
+
- **context.isReplay**
|
21
|
+
|
22
|
+
类型: `boolean`
|
23
|
+
|
24
|
+
当前是否回放模式
|
25
|
+
|
19
26
|
- **context.getDisplayer()**
|
20
27
|
|
21
28
|
在默认情况下 `Displayer` 为白板的 `room` 实例
|
@@ -32,10 +39,10 @@
|
|
32
39
|
|
33
40
|
- **context.getIsWritable()**
|
34
41
|
|
35
|
-
|
42
|
+
获取当前状态是否可写\
|
43
|
+
可以通过监听 `writableChange` 事件获取可写状态的改变
|
36
44
|
|
37
45
|
```ts
|
38
|
-
// isWritable === (room.isWritable && box.readonly)
|
39
46
|
const isWritable = context.getIsWritable();
|
40
47
|
```
|
41
48
|
|
@@ -50,46 +57,31 @@
|
|
50
57
|
box.$footer;
|
51
58
|
```
|
52
59
|
|
53
|
-
<h3 id="view"
|
54
|
-
|
55
|
-
`view` 可以理解为一块白板,可以从 `context` 中拿到这个实例并挂载到 `Dom` 中
|
56
|
-
|
57
|
-
- **context.getView()**
|
60
|
+
<h3 id="view">挂载白板</h3>
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
```ts
|
62
|
-
const view = context.getView();
|
63
|
-
```
|
62
|
+
当应用想要一个可以涂画的白板,可以使用以下接口
|
64
63
|
|
65
64
|
- **context.mountView()**
|
66
65
|
|
67
|
-
|
66
|
+
挂载白板到指定 dom
|
68
67
|
|
69
68
|
```ts
|
70
69
|
context.mountView(element);
|
71
70
|
```
|
72
71
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
切换当前 `view` 到指定的 `scenePath`
|
84
|
-
|
85
|
-
```ts
|
86
|
-
context.setScenePath("/page/2");
|
87
|
-
```
|
88
|
-
|
72
|
+
**注意** 在调用 `manager` 的 `addApp` 时必须填写 `scenePath` 才可以使用 `view`
|
73
|
+
```ts
|
74
|
+
manager.addApp({
|
75
|
+
kind: "xxx",
|
76
|
+
options: { // 可选配置
|
77
|
+
scenePath: "/example-path"
|
78
|
+
}
|
79
|
+
})
|
80
|
+
```
|
89
81
|
|
90
82
|
<h3 id="page">Page</h3>
|
91
83
|
|
92
|
-
|
84
|
+
白板有多页的概念, 可以通过以下接口添加,切换,以及删除
|
93
85
|
|
94
86
|
- **context.addPage()**
|
95
87
|
|
@@ -116,10 +108,19 @@
|
|
116
108
|
```ts
|
117
109
|
context.prevPage();
|
118
110
|
```
|
111
|
+
- **context.removePage()**
|
112
|
+
|
113
|
+
删除一页
|
114
|
+
|
115
|
+
```ts
|
116
|
+
context.removePage() // 默认删除当前页
|
117
|
+
context.removePage(1) // 也可以指定 index 删除
|
118
|
+
```
|
119
119
|
|
120
120
|
- **context.pageState**
|
121
121
|
|
122
|
-
获取当前所在的 `index`
|
122
|
+
获取当前所在的 `index` 和一共有多少页\
|
123
|
+
当想要监听 `pageState` 的变化时, 可以监听 `pageStateChange` 事件获取最新的 `pageState`
|
123
124
|
|
124
125
|
```ts
|
125
126
|
context.pageState;
|
@@ -141,17 +142,97 @@
|
|
141
142
|
context.storage
|
142
143
|
```
|
143
144
|
|
144
|
-
- **createStorage()**
|
145
|
+
- **context.createStorage(namespace)**
|
145
146
|
|
146
147
|
同时你也可以创建多个 `storage` 实例
|
148
|
+
|
149
|
+
返回: `Storage<State>`
|
147
150
|
|
148
151
|
```ts
|
149
|
-
|
150
|
-
const
|
152
|
+
type State = { count: number };
|
153
|
+
const defaultState = { count: 0 };
|
154
|
+
const storage = context.createStorage<State>("store1", defaultState);
|
151
155
|
```
|
152
156
|
|
157
|
+
- **storage.state**
|
158
|
+
|
159
|
+
类型: `State`\
|
160
|
+
默认值: `defaultState`
|
161
|
+
|
162
|
+
在所有客户端之间同步的状态,调用 `storage.setState()` 来改变它。
|
163
|
+
|
164
|
+
- **storage.ensureState(partialState)**
|
165
|
+
|
166
|
+
确保 `storage.state` 包含某些初始值,类似于执行了:
|
167
|
+
|
168
|
+
```js
|
169
|
+
// 这段代码不能直接运行,因为 app.state 是只读的
|
170
|
+
storage.state = { ...partialState, ...storage.state };
|
171
|
+
```
|
153
172
|
|
173
|
+
**partialState**
|
154
174
|
|
175
|
+
类型: `Partial<State>`
|
176
|
+
|
177
|
+
```js
|
178
|
+
storage.state; // { a: 1 }
|
179
|
+
storage.ensureState({ a: 0, b: 0 });
|
180
|
+
storage.state; // { a: 1, b: 0 }
|
181
|
+
```
|
182
|
+
|
183
|
+
- **storage.setState(partialState)**
|
184
|
+
|
185
|
+
和 React 的 `setState` 类似,更新 `storage.state` 并同步到所有客户端。
|
186
|
+
|
187
|
+
当设置某个字段为 `undefined` 时,它会被从 `storage.state` 里删除。
|
188
|
+
|
189
|
+
> - 状态同步所需的时间和网络状态与数据大小有关,建议只在 state 里存储必须的数据。
|
190
|
+
|
191
|
+
**partialState**
|
192
|
+
|
193
|
+
类型: `Partial<State>`
|
194
|
+
|
195
|
+
```js
|
196
|
+
storage.state; //=> { count: 0, a: 1 }
|
197
|
+
storage.setState({ count: storage.state.count + 1, b: 2 });
|
198
|
+
storage.state; //=> { count: 1, a: 1, b: 2 }
|
199
|
+
```
|
200
|
+
|
201
|
+
- **storage.addStateChangedListener(listener)**
|
202
|
+
|
203
|
+
它在有人调用 `storage.setState()` 后触发 (包含当前 `storage`)
|
204
|
+
|
205
|
+
返回: `() => void`
|
206
|
+
|
207
|
+
```js
|
208
|
+
const disposer = storage.addStateChangedListener(diff => {
|
209
|
+
console.log("state changed", diff.oldValue, diff.newValue);
|
210
|
+
disposer(); // remove listener by calling disposer
|
211
|
+
});
|
212
|
+
```
|
213
|
+
|
214
|
+
- **context.dispatchMagixEvent(event, payload)**
|
215
|
+
|
216
|
+
向其他客户端广播事件消息
|
217
|
+
|
218
|
+
```js
|
219
|
+
context.dispatchMagixEvent("click", { data: "data" });
|
220
|
+
```
|
221
|
+
|
222
|
+
- **context.addMagixEventListener(event, listener)**
|
223
|
+
|
224
|
+
当接收来自其他客户端的消息时(当其他客户端调用'context.dispatchMagixEvent()`时), 它会被触发
|
225
|
+
|
226
|
+
返回: `() => void` a disposer function.
|
227
|
+
|
228
|
+
```js
|
229
|
+
const disposer = context.addMagixEventListener("click", ({ payload }) => {
|
230
|
+
console.log(payload.data);
|
231
|
+
disposer();
|
232
|
+
});
|
233
|
+
|
234
|
+
context.dispatchMagixEvent("click", { data: "data" });
|
235
|
+
```
|
155
236
|
|
156
237
|
<h2 id="events">events</h2>
|
157
238
|
|
@@ -203,3 +284,13 @@
|
|
203
284
|
// { index: 0, length: 1 }
|
204
285
|
});
|
205
286
|
```
|
287
|
+
|
288
|
+
<h2 id="Advanced">Advanced</h2>
|
289
|
+
|
290
|
+
- **context.getView()**
|
291
|
+
|
292
|
+
获取 `view` 实例
|
293
|
+
|
294
|
+
```ts
|
295
|
+
const view = context.getView();
|
296
|
+
```
|
package/docs/develop-app.md
CHANGED
@@ -49,7 +49,7 @@ const Counter: NetlessApp<{ count: number }> = {
|
|
49
49
|
countDom.innerText = storage.state.count.toString();
|
50
50
|
$content.appendChild(countDom);
|
51
51
|
|
52
|
-
// state 变化回调
|
52
|
+
// 监听 state 变化回调
|
53
53
|
storage.addStateChangedListener(diff => {
|
54
54
|
if (diff.count) {
|
55
55
|
// diff 会给出 newValue 和 oldValue
|
package/package.json
CHANGED
package/src/App/AppProxy.ts
CHANGED
@@ -204,6 +204,10 @@ export class AppProxy implements PageRemoveService {
|
|
204
204
|
});
|
205
205
|
if (this.isAddApp && this.box) {
|
206
206
|
this.store.updateAppState(appId, AppAttributes.ZIndex, this.box.zIndex);
|
207
|
+
this.store.updateAppState(appId, AppAttributes.Size, {
|
208
|
+
width: this.box.intrinsicWidth,
|
209
|
+
height: this.box.intrinsicHeight
|
210
|
+
});
|
207
211
|
this.boxManager.focusBox({ appId }, false);
|
208
212
|
}
|
209
213
|
} catch (error: any) {
|
package/src/AppManager.ts
CHANGED
@@ -785,6 +785,7 @@ export class AppManager {
|
|
785
785
|
}
|
786
786
|
|
787
787
|
public async onReconnected() {
|
788
|
+
this.attributesUpdateCallback(this.attributes.apps);
|
788
789
|
const appProxies = Array.from(this.appProxies.values());
|
789
790
|
const reconnected = appProxies.map(appProxy => {
|
790
791
|
return appProxy.onReconnected();
|
package/src/Cursor/Cursor.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import App from "./Cursor.svelte";
|
2
|
-
import { ApplianceMap } from "./icons";
|
3
2
|
import { ApplianceNames } from "white-web-sdk";
|
4
3
|
import { findMemberByUid } from "../Helper";
|
5
4
|
import { omit } from "lodash";
|
@@ -159,8 +158,9 @@ export class Cursor {
|
|
159
158
|
|
160
159
|
private getIcon() {
|
161
160
|
if (this.member) {
|
162
|
-
const
|
163
|
-
|
161
|
+
const icons = this.cursorManager.applianceIcons;
|
162
|
+
const applianceSrc = icons[this.memberApplianceName || ApplianceNames.shape];
|
163
|
+
return applianceSrc || icons[ApplianceNames.shape];
|
164
164
|
}
|
165
165
|
}
|
166
166
|
|
package/src/Cursor/index.ts
CHANGED
@@ -5,10 +5,11 @@ import { emitter } from "../InternalEmitter";
|
|
5
5
|
import { SideEffectManager } from "side-effect-manager";
|
6
6
|
import { throttle } from "lodash";
|
7
7
|
import { WindowManager } from "../index";
|
8
|
-
import type { CursorMovePayload } from "../index";
|
8
|
+
import type { CursorMovePayload , ApplianceIcons} from "../index";
|
9
9
|
import type { PositionType } from "../AttributesDelegate";
|
10
10
|
import type { Point, RoomMember, View } from "white-web-sdk";
|
11
11
|
import type { AppManager } from "../AppManager";
|
12
|
+
import { ApplianceMap } from "./icons";
|
12
13
|
|
13
14
|
export type EventType = {
|
14
15
|
type: PositionType;
|
@@ -20,6 +21,7 @@ export type MoveCursorParams = {
|
|
20
21
|
x: number;
|
21
22
|
y: number;
|
22
23
|
};
|
24
|
+
|
23
25
|
export class CursorManager {
|
24
26
|
public containerRect?: DOMRect;
|
25
27
|
public wrapperRect?: DOMRect;
|
@@ -28,8 +30,9 @@ export class CursorManager {
|
|
28
30
|
private mainViewElement?: HTMLDivElement;
|
29
31
|
private sideEffectManager = new SideEffectManager();
|
30
32
|
private store = this.manager.store;
|
33
|
+
public applianceIcons: ApplianceIcons = ApplianceMap;
|
31
34
|
|
32
|
-
constructor(private manager: AppManager, private enableCursor: boolean) {
|
35
|
+
constructor(private manager: AppManager, private enableCursor: boolean, applianceIcons?: ApplianceIcons) {
|
33
36
|
this.roomMembers = this.manager.room?.state.roomMembers;
|
34
37
|
const wrapper = WindowManager.wrapper;
|
35
38
|
if (wrapper) {
|
@@ -42,6 +45,9 @@ export class CursorManager {
|
|
42
45
|
this.sideEffectManager.add(() => {
|
43
46
|
return emitter.on("playgroundSizeChange", () => this.updateContainerRect());
|
44
47
|
});
|
48
|
+
if (applianceIcons) {
|
49
|
+
this.applianceIcons = { ...ApplianceMap, ...applianceIcons };
|
50
|
+
}
|
45
51
|
}
|
46
52
|
|
47
53
|
private onCursorMove = (payload: CursorMovePayload) => {
|
package/src/Helper.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
import { getVersionNumber } from "./Utils/Common";
|
1
|
+
import { getVersionNumber, wait } from "./Utils/Common";
|
2
|
+
import { log } from "./Utils/log";
|
2
3
|
import { REQUIRE_VERSION } from "./constants";
|
3
4
|
import { WhiteVersion } from "white-web-sdk";
|
4
5
|
import { WhiteWebSDKInvalidError } from "./Utils/error";
|
@@ -45,3 +46,18 @@ export const findMemberByUid = (room: Room | undefined, uid: string) => {
|
|
45
46
|
const roomMembers = room?.state.roomMembers;
|
46
47
|
return roomMembers?.find(member => member.payload?.uid === uid);
|
47
48
|
};
|
49
|
+
|
50
|
+
export const createInvisiblePlugin = async (room: Room) => {
|
51
|
+
try {
|
52
|
+
const manager = (await room.createInvisiblePlugin(WindowManager, {})) as WindowManager;
|
53
|
+
return manager;
|
54
|
+
} catch (error) {
|
55
|
+
// 如果有两个用户同时调用 WindowManager.mount 有概率出现这个错误
|
56
|
+
if (error.message === `invisible plugin "WindowManager" exits`) {
|
57
|
+
await wait(200);
|
58
|
+
return room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
|
59
|
+
} else {
|
60
|
+
log("createInvisiblePlugin failed", error);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
};
|
@@ -4,6 +4,7 @@ import { RoomPhase } from "white-web-sdk";
|
|
4
4
|
import type { Room } from "white-web-sdk";
|
5
5
|
import type { EmitterType } from "./InternalEmitter";
|
6
6
|
import { EnsureReconnectEvent } from "./constants";
|
7
|
+
import { wait } from "./Utils/Common";
|
7
8
|
|
8
9
|
export type ReconnectRefresherContext = {
|
9
10
|
emitter: EmitterType;
|
@@ -41,19 +42,24 @@ export class ReconnectRefresher {
|
|
41
42
|
this.ctx = ctx;
|
42
43
|
}
|
43
44
|
|
44
|
-
private onPhaseChanged = (phase: RoomPhase) => {
|
45
|
+
private onPhaseChanged = async (phase: RoomPhase) => {
|
45
46
|
if (phase === RoomPhase.Reconnecting) {
|
46
47
|
this.ctx.emitter.emit("startReconnect");
|
47
48
|
}
|
48
49
|
if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
|
49
|
-
this.room?.
|
50
|
+
if (this.room?.isWritable) {
|
51
|
+
this.room?.dispatchMagixEvent(EnsureReconnectEvent, {});
|
52
|
+
} else {
|
53
|
+
await wait(500);
|
54
|
+
this.onReconnected();
|
55
|
+
}
|
50
56
|
}
|
51
57
|
this.phase = phase;
|
52
58
|
};
|
53
59
|
|
54
60
|
private onReconnected = debounce(() => {
|
55
61
|
this._onReconnected();
|
56
|
-
},
|
62
|
+
}, 1000);
|
57
63
|
|
58
64
|
private _onReconnected = () => {
|
59
65
|
log("onReconnected refresh reactors");
|
package/src/index.ts
CHANGED
@@ -2,7 +2,7 @@ import pRetry from "p-retry";
|
|
2
2
|
import { AppManager } from "./AppManager";
|
3
3
|
import { appRegister } from "./Register";
|
4
4
|
import { callbacks } from "./callback";
|
5
|
-
import { checkVersion, setupWrapper } from "./Helper";
|
5
|
+
import { checkVersion, createInvisiblePlugin, setupWrapper } from "./Helper";
|
6
6
|
import { ContainerResizeObserver } from "./ContainerResizeObserver";
|
7
7
|
import { createBoxManager } from "./BoxManager";
|
8
8
|
import { CursorManager } from "./Cursor";
|
@@ -29,13 +29,7 @@ import {
|
|
29
29
|
wait,
|
30
30
|
} from "./Utils/Common";
|
31
31
|
import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
|
32
|
-
import
|
33
|
-
AppCreateError,
|
34
|
-
AppManagerNotInitError,
|
35
|
-
BindContainerRoomPhaseInvalidError,
|
36
|
-
InvalidScenePath,
|
37
|
-
ParamsInvalidError,
|
38
|
-
} from "./Utils/error";
|
32
|
+
import * as Errors from "./Utils/error";
|
39
33
|
import type { Apps, Position } from "./AttributesDelegate";
|
40
34
|
import type {
|
41
35
|
Displayer,
|
@@ -54,7 +48,7 @@ import type {
|
|
54
48
|
SceneState,
|
55
49
|
} from "white-web-sdk";
|
56
50
|
import type { AppListeners } from "./AppListener";
|
57
|
-
import type { NetlessApp, RegisterParams } from "./typings";
|
51
|
+
import type { ApplianceIcons, NetlessApp, RegisterParams } from "./typings";
|
58
52
|
import type { TeleBoxColorScheme, TeleBoxState } from "@netless/telebox-insider";
|
59
53
|
import type { AppProxy } from "./App";
|
60
54
|
import type { PublicEvent } from "./callback";
|
@@ -143,6 +137,7 @@ export type MountParams = {
|
|
143
137
|
debug?: boolean;
|
144
138
|
disableCameraTransform?: boolean;
|
145
139
|
prefersColorScheme?: TeleBoxColorScheme;
|
140
|
+
applianceIcons?: ApplianceIcons;
|
146
141
|
};
|
147
142
|
|
148
143
|
export const reconnectRefresher = new ReconnectRefresher({ emitter });
|
@@ -238,7 +233,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
238
233
|
|
239
234
|
manager.appManager = new AppManager(manager);
|
240
235
|
manager._pageState = new PageStateImpl(manager.appManager);
|
241
|
-
manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor));
|
236
|
+
manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor), params.applianceIcons);
|
242
237
|
if (containerSizeRatio) {
|
243
238
|
manager.containerSizeRatio = containerSizeRatio;
|
244
239
|
}
|
@@ -259,8 +254,8 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
259
254
|
return manager;
|
260
255
|
}
|
261
256
|
|
262
|
-
private static async initManager(room: Room): Promise<WindowManager> {
|
263
|
-
let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager;
|
257
|
+
private static async initManager(room: Room): Promise<WindowManager | undefined> {
|
258
|
+
let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager | undefined;
|
264
259
|
if (!manager) {
|
265
260
|
if (isRoom(room)) {
|
266
261
|
if (room.isWritable === false) {
|
@@ -269,18 +264,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
269
264
|
} catch (error) {
|
270
265
|
throw new Error("[WindowManger]: room must be switched to be writable");
|
271
266
|
}
|
272
|
-
manager =
|
273
|
-
|
274
|
-
{}
|
275
|
-
)) as WindowManager;
|
276
|
-
manager.ensureAttributes();
|
267
|
+
manager = await createInvisiblePlugin(room);
|
268
|
+
manager?.ensureAttributes();
|
277
269
|
await wait(500);
|
278
270
|
await room.setWritable(false);
|
279
271
|
} else {
|
280
|
-
manager =
|
281
|
-
WindowManager,
|
282
|
-
{}
|
283
|
-
)) as WindowManager;
|
272
|
+
manager = await createInvisiblePlugin(room);
|
284
273
|
}
|
285
274
|
}
|
286
275
|
}
|
@@ -322,7 +311,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
322
311
|
|
323
312
|
public bindContainer(container: HTMLElement) {
|
324
313
|
if (isRoom(this.displayer) && this.room.phase !== RoomPhase.Connected) {
|
325
|
-
throw new BindContainerRoomPhaseInvalidError();
|
314
|
+
throw new Errors.BindContainerRoomPhaseInvalidError();
|
326
315
|
}
|
327
316
|
if (WindowManager.isCreated && WindowManager.container) {
|
328
317
|
if (WindowManager.container.firstChild) {
|
@@ -408,19 +397,19 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
408
397
|
return this._addApp(params);
|
409
398
|
}
|
410
399
|
} else {
|
411
|
-
throw new AppManagerNotInitError();
|
400
|
+
throw new Errors.AppManagerNotInitError();
|
412
401
|
}
|
413
402
|
}
|
414
403
|
|
415
404
|
private async _addApp<T = any>(params: AddAppParams<T>): Promise<string | undefined> {
|
416
405
|
if (this.appManager) {
|
417
406
|
if (!params.kind || typeof params.kind !== "string") {
|
418
|
-
throw new ParamsInvalidError();
|
407
|
+
throw new Errors.ParamsInvalidError();
|
419
408
|
}
|
420
409
|
const appImpl = await appRegister.appClasses.get(params.kind)?.();
|
421
410
|
if (appImpl && appImpl.config?.singleton) {
|
422
411
|
if (this.appManager.appProxies.has(params.kind)) {
|
423
|
-
throw new AppCreateError();
|
412
|
+
throw new Errors.AppCreateError();
|
424
413
|
}
|
425
414
|
}
|
426
415
|
const isDynamicPPT = this.setupScenePath(params, this.appManager);
|
@@ -433,7 +422,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
433
422
|
const appId = await this.appManager.addApp(params, Boolean(isDynamicPPT));
|
434
423
|
return appId;
|
435
424
|
} else {
|
436
|
-
throw new AppManagerNotInitError();
|
425
|
+
throw new Errors.AppManagerNotInitError();
|
437
426
|
}
|
438
427
|
}
|
439
428
|
|
@@ -443,7 +432,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
443
432
|
const { scenePath, scenes } = params.options;
|
444
433
|
if (scenePath) {
|
445
434
|
if (!isValidScenePath(scenePath)) {
|
446
|
-
throw new InvalidScenePath();
|
435
|
+
throw new Errors.InvalidScenePath();
|
447
436
|
}
|
448
437
|
const apps = Object.keys(this.apps || {});
|
449
438
|
for (const appId of apps) {
|
@@ -646,7 +635,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
646
635
|
if (this.appManager) {
|
647
636
|
return this.appManager.mainViewProxy.view;
|
648
637
|
} else {
|
649
|
-
throw new AppManagerNotInitError();
|
638
|
+
throw new Errors.AppManagerNotInitError();
|
650
639
|
}
|
651
640
|
}
|
652
641
|
|
@@ -654,7 +643,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
654
643
|
if (this.appManager) {
|
655
644
|
return this.appManager.mainViewProxy.view.camera;
|
656
645
|
} else {
|
657
|
-
throw new AppManagerNotInitError();
|
646
|
+
throw new Errors.AppManagerNotInitError();
|
658
647
|
}
|
659
648
|
}
|
660
649
|
|
@@ -662,7 +651,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
662
651
|
if (this.appManager) {
|
663
652
|
return this.appManager.mainViewProxy.cameraState;
|
664
653
|
} else {
|
665
|
-
throw new AppManagerNotInitError();
|
654
|
+
throw new Errors.AppManagerNotInitError();
|
666
655
|
}
|
667
656
|
}
|
668
657
|
|
@@ -674,7 +663,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
674
663
|
if (this.appManager) {
|
675
664
|
return this.appManager.boxManager?.boxState;
|
676
665
|
} else {
|
677
|
-
throw new AppManagerNotInitError();
|
666
|
+
throw new Errors.AppManagerNotInitError();
|
678
667
|
}
|
679
668
|
}
|
680
669
|
|
@@ -686,7 +675,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
686
675
|
if (this.appManager) {
|
687
676
|
return this.appManager.boxManager?.prefersColorScheme;
|
688
677
|
} else {
|
689
|
-
throw new AppManagerNotInitError();
|
678
|
+
throw new Errors.AppManagerNotInitError();
|
690
679
|
}
|
691
680
|
}
|
692
681
|
|
@@ -706,7 +695,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
706
695
|
if (this.appManager) {
|
707
696
|
return this.appManager?.getMainViewSceneDir();
|
708
697
|
} else {
|
709
|
-
throw new AppManagerNotInitError();
|
698
|
+
throw new Errors.AppManagerNotInitError();
|
710
699
|
}
|
711
700
|
}
|
712
701
|
|
@@ -731,7 +720,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
731
720
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
732
721
|
return this.appManager.sceneState!;
|
733
722
|
} else {
|
734
|
-
throw new AppManagerNotInitError();
|
723
|
+
throw new Errors.AppManagerNotInitError();
|
735
724
|
}
|
736
725
|
}
|
737
726
|
|
@@ -739,7 +728,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
739
728
|
if (this._pageState) {
|
740
729
|
return this._pageState.toObject();
|
741
730
|
} else {
|
742
|
-
throw new AppManagerNotInitError();
|
731
|
+
throw new Errors.AppManagerNotInitError();
|
743
732
|
}
|
744
733
|
}
|
745
734
|
|
package/src/typings.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import type Emittery from "emittery";
|
2
2
|
import type {
|
3
3
|
AnimationMode,
|
4
|
+
ApplianceNames,
|
4
5
|
Displayer,
|
5
6
|
DisplayerState,
|
6
7
|
Player,
|
@@ -75,6 +76,8 @@ export type RegisterParams<AppOptions = any, SetupResult = any, Attributes = any
|
|
75
76
|
|
76
77
|
export type AppListenerKeys = keyof AppEmitterEvent;
|
77
78
|
|
79
|
+
export type ApplianceIcons = Partial<Record<ApplianceNames, string>>;
|
80
|
+
|
78
81
|
export type { AppContext } from "./App/AppContext";
|
79
82
|
export type { ReadonlyTeleBox, TeleBoxRect };
|
80
83
|
export type { SceneState, SceneDefinition, View, AnimationMode, Displayer, Room, Player };
|