diff --git a/backend/Dockerfile b/backend/Dockerfile deleted file mode 100644 index a1eb533..0000000 --- a/backend/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM python:3.9.10 -ENV PYTHONBUFFERED=1 -ENV PORT 8080 -WORKDIR /app -COPY requirements.txt /app/requirements.txt -RUN pip install --upgrade pip -RUN pip install -r requirements.txt -COPY . /app/ -# --- start: For this app --- -RUN python manage.py migrate -RUN echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass1234')" | python manage.py shell -# --- end --- -CMD gunicorn -b :8080 server.wsgi:application -EXPOSE ${PORT} \ No newline at end of file diff --git a/frontend/src/App.css b/frontend/src/App.css index 052ca83..a7e81f4 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -81,6 +81,7 @@ border: none; margin: 6px 12px 6px 12px; outline: none; + width: calc(100% - 24px); } .search-bar::placeholder { color: white; @@ -207,14 +208,14 @@ background-color: #4e426d !important; } -.multi-chat-window { - position: absolute; - top: calc(10vh + 64px); - left: 10vw; - height: calc(80vh - 64px); - width: 80vw; - border: 1px solid black; +.ce-chat-engine { + position: absolute !important; + top: calc(10vh + 64px) !important; + left: 10vw !important; + height: calc(80vh - 64px) !important; + width: 80vw !important; + border: 1px solid black !important; box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px, - rgba(10, 37, 64, 0.35) 0px -2px 6px 0px inset; + rgba(10, 37, 64, 0.35) 0px -2px 6px 0px inset !important; } diff --git a/frontend/src/App.js b/frontend/src/App.js index dfadcca..91ff40b 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -2,8 +2,8 @@ import { useContext } from "react"; import "./App.css"; -import AuthPage from "./pages/auth"; -import ChatsPage from "./pages/chats"; +import AuthPage from "./authPage"; +import ChatsPage from "./chatsPage"; import { Context } from "./context"; diff --git a/frontend/src/pages/auth/Login/index.js b/frontend/src/authPage/Login/index.js similarity index 98% rename from frontend/src/pages/auth/Login/index.js rename to frontend/src/authPage/Login/index.js index 4453e49..b2b9402 100644 --- a/frontend/src/pages/auth/Login/index.js +++ b/frontend/src/authPage/Login/index.js @@ -3,7 +3,7 @@ import { useState, useContext } from "react"; import { Col, Row, Form, Input, Button, Checkbox, notification } from "antd"; import { login } from "./login"; -import { Context } from "../../../context"; +import { Context } from "../../context"; const Login = () => { const [error, setError] = useState(""); diff --git a/frontend/src/pages/auth/Login/login.js b/frontend/src/authPage/Login/login.js similarity index 100% rename from frontend/src/pages/auth/Login/login.js rename to frontend/src/authPage/Login/login.js diff --git a/frontend/src/pages/auth/Register/createUser.js b/frontend/src/authPage/Register/createUser.js similarity index 100% rename from frontend/src/pages/auth/Register/createUser.js rename to frontend/src/authPage/Register/createUser.js diff --git a/frontend/src/pages/auth/Register/index.js b/frontend/src/authPage/Register/index.js similarity index 98% rename from frontend/src/pages/auth/Register/index.js rename to frontend/src/authPage/Register/index.js index daa0051..ce809f7 100644 --- a/frontend/src/pages/auth/Register/index.js +++ b/frontend/src/authPage/Register/index.js @@ -3,7 +3,7 @@ import { useState, useContext } from "react"; import { Col, Row, Form, Input, Button, notification } from "antd"; import { createUser } from "./createUser"; -import { Context } from "../../../context"; +import { Context } from "../../context"; const Register = () => { const [error, setError] = useState(""); diff --git a/frontend/src/pages/auth/index.js b/frontend/src/authPage/index.js similarity index 100% rename from frontend/src/pages/auth/index.js rename to frontend/src/authPage/index.js diff --git a/frontend/src/chatsPage/ChatList/fetchUserList.js b/frontend/src/chatsPage/ChatList/fetchUserList.js new file mode 100644 index 0000000..e56587f --- /dev/null +++ b/frontend/src/chatsPage/ChatList/fetchUserList.js @@ -0,0 +1,8 @@ +import axios from "axios"; + +export const fetchUserList = (onSuccess, onError) => { + axios + .get("http://127.0.0.1:8000/users/", {}) + .then((r) => onSuccess(r)) + .catch((e) => onError(e.response.data)); +}; diff --git a/frontend/src/chatsPage/ChatList/getOrCreateChat.js b/frontend/src/chatsPage/ChatList/getOrCreateChat.js new file mode 100644 index 0000000..48aed7e --- /dev/null +++ b/frontend/src/chatsPage/ChatList/getOrCreateChat.js @@ -0,0 +1,21 @@ +import axios from "axios"; + +export const getOrCreateChat = (user, otherUsername, onSuccess, onError) => { + axios + .put( + "https://api.chatengine.io/chats/", + { + usernames: [user.username, otherUsername], + is_direct_chat: true, + }, + { + headers: { + "Project-Id": "70049943-b572-4372-9f3c-fbdeca940e0f", + "User-Name": user.username, + "User-Secret": user.hashed_password, + }, + } + ) + .then((r) => onSuccess(r)) + .catch((e) => onError(e.response.data)); +}; diff --git a/frontend/src/chatsPage/ChatList/index.js b/frontend/src/chatsPage/ChatList/index.js new file mode 100644 index 0000000..c9dc99d --- /dev/null +++ b/frontend/src/chatsPage/ChatList/index.js @@ -0,0 +1,122 @@ +import { useContext, useState, useEffect, useRef } from "react"; + +import { fetchUserList } from "./fetchUserList"; +import { getOrCreateChat } from "./getOrCreateChat"; + +import { Context } from "../../context"; +import { Input, ChatCard } from "react-chat-engine-advanced"; + +const ChatList = (props) => { + const didMountRef = useRef(false); + const { user, userList, setUserList } = useContext(Context); + const [search, setSearch] = useState(""); + + useEffect(() => { + if (!didMountRef.current) { + didMountRef.current = true; + fetchUserList( + (r) => { + console.log(r.data.results); + setUserList(r.data.results); + }, + (e) => console.log(e) + ); + } + }); + + const getOtherUser = (chat) => { + let username = ""; + chat.people.map((person) => { + if (person.person.username !== user.username) { + username = person.person.first_name + " " + person.person.last_name; + } + }); + return username; + }; + + const renderChats = () => { + return props.chats.map((chat, index) => { + return ( + props.onChatCardClick(chat.id)} + avatarUsername={chat.last_message.sender?.username} + avatarUrl={ + chat.last_message.sender + ? chat.last_message.sender.avatar + : "https://chat-engine-assets.s3.amazonaws.com/empty-chat-thumb.png" + } + /> + ); + }); + }; + + const renderSearch = () => { + return userList.map((otherUser, index) => { + const userStr = `${otherUser.username} ${otherUser.email} ${otherUser.first_name} ${otherUser.last_name}`; + + if ( + userStr.indexOf(search) !== -1 && + otherUser.username !== user.username && + otherUser.username !== "admin" + ) { + return ( + + getOrCreateChat( + user, + otherUser.username, + (r) => { + setSearch(""); + props.onChatCardClick(r.data.id); + }, + (e) => console.log(e) + ) + } + /> + ); + } else { + return
; + } + }); + }; + + return ( +
+ setSearch(e.target.value)} + className="search-bar" + /> + + {search.length > 0 ? renderSearch() : renderChats()} +
+ ); +}; + +export default ChatList; diff --git a/frontend/src/pages/chats/Header/MyAccount/DeleteAccount/deleteUser.js b/frontend/src/chatsPage/Header/MyAccount/DeleteAccount/deleteUser.js similarity index 100% rename from frontend/src/pages/chats/Header/MyAccount/DeleteAccount/deleteUser.js rename to frontend/src/chatsPage/Header/MyAccount/DeleteAccount/deleteUser.js diff --git a/frontend/src/pages/chats/Header/MyAccount/DeleteAccount/index.js b/frontend/src/chatsPage/Header/MyAccount/DeleteAccount/index.js similarity index 91% rename from frontend/src/pages/chats/Header/MyAccount/DeleteAccount/index.js rename to frontend/src/chatsPage/Header/MyAccount/DeleteAccount/index.js index e1d4e7d..f2e9c4c 100644 --- a/frontend/src/pages/chats/Header/MyAccount/DeleteAccount/index.js +++ b/frontend/src/chatsPage/Header/MyAccount/DeleteAccount/index.js @@ -3,7 +3,7 @@ import { useContext } from "react"; import { Button } from "antd"; import { deleteUser } from "./deleteUser"; -import { Context } from "../../../../../context"; +import { Context } from "../../../../context"; const DeleteAccount = () => { const { user, setUser } = useContext(Context); diff --git a/frontend/src/pages/chats/Header/MyAccount/UpdateAccount/index.js b/frontend/src/chatsPage/Header/MyAccount/UpdateAccount/index.js similarity index 98% rename from frontend/src/pages/chats/Header/MyAccount/UpdateAccount/index.js rename to frontend/src/chatsPage/Header/MyAccount/UpdateAccount/index.js index 771d062..862e700 100644 --- a/frontend/src/pages/chats/Header/MyAccount/UpdateAccount/index.js +++ b/frontend/src/chatsPage/Header/MyAccount/UpdateAccount/index.js @@ -3,7 +3,7 @@ import { useState, useContext } from "react"; import { Col, Row, Button, Form, Input, notification } from "antd"; import { updateUser } from "./updateUser"; -import { Context } from "../../../../../context"; +import { Context } from "../../../../context"; const EditAccount = (props) => { const [error, setError] = useState(""); diff --git a/frontend/src/pages/chats/Header/MyAccount/UpdateAccount/updateUser.js b/frontend/src/chatsPage/Header/MyAccount/UpdateAccount/updateUser.js similarity index 100% rename from frontend/src/pages/chats/Header/MyAccount/UpdateAccount/updateUser.js rename to frontend/src/chatsPage/Header/MyAccount/UpdateAccount/updateUser.js diff --git a/frontend/src/pages/chats/Header/MyAccount/index.js b/frontend/src/chatsPage/Header/MyAccount/index.js similarity index 100% rename from frontend/src/pages/chats/Header/MyAccount/index.js rename to frontend/src/chatsPage/Header/MyAccount/index.js diff --git a/frontend/src/pages/chats/Header/index.js b/frontend/src/chatsPage/Header/index.js similarity index 96% rename from frontend/src/pages/chats/Header/index.js rename to frontend/src/chatsPage/Header/index.js index 9e365c8..922124f 100644 --- a/frontend/src/pages/chats/Header/index.js +++ b/frontend/src/chatsPage/Header/index.js @@ -1,6 +1,6 @@ import { useContext } from "react"; -import { Context } from "../../../context"; +import { Context } from "../../context"; import MyAccount from "./MyAccount"; diff --git a/frontend/src/pages/chats/index.js b/frontend/src/chatsPage/index.js similarity index 72% rename from frontend/src/pages/chats/index.js rename to frontend/src/chatsPage/index.js index 1844275..659ad5d 100644 --- a/frontend/src/pages/chats/index.js +++ b/frontend/src/chatsPage/index.js @@ -1,8 +1,9 @@ import { useContext } from "react"; -import { Context } from "../../context"; +import { Context } from "../context"; import Header from "./Header"; +import ChatList from "./ChatList"; import { MultiChatWindow, @@ -36,7 +37,15 @@ const ChatsPage = () => {
- + ( + + )} + />
); diff --git a/frontend/src/context.js b/frontend/src/context.js index a9ac358..fde52bb 100644 --- a/frontend/src/context.js +++ b/frontend/src/context.js @@ -4,7 +4,9 @@ export const Context = createContext(); export const ContextProvider = (props) => { const [user, setUser] = useState(undefined); - const value = { user, setUser }; + const [userList, setUserList] = useState([]); + + const value = { user, setUser, userList, setUserList }; return {props.children}; };