Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

[PAY-1464] DMs: Go to chat after successful tip #3625

Merged
merged 5 commits into from
Jun 21, 2023
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/store/pages/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * as chatSelectors from './selectors'
export { sagas as chatSagas } from './sagas'
export { chatMiddleware } from './middleware'
export * from './types'
export { makeChatId } from './utils'
22 changes: 9 additions & 13 deletions packages/common/src/store/pages/chat/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ulid } from 'ulid'
import { ID } from 'models/Identifiers'
import { Status } from 'models/Status'
import { getAccountUser, getUserId } from 'store/account/selectors'
import { toastActions } from 'store/index'
import { makeChatId, toastActions } from 'store/index'

import { decodeHashId, encodeHashId, removeNullable } from '../../../utils'
import { cacheUsersActions } from '../../cache'
Expand Down Expand Up @@ -205,7 +205,7 @@ function* doSetMessageReaction(action: ReturnType<typeof setMessageReaction>) {
}

function* doCreateChat(action: ReturnType<typeof createChat>) {
const { userIds } = action.payload
const { userIds, skipNavigation } = action.payload
try {
const audiusSdk = yield* getContext('audiusSdk')
const sdk = yield* call(audiusSdk)
Expand All @@ -214,23 +214,19 @@ function* doCreateChat(action: ReturnType<typeof createChat>) {
throw new Error('User not found')
}
// Try to get existing chat:
const chatId = [currentUserId, ...userIds]
.map((id) => encodeHashId(id))
.sort()
.join(':')
const chatId = makeChatId([currentUserId, ...userIds])

// Optimistically navigate - if we fail we'll toast
yield* put(goToChat({ chatId }))
// Optimistically go to the chat. If we fail to create it, we'll toast
if (!skipNavigation) {
yield* put(goToChat({ chatId }))
}

try {
yield* call(doFetchChatIfNecessary, { chatId })
} catch {}
const existingChat = yield* select((state) => getChat(state, chatId))
if (existingChat) {
// Simply navigate to the existing chat
yield* put(goToChat({ chatId: existingChat.chat_id }))
} else {
// Create new chat and navigate to it
if (!existingChat) {
// Create new chat
yield* call([sdk.chats, sdk.chats.create], {
userId: encodeHashId(currentUserId),
invitedUserIds: userIds.map((id) => encodeHashId(id))
Expand Down
5 changes: 4 additions & 1 deletion packages/common/src/store/pages/chat/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ const slice = createSlice({
name: 'application/pages/chat',
initialState,
reducers: {
createChat: (_state, _action: PayloadAction<{ userIds: ID[] }>) => {
createChat: (
_state,
_action: PayloadAction<{ userIds: ID[]; skipNavigation?: boolean }>
) => {
// triggers saga
},
createChatSucceeded: (state, action: PayloadAction<{ chat: UserChat }>) => {
Expand Down
6 changes: 6 additions & 0 deletions packages/common/src/store/pages/chat/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ID } from 'models/Identifiers'
import { encodeHashId } from 'utils/hashIds'

export const makeChatId = (userIds: ID[]) => {
return userIds.map(encodeHashId).sort().join(':')
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const DrawerContent = () => {
}, [closeDrawer])

const handleTipPress = useCallback(() => {
dispatch(beginTip({ user, source: 'profile' }))
dispatch(beginTip({ user, source: 'inboxUnavailableModal' }))
navigation.navigate('TipArtist')
closeDrawer()
}, [closeDrawer, dispatch, navigation, user])
Expand Down
24 changes: 21 additions & 3 deletions packages/mobile/src/screens/tip-artist-screen/TipSentScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import { useCallback } from 'react'

import type { SolanaWalletAddress } from '@audius/common'
import {
makeChatId,
chatActions,
formatNumberCommas,
accountSelectors,
tippingSelectors
} from '@audius/common'
import { useNavigation } from '@react-navigation/native'
import { Platform } from 'react-native'
import { useSelector } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'

import IconCheck from 'app/assets/images/iconCheck.svg'
import IconRemove from 'app/assets/images/iconRemove.svg'
Expand Down Expand Up @@ -48,6 +50,7 @@ const useStyles = makeStyles(({ spacing }) => ({
}))

export const TipSentScreen = () => {
const dispatch = useDispatch()
const account = useSelector(getAccountUser)
const {
user: recipient,
Expand Down Expand Up @@ -78,8 +81,23 @@ export const TipSentScreen = () => {
}

const handleClose = useCallback(() => {
navigation.getParent()?.goBack()
}, [navigation])
// After success + close, take the user to the chat they were
// attempting to make if they were unlocking DMs by tipping.
// The saga will create the chat once the tip is confirmed
if (
source === 'inboxUnavailableModal' &&
account?.user_id &&
recipient?.user_id
) {
dispatch(
chatActions.goToChat({
chatId: makeChatId([account.user_id, recipient.user_id])
})
)
} else {
navigation.getParent()?.goBack()
}
}, [account?.user_id, dispatch, navigation, recipient?.user_id, source])

return (
<TipScreen
Expand Down
15 changes: 13 additions & 2 deletions packages/web/src/common/store/tipping/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,23 @@ function* sendTipAsync() {
source
})
)
yield put(refreshTipGatedTracks({ userId: recipient.user_id, trackId }))
yield fork(function* () {

yield* put(refreshTipGatedTracks({ userId: recipient.user_id, trackId }))
yield* fork(function* () {
yield* call(confirmTipIndexed, { sender, recipient })
yield* put(
fetchPermissions({ userIds: [sender.user_id, recipient.user_id] })
)
if (source === 'inboxUnavailableModal') {
console.debug('Creating chat silently...')
// Create the chat but don't navigate
yield* put(
chatActions.createChat({
userIds: [recipient.user_id],
skipNavigation: true
rickyrombo marked this conversation as resolved.
Show resolved Hide resolved
})
)
}
})

/**
Expand Down
26 changes: 23 additions & 3 deletions packages/web/src/components/tipping/tip-audio/TipAudioModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
tippingActions,
TippingSendStatus,
walletActions,
StringKeys
StringKeys,
chatActions,
accountSelectors,
makeChatId
} from '@audius/common'
import { Modal, ModalHeader, ModalTitle } from '@audius/stems'
import cn from 'classnames'
Expand All @@ -26,7 +29,7 @@ import styles from './TipAudio.module.css'
import { TipSent } from './TipSent'
const { getBalance } = walletActions
const { resetSend } = tippingActions
const { getSendStatus } = tippingSelectors
const { getSendStatus, getSendTipData } = tippingSelectors

const messages = {
sendATip: 'Send Tip',
Expand Down Expand Up @@ -111,14 +114,31 @@ export const TipAudioModal = () => {
const dispatch = useDispatch()
const sendStatus = useSelector(getSendStatus)
const previousSendStatus = usePrevious(sendStatus)
const { user: recipient, source } = useSelector(getSendTipData)
const currentUserId = useSelector(accountSelectors.getUserId)

const audioFeaturesDegradedText = useRemoteVar(
StringKeys.AUDIO_FEATURES_DEGRADED_TEXT
)

const onClose = useCallback(() => {
// After success + close, take the user to the chat they were
// attempting to make if they were unlocking DMs by tipping.
// The saga will create the chat once the tip is confirmed
if (
source === 'inboxUnavailableModal' &&
sendStatus === 'SUCCESS' &&
recipient?.user_id &&
currentUserId
) {
dispatch(
chatActions.goToChat({
chatId: makeChatId([currentUserId, recipient.user_id])
})
)
}
dispatch(resetSend())
}, [dispatch])
}, [currentUserId, dispatch, recipient?.user_id, sendStatus, source])

useEffect(() => {
if (sendStatus !== null) {
Expand Down