Skip to content

Commit a6a9382

Browse files
committed
Mesages Gotten Successfully
1 parent 6821c59 commit a6a9382

File tree

7 files changed

+287
-37
lines changed

7 files changed

+287
-37
lines changed

controller/inboxController.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
// External Module:
2+
const createError = require("http-errors");
3+
14
// Internal Module
25
const escape = require("../utilities/escape");
36
const User = require("../models/People");
47
const Conversation = require("../models/Conversation");
5-
const createError = require("http-errors");
8+
const Message = require("../models/Message");
69

710
// Get Inbox Page page
811
const getInbox = async (req, res, next) => {
@@ -12,7 +15,7 @@ const getInbox = async (req, res, next) => {
1215
{ "creator.id": req.user.userid },
1316
{ "participant.id": req.user.userid },
1417
],
15-
});
18+
}).sort("-createdAt");
1619
res.locals.data = conversations;
1720

1821
res.render("inbox");
@@ -87,5 +90,34 @@ const addConversation = async (req, res, next) => {
8790
}
8891
};
8992

93+
// Get Messages:
94+
const getMessages = async (req, res, next) => {
95+
try {
96+
const messages = await Message.find({
97+
conversation_id: req.params.conversation_id,
98+
}).sort("-createdAt");
99+
100+
const { participant } = await Conversation.findById(
101+
req.params.conversation_id
102+
);
103+
res.status(200).json({
104+
data: {
105+
messages: messages,
106+
participant,
107+
},
108+
user: req.user.userid,
109+
conversation_id: req.params.conversation_id,
110+
});
111+
} catch (error) {
112+
res.status(500).json({
113+
errors: {
114+
common: {
115+
msg: "Unknown Error Occured!",
116+
},
117+
},
118+
});
119+
}
120+
};
121+
90122
// Module Export
91-
module.exports = { getInbox, searchUser, addConversation };
123+
module.exports = { getMessages, getInbox, searchUser, addConversation };

router/inboxRouter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const {
77
getInbox,
88
searchUser,
99
addConversation,
10+
getMessages,
1011
} = require("../controller/inboxController");
1112
const { checkLogin } = require("../middlewares/common/checkLogin");
1213
const decorateHtmlResponse = require("../middlewares/common/decorateHtmlResponse");
@@ -20,5 +21,8 @@ router.post("/search", checkLogin, searchUser);
2021
// Add user For Conversation:
2122
router.post("/conversation", checkLogin, addConversation);
2223

24+
// Get Conversation Messages:
25+
router.get("/messages/:conversation_id", checkLogin, getMessages);
26+
2327
// Module Export:
2428
module.exports = router;

test.ejs

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
2+
<div id="chat-container">
3+
<div id="search-container">
4+
<input type="text" placeholder="Search" />
5+
</div>
6+
7+
<div class="new-message-container" onclick="openModal()">
8+
<a href="#">+</a>
9+
</div>
10+
11+
<div id="chat-title">
12+
<span id="conversation-partner"></span>
13+
<img src="./images/trash.png" alt="Delete Conversation" />
14+
</div>
15+
16+
<!-- placeholder div if no messages are in messages area -->
17+
<div id="chat-message-list">
18+
<div class="nothing">select a conversation</div>
19+
</div>
20+
21+
<!-- send message form -->
22+
<form id="chat-form" method="post" enctype="multipart/form-data">
23+
<label for="attachment"><img src="./images/attachment.png" alt="Add Attachment" /></label>
24+
<input type="file" multiple name="attachment" class="hide" id="attachment" />
25+
<input type="text" name="message" placeholder="Type a message" autocomplete="off" />
26+
</form>
27+
28+
</div>
29+
<%- include('./partials/add-conversation-modal.ejs'); %>
30+
31+
<!-- import socket io client from cdn -->
32+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.3/socket.io.min.js"></script>
33+
34+
<script>
35+
const form = document.querySelector('#chat-form');
36+
const messageContainer = document.querySelector('#chat-message-list');
37+
const chatTitleContainer = document.querySelector('#conversation-partner');
38+
const loggedinUserId = '<%= loggedInUser.userid %>';
39+
const loggedinUserName = '<%= loggedInUser.username %>';
40+
let participant = null; // selected conversation participant object
41+
let current_conversation_id; // selected conversation id
42+
43+
44+
// socket initialization
45+
const socket = io('<%= process.env.APP_URL %>');
46+
47+
48+
// handle new/live incoming message from socket
49+
socket.on("new_message", data => {
50+
// only respond if current conversation is open in any client
51+
if(data.message.conversation_id == current_conversation_id) {
52+
// message class
53+
const messageClass = data.message.sender.id === loggedinUserId ? 'you-message' : 'other-message';
54+
55+
const senderAvatar = data.message.sender.avatar ? `<img src="./uploads/avatars/${data.message.sender.avatar}" alt="${data.message.sender.name}" />` : `<img src="./images/nophoto.png" alt="${data.message.sender.name}" />`;
56+
// message attachments
57+
let attachments = '<div class="attachments">';
58+
if(data.message.attachment && data.message.attachment.length > 0) {
59+
data.message.attachment.forEach(attachment => {
60+
attachments += `<img src="./uploads/attachments/${attachment}" /> `;
61+
});
62+
}
63+
attachments += '</div>';
64+
let messageHTML;
65+
// do not show avatar for loggedin user
66+
if(data.message.sender.id == loggedinUserId) {
67+
messageHTML = `<div class="message-row ${messageClass}"><div class="message-content">
68+
<div class="message-text">${data.message.message}</div>
69+
${attachments}
70+
<div class="message-time">${moment(data.message.date_time).fromNow()}</div>
71+
</div></div>`;
72+
} else {
73+
messageHTML = `<div class="message-row ${messageClass}"><div class="message-content">
74+
${senderAvatar}
75+
<div class="message-text">${data.message.message}</div>
76+
${attachments}
77+
<div class="message-time">${moment(data.message.date_time).fromNow()}</div>
78+
</div></div>`;
79+
}
80+
// append the inoming message to message area as last item
81+
document.querySelector('#chat-message-list > .message-row:first-child').insertAdjacentHTML('beforeBegin', messageHTML);
82+
}
83+
});
84+
85+
86+
// get messages of a conversation
87+
async function getMessages(conversation_id, current_conversation_name){
88+
// messages failure toast
89+
const messagesFailureToast = Toastify({
90+
text: "Error loading messages!",
91+
duration: 1000,
92+
});
93+
let response = await fetch(`/inbox/messages/${conversation_id}`);
94+
const result= await response.json();
95+
if(!result.errors && result.data) {
96+
form.style.visibility = 'visible';
97+
98+
const {data, user, conversation_id} = result;
99+
participant = data.participant;
100+
current_conversation_id = conversation_id;
101+
if(data.messages) {
102+
let allMessages = '';
103+
if(data.messages.length > 0) {
104+
data.messages.forEach((message) => {
105+
let senderAvatar = message.sender.avatar ? `./uploads/avatars/${message.sender.avatar}` : './images/nophoto.png';
106+
const messageClass = message.sender.id === loggedinUserId ? 'you-message' : 'other-message';
107+
const showAvatar = message.sender.id === loggedinUserId ? '' : `<img src="${senderAvatar}" alt="${message.sender.name}" />`;
108+
// message attachments
109+
let attachments = '<div class="attachments">';
110+
if(message.attachment && message.attachment.length > 0) {
111+
message.attachment.forEach(attachment => {
112+
attachments += `<img src="./uploads/attachments/${attachment}" /> `;
113+
});
114+
}
115+
attachments += '</div>';
116+
// final message html
117+
let messageHTML = `<div class="message-row ${messageClass}"><div class="message-content">
118+
${showAvatar}
119+
<div class="message-text">${message.text}</div>
120+
${attachments}
121+
<div class="message-time">${moment(message.date_time).fromNow()}</div>
122+
</div></div>`;
123+
allMessages += messageHTML;
124+
messageContainer.innerHTML = allMessages;
125+
});
126+
} else if(data.messages.length === 0) {
127+
messageContainer.innerHTML = '<div class="message-row"></div>';
128+
}
129+
chatTitleContainer.textContent = current_conversation_name;
130+
}
131+
} else {
132+
messagesFailureToast.showToast();
133+
}
134+
}
135+
136+
137+
138+
// message sending
139+
form.onsubmit = async function (event) {
140+
event.preventDefault();
141+
const sendMessageFailureToast = Toastify({
142+
text: "Error sending message",
143+
duration: 1000,
144+
});
145+
// prepare the form data
146+
const formData = new FormData(form);
147+
formData.append('receiverId', participant.id);
148+
formData.append('receiverName', participant.name);
149+
formData.append('avatar', participant.avatar || '');
150+
formData.append('conversationId', current_conversation_id);
151+
// send the request to server
152+
let response = await fetch("/inbox/message", {
153+
method: "POST",
154+
body: formData,
155+
});
156+
// get response
157+
let result = await response.json();
158+
if (!result.errors) {
159+
form.reset(); // reset the form
160+
} else {
161+
sendMessageFailureToast.showToast();
162+
}
163+
}
164+
165+
166+
167+
</script>
168+
</body>
169+
</html>

test.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

views/inbox.ejs

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@
1212
<!-- IF LOGGED IN USER IS CONVERSATION CREATOR THEN WE WILL SHOW PARTICIPANT INFO -->
1313
<% if(conversation.creator.id == loggedInUser.userid){%>
1414
<!-- PARTICIPANT INFO -->
15-
<div class="conversation">
15+
<div class="conversation" onclick="getMessages('<%= conversation._id %>', '<%= conversation.participant.name %>')">
1616
<% if(conversation.participant.avatar){ %>
1717
<img src="./uploads/avatars/<%= conversation.participant.avatar %>" alt="Sumit" />
1818
<% }else{ %>
1919
<img src="./images/nophoto.png" alt="Sumit" />
2020
<% } %>
2121
<div class="title-text"><%= conversation.participant.name %></div>
22-
<div class="conversation-date"> <%= moment(conversation.last_updated).fromNow() %> </div>
22+
<div class="conversation-date"><%= conversation.last_updated %></div>
2323
</div>
2424
<% }else{ %>
2525
<!-- CREATOR INFO -->
26-
<div class="conversation">
26+
<div class="conversation" onclick="getMessages('<%= conversation._id %>', '<%= conversation.creator.name %>')">
2727
<% if(conversation.creator.avatar){ %>
2828
<img src="./uploads/avatars/<%= conversation.creator.avatar %>" alt="Sumit" />
2929
<% }else{ %>
3030
<img src="./images/nophoto.png" alt="Sumit" />
3131
<% } %>
3232
<div class="title-text"><%= conversation.creator.name %></div>
33-
<div class="conversation-date"> <%= moment(conversation.last_updated).fromNow() %> </div>
33+
<!-- <div class="conversation-date"> <%= moment(conversation.last_updated).fromNow() %> </div> -->
3434
</div>
3535
<% } %>
3636
<% }); %>
@@ -39,37 +39,91 @@
3939
<div class="nothing"><img src="./images/no-conversation.svg" alt="No Conversation"></div>
4040
<% } %>
4141
</div>
42-
4342
4443
<!-- Add New Conversation Button -->
4544
<div class="new-message-container" onclick="openModal()">
4645
<a href="#">+</a>
4746
</div>
4847
4948
<div id="chat-title">
50-
<span>Nazmul Huda</span>
49+
<span id="conversation-partner"></span>
5150
<img src="./images/trash.png" alt="Delete Conversation" />
5251
</div>
52+
53+
<!-- Placeholder div if no messages are in message area! -->
5354
<div id="chat-message-list">
54-
<div class="message-row other-message">
55-
<div class="message-content">
56-
<img src="./images/user1.png" alt="Sumit" />
57-
<div class="message-text">Ok then</div>
58-
<div class="message-time">Apr 16</div>
59-
</div>
60-
</div>
61-
<div class="message-row you-message">
62-
<div class="message-content">
63-
<div class="message-text">Lorem ipsum dolor sit amet</div>
64-
<div class="message-time">Apr 16</div>
65-
</div>
66-
</div>
67-
</div>
68-
<div id="chat-form">
69-
<img src="./images/attachment.png" alt=Add Attachment"" />
70-
<input type="text" placeholder="Type a message" />
55+
<div class="nothing">Select a conversation!</div>
7156
</div>
57+
58+
<!-- Send Message with attachment form -->
59+
<form id="chat-form" method="POST" enctype="multipart/form-data">
60+
<label for="attachment"><img src="./images/attachment.png" alt="Add Attachment" /></label>
61+
<input type="file" name="attachment" id="attachment" class="hide" multiple>
62+
<input type="text" name="message" placeholder="Type a message" autocomplete="off" />
63+
</form>
64+
7265
</div>
7366
<%- include('./partials/add-conversation-modal.ejs') %>
7467
</body>
68+
69+
<script>
70+
// Select Messages related elements for DOM Munipolation:
71+
const form = document.querySelector('#chat-form');
72+
const messageContainer = document.querySelector("#chat-message-list");
73+
const chatTitleContainer = document.querySelector("#conversation-partner");
74+
const loggedinUserId = '<%= loggedInUser.userid %>';
75+
const loggedinUserName = '<%= loggedInUser.username %>';
76+
let participant = null; //Selected Conversation Participant Object;
77+
let current_conversation_id; //Selected Conversation ID;
78+
79+
80+
// GET MESSAGES OF A CONVERSATION:
81+
const getMessages = async(conversation_id, current_conversation_name)=>{
82+
83+
// MESSAGE FAILURE TOAST:
84+
const messageFailureToast = Toastify({
85+
text:"Error loading message!",
86+
duration:1000,
87+
})
88+
89+
let response = await fetch(`/inbox/messages/${conversation_id}`)
90+
const result = await response.json();
91+
92+
console.log(result)
93+
94+
// if(!result.errors && result.data){
95+
// form.style.visibility ='visible';
96+
97+
// const {data, user, conversation_id} = result;
98+
// participant = data.participant;
99+
// current_conversation_id = conversation_id;
100+
101+
// if(data.messages){
102+
// let allMessages = '';
103+
104+
// if(data.message.length > 0){
105+
// data.messages.forEach((message)=>{
106+
// let senderAvatar = message.sender.avatar ? `./uploads/avatars/${message.sender.avatar}` : './images/nophoto.png';
107+
// const messageClass = message.sender.id === loggedinUserName ? 'you-message' : 'older-message';
108+
// const showAvatar = message.sender.id === loggedinUserId ? '': `<img src="${sender.avatar}" alt="${message.sender.name}" />`;
109+
110+
// let attachments = '<div class = "attachments">';
111+
112+
// if(message.attachment && message.attachment.length >0){
113+
// message.attachment.forEach(attachment=>{
114+
// attachments += `<img src="./uploads/attachments/${attachment}" />`
115+
// })
116+
// }else{}
117+
118+
// attachments += '</div>';
119+
120+
// })
121+
// }else{}
122+
// }else{}
123+
// }else{
124+
// messageFailureToast.showToast();
125+
// }
126+
127+
}
128+
</script>
75129
</html>

0 commit comments

Comments
 (0)