From 898463d305ca14eb8c90663af9956617f5b5c617 Mon Sep 17 00:00:00 2001 From: cha0s Date: Mon, 20 Jul 2020 19:24:55 -0500 Subject: [PATCH] flow: user ops --- src/client/chat--leftFriends.jsx | 8 +- src/client/chat--rightBlocked.jsx | 1 + src/client/chat--rightUsers.jsx | 125 +++++++++++++++++++++++------- src/client/dispatcher.jsx | 13 ++-- src/client/store/effects.js | 5 +- src/common/state/user.js | 15 +++- src/server/sockets.js | 5 +- 7 files changed, 131 insertions(+), 41 deletions(-) diff --git a/src/client/chat--leftFriends.jsx b/src/client/chat--leftFriends.jsx index ad9bd7e..3ae9316 100644 --- a/src/client/chat--leftFriends.jsx +++ b/src/client/chat--leftFriends.jsx @@ -77,12 +77,12 @@ export default function ChatLeftFriends() { const favoritesActions = [ { icon: '👎', - label: 'Deny', + label: 'Deny friend request', onClick: () => dispatch(submitRemoveFriend(adderId)), }, { icon: '👍', - label: 'Confirm', + label: 'Confirm friend request', onClick: () => dispatch(submitAddFriend({ addeeId, adderId, @@ -95,7 +95,7 @@ export default function ChatLeftFriends() { className="friends__item" > channelUsersSelector(state, channel)); const redditUsername = useSelector(redditUsernameSelector); const usernames = useSelector(usernamesSelector); - const list = ids.map((id) => usernames[id]).sort(); + const list = ids + .map((id) => [id, usernames[id]]) + .sort((l, r) => (l[1] < r[1] ? -1 : 1)); return (

Who's here

    - {list.map((username) => { - const isLinked = ( - redditUsername !== username - && '/r/anonymous' !== channel - ); + {list.map(([id, username]) => { + const hasBlocked = -1 !== blocked.indexOf(id); + const isAnonymous = '/r/anonymous' === channel; + const isSelf = redditUsername === username; + const index = friendshipIdIndex(friendship, id); + const hasFriendship = -1 !== index; const userActions = []; - if (isLinked) { - userActions.push({ - icon: '➕', - label: 'Add friend', - onClick: () => {}, - }); - userActions.push({ - icon: '☢️', - label: 'Block', - onClick: () => {}, - }); + if (!isAnonymous && !isSelf) { + if (hasFriendship) { + if ('active' === friendship[index].status) { + userActions.push({ + icon: '🚫', + label: 'Unfriend', + onClick: () => dispatch(submitRemoveFriend(id)), + }); + if (-1 === favoriteUsers.indexOf(username)) { + userActions.push({ + icon: '❤️', + label: 'Favorite', + onClick: () => dispatch(submitAddFavorite(`/u/${username}`)), + }); + } + else { + userActions.push({ + icon: '💔', + label: 'Unfavorite', + onClick: () => dispatch(submitRemoveFavorite(`/u/${username}`)), + }); + } + } + else if (friendship[index].adderId !== userId) { + userActions.push({ + icon: '👎', + label: 'Deny friend request', + onClick: () => dispatch(submitRemoveFriend(id)), + }); + const {addeeId, adderId} = friendship[index]; + userActions.push({ + icon: '👍', + label: 'Confirm friend request', + onClick: () => dispatch(submitAddFriend({ + adderId, + addeeId, + nameOrStatus: username, + })), + }); + } + } + else if (!hasBlocked) { + userActions.push({ + icon: '➕', + label: 'Add friend', + onClick: () => dispatch(submitAddFriend({nameOrStatus: username})), + }); + } + if (hasBlocked) { + userActions.push({ + icon: '😶', + label: 'Unblock', + onClick: () => dispatch(submitUnblock(id)), + }); + } + else { + userActions.push({ + icon: '☢️', + label: 'Block', + onClick: () => dispatch(submitBlock(id)), + }); + } } - // { - // icon: '❤️', - // label: 'Favorite', - // onClick: () => {}, - // }, return (
  • diff --git a/src/client/dispatcher.jsx b/src/client/dispatcher.jsx index 6ac3780..26184b6 100644 --- a/src/client/dispatcher.jsx +++ b/src/client/dispatcher.jsx @@ -20,6 +20,7 @@ import { block, confirmFriendship, friendshipIndex, + idSelector, pendingFriendshipSelector, removeFromFavorites, removeFriendship, @@ -30,6 +31,7 @@ import useSocket from './hooks/useSocket'; export default function Dispatcher({children}) { const dispatch = useDispatch(); + const id = useSelector(idSelector); const pendingFriendship = useSelector(pendingFriendshipSelector); useSocket((socket) => { const onPacket = (packet) => { @@ -38,13 +40,14 @@ export default function Dispatcher({children}) { const hasPendingFriendship = -1 !== friendshipIndex(pendingFriendship, packet.data); const friendship = { ...( - hasPendingFriendship - ? {addeeId: adderId, adderId: addeeId, status: nameOrStatus} - : {adderId, addeeId, status: nameOrStatus} + (hasPendingFriendship && id === addeeId) + ? {addeeId: adderId, adderId: addeeId} + : {adderId, addeeId} ), status: nameOrStatus, }; - dispatch((hasPendingFriendship ? confirmFriendship : addFriendship)(friendship)); + const creator = hasPendingFriendship ? confirmFriendship : addFriendship; + dispatch(creator(friendship)); } if (packet instanceof Block) { dispatch(block(packet.data)); @@ -72,7 +75,7 @@ export default function Dispatcher({children}) { socket.on('disconnect', () => socket.off('packet', onPacket)); socket.on('reconnect', () => socket.on('packet', onPacket)); return () => socket.off('packet', onPacket); - }); + }, [pendingFriendship]); return <>{children}; } diff --git a/src/client/store/effects.js b/src/client/store/effects.js index f71d541..1e166f1 100644 --- a/src/client/store/effects.js +++ b/src/client/store/effects.js @@ -65,8 +65,9 @@ const effects = { return; } dispatch((hasFriendship ? confirmFriendship : addFriendship)({ - addeeId: hasFriendship ? userId : id, - adderId: hasFriendship ? id : userId, + addeeId: id, + adderId: userId, + ...(hasFriendship ? payload : {}), status: hasFriendship ? 'active' : 'pending', })); }); diff --git a/src/common/state/user.js b/src/common/state/user.js index e4b1697..3f43f84 100644 --- a/src/common/state/user.js +++ b/src/common/state/user.js @@ -40,6 +40,11 @@ export const friendshipIndex = (friendship, test) => ( .findIndex(({addeeId, adderId}) => test.adderId === adderId && test.addeeId === addeeId) ); +export const friendshipIdIndex = (friendship, id) => ( + friendship + .findIndex(({addeeId, adderId}) => id === adderId || id === addeeId) +); + export const friendshipSelector = createSelector( userSelector, (user) => user.friendship, @@ -102,7 +107,13 @@ const slice = createSlice({ /* eslint-disable no-param-reassign */ reducers: { addFriendship: ({friendship}, {payload}) => { - friendship.push(payload); + const index = friendshipIndex(friendship, payload); + if (-1 === index) { + friendship.push(payload); + } + else { + friendship[index] = payload; + } }, addToFavorites: ({favorites}, {payload: favorite}) => { favorites.push(favorite); @@ -114,7 +125,7 @@ const slice = createSlice({ friendship[friendshipIndex(friendship, payload)].status = 'active'; }, removeFriendship: ({friendship}, id) => { - friendship.splice(friendshipIndex(friendship, {addeeId: id, adderId: id}), 1); + friendship.splice(friendshipIdIndex(friendship, id), 1); }, removeFromFavorites: ({favorites}, {payload: favorite}) => { favorites.splice(favorites.indexOf(favorite), 1); diff --git a/src/server/sockets.js b/src/server/sockets.js index f2accba..634c51a 100644 --- a/src/server/sockets.js +++ b/src/server/sockets.js @@ -106,6 +106,7 @@ export function createSocketServer(httpServer) { } const addeeId = user.id; let friendship = await Friendship.findOne({where: {adderId: addeeId, addeeId: adderId}}); + const friendshipIsActive = !!friendship; if (friendship) { friendship.status = 'active'; await friendship.save(); @@ -115,8 +116,8 @@ export function createSocketServer(httpServer) { } [addeeId, adderId].forEach((id) => { socket.to(`/user/${id}`, new AddFriend({ - addeeId, - adderId, + addeeId: friendshipIsActive ? adderId : addeeId, + adderId: friendshipIsActive ? addeeId : adderId, nameOrStatus: friendship.status, })); });