Merge branch 'main' into npease-chat-message-deletion
This commit is contained in:
@@ -8,7 +8,6 @@ import { useAuthState } from "react-firebase-hooks/auth"
|
||||
|
||||
// Refactored Component Imports
|
||||
|
||||
|
||||
// Data Structure Imports
|
||||
import { ProfileRoom } from "../../components/app/profile/ProfileRoom";
|
||||
import { ProfileEdit } from "../../components/app/profile/ProfileEdit";
|
||||
@@ -20,6 +19,9 @@ import { Header } from "../../components/app/header";
|
||||
// Friend Import
|
||||
import { addFriend } from "../../components/app/friends/friends";
|
||||
|
||||
// Icons
|
||||
import CircleIcon from '@mui/icons-material/Circle';
|
||||
|
||||
/**
|
||||
* User Profile Page
|
||||
* @returns {Object} - User Profile Page
|
||||
@@ -125,11 +127,10 @@ function UserProfile() {
|
||||
<div>
|
||||
<img
|
||||
src={profileData.pfp}
|
||||
style={{maxWidth: "350px", maxHeight: "450px"}}
|
||||
className="relative mx-auto rounded-2xl overflow-hidden"
|
||||
className="relative mx-auto rounded-2xl overflow-hidden w-[90%]"
|
||||
/>
|
||||
<div className="font-bold text-[30px]">
|
||||
{profileData.firstName} {profileData.lastName}
|
||||
<div className="font-bold text-[30px] flex justify-center items-center">
|
||||
{profileData.lastOnline == true && <CircleIcon className="text-lime-600 mr-3"/>}{profileData.firstName} {profileData.lastName}
|
||||
</div>
|
||||
<div className="text-[20px]">@{profileData.username}</div>
|
||||
<div className="pt-5">{profileData.bio}</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {remove, ref} from "firebase/database"
|
||||
// Icons
|
||||
import PersonIcon from '@mui/icons-material/Person';
|
||||
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
|
||||
import CircleIcon from '@mui/icons-material/Circle';
|
||||
|
||||
// Colors for Messages
|
||||
const userColors = [
|
||||
@@ -42,19 +43,27 @@ let dateOptions = {
|
||||
* @returns {String} - Formatted Message (IN HTML)
|
||||
*/
|
||||
function RMF(message) {
|
||||
var IMG_END = [".jpg", ".jpeg", ".png", ".gif", ".webp"]
|
||||
var URLREGEX = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;
|
||||
var URLmatch = message.match(URLREGEX);
|
||||
var newMessage = URLmatch ? [] : message
|
||||
if (URLmatch) {
|
||||
for (var i = 0; i < URLmatch.length; i++) {
|
||||
var link = (<span>
|
||||
{message.split(URLmatch[i])[0]}
|
||||
<Link href={"https://"+URLmatch[i]} target="_blank" className="hover:underline">{URLmatch[i]}</Link>
|
||||
{message.split(URLmatch[i])[1]}
|
||||
</span>)
|
||||
message = link
|
||||
if (IMG_END.includes(URLmatch[i].slice(-4)) || IMG_END.includes(URLmatch[i].slice(-5))) {
|
||||
// Its a photo
|
||||
newMessage.push((<img src={"https://"+URLmatch[i]} className="max-w-[100%] max-h-[100%]"/>))
|
||||
} else {
|
||||
console.log(message)
|
||||
newMessage.push((<span className="mr-2">
|
||||
{URLmatch.length == 1 && message.split(URLmatch[i])[0]}
|
||||
<Link href={"https://"+URLmatch[i]} target="_blank" className="hover:underline">{URLmatch[i]}</Link>
|
||||
{(i == URLmatch.length || URLmatch.length == 1) && message.split(URLmatch[i])[1]}
|
||||
</span>))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return message
|
||||
return newMessage
|
||||
}
|
||||
/**
|
||||
* Grabs Window Size
|
||||
@@ -101,15 +110,15 @@ const generateColor = (user_str) => {
|
||||
* @props {JSON} chatObj - Chat Object
|
||||
* @returns {Object} - Chat Message Component
|
||||
*/
|
||||
export function Chat({ chatObj, user, path }) {
|
||||
|
||||
export function Chat({ chatObj }) {
|
||||
function deleteMessage() {
|
||||
remove(ref(database, `/rooms/${path}/chats/${chatObj.timestamp}-${chatObj.user}`))
|
||||
}
|
||||
|
||||
var message = RMF(chatObj.body)
|
||||
if (message)
|
||||
message = filter.clean(message)
|
||||
|
||||
if (chatObj.body) {
|
||||
var message = filter.clean(chatObj.body)
|
||||
message = RMF(message)
|
||||
}
|
||||
return (
|
||||
<div className="width-[100%] bg-white rounded-lg mt-1 text-left p-1 grid grid-cols-2 mr-2">
|
||||
<div>
|
||||
@@ -163,7 +172,7 @@ export function Member({ memberObj }) {
|
||||
return (
|
||||
<Link href={"/user?uid=" + memberObj.uid}>
|
||||
<div className="cursor-pointer g-[aliceblue] rounded-lg m-3 shadow-xl p-2">
|
||||
{memberObj.username}
|
||||
{memberObj.lastOnline == true && <CircleIcon className="text-lime-600 mr-1 relative top-[-1px]" fontSize="20px"/>}{memberObj.username}
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -44,10 +44,12 @@ export function DM({user,friendObj}) {
|
||||
</div>
|
||||
<div className='col-span-3 cursor-pointer'>
|
||||
<div onClick={() => {openDM(user,friendObj.uid)}}>
|
||||
<div className='inline-block mr-8'><img src={friendObj.pfp} className='w-[38px] h-[50px]'/></div>
|
||||
<div className='inline-block relative top-[-6px]'>
|
||||
<div className="font-bold">{friendObj.firstName} {friendObj.lastName}</div>
|
||||
<div className="">@{friendObj.username}</div>
|
||||
<div className='grid grid-cols-2 justify-items-center'>
|
||||
<div className='mr-8'><img src={friendObj.pfp} className= 'w-[50px] h-[50px]'/></div>
|
||||
<div className=''>
|
||||
<div className="font-bold">{friendObj.lastOnline == true && <CircleIcon className="text-lime-600 mr-1 relative top-[-2px]" fontSize="20px"/>}{friendObj.firstName} {friendObj.lastName}</div>
|
||||
<div className="">@{friendObj.username}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { openDM } from './dm';
|
||||
// Icons
|
||||
import CheckIcon from '@mui/icons-material/Check';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import CircleIcon from '@mui/icons-material/Circle';
|
||||
|
||||
/**
|
||||
* Send a friend request to a user
|
||||
@@ -39,10 +40,12 @@ export function Friend({user,friendObj}) {
|
||||
</div>
|
||||
<div className='col-span-3 cursor-pointer'>
|
||||
<Link href={`/user?uid=${friendObj.uid}`}>
|
||||
<div className='inline-block mr-8'><img src={friendObj.pfp} className= 'w-[38px] h-[50px]'/></div>
|
||||
<div className='inline-block relative top-[-6px]'>
|
||||
<div className="font-bold">{friendObj.firstName} {friendObj.lastName}</div>
|
||||
<div className="">@{friendObj.username}</div>
|
||||
<div className='grid grid-cols-2 justify-items-center'>
|
||||
<div className='mr-8'><img src={friendObj.pfp} className= 'w-[50px] h-[50px]'/></div>
|
||||
<div className=''>
|
||||
<div className="font-bold">{friendObj.lastOnline == true && <CircleIcon className="text-lime-600 mr-1 relative top-[-2px]" fontSize="20px"/>}{friendObj.firstName} {friendObj.lastName}</div>
|
||||
<div className="">@{friendObj.username}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import Link from "next/link"
|
||||
|
||||
// Firebase Imports
|
||||
import { database } from "../../../firebase-config";
|
||||
import { ref, set, remove } from "firebase/database";
|
||||
import { ref, set, remove, onDisconnect, serverTimestamp } from "firebase/database";
|
||||
|
||||
// Component Imports
|
||||
import { NotificationPanel } from "./notifications/notifications";
|
||||
@@ -88,6 +88,17 @@ export function Header({mainTab,chatRoomObj,user,sidebarControl}) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sets User Online / Offline
|
||||
// Stored in header for easy code maintenance and retains user online/offline throughout app
|
||||
// Makes user online
|
||||
if (user.invisibleStatus == false) {
|
||||
set(ref(database, `/users/${user.uid}/lastOnline`), true)
|
||||
}
|
||||
|
||||
// Makes user offline (with last time online)
|
||||
onDisconnect(ref(database, `/users/${user.uid}/lastOnline`)).set(serverTimestamp())
|
||||
|
||||
return (
|
||||
<div className="flex m-2 rounded-lg h-[63px] bg-white shadow-2xl p-1">
|
||||
<div className="flex shrink h-[60px]">
|
||||
|
||||
@@ -50,23 +50,25 @@ export function ChatRoom({ roomObj, user }) {
|
||||
* @returns {void}
|
||||
*/
|
||||
function sendMessage(data) {
|
||||
reset();
|
||||
var payload = {
|
||||
body: data.message,
|
||||
user: user.username,
|
||||
uid: user.uid,
|
||||
isSystem: false,
|
||||
timestamp: new Date().getTime(),
|
||||
};
|
||||
set(
|
||||
ref(
|
||||
database,
|
||||
`/rooms/${
|
||||
roomObj.path + "/" + roomObj.name + "-" + roomObj.timestamp
|
||||
}/chats/${new Date().getTime()}-${user.username}`
|
||||
),
|
||||
payload
|
||||
);
|
||||
if (data.message) {
|
||||
reset();
|
||||
var payload = {
|
||||
body: data.message,
|
||||
user: user.username,
|
||||
uid: user.uid,
|
||||
isSystem: false,
|
||||
timestamp: new Date().getTime(),
|
||||
};
|
||||
set(
|
||||
ref(
|
||||
database,
|
||||
`/rooms/${
|
||||
roomObj.path + "/" + roomObj.name + "-" + roomObj.timestamp
|
||||
}/chats/${new Date().getTime()}-${user.username}`
|
||||
),
|
||||
payload
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!chats) return <div>No Chats</div>;
|
||||
|
||||
@@ -3,8 +3,9 @@ import { Popover } from "@headlessui/react";
|
||||
import Link from "next/link"
|
||||
|
||||
// Firebase Imports
|
||||
import { auth } from "../../../../firebase-config";
|
||||
import { auth, database } from "../../../../firebase-config";
|
||||
import { signOut } from "firebase/auth";
|
||||
import {update, ref, serverTimestamp} from "firebase/database";
|
||||
|
||||
/**
|
||||
* Logs out from Firebase Authentication
|
||||
@@ -43,6 +44,18 @@ export function ProfilePanel({user}) {
|
||||
>
|
||||
View Profile
|
||||
</Link>
|
||||
<div className="rounded-xl p-4 hover:bg-[#C0C0C0] cursor-pointer"
|
||||
onClick={() => {
|
||||
// Toggle Invisible Status
|
||||
update(ref(database, `/users/${user.uid}`), {
|
||||
invisibleStatus: user.invisibleStatus? !user.invisibleStatus: true,
|
||||
lastOnline: user.invisibleStatus? true: serverTimestamp()
|
||||
}
|
||||
);
|
||||
}}
|
||||
>
|
||||
{user.invisibleStatus ? "Go Online" : "Go Invisible"}
|
||||
</div>
|
||||
<Link
|
||||
className="rounded-xl p-4 hover:bg-[#C0C0C0]"
|
||||
onClick={logout}
|
||||
|
||||
Reference in New Issue
Block a user