From 3891f12f5d6fde16d4df7adc6a2b186bbd6592e0 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 20:52:49 +0800 Subject: [PATCH 1/8] Redirect to conversations page instead of homepage when joining or creating a study group --- src/routes/CreateGroup/CreateGroup.tsx | 4 ++-- src/routes/Home/Home.tsx | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/routes/CreateGroup/CreateGroup.tsx b/src/routes/CreateGroup/CreateGroup.tsx index 904d472..aee9326 100644 --- a/src/routes/CreateGroup/CreateGroup.tsx +++ b/src/routes/CreateGroup/CreateGroup.tsx @@ -82,9 +82,9 @@ export default function CreateGroup({ route }: any) { duration: 2000, animationType: "slide-in", }); - // Set a delay before going back to homepage to hopefully let the queries refresh in time + // Set a delay before going back to conversation page to hopefully let the queries refresh in time setTimeout(() => { - navigation.navigate("Home"); + navigation.navigate("Conversation"); }, 200); }, onError: (error: Error) => { diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index 9ee173d..063b8b3 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -47,7 +47,7 @@ import RefreshIcon from "../../icons/RefreshIcon/RefreshIcon"; export default function Home() { // Switch this condition to see the main map when debugging - const map_distance_override = false; + const map_distance_override = true; const navigation = useNavigation(); const [location, setLocation] = useState(null); const [locationPermitted, setLocationPermitted] = useState(false); @@ -228,6 +228,7 @@ export default function Home() { duration: 2000, animationType: "slide-in", }); + navigation.navigate("Conversation"); } queryClient.invalidateQueries({ queryKey: ["user_status"] }); From bd42b5418e734913ded42bbed9542b2ae350e539 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 21:16:43 +0800 Subject: [PATCH 2/8] Allow register and create group page to be scrollable when onscreen keyboard is open --- src/routes/CreateGroup/CreateGroup.tsx | 5 +++-- src/routes/Register/Register.tsx | 1 + src/styles.tsx | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/routes/CreateGroup/CreateGroup.tsx b/src/routes/CreateGroup/CreateGroup.tsx index aee9326..26b30de 100644 --- a/src/routes/CreateGroup/CreateGroup.tsx +++ b/src/routes/CreateGroup/CreateGroup.tsx @@ -24,6 +24,7 @@ import MapView, { UrlTile, Marker } from "react-native-maps"; import { useNavigation } from "@react-navigation/native"; import { useToast } from "react-native-toast-notifications"; import CaretLeftIcon from "../../icons/CaretLeftIcon/CaretLeftIcon"; +import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; export default function CreateGroup({ route }: any) { const { location, subject } = route.params; @@ -100,7 +101,7 @@ export default function CreateGroup({ route }: any) { if (location) { return ( - + @@ -183,7 +184,7 @@ export default function CreateGroup({ route }: any) { - + ); } diff --git a/src/routes/Register/Register.tsx b/src/routes/Register/Register.tsx index f9ac188..98a46ce 100644 --- a/src/routes/Register/Register.tsx +++ b/src/routes/Register/Register.tsx @@ -17,6 +17,7 @@ import { UserRegister } from "../../components/Api/Api"; import IsNumber from "../../components/IsNumber/IsNumber"; import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; import { useToast } from "react-native-toast-notifications"; +import { ScrollView } from "react-native-gesture-handler"; export default function Register() { const navigation = useNavigation(); diff --git a/src/styles.tsx b/src/styles.tsx index af0d3fa..71beda4 100644 --- a/src/styles.tsx +++ b/src/styles.tsx @@ -44,8 +44,9 @@ const styles = StyleSheet.create({ justifyContent: "center", display: "flex", flexDirection: "column", - flex: 1, + flexGrow: 1, paddingHorizontal: 4, + paddingVertical: 32, }, flex_row: { display: "flex", From 88d8ce05b88719937b212d049b1d27a8ad7fea34 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 21:43:34 +0800 Subject: [PATCH 3/8] Possible fix to race conditions between queries in homepage which resulted in laggy rerenders of map --- src/routes/Home/Home.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index 063b8b3..1cbcdc2 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -381,12 +381,14 @@ export default function Home() { ); } else if ( - (StudentStatusQuery.isFetching && studying) || - StudentStatusListQuery.isFetching || - StudyGroupQuery.isFetching || - (StudentStatusQuery.isFetching && !studying) || - StudentStatusListGlobalQuery.isFetching || - StudyGroupGlobalQuery.isFetching + (!StudentStatusQuery.isSuccess && + studying && + !StudentStatusListQuery.isSuccess && + !StudyGroupQuery.isSuccess && + !StudentStatusQuery.isSuccess) || + (!studying && + !StudentStatusListGlobalQuery.isSuccess && + !StudyGroupGlobalQuery.isSuccess) ) { return ( <> From a65a3a84aad94ccff4b07eb26a7989ce79774476 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 22:03:46 +0800 Subject: [PATCH 4/8] Added enter button to conversation page and fixed error not properly displaying when sending an invalid message. Also added refresh interval of 20 seconds to study group query in conversations page to automatically refresh students count --- src/icons/CaretLeftIcon/CaretLeftIcon.tsx | 6 +- src/icons/CaretRightIcon/CaretLeftIcon.tsx | 28 +++++++++ .../ConversationPage/ConversationPage.tsx | 58 +++++++++++++------ 3 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 src/icons/CaretRightIcon/CaretLeftIcon.tsx diff --git a/src/icons/CaretLeftIcon/CaretLeftIcon.tsx b/src/icons/CaretLeftIcon/CaretLeftIcon.tsx index e2caaa5..d6f2c5c 100644 --- a/src/icons/CaretLeftIcon/CaretLeftIcon.tsx +++ b/src/icons/CaretLeftIcon/CaretLeftIcon.tsx @@ -3,7 +3,7 @@ import { IconProps } from "../../interfaces/Interfaces"; import { Svg, Path } from "react-native-svg"; import { colors } from "../../styles"; -export default function CaretLeftIcon(props: IconProps) { +export default function CaretRightIcon(props: IconProps) { return ( <> diff --git a/src/icons/CaretRightIcon/CaretLeftIcon.tsx b/src/icons/CaretRightIcon/CaretLeftIcon.tsx new file mode 100644 index 0000000..e2caaa5 --- /dev/null +++ b/src/icons/CaretRightIcon/CaretLeftIcon.tsx @@ -0,0 +1,28 @@ +import * as React from "react"; +import { IconProps } from "../../interfaces/Interfaces"; +import { Svg, Path } from "react-native-svg"; +import { colors } from "../../styles"; + +export default function CaretLeftIcon(props: IconProps) { + return ( + <> + + + + + + ); +} diff --git a/src/routes/ConversationPage/ConversationPage.tsx b/src/routes/ConversationPage/ConversationPage.tsx index b2fd297..5f433ef 100644 --- a/src/routes/ConversationPage/ConversationPage.tsx +++ b/src/routes/ConversationPage/ConversationPage.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { ActivityIndicator, Image } from "react-native"; +import { ActivityIndicator, Image, Pressable } from "react-native"; import styles from "../../styles"; import { View, @@ -36,6 +36,7 @@ import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContai import AsyncStorage from "@react-native-async-storage/async-storage"; import { useSelector } from "react-redux"; import { RootState } from "../../features/redux/Store/Store"; +import CaretRightIcon from "../../icons/CaretLeftIcon/CaretLeftIcon"; export default function ConversationPage() { const toast = useToast(); @@ -70,6 +71,7 @@ export default function ConversationPage() { enabled: student_status?.study_group != "" && student_status?.study_group != null, queryKey: ["study_group"], + refetchInterval: 20, queryFn: async () => { const data = await GetStudyGroup(student_status?.study_group || ""); if (data[0] == false) { @@ -162,7 +164,7 @@ export default function ConversationPage() { mutationFn: async (info: MessagePostType) => { const data = await PostMessage(info); if (data[0] != true) { - return Promise.reject(new Error()); + return Promise.reject(new Error(data[1])); } return data; }, @@ -293,23 +295,41 @@ export default function ConversationPage() { There are no messages )} - - ): void => { - setMessage(e.nativeEvent.text); - }} - onSubmitEditing={() => { - send_message.mutate({ - message_content: message, - }); - setMessage(""); - }} - /> + + + ): void => { + setMessage(e.nativeEvent.text); + }} + onSubmitEditing={() => { + send_message.mutate({ + message_content: message, + }); + setMessage(""); + }} + /> + { + send_message.mutate({ + message_content: message, + }); + setMessage(""); + }} + > + + + ); From 8a32d2b32ce0cb8aa2f9bd373a57c240b64dfc03 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 22:06:52 +0800 Subject: [PATCH 5/8] Fixed left and right caret icons --- src/icons/CaretLeftIcon/CaretLeftIcon.tsx | 4 ++-- .../{CaretLeftIcon.tsx => CaretRightIcon.tsx} | 2 +- src/routes/ConversationPage/ConversationPage.tsx | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-) rename src/icons/CaretRightIcon/{CaretLeftIcon.tsx => CaretRightIcon.tsx} (94%) diff --git a/src/icons/CaretLeftIcon/CaretLeftIcon.tsx b/src/icons/CaretLeftIcon/CaretLeftIcon.tsx index d6f2c5c..eb5655e 100644 --- a/src/icons/CaretLeftIcon/CaretLeftIcon.tsx +++ b/src/icons/CaretLeftIcon/CaretLeftIcon.tsx @@ -18,9 +18,9 @@ export default function CaretRightIcon(props: IconProps) { > diff --git a/src/icons/CaretRightIcon/CaretLeftIcon.tsx b/src/icons/CaretRightIcon/CaretRightIcon.tsx similarity index 94% rename from src/icons/CaretRightIcon/CaretLeftIcon.tsx rename to src/icons/CaretRightIcon/CaretRightIcon.tsx index e2caaa5..eb5655e 100644 --- a/src/icons/CaretRightIcon/CaretLeftIcon.tsx +++ b/src/icons/CaretRightIcon/CaretRightIcon.tsx @@ -3,7 +3,7 @@ import { IconProps } from "../../interfaces/Interfaces"; import { Svg, Path } from "react-native-svg"; import { colors } from "../../styles"; -export default function CaretLeftIcon(props: IconProps) { +export default function CaretRightIcon(props: IconProps) { return ( <> { const data = await GetStudyGroup(student_status?.study_group || ""); if (data[0] == false) { @@ -129,7 +129,7 @@ export default function ConversationPage() { // Avatar List const [users, setUsers] = useState([]); const AvatarsQuery = useQuery({ - refetchInterval: 3000, + refetchInterval: 10000, enabled: student_status?.study_group != null || (student_status?.study_group != "" && @@ -211,7 +211,9 @@ export default function ConversationPage() { paddingRight: 4, }} > - {studygroup.students.length} studying + {!StudyGroupQuery.isFetching + ? studygroup.students.length + " studying" + : "Loading"} {users.map((user: GroupMessageAvatarType, index: number) => { if (index > 6) { From 856621fe06b1916746b4429658ca9e46b042aee3 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 22:16:23 +0800 Subject: [PATCH 6/8] Remove a redundant refresh on load as it prevented users from overriding their location --- src/routes/Home/Home.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index 1cbcdc2..bf65cfd 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -97,7 +97,6 @@ export default function Home() { } // Refresh every 10 seconds - requestLocation(); useEffect(() => { const interval = setInterval(() => { requestLocation(); From 5d7327ef267dee69bcc5e7a60c560ae75ec8f9c6 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 27 Oct 2023 23:13:41 +0800 Subject: [PATCH 7/8] Do not redirect to conversations page if leaving a group --- .../DrawerSettings/CustomDrawerContent.tsx | 4 +- src/routes/Home/Home.tsx | 43 +++++++++---------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/components/DrawerSettings/CustomDrawerContent.tsx b/src/components/DrawerSettings/CustomDrawerContent.tsx index 48c31e2..61ec820 100644 --- a/src/components/DrawerSettings/CustomDrawerContent.tsx +++ b/src/components/DrawerSettings/CustomDrawerContent.tsx @@ -27,7 +27,7 @@ import { useToast } from "react-native-toast-notifications"; import MessageIcon from "../../icons/MessageIcon/MessageIcon"; export default function CustomDrawerContent(props: {}) { - const debug = false; + const debug = true; const navigation = useNavigation(); const status = useSelector((state: RootState) => state.status); const dispatch = useDispatch(); @@ -143,7 +143,7 @@ export default function CustomDrawerContent(props: {}) { { // We don't clear student statuses when logging out on debug - if (!debug) { + if (debug) { queryClient.clear(); dispatch(logout()); await AsyncStorage.clear(); diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index bf65cfd..b7c6e12 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -61,7 +61,7 @@ export default function Home() { const [modalOpen, setModalOpen] = useState(false); const [modalByGroup, setModalByGroup] = useState(false); - async function requestLocation() { + async function requestLocationPermission() { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== "granted") { setFeedback("Allow location permissions to continue"); @@ -75,12 +75,13 @@ export default function Home() { } ); return; + } else { + setLocationPermitted(true); } - if (status == "granted") { - if (locationPermitted === false) { - setLocationPermitted(true); - } + } + async function requestLocation() { + if (locationPermitted) { let newLocation = await Location.getCurrentPositionAsync(); if (newLocation) { // Only update location state if user's location has changed @@ -96,22 +97,18 @@ export default function Home() { } } - // Refresh every 10 seconds useEffect(() => { + console.log("changed"); + console.log(locationPermitted); + requestLocation(); + }, [locationPermitted]); + + useEffect(() => { + requestLocationPermission(); + // Refresh every 30 seconds const interval = setInterval(() => { requestLocation(); }, 30000); - setTimeout(() => { - queryClient.invalidateQueries({ queryKey: ["user"] }); - queryClient.invalidateQueries({ queryKey: ["user_status"] }); - queryClient.invalidateQueries({ - queryKey: ["user_status_list"], - }); - queryClient.invalidateQueries({ - queryKey: ["study_group_list"], - }); - requestLocation(); - }, 2000); return () => clearInterval(interval); }, []); @@ -219,7 +216,7 @@ export default function Home() { return data; }, onSuccess: () => { - if (student_status?.study_group) { + if (student_status?.study_group == "") { // Display separate toast if you stop studying while in a study group toast.show("You left study group \n" + student_status?.study_group, { type: "success", @@ -227,8 +224,8 @@ export default function Home() { duration: 2000, animationType: "slide-in", }); - navigation.navigate("Conversation"); } + queryClient.invalidateQueries({ queryKey: ["user_status"] }); // Delay refetching for study groups since backend still needs to delete groups without students after leaving a study group @@ -383,9 +380,9 @@ export default function Home() { (!StudentStatusQuery.isSuccess && studying && !StudentStatusListQuery.isSuccess && - !StudyGroupQuery.isSuccess && - !StudentStatusQuery.isSuccess) || - (!studying && + !StudyGroupQuery.isSuccess) || + (!StudentStatusQuery.isSuccess && + !studying && !StudentStatusListGlobalQuery.isSuccess && !StudyGroupGlobalQuery.isSuccess) ) { @@ -600,6 +597,7 @@ export default function Home() { study_group: studygroup.name, subject: studygroup.subject, }); + navigation.navigate("Conversation"); }} > @@ -1051,6 +1049,7 @@ export default function Home() { study_group: studygroup.name, subject: studygroup.subject, }); + navigation.navigate("Conversation"); setModalOpen(!modalOpen); }} > From 2603741aabf83baa1bbecac59747bc310504d670 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Sat, 28 Oct 2023 00:22:17 +0800 Subject: [PATCH 8/8] Turn off debug flags and clear study group messages notification cache when switching study groups --- src/components/DrawerSettings/CustomDrawerContent.tsx | 2 +- src/routes/Home/Home.tsx | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/DrawerSettings/CustomDrawerContent.tsx b/src/components/DrawerSettings/CustomDrawerContent.tsx index 61ec820..578d429 100644 --- a/src/components/DrawerSettings/CustomDrawerContent.tsx +++ b/src/components/DrawerSettings/CustomDrawerContent.tsx @@ -27,7 +27,7 @@ import { useToast } from "react-native-toast-notifications"; import MessageIcon from "../../icons/MessageIcon/MessageIcon"; export default function CustomDrawerContent(props: {}) { - const debug = true; + const debug = false; const navigation = useNavigation(); const status = useSelector((state: RootState) => state.status); const dispatch = useDispatch(); diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index b7c6e12..3769c06 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -44,10 +44,11 @@ import Modal from "react-native-modal"; import DropdownIcon from "../../icons/CaretDownIcon/CaretDownIcon"; import CaretUpIcon from "../../icons/CaretUpIcon/CaretUpIcon"; import RefreshIcon from "../../icons/RefreshIcon/RefreshIcon"; +import AsyncStorage from "@react-native-async-storage/async-storage"; export default function Home() { // Switch this condition to see the main map when debugging - const map_distance_override = true; + const map_distance_override = false; const navigation = useNavigation(); const [location, setLocation] = useState(null); const [locationPermitted, setLocationPermitted] = useState(false); @@ -125,6 +126,9 @@ export default function Home() { } } + async function clear_messages_notification_cache() { + AsyncStorage.setItem("messages", ""); + } // Student Status const [studying, setStudying] = useState(false); const [subject, setSubject] = useState(""); @@ -163,7 +167,7 @@ export default function Home() { mutationFn: async (info: StudentStatusPatchType) => { const data = await PatchStudentStatus(info); if (data[0] != true) { - return Promise.reject(new Error()); + return Promise.reject(new Error(JSON.stringify(data[1]))); } return data; }, @@ -224,6 +228,7 @@ export default function Home() { duration: 2000, animationType: "slide-in", }); + clear_messages_notification_cache(); } queryClient.invalidateQueries({ queryKey: ["user_status"] }); @@ -932,6 +937,8 @@ export default function Home() { return ; } } else { + requestLocationPermission(); + requestLocation(); return ( <>