flow: user ops
This commit is contained in:
parent
21f5feb9c0
commit
898463d305
|
@ -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"
|
||||
>
|
||||
<Channel
|
||||
key={channel}
|
||||
key={JSON.stringify(friendship)}
|
||||
actions={favoritesActions}
|
||||
href={`/chat/u/${channel}`}
|
||||
name={channel}
|
||||
|
@ -121,6 +121,7 @@ export default function ChatLeftFriends() {
|
|||
];
|
||||
return (
|
||||
<li
|
||||
key={channel}
|
||||
className="friends__item"
|
||||
>
|
||||
<Channel
|
||||
|
@ -167,6 +168,7 @@ export default function ChatLeftFriends() {
|
|||
];
|
||||
return (
|
||||
<li
|
||||
key={channel}
|
||||
className="friends__item"
|
||||
>
|
||||
<Channel
|
||||
|
|
|
@ -29,6 +29,7 @@ export default function ChatRightBlocked(props) {
|
|||
];
|
||||
return (
|
||||
<li
|
||||
key={id}
|
||||
className="blocked__item"
|
||||
>
|
||||
<Channel
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
import './chat--rightUsers.scss';
|
||||
|
||||
import React from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import {channelUsersSelector} from '~/common/state/chat';
|
||||
import {redditUsernameSelector} from '~/common/state/user';
|
||||
import {
|
||||
blockedSelector,
|
||||
favoriteUsersSelector,
|
||||
friendshipIdIndex,
|
||||
friendshipSelector,
|
||||
idSelector,
|
||||
redditUsernameSelector,
|
||||
submitAddFavorite,
|
||||
submitAddFriend,
|
||||
submitBlock,
|
||||
submitRemoveFavorite,
|
||||
submitRemoveFriend,
|
||||
submitUnblock,
|
||||
} from '~/common/state/user';
|
||||
import {usernamesSelector} from '~/common/state/usernames';
|
||||
|
||||
import useChannel from '~/client/hooks/useChannel';
|
||||
|
@ -13,48 +26,106 @@ import Channel from './channel';
|
|||
|
||||
export default function ChatRightUsers() {
|
||||
const channel = useChannel();
|
||||
const dispatch = useDispatch();
|
||||
const blocked = useSelector(blockedSelector);
|
||||
const favoriteUsers = useSelector(favoriteUsersSelector);
|
||||
const friendship = useSelector(friendshipSelector);
|
||||
const userId = useSelector(idSelector);
|
||||
const ids = useSelector((state) => 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 (
|
||||
<div
|
||||
className="chat--rightUsers"
|
||||
>
|
||||
<h2 className="users__chatsTitle">Who's here</h2>
|
||||
<ul className="users__chatsList">
|
||||
{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) {
|
||||
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: () => {},
|
||||
onClick: () => dispatch(submitAddFriend({nameOrStatus: username})),
|
||||
});
|
||||
}
|
||||
if (hasBlocked) {
|
||||
userActions.push({
|
||||
icon: '😶',
|
||||
label: 'Unblock',
|
||||
onClick: () => dispatch(submitUnblock(id)),
|
||||
});
|
||||
}
|
||||
else {
|
||||
userActions.push({
|
||||
icon: '☢️',
|
||||
label: 'Block',
|
||||
onClick: () => {},
|
||||
onClick: () => dispatch(submitBlock(id)),
|
||||
});
|
||||
}
|
||||
// {
|
||||
// icon: '❤️',
|
||||
// label: 'Favorite',
|
||||
// onClick: () => {},
|
||||
// },
|
||||
}
|
||||
return (
|
||||
<li
|
||||
className="users__item"
|
||||
key={username}
|
||||
key={id}
|
||||
>
|
||||
<Channel
|
||||
actions={userActions}
|
||||
href={isLinked ? `/chat/u/${username}` : null}
|
||||
name={username}
|
||||
href={(
|
||||
(hasFriendship && userId !== id)
|
||||
? `/chat/u/${username}`
|
||||
: null
|
||||
)}
|
||||
name={username || '?'}
|
||||
prefix="/u/"
|
||||
/>
|
||||
</li>
|
||||
|
|
|
@ -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}</>;
|
||||
}
|
||||
|
||||
|
|
5
src/client/store/effects.js
vendored
5
src/client/store/effects.js
vendored
|
@ -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',
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -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}) => {
|
||||
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);
|
||||
|
|
|
@ -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,
|
||||
}));
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user