• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atlp-rwanda / trojans-ec-fe / d7f1f54f-736d-45ff-ad42-06d6877ab04d

pending completion
d7f1f54f-736d-45ff-ad42-06d6877ab04d

Pull #46

circleci

teerenzo
fix chat
Pull Request #46: fix chat

553 of 796 branches covered (69.47%)

Branch coverage included in aggregate %.

1291 of 1630 relevant lines covered (79.2%)

25.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.49
/src/components/chatModel.js
1
/* eslint-disable react/jsx-key */
2
/* eslint-disable no-unused-vars */
3
import React from "react";
4

5
import { useEffect, useState, useRef } from "react";
6
import { useDispatch, useSelector } from "react-redux";
7
import { socket } from "../config/socket";
8
import chatIcon from "../assets/images/chat.svg";
9
import { ToastContainer, toast } from "react-toastify";
10
import {
11
  setLoading,
12
  setData,
13
  setSingle,
14
  setHasNewMessages,
15
} from "../redux/features/slices/chat";
16
import ChatMessage from "./chatMessage";
17

18
const chatModel = () => {
4✔
19
  const dispatch = useDispatch();
18✔
20

21
  const { loading, data, hasNewMessage, error, success } = useSelector(
16✔
22
    (state) => state.chat
18✔
23
  );  
24
  const { userProfile } = useSelector(
16✔
25
    (state) => state.userProfile
18✔
26
  );
27

28
  const [username, setUsername] = useState("");
16✔
29
  const [currentUser, setCurrentUser] = useState("");
16✔
30
  const [showNewMessages, setShowNewMessages] = useState(false);
16✔
31
  const [message, setMessage] = useState("");
16✔
32
  const [showChat, setShowChat] = useState(false);
16✔
33
  const messagesEndRef = useRef(null);
16✔
34
  const [connectedUser, setConnectedUser] = useState("");
16✔
35
  const [showConnectedUser, setShowConnectedUser] = useState(false);
16✔
36

37
  const currentUserLocal = localStorage.getItem("name");
16✔
38

39
  const scrollToBottom = () => {
16✔
40
    messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
×
41
  };
42
  const handleScroll = (event) => {
16✔
43
    const { scrollTop, scrollHeight, clientHeight } = event.target;
×
44
    console.log(scrollTop + clientHeight);
×
45
    console.log(scrollHeight);
×
46

47
    if (
×
48
      scrollTop + clientHeight === scrollHeight - 0.5 ||
×
49
      scrollTop + clientHeight === scrollHeight + 0.5 ||
50
      scrollTop + clientHeight === scrollHeight
51
    ) {
52
      setShowNewMessages(false);
×
53
    } else {
54
      setShowNewMessages(true);
×
55
    }
56
  };
57
  useEffect(() => {
16✔
58
    setCurrentUser(currentUserLocal);
6✔
59
    socket.on("chat-message", (messageData) => {
6✔
60
      dispatch(setHasNewMessages(true));
×
61
      const msg = {
×
62
        User: {
63
          email: "testBuyer@example.com",
64
          name: messageData.name,
65
          profilePic:
66
            "https://res.cloudinary.com/dmjxukx09/image/upload/v1675844692/profiles/Profile-Avatar-PNG-Free-Download_paqfrf.png",
67
          role: "buyer",
68
        },
69
        createdAt: new Date(),
70
        message: messageData.message,
71
      };
72
      dispatch(setSingle(msg));
×
73
    });
74

75
    socket.emit("new-user", username);
6✔
76

77
    socket.on("user-connected", (name) => {
6✔
78
      setConnectedUser(name);
×
79
      setShowConnectedUser(true);
×
80

81
      setTimeout(() => {
×
82
        setConnectedUser("");
×
83
        setShowConnectedUser(false);
×
84
      }, 4000);
85
    });
86
    socket.on("all-messages", (message) => {
6✔
87
      dispatch(setData(message));
×
88
    });
89
    socket.on("username", (name) => {
6✔
90
      console.log(username);
×
91
      setUsername(name);
×
92
    });
93
    
94
  }, []);
95

96
  const sendMessage = (e) => {
16✔
97
    e.preventDefault();
2✔
98
    const date = formatISODate(new Date());
2✔
99
    if (message != "" && data) {
2!
100
      dispatch(
2✔
101
        setData([
102
          ...data,
103
          {
104
            User: {
105
              email: "testBuyer@example.com",
106
              name: username,
107
              profilePic:
108
              userProfile?.profilePic,
109
              role: "buyer",
110
            },
111
            createdAt: new Date(),
112
            message: message,
113
          },
114
        ])
115
      );
116

117
      socket.emit("send-chat-message", { username, message, date });
2✔
118
      setMessage("");
2✔
119
    }
120
  };
121

122
  function formatISODate(isoDate) {
123
    const date = new Date(isoDate);
2✔
124
    const options = {
2✔
125
      year: "numeric",
126
      month: "long",
127
      day: "numeric",
128
      hour: "numeric",
129
      minute: "numeric",
130
      hour12: false,
131
    };
132
    return date.toLocaleDateString(undefined, options);
2✔
133
  }
134

135
  const Show = () => {
16✔
136
    setShowChat(!showChat);
×
137
    dispatch(setHasNewMessages(false));
×
138
  };
139

140
  return (
16✔
141
    <>
142
      <ToastContainer />
143

144
      <div
145
        className={
146
          showChat
16!
147
            ? "fixed bottom-28 flex flex-col h-2/3 bg-white md:w-1/3 md:right-4 right-6 w-11/12"
148
            : "hidden"
149
        }
150
      >
151
        <header className="bg-purple-900 rounded-t-lg text-white p-4 px-6 flex justify-between ">
152
          <p className="text-white">Chat</p>
153

154
          <button onClick={() => setShowChat(false)}>x</button>
×
155
        </header>
156
        <div className="flex justify-center z-10">
157
          <p className="bg-gray-400 rounded-full px-2">
158
            {" "}
159
            {showConnectedUser ? connectedUser + " connected" : ""}{" "}
16!
160
          </p>
161
        </div>
162
        <div
163
          className="flex flex-col flex-1 overflow-y-auto px-4 py-6"
164
          onScroll={handleScroll}
165
        >
166
          {data &&
32✔
167
            data.map((message) => (
168
              <ChatMessage
12✔
169
                key={data.indexOf(message)}
170
                message={message}
171
                currentUser={currentUser}
172
                isSelf={message.isSelf}
173
              />
174
            ))}
175

176
          <div ref={messagesEndRef}></div>
177
        </div>
178
        {showNewMessages && (
16!
179
          <div className="flex justify-center bg-white">
180
            <button
181
              className="bottom-4 right-4 bg-gray-500 text-white rounded-full p-4 "
182
              onClick={scrollToBottom}
183
            >
184
              <svg
185
                width="12"
186
                height="8"
187
                viewBox="0 0 12 8"
188
                fill="none"
189
                xmlns="http://www.w3.org/2000/svg"
190
              >
191
                <path
192
                  d="M1.41 0L6 4.58L10.59 0L12 1.41L6 7.41L0 1.41L1.41 0Z"
193
                  fill="white"
194
                />
195
              </svg>
196
            </button>
197
          </div>
198
        )}
199

200
        <div className="bg-white ">
201
          <form className="flex flex-row px-4 py-2" onSubmit={sendMessage}>
202
            <input
203
              type="text"
204
              value={message}
205
              onChange={(e) => setMessage(e.target.value)}
2✔
206
              placeholder="Type a message..."
207
              className="flex-grow rounded-full bg-gray-200 py-2 px-4"
208
            />
209
            <button
210
              type="submit"
211
              data-testid="send message"
212
              className="ml-4 bg-purple-900 hover:bg-purple-800 text-white font-bold py-2 px-4 rounded-full"
213
            >
214
              Send
215
            </button>
216
          </form>
217
        </div>
218
      </div>
219

220
      <button
221
        onClick={() => Show()}
×
222
        title="Chat"
223
        className="fixed z-90 bottom-10 right-8  w-20 h-20 rounded-full drop-shadow-lg flex justify-center items-center text-white text-4xl  hover:animate-pulse duration-300"
224
      >
225
        <div style={{ position: "relative", display: "inline-block" }}>
226
          <img src={chatIcon} alt="Chat icon" />
227

228
          {hasNewMessage && (
16!
229
            <div
230
              style={{
231
                position: "absolute",
232
                top: "-5px",
233
                left: "-5px",
234
                backgroundColor: "red",
235
                width: "10px",
236
                height: "10px",
237
                borderRadius: "50%",
238
              }}
239
            />
240
          )}
241
        </div>
242
      </button>
243
    </>
244
  );
245
};
246

247
export default chatModel;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc