Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAY-3220] Inbox unavailable UI for new chat permissions #10012

Merged
merged 4 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/common/src/models/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ export enum FavoriteSource {
NAVIGATOR = 'navigator'
}
export enum FollowSource {
INBOX_UNAVAILABLE_MODAL = 'inbox unavailable modal',
PROFILE_PAGE = 'profile page',
TRACK_PAGE = 'track page',
COLLECTION_PAGE = 'collection page',
Expand Down
6 changes: 5 additions & 1 deletion packages/common/src/store/pages/chat/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,12 @@ export const getCanCreateChat = createSelector(
action = ChatPermissionAction.WAIT
} else if (blockees.includes(user.user_id)) {
action = ChatPermissionAction.UNBLOCK
} else if (userPermissions.permits === ChatPermission.TIPPERS) {
} else if (userPermissions.permit_list.includes(ChatPermission.TIPPERS)) {
action = ChatPermissionAction.TIP
} else if (
userPermissions.permit_list.includes(ChatPermission.FOLLOWERS)
) {
action = ChatPermissionAction.FOLLOW
} else {
action = ChatPermissionAction.NONE
}
Expand Down
2 changes: 2 additions & 0 deletions packages/common/src/store/pages/chat/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export enum ChatPermissionAction {
NONE,
/** Current user can tip user */
TIP,
/** Current user can follow user */
FOLLOW,
/** Current user can unblock user */
UNBLOCK,
/** User is signed out and needs to sign in */
Expand Down
8 changes: 5 additions & 3 deletions packages/common/src/store/social/users/actions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Action } from '@reduxjs/toolkit'
import { createCustomAction } from 'typesafe-actions'

import { FollowSource, ShareSource } from '../../../models/Analytics'
Expand All @@ -22,13 +23,14 @@ export const followUser = createCustomAction(
(
userId: ID,
source: FollowSource,
trackId?: ID // in case the user is following the artist from a gated track page / modal
) => ({ userId, source, trackId })
trackId?: ID, // in case the user is following the artist from a gated track page / modal
onSuccessActions?: Action[]
) => ({ userId, source, trackId, onSuccessActions })
)

export const followUserSucceeded = createCustomAction(
FOLLOW_USER_SUCCEEDED,
(userId: ID) => ({ userId })
(userId: ID, onSuccessActions?: Action[]) => ({ userId, onSuccessActions })
)

export const followUserFailed = createCustomAction(
Expand Down
4 changes: 4 additions & 0 deletions packages/harmony/src/assets/icons/MessageSlash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/harmony/src/icons/utilityIcons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import IconMerchSVG from '../assets/icons/Merch.svg'
import IconMessageSVG from '../assets/icons/Message.svg'
import IconMessageBlockSVG from '../assets/icons/MessageBlock.svg'
import IconMessageLockedSVG from '../assets/icons/MessageLocked.svg'
import IconMessageSlashSVG from '../assets/icons/MessageSlash.svg'
import IconMessageUnblockSVG from '../assets/icons/MessageUnblock.svg'
import IconMessagesSVG from '../assets/icons/Messages.svg'
import IconMinusSVG from '../assets/icons/Minus.svg'
Expand Down Expand Up @@ -204,6 +205,7 @@ export const IconMessage = IconMessageSVG as IconComponent
export const IconStar = IconStarSVG as IconComponent
export const IconCastAirplay = IconCastAirplaySVG as IconComponent
export const IconMessageBlock = IconMessageBlockSVG as IconComponent
export const IconMessageSlash = IconMessageSlashSVG as IconComponent
export const IconStars = IconStarsSVG as IconComponent
export const IconCastChromecast = IconCastChromecastSVG as IconComponent
export const IconMessageLocked = IconMessageLockedSVG as IconComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { View } from 'react-native'
import { useDispatch, useSelector } from 'react-redux'

import { IconMessageBlock, IconInfo, Button } from '@audius/harmony-native'
import { IconMessageSlash, IconInfo, Button } from '@audius/harmony-native'
import { Text } from 'app/components/core'
import { NativeDrawer } from 'app/components/drawer'
import { useDrawer } from 'app/hooks/useDrawer'
Expand Down Expand Up @@ -158,7 +158,7 @@ export const BlockMessagesDrawer = () => {
<NativeDrawer drawerName={BLOCK_MESSAGES_MODAL_NAME}>
<View style={styles.drawer}>
<View style={styles.titleContainer}>
<IconMessageBlock fill={neutralLight2} />
<IconMessageSlash fill={neutralLight2} />
<Text style={styles.title}>{messages.title}</Text>
</View>
<Text style={styles.confirm}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ReactNode } from 'react'
import { useCallback } from 'react'

import { FollowSource } from '@audius/common/models'
import {
accountSelectors,
cacheUsersSelectors,
Expand All @@ -9,9 +10,11 @@ import {
makeChatId,
ChatPermissionAction,
tippingActions,
useInboxUnavailableModal
useInboxUnavailableModal,
usersSocialActions
} from '@audius/common/store'
import { CHAT_BLOG_POST_URL } from '@audius/common/utils'
import type { Action } from '@reduxjs/toolkit'
import { View } from 'react-native'
import { useDispatch, useSelector } from 'react-redux'

Expand All @@ -23,6 +26,7 @@ import { makeStyles, flexRowCentered } from 'app/styles'
import { useColor } from 'app/utils/theme'

import { UserBadges } from '../user-badges'
const { followUser } = usersSocialActions

const { unblockUser, createChat } = chatActions
const { getCanCreateChat } = chatSelectors
Expand All @@ -38,11 +42,19 @@ const messages = {
{' a tip before you can send them messages.'}
</>
),
followRequired: (displayName: ReactNode) => (
<>
{'You must follow '}
{displayName}
{' before you can send them messages.'}
</>
),
noAction: "You can't 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',
follow: 'Follow',
cancel: 'Cancel'
}

Expand Down Expand Up @@ -157,6 +169,25 @@ const DrawerContent = ({ data, onClose }: DrawerContentProps) => {
onClose()
}, [onClose, currentUserId, dispatch, navigation, user, presetMessage])

const handleFollowPress = useCallback(() => {
if (userId) {
const followSuccessActions: Action[] = [
chatActions.createChat({
userIds: [userId]
})
]
dispatch(
followUser(
userId,
FollowSource.INBOX_UNAVAILABLE_MODAL,
undefined,
followSuccessActions
)
)
}
onClose()
}, [userId, dispatch, onClose])

switch (callToAction) {
case ChatPermissionAction.NONE:
return (
Expand Down Expand Up @@ -206,6 +237,30 @@ const DrawerContent = ({ data, onClose }: DrawerContentProps) => {
</Button>
</>
)
case ChatPermissionAction.FOLLOW:
return (
<>
<Text style={styles.callToActionText}>
{messages.followRequired(
user ? (
<UserBadges
user={user}
nameStyle={styles.callToActionText}
as={Text}
/>
) : null
)}
</Text>
<Button
key={messages.follow}
onPress={handleFollowPress}
variant='primary'
fullWidth
>
{messages.follow}
</Button>
</>
)
case ChatPermissionAction.UNBLOCK:
return (
<>
Expand Down
1 change: 1 addition & 0 deletions packages/mobile/src/harmony-native/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export { default as IconMerch } from '@audius/harmony/src/assets/icons/Merch.svg
export { default as IconStar } from '@audius/harmony/src/assets/icons/Star.svg'
export { default as IconCastAirplay } from '@audius/harmony/src/assets/icons/CastAirplay.svg'
export { default as IconMessageBlock } from '@audius/harmony/src/assets/icons/MessageBlock.svg'
export { default as IconMessageSlash } from '@audius/harmony/src/assets/icons/MessageSlash.svg'
export { default as IconStars } from '@audius/harmony/src/assets/icons/Stars.svg'
export { default as IconCastChromecast } from '@audius/harmony/src/assets/icons/CastChromecast.svg'
export { default as IconMessageLocked } from '@audius/harmony/src/assets/icons/MessageLocked.svg'
Expand Down
6 changes: 4 additions & 2 deletions packages/mobile/src/screens/chat-screen/ChatUserListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { View, TouchableOpacity, Keyboard } from 'react-native'
import { useDispatch } from 'react-redux'

import {
IconMessageBlock,
IconMessageSlash,
IconKebabHorizontal,
IconUser
} from '@audius/harmony-native'
Expand All @@ -34,6 +34,7 @@ const messages = {
followers: 'Followers',
ctaNone: 'Cannot Be Messaged',
ctaTip: 'Send a Tip To Message',
ctaFollow: 'Follow to Message',
ctaBlock: 'Blocked'
}

Expand Down Expand Up @@ -134,6 +135,7 @@ const useStyles = makeStyles(({ spacing, palette, typography }) => ({

const ctaToTextMap: Record<ChatPermissionAction, string> = {
[ChatPermissionAction.TIP]: messages.ctaTip,
[ChatPermissionAction.FOLLOW]: messages.ctaFollow,
[ChatPermissionAction.UNBLOCK]: messages.ctaBlock,
[ChatPermissionAction.NONE]: messages.ctaNone,
[ChatPermissionAction.WAIT]: messages.ctaNone,
Expand Down Expand Up @@ -252,7 +254,7 @@ export const ChatUserListItem = ({
</>
) : (
<View style={styles.ctaContainer}>
<IconMessageBlock
<IconMessageSlash
fill={styles.iconBlock.fill}
width={styles.iconBlock.width}
height={styles.iconBlock.height}
Expand Down
42 changes: 38 additions & 4 deletions packages/web/src/common/store/social/users/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
confirmTransaction
} from '@audius/common/store'
import { makeKindId, route } from '@audius/common/utils'
import { Action } from '@reduxjs/toolkit'
import { call, select, takeEvery, put } from 'typed-redux-saga'

import { make } from 'common/store/analytics/actions'
Expand Down Expand Up @@ -84,7 +85,12 @@ export function* followUser(
const event = make(Name.FOLLOW, { id: action.userId, source: action.source })
yield* put(event)

yield* call(confirmFollowUser, action.userId, accountId)
yield* call(
confirmFollowUser,
action.userId,
accountId,
action.onSuccessActions
)
yield* put(
setNotificationSubscription(
action.userId,
Expand All @@ -94,7 +100,11 @@ export function* followUser(
)
}

export function* confirmFollowUser(userId: ID, accountId: ID) {
export function* confirmFollowUser(
userId: ID,
accountId: ID,
onSuccessActions?: Action[]
) {
const audiusBackendInstance = yield* getContext('audiusBackendInstance')
yield* put(
confirmerActions.requestConfirmation(
Expand All @@ -117,7 +127,7 @@ export function* confirmFollowUser(userId: ID, accountId: ID) {
return accountId
},
function* () {
yield* put(socialActions.followUserSucceeded(userId))
yield* put(socialActions.followUserSucceeded(userId, onSuccessActions))
},
function* ({ timeout, message }: { timeout: boolean; message: string }) {
yield* put(
Expand Down Expand Up @@ -152,6 +162,24 @@ export function* confirmFollowUser(userId: ID, accountId: ID) {
)
}

export function* watchFollowUserSucceeded() {
yield* takeEvery(socialActions.FOLLOW_USER_SUCCEEDED, followUserSucceeded)
}

export function* followUserSucceeded(
action: ReturnType<typeof socialActions.followUserSucceeded>
) {
const { onSuccessActions } = action
// Do any callbacks
if (onSuccessActions) {
// Spread here to unfreeze the action
// Redux sagas can't "put" frozen actions
for (const onSuccessAction of onSuccessActions) {
yield* put({ ...onSuccessAction })
}
}
}

export function* watchUnfollowUser() {
yield* takeEvery(socialActions.UNFOLLOW_USER, unfollowUser)
}
Expand Down Expand Up @@ -434,7 +462,13 @@ export function* watchShareUser() {
}

const sagas = () => {
return [watchFollowUser, watchUnfollowUser, watchShareUser, errorSagas]
return [
watchFollowUser,
watchUnfollowUser,
watchFollowUserSucceeded,
watchShareUser,
errorSagas
]
}

export default sagas
2 changes: 1 addition & 1 deletion packages/web/src/common/store/social/users/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('follow', () => {
fieldName: 'followee_count',
delta: 1
})
.call(sagas.confirmFollowUser, 2, 1)
.call(sagas.confirmFollowUser, 2, 1, undefined)
.put(
cacheActions.update(Kind.USERS, [
{
Expand Down
Loading