From 0042244b8048fe3ff64ee8b3e6be45a7910e271c Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Sun, 3 Mar 2024 03:17:53 +0000 Subject: [PATCH 01/10] Prelim Profile --- frontend-next/src/app/app/page.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index ad74268..68ec564 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -187,12 +187,16 @@ function Home() { var [tab, setTab] = useState("nearby") var [mainTab, setMainTab] = useState("home") var [chatRoom, setChatRoom] = useState("Dev") + const [chatSidebar, setChatSidebar] = useState("home") + var [user, setUser] = useState(null) + const [myRooms, setRoomData] = useState(null) const [isRoomLoading, setRoomLoading] = useState(true) useEffect(() => { fetch('/api/user').then((res) => res.json()) .then((user) => { + setUser(user) get(ref(database, '/users/'+user.uid+'/rooms')).then((snapshot) => { var rooms = snapshot.val() var roomArr = [] @@ -210,6 +214,7 @@ function Home() { const [loadingLoc, setLoadingLoc] = useState(true) const [nearby, setNearby] = useState(null); const [loadingNearby, setLoadingNearby] = useState(true); + const [myRoomsData, setMyRoomsData] = useState(null) useEffect(() => { if('geolocation' in navigator) { // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API @@ -221,6 +226,7 @@ function Home() { get(ref(database, `/rooms/${path}`)).then((snapshot) => { if (snapshot.exists()) { var data = snapshot.val() + setMyRoomsData(data) for (var room in data) { nearbyArr.push( {setChatRoom(data[room].path+"/"+data[room].name+"-"+data[room].timestamp);setMainTab("chat")}}/>) } @@ -243,6 +249,8 @@ function Home() {
+ {(mainTab == "chat") && {alert("WIP")}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Add to "My Rooms"} + {(mainTab == "chat") && {alert("WIP")}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Remove from "My Rooms"} {mainTab == "chat" && {setMainTab("home")}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Close Chat} Sign Out
@@ -253,6 +261,7 @@ function Home() { {mainTab == "chat" && } + {mainTab == "home" &&
@@ -279,7 +288,29 @@ function Home() { {(tab == "create" && !loadingLoc) && } {(tab == "create" && loadingLoc) &&
Loading...
}
+
} + {(mainTab == "chat" && chatSidebar=="home") && +
+
+
+ Top +
+
+ Online Members +
+
+ Offline Members +
+
+ } + {(mainTab == "chat" && chatSidebar=="profile") && +
+
+ Profile +
+
+ }
) } -- 2.52.0 From c77f16d3fce61407b70aee915ab3ad06634450fa Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Mon, 4 Mar 2024 05:30:42 +0000 Subject: [PATCH 02/10] UI Worked On, Need to Pass Chatroom Path Data to sidebar somehow --- frontend-next/src/app/app/page.js | 48 +++++++++++++++++------------ frontend-next/src/app/login/page.js | 2 +- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 68ec564..0ce303d 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -1,5 +1,5 @@ "use client" -import { useState, useEffect, createContext, useContext } from 'react' +import { useState, useEffect } from 'react' import {Map, Marker, ZoomControl} from "pigeon-maps" import { Form, useForm } from "react-hook-form"; import { app } from "../api/firebase-config"; @@ -28,6 +28,14 @@ function Chat({chatObj}) { ) } +function Member() { + return ( +
+ LAX18 +
+ ) +} + function ChatRoomSidebar({roomObj, click}) { return (
@@ -68,12 +76,13 @@ function WelcomeMessage() { } -function Geo({loc}) { +// TODO: MAKE NOT MOVABLE +function Geo({loc, zoom, movable}) { if (loc) { return ( - + {zoom && } ) } else { @@ -92,24 +101,17 @@ function MainTabHome({loc}) { <>
- +
) } -function MainTabChatRoom({room}) { +function MainTabChatRoom({room, user}) { var { register, control, reset, handleSubmit} = useForm() const [chats, setData] = useState(null) const [isLoading, setLoading] = useState(true) - var user - fetch('/api/user') - .then((res) => res.json()) - .then((data) => { - user = data - }) - var unsubscribeUpdater useEffect(() => { unsubscribeUpdater = onValue(ref(database, `/rooms/${room}/chats`), (snapshot) => { @@ -130,7 +132,7 @@ function MainTabChatRoom({room}) { user: user.username, timestamp: new Date().getTime() } - set(ref(database,`/rooms/${room}/chats/${user.username}-${new Date().getTime()}`), payload) + set(ref(database,`/rooms/${room}/chats/${new Date().getTime()}-${user.username}`), payload) } @@ -201,7 +203,7 @@ function Home() { var rooms = snapshot.val() var roomArr = [] for (var room in rooms) { - roomArr.push( {setChatRoom(rooms[room].path+"/"+rooms[room].name+"-"+rooms[room].timestamp);setMainTab("chat")}}/>) + roomArr.push( {setChatRoom(rooms[room].path+"/"+rooms[room].name+"-"+rooms[room].timestamp);setMainTab("chat")}} user={user}/>) } setRoomData(roomArr) setRoomLoading(false) @@ -226,7 +228,6 @@ function Home() { get(ref(database, `/rooms/${path}`)).then((snapshot) => { if (snapshot.exists()) { var data = snapshot.val() - setMyRoomsData(data) for (var room in data) { nearbyArr.push( {setChatRoom(data[room].path+"/"+data[room].name+"-"+data[room].timestamp);setMainTab("chat")}}/>) } @@ -258,7 +259,7 @@ function Home() {
{(mainTab == "home" && !loadingLoc) && } {(mainTab == "home" && loadingLoc) && } - {mainTab == "chat" && } + {mainTab == "chat" && }
{mainTab == "home" && @@ -292,11 +293,20 @@ function Home() { {(mainTab == "chat" && chatSidebar=="home") &&
-
- Top +
+
+ +
+
+ Room Name
+ Room Description +
- Online Members +
+ Online Members +
+
Offline Members diff --git a/frontend-next/src/app/login/page.js b/frontend-next/src/app/login/page.js index 52637ce..96f2a1a 100644 --- a/frontend-next/src/app/login/page.js +++ b/frontend-next/src/app/login/page.js @@ -35,7 +35,7 @@ function Login() { + +
+ ) } - return ( -
-
- -
-
- Creating room near ({loc.latitude.toFixed(2)}, {loc.longitude.toFixed(2)}) -
- -
-
- ) -} - -function Home() { - var [tab, setTab] = useState("nearby") - var [mainTab, setMainTab] = useState("home") - var [chatRoom, setChatRoom] = useState("Dev") - const [chatSidebar, setChatSidebar] = useState("home") - var [user, setUser] = useState(null) - - - const [myRooms, setRoomData] = useState(null) - const [isRoomLoading, setRoomLoading] = useState(true) + // Grabs user data, saves to user, then lists the users saved rooms useEffect(() => { fetch('/api/user').then((res) => res.json()) .then((user) => { @@ -211,12 +225,7 @@ function Home() { }) }, []) - - const [location, setLocation] = useState(null); - const [loadingLoc, setLoadingLoc] = useState(true) - const [nearby, setNearby] = useState(null); - const [loadingNearby, setLoadingNearby] = useState(true); - const [myRoomsData, setMyRoomsData] = useState(null) + // Grabs the user location useEffect(() => { if('geolocation' in navigator) { // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API @@ -241,10 +250,11 @@ function Home() { } }, []); - return (
+ {/* Left Side of Page */}
+ {/* Header */}
@@ -256,12 +266,14 @@ function Home() { Sign Out
+ {/* Main Page Section */}
{(mainTab == "home" && !loadingLoc) && } {(mainTab == "home" && loadingLoc) && } {mainTab == "chat" && }
+ {/* Sidebar (Right Side of Page) */} {mainTab == "home" &&
@@ -290,7 +302,7 @@ function Home() { {(tab == "create" && loadingLoc) &&
Loading...
}
} - {(mainTab == "chat" && chatSidebar=="home") && + {(mainTab == "chat") &&
@@ -314,7 +326,7 @@ function Home() {
} - {(mainTab == "chat" && chatSidebar=="profile") && + {(mainTab == "profile") &&
Profile -- 2.52.0 From 1f22895904ef917c3e6f78d50b506afc45c3381f Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Tue, 5 Mar 2024 06:01:28 +0000 Subject: [PATCH 04/10] Prelim Chat Sidebar Data Working --- frontend-next/src/app/app/page.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index de9f42d..992e60d 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -168,6 +168,7 @@ function Home() { const [tab, setTab] = useState("nearby") // Sidebar Tab const [chatRoom, setChatRoom] = useState(null) // Selected chatroom path const [user, setUser] = useState(null) // Current user object + const [chatRoomObj, setChatRoomObj] = useState(null) // Current chatroom object const [myRooms, setRoomData] = useState(null) // Current user saved rooms list const [isRoomLoading, setRoomLoading] = useState(true) // myRooms loading variable, true = myrooms loading, false = finished loading const [location, setLocation] = useState(null) // location variable [lat,long] @@ -208,6 +209,14 @@ function Home() { ) } + function selectChatRoom(roomObj) { + var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp + setChatRoomObj(roomObj) + setChatRoom(path) + setMainTab("chat") + console.log(roomObj) + } + // Grabs user data, saves to user, then lists the users saved rooms useEffect(() => { fetch('/api/user').then((res) => res.json()) @@ -217,7 +226,7 @@ function Home() { var rooms = snapshot.val() var roomArr = [] for (var room in rooms) { - roomArr.push( {setChatRoom(rooms[room].path+"/"+rooms[room].name+"-"+rooms[room].timestamp);setMainTab("chat")}} user={user}/>) + roomArr.push( {selectChatRoom(rooms[room])}} user={user}/>) } setRoomData(roomArr) setRoomLoading(false) @@ -238,7 +247,7 @@ function Home() { if (snapshot.exists()) { var data = snapshot.val() for (var room in data) { - nearbyArr.push( {setChatRoom(data[room].path+"/"+data[room].name+"-"+data[room].timestamp);setMainTab("chat")}}/>) + nearbyArr.push( {selectChatRoom(data[room])}}/>) } setLoadingNearby(false) setNearby(nearbyArr) @@ -307,11 +316,11 @@ function Home() {
- +
- Room Name
- Room Description + {chatRoomObj.name}
+ {chatRoomObj.description}
-- 2.52.0 From d26e7d42906e12fd8a162b095567efdbe80770ae Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 6 Mar 2024 04:26:36 +0000 Subject: [PATCH 05/10] WIP --- frontend-next/src/app/app/page.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 992e60d..ddb78aa 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -32,10 +32,10 @@ function Chat({chatObj}) { } // Member for Active/Room members in sidebar -function Member() { +function Member({memberObj}) { return (
- LAX18 + {memberObj.username}
) } @@ -175,6 +175,9 @@ function Home() { const [loadingLoc, setLoadingLoc] = useState(true) // location variable loading, true = loading, false = finished loading const [nearby, setNearby] = useState(null); // nearby rooms array const [loadingNearby, setLoadingNearby] = useState(true); // loading nearby rooms array, true = loading, false = finished loading + const [chatroomOnline, setChatRoomOnline] = useState(null) // holds online users + const [chatroomUsers, setChatroomUsers] = useState(null) // holds all chatroom users + // CreateRoom Module for Sidebar Create Tab function CreateRoom({loc}) { @@ -212,6 +215,11 @@ function Home() { function selectChatRoom(roomObj) { var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp setChatRoomObj(roomObj) + /* Code for Room Data + get(ref(database, `/rooms/${path}`)).then((snapshot) => { + + }) + */ setChatRoom(path) setMainTab("chat") console.log(roomObj) @@ -316,7 +324,7 @@ function Home() {
- +
{chatRoomObj.name}
@@ -327,7 +335,7 @@ function Home() {
Online Members
- +
Offline Members -- 2.52.0 From 29d6833e42d11029281c12f49235dcb6b7cec5ec Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Sun, 10 Mar 2024 04:22:42 +0000 Subject: [PATCH 06/10] Initial Working Online/Offline Members --- frontend-next/src/app/app/page.js | 240 +++++++++++++++++++++--------- 1 file changed, 173 insertions(+), 67 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index ddb78aa..07d93c6 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -3,7 +3,7 @@ import { useState, useEffect } from 'react' import {Map, Marker, ZoomControl} from "pigeon-maps" import { Form, useForm } from "react-hook-form"; import { app } from "../api/firebase-config"; -import { getDatabase, ref, onValue, get, set} from "firebase/database"; +import { getDatabase, ref, onValue, get, set, remove} from "firebase/database"; var database = getDatabase(app) @@ -31,6 +31,28 @@ function Chat({chatObj}) { ) } +// System Chat Message +function SystemMessage({chatObj}) { + let dateOptions = { + weekday: 'long', + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }; + return ( +
+
+ {chatObj.user} has {chatObj.body} the room. +
+
+ {new Date(chatObj.timestamp).toLocaleString(dateOptions)} +
+
+ ) +} + // Member for Active/Room members in sidebar function Member({memberObj}) { return ( @@ -113,18 +135,22 @@ function MainTabHome({loc}) { } // Chatroom Module for Primary Tab -function MainTabChatRoom({room, user}) { +function MainTabChatRoom({roomObj}) { var { register, control, reset, handleSubmit} = useForm() const [chats, setData] = useState(null) const [isLoading, setLoading] = useState(true) var unsubscribeUpdater useEffect(() => { - unsubscribeUpdater = onValue(ref(database, `/rooms/${room}/chats`), (snapshot) => { + unsubscribeUpdater = onValue(ref(database, `/rooms/${roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp}/chats`), (snapshot) => { var chatsArr = [] var messages = snapshot.val() for (var message in messages) { - chatsArr.push() + if (messages[message].isSystem) { + chatsArr.push() + } else { + chatsArr.push() + } } setData(chatsArr.reverse()) setLoading(false) @@ -133,15 +159,18 @@ function MainTabChatRoom({room, user}) { function sendMessage(data) { reset() - var payload = { - body: data.message, - user: user.username, - timestamp: new Date().getTime() - } - set(ref(database,`/rooms/${room}/chats/${new Date().getTime()}-${user.username}`), payload) + fetch('/api/user').then((res) => res.json()) + .then((user) => { + var payload = { + body: data.message, + user: user.username, + isSystem: false, + timestamp: new Date().getTime() + } + set(ref(database,`/rooms/${roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp}/chats/${new Date().getTime()}-${user.username}`), payload) + }) } - if (isLoading) return
Loading
if (!chats) return
No Chats
return ( @@ -166,8 +195,7 @@ function Home() { // State variables for app page const [mainTab, setMainTab] = useState("home") // Primary tab const [tab, setTab] = useState("nearby") // Sidebar Tab - const [chatRoom, setChatRoom] = useState(null) // Selected chatroom path - const [user, setUser] = useState(null) // Current user object + const [loadingUser, setLoadingUser] = useState(true) const [chatRoomObj, setChatRoomObj] = useState(null) // Current chatroom object const [myRooms, setRoomData] = useState(null) // Current user saved rooms list const [isRoomLoading, setRoomLoading] = useState(true) // myRooms loading variable, true = myrooms loading, false = finished loading @@ -177,7 +205,76 @@ function Home() { const [loadingNearby, setLoadingNearby] = useState(true); // loading nearby rooms array, true = loading, false = finished loading const [chatroomOnline, setChatRoomOnline] = useState(null) // holds online users const [chatroomUsers, setChatroomUsers] = useState(null) // holds all chatroom users + const [users, setUsers] = useState(null) // all users from firebase + + // Handles closing the tab and removing the user from the online section + useEffect(() => { + window.addEventListener("beforeunload", (ev) => { + ev.preventDefault(); + fetch('/api/user').then((res) => res.json()) + .then((user) => { + if (chatRoomObj != null) { + var payload = { + body: "left", + user: user.username, + isSystem: true, + timestamp: new Date().getTime() + } + set(ref(database,`/rooms/${chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp}/chats/${new Date().getTime()}-${user.username}`), payload) + remove(ref(database, `/rooms/${chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp}/users/online/${user.uid}`)) + } + }) + }); + }, [chatRoomObj]) + // Grabs user data, saves to user, then lists the users saved rooms + useEffect(() => { + fetch('/api/user').then((res) => res.json()) + .then((user) => { + get(ref(database, '/users/'+user.uid+'/rooms')).then((snapshot) => { + var rooms = snapshot.val() + var roomArr = [] + for (var room in rooms) { + roomArr.push( {selectChatRoom(rooms[room], user)}}/>) + } + setRoomData(roomArr) + setRoomLoading(false) + }) + }) +}, []) + + // Grabs the user location + useEffect(() => { + if('geolocation' in navigator) { + // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API + navigator.geolocation.getCurrentPosition(({ coords }) => { + setLocation(coords) + setLoadingLoc(false) + var nearbyArr = [] + var path = String(coords.latitude.toFixed(2)).replace(".","")+"/"+String(coords.longitude.toFixed(2)).replace(".","") + get(ref(database, `/rooms/${path}`)).then((snapshot) => { + if (snapshot.exists()) { + var data = snapshot.val() + for (var room in data) { + nearbyArr.push( {selectChatRoom(data[room])}}/>) + } + setLoadingNearby(false) + setNearby(nearbyArr) + } else { + setLoadingNearby(false) + } + }) + }) + } + }, []); + + // Grab list of all users + useEffect(() => { + get(ref(database, `/users`)).then((snapshot) => { + setUsers(snapshot.val()) + }) + + }, []); // CreateRoom Module for Sidebar Create Tab function CreateRoom({loc}) { @@ -212,60 +309,66 @@ function Home() { ) } + // Selects chat room function selectChatRoom(roomObj) { - var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp - setChatRoomObj(roomObj) - /* Code for Room Data - get(ref(database, `/rooms/${path}`)).then((snapshot) => { + fetch('/api/user').then((res) => res.json()) + .then((user) => { + // Path of chatroom + var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp + setChatRoomObj(roomObj) + + // Send entered message + var payload = { + body: "entered", + user: user.username, + isSystem: true, + timestamp: new Date().getTime() + } + set(ref(database,`/rooms/${path}/chats/${new Date().getTime()}-${user.username}`), payload) + // Code for Room Data + set(ref(database, `/rooms/${path}/users/online/${user.uid}`), user) + onValue(ref(database, `/rooms/${path}`), (snapshot) => { + + // Active users list + if (snapshot.val().hasOwnProperty("users") && snapshot.val().users.hasOwnProperty("online")) { + var activeUsers = [] + var activeUsersJSON = snapshot.val().users.online + for (var user in activeUsersJSON) + activeUsers.push() + setChatRoomOnline(activeUsers) + } + + // Users who added to "my rooms" + if (snapshot.val().hasOwnProperty("users") && snapshot.val().users.hasOwnProperty("all")) { + var allUsers = [] + var allUsersJSON = snapshot.val().users.all + for (var user in allUsersJSON) + allUsers.push() + setChatroomUsers(allUsers) + } + + }) + setMainTab("chat") }) - */ - setChatRoom(path) - setMainTab("chat") - console.log(roomObj) } - // Grabs user data, saves to user, then lists the users saved rooms - useEffect(() => { - fetch('/api/user').then((res) => res.json()) - .then((user) => { - setUser(user) - get(ref(database, '/users/'+user.uid+'/rooms')).then((snapshot) => { - var rooms = snapshot.val() - var roomArr = [] - for (var room in rooms) { - roomArr.push( {selectChatRoom(rooms[room])}} user={user}/>) - } - setRoomData(roomArr) - setRoomLoading(false) - }) - }) - }, []) - - // Grabs the user location - useEffect(() => { - if('geolocation' in navigator) { - // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API - navigator.geolocation.getCurrentPosition(({ coords }) => { - setLocation(coords) - setLoadingLoc(false) - var nearbyArr = [] - var path = String(coords.latitude.toFixed(2)).replace(".","")+"/"+String(coords.longitude.toFixed(2)).replace(".","") - get(ref(database, `/rooms/${path}`)).then((snapshot) => { - if (snapshot.exists()) { - var data = snapshot.val() - for (var room in data) { - nearbyArr.push( {selectChatRoom(data[room])}}/>) - } - setLoadingNearby(false) - setNearby(nearbyArr) - } else { - setLoadingNearby(false) - } - }) - }) - } - }, []); + // Closes chat room + function closeChatRoom(roomObj) { + fetch('/api/user').then((res) => res.json()) + .then((user) => { + var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp + var payload = { + body: "left", + user: user.username, + isSystem: true, + timestamp: new Date().getTime() + } + set(ref(database,`/rooms/${path}/chats/${new Date().getTime()}-${user.username}`), payload) + remove(ref(database, `/rooms/${path}/users/online/${user.uid}`)) + setMainTab("home") + }) + } return ( @@ -287,7 +390,7 @@ function Home() {
{(mainTab == "home" && !loadingLoc) && } {(mainTab == "home" && loadingLoc) && } - {mainTab == "chat" && } + {mainTab == "chat" && }
{/* Sidebar (Right Side of Page) */} @@ -301,7 +404,7 @@ function Home() {
{setTab("create")}}>Create
- {tab == "nearby" &&
+ {(tab == "nearby") &&
{(!nearby && !loadingNearby) &&
No Nearby Rooms
Create One?
} {loadingNearby &&
Loading...
} @@ -335,10 +438,13 @@ function Home() {
Online Members
- + {chatroomOnline}
- Offline Members +
+ All Members +
+ {chatroomUsers}
-- 2.52.0 From aa4934193777b91d81ee4c0d089fc7111b4e8b73 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Sun, 10 Mar 2024 06:10:39 +0000 Subject: [PATCH 07/10] myRooms Working --- frontend-next/package-lock.json | 9 +++ frontend-next/package.json | 1 + frontend-next/src/app/app/page.js | 102 +++++++++++++++++++++--------- 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/frontend-next/package-lock.json b/frontend-next/package-lock.json index 7d4b26b..3a0c916 100644 --- a/frontend-next/package-lock.json +++ b/frontend-next/package-lock.json @@ -13,6 +13,7 @@ "next": "^14.1.0", "pigeon-maps": "^0.21.3", "react": "^18.2.0", + "react-beforeunload": "^2.6.0", "react-dom": "^18.2.0", "react-hook-form": "^7.50.1" }, @@ -5739,6 +5740,14 @@ "node": ">=0.10.0" } }, + "node_modules/react-beforeunload": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-beforeunload/-/react-beforeunload-2.6.0.tgz", + "integrity": "sha512-aKrGaRNc7fZQlDnmSYrXu4cbz9QEPhScA4A2mLxhjcULDy4VILLyLhSEjg2goIw3o5LQ1zss44kmQh5LXWYGCw==", + "peerDependencies": { + "react": "^16.8.0 || 17 || 18" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", diff --git a/frontend-next/package.json b/frontend-next/package.json index 1912fa3..544379a 100644 --- a/frontend-next/package.json +++ b/frontend-next/package.json @@ -14,6 +14,7 @@ "next": "^14.1.0", "pigeon-maps": "^0.21.3", "react": "^18.2.0", + "react-beforeunload": "^2.6.0", "react-dom": "^18.2.0", "react-hook-form": "^7.50.1" }, diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 07d93c6..ad656e7 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -4,6 +4,7 @@ import {Map, Marker, ZoomControl} from "pigeon-maps" import { Form, useForm } from "react-hook-form"; import { app } from "../api/firebase-config"; import { getDatabase, ref, onValue, get, set, remove} from "firebase/database"; +import { useBeforeunload } from 'react-beforeunload'; var database = getDatabase(app) @@ -64,8 +65,12 @@ function Member({memberObj}) { // Chat Room for myRooms and Nearby in sidebar function ChatRoomSidebar({roomObj, click}) { + // TODO: Gross fix but it works +function clicker() { + click(roomObj.name, roomObj) +} return ( -
+
{roomObj.name}
{roomObj.description}
@@ -140,9 +145,9 @@ function MainTabChatRoom({roomObj}) { const [chats, setData] = useState(null) const [isLoading, setLoading] = useState(true) - var unsubscribeUpdater + // Message updater useEffect(() => { - unsubscribeUpdater = onValue(ref(database, `/rooms/${roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp}/chats`), (snapshot) => { + onValue(ref(database, `/rooms/${roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp}/chats`), (snapshot) => { var chatsArr = [] var messages = snapshot.val() for (var message in messages) { @@ -195,10 +200,10 @@ function Home() { // State variables for app page const [mainTab, setMainTab] = useState("home") // Primary tab const [tab, setTab] = useState("nearby") // Sidebar Tab - const [loadingUser, setLoadingUser] = useState(true) const [chatRoomObj, setChatRoomObj] = useState(null) // Current chatroom object const [myRooms, setRoomData] = useState(null) // Current user saved rooms list - const [isRoomLoading, setRoomLoading] = useState(true) // myRooms loading variable, true = myrooms loading, false = finished loading + const [isRoomLoading, setRoomLoading] = useState(true) // myRooms loading variable, true = myRooms loading, false = finished loading + const [isMyRoom, setIsMyRoom] = useState(false) // Is current room in myRooms? true, false const [location, setLocation] = useState(null) // location variable [lat,long] const [loadingLoc, setLoadingLoc] = useState(true) // location variable loading, true = loading, false = finished loading const [nearby, setNearby] = useState(null); // nearby rooms array @@ -206,26 +211,7 @@ function Home() { const [chatroomOnline, setChatRoomOnline] = useState(null) // holds online users const [chatroomUsers, setChatroomUsers] = useState(null) // holds all chatroom users const [users, setUsers] = useState(null) // all users from firebase - - // Handles closing the tab and removing the user from the online section - useEffect(() => { - window.addEventListener("beforeunload", (ev) => { - ev.preventDefault(); - fetch('/api/user').then((res) => res.json()) - .then((user) => { - if (chatRoomObj != null) { - var payload = { - body: "left", - user: user.username, - isSystem: true, - timestamp: new Date().getTime() - } - set(ref(database,`/rooms/${chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp}/chats/${new Date().getTime()}-${user.username}`), payload) - remove(ref(database, `/rooms/${chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp}/users/online/${user.uid}`)) - } - }) - }); - }, [chatRoomObj]) + const [alreadyLeft, setAlreadyLeft] = useState(false) // if already left from room // Grabs user data, saves to user, then lists the users saved rooms useEffect(() => { @@ -235,7 +221,8 @@ function Home() { var rooms = snapshot.val() var roomArr = [] for (var room in rooms) { - roomArr.push( {selectChatRoom(rooms[room], user)}}/>) + var newRoom = + roomArr.push(newRoom) } setRoomData(roomArr) setRoomLoading(false) @@ -256,7 +243,7 @@ function Home() { if (snapshot.exists()) { var data = snapshot.val() for (var room in data) { - nearbyArr.push( {selectChatRoom(data[room])}}/>) + nearbyArr.push() } setLoadingNearby(false) setNearby(nearbyArr) @@ -310,11 +297,21 @@ function Home() { } // Selects chat room - function selectChatRoom(roomObj) { + function selectChatRoom(roomName, roomObj) { fetch('/api/user').then((res) => res.json()) .then((user) => { // Path of chatroom var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp + + // Test if Room is in myRooms + if (myRooms != null && roomName in myRooms.keys) { + // its in there + setIsMyRoom(true) + } else { + // its not in there + setIsMyRoom(false) + } + setChatRoomObj(roomObj) // Send entered message @@ -350,6 +347,7 @@ function Home() { }) setMainTab("chat") + setAlreadyLeft(false) }) } @@ -366,10 +364,54 @@ function Home() { } set(ref(database,`/rooms/${path}/chats/${new Date().getTime()}-${user.username}`), payload) remove(ref(database, `/rooms/${path}/users/online/${user.uid}`)) + setChatRoomObj(null) + setAlreadyLeft(true) setMainTab("home") }) } + // Adds room to myRooms + function addToMyRooms() { + fetch('/api/user').then((res) => res.json()) + .then((user) => { + set(ref(database,`/users/${user.uid}/rooms/${chatRoomObj.name}-${chatRoomObj.timestamp}`), { + name: chatRoomObj.name, + path: chatRoomObj.path, + timestamp: chatRoomObj.timestamp, + description: chatRoomObj.description, + longitude: chatRoomObj.longitude, + latitude: chatRoomObj.latitude, + }) + }) + setIsMyRoom(true) + } + + // Deletes saved room from myRooms + function removeFromMyRooms() { + fetch('/api/user').then((res) => res.json()) + .then((user) => { + remove(ref(database,`/users/${user.uid}/rooms/${chatRoomObj.name}-${chatRoomObj.timestamp}`)) + }) + setIsMyRoom(false) + } + + // Fires to tell other uses that you are leaving the room + useBeforeunload(() => { + fetch('/api/user').then((res) => res.json()) + .then((user) => { + if (chatRoomObj && mainTab == "chat") { + var payload = { + body: "left", + user: user.username, + isSystem: true, + timestamp: new Date().getTime() + } + set(ref(database,`/rooms/${chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp}/chats/${new Date().getTime()}-${user.username}`), payload) + remove(ref(database, `/rooms/${chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp}/users/online/${user.uid}`)) + } + }) + }); + return (
{/* Left Side of Page */} @@ -380,8 +422,8 @@ function Home() {
- {(mainTab == "chat") && {alert("WIP")}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Add to "My Rooms"} - {(mainTab == "chat") && {alert("WIP")}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Remove from "My Rooms"} + {(mainTab == "chat" && isMyRoom == false) && {addToMyRooms()}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Add to "My Rooms"} + {(mainTab == "chat" && isMyRoom == true) && {removeFromMyRooms()}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Remove from "My Rooms"} {mainTab == "chat" && {closeChatRoom(chatRoomObj)}} className="p-2 cursor-pointer bg-[#dee0e0] bg-cyan-500 text-white font-bold rounded-full mr-5">Close Chat} Sign Out
-- 2.52.0 From 9802ea80962af980233ce9ae9922306ca91761d0 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Sun, 10 Mar 2024 06:27:31 +0000 Subject: [PATCH 08/10] Final myRooms Fix --- frontend-next/src/app/app/page.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index ad656e7..474e434 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -67,7 +67,7 @@ function Member({memberObj}) { function ChatRoomSidebar({roomObj, click}) { // TODO: Gross fix but it works function clicker() { - click(roomObj.name, roomObj) + click(roomObj.name+"-"+roomObj.timestamp, roomObj) } return (
@@ -201,6 +201,7 @@ function Home() { const [mainTab, setMainTab] = useState("home") // Primary tab const [tab, setTab] = useState("nearby") // Sidebar Tab const [chatRoomObj, setChatRoomObj] = useState(null) // Current chatroom object + const [myRoomsObj, setMyRoomsObj] = useState(null) // My Rooms Object const [myRooms, setRoomData] = useState(null) // Current user saved rooms list const [isRoomLoading, setRoomLoading] = useState(true) // myRooms loading variable, true = myRooms loading, false = finished loading const [isMyRoom, setIsMyRoom] = useState(false) // Is current room in myRooms? true, false @@ -219,6 +220,7 @@ function Home() { .then((user) => { get(ref(database, '/users/'+user.uid+'/rooms')).then((snapshot) => { var rooms = snapshot.val() + setMyRoomsObj(rooms) var roomArr = [] for (var room in rooms) { var newRoom = @@ -263,6 +265,19 @@ function Home() { }, []); + useEffect(() => { + if (myRoomsObj && chatRoomObj) { + var roomName = chatRoomObj.name+"-"+chatRoomObj.timestamp + if (myRooms != null && roomName in myRoomsObj) { + // its in there + setIsMyRoom(true) + } else { + // its not in there + setIsMyRoom(false) + } + } + }, [chatRoomObj]) + // CreateRoom Module for Sidebar Create Tab function CreateRoom({loc}) { var { register, control, reset, handleSubmit} = useForm() @@ -303,15 +318,6 @@ function Home() { // Path of chatroom var path = roomObj.path+"/"+roomObj.name+"-"+roomObj.timestamp - // Test if Room is in myRooms - if (myRooms != null && roomName in myRooms.keys) { - // its in there - setIsMyRoom(true) - } else { - // its not in there - setIsMyRoom(false) - } - setChatRoomObj(roomObj) // Send entered message -- 2.52.0 From b1009b186e6dfae1e8f07548491c2ffa81c21ed3 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Sun, 10 Mar 2024 16:43:08 +0000 Subject: [PATCH 09/10] Fix Added Members, onValue for Room List, Nearby --- frontend-next/src/app/app/page.js | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/frontend-next/src/app/app/page.js b/frontend-next/src/app/app/page.js index 474e434..3c19426 100644 --- a/frontend-next/src/app/app/page.js +++ b/frontend-next/src/app/app/page.js @@ -211,6 +211,7 @@ function Home() { const [loadingNearby, setLoadingNearby] = useState(true); // loading nearby rooms array, true = loading, false = finished loading const [chatroomOnline, setChatRoomOnline] = useState(null) // holds online users const [chatroomUsers, setChatroomUsers] = useState(null) // holds all chatroom users + const [chatroomUsersLoading ,setChatroomUsersLoading] = useState(true) const [users, setUsers] = useState(null) // all users from firebase const [alreadyLeft, setAlreadyLeft] = useState(false) // if already left from room @@ -218,7 +219,8 @@ function Home() { useEffect(() => { fetch('/api/user').then((res) => res.json()) .then((user) => { - get(ref(database, '/users/'+user.uid+'/rooms')).then((snapshot) => { + onValue(ref(database, '/users/'+user.uid+'/rooms'),(snapshot) => { + setRoomLoading(true) var rooms = snapshot.val() setMyRoomsObj(rooms) var roomArr = [] @@ -239,9 +241,10 @@ function Home() { navigator.geolocation.getCurrentPosition(({ coords }) => { setLocation(coords) setLoadingLoc(false) - var nearbyArr = [] var path = String(coords.latitude.toFixed(2)).replace(".","")+"/"+String(coords.longitude.toFixed(2)).replace(".","") - get(ref(database, `/rooms/${path}`)).then((snapshot) => { + setLoadingNearby(true) + onValue(ref(database, `/rooms/${path}`), (snapshot) => { + var nearbyArr = [] if (snapshot.exists()) { var data = snapshot.val() for (var room in data) { @@ -265,6 +268,7 @@ function Home() { }, []); + // Dont Double Send Leaving Message useEffect(() => { if (myRoomsObj && chatRoomObj) { var roomName = chatRoomObj.name+"-"+chatRoomObj.timestamp @@ -333,6 +337,9 @@ function Home() { set(ref(database, `/rooms/${path}/users/online/${user.uid}`), user) onValue(ref(database, `/rooms/${path}`), (snapshot) => { + setChatRoomOnline(null) + setChatroomUsers(null) + // Active users list if (snapshot.val().hasOwnProperty("users") && snapshot.val().users.hasOwnProperty("online")) { var activeUsers = [] @@ -343,12 +350,16 @@ function Home() { } // Users who added to "my rooms" + console.log(snapshot.val().hasOwnProperty("users") && snapshot.val().users.hasOwnProperty("all")) if (snapshot.val().hasOwnProperty("users") && snapshot.val().users.hasOwnProperty("all")) { + setChatroomUsersLoading(true) var allUsers = [] var allUsersJSON = snapshot.val().users.all for (var user in allUsersJSON) allUsers.push() setChatroomUsers(allUsers) + setChatroomUsersLoading(false) + } }) @@ -388,6 +399,8 @@ function Home() { longitude: chatRoomObj.longitude, latitude: chatRoomObj.latitude, }) + var path = chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp + set(ref(database, `/rooms/${path}/users/all/${user.uid}`), user) }) setIsMyRoom(true) } @@ -396,7 +409,9 @@ function Home() { function removeFromMyRooms() { fetch('/api/user').then((res) => res.json()) .then((user) => { + var path = chatRoomObj.path+"/"+chatRoomObj.name+"-"+chatRoomObj.timestamp remove(ref(database,`/users/${user.uid}/rooms/${chatRoomObj.name}-${chatRoomObj.timestamp}`)) + remove(ref(database, `/rooms/${path}/users/all/${user.uid}`)) }) setIsMyRoom(false) } @@ -492,7 +507,7 @@ function Home() {
All Members
- {chatroomUsers} + {!chatroomUsersLoading && chatroomUsers}
-- 2.52.0 From 0c8ca183267dc12f166bb9dd0c5350cbc2873111 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Sun, 10 Mar 2024 17:39:08 +0000 Subject: [PATCH 10/10] Add counter for unauthenticated users on homepage to show rooms nearby --- frontend-next/src/app/page.js | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/frontend-next/src/app/page.js b/frontend-next/src/app/page.js index 87cc7d7..a2ab97f 100644 --- a/frontend-next/src/app/page.js +++ b/frontend-next/src/app/page.js @@ -1,10 +1,17 @@ "use client" import { useState, useEffect } from 'react' +import { app } from "./api/firebase-config"; +import { getDatabase, ref, get} from "firebase/database"; + +var database = getDatabase(app) + function Home() { const [statusCode, setData] = useState(null) const [isLoading, setLoading] = useState(true) + const [isLoadingLoc, setLoadingLoc] = useState(true) + const [roomCount, setRoomCount] = useState(null) useEffect(() => { fetch('/api/user') .then((res) => res.status) @@ -13,6 +20,28 @@ function Home() { setLoading(false) }) }, []) + + useEffect(() => { + if('geolocation' in navigator) { + // Retrieve latitude & longitude coordinates from `navigator.geolocation` Web API + navigator.geolocation.getCurrentPosition(({ coords }) => { + var path = String(coords.latitude.toFixed(2)).replace(".","")+"/"+String(coords.longitude.toFixed(2)).replace(".","") + get(ref(database, `/rooms/${path}`)).then((snapshot) => { + if (snapshot.exists()) { + var count = 0 + for (var room in snapshot.val()) { + count += 1 + } + setRoomCount(count) + } else { + console.log("No rooms nearby") + setRoomCount(0) + } + setLoadingLoc(false) + }); + }); + } + }) return (
@@ -29,7 +58,8 @@ function Home() {
} {statusCode == 200 && } - + {(!isLoadingLoc && roomCount != 0) &&
Join others in {roomCount} rooms near you!
} + {(isLoadingLoc || (roomCount == 0 && !isLoadingLoc)) &&
Start the conversation today!
}
-- 2.52.0