-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
ee1fae8
commit 9f675c0
Showing
8 changed files
with
374 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
apps/audius-client/packages/mobile/src/assets/images/iconMessageLocked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
260 changes: 260 additions & 0 deletions
260
...client/packages/mobile/src/components/inbox-unavailable-drawer/InboxUnavailableDrawer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
import type { ReactNode } from 'react' | ||
import { useCallback, useMemo } from 'react' | ||
|
||
import type { User } from '@audius/common' | ||
import { | ||
chatSelectors, | ||
chatActions, | ||
tippingActions, | ||
cacheUsersSelectors, | ||
ChatPermissionAction | ||
} from '@audius/common' | ||
import { View } from 'react-native' | ||
import { useDispatch, useSelector } from 'react-redux' | ||
|
||
import IconMessageLocked from 'app/assets/images/iconMessageLocked.svg' | ||
import IconTip from 'app/assets/images/iconTip.svg' | ||
import { Text, Button } from 'app/components/core' | ||
import { NativeDrawer } from 'app/components/drawer' | ||
import { useNavigation } from 'app/hooks/useNavigation' | ||
import { getData } from 'app/store/drawers/selectors' | ||
import { setVisibility } from 'app/store/drawers/slice' | ||
import { makeStyles, flexRowCentered } from 'app/styles' | ||
import { useColor } from 'app/utils/theme' | ||
|
||
import { UserBadges } from '../user-badges' | ||
|
||
const { unblockUser } = chatActions | ||
const { getCanChat } = chatSelectors | ||
const { getUser } = cacheUsersSelectors | ||
const { beginTip } = tippingActions | ||
|
||
const INBOX_UNAVAILABLE_MODAL_NAME = 'InboxUnavailable' | ||
|
||
const messages = { | ||
title: 'Inbox Unavailable', | ||
blockee: 'You cannot send messages to users you have blocked.', | ||
tipGated: (displayName: ReactNode) => ( | ||
<> | ||
{'You must send '} | ||
{displayName} | ||
{' a tip before you can send them messages.'} | ||
</> | ||
), | ||
noAction: 'You can no longer send messages to ', | ||
info: 'This will not affect their ability to view your profile or interact with your content.', | ||
unblockUser: 'Unblock User', | ||
learnMore: 'Learn More', | ||
sendAudio: 'Send $AUDIO', | ||
cancel: 'Cancel' | ||
} | ||
|
||
const useStyles = makeStyles(({ spacing, typography, palette }) => ({ | ||
drawer: { | ||
marginTop: spacing(2), | ||
marginBottom: spacing(5), | ||
padding: spacing(3.5), | ||
gap: spacing(4) | ||
}, | ||
titleContainer: { | ||
...flexRowCentered(), | ||
gap: spacing(3.5), | ||
alignSelf: 'center' | ||
}, | ||
title: { | ||
fontSize: typography.fontSize.xl, | ||
fontFamily: typography.fontByWeight.heavy, | ||
color: palette.neutralLight2, | ||
textTransform: 'uppercase', | ||
lineHeight: typography.fontSize.xl * 1.25 | ||
}, | ||
infoContainer: { | ||
display: 'flex', | ||
flexDirection: 'row', | ||
alignItems: 'center', | ||
gap: spacing(4.5), | ||
paddingVertical: spacing(2), | ||
paddingHorizontal: spacing(4), | ||
backgroundColor: palette.neutralLight9, | ||
borderWidth: 1, | ||
borderColor: palette.neutralLight7, | ||
borderRadius: spacing(2) | ||
}, | ||
callToActionText: { | ||
color: palette.neutral, | ||
fontSize: typography.fontSize.large, | ||
fontFamily: typography.fontByWeight.medium, | ||
lineHeight: typography.fontSize.large * 1.3, | ||
textAlign: 'center' | ||
}, | ||
button: { | ||
padding: spacing(4), | ||
height: spacing(12) | ||
}, | ||
buttonText: { | ||
color: palette.neutral, | ||
fontSize: typography.fontSize.large, | ||
fontFamily: typography.fontByWeight.bold | ||
}, | ||
buttonTextWhite: { | ||
color: palette.white | ||
}, | ||
border: { | ||
borderBottomWidth: 1, | ||
borderBottomColor: palette.neutralLight8 | ||
} | ||
})) | ||
|
||
const mapActionToContent = ( | ||
callToAction: ChatPermissionAction, | ||
styles: ReturnType<typeof useStyles>, | ||
user: User | null | ||
) => { | ||
switch (callToAction) { | ||
case ChatPermissionAction.NONE: | ||
return ( | ||
<> | ||
{messages.noAction} | ||
{user ? ( | ||
<UserBadges | ||
user={user} | ||
nameStyle={styles.callToActionText} | ||
as={Text} | ||
/> | ||
) : null} | ||
</> | ||
) | ||
case ChatPermissionAction.TIP: | ||
return ( | ||
<> | ||
{messages.tipGated( | ||
user ? ( | ||
<UserBadges | ||
user={user} | ||
nameStyle={styles.callToActionText} | ||
as={Text} | ||
/> | ||
) : null | ||
)} | ||
</> | ||
) | ||
case ChatPermissionAction.UNBLOCK: | ||
return <>{messages.blockee}</> | ||
default: | ||
return null | ||
} | ||
} | ||
|
||
export const InboxUnavailableDrawer = () => { | ||
const dispatch = useDispatch() | ||
const navigation = useNavigation() | ||
const styles = useStyles() | ||
const neutralLight2 = useColor('neutralLight2') | ||
|
||
const { userId } = useSelector((state) => getData<'InboxUnavailable'>(state)) | ||
const user = useSelector((state) => getUser(state, { id: userId })) | ||
const { callToAction } = useSelector((state) => getCanChat(state, userId)) | ||
|
||
const closeDrawer = useCallback(() => { | ||
dispatch( | ||
setVisibility({ | ||
drawer: 'InboxUnavailable', | ||
visible: false | ||
}) | ||
) | ||
}, [dispatch]) | ||
|
||
const handleUnblockPress = useCallback(() => { | ||
dispatch(unblockUser({ userId })) | ||
closeDrawer() | ||
}, [dispatch, userId, closeDrawer]) | ||
|
||
const handleLearnMorePress = useCallback(() => { | ||
// TODO: Link to blog | ||
closeDrawer() | ||
}, [closeDrawer]) | ||
|
||
const handleTipPress = useCallback(() => { | ||
dispatch(beginTip({ user, source: 'profile' })) | ||
navigation.navigate('TipArtist') | ||
closeDrawer() | ||
}, [closeDrawer, dispatch, navigation, user]) | ||
|
||
const actionToButtonsMap = useMemo(() => { | ||
return { | ||
[ChatPermissionAction.NONE]: [ | ||
{ | ||
buttonTitle: messages.learnMore, | ||
buttonPress: handleLearnMorePress, | ||
buttonVariant: 'common' | ||
} | ||
], | ||
[ChatPermissionAction.TIP]: [ | ||
{ | ||
buttonTitle: messages.sendAudio, | ||
buttonPress: handleTipPress, | ||
buttonVariant: 'primary', | ||
buttonIcon: IconTip, | ||
buttonTextStyle: styles.buttonTextWhite | ||
} | ||
], | ||
[ChatPermissionAction.UNBLOCK]: [ | ||
{ | ||
buttonTitle: messages.unblockUser, | ||
buttonPress: handleUnblockPress, | ||
buttonVariant: 'primary', | ||
buttonTextStyle: styles.buttonTextWhite | ||
}, | ||
{ | ||
buttonTitle: messages.cancel, | ||
buttonPress: closeDrawer, | ||
buttonVariant: 'common' | ||
} | ||
] | ||
} | ||
}, [ | ||
handleLearnMorePress, | ||
handleTipPress, | ||
styles.buttonTextWhite, | ||
handleUnblockPress, | ||
closeDrawer | ||
]) | ||
|
||
const content = mapActionToContent(callToAction, styles, user) | ||
|
||
return ( | ||
<NativeDrawer drawerName={INBOX_UNAVAILABLE_MODAL_NAME}> | ||
<View style={styles.drawer}> | ||
<View style={styles.titleContainer}> | ||
<IconMessageLocked fill={neutralLight2} /> | ||
<Text style={styles.title}>{messages.title}</Text> | ||
</View> | ||
<View style={styles.border} /> | ||
<Text style={styles.callToActionText}>{content}</Text> | ||
{actionToButtonsMap[callToAction].map( | ||
({ | ||
buttonTitle, | ||
buttonPress, | ||
buttonVariant, | ||
buttonIcon, | ||
buttonTextStyle | ||
}) => ( | ||
<Button | ||
key={buttonTitle} | ||
title={buttonTitle} | ||
onPress={buttonPress} | ||
variant={buttonVariant} | ||
icon={buttonIcon} | ||
iconPosition='left' | ||
styles={{ | ||
root: styles.button, | ||
text: [styles.buttonText, buttonTextStyle] | ||
}} | ||
fullWidth | ||
/> | ||
) | ||
)} | ||
</View> | ||
</NativeDrawer> | ||
) | ||
} |
1 change: 1 addition & 0 deletions
1
apps/audius-client/packages/mobile/src/components/inbox-unavailable-drawer/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './InboxUnavailableDrawer' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
apps/audius-client/packages/mobile/src/screens/profile-screen/MessageLockedButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { useCallback } from 'react' | ||
|
||
import type { User } from '@audius/common' | ||
import { useDispatch } from 'react-redux' | ||
|
||
import IconMessageLocked from 'app/assets/images/iconMessageLocked.svg' | ||
import { Button } from 'app/components/core' | ||
import { setVisibility } from 'app/store/drawers/slice' | ||
import { makeStyles } from 'app/styles' | ||
|
||
const messages = { | ||
inboxUnavailable: 'Inbox Unavailable' | ||
} | ||
|
||
const useStyles = makeStyles(({ palette, spacing }) => ({ | ||
root: { | ||
paddingHorizontal: 0, | ||
height: spacing(8), | ||
width: spacing(8), | ||
marginRight: spacing(2), | ||
borderColor: palette.neutralLight4 | ||
} | ||
})) | ||
|
||
type MessageLockedButtonProps = { | ||
profile: Pick<User, 'user_id'> | ||
} | ||
|
||
export const MessageLockedButton = (props: MessageLockedButtonProps) => { | ||
const styles = useStyles() | ||
const { profile } = props | ||
const { user_id: userId } = profile | ||
const dispatch = useDispatch() | ||
|
||
const handlePress = useCallback(() => { | ||
dispatch( | ||
setVisibility({ | ||
drawer: 'InboxUnavailable', | ||
visible: true, | ||
data: { userId } | ||
}) | ||
) | ||
}, [dispatch, userId]) | ||
|
||
return ( | ||
<Button | ||
style={styles.root} | ||
noText | ||
title={messages.inboxUnavailable} | ||
icon={IconMessageLocked} | ||
variant={'common'} | ||
size='small' | ||
onPress={handlePress} | ||
/> | ||
) | ||
} |
Oops, something went wrong.