e74f94bc72
* Replace react-native-root-toast with a custom toast that fits the visual style * Tune dark mode colors * Tune colors a bit more * Move the reply prompt to a fixed position in the footer * Fully hide muted posts but give a control to show anyway (close #270) * Improve thread rendering (better clarity on reply lines) * Add follower/following counts to side menu * Fix issues with display name overflows
123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
import {makeAutoObservable, runInAction} from 'mobx'
|
|
import {RootStoreModel} from './root-store'
|
|
import {FeedModel} from './feed-view'
|
|
import {NotificationsViewModel} from './notifications-view'
|
|
import {MyFollowsModel} from './my-follows'
|
|
import {isObj, hasProp} from 'lib/type-guards'
|
|
|
|
export class MeModel {
|
|
did: string = ''
|
|
handle: string = ''
|
|
displayName: string = ''
|
|
description: string = ''
|
|
avatar: string = ''
|
|
followsCount: number | undefined
|
|
followersCount: number | undefined
|
|
mainFeed: FeedModel
|
|
notifications: NotificationsViewModel
|
|
follows: MyFollowsModel
|
|
|
|
constructor(public rootStore: RootStoreModel) {
|
|
makeAutoObservable(
|
|
this,
|
|
{rootStore: false, serialize: false, hydrate: false},
|
|
{autoBind: true},
|
|
)
|
|
this.mainFeed = new FeedModel(this.rootStore, 'home', {
|
|
algorithm: 'reverse-chronological',
|
|
})
|
|
this.notifications = new NotificationsViewModel(this.rootStore, {})
|
|
this.follows = new MyFollowsModel(this.rootStore)
|
|
}
|
|
|
|
clear() {
|
|
this.mainFeed.clear()
|
|
this.notifications.clear()
|
|
this.did = ''
|
|
this.handle = ''
|
|
this.displayName = ''
|
|
this.description = ''
|
|
this.avatar = ''
|
|
}
|
|
|
|
serialize(): unknown {
|
|
return {
|
|
did: this.did,
|
|
handle: this.handle,
|
|
displayName: this.displayName,
|
|
description: this.description,
|
|
avatar: this.avatar,
|
|
}
|
|
}
|
|
|
|
hydrate(v: unknown) {
|
|
if (isObj(v)) {
|
|
let did, handle, displayName, description, avatar
|
|
if (hasProp(v, 'did') && typeof v.did === 'string') {
|
|
did = v.did
|
|
}
|
|
if (hasProp(v, 'handle') && typeof v.handle === 'string') {
|
|
handle = v.handle
|
|
}
|
|
if (hasProp(v, 'displayName') && typeof v.displayName === 'string') {
|
|
displayName = v.displayName
|
|
}
|
|
if (hasProp(v, 'description') && typeof v.description === 'string') {
|
|
description = v.description
|
|
}
|
|
if (hasProp(v, 'avatar') && typeof v.avatar === 'string') {
|
|
avatar = v.avatar
|
|
}
|
|
if (did && handle) {
|
|
this.did = did
|
|
this.handle = handle
|
|
this.displayName = displayName || ''
|
|
this.description = description || ''
|
|
this.avatar = avatar || ''
|
|
}
|
|
}
|
|
}
|
|
|
|
async load() {
|
|
const sess = this.rootStore.session
|
|
this.rootStore.log.debug('MeModel:load', {hasSession: sess.hasSession})
|
|
if (sess.hasSession) {
|
|
this.did = sess.currentSession?.did || ''
|
|
this.handle = sess.currentSession?.handle || ''
|
|
const profile = await this.rootStore.api.app.bsky.actor.getProfile({
|
|
actor: this.did,
|
|
})
|
|
runInAction(() => {
|
|
if (profile?.data) {
|
|
this.displayName = profile.data.displayName || ''
|
|
this.description = profile.data.description || ''
|
|
this.avatar = profile.data.avatar || ''
|
|
this.followsCount = profile.data.followsCount
|
|
this.followersCount = profile.data.followersCount
|
|
} else {
|
|
this.displayName = ''
|
|
this.description = ''
|
|
this.avatar = ''
|
|
this.followsCount = profile.data.followsCount
|
|
this.followersCount = undefined
|
|
}
|
|
})
|
|
this.mainFeed.clear()
|
|
await this.follows.fetch().catch(e => {
|
|
this.rootStore.log.error('Failed to load my follows', e)
|
|
})
|
|
await Promise.all([
|
|
this.mainFeed.setup().catch(e => {
|
|
this.rootStore.log.error('Failed to setup main feed model', e)
|
|
}),
|
|
this.notifications.setup().catch(e => {
|
|
this.rootStore.log.error('Failed to setup notifications model', e)
|
|
}),
|
|
])
|
|
this.rootStore.emitSessionLoaded()
|
|
} else {
|
|
this.clear()
|
|
}
|
|
}
|
|
}
|