Skip to content

Commit

Permalink
➕ added facebook messenger features(#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
SashenJayathilaka committed Oct 7, 2022
1 parent f6451eb commit 8929913
Show file tree
Hide file tree
Showing 9 changed files with 362 additions and 73 deletions.
45 changes: 34 additions & 11 deletions components/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable @next/next/no-img-element */
import AddIcon from "@mui/icons-material/Add";
import DarkModeIcon from "@mui/icons-material/DarkMode";
import HomeIcon from "@mui/icons-material/Home";
import LightModeIcon from "@mui/icons-material/LightMode";
import LiveTvIcon from "@mui/icons-material/LiveTv";
import MenuIcon from "@mui/icons-material/Menu";
import MessageIcon from "@mui/icons-material/Message";
Expand All @@ -9,18 +11,20 @@ import PeopleIcon from "@mui/icons-material/People";
import StoreIcon from "@mui/icons-material/Store";
import ViewComfyIcon from "@mui/icons-material/ViewComfy";
import { signOut } from "firebase/auth";
import { motion } from "framer-motion";
import { useTheme } from "next-themes";
import { useRouter } from "next/router";
import React from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth } from "../firebase/firebase";
import DarkModeIcon from "@mui/icons-material/DarkMode";
import { useTheme } from "next-themes";
import LightModeIcon from "@mui/icons-material/LightMode";
import { motion } from "framer-motion";
import DynamicFeedIcon from "@mui/icons-material/DynamicFeed";

type NavBarProps = {};
type NavBarProps = {
isMessenger: boolean;
setIsMessenger: any;
};

const NavBar: React.FC<NavBarProps> = () => {
const NavBar: React.FC<NavBarProps> = ({ isMessenger, setIsMessenger }) => {
const [user] = useAuthState(auth);
const router = useRouter();
const { setTheme, resolvedTheme, theme } = useTheme();
Expand Down Expand Up @@ -159,15 +163,34 @@ const NavBar: React.FC<NavBarProps> = () => {
</li>
{user && (
<>
<li>
{/* <li>
<div className="text-xl hidden xl:grid place-items-center bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-800 dark:text-white rounded-full mx-1 p-3 cursor-pointer hover:bg-gray-300 relative">
<AddIcon />
</div>
</li>
</li> */}
<li>
<div className="text-xl hidden xl:grid place-items-center bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-800 dark:text-white rounded-full mx-1 p-3 cursor-pointer hover:bg-gray-300 relative">
<MessageIcon />
</div>
{isMessenger ? (
<motion.div
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
onClick={() => setIsMessenger(false)}
className="text-xl xl:grid place-items-center bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-800 dark:text-white rounded-full mx-1 p-3 cursor-pointer hover:bg-gray-300 relative"
>
<DynamicFeedIcon />
</motion.div>
) : (
<motion.div
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
onClick={() => setIsMessenger(true)}
className="text-xl xl:grid place-items-center bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-800 dark:text-white rounded-full mx-1 p-3 cursor-pointer hover:bg-gray-300 relative"
>
<MessageIcon />
<span className="animate-ping text-xs absolute top-0 right-0 bg-blue-500 text-white font-semibold rounded-full px-1 text-center">
New
</span>
</motion.div>
)}
</li>
<li>
<div className="text-xl grid place-items-center bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-800 dark:text-white rounded-full mx-1 p-3 cursor-pointer hover:bg-gray-300 relative">
Expand Down
110 changes: 58 additions & 52 deletions components/RightMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { faker } from "@faker-js/faker";
import SearchIcon from "@mui/icons-material/Search";
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";

type RightMenuProps = {};
type RightMenuProps = {
isMessenger: boolean;
};

const RightMenu: React.FC<RightMenuProps> = () => {
const RightMenu: React.FC<RightMenuProps> = ({ isMessenger }) => {
const [suggestions, setSuggestions] = useState<any[]>([]);

useEffect(() => {
Expand All @@ -28,59 +30,63 @@ const RightMenu: React.FC<RightMenuProps> = () => {
return (
<div className="w-1/5 bg-[#f7f7f7] dark:bg-[#18191a] pt-16 h-full hidden xl:block px-4 fixed top-0 right-0 overflow-scroll scrollbar-hide">
<div className="h-full">
<div className="flex justify-between items-center px-0 pt-4">
<span className="font-semibold text-gray-500 text-lg dark:text-gray-300">
Sponsored
</span>
</div>
<div className="mt-2">
<div className="flex items-center space-x-4 dark:hover:bg-dark-third rounded-lg transition-all cursor-pointer">
<img
src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Apple-logo.png"
alt="Profile picture"
className="w-8 h-8 rounded-full"
/>
<div className="dark:text-dark-txt">
<span className="font-semibold">Apple</span>
{!isMessenger && (
<>
<div className="flex justify-between items-center px-0 pt-4">
<span className="font-semibold text-gray-500 text-lg dark:text-gray-300">
Sponsored
</span>
</div>
<div className="mt-2">
<div className="flex items-center space-x-4 dark:hover:bg-dark-third rounded-lg transition-all cursor-pointer">
<img
src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Apple-logo.png"
alt="Profile picture"
className="w-8 h-8 rounded-full"
/>
<div className="dark:text-dark-txt">
<span className="font-semibold">Apple</span>
</div>
</div>
</div>
<div className="cursor-pointer">
<div className="flex-1 space-x-2 mt-2">
<p>
Apple reportedly readjusts iPhone 14 production targets after
slow demand...
</p>
</div>
<div className="mb-8">
<img
className="rounded-xl"
src="https://fs.npstatic.com/userfiles/7687254/image/NextPit-Apple-iPhone-14-Plus-vs-iPhone-14-Pro-Max-w810h462.jpg"
/>
</div>
</div>
</div>
</div>
<div className="cursor-pointer">
<div className="flex-1 space-x-2 mt-2">
<p>
Apple reportedly readjusts iPhone 14 production targets after slow
demand...
</p>
</div>
<div className="mb-8">
<img
className="rounded-xl"
src="https://fs.npstatic.com/userfiles/7687254/image/NextPit-Apple-iPhone-14-Plus-vs-iPhone-14-Pro-Max-w810h462.jpg"
/>
</div>
</div>

<div className="border-b border-gray-200 dark:border-dark-third mb-3"></div>
<div className="border-b border-gray-200 dark:border-dark-third mb-3"></div>

<div>
<div className="flex justify-start font-semibold text-lg text-gray-600 dark:text-gray-300">
<h1>Birthdays</h1>
</div>
<div className="flex justify-between mt-3 cursor-pointer hover:bg-gray-300 dark:hover:bg-gray-800 px-2 py-2 rounded-md">
<img
className="w-8 h-8 mr-2"
src="https://freepikpsd.com/file/2019/10/birthday-present-transparent-background-5-Transparent-Images.png"
alt=""
/>
<p className="text-md">
<span className="font-semibold">
{faker.name.firstName()}, {faker.name.firstName()}
</span>{" "}
and <span className="font-semibold">2 others</span> have birthdays
today
</p>
</div>
</div>
<div>
<div className="flex justify-start font-semibold text-lg text-gray-600 dark:text-gray-300">
<h1>Birthdays</h1>
</div>
<div className="flex justify-between mt-3 cursor-pointer hover:bg-gray-300 dark:hover:bg-gray-800 px-2 py-2 rounded-md">
<img
className="w-8 h-8 mr-2"
src="https://freepikpsd.com/file/2019/10/birthday-present-transparent-background-5-Transparent-Images.png"
alt=""
/>
<p className="text-md">
<span className="font-semibold">
{faker.name.firstName()}, {faker.name.firstName()}
</span>{" "}
and <span className="font-semibold">2 others</span> have
birthdays today
</p>
</div>
</div>
</>
)}

<div className="border-b border-gray-200 dark:border-dark-third mt-3"></div>

Expand Down
180 changes: 180 additions & 0 deletions components/messenger/Messenger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import CallIcon from "@mui/icons-material/Call";
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
import SendIcon from "@mui/icons-material/Send";
import VideocamIcon from "@mui/icons-material/Videocam";
import Button from "@mui/material/Button";
import {
addDoc,
collection,
onSnapshot,
orderBy,
query,
serverTimestamp,
Timestamp,
} from "firebase/firestore";
import { motion } from "framer-motion";
import React, { useEffect, useState } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth, firestore } from "../../firebase/firebase";
import Stories from "./Stories";
import moment from "moment";
import LoopIcon from "@mui/icons-material/Loop";

type MessengerProps = {};

const Messenger: React.FC<MessengerProps> = () => {
const [user] = useAuthState(auth);
const [input, setInput] = useState("");
const [speed, setSpeed] = useState<any>("");
const [loading, setLoading] = useState<boolean>(false);
const [meassage, setMeassage] = useState<any[]>([]);

const handleSendMeassage = async () => {
setLoading(true);
try {
const docRef = await addDoc(collection(firestore, "meassage"), {
userid: user?.uid,
username: user?.displayName,
meassage: input,
profileImage: user?.photoURL,
timestamp: serverTimestamp() as Timestamp,
});
} catch (error) {
console.log(error);
}

setLoading(false);
setInput("");
};

useEffect(
() =>
onSnapshot(
query(collection(firestore, "meassage"), orderBy("timestamp", "desc")),
(snapshot) => setMeassage(snapshot.docs)
),
[firestore]
);

useEffect(() => {
setSpeed(Math.floor(Math.random() * 5000));
}, []);

return (
<>
<div className="flex flex-col flex-grow w-full max-w-xl bg-white shadow-xl rounded-lg overflow-hidden dark:bg-[#28282B]">
<Stories />
<div className="flex px-8 py-2.5 justify-between">
<div className="flex justify-start">
<img
src={`https://avatars.dicebear.com/api/jdenticon/${speed}.svg`}
alt=""
className="rounded-full w-10 h-10 mr-5"
/>

<p className="font-semibold text-center m-auto text-lg dark:text-white">
Messenger
</p>
</div>
<div className="flex justify-center gap-2 dark:text-gray-200 cursor-pointer">
<motion.div whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
<CallIcon />
</motion.div>
<motion.div whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
<VideocamIcon />
</motion.div>
<motion.div whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
<MoreHorizIcon />
</motion.div>
</div>
</div>
<div
className="flex flex-col flex-grow h-0 p-4 overflow-auto hover:scrollbar-thin
hover:scrollbar-thumb-black scrollbar-hide hover:scrollbar-default dark:bg-[#28282B] dark:border-none"
>
{meassage.map((data) => (
<div key={data.id}>
{data.data().userid === user?.uid ? (
<div className="flex w-full mt-2 space-x-3 max-w-xs ml-auto justify-end">
<div>
<p className="text-sm flex justify-end lowercase">
{data.data().username}
</p>
<div className="bg-blue-600 text-white p-3 rounded-l-lg rounded-br-lg">
<p className="text-md font-medium">
{data.data().meassage}
</p>
</div>
<span className="text-xs text-gray-500 leading-none">
{moment(
new Date(data.data().timestamp?.seconds * 1000)
).fromNow()}
</span>
</div>
<div className="flex-shrink-0 h-10 w-10 rounded-full bg-gray-300">
<img
className="rounded-full"
src={data.data().profileImage}
alt={data.data().username}
/>
</div>
</div>
) : (
<div className="flex w-full mt-2 space-x-3 max-w-xs">
<div className="flex-shrink-0 h-10 w-10 rounded-full bg-gray-300">
<img
className="rounded-full"
src={data.data().profileImage}
alt={data.data().username}
/>
</div>
<div>
<p className="text-sm flex justify-start lowercase">
{data.data().username}
</p>
<div className="bg-gray-300 p-3 rounded-r-lg rounded-bl-lg">
<p className="text-sm font-medium">
{data.data().meassage}
</p>
</div>
<span className="text-xs text-gray-500 leading-none">
{moment(
new Date(data.data().timestamp?.seconds * 1000)
).fromNow()}
</span>
</div>
</div>
)}
</div>
))}
</div>

<div className="bg-gray-300 dark:bg-gray-700 dark:text-white font-medium p-4 z-50 flex">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
className="flex items-center h-10 w-full rounded px-3 text-sm outline-none"
type="text"
placeholder="Type your message…"
/>
{input && (
<Button
disabled={!input}
onClick={handleSendMeassage}
className={
loading ? `bg-blue-400 cursor-not-allowed` : `bg-blue-400`
}
variant="contained"
endIcon={
loading ? <LoopIcon className="animate-spin" /> : <SendIcon />
}
>
{!loading && `Send`}
</Button>
)}
</div>
</div>
</>
);
};
export default Messenger;
Loading

0 comments on commit 8929913

Please sign in to comment.