Skip to content

Commit

Permalink
[PAY-924][Desktop] DMs: Blocking/Unblocking Wire Up/UI (#3155)
Browse files Browse the repository at this point in the history
  • Loading branch information
rickyrombo authored Apr 5, 2023
1 parent 7038d81 commit 7e3d44c
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 28 deletions.
68 changes: 65 additions & 3 deletions packages/common/src/store/pages/chat/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Status } from 'models/Status'
import { getAccountUser, getUserId } from 'store/account/selectors'
import { setVisibility } from 'store/ui/modals/slice'

import { decodeHashId, encodeHashId } from '../../../utils'
import { decodeHashId, encodeHashId, removeNullable } from '../../../utils'
import { cacheUsersActions } from '../../cache'
import { getContext } from '../../effects'

Expand All @@ -33,7 +33,11 @@ const {
markChatAsReadFailed,
sendMessage,
sendMessageFailed,
addMessage
addMessage,
fetchBlockees,
fetchBlockeesSucceeded,
unblockUser,
blockUser
} = chatActions
const { getChatsSummary, getChat } = chatSelectors

Expand Down Expand Up @@ -257,6 +261,49 @@ function* fetchChatIfNecessary(args: { chatId: string }) {
}
}

function* doFetchBlockees() {
try {
const audiusSdk = yield* getContext('audiusSdk')
const sdk = yield* call(audiusSdk)
const { data } = yield* call([sdk.chats, sdk.chats.getBlockees])
yield* put(
fetchBlockeesSucceeded({
blockees: data
.map((encodedId) => decodeHashId(encodedId))
.filter(removeNullable)
})
)
} catch (e) {
console.error('fetchBlockeesFailed', e)
}
}

function* doBlockUser(action: ReturnType<typeof blockUser>) {
try {
const audiusSdk = yield* getContext('audiusSdk')
const sdk = yield* call(audiusSdk)
yield* call([sdk.chats, sdk.chats.block], {
userId: encodeHashId(action.payload.userId)
})
yield* put(fetchBlockees())
} catch (e) {
console.error('blockUserFailed', e)
}
}

function* doUnblockUser(action: ReturnType<typeof unblockUser>) {
try {
const audiusSdk = yield* getContext('audiusSdk')
const sdk = yield* call(audiusSdk)
yield* call([sdk.chats, sdk.chats.unblock], {
userId: encodeHashId(action.payload.userId)
})
yield* put(fetchBlockees())
} catch (e) {
console.error('unblockUserFailed', e)
}
}

function* watchAddMessage() {
yield takeEvery(addMessage, ({ payload }) => fetchChatIfNecessary(payload))
}
Expand Down Expand Up @@ -285,6 +332,18 @@ function* watchMarkChatAsRead() {
yield takeEvery(markChatAsRead, doMarkChatAsRead)
}

function* watchFetchBlockees() {
yield takeLatest(fetchBlockees, doFetchBlockees)
}

function* watchBlockUser() {
yield takeEvery(blockUser, doBlockUser)
}

function* watchUnblockUser() {
yield takeEvery(unblockUser, doUnblockUser)
}

export const sagas = () => {
return [
watchFetchChats,
Expand All @@ -293,6 +352,9 @@ export const sagas = () => {
watchCreateChat,
watchMarkChatAsRead,
watchSendMessage,
watchAddMessage
watchAddMessage,
watchFetchBlockees,
watchBlockUser,
watchUnblockUser
]
}
2 changes: 2 additions & 0 deletions packages/common/src/store/pages/chat/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const getOptimisticReads = (state: CommonState) =>
export const getOptimisticReactions = (state: CommonState) =>
state.pages.chat.optimisticReactions

export const getBlockees = (state: CommonState) => state.pages.chat.blockees

export const getChats = createSelector(
[selectAllChats, getOptimisticReads],
(chats, optimisticReads) => {
Expand Down
19 changes: 18 additions & 1 deletion packages/common/src/store/pages/chat/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type ChatState = {
optimisticReactions: Record<string, ChatMessageReaction>
optimisticChatRead: Record<string, UserChat>
activeChatId: string | null
blockees: ID[]
}

type SetMessageReactionPayload = {
Expand Down Expand Up @@ -81,7 +82,8 @@ const initialState: ChatState = {
messages: {},
optimisticChatRead: {},
optimisticReactions: {},
activeChatId: null
activeChatId: null,
blockees: []
}

const slice = createSlice({
Expand Down Expand Up @@ -340,6 +342,21 @@ const slice = createSlice({
},
disconnect: (_state, _action: Action) => {
// triggers middleware
},
fetchBlockees: (_state, _action: Action) => {
// triggers saga
},
fetchBlockeesSucceeded: (
state,
action: PayloadAction<{ blockees: ID[] }>
) => {
state.blockees = action.payload.blockees
},
blockUser: (_state, _action: PayloadAction<{ userId: ID }>) => {
// triggers saga
},
unblockUser: (_state, _action: PayloadAction<{ userId: ID }>) => {
// triggers saga
}
}
})
Expand Down
7 changes: 6 additions & 1 deletion packages/web/src/common/store/account/sagas.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
solanaSelectors,
createUserBankIfNeeded,
getContext,
FeatureFlags
FeatureFlags,
chatActions
} from '@audius/common'
import { call, put, fork, select, takeEvery } from 'redux-saga/effects'

Expand All @@ -22,6 +23,7 @@ import disconnectedWallets from './disconnected_wallet_fix.json'

const { fetchProfile } = profilePageActions
const { getFeePayer } = solanaSelectors
const { fetchBlockees } = chatActions

const {
getUserId,
Expand Down Expand Up @@ -256,6 +258,9 @@ function* cacheAccount(account) {
yield call([localStorage, 'setAudiusAccountUser'], account)

yield put(fetchAccountSucceeded(formattedAccount))

// Fetch user's chat blockee list after fetching their account
yield put(fetchBlockees())
}

// Pull from redux cache and persist to local storage cache
Expand Down
29 changes: 20 additions & 9 deletions packages/web/src/components/stat-banner/StatBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
IconKebabHorizontal,
IconMessage,
PopupMenu,
IconUnblockMessages
IconUnblockMessages,
IconBlockMessages
} from '@audius/stems'
import cn from 'classnames'

Expand Down Expand Up @@ -58,6 +59,9 @@ type StatsBannerProps = {
isSubscribed?: boolean
onToggleSubscribe?: () => void
onMessage?: () => void
onBlock?: () => void
onUnblock?: () => void
isBlocked?: boolean
}

export const StatBanner = (props: StatsBannerProps) => {
Expand All @@ -78,8 +82,11 @@ export const StatBanner = (props: StatsBannerProps) => {
onCancel,
onFollow,
onUnfollow,
onMessage,
following,
onMessage,
onBlock,
onUnblock,
isBlocked,
isSubscribed,
onToggleSubscribe
} = props
Expand Down Expand Up @@ -146,13 +153,17 @@ export const StatBanner = (props: StatsBannerProps) => {
onClick: onShare!,
icon: <IconShare />
},
{
text: messages.unblockMessages,
onClick: () => {
// TODO
},
icon: <IconUnblockMessages />
}
isBlocked
? {
text: messages.unblockMessages,
onClick: onUnblock!,
icon: <IconUnblockMessages />
}
: {
text: messages.blockMessages,
onClick: onBlock!,
icon: <IconBlockMessages />
}
]}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useCallback, useEffect } from 'react'
import {
accountSelectors,
chatActions,
chatSelectors,
tippingActions,
tippingSelectors,
User
Expand All @@ -12,6 +13,7 @@ import {
IconButton,
IconKebabHorizontal,
IconMessage,
IconUnblockMessages,
IconUser,
PopupMenu,
PopupPosition
Expand All @@ -29,7 +31,8 @@ const messages = {
moreOptions: 'More options',
message: 'Message This User',
visit: "Visit User's Profile",
block: 'Block Messages'
block: 'Block Messages',
unblock: 'Unblock Messages'
}

type UserResultComposeProps = {
Expand All @@ -41,7 +44,8 @@ const { getUserId } = accountSelectors
const { getOptimisticSupporters, getOptimisticSupporting } = tippingSelectors

const { fetchSupportersForUser } = tippingActions
const { createChat } = chatActions
const { createChat, blockUser, unblockUser } = chatActions
const { getBlockees } = chatSelectors

const renderTrigger = (
anchorRef: React.MutableRefObject<any>,
Expand All @@ -61,6 +65,8 @@ export const MessageUserSearchResult = (props: UserResultComposeProps) => {
const currentUserId = useSelector(getUserId)
const supportingMap = useSelector(getOptimisticSupporting)
const supportersMap = useSelector(getOptimisticSupporters)
const blockeeList = useSelector(getBlockees)
const isBlocked = blockeeList.includes(user.user_id)

const handleComposeClicked = useCallback(() => {
dispatch(createChat({ userIds: [user.user_id] }))
Expand All @@ -72,8 +78,12 @@ export const MessageUserSearchResult = (props: UserResultComposeProps) => {
}, [dispatch, user, closeModal])

const handleBlockClicked = useCallback(() => {
// TODO
}, [])
dispatch(blockUser({ userId: user.user_id }))
}, [dispatch, user])

const handleUnblockClicked = useCallback(() => {
dispatch(unblockUser({ userId: user.user_id }))
}, [dispatch, user])

const items = [
{
Expand All @@ -82,11 +92,17 @@ export const MessageUserSearchResult = (props: UserResultComposeProps) => {
onClick: handleComposeClicked
},
{ icon: <IconUser />, text: messages.visit, onClick: handleVisitClicked },
{
icon: <IconBlockMessages />,
text: messages.block,
onClick: handleBlockClicked
}
isBlocked
? {
icon: <IconUnblockMessages />,
text: messages.unblock,
onClick: handleUnblockClicked
}
: {
icon: <IconBlockMessages />,
text: messages.block,
onClick: handleBlockClicked
}
]

useEffect(() => {
Expand Down
Loading

0 comments on commit 7e3d44c

Please sign in to comment.