Skip to content

Commit

Permalink
Merge branch 'feature-4-improve-socket' of https://github.com/tomtheh…
Browse files Browse the repository at this point in the history
…uman/messenger-app into feature-4-improve-socket
  • Loading branch information
TomTheHuman committed Jul 3, 2021
2 parents a9314db + 2060d5a commit a801b7a
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 80 deletions.
8 changes: 2 additions & 6 deletions client/src/components/ActiveChat/ActiveChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ const ActiveChat = (props) => {
online={conversation.otherUser.online || false}
/>
<Box className={classes.chatContainer}>
<Messages
messages={[...conversation.messages]}
otherUser={conversation.otherUser}
userId={user.id}
/>
<Messages userId={user.id} />
<Input
otherUser={conversation.otherUser}
conversationId={conversation.id}
Expand All @@ -63,4 +59,4 @@ const mapStateToProps = (state) => {
};
};

export default connect(mapStateToProps, null)(ActiveChat);
export default connect(mapStateToProps)(ActiveChat);
44 changes: 28 additions & 16 deletions client/src/components/ActiveChat/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@ import { Box } from "@material-ui/core";
import { SenderBubble, OtherUserBubble } from "../ActiveChat";
import moment from "moment";
import { connect } from "react-redux";
import { updateMessage } from "../../store/utils/thunkCreators";
import { patchMessages } from "../../store/utils/thunkCreators";

async function updateMessages(props, reqBody) {
if (props.conversation.unreadMessages.otherUser.length > 0) {
await props.patchMessages(reqBody);
}
}

const Messages = (props) => {
const { messages, otherUser, userId } = props;
const { userId } = props;
const { messages, otherUser, id } = props.conversation;
const lastIndex = messages.length - 1;

const handleReadMessage = async (message, otherUser) => {
if (message.senderId === otherUser.id && message.read === false) {
const reqBody = {
message: message,
sender: message.senderId,
};
await props.updateMessage(reqBody);
}
};
// run update messages whenever a chat page is rendered
updateMessages(props, reqBody);

return (
<Box>
{messages.map((message, index) => {
const time = moment(message.createdAt).format("h:mm");
const lastMessage = index === lastIndex;

handleReadMessage(message, otherUser);
return message.senderId === userId ? (
<SenderBubble
key={message.id}
text={message.text}
time={time}
lastMessage={index === lastIndex}
lastMessage={lastMessage}
read={message.read}
otherUser={otherUser}
/>
Expand All @@ -47,12 +47,24 @@ const Messages = (props) => {
);
};

const mapStateToProps = (state) => {
return {
user: state.user,
conversation:
state.conversations &&
state.conversations.find(
(conversation) =>
conversation.otherUser.username === state.activeConversation
),
};
};

const mapDispatchToProps = (dispatch) => {
return {
updateMessage: (body) => {
dispatch(updateMessage(body));
patchMessages: (body) => {
dispatch(patchMessages(body));
},
};
};

export default connect(null, mapDispatchToProps)(Messages);
export default connect(mapStateToProps, mapDispatchToProps)(Messages);
18 changes: 8 additions & 10 deletions client/src/components/ActiveChat/ReadStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,16 @@ const useStyles = makeStyles(() => ({

const ReadStatus = (props) => {
const classes = useStyles();
const { lastMessage, read, otherUser } = props;
const { read, otherUser } = props;

return (
lastMessage && (
<Box className={classes.root}>
{read ? (
<StatusUserAvatar otherUser={otherUser} />
) : (
<span className={classes.status}>Delivered</span>
)}
</Box>
)
<Box className={classes.root}>
{read ? (
<StatusUserAvatar otherUser={otherUser} />
) : (
<span className={classes.status}>Delivered</span>
)}
</Box>
);
};

Expand Down
2 changes: 1 addition & 1 deletion client/src/components/ActiveChat/SenderBubble.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const SenderBubble = (props) => {
<Box className={classes.bubble}>
<Typography className={classes.text}>{text}</Typography>
</Box>
<ReadStatus lastMessage={lastMessage} read={read} otherUser={otherUser} />
{lastMessage && <ReadStatus read={read} otherUser={otherUser} />}
</Box>
);
};
Expand Down
13 changes: 12 additions & 1 deletion client/src/components/Sidebar/Chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Chat extends Component {
render() {
const { classes } = this.props;
const otherUser = this.props.conversation.otherUser;

return (
<Box
onClick={() => this.handleClick(this.props.conversation)}
Expand All @@ -44,6 +45,13 @@ class Chat extends Component {
}
}

const mapStateToProps = (state) => {
return {
user: state.user,
conversations: state.conversations,
};
};

const mapDispatchToProps = (dispatch) => {
return {
setActiveChat: (id) => {
Expand All @@ -52,4 +60,7 @@ const mapDispatchToProps = (dispatch) => {
};
};

export default connect(null, mapDispatchToProps)(withStyles(styles)(Chat));
export default connect(
mapStateToProps,
mapDispatchToProps
)(withStyles(styles)(Chat));
10 changes: 3 additions & 7 deletions client/src/components/Sidebar/ChatContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ const ChatContent = (props) => {

const { conversation } = props;
const { latestMessageText, otherUser } = conversation;
const unreadMessages = conversation.messages.filter((message) => {
return !message.read && message.senderId === otherUser.id;
});
const unreadCount = unreadMessages.length;
const unreadCount = conversation.unreadMessages.otherUser.length;

return (
<Box className={classes.root}>
Expand All @@ -94,20 +91,19 @@ const ChatContent = (props) => {
{latestMessageText}
</Typography>
</Box>
{unreadCount > 0 && <UnreadCount count={unreadCount} />}
{unreadCount > 0 && <UnreadCount unread={unreadCount} />}
</Box>
);
};

const UnreadCount = (props) => {
const classes = useStyles();
const { count } = props;

return (
<Box className={classes.countContainer}>
<Box>
<Box className={classes.bubble}>
<Typography className={classes.bubbleText}>{count}</Typography>
<Typography className={classes.bubbleText}>{props.unread}</Typography>
</Box>
</Box>
</Box>
Expand Down
8 changes: 5 additions & 3 deletions client/src/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
setNewMessage,
removeOfflineUser,
addOnlineUser,
readMessage,
readConvo,
} from "./store/conversations";

const socket = io(window.location.origin);
Expand All @@ -20,10 +20,12 @@ socket.on("connect", () => {
store.dispatch(removeOfflineUser(id));
});
socket.on("new-message", (data) => {
store.dispatch(setNewMessage(data.message, data.sender));
store.dispatch(
setNewMessage(data.message, data.onSenderClient, data.sender)
);
});
socket.on("read-message", (body) => {
store.dispatch(readMessage(body.message));
store.dispatch(readConvo(body.conversationId, body.onSenderClient));
});
});

Expand Down
22 changes: 13 additions & 9 deletions client/src/store/conversations.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import {
addSearchedUsersToStore,
removeOfflineUserFromStore,
addMessageToStore,
updateMessageInStore,
readConvoInStore,
} from "./utils/reducerFunctions";

// ACTIONS

const GET_CONVERSATIONS = "GET_CONVERSATIONS";
const SET_MESSAGE = "SET_MESSAGE";
const READ_MESSAGE = "READ_MESSAGE";
const READ_CONVO = "READ_CONVO";
const ADD_ONLINE_USER = "ADD_ONLINE_USER";
const REMOVE_OFFLINE_USER = "REMOVE_OFFLINE_USER";
const SET_SEARCHED_USERS = "SET_SEARCHED_USERS";
Expand All @@ -27,17 +27,21 @@ export const gotConversations = (conversations) => {
};
};

export const setNewMessage = (message, sender) => {
export const setNewMessage = (message, onSenderClient, sender) => {
return {
type: SET_MESSAGE,
payload: { message, sender: sender || null },
payload: {
message,
onSenderClient,
sender: sender || null,
},
};
};

export const readMessage = (message) => {
export const readConvo = (conversationId, onSenderClient) => {
return {
type: READ_MESSAGE,
message,
type: READ_CONVO,
payload: { conversationId, onSenderClient },
};
};

Expand Down Expand Up @@ -84,8 +88,8 @@ const reducer = (state = [], action) => {
return action.conversations;
case SET_MESSAGE:
return addMessageToStore(state, action.payload);
case READ_MESSAGE:
return updateMessageInStore(state, action.message);
case READ_CONVO:
return readConvoInStore(state, action.payload);
case ADD_ONLINE_USER: {
return addOnlineUserToStore(state, action.id);
}
Expand Down
57 changes: 49 additions & 8 deletions client/src/store/utils/reducerFunctions.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
export const addMessageToStore = (state, payload) => {
const { message, sender } = payload;
const { message, onSenderClient, sender } = payload;
// if sender isn't null, that means the message needs to be put in a brand new convo
if (sender !== null) {
const unread = {
index: 0,
senderId: message.senderId,
};

const newConvo = {
id: message.conversationId,
otherUser: sender,
messages: [message],
unreadMessages: {
currentUser: [],
otherUser: [],
},
};

// update unread messages store based on where request originated
if (onSenderClient) {
newConvo.unreadMessages.currentUser.push(unread);
} else {
newConvo.unreadMessages.otherUser.push(unread);
}

newConvo.latestMessageText = message.text;
return [newConvo, ...state];
}
Expand All @@ -15,6 +32,19 @@ export const addMessageToStore = (state, payload) => {
if (convo.id === message.conversationId) {
const convoCopy = { ...convo };
convoCopy.messages.push(message);

// update unread messages store based on where request originated
const index = convoCopy.messages.length - 1;
let unread = {
index: index,
senderId: message.senderId,
};
if (onSenderClient) {
convoCopy.unreadMessages.currentUser.push(unread);
} else {
convoCopy.unreadMessages.otherUser.push(unread);
}

convoCopy.latestMessageText = message.text;

return convoCopy;
Expand All @@ -25,16 +55,27 @@ export const addMessageToStore = (state, payload) => {
};

// locates message by convo id and message id and marks as read
export const updateMessageInStore = (state, message) => {
console.log(state);
export const readConvoInStore = (state, payload) => {
const { conversationId, onSenderClient } = payload;

return state.map((convo) => {
if (convo.id === message.conversationId) {
if (convo.id === conversationId) {
const convoCopy = { ...convo };

let messageIndex = convoCopy.messages.findIndex(
(convoMessage) => convoMessage.id === message.id
);
convoCopy.messages[messageIndex].read = true;
// update unread messages store based on where request originated
if (onSenderClient) {
for (let i = 0; i < convoCopy.unreadMessages.otherUser.length; i++) {
let index = convoCopy.unreadMessages.otherUser[i].index;
convoCopy.messages[index].read = true;
}
convoCopy.unreadMessages.otherUser = [];
} else {
for (let i = 0; i < convoCopy.unreadMessages.currentUser.length; i++) {
let index = convoCopy.unreadMessages.currentUser[i].index;
convoCopy.messages[index].read = true;
}
convoCopy.unreadMessages.currentUser = [];
}

return convoCopy;
} else {
Expand Down
Loading

0 comments on commit a801b7a

Please sign in to comment.