Skip to content

Commit

Permalink
Finished Post Sharing in Messages
Browse files Browse the repository at this point in the history
Added BottomSheet using reanimated-bottom-sheet for Post Menu and sharing modal
Code Cleanup
  • Loading branch information
NiketanG committed Apr 22, 2021
1 parent 0f98e2c commit f054d00
Show file tree
Hide file tree
Showing 21 changed files with 1,054 additions and 310 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"dependencies": {
"@gorhom/animated-tabbar": "^2.1.1",
"@gorhom/bottom-sheet": "^3",
"@react-native-async-storage/async-storage": "^1.15.1",
"@react-native-community/google-signin": "^5.0.0",
"@react-native-community/masked-view": "^0.1.10",
Expand Down Expand Up @@ -48,7 +49,9 @@
"react-native-url-polyfill": "^1.3.0",
"react-native-vector-icons": "^8.1.0",
"react-native-web": "^0.15.5",
"reactotron-mst": "^3.1.3"
"reactotron-mst": "^3.1.3",
"reanimated-bottom-sheet": "^1.0.0-alpha.22",
"use-memo-one": "^1.1.2"
},
"devDependencies": {
"@babel/core": "^7.13.14",
Expand Down
33 changes: 29 additions & 4 deletions src/app/App.native.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { NavigationContainer } from "@react-navigation/native";
import React, { useContext } from "react";
import { Platform } from "react-native";
import { Platform, StatusBar, View } from "react-native";
import "react-native-gesture-handler";
import { DarkTheme, Provider as PaperProvider } from "react-native-paper";
import {
DarkTheme,
Provider as PaperProvider,
Title,
useTheme,
} from "react-native-paper";
import SwipeTabNavigation from "./Routes/MainSwipeNavigation";
import SignInNavigation from "./Routes/SignInNavigation";
import AppContextProvider, { AppContext } from "./utils/appContext";

// eslint-disable-next-line no-undef
const theme: ReactNativePaper.Theme = {
...DarkTheme,
Expand All @@ -20,7 +24,28 @@ const theme: ReactNativePaper.Theme = {
};

const Main = () => {
const { signupDone } = useContext(AppContext);
const { loading, signupDone } = useContext(AppContext);
const { colors, dark } = useTheme();
if (loading)
return (
<>
<StatusBar
backgroundColor={colors.background}
barStyle={dark ? "light-content" : "dark-content"}
animated
/>
<View
style={{
flex: 1,
backgroundColor: colors.background,
alignItems: "center",
justifyContent: "center",
}}
>
<Title>Instaclone</Title>
</View>
</>
);

if (signupDone) return <SwipeTabNavigation />;
return <SignInNavigation />;
Expand Down
69 changes: 69 additions & 0 deletions src/app/Components/Post/PostMenuModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";
import { ToastAndroid, useWindowDimensions, View } from "react-native";
import { List } from "react-native-paper";
import { useNavigation } from "@react-navigation/native";
import PostsStore from "../../store/PostsStore";

type ModalProps = {
closeModal: () => void;
ownPost: boolean;
postId: number;
username: string;
viewProfile: () => void;
};

export const PostModal: React.FC<ModalProps> = ({
postId,
closeModal,
ownPost,
viewProfile,
}) => {
const { width } = useWindowDimensions();
const navigation = useNavigation();
const deletePost = async () => {
try {
await PostsStore.deletePost(postId);
closeModal();
navigation.goBack();
} catch (err) {
console.error("[deletePost]", err);
ToastAndroid.show("An error occured", ToastAndroid.LONG);
}
};

const openProfile = () => {
closeModal();
viewProfile();
};

return (
<View
style={{
width,
backgroundColor: "#1f1f1f",
justifyContent: "center",
paddingVertical: 16,
zIndex: 6,
elevation: 6,
}}
>
{ownPost && (
<List.Item
title="Delete Post"
onPress={deletePost}
style={{
paddingHorizontal: 16,
}}
/>
)}

<List.Item
title="View Profile"
onPress={openProfile}
style={{
paddingHorizontal: 16,
}}
/>
</View>
);
};
178 changes: 178 additions & 0 deletions src/app/Components/Post/PostShareModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import React, { useContext, useEffect, useState } from "react";
import {
ActivityIndicator,
FlatList,
StatusBar,
TextInput,
ToastAndroid,
useWindowDimensions,
View,
} from "react-native";
import { Divider, Text, useTheme } from "react-native-paper";
import NewChatItem, {
NewChatItemType,
} from "../../Screens/Messages/NewChatItem";
import { Follower } from "../../store/FollowersStore";
import MessagesStore, { Message } from "../../store/MessagesStore";
import { AppContext } from "../../utils/appContext";
import { newMessageInDb } from "../../utils/supabaseUtils";
import useChatList, { ChatList } from "../../utils/useChatList";
import useUser from "../../utils/useUser";

type ModalProps = {
closeModal: () => void;
postId: number;
};

const PostShareModal: React.FC<ModalProps> = ({ postId, closeModal }) => {
const { colors } = useTheme();
const { width, height } = useWindowDimensions();
const { messageList, loading } = useChatList();
const [searchTerm, setSearchTerm] = useState("");

const { username: currentUsername } = useContext(AppContext);
const { following } = useUser(currentUsername);

const [chatList, setChatList] = useState<NewChatItemType[]>([]);

const getUsersList = (chatsList: ChatList[], followingList: Follower[]) => {
const followingListData = followingList.map((user) => ({
username: user.following,
}));

const chatListData = [...chatsList, ...followingListData];
return [
...new Map(
chatListData.map((item) => [item.username, item])
).values(),
];
};

const [searchResults, setSearchResults] = useState<
NewChatItemType[] | null
>(null);

useEffect(() => {
if (searchTerm.length > 0) {
setSearchResults(
messageList.filter((item) =>
item.username.includes(searchTerm.toLowerCase())
)
);
} else {
setSearchResults(null);
}
}, [messageList, searchTerm]);

useEffect(() => {
if (messageList && following)
setChatList(getUsersList(messageList, following));
}, [messageList, following]);

useEffect(() => {
if (searchTerm.length > 0) {
setSearchResults(
messageList.filter((item) =>
item.username.includes(searchTerm.toLowerCase())
)
);
} else {
setSearchResults(null);
}
}, [messageList, searchTerm]);

const newMessage = async (username: string) => {
const messageToSend = {
imageUrl: undefined,
message_type: "POST",
postId: postId,
receiver: username,
text: undefined,
};
const newMessageData = await newMessageInDb(messageToSend);
if (newMessageData) {
MessagesStore.addMessage(newMessageData);
ToastAndroid.show("Post sent", ToastAndroid.LONG);
}
closeModal();
};

return (
<View
style={{
height: height / 1.5,
zIndex: 2,
elevation: 2,
backgroundColor: "#1f1f1f",
paddingVertical: 16,
justifyContent: "center",
}}
>
{loading && (
<View
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
}}
>
<ActivityIndicator color={colors.text} />
</View>
)}

<FlatList
ListHeaderComponent={
<>
<TextInput
placeholder="Search"
placeholderTextColor={"gray"}
onChangeText={(text) => setSearchTerm(text)}
style={{
flex: 1,
marginHorizontal: 16,
marginVertical: 16,
height: 40,
backgroundColor: "#3a3a3a",
borderRadius: 6,
paddingHorizontal: 16,
color: colors.text,
}}
/>
<Divider />
<Text
style={{
marginHorizontal: 16,
marginTop: 16,
}}
>
Suggested
</Text>
</>
}
ListEmptyComponent={
<View
style={{
display: "flex",
flexDirection: "column",
height: height - (StatusBar.currentHeight || 0),
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Nothing to see here, yet.</Text>
</View>
}
data={searchResults ? searchResults : chatList}
ItemSeparatorComponent={Divider}
renderItem={({ item }) => (
<NewChatItem item={item} openMessage={newMessage} />
)}
keyExtractor={(item) => item.username}
bouncesZoom
bounces
/>
</View>
);
};

export default PostShareModal;
Loading

0 comments on commit f054d00

Please sign in to comment.