Skip to content

Commit

Permalink
Merge pull request #306 from Aymanhki/ayman
Browse files Browse the repository at this point in the history
Bug fixes
  • Loading branch information
Aymanhki authored Mar 26, 2024
2 parents 2e8ff1c + 7e72d30 commit f7387cf
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 69 deletions.
5 changes: 2 additions & 3 deletions epoch_backend/persistence/epoch/epoch_post_persistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,11 @@ def get_all_user_posts(self, user_id: int):
def get_all_hashtag_posts(self, hashtag: str):
connection = get_db_connection()
cursor = connection.cursor()
hashtag_pattern = f"%{hashtag}%"
cursor.execute("SELECT * FROM posts WHERE caption LIKE %s", (hashtag_pattern,))
hashtag_pattern = f"% {hashtag} %"
cursor.execute("SELECT * FROM posts WHERE CONCAT(' ', caption, ' ') LIKE %s", (hashtag_pattern,))
posts = cursor.fetchall()
posts_media = get_posts_media(posts)
posts_users_info = get_posts_users_info(posts)

all_posts = []

for i in range(len(posts)):
Expand Down
186 changes: 122 additions & 64 deletions epoch_frontend/src/modules/Post.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ArrowCircleDownSharpIcon from '@mui/icons-material/ArrowCircleDownSharp';
import {favoritePost, removeFavoritePost, votePost, removeVotePost} from "../services/post";
import ForumOutlinedIcon from '@mui/icons-material/ForumOutlined';
import PopupUserList from "./PopupUserList";
import {animated, useSpring} from "react-spring";


export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isInFavorites}) {
Expand Down Expand Up @@ -52,7 +53,18 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
const [voteByUsernameList, setVoteByUsernameList] = useState((post && post.votes_by_usernames) ? post.votes_by_usernames : []);
const [showFavoritedByList, setShowFavoritedByList] = useState(false);
const [showVoteByList, setShowVoteByList] = useState(false);

const [showDeletePostPopup, setShowDeletePostPopup] = useState(false);
const [deletePostError, setDeletePostError] = useState(false);
const [deletePostErrorPrompt, setDeletePostErrorPrompt] = useState('');
const {transform: inTransformDelete} = useSpring({
transform: `translateY(${showDeletePostPopup ? 0 : 100}vh)`,
config: {duration: 300},
});

const {transform: outTransformDelete} = useSpring({
transform: `translateY(${showDeletePostPopup ? 0 : -100}vh)`,
config: {duration: 300},
});

useEffect(() => {
let postTime = new Date(post.created_at)
Expand Down Expand Up @@ -86,7 +98,6 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
setEditing(false);
}
}, [showPostPopup]);

const handleProfilePhotoClick = (imageUrl) => {
setOverlayImageUrl(imageUrl);
setShowOverlay(true);
Expand Down Expand Up @@ -190,24 +201,27 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
}

const onDeletePost = (postId, userId) => {
setError(true);
setErrorMessage('Deleting post...');

setDeletePostError(true);
setDeletePostErrorPrompt('Deleting post...');

deletePost(postId, userId)
.then(() => {
setError(false);
setErrorMessage('');
setDeletePostError(false);
setDeletePostErrorPrompt('');
setShowDeletePostPopup(false);
setPostAdmin(false);
setError(false);
setErrorMessage('');
setDeleted(true);
setRefreshFeed(true);
})
.catch((error) => {
setError(true);
setErrorMessage(error);
setShowDeletePostPopup(true);
setDeletePostError(true);
setDeletePostErrorPrompt(error);

setTimeout(() => {
setError(false);
setErrorMessage('');
setDeletePostError(false);
setDeletePostErrorPrompt('');
}, 5000);
});
}
Expand All @@ -225,8 +239,6 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
setShowPostPopup(true);
}



const getReleaseFormat = () => {
let date = new Date(post.release);
date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
Expand All @@ -248,11 +260,11 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
const diff = date - now;
const diffInSeconds = Math.floor(diff / 1000);
if (diffInSeconds < 60) {
return "In " + Math.floor(diffInSeconds) + " seconds";
return "In " + Math.floor(diffInSeconds) + (Math.floor(diffInSeconds) > 1 ? " seconds" : " second");
}

if (diffInSeconds < 3600) {
return "In " + Math.floor(diffInSeconds / 60) + " minutes";
return "In " + Math.floor(diffInSeconds / 60) + (Math.floor(diffInSeconds / 60) > 1 ? " minutes" : " minute");
}

if (diffInSeconds < 86400) {
Expand All @@ -267,7 +279,7 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
}

if (diffInSeconds < 3600) {
return Math.floor(diffInSeconds / 60) + " minutes ago";
return Math.floor(diffInSeconds / 60) + (Math.floor(diffInSeconds / 60) > 1 ? " minutes ago" : " minute ago");
}

if (diffInSeconds < 86400) {
Expand Down Expand Up @@ -518,7 +530,6 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI

}, [post.votes, postViewer]);


useEffect(() => {
if (favorited)
{
Expand Down Expand Up @@ -553,6 +564,7 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
}
}, [vote, voteByUsernameList, postViewer, post, voteResult]);


return (
<div className={`post ${showFullCaption ? 'post-expanded' : ''}`}
style={{display: (((postIsInThePast() || postAdmin) && (!deleted) && ((isInFavorites && favorited) || !isInFavorites))) ? 'block' : 'none'}}>
Expand All @@ -579,32 +591,32 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
}}></BorderColorOutlinedIcon>)}
{(postViewer && postAdmin && !editing) && (
<DeleteForeverOutlinedIcon className="delete-post-button-icon" onClick={() => {
onDeletePost(post.post_id, postViewer.id);
setShowDeletePostPopup(true);
}}></DeleteForeverOutlinedIcon>)}

</div>
</div>

<div className="post-body">
{post.caption && post.caption.length > 0 && (
<p className={"post-caption"}>
{(showFullCaption && post.caption) ? renderCaptionWithHashtags(post.caption) : (
<>
{renderCaptionWithHashtags(truncatedCaption)}
<span className="see-more" onClick={toggleCaptionVisibility}>
<p className={"post-caption"}>
{(showFullCaption && post.caption) ? renderCaptionWithHashtags(post.caption) : (
<>
{renderCaptionWithHashtags(truncatedCaption)}
<span className="see-more" onClick={toggleCaptionVisibility}>
See more
</span>
</>
)}
{(showFullCaption && post.caption && post.caption.length >= captionCharLimit) && (
<>
{' '}
<span className="see-less" onClick={toggleSeeLess}>
</>
)}
{(showFullCaption && post.caption && post.caption.length >= captionCharLimit) && (
<>
{' '}
<span className="see-less" onClick={toggleSeeLess}>
See less
</span>
</>
)}
</p>
</>
)}
</p>
)}
{(post.file && showFullCaption) && <div className={'file-wrapper'} onClick={handlePostMediaClick}>
<div className={'post-file'}><SmartMedia file={post.file} fileUrl={post.file}
Expand All @@ -615,42 +627,41 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
<div className="post-footer">
{postViewer && (
<div className={'vote-buttons'}>
<ArrowCircleUpSharpIcon className={`up-vote-button ${upVoted ? 'active' : ''}`} onClick={() => {
if(vote === 1)
{
onVotePost(post.post_id, postViewer.id, vote, 'removeUpVote');
}
else
{
onVotePost(post.post_id, postViewer.id, vote, 'upVote');
}
}}></ArrowCircleUpSharpIcon>
<ArrowCircleUpSharpIcon className={`up-vote-button ${upVoted ? 'active' : ''}`}
onClick={() => {
if (vote === 1) {
onVotePost(post.post_id, postViewer.id, vote, 'removeUpVote');
} else {
onVotePost(post.post_id, postViewer.id, vote, 'upVote');
}
}}></ArrowCircleUpSharpIcon>
<button className={'vote-count'} onClick={() => {
if (voteByUsernameList.length > 0) {
setShowFavoritedByList(false);
setShowVoteByList(true);
}
}}>{voteResult}</button>
<ArrowCircleDownSharpIcon className={`down-vote-button ${downVoted ? 'active' : ''}`} onClick={() => {
if(vote === -1)
{
onVotePost(post.post_id, postViewer.id, vote, 'removeDownVote');
}
else
{
onVotePost(post.post_id, postViewer.id, vote, 'downVote');
}
}}></ArrowCircleDownSharpIcon>
<ArrowCircleDownSharpIcon className={`down-vote-button ${downVoted ? 'active' : ''}`}
onClick={() => {
if (vote === -1) {
onVotePost(post.post_id, postViewer.id, vote, 'removeDownVote');
} else {
onVotePost(post.post_id, postViewer.id, vote, 'downVote');
}
}}></ArrowCircleDownSharpIcon>
</div>
)}

{((!showCommentsSection) && postViewer) && (
<button className={"view-comments-button"} onClick={() => navigate(`/epoch/comments/${post.post_id}`)}><ForumOutlinedIcon/></button>
<button className={"view-comments-button"}
onClick={() => navigate(`/epoch/comments/${post.post_id}`)}><ForumOutlinedIcon/>
</button>
)}

{postViewer && (
<div className={'favorite-button-wrapper'}>
<FavoriteBorderOutlinedIcon className={`favorite-button ${favorited ? 'active' : ''}`} onClick={() => toggleFavorite()}></FavoriteBorderOutlinedIcon>
<FavoriteBorderOutlinedIcon className={`favorite-button ${favorited ? 'active' : ''}`}
onClick={() => toggleFavorite()}></FavoriteBorderOutlinedIcon>
<button className={'favorited-by-count'} onClick={() => {
if (favoritedByCount > 0) {
setShowVoteByList(false);
Expand All @@ -663,9 +674,19 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI

</div>
{(post.file) ?
(showPostPopup && fileBlob && postViewer && postAdmin) && (<PostPopup showPopup={showPostPopup} setShowPopup={setShowPostPopup} username={postViewer.username} profilePic={postViewer.profile_pic_data} refreshFeed={refreshFeed} setRefreshFeed={setRefreshFeed} editPost={true} caption={post.caption} postFile={fileBlob} year={releaseYear} month={releaseMonth} day={releaseDay} hour={releaseHour} postId={post.post_id} userId={postViewer.id}/>)
:
(showPostPopup && postViewer && postAdmin) && (<PostPopup showPopup={showPostPopup} setShowPopup={setShowPostPopup} username={postViewer.username} profilePic={postViewer.profile_pic_data} refreshFeed={refreshFeed} setRefreshFeed={setRefreshFeed} editPost={true} caption={post.caption} year={releaseYear} month={releaseMonth} day={releaseDay} hour={releaseHour} postId={post.post_id} userId={postViewer.id}/>)
(showPostPopup && fileBlob && postViewer && postAdmin) && (
<PostPopup showPopup={showPostPopup} setShowPopup={setShowPostPopup} username={postViewer.username}
profilePic={postViewer.profile_pic_data} refreshFeed={refreshFeed}
setRefreshFeed={setRefreshFeed} editPost={true} caption={post.caption}
postFile={fileBlob} year={releaseYear} month={releaseMonth} day={releaseDay}
hour={releaseHour} postId={post.post_id} userId={postViewer.id}/>)
:
(showPostPopup && postViewer && postAdmin) && (
<PostPopup showPopup={showPostPopup} setShowPopup={setShowPostPopup} username={postViewer.username}
profilePic={postViewer.profile_pic_data} refreshFeed={refreshFeed}
setRefreshFeed={setRefreshFeed} editPost={true} caption={post.caption} year={releaseYear}
month={releaseMonth} day={releaseDay} hour={releaseHour} postId={post.post_id}
userId={postViewer.id}/>)
}
{showOverlay && (
<div className={'post-full-size-profile-photo-overlay'} onClick={closeOverlay}>
Expand All @@ -674,25 +695,62 @@ export default function Post({post, postViewer, refreshFeed, setRefreshFeed, isI
)}
</div>

<PopupUserList showUserListModal={showFavoritedByList} setShowUserListModal={setShowFavoritedByList} popupList={favoritedByUsernameList}/>
<PopupUserList showUserListModal={showVoteByList} setShowUserListModal={setShowVoteByList} popupList={voteByUsernameList}/>
<PopupUserList showUserListModal={showFavoritedByList} setShowUserListModal={setShowFavoritedByList}
popupList={favoritedByUsernameList}/>
<PopupUserList showUserListModal={showVoteByList} setShowUserListModal={setShowVoteByList}
popupList={voteByUsernameList}/>



{(post.file) ?
(showPostPopup && fileBlob && postViewer && postAdmin) && (
<PostPopup showPopup={showPostPopup} setShowPopup={setShowPostPopup} username={postViewer.username}
profilePic={postViewer.profile_pic_data} refreshFeed={refreshFeed}
setRefreshFeed={setRefreshFeed} editPost={true} caption={post.caption} postFile={fileBlob}
year={releaseYear} month={releaseMonth} day={releaseDay} hour={releaseHour} minute={releaseMinute} second={releaseSecond}
year={releaseYear} month={releaseMonth} day={releaseDay} hour={releaseHour}
minute={releaseMinute} second={releaseSecond}
postId={post.post_id} userId={postViewer.id}/>)
:
(showPostPopup && postViewer && postAdmin) && (
<PostPopup showPopup={showPostPopup} setShowPopup={setShowPostPopup} username={postViewer.username}
profilePic={postViewer.profile_pic_data} refreshFeed={refreshFeed}
setRefreshFeed={setRefreshFeed} editPost={true} caption={post.caption} year={releaseYear}
month={releaseMonth} day={releaseDay} hour={releaseHour} minute={releaseMinute} second={releaseSecond} postId={post.post_id}
month={releaseMonth} day={releaseDay} hour={releaseHour} minute={releaseMinute}
second={releaseSecond} postId={post.post_id}
userId={postViewer.id}/>)
}

<animated.div
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
backgroundColor: 'rgba(0, 0, 0, 0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
transform: showDeletePostPopup ? inTransformDelete : outTransformDelete,
zIndex: 1000
}}
>
<div className="delete-post-overlay" onClick={() => setShowDeletePostPopup(false)}></div>

<div className="delete-post-modal">
<h3 className="delete-post-header">Are you sure you want to delete this post?</h3>
{deletePostError && <p className="delete-post-error">{deletePostErrorPrompt}</p>}

<div className={'delete-post-buttons-wrapper'}>
<button className="delete-post-button-no"
onClick={() => setShowDeletePostPopup(false)}>No
</button>
<button className="delete-post-button-yes" data-testid="delete-post-button-yes"
id="delete-post-button-yes"
onClick={() => {onDeletePost(post.post_id, postViewer.id);}}>Yes
</button>
</div>
</div>
</animated.div>
</div>
);
}
1 change: 0 additions & 1 deletion epoch_frontend/src/pages/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ function Profile() {
const [deleteAccountErrorPrompt, setDeleteAccountErrorPrompt] = useState("");
const [deletingAccount, setDeletingAccount] = useState(false);


const {transform: inTransformDelete} = useSpring({
transform: `translateY(${showDeleteAccountPopup ? 0 : 100}vh)`,
config: {duration: 300},
Expand Down
2 changes: 1 addition & 1 deletion epoch_frontend/src/styles/NavBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
padding: 10px 20px;
height: 3rem;
border-bottom: 1px solid lightgrey;
z-index: 9000;
z-index: 1000;
}

.navbar .left {
Expand Down
Loading

0 comments on commit f7387cf

Please sign in to comment.