Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context restructure #79

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions src/APIContext.js

This file was deleted.

6 changes: 0 additions & 6 deletions src/AllUsersContext.js

This file was deleted.

7 changes: 7 additions & 0 deletions src/Services/UserContexts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createContext } from "react";

const UserDbContext = createContext();
const ChannelDbContext = createContext();
const ChatContext = createContext();

export { UserDbContext, ChannelDbContext, ChatContext };
45 changes: 22 additions & 23 deletions src/components/Chat/Chat.js
Original file line number Diff line number Diff line change
@@ -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 (
<div className="chat">
<div className="chat-header">
<ChatHeader
chat={chat}
<ChatHeader chat={chat} chatType={chatType} />
</div>
{!chat ? (
<NewChat setNewChat={setNewChat} />
) : (
<ChatArea
userId={chat.id}
userEmail={chat.uid}
convo={convo}
setConvo={setConvo}
chatType={chatType}
userDb={userDb}
setUserDb={setUserDb}
recentDms={recentDms}
setRecentDms={setRecentDms}
/>
</div>
<ChatArea
userId={chatWith.id}
userEmail={chatWith.uid}
convo={convo}
setConvo={setConvo}
chatType={chatType}
recentDms={recentDms}
setRecentDms={setRecentDms}
chat={chat}
userDb={userDb}
/>
)}
<ChatForm
userId={chatWith.id}
newChat={newChat}
userId={chat.id}
setConvo={setConvo}
convo={convo}
userEmail={chatWith.uid}
chatType={chatType}
/>
</div>
Expand Down
57 changes: 27 additions & 30 deletions src/components/Chat/ChatArea.js
Original file line number Diff line number Diff line change
@@ -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("");
Expand All @@ -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]);
Expand All @@ -57,14 +51,15 @@ function ChatArea(props) {
}

const interval = setInterval(() => {
retrieveMsgs(userId, chatType, true);
UserAPI.getRecent(header)
.then((res) => {
setRecentDms(res.data.data);
})
.catch((e) => {
console.log(e);
});
if (userId === undefined) console.log("undefined ID at 61");
retrieveMsgs(userId, chatType, true);
}, 3000);

return () => clearInterval(interval);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 <div></div>;
if (userEmail === header.uid)
return (
<div className="messages-header">
Expand Down
21 changes: 19 additions & 2 deletions src/components/Chat/ChatForm.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
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,
IoAttach,
IoVideocamOutline,
IoMicOutline,
} from "react-icons/io5";

import {
BsEmojiSmile,
BsFillLightningFill,
Expand All @@ -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("");

Expand Down Expand Up @@ -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)
Expand Down
12 changes: 9 additions & 3 deletions src/components/Chat/ChatHeader.js
Original file line number Diff line number Diff line change
@@ -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);
Expand Down Expand Up @@ -61,7 +63,11 @@ function ChatHeader({ chat, chatType, userDb, setUserDb }) {
/>
</div>

{chatType === "User" ? (
{!chat ? (
<div className="chat-title">
<h1>New Message</h1>
</div>
) : chatType === "User" ? (
<div className="chat-title">
<h1> {chat.uid}</h1>
</div>
Expand Down
29 changes: 29 additions & 0 deletions src/components/Chat/NewChat.css
Original file line number Diff line number Diff line change
@@ -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;
}
72 changes: 72 additions & 0 deletions src/components/Chat/NewChat.js
Original file line number Diff line number Diff line change
@@ -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 (
<SearchResult
key={user.id}
user={user}
setSearchEntry={setSearchEntry}
/>
);
})
: null;
return (
<div className="NewChat" style={{ height: "100%" }}>
<div className="newchat-input-container">
To:{" "}
<input
className="input-search newchat-input-search"
value={searchEntry}
onChange={(e) => {
setSearchEntry(e.target.value);
}}
placeholder="[email protected]"
onFocus={() => setIsActive(true)}
/>
<div className="newchat-suggestions-wrapper">
{isActive && Suggestions}
</div>
</div>
</div>
);
}

export default NewChat;
Loading