diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-04-05 18:56:02 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-05 18:56:02 -0500 |
commit | ea04c2bd330dc5b46d6f9df0d7d4619bbd8f56d0 (patch) | |
tree | 870c7d3dbffe1f382cba30b858eaa2b76b31af36 /src/state/models/invited-users.ts | |
parent | 8e28d3c6be8e063b6d563b0068cb4fc907ff5df0 (diff) | |
download | voidsky-ea04c2bd330dc5b46d6f9df0d7d4619bbd8f56d0.tar.zst |
Add user invite codes (#393)
* Add mobile UIs for invite codes * Update invite code UIs for web * Finish implementing invite code behaviors (including notifications of invited users) * Bump deps * Update web right nav to use real data; also fix lint
Diffstat (limited to 'src/state/models/invited-users.ts')
-rw-r--r-- | src/state/models/invited-users.ts | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/state/models/invited-users.ts b/src/state/models/invited-users.ts new file mode 100644 index 000000000..121161a32 --- /dev/null +++ b/src/state/models/invited-users.ts @@ -0,0 +1,70 @@ +import {makeAutoObservable, runInAction} from 'mobx' +import {ComAtprotoServerDefs, AppBskyActorDefs} from '@atproto/api' +import {RootStoreModel} from './root-store' +import {isObj, hasProp, isStrArray} from 'lib/type-guards' + +export class InvitedUsers { + seenDids: string[] = [] + profiles: AppBskyActorDefs.ProfileViewDetailed[] = [] + + get numNotifs() { + return this.profiles.length + } + + constructor(public rootStore: RootStoreModel) { + makeAutoObservable( + this, + {rootStore: false, serialize: false, hydrate: false}, + {autoBind: true}, + ) + } + + serialize() { + return {seenDids: this.seenDids} + } + + hydrate(v: unknown) { + if (isObj(v) && hasProp(v, 'seenDids') && isStrArray(v.seenDids)) { + this.seenDids = v.seenDids + } + } + + async fetch(invites: ComAtprotoServerDefs.InviteCode[]) { + // pull the dids of invited users not marked seen + const dids = [] + for (const invite of invites) { + for (const use of invite.uses) { + if (!this.seenDids.includes(use.usedBy)) { + dids.push(use.usedBy) + } + } + } + + // fetch their profiles + this.profiles = [] + if (dids.length) { + try { + const res = await this.rootStore.agent.app.bsky.actor.getProfiles({ + actors: dids, + }) + runInAction(() => { + // save the ones following -- these are the ones we want to notify the user about + this.profiles = res.data.profiles.filter( + profile => !profile.viewer?.following, + ) + }) + this.rootStore.me.follows.hydrateProfiles(this.profiles) + } catch (e) { + this.rootStore.log.error( + 'Failed to fetch profiles for invited users', + e, + ) + } + } + } + + markSeen(did: string) { + this.seenDids.push(did) + this.profiles = this.profiles.filter(profile => profile.did !== did) + } +} |