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
|
import {makeAutoObservable} from 'mobx'
import {RootStoreModel} from './root-store'
import {ProfileViewModel} from './profile-view'
import {FeedModel} from './feed-view'
import {BadgesViewModel} from './badges-view'
export const SECTION_IDS = {
POSTS: 0,
BADGES: 1,
}
export interface ProfileUiParams {
user: string
}
export class ProfileUiModel {
// constants
static SELECTOR_ITEMS = ['Posts', 'Scenes']
// data
profile: ProfileViewModel
feed: FeedModel
badges: BadgesViewModel
// ui state
selectedViewIndex = 0
constructor(
public rootStore: RootStoreModel,
public params: ProfileUiParams,
) {
makeAutoObservable(
this,
{
rootStore: false,
params: false,
},
{autoBind: true},
)
this.profile = new ProfileViewModel(rootStore, {user: params.user})
this.feed = new FeedModel(rootStore, 'author', {
author: params.user,
limit: 10,
})
this.badges = new BadgesViewModel(rootStore)
}
get currentView(): FeedModel | BadgesViewModel {
if (this.selectedViewIndex === SECTION_IDS.POSTS) {
return this.feed
}
if (this.selectedViewIndex === SECTION_IDS.BADGES) {
return this.badges
}
throw new Error(`Invalid selector value: ${this.selectedViewIndex}`)
}
get isInitialLoading() {
const view = this.currentView
return view.isLoading && !view.isRefreshing && !view.hasContent
}
get isRefreshing() {
return this.profile.isRefreshing || this.currentView.isRefreshing
}
// public api
// =
setSelectedViewIndex(index: number) {
this.selectedViewIndex = index
}
async setup() {
await Promise.all([
this.profile
.setup()
.catch(err => console.error('Failed to fetch profile', err)),
this.feed
.setup()
.catch(err => console.error('Failed to fetch feed', err)),
this.badges
.setup()
.catch(err => console.error('Failed to fetch badges', err)),
])
}
async update() {
await this.currentView.update()
}
async refresh() {
await Promise.all([this.profile.refresh(), this.currentView.refresh()])
}
async loadMore() {
if (!this.currentView.isLoading && !this.currentView.hasError) {
await this.currentView.loadMore()
}
}
}
|