|
@@ -0,0 +1,211 @@
|
|
|
+import { usePostGetGroupMessageStatusQuery } from '@api/chat';
|
|
|
+import React, { useEffect, useState } from 'react';
|
|
|
+import {
|
|
|
+ StyleSheet,
|
|
|
+ View,
|
|
|
+ Text,
|
|
|
+ Image,
|
|
|
+ TouchableOpacity,
|
|
|
+ ScrollView,
|
|
|
+ Platform
|
|
|
+} from 'react-native';
|
|
|
+import ActionSheet, { SheetManager } from 'react-native-actions-sheet';
|
|
|
+import { AvatarWithInitials } from 'src/components';
|
|
|
+import { API_HOST } from 'src/constants';
|
|
|
+import { storage, StoreType } from 'src/storage';
|
|
|
+import { FlashList } from '@shopify/flash-list';
|
|
|
+import { Colors } from 'src/theme';
|
|
|
+import { getFontSize } from 'src/utils';
|
|
|
+import moment from 'moment';
|
|
|
+import { NAVIGATION_PAGES } from 'src/types';
|
|
|
+import { useNavigation } from '@react-navigation/native';
|
|
|
+
|
|
|
+const GroupStatusModal = () => {
|
|
|
+ const navigation = useNavigation();
|
|
|
+ const uid = (storage.get('uid', StoreType.STRING) as number) ?? 0;
|
|
|
+ const token = storage.get('token', StoreType.STRING) as string;
|
|
|
+ const [groupToken, setGroupToken] = useState<string | null>(null);
|
|
|
+ const [messageId, setMessageId] = useState<number | null>(null);
|
|
|
+ const [payloadData, setPayloadData] = useState<any>(null);
|
|
|
+ const { data } = usePostGetGroupMessageStatusQuery(
|
|
|
+ token,
|
|
|
+ groupToken as string,
|
|
|
+ messageId as number,
|
|
|
+ groupToken && messageId ? true : false
|
|
|
+ );
|
|
|
+ const [read, setRead] = useState<any[]>([]);
|
|
|
+ const [received, setReceived] = useState<any[]>([]);
|
|
|
+
|
|
|
+ const handleSheetOpen = (payload: any) => {
|
|
|
+ setGroupToken(payload.groupToken);
|
|
|
+ setMessageId(payload.messageId);
|
|
|
+ setPayloadData(payload);
|
|
|
+ };
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data && data.status) {
|
|
|
+ setRead(data.status?.filter((status) => status.status === 3 && status.uid !== +uid) ?? []);
|
|
|
+ setReceived(
|
|
|
+ data.status?.filter((status) => status.status === 2 && status.uid !== +uid) ?? []
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }, [data]);
|
|
|
+
|
|
|
+ const formatDate = (utcDateString: string): string => {
|
|
|
+ const date = moment.utc(utcDateString).local();
|
|
|
+
|
|
|
+ if (date.isSame(moment(), 'day')) {
|
|
|
+ return `today ${date.format('HH:mm')}`;
|
|
|
+ } else if (date.isSame(moment().subtract(1, 'day'), 'day')) {
|
|
|
+ return `yesterday ${date.format('HH:mm')}`;
|
|
|
+ } else {
|
|
|
+ return date.format('DD.MM HH:mm');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const renderUserItem = ({ item }: { item: any }) => {
|
|
|
+ return (
|
|
|
+ <TouchableOpacity
|
|
|
+ style={styles.userItem}
|
|
|
+ onPress={() => {
|
|
|
+ SheetManager.hide('group-status');
|
|
|
+ navigation.navigate(
|
|
|
+ ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: item.uid }] as never)
|
|
|
+ );
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {item.avatar ? (
|
|
|
+ <Image source={{ uri: API_HOST + item.avatar }} style={styles.avatar} />
|
|
|
+ ) : (
|
|
|
+ <AvatarWithInitials
|
|
|
+ text={item.name?.split(' ')[0][0] + item.name?.split(' ')[1][0]}
|
|
|
+ flag={API_HOST + item?.flag1}
|
|
|
+ size={36}
|
|
|
+ fontSize={16}
|
|
|
+ borderColor={Colors.LIGHT_GRAY}
|
|
|
+ borderWidth={1}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ <View style={styles.userDetails}>
|
|
|
+ <Text style={styles.userName}>{item.name}</Text>
|
|
|
+ </View>
|
|
|
+ <Text style={[styles.text, { fontSize: getFontSize(12) }]}>
|
|
|
+ {formatDate(item.datetime)}
|
|
|
+ </Text>
|
|
|
+ </TouchableOpacity>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <ActionSheet
|
|
|
+ id="group-status"
|
|
|
+ gestureEnabled={Platform.OS === 'ios'}
|
|
|
+ containerStyle={{
|
|
|
+ borderTopLeftRadius: 15,
|
|
|
+ borderTopRightRadius: 15,
|
|
|
+ height: '70%',
|
|
|
+ padding: 10,
|
|
|
+ paddingBottom: 0
|
|
|
+ }}
|
|
|
+ isModal={false}
|
|
|
+ defaultOverlayOpacity={0.5}
|
|
|
+ onBeforeShow={(sheetRef) => {
|
|
|
+ const payload = sheetRef || null;
|
|
|
+ handleSheetOpen(payload);
|
|
|
+ }}
|
|
|
+ onBeforeClose={() => {
|
|
|
+ payloadData?.setInsetsColor(Colors.FILL_LIGHT);
|
|
|
+ }}
|
|
|
+ onClose={() => {
|
|
|
+ setGroupToken(null);
|
|
|
+ setMessageId(null);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <ScrollView
|
|
|
+ style={{ height: '100%', width: '100%', paddingTop: 8 }}
|
|
|
+ contentContainerStyle={{ gap: 8 }}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ >
|
|
|
+ {read.length > 0 ? (
|
|
|
+ <>
|
|
|
+ <Text style={styles.text}>Read by:</Text>
|
|
|
+ <FlashList
|
|
|
+ viewabilityConfig={{
|
|
|
+ waitForInteraction: true,
|
|
|
+ itemVisiblePercentThreshold: 50,
|
|
|
+ minimumViewTime: 1000
|
|
|
+ }}
|
|
|
+ data={read || []}
|
|
|
+ renderItem={renderUserItem}
|
|
|
+ keyExtractor={(item) => item.uid.toString()}
|
|
|
+ estimatedItemSize={100}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ contentContainerStyle={{ paddingBottom: 8 }}
|
|
|
+ scrollEnabled={false}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {received.length > 0 ? (
|
|
|
+ <>
|
|
|
+ <Text style={styles.text}>Delivered to:</Text>
|
|
|
+ <FlashList
|
|
|
+ viewabilityConfig={{
|
|
|
+ waitForInteraction: true,
|
|
|
+ itemVisiblePercentThreshold: 50,
|
|
|
+ minimumViewTime: 1000
|
|
|
+ }}
|
|
|
+ data={received || []}
|
|
|
+ renderItem={renderUserItem}
|
|
|
+ keyExtractor={(item) => item.uid.toString()}
|
|
|
+ estimatedItemSize={100}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ contentContainerStyle={{ paddingBottom: 16 }}
|
|
|
+ scrollEnabled={false}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+ </ScrollView>
|
|
|
+ </ActionSheet>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const styles = StyleSheet.create({
|
|
|
+ userDetails: {
|
|
|
+ flex: 1
|
|
|
+ },
|
|
|
+ userName: {
|
|
|
+ color: Colors.DARK_BLUE,
|
|
|
+ fontSize: getFontSize(14),
|
|
|
+ fontFamily: 'montserrat-700'
|
|
|
+ },
|
|
|
+ userSubtitle: {
|
|
|
+ color: Colors.DARK_BLUE,
|
|
|
+ fontSize: 14,
|
|
|
+ fontFamily: 'montserrat-500'
|
|
|
+ },
|
|
|
+ userItem: {
|
|
|
+ flexDirection: 'row',
|
|
|
+ alignItems: 'center',
|
|
|
+ paddingVertical: 8,
|
|
|
+ paddingHorizontal: 12,
|
|
|
+ backgroundColor: Colors.FILL_LIGHT,
|
|
|
+ gap: 8,
|
|
|
+ borderRadius: 8,
|
|
|
+ marginBottom: 6
|
|
|
+ },
|
|
|
+ avatar: {
|
|
|
+ width: 36,
|
|
|
+ height: 36,
|
|
|
+ borderRadius: 18,
|
|
|
+ borderWidth: 1,
|
|
|
+ borderColor: Colors.LIGHT_GRAY
|
|
|
+ },
|
|
|
+ text: {
|
|
|
+ color: Colors.DARK_BLUE,
|
|
|
+ fontSize: getFontSize(13),
|
|
|
+ fontWeight: '600'
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export default GroupStatusModal;
|