about summary refs log tree commit diff
path: root/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'src/state')
-rw-r--r--src/state/invites.tsx56
-rw-r--r--src/state/models/feeds/notifications.ts2
-rw-r--r--src/state/models/invited-users.ts88
-rw-r--r--src/state/models/me.ts1
-rw-r--r--src/state/models/root-store.ts6
-rw-r--r--src/state/persisted/legacy.ts6
-rw-r--r--src/state/persisted/schema.ts6
7 files changed, 61 insertions, 104 deletions
diff --git a/src/state/invites.tsx b/src/state/invites.tsx
new file mode 100644
index 000000000..6a0d1b590
--- /dev/null
+++ b/src/state/invites.tsx
@@ -0,0 +1,56 @@
+import React from 'react'
+import * as persisted from '#/state/persisted'
+
+type StateContext = persisted.Schema['invites']
+type ApiContext = {
+  setInviteCopied: (code: string) => void
+}
+
+const stateContext = React.createContext<StateContext>(
+  persisted.defaults.invites,
+)
+const apiContext = React.createContext<ApiContext>({
+  setInviteCopied(_: string) {},
+})
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+  const [state, setState] = React.useState(persisted.get('invites'))
+
+  const api = React.useMemo(
+    () => ({
+      setInviteCopied(code: string) {
+        setState(state => {
+          state = {
+            ...state,
+            copiedInvites: state.copiedInvites.includes(code)
+              ? state.copiedInvites
+              : state.copiedInvites.concat([code]),
+          }
+          persisted.write('invites', state)
+          return state
+        })
+      },
+    }),
+    [setState],
+  )
+
+  React.useEffect(() => {
+    return persisted.onUpdate(() => {
+      setState(persisted.get('invites'))
+    })
+  }, [setState])
+
+  return (
+    <stateContext.Provider value={state}>
+      <apiContext.Provider value={api}>{children}</apiContext.Provider>
+    </stateContext.Provider>
+  )
+}
+
+export function useInvitesState() {
+  return React.useContext(stateContext)
+}
+
+export function useInvitesAPI() {
+  return React.useContext(apiContext)
+}
diff --git a/src/state/models/feeds/notifications.ts b/src/state/models/feeds/notifications.ts
index 272d52881..5f34feb66 100644
--- a/src/state/models/feeds/notifications.ts
+++ b/src/state/models/feeds/notifications.ts
@@ -304,7 +304,7 @@ export class NotificationsFeedModel {
   }
 
   get unreadCountLabel(): string {
-    const count = this.unreadCount + this.rootStore.invitedUsers.numNotifs
+    const count = this.unreadCount
     if (count >= MAX_VISIBLE_NOTIFS) {
       return `${MAX_VISIBLE_NOTIFS}+`
     }
diff --git a/src/state/models/invited-users.ts b/src/state/models/invited-users.ts
deleted file mode 100644
index 9ba65e19e..000000000
--- a/src/state/models/invited-users.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import {makeAutoObservable, runInAction} from 'mobx'
-import {ComAtprotoServerDefs, AppBskyActorDefs} from '@atproto/api'
-import {RootStoreModel} from './root-store'
-import {isObj, hasProp, isStrArray} from 'lib/type-guards'
-import {logger} from '#/logger'
-
-export class InvitedUsers {
-  copiedInvites: string[] = []
-  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, copiedInvites: this.copiedInvites}
-  }
-
-  hydrate(v: unknown) {
-    if (isObj(v) && hasProp(v, 'seenDids') && isStrArray(v.seenDids)) {
-      this.seenDids = v.seenDids
-    }
-    if (
-      isObj(v) &&
-      hasProp(v, 'copiedInvites') &&
-      isStrArray(v.copiedInvites)
-    ) {
-      this.copiedInvites = v.copiedInvites
-    }
-  }
-
-  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.hydrateMany(this.profiles)
-      } catch (e) {
-        logger.error('Failed to fetch profiles for invited users', {
-          error: e,
-        })
-      }
-    }
-  }
-
-  isInviteCopied(invite: string) {
-    return this.copiedInvites.includes(invite)
-  }
-
-  setInviteCopied(invite: string) {
-    if (!this.isInviteCopied(invite)) {
-      this.copiedInvites.push(invite)
-    }
-  }
-
-  markSeen(did: string) {
-    this.seenDids.push(did)
-    this.profiles = this.profiles.filter(profile => profile.did !== did)
-  }
-}
diff --git a/src/state/models/me.ts b/src/state/models/me.ts
index d12cb68c4..d3061f166 100644
--- a/src/state/models/me.ts
+++ b/src/state/models/me.ts
@@ -193,7 +193,6 @@ export class MeModel {
           error: e,
         })
       }
-      await this.rootStore.invitedUsers.fetch(this.invites)
     }
   }
 
diff --git a/src/state/models/root-store.ts b/src/state/models/root-store.ts
index fadd279fc..d11e9a148 100644
--- a/src/state/models/root-store.ts
+++ b/src/state/models/root-store.ts
@@ -15,7 +15,6 @@ import {ProfilesCache} from './cache/profiles-view'
 import {PostsCache} from './cache/posts'
 import {LinkMetasCache} from './cache/link-metas'
 import {MeModel} from './me'
-import {InvitedUsers} from './invited-users'
 import {PreferencesModel} from './ui/preferences'
 import {resetToTab} from '../../Navigation'
 import {ImageSizesCache} from './cache/image-sizes'
@@ -42,7 +41,6 @@ export class RootStoreModel {
   shell = new ShellUiModel(this)
   preferences = new PreferencesModel(this)
   me = new MeModel(this)
-  invitedUsers = new InvitedUsers(this)
   handleResolutions = new HandleResolutionsCache()
   profiles = new ProfilesCache(this)
   posts = new PostsCache(this)
@@ -68,7 +66,6 @@ export class RootStoreModel {
       session: this.session.serialize(),
       me: this.me.serialize(),
       preferences: this.preferences.serialize(),
-      invitedUsers: this.invitedUsers.serialize(),
     }
   }
 
@@ -89,9 +86,6 @@ export class RootStoreModel {
       if (hasProp(v, 'preferences')) {
         this.preferences.hydrate(v.preferences)
       }
-      if (hasProp(v, 'invitedUsers')) {
-        this.invitedUsers.hydrate(v.invitedUsers)
-      }
     }
   }
 
diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts
index 67eef81a0..3da509304 100644
--- a/src/state/persisted/legacy.ts
+++ b/src/state/persisted/legacy.ts
@@ -97,11 +97,9 @@ export function transform(legacy: LegacySchema): Schema {
       legacy.preferences.requireAltTextEnabled ||
       defaults.requireAltTextEnabled,
     mutedThreads: legacy.mutedThreads.uris || defaults.mutedThreads,
-    invitedUsers: {
-      seenDids: legacy.invitedUsers.seenDids || defaults.invitedUsers.seenDids,
+    invites: {
       copiedInvites:
-        legacy.invitedUsers.copiedInvites ||
-        defaults.invitedUsers.copiedInvites,
+        legacy.invitedUsers.copiedInvites || defaults.invites.copiedInvites,
     },
     onboarding: {
       step: legacy.onboarding.step || defaults.onboarding.step,
diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts
index 708930610..9c52661e4 100644
--- a/src/state/persisted/schema.ts
+++ b/src/state/persisted/schema.ts
@@ -29,8 +29,7 @@ export const schema = z.object({
   }),
   requireAltTextEnabled: z.boolean(), // should move to server
   mutedThreads: z.array(z.string()), // should move to server
-  invitedUsers: z.object({
-    seenDids: z.array(z.string()),
+  invites: z.object({
     copiedInvites: z.array(z.string()),
   }),
   onboarding: z.object({
@@ -58,8 +57,7 @@ export const defaults: Schema = {
   },
   requireAltTextEnabled: false,
   mutedThreads: [],
-  invitedUsers: {
-    seenDids: [],
+  invites: {
     copiedInvites: [],
   },
   onboarding: {