Skip to content

Commit 486a1f2

Browse files
committed
Fixed like and comment flicker issue + minor ui changes
1 parent a35fee7 commit 486a1f2

7 files changed

Lines changed: 154 additions & 117 deletions

File tree

app/(tabs)/home/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//components
22
import HomeHeader from "@components/containers/HomeHeader";
33
import Post from "@components/containers/post";
4-
import { ActivityIndicator, Animated, KeyboardAvoidingView, RefreshControl, View , ListRenderItem, ListRenderItemInfo } from "react-native";
4+
import { ActivityIndicator, Animated, KeyboardAvoidingView, ListRenderItem, ListRenderItemInfo, RefreshControl, View } from "react-native";
55

66
//others
77
import { useSafeAreaInsets } from 'react-native-safe-area-context';
@@ -53,7 +53,8 @@ export default function HomeScreen() {
5353
const renderPost: ListRenderItem<post> = useCallback(({ item }: ListRenderItemInfo<post>) =>
5454
(
5555
<Post comment_count={item.num_comments}
56-
like_count={item.likes} user_uid={user ? user.uid : ""}
56+
like_count={item.likes}
57+
user_uid={user ? user.uid : ""}
5758
id={item.id}
5859
uid={item.uid}
5960
timestamp={item.timestamp}

app/(tabs)/search.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export default function SearchScreen() {
114114
}, [])
115115

116116
return (
117-
<View style={{ backgroundColor: "#17171d", flex: 1, paddingTop: 50, paddingBottom: 100, alignItems: "center" }}>
117+
<View style={{ backgroundColor: "#17171d", flex: 1, paddingTop: 50, alignItems: "center" }}>
118118

119119
<View style={{ flexDirection: "row", alignItems: "center" }}>
120120

app/comments/[post_id].tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
import Comment from "@components/containers/comment";
33
import Post from "@components/containers/post";
44
import NothingHere from "@components/display/nothing";
5-
import InputBox from "@components/inputs/inptField";
6-
import MaterialDesignIcons from "@react-native-vector-icons/material-design-icons";
75
import { Stack } from "expo-router";
8-
import { FlatList, KeyboardAvoidingView, Pressable, RefreshControl, StyleSheet, View } from "react-native";
6+
import { FlatList, KeyboardAvoidingView, RefreshControl, View } from "react-native";
97

108
//firebase
119
import {
@@ -29,7 +27,6 @@ import React, { useEffect, useState } from 'react';
2927

3028
//func
3129
import { chunkArray } from "@utils/arrayUtils";
32-
import { addComment } from "@utils/otherUtils";
3330

3431
//typecasting
3532
import CustomText from "@components/display/customText";
@@ -49,7 +46,6 @@ export default function CommentsScreen() {
4946
const user = auth.currentUser;
5047

5148
const [usersData, setUsersData] = useState<Record<string, UserData>>({})
52-
const [comment, setComment] = useState("");
5349
const [commentData, setCommentData] = useState<comment[]>([]);
5450

5551
const [postData, setPostData] = useState<post>();
@@ -180,15 +176,12 @@ export default function CommentsScreen() {
180176
ListEmptyComponent={
181177
<NothingHere text="No comments yet... " />
182178
}
179+
ListFooterComponent={
180+
<View style={{ paddingBottom: 100 }} />
181+
}
183182
style={{ backgroundColor: "#17171d", flex: 1, height: "100%" }}
184183
removeClippedSubviews={true}
185184
/>
186-
<View style={{ marginBottom: 70, flexDirection: "row", alignItems: "center", width: "100%", borderColor: "#25252fff", borderTopWidth: StyleSheet.hairlineWidth }}>
187-
<InputBox secure={false} value={comment} valueFn={setComment} color="#8492a6" icon="comment" type="none" placeholder="Comment here" />
188-
<Pressable style={{ padding: 8 }} onPress={() => { addComment(comment, post_id, user ? user.uid : "", () => { loadComments(); setComment(""); }) }}>
189-
<MaterialDesignIcons name="send" color="#5f6878" size={25} />
190-
</Pressable>
191-
</View>
192185
</KeyboardAvoidingView>
193186
);
194187
}

src/components/containers/post.tsx

Lines changed: 8 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,11 @@ import MaterialDesignIcons from "@react-native-vector-icons/material-design-icon
33
import { Image, Pressable, StyleSheet, View } from "react-native";
44
import CarouselComponent from "../display/carousel";
55
import CustomText from "../display/customText";
6-
import InputBox from "../inputs/inptField";
76

87
//firebase
9-
import { db, getUserData } from "@auth/firebase";
8+
import { getUserData } from "@auth/firebase";
109
import {
11-
addDoc,
12-
collection,
13-
deleteDoc,
14-
doc,
15-
getDoc,
16-
increment,
17-
serverTimestamp,
18-
setDoc,
19-
Timestamp,
20-
updateDoc
10+
Timestamp
2111
} from "firebase/firestore";
2212

2313
//react and expo
@@ -26,6 +16,9 @@ import { useRouter } from 'expo-router';
2616
import { memo, useEffect, useState } from "react";
2717

2818
//func
19+
// import { checkUserLiked, dislikePost, likePost } from "@utils/otherUtils";
20+
import CommentBox from "@components/inputs/commentBox";
21+
import LikeButton from "@components/inputs/likeButton";
2922
import { extractTime } from "@utils/stringTimeUtils";
3023

3124

@@ -44,12 +37,8 @@ interface Prop {
4437

4538
const Post = memo(function Post({ id, user_uid, media, used_media, message, uid, timestamp, like_count, comment_count }: Prop) {
4639
const router = useRouter();
47-
const [liked, setLiked] = useState(false);
48-
const [likeCount, setLikeCount] = useState(like_count);
4940
const [commentCount, setCommentCount] = useState(comment_count);
5041

51-
52-
const [comment, setComment] = useState("");
5342
const [userPfp, setUserPfp] = useState("https://i.pinimg.com/736x/15/0f/a8/150fa8800b0a0d5633abc1d1c4db3d87.jpg");
5443
const [OPName, setOPName] = useState("Your Name");
5544

@@ -62,78 +51,9 @@ const Post = memo(function Post({ id, user_uid, media, used_media, message, uid,
6251

6352
useEffect(() => {
6453
getOP();
54+
console.log(user_uid, message, "OP: ", uid);
6555
}, [uid])
6656

67-
useEffect(() => {
68-
checkIfUserLiked();
69-
console.log("rendering: ", id);
70-
}, [])
71-
72-
73-
async function checkIfUserLiked() {
74-
const likeRef = doc(db, "posts", id, "likes", user_uid);
75-
try {
76-
77-
const likeSnap = await getDoc(likeRef);
78-
const liked = likeSnap.exists();
79-
setLiked(liked);
80-
}
81-
catch (e) {
82-
console.log(e, " there's an error...");
83-
}
84-
}
85-
86-
async function addComment() {
87-
try {
88-
await addDoc(collection(db, "posts", id, "comments"), {
89-
uid: user_uid,
90-
message: comment,
91-
timestamp: serverTimestamp(),
92-
likes: 0
93-
})
94-
await updateDoc(doc(db, "posts", id),
95-
{
96-
num_comments: increment(1)
97-
})
98-
setCommentCount(commentCount + 1);
99-
} catch (e) {
100-
console.log(e);
101-
}
102-
}
103-
104-
async function likePost() {
105-
try {
106-
await setDoc(doc(db, "posts", id, "likes", user_uid),
107-
{
108-
createdAt: new Date()
109-
}
110-
)
111-
await updateDoc(doc(db, "posts", id),
112-
{
113-
likes: increment(1)
114-
}).then(() => {
115-
setLikeCount(likeCount + 1);
116-
})
117-
118-
} catch (e) {
119-
console.log(e);
120-
}
121-
}
122-
123-
async function dislikePost() {
124-
try {
125-
await deleteDoc(doc(db, "posts", id, "likes", user_uid));
126-
updateDoc(doc(db, "posts", id),
127-
{
128-
likes: increment(-1)
129-
}).then(() => {
130-
setLikeCount(likeCount - 1);
131-
}
132-
)
133-
} catch (e) {
134-
console.log(e);
135-
}
136-
}
13757

13858
async function getOP() {
13959
await getUserData("users", uid).then(
@@ -183,10 +103,7 @@ const Post = memo(function Post({ id, user_uid, media, used_media, message, uid,
183103

184104
{/* Buttons */}
185105
<View style={{ flexDirection: "row", paddingHorizontal: 20, justifyContent: "flex-start", alignItems: "center", width: "auto" }}>
186-
<Pressable style={{ padding: 8, flexDirection: "row" }} onPress={() => { setLiked(!liked); liked ? dislikePost() : likePost() }}>
187-
<MaterialDesignIcons name={liked ? "heart" : "heart-outline"} color={liked ? "#ec3750" : "#5f6878"} size={25} />
188-
<CustomText style={{ color: "#8492a6", marginLeft: 5 }}>{likeCount}</CustomText>
189-
</Pressable>
106+
<LikeButton likeCount={like_count} userId={user_uid} postId={id} />
190107

191108
<Pressable style={{ padding: 8, flexDirection: "row" }} onPress={() => { router.push(`/comments/${id}`) }}>
192109
<MaterialDesignIcons name="comment" color="#5f6878" size={25} />
@@ -197,15 +114,7 @@ const Post = memo(function Post({ id, user_uid, media, used_media, message, uid,
197114
<MaterialDesignIcons name="share" color="#5f6878" size={25} />
198115
</Pressable>
199116
</View>
200-
201-
{/* add a comment*/}
202-
<View style={{ flexDirection: "row", alignItems: "center", width: "100%" }}>
203-
<InputBox secure={false} value={comment} valueFn={setComment} color="#8492a6" icon="comment" type="none" placeholder="Comment here" />
204-
<Pressable style={{ padding: 8 }} onPress={addComment}>
205-
<MaterialDesignIcons name="send" color="#5f6878" size={25} />
206-
</Pressable>
207-
</View>
208-
117+
<CommentBox userId={user_uid} postId={id} />
209118
</View>
210119
);
211120
})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import MaterialDesignIcons from "@react-native-vector-icons/material-design-icons";
2+
import { addComment } from "@utils/otherUtils";
3+
import { useState } from "react";
4+
import { Pressable, View } from "react-native";
5+
import InputBox from "./inptField";
6+
7+
interface Prop {
8+
userId: string;
9+
postId: string;
10+
}
11+
12+
export default function CommentBox({ userId, postId }: Prop) {
13+
const [comment, setComment] = useState("");
14+
15+
return (
16+
<View style={{ flexDirection: "row", alignItems: "center", width: "100%" }}>
17+
<InputBox secure={false} value={comment} valueFn={setComment} color="#8492a6" icon="comment" type="none" placeholder="Comment here" />
18+
<Pressable style={{ padding: 8 }} onPress={() => { addComment(comment, postId); setComment("") }}>
19+
<MaterialDesignIcons name="send" color="#5f6878" size={25} />
20+
</Pressable>
21+
</View>
22+
);
23+
24+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import CustomText from "@components/display/customText";
2+
import MaterialDesignIcons from "@react-native-vector-icons/material-design-icons";
3+
import { checkUserLiked, dislikePost, likePost } from "@utils/otherUtils";
4+
import { useEffect, useRef, useState } from "react";
5+
import { Pressable } from 'react-native';
6+
7+
interface Prop {
8+
likeCount: number;
9+
userId: string;
10+
postId: string;
11+
}
12+
export default function LikeButton({ likeCount, userId, postId }: Prop) {
13+
const [liked, setLiked] = useState(false);
14+
const likeRef = useRef(likeCount);
15+
const likeCooldown = useRef(false);
16+
17+
useEffect(() => {
18+
setDefaultLikedState();
19+
}, [])
20+
21+
function handleLike() {
22+
setLiked(!liked);
23+
// because liked changes after next render, we gotta use opposite thingy
24+
if (liked) {
25+
if (!likeCooldown.current) {
26+
likeRef.current -= 1;
27+
likeCooldown.current = true;
28+
dislikePost(postId, userId).then(
29+
() => {
30+
likeCooldown.current = false
31+
}
32+
).catch((e) => { console.log("dislike failed!") });
33+
}
34+
} else {
35+
if (!likeCooldown.current) {
36+
likeRef.current += 1;
37+
likeCooldown.current = true;
38+
likePost(postId, userId).then(
39+
() => {
40+
likeCooldown.current = false
41+
}
42+
).catch((e) => { console.log("like failed!") });
43+
}
44+
}
45+
}
46+
47+
async function setDefaultLikedState() {
48+
const userLiked = await checkUserLiked(postId, userId);
49+
setLiked(userLiked);
50+
}
51+
52+
return (
53+
<Pressable style={{ padding: 8, flexDirection: "row" }} onPress={handleLike}>
54+
<MaterialDesignIcons name={liked ? "heart" : "heart-outline"} color={liked ? "#ec3750" : "#5f6878"} size={25} />
55+
<CustomText style={{ color: "#8492a6", marginLeft: 5 }}>{likeRef.current}</CustomText>
56+
</Pressable>
57+
)
58+
59+
60+
61+
62+
}

src/utils/otherUtils.tsx

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { db } from "@auth/firebase";
2-
import { addDoc, collection, doc, increment, serverTimestamp, updateDoc } from "firebase/firestore";
1+
import { auth, db } from "@auth/firebase";
2+
import { addDoc, collection, deleteDoc, doc, getDoc, increment, serverTimestamp, setDoc, updateDoc } from "firebase/firestore";
33
import { extractUrl } from "./stringTimeUtils";
44

55
export async function uploadToHc(urls: string[]) {
@@ -56,7 +56,9 @@ export const uploadFileTemp = async (file: any): Promise<string> => {
5656
}
5757

5858

59-
export async function addComment(comment: string, post_id: string, uid: string, fn?: () => void) {
59+
export async function addComment(comment: string, post_id: string, fn?: () => void) {
60+
const uid = auth.currentUser ? auth.currentUser.uid : "";
61+
console.log("Trying to add comment as ", uid, " comment: ", comment);
6062
try {
6163
await addDoc(collection(db, "posts", post_id, "comments"), {
6264
uid: uid,
@@ -79,4 +81,50 @@ export async function addComment(comment: string, post_id: string, uid: string,
7981

8082
export function handleSlackLogin() {
8183
console.log("Tried slack login");
82-
}
84+
}
85+
86+
87+
88+
// post functions
89+
export async function checkUserLiked(postId: string, userUid: string) {
90+
const likeRef = doc(db, "posts", postId, "likes", userUid);
91+
try {
92+
93+
const likeSnap = await getDoc(likeRef);
94+
const liked = likeSnap.exists();
95+
return liked;
96+
}
97+
catch (e) {
98+
console.log(e, " there's an error...");
99+
return false;
100+
}
101+
}
102+
103+
export async function likePost(postId: string, userUid: string) {
104+
try {
105+
await setDoc(doc(db, "posts", postId, "likes", userUid),
106+
{
107+
createdAt: new Date()
108+
}
109+
)
110+
await updateDoc(doc(db, "posts", postId),
111+
{
112+
likes: increment(1)
113+
})
114+
115+
} catch (e) {
116+
console.log(e);
117+
}
118+
}
119+
120+
export async function dislikePost(postId: string, userUid: string) {
121+
try {
122+
await deleteDoc(doc(db, "posts", postId, "likes", userUid));
123+
updateDoc(doc(db, "posts", postId),
124+
{
125+
likes: increment(-1)
126+
})
127+
} catch (e) {
128+
console.log(e);
129+
}
130+
}

0 commit comments

Comments
 (0)