Skip to content

Commit f02e327

Browse files
committed
Added three dot menu on posts
1 parent 80589c8 commit f02e327

13 files changed

Lines changed: 332 additions & 36 deletions

File tree

App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
import "expo-router/entry";
1+
import "expo-router/entry";
2+

app/_layout.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Stack } from "expo-router";
33

44
//contexts
5+
import { BottomSheetProvider } from "@contexts/BottomSheetContext";
56
import { ModalProvider } from "@contexts/modalContext";
67
import { UserDataProvider } from "@contexts/userContext";
78

@@ -11,6 +12,7 @@ import { useEffect, useState } from "react";
1112
//auth
1213
import { auth } from "@auth/firebase";
1314
import { User, onAuthStateChanged } from "firebase/auth";
15+
import { GestureHandlerRootView } from "react-native-gesture-handler";
1416
import LoadingScreen from "./loading";
1517

1618

@@ -37,11 +39,15 @@ export default function RootLayout() {
3739
}
3840

3941
return (
40-
<ModalProvider>
41-
<UserDataProvider>
42-
<Stack initialRouteName={"auth/login"} screenOptions={{ contentStyle: { backgroundColor: "#17171d" }, headerShown: false, animation: "fade" }}>
43-
</Stack>
44-
</UserDataProvider>
45-
</ModalProvider>
42+
<GestureHandlerRootView>
43+
<BottomSheetProvider>
44+
<ModalProvider>
45+
<UserDataProvider>
46+
<Stack initialRouteName={"auth/login"} screenOptions={{ contentStyle: { backgroundColor: "#17171d" }, headerShown: false, animation: "fade" }}>
47+
</Stack>
48+
</UserDataProvider>
49+
</ModalProvider>
50+
</BottomSheetProvider>
51+
</GestureHandlerRootView>
4652
);
4753
}

app/comments/[post_id].tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export default function CommentsScreen() {
163163
ListHeaderComponent={
164164
<View style={{ paddingTop: insets.top }}>
165165
<OnlyIconButton icon="arrow-left" func={() => { router.back() }} style={{ position: "absolute", top: 0, left: 20, zIndex: 5 }} />
166-
<CustomText style={{ color: "white", left: 80, fontSize: 18, top: 0, fontWeight: 700 }}>Comments</CustomText>
166+
<CustomText style={{ color: "white", left: 80, fontSize: 18, top: 0, fontWeight: 700 }}>Post</CustomText>
167167
{
168168
postData ?
169169
<Post id={post_id} user_uid={postData.uid} media={postData.media} used_media={postData.used_media} message={postData.post_message}

babel.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ module.exports = function (api) {
2424

2525
// Optional - For using decorators
2626
['@babel/plugin-proposal-decorators', { legacy: true }],
27+
28+
//ALways at last as per docs
29+
'react-native-worklets/plugin',
2730
],
2831
};
2932
};

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
},
1313
"dependencies": {
1414
"@expo/vector-icons": "^14.1.0",
15-
"@gorhom/bottom-sheet": "^5.1.8",
15+
"@gorhom/bottom-sheet": "^5",
1616
"@react-native-async-storage/async-storage": "2.1.2",
1717
"@react-native-vector-icons/evil-icons": "^12.2.0",
1818
"@react-native-vector-icons/material-design-icons": "^12.2.0",
@@ -27,12 +27,14 @@
2727
"expo-blur": "~14.1.5",
2828
"expo-constants": "~17.1.7",
2929
"expo-dev-client": "^5.2.4",
30+
"expo-device": "^7.1.4",
3031
"expo-doctor": "^1.17.0",
3132
"expo-font": "~13.3.2",
3233
"expo-haptics": "~14.1.4",
3334
"expo-image": "~2.4.0",
3435
"expo-image-picker": "~16.1.4",
3536
"expo-linking": "~7.1.7",
37+
"expo-notifications": "~0.31.4",
3638
"expo-random": "^14.0.1",
3739
"expo-router": "5.1.5",
3840
"expo-splash-screen": "~0.30.10",
@@ -54,7 +56,8 @@
5456
"react-native-screens": "~4.11.1",
5557
"react-native-svg": "15.11.2",
5658
"react-native-web": "~0.20.0",
57-
"react-native-webview": "13.13.5"
59+
"react-native-webview": "13.13.5",
60+
"react-native-worklets": "^0.5.0"
5861
},
5962
"devDependencies": {
6063
"@babel/core": "^7.25.2",

src/components/containers/post.tsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//components
2+
import CommentBox from "@components/inputs/commentBox";
3+
import LikeButton from "@components/inputs/likeButton";
24
import MaterialDesignIcons from "@react-native-vector-icons/material-design-icons";
35
import { Image, Pressable, StyleSheet, View } from "react-native";
46
import CarouselComponent from "../display/carousel";
57
import CustomText from "../display/customText";
6-
78
//firebase
89
import { getUserData } from "@auth/firebase";
910
import {
@@ -17,8 +18,8 @@ import { memo, useEffect, useState } from "react";
1718

1819
//func
1920
// import { checkUserLiked, dislikePost, likePost } from "@utils/otherUtils";
20-
import CommentBox from "@components/inputs/commentBox";
21-
import LikeButton from "@components/inputs/likeButton";
21+
import ThreeDots from "@components/display/threeDots";
22+
import { deletePost } from "@utils/otherUtils";
2223
import { extractTime } from "@utils/stringTimeUtils";
2324

2425

@@ -42,6 +43,7 @@ const Post = memo(function Post({ id, user_uid, media, used_media, message, uid,
4243
const [OPName, setOPName] = useState("Your Name");
4344

4445

46+
4547
const mediaMod: ImagePickerAsset[] = media.map(uri => ({
4648
uri,
4749
width: 0,
@@ -82,11 +84,24 @@ const Post = memo(function Post({ id, user_uid, media, used_media, message, uid,
8284
<CustomText style={styles.timestamp}>{extractTime(timestamp)}</CustomText>
8385
</Pressable>
8486
</View>
85-
<View>
86-
<Pressable style={{ padding: 5, marginLeft: "auto" }}>
87-
<MaterialDesignIcons name="dots-vertical" color="#5f6878" size={25} />
87+
{/* <View>
88+
<Pressable onPress={() => { }}>
89+
<MaterialDesignIcons name="dots-vertical" size={25} color={"#8492a6"} />
8890
</Pressable>
89-
</View>
91+
</View> */}
92+
<ThreeDots
93+
data={[
94+
(uid == user_uid) ?
95+
{ text: "Delete Post", func: () => { deletePost(id) }, icon: "delete" } :
96+
{ text: "Like Post", func: () => { }, icon: "heart" }
97+
,
98+
{ text: "Share Post", func: () => { console.log("Tried to share post"); }, icon: "share-variant" },
99+
{ text: "Follow User", func: () => { console.log("Tried to share post"); }, icon: "account-plus" }
100+
]}
101+
/>
102+
{/* <CustomBottomSheet
103+
data={[{ text: "Delete Post", func: () => { deletePost(id) } }]}
104+
/> */}
90105
</View>
91106
<View style={{ paddingVertical: 10, borderColor: "#25252fff", borderTopWidth: StyleSheet.hairlineWidth, height: "auto" }}>
92107
{/* Posted content */}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { useBottomSheetContext } from '@contexts/BottomSheetContext';
2+
import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons';
3+
import { BottomSheetItem } from '@utils/types';
4+
import { useState } from 'react';
5+
import { Pressable, View } from 'react-native';
6+
7+
8+
interface Props {
9+
data: BottomSheetItem[]
10+
}
11+
12+
export default function ThreeDots({ data }: Props) {
13+
const [isVisible, setVisible] = useState(false);
14+
const { setSheetData, closeSheet, expandSheet } = useBottomSheetContext();
15+
16+
function toggleSheet() {
17+
setSheetData(data);
18+
setVisible(!isVisible);
19+
if (isVisible) {
20+
closeSheet();
21+
} else {
22+
expandSheet();
23+
}
24+
}
25+
26+
return (
27+
<View>
28+
<Pressable onPress={toggleSheet}>
29+
<MaterialDesignIcons name="dots-vertical" size={25} color={"#8492a6"} />
30+
</Pressable>
31+
</View>
32+
);
33+
}

src/components/inputs/likeButton.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ import { useEffect, useRef, useState } from "react";
55
import { Pressable } from 'react-native';
66

77
interface Prop {
8-
likeCount: number;
98
userId: string;
109
postId: string;
1110
}
12-
export default function LikeButton({ likeCount, userId, postId }: Prop) {
11+
export default function LikeButton({ userId, postId }: Prop) {
1312
const [liked, setLiked] = useState(false);
14-
const likeRef = useRef(likeCount);
13+
const likeRef = useRef(0);
1514
const likeCooldown = useRef(false);
1615

1716
useEffect(() => {
@@ -45,9 +44,8 @@ export default function LikeButton({ likeCount, userId, postId }: Prop) {
4544

4645
async function setDefaultLikedState() {
4746
const userLiked = await checkUserLiked(postId, userId);
48-
setLiked(userLiked);
49-
5047
likeRef.current = await getLikeCount(postId);
48+
setLiked(userLiked);
5149
}
5250

5351
return (
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import CustomText from '@components/display/customText';
2+
import BottomSheet, { BottomSheetBackdrop, BottomSheetView } from '@gorhom/bottom-sheet';
3+
import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons';
4+
import { BottomSheetItem } from '@utils/types';
5+
import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
6+
import { StyleSheet } from 'react-native';
7+
import { Pressable } from 'react-native-gesture-handler';
8+
9+
type sheetContextType = {
10+
setSheetData: (data: BottomSheetItem[]) => void;
11+
closeSheet: () => void;
12+
expandSheet: () => void;
13+
}
14+
const BottomSheetContext = createContext<sheetContextType | null>(null);
15+
16+
export function BottomSheetProvider({ children }: { children: React.ReactNode }) {
17+
const [data, setData] = useState<BottomSheetItem[]>([]);
18+
const bottomSheetRef = useRef<BottomSheet>(null);
19+
const snapPoints = useMemo(() => ["25%", "50%"], []);
20+
21+
const renderBackdrop = useCallback(
22+
(props: any) => (
23+
<BottomSheetBackdrop
24+
{...props}
25+
disappearsOnIndex={1}
26+
appearsOnIndex={2}
27+
/>
28+
),
29+
[]
30+
);
31+
32+
function setSheetData(data: BottomSheetItem[]) {
33+
setData(data);
34+
}
35+
function closeSheet() {
36+
bottomSheetRef.current?.close();
37+
}
38+
function expandSheet() {
39+
bottomSheetRef.current?.expand();
40+
console.log("expanding");
41+
}
42+
43+
return (
44+
<BottomSheetContext.Provider
45+
value={{
46+
setSheetData,
47+
closeSheet,
48+
expandSheet
49+
}}
50+
>
51+
{children}
52+
<BottomSheet
53+
handleIndicatorStyle={{ backgroundColor: "white" }}
54+
index={-1}
55+
snapPoints={snapPoints}
56+
enablePanDownToClose
57+
ref={bottomSheetRef}
58+
backdropComponent={renderBackdrop}
59+
backgroundStyle={{ backgroundColor: "#17171d" }}
60+
61+
>
62+
<BottomSheetView style={styles.contentContainer}>
63+
{
64+
data.map((item: BottomSheetItem) => (
65+
<Pressable onPress={item.func} key={item.text} style={styles.button}>
66+
<MaterialDesignIcons name={item.icon} color="#bec5d0ff" size={25} />
67+
<CustomText style={{ marginLeft: 10, color: "#bec5d0ff" }}>
68+
{item.text}
69+
</CustomText>
70+
</Pressable>
71+
))
72+
}
73+
</BottomSheetView>
74+
</BottomSheet>
75+
76+
</BottomSheetContext.Provider>
77+
)
78+
}
79+
80+
const styles = StyleSheet.create({
81+
button: {
82+
width: "100%",
83+
flexDirection: "row",
84+
alignItems: "center",
85+
justifyContent: "flex-start",
86+
paddingVertical: 15
87+
},
88+
contentContainer: {
89+
backgroundColor: "#17171d",
90+
borderColor: "#25252f",
91+
flex: 1,
92+
padding: 36,
93+
alignItems: 'flex-start',
94+
zIndex: 1,
95+
},
96+
});
97+
98+
export function useBottomSheetContext() {
99+
const context = useContext(BottomSheetContext);
100+
if (!context) {
101+
throw new Error("useUser must be used within a ModalContext");
102+
}
103+
return context;
104+
}

src/utils/notificationUtils.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
// export async function sendPushNotification(expoPushToken: string) {
3+
// const message = {
4+
// to: expoPushToken,
5+
// sound: 'default',
6+
// title: 'Original Title',
7+
// body: 'And here is the body!',
8+
// data: { someData: 'goes here' },
9+
// };
10+
11+
// await fetch('https://exp.host/--/api/v2/push/send', {
12+
// method: 'POST',
13+
// headers: {
14+
// Accept: 'application/json',
15+
// 'Accept-encoding': 'gzip, deflate',
16+
// 'Content-Type': 'application/json',
17+
// },
18+
// body: JSON.stringify(message),
19+
// });
20+
// }

0 commit comments

Comments
 (0)