diff --git a/client/src/App.js b/client/src/App.js index e232d9f9..77bdaa27 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,10 +1,10 @@ -import { BrowserRouter, Routes, Route, useNavigate } from 'react-router-dom'; -import Hero from './components/Hero'; -import Header from './components/Header'; -import Home from './components/Home'; -import SignUp from './components/SignUp'; -import LogIn from './components/LogIn'; -import React, { useState, useEffect } from 'react'; +import { BrowserRouter, Routes, Route, useNavigate } from "react-router-dom"; +import Hero from "./components/Hero"; +import Header from "./components/Header"; +import Home from "./components/Home"; +import SignUp from "./components/SignUp"; +import LogIn from "./components/LogIn"; +import React, { useState, useEffect } from "react"; // let ws; // function establishWSConnection() { @@ -78,7 +78,11 @@ function App() { }> - }> + } + > { + const timerID = setInterval(() => { + setRenderTime(renderTime + 1); + }, 1000); + if (!recipient) { - console.log('do nothing'); + console.log("do nothing"); } else { - if (recipient.typeOf === 'channel') { + if (recipient.typeOf === "channel") { fetch(`http://localhost:9292/channels/${recipient.name}/messages`) .then((response) => response.json()) .then((data) => { @@ -32,18 +40,25 @@ function Chat({ recipient, user }) { .includes(sendSearchChat.toLowerCase()); }); newData.messages = filteredMessages; - setAllMessages(newData); + setAllChannelMessages(newData); + setReadyToMount(true); } else { - setAllMessages(data); + setAllChannelMessages(data); + setReadyToMount(true); } }) .catch((error) => window.alert(error)); - } else if (recipient.typeOf === 'user') { - fetch(`http://localhost:9292/channels/${recipient.name}/messages`) + } else if (recipient.typeOf === "user") { + fetch( + `http://localhost:9292/users/${user.id}/messages/${recipient.name}` + ) .then((response) => response.json()) .then((data) => { let newData; - if (sendSearchChat) { + if (data === []) { + setAllDirectMessages(null); + setReadyToMount(true); + } else if (sendSearchChat) { newData = { ...data }; const filteredMessages = data.messages.filter((message) => { return message.username @@ -51,17 +66,30 @@ function Chat({ recipient, user }) { .includes(sendSearchChat.toLowerCase()); }); newData.messages = filteredMessages; - setAllMessages(newData); + setAllDirectMessages(newData); + setReadyToMount(true); } else { - setAllMessages(data); + setAllDirectMessages(data); + setReadyToMount(true); } }) .catch((error) => window.alert(error)); } else { - console.log('something is up'); + console.log("something is up"); } } - }, [sendSearchChat, recipient]); + + return function cleanup() { + clearInterval(timerID); + }; + }, [sendSearchChat, recipient, renderTime]); + + useEffect(() => { + const timer = setTimeout(() => { + bottomRef.current?.scrollIntoView({ behavior: "smooth" }); + }, 300); + return () => clearTimeout(timer); + }, [recipient]); function handleChange(e) { e.preventDefault(); @@ -70,22 +98,52 @@ function Chat({ recipient, user }) { const sendMessage = (e) => { e.preventDefault(); - console.log('sending a message'); - - // fetch("http://localhost:9292", { - // method: "POST", - // headers: { - // "Content-Type": "application/json", - // }, - // body: JSON.stringify(newMessage), - // }) - // .then((response) => response.json()) - // .then((data) => { - // setResponse(data); - // }) - // .catch((error) => window.alert(error)); + console.log("sending a message"); + + if (recipient.typeOf === "user") { + fetch("http://localhost:9292/users/friends/send_message", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + message: newMessage, + user_id: user.id, + recipient: recipient.name, + }), + }) + .then((response) => response.json()) + .then((data) => { + setAllDirectMessages([...allDirectMessages, data]); + setNewMessage(""); + }) + .catch((error) => window.alert(error)); + } else if (recipient.typeOf === "channel") { + fetch("http://localhost:9292/users/channels/send_message", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + message: newMessage, + user_id: user.id, + recipient: recipient.name, + }), + }) + .then((response) => response.json()) + .then((data) => { + const newData = { ...allChannelMessages }; + const updatedMessages = [...newData.messages, data]; + newData.messages = updatedMessages; + setAllChannelMessages(newData); + setNewMessage(""); + }) + .catch((error) => window.alert(error)); + } }; + console.log(allChannelMessages); + function handleSearchChange(e) { e.preventDefault(); setSearchChat(e.target.value); @@ -97,8 +155,40 @@ function Chat({ recipient, user }) { function handleClearSearch(e) { e.preventDefault(); - setSearchChat(''); - setSendSearchChat(''); + setSearchChat(""); + setSendSearchChat(""); + } + + function channelOrDm() { + if (recipient.typeOf === "channel") { + return allChannelMessages.messages.map((message) => { + return ( + + ); + }); + } else if (recipient.typeOf === "user") { + return allDirectMessages.map((message) => { + console.log(message); + return ( + + ); + }); + } } return ( @@ -135,21 +225,8 @@ function Chat({ recipient, user }) { - {allMessages - ? allMessages.messages.map((message) => { - return ( - - ); - }) - : 'lodaing'} + {readyToMount ? channelOrDm() : "lodaing"} + diff --git a/client/src/components/Friend.js b/client/src/components/Friend.js index 5e041e18..cdfc5d63 100644 --- a/client/src/components/Friend.js +++ b/client/src/components/Friend.js @@ -1,9 +1,10 @@ -import React from 'react'; -import { HashtagIcon } from '@heroicons/react/outline'; +import React from "react"; +import { HashtagIcon } from "@heroicons/react/outline"; -function Friend({ id, friendName, setRecipient }) { +function Friend({ id, friendName, setRecipient, setReadyToMount }) { function displayFriend() { - setRecipient({ name: friendName, typeOf: 'user' }); + setReadyToMount(false); + setRecipient({ name: friendName, typeOf: "user" }); } return ( { if (!response) { - navigate('/'); + navigate("/"); } else { fetch(`http://localhost:9292/users/${response.user_id}`) .then((response) => response.json()) @@ -58,15 +59,15 @@ function Home({ response }) { }, [sendChannelSearch]); const handleJoinChannel = () => { - const newChannelName = prompt('Enter a channel to join'); + const newChannelName = prompt("Enter a channel to join"); console.log( - 'This is where we are joining a new channel: ' + newChannelName + "This is where we are joining a new channel: " + newChannelName ); if (newChannelName) { fetch(`http://localhost:9292/channels/join`, { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify({ channelName: newChannelName, @@ -86,13 +87,13 @@ function Home({ response }) { }; const handleCreateChannel = () => { - const newChannelName = prompt('Enter a new channel name'); - console.log('This is where we are making a new channel: ' + newChannelName); + const newChannelName = prompt("Enter a new channel name"); + console.log("This is where we are making a new channel: " + newChannelName); if (newChannelName) { - fetch('http://localhost:9292/channels', { - method: 'POST', + fetch("http://localhost:9292/channels", { + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify({ channelName: newChannelName, @@ -138,12 +139,12 @@ function Home({ response }) { } function handleSettings() { - const settingsButton = prompt('This is just to show settings one day'); + const settingsButton = prompt("This is just to show settings one day"); } function logOut() { response = null; - navigate('/'); + navigate("/"); } function handleChannelSearchChange(e) { @@ -156,8 +157,8 @@ function Home({ response }) { function handleChannelClearSearch(e) { e.preventDefault(); - setChannelSearch(''); - setSendChannelSearch(''); + setChannelSearch(""); + setSendChannelSearch(""); } return ( @@ -204,6 +205,7 @@ function Home({ response }) { id={channel.id} channelName={channel.channel_name} setRecipient={setRecipient} + setReadyToMount={setReadyToMount} /> )) : null} @@ -251,9 +253,14 @@ function Home({ response }) { {recipient ? ( - + ) : ( - 'Please select a channel or friend' + "Please select a channel or friend" )} @@ -275,6 +282,8 @@ function Home({ response }) { key={friend.id} id={friend.id} friendName={friend.username} + setRecipient={setRecipient} + setReadyToMount={setReadyToMount} /> )) : null} @@ -284,7 +293,7 @@ function Home({ response }) { > ) : ( - 'Loading...' + "Loading..." )} > ); diff --git a/client/src/components/Message.js b/client/src/components/Message.js index c6ded880..3bcc602e 100644 --- a/client/src/components/Message.js +++ b/client/src/components/Message.js @@ -1,7 +1,8 @@ -import React from 'react'; -import { TrashIcon } from '@heroicons/react/solid'; +import React from "react"; +import { TrashIcon } from "@heroicons/react/solid"; -function Message({ user_id, recipinet, message, username, loggedInUserId }) { +function Message({ user_id, message, username, loggedInUserId }) { + console.log(user_id, message, username, loggedInUserId); return ( {loggedInUserId === user_id ? ( diff --git a/client/src/components/SignUp.js b/client/src/components/SignUp.js index cb6c0ee1..9c417784 100644 --- a/client/src/components/SignUp.js +++ b/client/src/components/SignUp.js @@ -1,14 +1,14 @@ -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; -function SignUp() { +function SignUp({ setResponse }) { const [success, setSuccess] = useState(false); const navigate = useNavigate(); const [formData, setFormData] = useState({ - username: '', - password: '', - email: '', - name: '', + username: "", + password: "", + email: "", + name: "", }); function handleChange(e) { @@ -18,15 +18,22 @@ function SignUp() { function handleFormSubmit(e) { e.preventDefault(); console.log(formData); - fetch('http://localhost:9292', { - method: 'POST', + fetch("http://localhost:9292/signup", { + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify(formData), }) .then((response) => response.json()) - .then((data) => setSuccess(data.success)) + .then((data) => { + if (data.success) { + setResponse(data); + navigate("/"); + } else { + alert("Please try again!"); + } + }) .catch((error) => window.alert(error)); } @@ -91,9 +98,9 @@ function SignUp() { { - navigate('/'); - }} + // onClick={() => { + // navigate("/"); + // }} > Sign Up diff --git a/server/app/controllers/application_controller.rb b/server/app/controllers/application_controller.rb index c2cac878..7462d505 100644 --- a/server/app/controllers/application_controller.rb +++ b/server/app/controllers/application_controller.rb @@ -94,22 +94,21 @@ class ApplicationController < Sinatra::Base ## two users become friends post "/user/add_friend" do - binding.pry user = User.find_by(id: params[:userId]) new_friend = User.find_by(username: params[:friendName]) if (new_friend) if (user.friends?(new_friend)) - { error: "you and #{friendName} are already friends" }.to_json + { error: "you and #{params[:friendName]} are already friends" }.to_json else user.become_friends(new_friend) - binding.pry + # binding.pry { "username" => new_friend.attributes["username"], "id" => new_friend.attributes["id"] }.to_json end else - { error: "#{friendName} does not exist" }.to_json + { error: "#{params[:friendName]} does not exist" }.to_json end end @@ -126,6 +125,18 @@ class ApplicationController < Sinatra::Base user.current_pair_messages(connection).to_json end + post "/users/friends/send_message" do + user = User.find_by(id: params[:user_id]) + recipient = User.find_by(username: params[:recipient]) + user.send_pair_message(recipient, params[:message]).to_json + end + + post "/users/channels/send_message" do + user = User.find_by(id: params[:user_id]) + recipient = Channel.find_by(channel_name: params[:recipient]) + user.send_channel_message(recipient, params[:message]).to_json + end + ## returns a list of all of the channel names get "/channels" do Channel.all.to_json(include: :channel_messages) diff --git a/server/app/models/user.rb b/server/app/models/user.rb index 9f93954c..7628be9a 100644 --- a/server/app/models/user.rb +++ b/server/app/models/user.rb @@ -26,6 +26,21 @@ def pair?(user) end end + def channel_user?(channel) + channel_user = + self.channel_users.find do |channel_user| + ( + channel_user.channel_id == channel.id && + channel_user.user_id == self.id + ) + end + if channel_user + return channel_user + else + return false + end + end + def connections self .pairs @@ -95,10 +110,13 @@ def create_channel_connection(channel) # methods meant to be used to communicate with front end def become_friends(user) - create_connection(user) if (!self.connection?(user)) - if (!friends?(user)) - binding.pry - self.pair?(user).update(friend: true) + self.create_connection(user) if (!self.connection?(user)) + if (!self.friends?(user)) + new_self = User.find_by(id: self.id) + new_user = User.find_by(id: user.id) + # binding.pry + pair = new_self.pair?(new_user) + pair.update(friend: true) else "You are already friends with this person!" end @@ -118,11 +136,13 @@ def send_pair_message(user, message) PairMessage.create(user: self, user_pair: pair, body: message) end - # def send_channel_message(channel, message) - # create_channel_connection(channel) if (!channel_connection?(channel)) - # post_to = self.pair?(user) - # PairMessage.create(user: self, user_pair: pair, body: message) - # end + def send_channel_message(channel, message) + if (!self.channel_connection?(channel)) + self.create_channel_connection(channel) + end + post_to = self.channel_user?(channel) + ChannelMessage.create(user: self, channel: channel, body: message) + end def current_pair_messages(user) messages = self.pair?(user).pair_messages