import * as React from "react"; import { ActivityIndicator, Image, Pressable } from "react-native"; import styles from "../../styles"; import { View, Text, TextInput, ScrollView, NativeSyntheticEvent, TextInputChangeEventData, } from "react-native"; import { colors } from "../../styles"; import { useRef, useState } from "react"; import { useMutation, useQuery } from "@tanstack/react-query"; import { GetStudentStatus, GetStudyGroup, GetStudyGroupMemberAvatars, GetStudyGroupMessages, PostMessage, } from "../../components/Api/Api"; import { StudentStatusType, StudentStatusReturnType, StudyGroupType, StudyGroupDetailReturnType, MessageType, MessageReturnType, MessagePostType, GroupMessageAvatarType, GroupMessageAvatarReturnType, } from "../../interfaces/Interfaces"; import { useToast } from "react-native-toast-notifications"; import { useQueryClient } from "@tanstack/react-query"; import AnimatedContainer from "../../components/AnimatedContainer/AnimatedContainer"; 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(); const user = useSelector((state: RootState) => state.user); // Student Status const [student_status, setStudentStatus] = useState(); const StudentStatusQuery = useQuery({ queryKey: ["user_status"], queryFn: async () => { const data = await GetStudentStatus(); if (data[0] == false) { return Promise.reject(new Error(JSON.stringify(data[1]))); } return data; }, onSuccess: (data: StudentStatusReturnType) => { setStudentStatus(data[1]); }, onError: (error: Error) => { toast.show(String(error), { type: "warning", placement: "top", duration: 2000, animationType: "slide-in", }); }, }); // Study Group Detail const [studygroup, setStudyGroup] = useState(); const StudyGroupQuery = useQuery({ enabled: student_status?.study_group != "" && student_status?.study_group != null, queryKey: ["study_group"], refetchInterval: 10000, queryFn: async () => { const data = await GetStudyGroup(student_status?.study_group || ""); if (data[0] == false) { return Promise.reject(new Error(JSON.stringify(data[1]))); } return data; }, onSuccess: (data: StudyGroupDetailReturnType) => { if (data[1]) { setStudyGroup(data[1]); } }, onError: (error: Error) => { toast.show(String(error), { type: "warning", placement: "top", duration: 2000, animationType: "slide-in", }); }, }); // Study Group Messages const [messages, setMessages] = useState([]); const MessageQuery = useQuery({ refetchInterval: 3000, enabled: !StudentStatusQuery.isLoading && (student_status?.study_group != null || student_status?.study_group != ""), queryKey: ["study_group_messages"], queryFn: async () => { const data = await GetStudyGroupMessages(); if (data[0] == false) { return Promise.reject(new Error(JSON.stringify(data[1]))); } return data; }, onSuccess: async (data: MessageReturnType) => { if (data[1]) { await AsyncStorage.setItem("messages", JSON.stringify(data[1])); setMessages(data[1]); } }, onError: (error: Error) => { toast.show(String(error), { type: "warning", placement: "top", duration: 2000, animationType: "slide-in", }); }, }); // Avatar List const [users, setUsers] = useState([]); const AvatarsQuery = useQuery({ refetchInterval: 10000, enabled: student_status?.study_group != null || (student_status?.study_group != "" && studygroup != null && studygroup.students != null), queryKey: ["study_group_avatars"], queryFn: async () => { const data = await GetStudyGroupMemberAvatars(); if (data[0] == false) { return Promise.reject(new Error(JSON.stringify(data[1]))); } return data; }, onSuccess: (data: GroupMessageAvatarReturnType) => { if (data[1]) { setUsers(data[1]); } }, onError: (error: Error) => { toast.show(String(error), { type: "warning", placement: "top", duration: 2000, animationType: "slide-in", }); }, }); const scrollViewRef = useRef(null); const queryClient = useQueryClient(); const [message, setMessage] = useState(""); const send_message = useMutation({ mutationFn: async (info: MessagePostType) => { const data = await PostMessage(info); if (data[0] != true) { return Promise.reject(new Error(data[1])); } return data; }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["study_group_messages"] }); }, onError: (error: Error) => { toast.show(String(error), { type: "warning", placement: "top", duration: 2000, animationType: "slide-in", }); }, }); if ( !StudyGroupQuery.isLoading && !AvatarsQuery.isLoading && !MessageQuery.isLoading && student_status && studygroup && studygroup.students ) { return ( {`Group: ${studygroup?.name ? studygroup.name : ""}`} {!StudyGroupQuery.isFetching ? studygroup.students.length + " studying" : "Loading"} {users.map((user: GroupMessageAvatarType, index: number) => { if (index > 6) { return ; } return ( {user.avatar != null && user.avatar != "" ? ( ) : ( )} ); })} scrollViewRef.current?.scrollToEnd()} ref={scrollViewRef} > {messages.length > 0 ? ( messages.map((message: MessageType, index: number) => { let avatar = ""; users.filter((user: GroupMessageAvatarType) => { if (user.username == message.user) { avatar = user.avatar; } }); return ( {avatar != null && avatar != "" ? ( ) : ( )} {message.user} {message.timestamp} {message.message_content} ); }) ) : ( There are no messages )} ): void => { setMessage(e.nativeEvent.text); }} onSubmitEditing={() => { send_message.mutate({ message_content: message, }); setMessage(""); }} /> { send_message.mutate({ message_content: message, }); setMessage(""); }} > ); } else if (!student_status?.study_group) { return ( You are not in a study group. Join one to start a conversation! ); } return ( Loading... ); }