@netless/window-manager 0.3.17-canary.2 → 0.4.0-canary.1
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 +16 -0
- package/README.md +4 -43
- package/dist/AppContext.d.ts +3 -2
- package/dist/AppListener.d.ts +2 -1
- package/dist/AppManager.d.ts +10 -7
- package/dist/AppProxy.d.ts +3 -0
- package/dist/AttributesDelegate.d.ts +19 -11
- package/dist/Base/index.d.ts +1 -2
- package/dist/BoxManager.d.ts +23 -7
- package/dist/Cursor/index.d.ts +2 -1
- package/dist/MainView.d.ts +1 -0
- package/dist/ReconnectRefresher.d.ts +6 -3
- package/dist/Utils/RoomHacker.d.ts +2 -2
- package/dist/Utils/error.d.ts +3 -0
- package/dist/constants.d.ts +2 -1
- package/dist/index.d.ts +13 -16
- package/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/docs/api.md +17 -0
- package/docs/migrate.md +42 -0
- package/package.json +3 -2
- package/src/AppContext.ts +2 -2
- package/src/AppListener.ts +14 -3
- package/src/AppManager.ts +87 -69
- package/src/AppProxy.ts +36 -17
- package/src/AttributesDelegate.ts +76 -49
- package/src/Base/Context.ts +2 -2
- package/src/Base/index.ts +2 -2
- package/src/BoxManager.ts +93 -35
- package/src/Cursor/Cursor.ts +12 -5
- package/src/Cursor/index.ts +15 -8
- package/src/MainView.ts +11 -3
- package/src/ReconnectRefresher.ts +17 -10
- package/src/Utils/RoomHacker.ts +5 -5
- package/src/Utils/error.ts +6 -1
- package/src/constants.ts +1 -0
- package/src/index.ts +115 -103
- package/src/style.css +1 -1
- package/src/viewManager.ts +2 -2
- package/yarn-error.log +0 -4285
package/src/AppProxy.ts
CHANGED
@@ -25,6 +25,7 @@ import type { AppManager } from "./AppManager";
|
|
25
25
|
import type { NetlessApp } from "./typings";
|
26
26
|
import type { ReadonlyTeleBox } from "@netless/telebox-insider";
|
27
27
|
import { Base } from "./Base";
|
28
|
+
import { BoxManagerNotFoundError } from "./Utils/error";
|
28
29
|
|
29
30
|
export class AppProxy extends Base {
|
30
31
|
public id: string;
|
@@ -40,6 +41,9 @@ export class AppProxy extends Base {
|
|
40
41
|
private kind: string;
|
41
42
|
public isAddApp: boolean;
|
42
43
|
private status: "normal" | "destroyed" = "normal";
|
44
|
+
private stateKey: string;
|
45
|
+
private appResult?: NetlessApp<any>;
|
46
|
+
private appContext?: AppContext<any, any>;
|
43
47
|
|
44
48
|
constructor(
|
45
49
|
private params: BaseInsertParams,
|
@@ -50,6 +54,7 @@ export class AppProxy extends Base {
|
|
50
54
|
super(manager);
|
51
55
|
this.kind = params.kind;
|
52
56
|
this.id = appId;
|
57
|
+
this.stateKey = `${this.id}_state`;
|
53
58
|
this.appProxies.set(this.id, this);
|
54
59
|
this.appEmitter = new Emittery();
|
55
60
|
this.appListener = this.makeAppEventListener(this.id);
|
@@ -129,15 +134,15 @@ export class AppProxy extends Base {
|
|
129
134
|
private focusApp() {
|
130
135
|
this.focusBox();
|
131
136
|
this.context.switchAppToWriter(this.id);
|
132
|
-
this.store.setMainViewFocusPath();
|
137
|
+
this.store.setMainViewFocusPath(this.manager.mainView);
|
133
138
|
}
|
134
139
|
|
135
140
|
public get box(): ReadonlyTeleBox | undefined {
|
136
|
-
return this.boxManager
|
141
|
+
return this.boxManager?.getBox(this.id);
|
137
142
|
}
|
138
143
|
|
139
144
|
public focusBox() {
|
140
|
-
this.boxManager
|
145
|
+
this.boxManager?.focusBox({ appId: this.id });
|
141
146
|
}
|
142
147
|
|
143
148
|
private async setupApp(
|
@@ -148,13 +153,17 @@ export class AppProxy extends Base {
|
|
148
153
|
appOptions?: any
|
149
154
|
) {
|
150
155
|
log("setupApp", appId, app, options);
|
151
|
-
|
156
|
+
if (!this.boxManager) {
|
157
|
+
throw new BoxManagerNotFoundError();
|
158
|
+
}
|
159
|
+
const context = new AppContext(this.manager, this.boxManager, appId, this, appOptions);
|
160
|
+
this.appContext = context;
|
152
161
|
try {
|
153
162
|
emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
|
154
163
|
let boxInitState: AppInitState | undefined;
|
155
164
|
if (!skipUpdate) {
|
156
165
|
boxInitState = this.getAppInitState(appId);
|
157
|
-
this.boxManager
|
166
|
+
this.boxManager?.updateBoxState(boxInitState);
|
158
167
|
}
|
159
168
|
this.appEmitter.onAny(this.appListener);
|
160
169
|
this.appAttributesUpdateListener(appId);
|
@@ -162,12 +171,13 @@ export class AppProxy extends Base {
|
|
162
171
|
setTimeout(async () => {
|
163
172
|
// 延迟执行 setup, 防止初始化的属性没有更新成功
|
164
173
|
const result = await app.setup(context);
|
174
|
+
this.appResult = result;
|
165
175
|
appRegister.notifyApp(app.kind, "created", { appId, result });
|
166
176
|
this.afterSetupApp(boxInitState);
|
167
177
|
this.fixMobileSize();
|
168
178
|
}, 50);
|
169
179
|
});
|
170
|
-
this.boxManager
|
180
|
+
this.boxManager?.createBox({
|
171
181
|
appId: appId,
|
172
182
|
app,
|
173
183
|
options,
|
@@ -182,9 +192,9 @@ export class AppProxy extends Base {
|
|
182
192
|
|
183
193
|
// 兼容移动端创建时会出现 PPT 不适配的问题
|
184
194
|
private fixMobileSize() {
|
185
|
-
const box = this.boxManager
|
195
|
+
const box = this.boxManager?.getBox(this.id);
|
186
196
|
if (box) {
|
187
|
-
this.boxManager
|
197
|
+
this.boxManager?.resizeBox({
|
188
198
|
appId: this.id,
|
189
199
|
width: box.intrinsicWidth + 0.001,
|
190
200
|
height: box.intrinsicHeight + 0.001,
|
@@ -199,7 +209,7 @@ export class AppProxy extends Base {
|
|
199
209
|
this.context.switchAppToWriter(this.id);
|
200
210
|
}
|
201
211
|
if (!boxInitState?.x || !boxInitState.y) {
|
202
|
-
this.boxManager
|
212
|
+
this.boxManager?.setBoxInitState(this.id);
|
203
213
|
}
|
204
214
|
}
|
205
215
|
}
|
@@ -207,7 +217,7 @@ export class AppProxy extends Base {
|
|
207
217
|
public onSeek(time: number) {
|
208
218
|
this.appEmitter.emit("seek", time);
|
209
219
|
const boxInitState = this.getAppInitState(this.id);
|
210
|
-
this.boxManager
|
220
|
+
this.boxManager?.updateBoxState(boxInitState);
|
211
221
|
}
|
212
222
|
|
213
223
|
public async onReconnected() {
|
@@ -217,7 +227,7 @@ export class AppProxy extends Base {
|
|
217
227
|
const params = this.params;
|
218
228
|
const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);
|
219
229
|
await appProxy.baseInsertApp(true, this.store.focus === this.id);
|
220
|
-
this.boxManager
|
230
|
+
this.boxManager?.updateBoxState(currentAppState);
|
221
231
|
}
|
222
232
|
|
223
233
|
public switchToWritable() {
|
@@ -227,7 +237,7 @@ export class AppProxy extends Base {
|
|
227
237
|
if (this.view.mode === ViewVisionMode.Writable) return;
|
228
238
|
try {
|
229
239
|
if (this.manager.mainView.mode === ViewVisionMode.Writable) {
|
230
|
-
this.store.setMainViewFocusPath();
|
240
|
+
this.store.setMainViewFocusPath(this.manager.mainView);
|
231
241
|
notifyMainViewModeChange(callbacks, ViewVisionMode.Freedom);
|
232
242
|
setViewMode(this.manager.mainView, ViewVisionMode.Freedom);
|
233
243
|
}
|
@@ -278,7 +288,7 @@ export class AppProxy extends Base {
|
|
278
288
|
if (!this.manager.canOperate) return;
|
279
289
|
switch (eventName) {
|
280
290
|
case "setBoxSize": {
|
281
|
-
this.boxManager
|
291
|
+
this.boxManager?.resizeBox({
|
282
292
|
appId,
|
283
293
|
width: data.width,
|
284
294
|
height: data.height,
|
@@ -287,7 +297,7 @@ export class AppProxy extends Base {
|
|
287
297
|
break;
|
288
298
|
}
|
289
299
|
case "setBoxMinSize": {
|
290
|
-
this.boxManager
|
300
|
+
this.boxManager?.setBoxMinSize({
|
291
301
|
appId,
|
292
302
|
minWidth: data.minwidth,
|
293
303
|
minHeight: data.minheight,
|
@@ -295,7 +305,7 @@ export class AppProxy extends Base {
|
|
295
305
|
break;
|
296
306
|
}
|
297
307
|
case "setBoxTitle": {
|
298
|
-
this.boxManager
|
308
|
+
this.boxManager?.setBoxTitle({ appId, title: data.title });
|
299
309
|
break;
|
300
310
|
}
|
301
311
|
case AppEvents.destroy: {
|
@@ -307,7 +317,7 @@ export class AppProxy extends Base {
|
|
307
317
|
break;
|
308
318
|
}
|
309
319
|
case "focus": {
|
310
|
-
this.boxManager
|
320
|
+
this.boxManager?.focusBox({ appId: this.id });
|
311
321
|
emitter.emit("focus", { appId: this.id });
|
312
322
|
break;
|
313
323
|
}
|
@@ -327,6 +337,14 @@ export class AppProxy extends Base {
|
|
327
337
|
}
|
328
338
|
});
|
329
339
|
});
|
340
|
+
this.manager.refresher?.add(this.stateKey,() => {
|
341
|
+
return autorun(() => {
|
342
|
+
const appState = this.appAttributes?.state;
|
343
|
+
if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {
|
344
|
+
this.boxManager?.setZIndex(appId, appState.zIndex);
|
345
|
+
}
|
346
|
+
});
|
347
|
+
});
|
330
348
|
};
|
331
349
|
|
332
350
|
public setScenePath(): void {
|
@@ -364,7 +382,7 @@ export class AppProxy extends Base {
|
|
364
382
|
this.appEmitter.clearListeners();
|
365
383
|
emitter.emit(`destroy-${this.id}` as any, { error });
|
366
384
|
if (needCloseBox) {
|
367
|
-
this.boxManager
|
385
|
+
this.boxManager?.closeBox(this.id, skipUpdate);
|
368
386
|
}
|
369
387
|
if (cleanAttrs) {
|
370
388
|
this.store.cleanAppAttributes(this.id);
|
@@ -375,6 +393,7 @@ export class AppProxy extends Base {
|
|
375
393
|
this.viewManager.destroyView(this.id);
|
376
394
|
this.manager.appStatus.delete(this.id);
|
377
395
|
this.manager.refresher?.remove(this.id);
|
396
|
+
this.manager.refresher?.remove(this.stateKey);
|
378
397
|
}
|
379
398
|
|
380
399
|
public close(): Promise<void> {
|
@@ -2,8 +2,7 @@ import { AppAttributes } from "./constants";
|
|
2
2
|
import { get, pick } from "lodash";
|
3
3
|
import { setViewFocusScenePath } from "./Utils/Common";
|
4
4
|
import type { AddAppParams, AppSyncAttributes } from "./index";
|
5
|
-
import type { Camera, Size } from "white-web-sdk";
|
6
|
-
import type { AppManager } from "./AppManager";
|
5
|
+
import type { Camera, Size, View } from "white-web-sdk";
|
7
6
|
import type { Cursor } from "./Cursor/Cursor";
|
8
7
|
|
9
8
|
export enum Fields {
|
@@ -17,7 +16,7 @@ export enum Fields {
|
|
17
16
|
Cursors = "cursors",
|
18
17
|
Position = "position",
|
19
18
|
CursorState = "cursorState",
|
20
|
-
FullPath = "fullPath"
|
19
|
+
FullPath = "fullPath",
|
21
20
|
}
|
22
21
|
|
23
22
|
export type Apps = {
|
@@ -33,15 +32,29 @@ export type Position = {
|
|
33
32
|
|
34
33
|
export type PositionType = "main" | "app";
|
35
34
|
|
35
|
+
export type StoreContext = {
|
36
|
+
getAttributes: () => any;
|
37
|
+
safeUpdateAttributes: (keys: string[], value: any) => void;
|
38
|
+
safeSetAttributes: (attributes: any) => void;
|
39
|
+
}
|
36
40
|
export class AttributesDelegate {
|
37
|
-
|
41
|
+
|
42
|
+
constructor(private context: StoreContext) {}
|
43
|
+
|
44
|
+
public setContext(context: StoreContext) {
|
45
|
+
this.context = context;
|
46
|
+
}
|
47
|
+
|
48
|
+
public get attributes() {
|
49
|
+
return this.context.getAttributes();
|
50
|
+
}
|
38
51
|
|
39
52
|
public apps(): Apps {
|
40
|
-
return get(this.
|
53
|
+
return get(this.attributes, [Fields.Apps]);
|
41
54
|
}
|
42
55
|
|
43
56
|
public get focus(): string | undefined {
|
44
|
-
return get(this.
|
57
|
+
return get(this.attributes, [Fields.Focus]);
|
45
58
|
}
|
46
59
|
|
47
60
|
public getAppAttributes(id: string): AppSyncAttributes {
|
@@ -53,13 +66,17 @@ export class AttributesDelegate {
|
|
53
66
|
}
|
54
67
|
|
55
68
|
public getMaximized() {
|
56
|
-
return get(this.
|
69
|
+
return get(this.attributes, ["maximized"]);
|
70
|
+
}
|
71
|
+
|
72
|
+
public getMinimized() {
|
73
|
+
return get(this.attributes, ["minimized"]);
|
57
74
|
}
|
58
75
|
|
59
76
|
public setupAppAttributes(params: AddAppParams, id: string, isDynamicPPT: boolean) {
|
60
|
-
const attributes = this.
|
77
|
+
const attributes = this.attributes;
|
61
78
|
if (!attributes.apps) {
|
62
|
-
this.
|
79
|
+
this.context.safeSetAttributes({ apps: {} });
|
63
80
|
}
|
64
81
|
const attrNames = ["scenePath", "title"];
|
65
82
|
if (!isDynamicPPT) {
|
@@ -70,32 +87,32 @@ export class AttributesDelegate {
|
|
70
87
|
if (typeof params.src === "string") {
|
71
88
|
attrs.src = params.src;
|
72
89
|
}
|
73
|
-
|
74
|
-
this.
|
90
|
+
attrs.createdAt = Date.now();
|
91
|
+
this.context.safeUpdateAttributes([Fields.Apps, id], attrs);
|
92
|
+
this.context.safeUpdateAttributes([Fields.Apps, id, Fields.State], {
|
75
93
|
[AppAttributes.Size]: {},
|
76
94
|
[AppAttributes.Position]: {},
|
77
95
|
[AppAttributes.SceneIndex]: 0,
|
78
|
-
[AppAttributes.ZIndex]: 100,
|
79
96
|
});
|
80
97
|
}
|
81
98
|
|
82
99
|
public updateAppState(appId: string, stateName: AppAttributes, state: any) {
|
83
|
-
if (get(this.
|
84
|
-
this.
|
100
|
+
if (get(this.attributes, [Fields.Apps, appId, Fields.State])) {
|
101
|
+
this.context.safeUpdateAttributes([Fields.Apps, appId, Fields.State, stateName], state);
|
85
102
|
}
|
86
103
|
}
|
87
104
|
|
88
105
|
public cleanAppAttributes(id: string) {
|
89
|
-
this.
|
90
|
-
this.
|
91
|
-
const focus = this.
|
106
|
+
this.context.safeUpdateAttributes([Fields.Apps, id], undefined);
|
107
|
+
this.context.safeSetAttributes({ [id]: undefined });
|
108
|
+
const focus = this.attributes[Fields.Focus];
|
92
109
|
if (focus === id) {
|
93
110
|
this.cleanFocus();
|
94
111
|
}
|
95
112
|
}
|
96
113
|
|
97
114
|
public cleanFocus() {
|
98
|
-
this.
|
115
|
+
this.context.safeSetAttributes({ [Fields.Focus]: undefined });
|
99
116
|
}
|
100
117
|
|
101
118
|
public getAppSceneIndex(id: string) {
|
@@ -107,82 +124,79 @@ export class AttributesDelegate {
|
|
107
124
|
}
|
108
125
|
|
109
126
|
public getMainViewScenePath() {
|
110
|
-
return this.
|
127
|
+
return this.attributes["_mainScenePath"];
|
111
128
|
}
|
112
129
|
|
113
130
|
public getMainViewSceneIndex() {
|
114
|
-
return this.
|
131
|
+
return this.attributes["_mainSceneIndex"];
|
115
132
|
}
|
116
133
|
|
117
134
|
public getBoxState() {
|
118
|
-
return this.
|
135
|
+
return this.attributes[Fields.BoxState];
|
119
136
|
}
|
120
137
|
|
121
138
|
public setMainViewScenePath(scenePath: string) {
|
122
|
-
this.
|
139
|
+
this.context.safeSetAttributes({ _mainScenePath: scenePath });
|
123
140
|
}
|
124
141
|
|
125
142
|
public setMainViewSceneIndex(index: number) {
|
126
|
-
this.
|
143
|
+
this.context.safeSetAttributes({ _mainSceneIndex: index });
|
127
144
|
}
|
128
145
|
|
129
146
|
public getMainViewCamera(): MainViewCamera {
|
130
|
-
return get(this.
|
147
|
+
return get(this.attributes, [Fields.MainViewCamera]);
|
131
148
|
}
|
132
149
|
|
133
150
|
public getMainViewSize(): MainViewSize {
|
134
|
-
return get(this.
|
151
|
+
return get(this.attributes, [Fields.MainViewSize]);
|
135
152
|
}
|
136
153
|
|
137
|
-
public setMainViewCamera(camera: Camera & { id: string } | undefined) {
|
138
|
-
this.
|
154
|
+
public setMainViewCamera(camera: (Camera & { id: string }) | undefined) {
|
155
|
+
this.context.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });
|
139
156
|
}
|
140
157
|
|
141
|
-
public setMainViewSize(size: Size & { id: string } | undefined) {
|
142
|
-
this.
|
158
|
+
public setMainViewSize(size: (Size & { id: string }) | undefined) {
|
159
|
+
this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });
|
143
160
|
}
|
144
161
|
|
145
162
|
public setAppFocus(appId: string, focus: boolean) {
|
146
163
|
if (focus) {
|
147
|
-
this.
|
164
|
+
this.context.safeSetAttributes({ [Fields.Focus]: appId });
|
148
165
|
} else {
|
149
|
-
this.
|
166
|
+
this.context.safeSetAttributes({ [Fields.Focus]: undefined });
|
150
167
|
}
|
151
168
|
}
|
152
169
|
|
153
170
|
public updateCursor(uid: string, position: Position) {
|
154
|
-
if (!get(this.
|
155
|
-
this.
|
171
|
+
if (!get(this.attributes, [Fields.Cursors])) {
|
172
|
+
this.context.safeUpdateAttributes([Fields.Cursors], {});
|
156
173
|
}
|
157
|
-
if (!get(this.
|
158
|
-
this.
|
174
|
+
if (!get(this.attributes, [Fields.Cursors, uid])) {
|
175
|
+
this.context.safeUpdateAttributes([Fields.Cursors, uid], {});
|
159
176
|
}
|
160
|
-
this.
|
177
|
+
this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.Position], position);
|
161
178
|
}
|
162
179
|
|
163
180
|
public updateCursorState(uid: string, cursorState: string | undefined) {
|
164
|
-
if (!get(this.
|
165
|
-
this.
|
181
|
+
if (!get(this.attributes, [Fields.Cursors, uid])) {
|
182
|
+
this.context.safeUpdateAttributes([Fields.Cursors, uid], {});
|
166
183
|
}
|
167
|
-
this.
|
168
|
-
[Fields.Cursors, uid, Fields.CursorState],
|
169
|
-
cursorState
|
170
|
-
);
|
184
|
+
this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.CursorState], cursorState);
|
171
185
|
}
|
172
186
|
|
173
187
|
public getCursorState(uid: string) {
|
174
|
-
return get(this.
|
188
|
+
return get(this.attributes, [Fields.Cursors, uid, Fields.CursorState]);
|
175
189
|
}
|
176
190
|
|
177
191
|
public cleanCursor(uid: string) {
|
178
|
-
this.
|
192
|
+
this.context.safeUpdateAttributes([Fields.Cursors, uid], undefined);
|
179
193
|
}
|
180
194
|
|
181
195
|
// TODO 状态中保存一个 SceneName 优化性能
|
182
|
-
public setMainViewFocusPath() {
|
196
|
+
public setMainViewFocusPath(mainView: View) {
|
183
197
|
const scenePath = this.getMainViewScenePath();
|
184
198
|
if (scenePath) {
|
185
|
-
setViewFocusScenePath(
|
199
|
+
setViewFocusScenePath(mainView, scenePath);
|
186
200
|
}
|
187
201
|
}
|
188
202
|
}
|
@@ -191,15 +205,28 @@ export type MainViewSize = {
|
|
191
205
|
id: string;
|
192
206
|
width: number;
|
193
207
|
height: number;
|
194
|
-
}
|
208
|
+
};
|
195
209
|
|
196
210
|
export type MainViewCamera = {
|
197
211
|
id: string;
|
198
212
|
centerX: number;
|
199
213
|
centerY: number;
|
200
214
|
scale: number;
|
201
|
-
}
|
215
|
+
};
|
202
216
|
|
203
217
|
export type Cursors = {
|
204
218
|
[key: string]: Cursor;
|
205
|
-
}
|
219
|
+
};
|
220
|
+
|
221
|
+
|
222
|
+
export const store = new AttributesDelegate({
|
223
|
+
getAttributes: () => {
|
224
|
+
throw new Error("getAttributes not implemented")
|
225
|
+
},
|
226
|
+
safeSetAttributes: () => {
|
227
|
+
throw new Error("safeSetAttributes not implemented")
|
228
|
+
},
|
229
|
+
safeUpdateAttributes: () => {
|
230
|
+
throw new Error("safeUpdateAttributes not implemented")
|
231
|
+
},
|
232
|
+
});
|
package/src/Base/Context.ts
CHANGED
@@ -27,11 +27,11 @@ export class Context {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
public updateManagerRect() {
|
30
|
-
this.manager.boxManager
|
30
|
+
this.manager.boxManager?.updateManagerRect();
|
31
31
|
}
|
32
32
|
|
33
33
|
public blurFocusBox() {
|
34
|
-
this.manager.boxManager
|
34
|
+
this.manager.boxManager?.blurAllBox();
|
35
35
|
}
|
36
36
|
|
37
37
|
public switchAppToWriter(id: string) {
|
package/src/Base/index.ts
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import type { AppManager } from "../AppManager";
|
2
|
-
import {
|
2
|
+
import { store } from "../AttributesDelegate";
|
3
3
|
import { createContext } from "./Context";
|
4
4
|
|
5
5
|
export class Base {
|
6
|
-
public store =
|
6
|
+
public store = store;
|
7
7
|
public context = createContext(this.manager);
|
8
8
|
|
9
9
|
constructor(public manager: AppManager) {}
|