mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at push-notifications 116 lines 2.3 kB view raw
1import {makeAutoObservable} from 'mobx' 2import {AppBskyActorGetSuggestions as GetSuggestions} from '@atproto/api' 3import {RootStoreModel} from './root-store' 4 5export type SuggestedActor = GetSuggestions.Actor & { 6 _reactKey: string 7} 8 9export class SuggestedActorsViewModel { 10 // state 11 isLoading = false 12 isRefreshing = false 13 hasLoaded = false 14 error = '' 15 16 // data 17 suggestions: SuggestedActor[] = [] 18 19 constructor(public rootStore: RootStoreModel) { 20 makeAutoObservable( 21 this, 22 { 23 rootStore: false, 24 }, 25 {autoBind: true}, 26 ) 27 } 28 29 get hasContent() { 30 return this.suggestions.length > 0 31 } 32 33 get hasError() { 34 return this.error !== '' 35 } 36 37 get isEmpty() { 38 return this.hasLoaded && !this.hasContent 39 } 40 41 // public api 42 // = 43 44 async setup() { 45 await this._fetch() 46 } 47 48 async refresh() { 49 await this._fetch(true) 50 } 51 52 // state transitions 53 // = 54 55 private _xLoading(isRefreshing = false) { 56 this.isLoading = true 57 this.isRefreshing = isRefreshing 58 this.error = '' 59 } 60 61 private _xIdle(err?: any) { 62 this.isLoading = false 63 this.isRefreshing = false 64 this.hasLoaded = true 65 this.error = err ? err.toString() : '' 66 if (err) { 67 this.rootStore.log.error('Failed to fetch suggested actors', err) 68 } 69 } 70 71 // loader functions 72 // = 73 74 private async _fetch(isRefreshing = false) { 75 this.suggestions.length = 0 76 this._xLoading(isRefreshing) 77 let cursor 78 let res 79 try { 80 do { 81 res = await this.rootStore.api.app.bsky.actor.getSuggestions({ 82 limit: 20, 83 cursor, 84 }) 85 this._appendAll(res) 86 cursor = res.data.cursor 87 } while ( 88 cursor && 89 res.data.actors.length === 20 && 90 this.suggestions.length < 20 91 ) 92 this._xIdle() 93 } catch (e: any) { 94 this._xIdle(e) 95 } 96 } 97 98 private _appendAll(res: GetSuggestions.Response) { 99 for (const item of res.data.actors) { 100 if (item.did === this.rootStore.me.did) { 101 continue // skip self 102 } 103 if (item.myState?.follow) { 104 continue // skip already-followed users 105 } 106 this._append({ 107 _reactKey: `item-${this.suggestions.length}`, 108 ...item, 109 }) 110 } 111 } 112 113 private _append(item: SuggestedActor) { 114 this.suggestions.push(item) 115 } 116}