diff --git a/src/APIContext.js b/src/APIContext.js
deleted file mode 100644
index 5b2dcbc..0000000
--- a/src/APIContext.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { createContext } from "react";
-
-const headerTemplate = {
- "access-token": "",
- client: "",
- uid: "",
- expiry: "",
-};
-
-const APIHeaders = createContext(headerTemplate);
-
-export default APIHeaders;
diff --git a/src/AllUsersContext.js b/src/AllUsersContext.js
deleted file mode 100644
index c33a2fe..0000000
--- a/src/AllUsersContext.js
+++ /dev/null
@@ -1,6 +0,0 @@
-
-import { createContext } from "react";
-
-const AllUsers = createContext([]);
-
-export default AllUsers;
diff --git a/src/Services/UserContexts.js b/src/Services/UserContexts.js
new file mode 100644
index 0000000..5c3f2ea
--- /dev/null
+++ b/src/Services/UserContexts.js
@@ -0,0 +1,7 @@
+import { createContext } from "react";
+
+const UserDbContext = createContext();
+const ChannelDbContext = createContext();
+const ChatContext = createContext();
+
+export { UserDbContext, ChannelDbContext, ChatContext };
diff --git a/src/components/Chat/Chat.js b/src/components/Chat/Chat.js
index 78febee..7654fc2 100644
--- a/src/components/Chat/Chat.js
+++ b/src/components/Chat/Chat.js
@@ -1,54 +1,53 @@
import React, { useState, useEffect } from "react";
import ChatArea from "./ChatArea";
import ChatForm from "./ChatForm";
+import { UserDbContext, ChatContext } from "../../Services/UserContexts";
import "./Chat.css";
import ChatHeader from "./ChatHeader";
+import { useContext } from "react/cjs/react.development";
+import NewChat from "./NewChat";
function Chat(props) {
- const { chat, recentDms, userDb, setRecentDms, setUserDb } = props;
- const [chatWith, setChatWith] = useState("");
+ const { recentDms, setRecentDms } = props;
const [convo, setConvo] = useState([]);
const [chatType, setChatType] = useState("User"); // can be Channel, CAPITALIZE FIRST LETTER!
+ const [newChat, setNewChat] = useState("");
+ const [chat, setChat] = useContext(ChatContext);
+ const [userDb, setUserDb] = useContext(UserDbContext);
useEffect(() => {
if (!chat) return;
if (chat["owner_id"] !== undefined) {
// if object passed has owner id, set chat type to channel!
setChatType("Channel");
- setChatWith(chat);
} else if (chat["email"] !== undefined) {
// if chat has property: email, single user lang siya
setChatType("User");
- setChatWith(chat);
}
}, [chat]);
return (
-
+
+ {!chat ? (
+
+ ) : (
+
-
-
+ )}
diff --git a/src/components/Chat/ChatArea.js b/src/components/Chat/ChatArea.js
index bbc7211..5236e3b 100644
--- a/src/components/Chat/ChatArea.js
+++ b/src/components/Chat/ChatArea.js
@@ -1,21 +1,15 @@
-import React, { useEffect, useState, useRef } from "react";
+import React, { useEffect, useState, useRef, useContext } from "react";
import ChatMsg from "./ChatMsg";
import * as UserAPI from "../../UserAPI";
import Headers from "../../Helpers/Headers";
+import { UserDbContext, ChatContext } from "../../Services/UserContexts";
import "./ChatArea.css";
import Avatar from "../Avatar/Avatar";
function ChatArea(props) {
- const {
- userId,
- userEmail,
- convo,
- setConvo,
- chatType,
- userDb,
- chat,
- setRecentDms,
- } = props;
+ const { userId, userEmail, convo, setConvo, chatType, setRecentDms } = props;
+ const [chat, setChat] = useContext(ChatContext);
+ const [userDb, setUserDb] = useContext(UserDbContext);
const [header] = useState(Headers);
const msgEnd = useRef(null);
const [prevLen, setPrevLen] = useState("");
@@ -24,28 +18,28 @@ function ChatArea(props) {
if (header["access-token"] === undefined || userId === undefined) {
return;
}
- setConvo([]); // reset all messages before going into the next one
- retrieveMsgs(userId, chatType, false);
- }, [userId, header, setConvo, chatType]);
- useEffect(() => {
- if (header["access-token"] === undefined || userId === undefined) {
- return;
+ let type = "";
+ if (!chat) return;
+ if (chat["owner_id"] !== undefined) {
+ // if object passed has owner id, set chat type to channel!
+ type = "Channel";
+ } else if (chat["email"] !== undefined) {
+ // if chat has property: email, single user lang siya
+ type = "User";
}
setConvo([]); // reset all messages before going into the next one
- retrieveMsgs(userId, chatType, false);
-
- let clen = convo.length;
- if (clen > 1) {
- setPrevLen(clen);
- }
- }, []);
+ if (userId === undefined) console.log("undefined ID at 31");
+ retrieveMsgs(userId, type, false);
+ }, [userId, header, setConvo, chat]);
useEffect(() => {
- let clen = convo.length;
- if (clen > 1) {
- if (prevLen !== clen) {
- scrollToBottom();
- setPrevLen(clen);
+ if (convo) {
+ let clen = convo.length;
+ if (clen > 1) {
+ if (prevLen !== clen) {
+ scrollToBottom();
+ setPrevLen(clen);
+ }
}
}
}, [chat, convo]);
@@ -57,7 +51,6 @@ function ChatArea(props) {
}
const interval = setInterval(() => {
- retrieveMsgs(userId, chatType, true);
UserAPI.getRecent(header)
.then((res) => {
setRecentDms(res.data.data);
@@ -65,6 +58,8 @@ function ChatArea(props) {
.catch((e) => {
console.log(e);
});
+ if (userId === undefined) console.log("undefined ID at 61");
+ retrieveMsgs(userId, chatType, true);
}, 3000);
return () => clearInterval(interval);
@@ -111,6 +106,7 @@ function ChatArea(props) {
};
const retrieveMsgs = (userId, chatType, isChecking = false) => {
+ if (!userId || !chat) return;
UserAPI.getMsgs(header, userId, chatType).then((res) => {
let len = res.data.data.length;
let convoLen = convo.length;
@@ -160,6 +156,7 @@ function ChatArea(props) {
if (chatType === "Channel" && chat.owner_id) {
channelOwner = userDb.find((user) => user.id === chat.owner_id).uid;
}
+ if (chat === undefined) return ;
if (userEmail === header.uid)
return (
diff --git a/src/components/Chat/ChatForm.js b/src/components/Chat/ChatForm.js
index e78cb67..25c9273 100644
--- a/src/components/Chat/ChatForm.js
+++ b/src/components/Chat/ChatForm.js
@@ -1,7 +1,12 @@
-import React, { useState } from "react";
+import React, { useState, useContext } from "react";
import * as UserAPI from "../../UserAPI";
import Headers from "../../Helpers/Headers";
import "./ChatForm.css";
+import {
+ ChannelDbContext,
+ UserDbContext,
+ ChatContext,
+} from "../../Services/UserContexts";
import {
IoAtOutline,
IoSend,
@@ -9,6 +14,7 @@ import {
IoVideocamOutline,
IoMicOutline,
} from "react-icons/io5";
+
import {
BsEmojiSmile,
BsFillLightningFill,
@@ -24,7 +30,12 @@ import {
} from "react-icons/bs";
function ChatForm(props) {
- const { userId, setConvo, chatType } = props;
+ const { userId, setConvo, chatType, newChat } = props;
+
+ const [chat, setChat] = useContext(ChatContext);
+ const [channelDb, setChannelDb] = useContext(ChannelDbContext);
+ const [userDb, setUserDb] = useContext(UserDbContext);
+
const [header] = useState(Headers);
const [chatInput, setChatInput] = useState("");
@@ -54,6 +65,12 @@ function ChatForm(props) {
let input = chatInput;
if (chatInput == null || input.trim().length === 0) return;
if (header["access-token"] === undefined) return;
+ if (!chat) {
+ raw.receiver_id = newChat.id;
+ if (!newChat) alert("Enter a valid receiver first!");
+ setChat(newChat);
+ setConvo([]);
+ }
UserAPI.sendMsg(header, raw)
.then((res) => {
UserAPI.getMsgs(header, userId, chatType)
diff --git a/src/components/Chat/ChatHeader.js b/src/components/Chat/ChatHeader.js
index d3d8202..282f3e0 100644
--- a/src/components/Chat/ChatHeader.js
+++ b/src/components/Chat/ChatHeader.js
@@ -1,13 +1,15 @@
-import React, { useState } from "react";
+import React, { useState, useContext } from "react";
import AddMembers from "../Channel/AddMembers";
import ShowChannelMembers from "../Channel/ShowChannelMembers";
import * as UserAPI from "../../UserAPI";
import Headers from "../../Helpers/Headers";
import "./ChatHeader.css";
+import { UserDbContext } from "../../Services/UserContexts";
import { MdLock } from "react-icons/md";
-function ChatHeader({ chat, chatType, userDb, setUserDb }) {
+function ChatHeader({ chat, chatType }) {
//modal add members
+ const [userDb, setUserDb] = useContext(UserDbContext);
const [showAddMembers, setShowAddMembers] = useState(false);
const openMemberModal = () => {
setShowAddMembers((prev) => !prev);
@@ -61,7 +63,11 @@ function ChatHeader({ chat, chatType, userDb, setUserDb }) {
/>
- {chatType === "User" ? (
+ {!chat ? (
+
+
New Message
+
+ ) : chatType === "User" ? (
{chat.uid}
diff --git a/src/components/Chat/NewChat.css b/src/components/Chat/NewChat.css
new file mode 100644
index 0000000..434c530
--- /dev/null
+++ b/src/components/Chat/NewChat.css
@@ -0,0 +1,29 @@
+.newchat-input-search {
+ font-size: 1em;
+ border: none;
+ width: 100%;
+ padding: 10px;
+ outline: none;
+ color: black;
+ background-color: white;
+}
+.newchat-input-search:focus {
+ color: black !important;
+}
+.newchat-input-container {
+ display: flex;
+ color: rgba(0, 0, 0, 0.4);
+ align-items: center;
+ padding: 10px 20px;
+ width: 100%;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.3);
+ box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.4);
+ position: relative;
+}
+.newchat-suggestions-wrapper {
+ position: absolute;
+ top: calc(1em + 33px);
+ left: 60px;
+ overflow-y: scroll;
+ max-height: 400px;
+}
diff --git a/src/components/Chat/NewChat.js b/src/components/Chat/NewChat.js
new file mode 100644
index 0000000..fd46f09
--- /dev/null
+++ b/src/components/Chat/NewChat.js
@@ -0,0 +1,72 @@
+import React, { useState, useContext, useEffect, useCallback } from "react";
+import { ChannelDbContext, UserDbContext } from "../../Services/UserContexts";
+import SearchResult from "../SearchBar/SearchResult";
+import "./NewChat.css";
+
+function NewChat(props) {
+ const { setNewChat } = props;
+ const [searchEntry, setSearchEntry] = useState("");
+ const [userDb, setUserDb] = useContext(UserDbContext);
+ const [channelDb, channelDbContext] = useContext(ChannelDbContext);
+ const [isActive, setIsActive] = useState(false);
+ const [searchSuggestions, setSearchSuggestions] = useState([]);
+
+ useEffect(() => {
+ setSearchSuggestions(
+ userDb.filter((user) => user.uid.includes(searchEntry))
+ );
+ }, [userDb, searchEntry]);
+ useEffect(() => {
+ if (searchSuggestions.length === 1) {
+ setNewChat(searchSuggestions[0]);
+ }
+ }, [searchSuggestions]);
+
+ const handleClick = useCallback(
+ (e) => {
+ let cl = e.target.classList;
+ if (cl.contains("result")) {
+ setIsActive(false);
+ } else if (!cl.contains("input-search")) {
+ setIsActive(false);
+ }
+ },
+ [setIsActive]
+ );
+ useEffect(() => {
+ document.addEventListener("click", handleClick);
+ return () => document.removeEventListener("click", handleClick);
+ }, [handleClick]);
+ const Suggestions = searchSuggestions
+ ? searchSuggestions.map((user) => {
+ return (
+
+ );
+ })
+ : null;
+ return (
+
+
+ To:{" "}
+
{
+ setSearchEntry(e.target.value);
+ }}
+ placeholder="somebody@example.com"
+ onFocus={() => setIsActive(true)}
+ />
+
+ {isActive && Suggestions}
+
+
+
+ );
+}
+
+export default NewChat;
diff --git a/src/components/Dashboard/Dashboard.js b/src/components/Dashboard/Dashboard.js
index d4840a5..9e0636c 100644
--- a/src/components/Dashboard/Dashboard.js
+++ b/src/components/Dashboard/Dashboard.js
@@ -4,6 +4,11 @@ import Chat from "../Chat/Chat";
import Headers from "../../Helpers/Headers";
import Header from "../Header/Header";
import * as UserAPI from "../../UserAPI";
+import {
+ ChannelDbContext,
+ UserDbContext,
+ ChatContext,
+} from "../../Services/UserContexts";
import "./Dashboard.css";
function Dashboard() {
@@ -99,55 +104,37 @@ function Dashboard() {
if (channelsAreLoaded) n++;
if (n === dependencies) setLoadingComplete(true);
-
- let found = userDb.find((user) => user.uid === headers.uid);
- setChat(found);
+ if (userDb) {
+ let found = userDb.find((user) => user.uid === headers.uid);
+ setChat(found);
+ }
}, [usersAreLoaded, recentsAreLoaded, channelsAreLoaded]);
- useEffect(() => {}, [filteredRecents, channelDb]);
-
const displayErrorMsg = () => {
return Please log in again to continue
;
};
return (
{isErrorLoading ? displayErrorMsg() : null}
-
-
-
- {loadingComplete && (
-
- )}
-
-
- {loadingComplete && (
-
- )}
-
-
- {loadingComplete && (
-
- )}
-
-
+
+
+
+
+
+ {loadingComplete && }
+
+
+ {loadingComplete && }
+
+
+ {loadingComplete && (
+
+ )}
+
+
+
+
+
);
}
diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js
index 47b0da5..96d40e5 100644
--- a/src/components/Header/Header.js
+++ b/src/components/Header/Header.js
@@ -4,20 +4,16 @@ import SearchBar from "../SearchBar/SearchBar";
import Logout from "../Logout/Logout";
import { FiClock } from "react-icons/fi";
-function Header({ userDb, channelDb, setChat, setUserDb }) {
+function Header() {
return (
-
-
+
);
diff --git a/src/components/SearchBar/SearchBar.js b/src/components/SearchBar/SearchBar.js
index 773bdac..98a3093 100644
--- a/src/components/SearchBar/SearchBar.js
+++ b/src/components/SearchBar/SearchBar.js
@@ -1,22 +1,25 @@
-import React, { useState, useCallback } from "react";
+import React, { useState, useCallback, useContext } from "react";
import SearchResult from "./SearchResult";
import Headers from "../../Helpers/Headers";
import { useEffect } from "react/cjs/react.development";
import * as UserAPI from "../../UserAPI";
import { BiSearch } from "react-icons/bi";
import MsgPrompt from "../MsgPrompt/MsgPrompt";
+
+import {
+ ChannelDbContext,
+ UserDbContext,
+ ChatContext,
+} from "../../Services/UserContexts";
import "./SearchBar.css";
+import { IoFastFood } from "react-icons/io5";
function SearchBar(props) {
- const {
- placeholder,
- setChatWith,
- userDb,
- setUserDb,
- searchBarFor,
- onAddMember,
- setNewMember,
- } = props;
+ const { placeholder, searchBarFor, onAddMember, setNewMember } = props;
+
+ const [userDb, setUserDb] = useContext(UserDbContext);
+ const [chat, setChat] = useContext(ChatContext);
+ const [channelDb, setChannelDb] = useContext(ChannelDbContext);
const [searchEntry, setSearchEntry] = useState("");
const [header] = useState(Headers);
const [searchSuggestions, setSearchSuggestions] = useState([]);
@@ -48,16 +51,19 @@ function SearchBar(props) {
return () => document.removeEventListener("click", handleClick);
}, [handleClick]);
+ const filterCallback = (chatObj) => {
+ if (chatObj.uid) return chatObj.uid.includes(searchEntry);
+ else if (chatObj.name) return chatObj.name.includes(searchEntry);
+ };
useEffect(() => {
if (header["access-token"] === undefined) return;
if (userDb[0] === undefined) {
alert("still loading db");
return;
}
- setSearchSuggestions(
- userDb.filter((user) => user.uid.includes(searchEntry))
- );
- }, [searchEntry, userDb, header]);
+ let arr = userDb.concat(channelDb);
+ setSearchSuggestions(arr.filter(filterCallback));
+ }, [searchEntry, userDb, header, channelDb]);
const submitHandler = (e) => {
e.preventDefault();
@@ -71,7 +77,7 @@ function SearchBar(props) {
} else {
setResponseMsg("");
setErrors(false);
- setChatWith(found);
+ setChat(found);
setIsActive(false);
}
};
@@ -87,15 +93,24 @@ function SearchBar(props) {
};
let suggestions = searchSuggestions
? searchSuggestions.map((user) => {
- return (
+ if (user.uid)
+ return (
+
+ );
+ else if (user.name)
- );
+ />;
})
: null;
return (
diff --git a/src/components/Sidebar/Sidebar.css b/src/components/Sidebar/Sidebar.css
index 3669ad5..18db85c 100644
--- a/src/components/Sidebar/Sidebar.css
+++ b/src/components/Sidebar/Sidebar.css
@@ -69,7 +69,10 @@
opacity: 0.9;
background-color: #340e36;
}
-
+.sidebar-newmsg {
+ cursor: pointer;
+ border-radius: 50%;
+}
.user-name {
padding-top: 3px;
}
@@ -102,7 +105,7 @@
pointer-events: none;
}
-.disclaimer{
+.disclaimer {
margin-right: 20px;
padding: 8px 0;
font-size: 12px;
@@ -113,4 +116,4 @@
bottom: 0;
background-color: #4a154b;
width: calc(var(--sidebar-width));
-}
\ No newline at end of file
+}
diff --git a/src/components/Sidebar/Sidebar.js b/src/components/Sidebar/Sidebar.js
index 89d2db7..348dc1c 100644
--- a/src/components/Sidebar/Sidebar.js
+++ b/src/components/Sidebar/Sidebar.js
@@ -16,12 +16,17 @@ import {
RiArrowRightSFill,
RiAddFill,
} from "react-icons/ri";
+import { ChannelDbContext, ChatContext } from "../../Services/UserContexts";
import SidebarOptions from "./SidebarOptions";
import DirectMessages from "../DirectMessages/DirectMessages";
-import { useEffect } from "react/cjs/react.development";
+import { useContext, useEffect } from "react/cjs/react.development";
function Sidebar(props) {
- const { recentDms, channelDb, setChat, chat } = props;
+ const { recentDms } = props;
+
+ const [chat, setChat] = useContext(ChatContext);
+ const [channelDb, setChannelDb] = useContext(ChannelDbContext);
+
const [setUserChannels] = useState([]);
const [setUserName] = useState([]);
const [dmsExpanded, setDmsExpanded] = useState(true);
@@ -65,7 +70,7 @@ function Sidebar(props) {
setChat(selectedChannel);
}}
className={"channel-name " + (isActive ? "isActiveChat" : "")}
- key={channel.id}
+ key={channel.name}
>
{channel.name}
@@ -88,16 +93,23 @@ function Sidebar(props) {
Slack Clone{" "}
- {
+ setChat("");
}}
- />
+ >
+
+