PresenterBase.ts
3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { View, Subview, OnSubviewCreated } from "./ViewBase";
import { CompositeDisposable } from "simba-eventkit";
let presenterViewFactory: (<P, V extends View, PR extends Presenter<P, V>>(presenterCls: { new(): PR, uuid: string }) => Promise<V>) & { preloadView: (presenterCls: { new(): Presenter, uuid: string }) => Promise<void> };
export function setPresenterViewFactory(factory: typeof presenterViewFactory) {
presenterViewFactory = factory;
}
let subpresenterFactory: (subview: Subview) => Subpresenter;
export function setSubpresenterwFactory(factory: (subview: Subview) => Subpresenter) {
subpresenterFactory = factory;
}
let currentCreatingPresenter: Presenter<any, any> | undefined;
export async function createPresenter<P, V extends View, PR extends Presenter<P, V>>(presenterCls: { new(): PR, uuid: string }): Promise<PR> {
await presenterViewFactory.preloadView(presenterCls as any);
if (currentCreatingPresenter) {
console.warn("create presenter simultaneously will cause sub presenters error!");
}
let presenter = currentCreatingPresenter = new presenterCls;
let view = await presenterViewFactory<P, V, PR>(presenterCls);
presenter.attachView(view);
currentCreatingPresenter = undefined;
return presenter;
}
OnSubviewCreated.on((subview) => {
if (!currentCreatingPresenter) {
return;
}
let presenter = subpresenterFactory(subview);
presenter.owner = currentCreatingPresenter;
(currentCreatingPresenter as any)._subpresenters.push(presenter);
});
export type PresenterParamType<T> = T extends Presenter<infer U, any> ? U : any;
class PresenterBase {
protected _disposable: CompositeDisposable;
onShow() {
}
onHide() {
}
}
export class Subpresenter<V extends Subview = Subview, Owner extends Presenter<any, any> = Presenter<any, any>> extends PresenterBase {
owner: Owner;
_view: Subview;
get view() { return this._view as V; }
attachView(view: V) {
this._view = view;
}
onOpen() {
this._disposable = new CompositeDisposable;
this._disposable.add(this._view.onShow.on(() => this.onShow()));
this._disposable.add(this._view.onHide.on(() => this.onHide()));
}
onClose() {
this._disposable.dispose();
}
onOwnerShow() {
}
onOwnerHide() {
}
onOwnerEnterForeground() {
}
onOwnerEnterBackground() {
}
}
export class Presenter<P = undefined, V extends View = View> extends PresenterBase {
protected _view: V;
protected _isInBackground = false;
protected _subpresenters: Subpresenter[] = [];
get view() { return this._view as V; }
open = (parent: View, props: P) => {
this._view.open(parent);
this.onOpen(props);
}
attachView(view: V) {
this._view = view;
}
onOpen(props: P) {
this._disposable = new CompositeDisposable;
this._disposable.add(this._view.onClose.on(() => this.onClose()));
this._disposable.add(this._view.onShow.on(() => this.onShow()));
this._disposable.add(this._view.onHide.on(() => this.onHide()));
this._subpresenters.forEach((p) => {
p.onOpen();
});
}
onClose() {
this._disposable.dispose();
this._subpresenters.forEach((p) => {
p.onClose();
});
}
onShow() {
this._subpresenters.forEach((p) => {
p.onOwnerShow();
});
}
onHide() {
this._subpresenters.forEach((p) => {
p.onOwnerHide();
});
}
onEnterForeground() {
this._isInBackground = false;
this._subpresenters.forEach((p) => {
p.onOwnerEnterForeground();
});
}
onEnterBackground() {
this._isInBackground = true;
this._subpresenters.forEach((p) => {
p.onOwnerEnterBackground();
});
}
}