Move invite-state to new persistence + context and replace the notifications with just showing uses in the modal (#1840)
This commit is contained in:
parent
74f8390f1d
commit
e75b2d508b
12 changed files with 137 additions and 259 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue