diff --git a/src/components/ImgUpload/index.css b/src/components/ImgUpload/index.css
index bfb10027c..d09c2eca3 100644
--- a/src/components/ImgUpload/index.css
+++ b/src/components/ImgUpload/index.css
@@ -190,6 +190,22 @@ input {
font-size: large;
}
+.shareBtnContainer {
+ width: 100%;
+ display: flex;
+ gap: 5px;
+}
+
+.disable_post_btn {
+ background: grey;
+ cursor: not-allowed;
+}
+
+.disable_post_btn:hover {
+ background: grey;
+ cursor: not-allowed;
+}
+
@media only screen and (min-width: 800px) {
.dialogStyle {
width: 60vw;
@@ -239,6 +255,7 @@ input {
.small_post_view {
display: none;
+ width: 100%;
}
}
@@ -263,7 +280,7 @@ input {
}
.post__caption_section {
- width: 48vw;
+ width: 100%;
}
.next_button {
diff --git a/src/components/ImgUpload/index.jsx b/src/components/ImgUpload/index.jsx
index 68ae1612d..071b5407d 100644
--- a/src/components/ImgUpload/index.jsx
+++ b/src/components/ImgUpload/index.jsx
@@ -25,6 +25,7 @@ export default function ImgUpload(props) {
const [imagePreviews, setImagePreviews] = useState([]);
const [isValidimage, setisValidimage] = useState(true);
const [buttonPopup, setButtonPopup] = useState(false);
+ const [isStoryUploaded, setIsStoryUploaded] = useState(false);
const [username, setUsername] = useState("");
const displayName = auth.currentUser.displayName;
@@ -48,8 +49,10 @@ export default function ImgUpload(props) {
const docRef = doc(db, "users", auth?.currentUser?.uid);
const docSnap = await getDoc(docRef);
setUsername(docSnap.data().username);
+ if (docSnap.data().storyTimestamp) {
+ setIsStoryUploaded(true);
+ }
}
-
getUsername();
}, []);
@@ -87,30 +90,51 @@ export default function ImgUpload(props) {
setImagePreviews(images);
};
- const savePost = async (imageUrl = "") => {
+ const savePost = async (imageUrl = "", type) => {
try {
- const postRef = await db.collection("posts").add({
- timestamp: firebase.firestore.FieldValue.serverTimestamp(),
- caption: caption,
- imageUrl,
- username: username,
- displayName: props.user.displayName,
- avatar: props.user.photoURL,
- likecount: [],
- uid: auth?.currentUser?.uid,
- });
+ if (type === "Post") {
+ const postRef = await db.collection("posts").add({
+ timestamp: firebase.firestore.FieldValue.serverTimestamp(),
+ caption: caption,
+ imageUrl,
+ username: username,
+ displayName: props.user.displayName,
+ avatar: props.user.photoURL,
+ likecount: [],
+ uid: auth?.currentUser?.uid,
+ });
- const postId = postRef.id; // Store post ID in a separate variable
+ const postId = postRef.id; // Store post ID in a separate variable
- await db
- .collection("users")
- .doc(props.user.uid)
- .update({
- posts: firebase.firestore.FieldValue.arrayUnion(postId), // Use postId instead of postRef.id
+ await db
+ .collection("users")
+ .doc(props.user.uid)
+ .update({
+ posts: firebase.firestore.FieldValue.arrayUnion(postId), // Use postId instead of postRef.id
+ });
+ } else {
+ await db.collection("story").add({
+ caption: caption,
+ imageUrl,
+ username: username,
+ uid: auth?.currentUser?.uid,
});
+ const querySnapshot = await db
+ .collection("users")
+ .where("username", "==", username)
+ .get();
+ if (!querySnapshot.empty) {
+ const userRef = querySnapshot.docs[0].ref;
+ // Update the 'storyTimestamp' field
+ await userRef.update({
+ storyTimestamp: firebase.firestore.FieldValue.serverTimestamp(),
+ });
+ }
+ }
+
playSuccessSound();
- enqueueSnackbar("Post was uploaded successfully!", {
+ enqueueSnackbar(`${type} uploaded successfully!`, {
variant: "success",
});
@@ -138,7 +162,7 @@ export default function ImgUpload(props) {
}
};
- function handleUpload() {
+ function handleUpload(type) {
if ((!image && !caption) || !isValidimage) {
enqueueSnackbar("Upload valid image and caption!", {
variant: "error",
@@ -152,7 +176,7 @@ export default function ImgUpload(props) {
}
if (!image) {
- savePost();
+ savePost("", type);
return;
}
@@ -167,7 +191,7 @@ export default function ImgUpload(props) {
},
})
.then((urls) => {
- savePost(JSON.stringify(urls));
+ savePost(JSON.stringify(urls), type);
})
.catch((err) => {
enqueueSnackbar(err.message, {
@@ -311,13 +335,24 @@ export default function ImgUpload(props) {
}}
style={{ color: "var(--color) !important" }}
/>
-
+
+
+
+
@@ -430,6 +465,7 @@ export default function ImgUpload(props) {
)}
setCaption(e.target.value)}
value={caption}
variant="filled"
@@ -445,16 +481,29 @@ export default function ImgUpload(props) {
},
"& .MuiFilledInput-root": {
background: "transparent",
+ color: "var(--color)",
},
}}
+ style={{ color: "var(--color) !important" }}
/>
-
+
+
+
+
)}
diff --git a/src/components/Post/index.jsx b/src/components/Post/index.jsx
index f1ff0ddb4..d56390e15 100644
--- a/src/components/Post/index.jsx
+++ b/src/components/Post/index.jsx
@@ -60,7 +60,7 @@ function Post(prop) {
snapshot.docs.map((doc) => ({
id: doc.id,
content: doc.data(),
- })),
+ }))
);
});
}
@@ -138,13 +138,6 @@ function Post(prop) {
const tempLikeCount = likecount ? [...likecount] : [];
- const buttonStyle = {
- ":hover": {
- color: "#FF4D4D",
- fontSize: "29px",
- },
- };
-
async function likesHandler() {
if (user && likecount !== undefined) {
let ind = tempLikeCount.indexOf(user.uid);
diff --git a/src/components/SideBar/index.jsx b/src/components/SideBar/index.jsx
index 2013fa5b2..edd3e8bfd 100644
--- a/src/components/SideBar/index.jsx
+++ b/src/components/SideBar/index.jsx
@@ -53,7 +53,8 @@ function SideBar({ anonymous }) {
}
>
-
New Post
+
{" "}
+
New Post/Story
{
+ const [storyData, setStoryData] = useState({});
+ const [storyImage, setStoryImage] = useState("");
+ const { imageUrl, caption } = storyData;
+
+ useEffect(() => {
+ async function getStory() {
+ const docRef = db
+ .collection("story")
+ .where("username", "==", username)
+ .limit(1);
+
+ docRef.get().then((snapshot) => {
+ const doc = snapshot.docs[0];
+ setStoryData({
+ ...doc?.data(),
+ });
+ try {
+ setStoryImage(JSON.parse(doc.data().imageUrl));
+ } catch {
+ const img = doc
+ ?.data()
+ ?.imageUrl?.split(",")
+ .map((url) => ({
+ imageUrl: url,
+ imageWidth: 0,
+ imageHeight: 0,
+ thumbnail: null,
+ }));
+ setStoryImage(img);
+ }
+ });
+ }
+
+ getStory();
+ }, []);
+
+ async function deleteStory() {
+ // Delete the story from story collection
+ const querySnapshot = await db
+ .collection("story")
+ .where("username", "==", username)
+ .get();
+
+ querySnapshot?.forEach((doc) => {
+ doc.ref.delete().catch((error) => {
+ console.error("Error deleting document: ", error);
+ });
+ });
+
+ // Delete story timestamp from user Doc
+ const userDocSnapshot = await db
+ .collection("users")
+ .where("username", "==", username)
+ .get();
+
+ userDocSnapshot?.forEach((doc) => {
+ doc.ref
+ .update({
+ storyTimestamp: deleteField(),
+ })
+ .then(() => {
+ setUserData((prevData) => ({
+ ...prevData,
+ storyTimestamp: null,
+ }));
+ })
+ .catch((error) => {
+ console.error("Error deleting document: ", error);
+ });
+ });
+ }
+
+ return (
+
+
setViewStory(false)}
+ />
+ {storyData !== {} ? (
+ <>
+ {
+ deleteStory();
+ setViewStory(false);
+ }}
+ />
+
+ {imageUrl == "" ? (
+
+
+
{caption}
+
+ ) : (
+
+
+
{caption}
+
+ )}
+
+ >
+ ) : (
+ Sorry😓 No story!
+ )}
+
+ );
+};
+
+export default StoryView;
diff --git a/src/components/index.js b/src/components/index.js
index e396062cf..f487fb6f8 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -13,6 +13,7 @@ import Post from "./Post";
import ReadMore from "./ReadMore";
import SearchBar from "./SearchBar";
import SideBar from "./SideBar";
+import StoryView from "./Story";
export {
Caption,
@@ -30,6 +31,7 @@ export {
ReadMore,
SearchBar,
SideBar,
+ StoryView,
};
export default Post;
diff --git a/src/pages/Profile/index.css b/src/pages/Profile/index.css
index ddca15671..715bac841 100644
--- a/src/pages/Profile/index.css
+++ b/src/pages/Profile/index.css
@@ -135,6 +135,10 @@
font-weight: 600;
}
+.story_available_border {
+ border: 6px solid rgba(2, 106, 242, 0.6);
+}
+
.setting-logout {
display: flex;
flex-direction: row;
diff --git a/src/pages/Profile/index.jsx b/src/pages/Profile/index.jsx
index 0a6edd195..2186e12dd 100644
--- a/src/pages/Profile/index.jsx
+++ b/src/pages/Profile/index.jsx
@@ -9,8 +9,14 @@ import {
Typography,
useMediaQuery,
} from "@mui/material";
-import { auth, db } from "../../lib/firebase";
-import { collection, onSnapshot, query, where } from "firebase/firestore";
+import { auth, db, storage } from "../../lib/firebase";
+import {
+ collection,
+ deleteField,
+ onSnapshot,
+ query,
+ where,
+} from "firebase/firestore";
import { getModalStyle, useStyles } from "../../App";
import { lazy, useEffect, useState } from "react";
import { playErrorSound, playSuccessSound } from "../../js/sounds";
@@ -25,6 +31,7 @@ import LogoutIcon from "@mui/icons-material/Logout";
import Modal from "@mui/material/Modal";
import NotFound from "../NotFound";
import SettingsIcon from "@mui/icons-material/Settings";
+import { StoryView } from "../../components";
import ViewsCounter from "../../reusableComponents/views";
import firebase from "firebase/compat/app";
import logo from "../../assets/logo.webp";
@@ -48,6 +55,7 @@ function Profile() {
const [userData, setUserData] = useState(null);
const [isEditing, setIsEditing] = useState(false);
const [userExists, setUserExists] = useState(true);
+ const [viewStory, setViewStory] = useState(false);
const { username } = useParams();
let name = "";
@@ -55,6 +63,7 @@ function Profile() {
let uid = "";
let bio = "";
let country = "";
+ let storyTimestamp = null;
if (userData) {
name = userData.name;
@@ -62,6 +71,7 @@ function Profile() {
uid = userData.uid;
bio = userData.bio;
country = userData.country;
+ storyTimestamp = userData.storyTimestamp;
}
const handleClose = () => setOpen(false);
@@ -77,14 +87,43 @@ function Profile() {
.then((snapshot) => {
if (snapshot.docs) {
const doc = snapshot.docs[0];
+
+ const currTimestamp = firebase.firestore.Timestamp.now().seconds;
+ const storyTimestamp = doc.data().storyTimestamp?.seconds;
+
+ //Check if story is expired or not
+ if (storyTimestamp && currTimestamp - storyTimestamp > 86400) {
+ async function deleteStory() {
+ const querySnapshot = await db
+ .collection("story")
+ .where("username", "==", username)
+ .get();
+
+ // Delete the story that are expired
+ querySnapshot?.forEach((doc) => {
+ doc.ref.delete().catch((error) => {
+ console.error("Error deleting document: ", error);
+ });
+ });
+
+ const docRef = doc.ref;
+ docRef.update({
+ storyTimestamp: deleteField(),
+ });
+ }
+ deleteStory();
+ }
+
+ const data = doc.data();
setUserData({
- name: doc.data().name,
- avatar: doc.data().photoURL,
- uid: doc.data().uid,
- bio: doc.data().bio
- ? doc.data().bio
+ name: data.name,
+ avatar: data.photoURL,
+ uid: data.uid,
+ bio: data.bio
+ ? data.bio
: "Lorem ipsum dolor sit amet consectetur",
- country: doc.data().country ? doc.data().country : "Global",
+ country: data.country ? data.country : "Global",
+ storyTimestamp: data.storyTimestamp,
});
} else {
setUserExists(false);
@@ -241,6 +280,13 @@ function Profile() {
+ {viewStory && (
+
+ )}
{isEditing && (
{avatar ? (
setOpen((on) => !on)}
+ onClick={() => {
+ if (storyTimestamp) {
+ setViewStory(true);
+ }
+ }}
alt={name}
src={avatar}
- className="profile-pic-container"
+ className={`profile-pic-container ${
+ storyTimestamp ? "story_available_border" : null
+ }`}
/>
) : (
diff --git a/src/reusableComponents/ImageSlider/index.jsx b/src/reusableComponents/ImageSlider/index.jsx
index 5e6eb5c94..a9c532210 100644
--- a/src/reusableComponents/ImageSlider/index.jsx
+++ b/src/reusableComponents/ImageSlider/index.jsx
@@ -28,7 +28,7 @@ const ImageSlider = ({ slides, doubleClickHandler }) => {
return slides.length ? (
- {slides.map(({ imageUrl, imageWidth, imageHeight, thumbnail }, index) => (
+ {slides.map(({ imageUrl, thumbnail }, index) => (