From e75b2d508baf9b19e7340657ac2951e9f057b735 Mon Sep 17 00:00:00 2001
From: Paul Frazee <pfrazee@gmail.com>
Date: Wed, 8 Nov 2023 09:10:59 -0800
Subject: Move invite-state to new persistence + context and replace the
 notifications with just showing uses in the modal (#1840)

---
 src/view/com/modals/InviteCodes.tsx | 105 +++++++++++++++++++++++-------------
 1 file changed, 68 insertions(+), 37 deletions(-)

(limited to 'src/view/com/modals/InviteCodes.tsx')

diff --git a/src/view/com/modals/InviteCodes.tsx b/src/view/com/modals/InviteCodes.tsx
index 09cfd4de7..a8aa164c3 100644
--- a/src/view/com/modals/InviteCodes.tsx
+++ b/src/view/com/modals/InviteCodes.tsx
@@ -1,6 +1,7 @@
 import React from 'react'
 import {StyleSheet, TouchableOpacity, View} from 'react-native'
 import {observer} from 'mobx-react-lite'
+import {ComAtprotoServerDefs} from '@atproto/api'
 import {
   FontAwesomeIcon,
   FontAwesomeIconStyle,
@@ -14,6 +15,10 @@ import {ScrollView} from './util'
 import {usePalette} from 'lib/hooks/usePalette'
 import {isWeb} from 'platform/detection'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {useInvitesState, useInvitesAPI} from '#/state/invites'
+import {UserInfoText} from '../util/UserInfoText'
+import {makeProfileLink} from '#/lib/routes/links'
+import {Link} from '../util/Link'
 
 export const snapPoints = ['70%']
 
@@ -66,7 +71,7 @@ export function Component({}: {}) {
           <InviteCode
             testID={`inviteCode-${i}`}
             key={invite.code}
-            code={invite.code}
+            invite={invite}
             used={invite.available - invite.uses.length <= 0 || invite.disabled}
           />
         ))}
@@ -87,52 +92,81 @@ export function Component({}: {}) {
 
 const InviteCode = observer(function InviteCodeImpl({
   testID,
-  code,
+  invite,
   used,
 }: {
   testID: string
-  code: string
+  invite: ComAtprotoServerDefs.InviteCode
   used?: boolean
 }) {
   const pal = usePalette('default')
   const store = useStores()
   const {invitesAvailable} = store.me
+  const invitesState = useInvitesState()
+  const {setInviteCopied} = useInvitesAPI()
 
   const onPress = React.useCallback(() => {
-    Clipboard.setString(code)
+    Clipboard.setString(invite.code)
     Toast.show('Copied to clipboard')
-    store.invitedUsers.setInviteCopied(code)
-  }, [store, code])
+    setInviteCopied(invite.code)
+  }, [setInviteCopied, invite])
 
   return (
-    <TouchableOpacity
-      testID={testID}
-      style={[styles.inviteCode, pal.border]}
-      onPress={onPress}
-      accessibilityRole="button"
-      accessibilityLabel={
-        invitesAvailable === 1
-          ? 'Invite codes: 1 available'
-          : `Invite codes: ${invitesAvailable} available`
-      }
-      accessibilityHint="Opens list of invite codes">
-      <Text
-        testID={`${testID}-code`}
-        type={used ? 'md' : 'md-bold'}
-        style={used ? [pal.textLight, styles.strikeThrough] : pal.text}>
-        {code}
-      </Text>
-      <View style={styles.flex1} />
-      {!used && store.invitedUsers.isInviteCopied(code) && (
-        <Text style={[pal.textLight, styles.codeCopied]}>Copied</Text>
-      )}
-      {!used && (
-        <FontAwesomeIcon
-          icon={['far', 'clone']}
-          style={pal.text as FontAwesomeIconStyle}
-        />
-      )}
-    </TouchableOpacity>
+    <View
+      style={[
+        pal.border,
+        {borderBottomWidth: 1, paddingHorizontal: 20, paddingVertical: 14},
+      ]}>
+      <TouchableOpacity
+        testID={testID}
+        style={[styles.inviteCode]}
+        onPress={onPress}
+        accessibilityRole="button"
+        accessibilityLabel={
+          invitesAvailable === 1
+            ? 'Invite codes: 1 available'
+            : `Invite codes: ${invitesAvailable} available`
+        }
+        accessibilityHint="Opens list of invite codes">
+        <Text
+          testID={`${testID}-code`}
+          type={used ? 'md' : 'md-bold'}
+          style={used ? [pal.textLight, styles.strikeThrough] : pal.text}>
+          {invite.code}
+        </Text>
+        <View style={styles.flex1} />
+        {!used && invitesState.copiedInvites.includes(invite.code) && (
+          <Text style={[pal.textLight, styles.codeCopied]}>Copied</Text>
+        )}
+        {!used && (
+          <FontAwesomeIcon
+            icon={['far', 'clone']}
+            style={pal.text as FontAwesomeIconStyle}
+          />
+        )}
+      </TouchableOpacity>
+      {invite.uses.length > 0 ? (
+        <View
+          style={{
+            flexDirection: 'column',
+            gap: 8,
+            paddingTop: 6,
+          }}>
+          <Text style={pal.text}>Used by:</Text>
+          {invite.uses.map(use => (
+            <Link
+              key={use.usedBy}
+              href={makeProfileLink({handle: use.usedBy, did: ''})}
+              style={{
+                flexDirection: 'row',
+              }}>
+              <Text style={pal.text}>• </Text>
+              <UserInfoText did={use.usedBy} style={pal.link} />
+            </Link>
+          ))}
+        </View>
+      ) : null}
+    </View>
   )
 })
 
@@ -176,9 +210,6 @@ const styles = StyleSheet.create({
   inviteCode: {
     flexDirection: 'row',
     alignItems: 'center',
-    borderBottomWidth: 1,
-    paddingHorizontal: 20,
-    paddingVertical: 14,
   },
   codeCopied: {
     marginRight: 8,
-- 
cgit 1.4.1

