index.tsx 4.97 KB
Newer Older
Diego Mello's avatar
Diego Mello committed
1
import React from 'react';
2
import { FlatList, Text, View, RefreshControl } from 'react-native';
3
import { dequal } from 'dequal';
Diego Mello's avatar
Diego Mello committed
4
5
import moment from 'moment';
import { connect } from 'react-redux';
6
7
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/core';
Diego Mello's avatar
Diego Mello committed
8

9
import * as List from '../../containers/List';
Diego Mello's avatar
Diego Mello committed
10
import Avatar from '../../containers/Avatar';
11
import * as HeaderButton from '../../containers/HeaderButton';
Diego Mello's avatar
Diego Mello committed
12
13
14
import I18n from '../../i18n';
import RocketChat from '../../lib/rocketchat';
import StatusBar from '../../containers/StatusBar';
Diego Mello's avatar
Diego Mello committed
15
16
import { withTheme } from '../../theme';
import { themes } from '../../constants/colors';
17
import SafeAreaView from '../../containers/SafeAreaView';
18
import styles from './styles';
19
import { ChatsStackParamList } from '../../stacks/types';
Diego Mello's avatar
Diego Mello committed
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
interface IReceipts {
	_id: string;
	roomId: string;
	userId: string;
	messageId: string;
	ts: string;
	user?: {
		_id: string;
		name: string;
		username: string;
	};
}

interface IReadReceiptViewState {
	loading: boolean;
	receipts: IReceipts[];
}

interface INavigationOption {
40
41
	navigation: StackNavigationProp<ChatsStackParamList, 'ReadReceiptsView'>;
	route: RouteProp<ChatsStackParamList, 'ReadReceiptsView'>;
42
43
44
45
46
47
48
49
50
51
52
53
54
	isMasterDetail: boolean;
}

interface IReadReceiptViewProps extends INavigationOption {
	Message_TimeAndDateFormat: string;
	theme: string;
}

class ReadReceiptView extends React.Component<IReadReceiptViewProps, IReadReceiptViewState> {
	private messageId: string;

	static navigationOptions = ({ navigation, isMasterDetail }: INavigationOption) => {
		const options: StackNavigationOptions = {
55
56
57
			title: I18n.t('Read_Receipt')
		};
		if (isMasterDetail) {
58
			options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} testID='read-receipt-view-close' />;
59
60
		}
		return options;
61
	};
Diego Mello's avatar
Diego Mello committed
62

63
	constructor(props: IReadReceiptViewProps) {
Diego Mello's avatar
Diego Mello committed
64
		super(props);
65
		this.messageId = props.route.params?.messageId;
Diego Mello's avatar
Diego Mello committed
66
67
68
69
70
71
72
73
74
75
		this.state = {
			loading: false,
			receipts: []
		};
	}

	componentDidMount() {
		this.load();
	}

76
	shouldComponentUpdate(nextProps: IReadReceiptViewProps, nextState: IReadReceiptViewState) {
Diego Mello's avatar
Diego Mello committed
77
		const { loading, receipts } = this.state;
Diego Mello's avatar
Diego Mello committed
78
79
80
81
		const { theme } = this.props;
		if (nextProps.theme !== theme) {
			return true;
		}
Diego Mello's avatar
Diego Mello committed
82
83
84
		if (nextState.loading !== loading) {
			return true;
		}
85
		if (!dequal(nextState.receipts, receipts)) {
Diego Mello's avatar
Diego Mello committed
86
87
88
89
90
			return true;
		}
		return false;
	}

91
	load = async () => {
Diego Mello's avatar
Diego Mello committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
		const { loading } = this.state;
		if (loading) {
			return;
		}

		this.setState({ loading: true });

		try {
			const result = await RocketChat.getReadReceipts(this.messageId);
			if (result.success) {
				this.setState({
					receipts: result.receipts,
					loading: false
				});
			}
		} catch (error) {
			this.setState({ loading: false });
			console.log('err_fetch_read_receipts', error);
		}
111
	};
Diego Mello's avatar
Diego Mello committed
112

Diego Mello's avatar
Diego Mello committed
113
	renderEmpty = () => {
114
		const { loading } = this.state;
Diego Mello's avatar
Diego Mello committed
115
		const { theme } = this.props;
116
117
118
		if (loading) {
			return null;
		}
Diego Mello's avatar
Diego Mello committed
119
		return (
120
121
122
			<View
				style={[styles.listEmptyContainer, { backgroundColor: themes[theme].chatComponentBackground }]}
				testID='read-receipt-view'>
123
				<Text style={[styles.emptyText, { color: themes[theme].auxiliaryTintColor }]}>{I18n.t('No_Read_Receipts')}</Text>
Diego Mello's avatar
Diego Mello committed
124
125
			</View>
		);
126
	};
Diego Mello's avatar
Diego Mello committed
127

128
	renderItem = ({ item }: { item: IReceipts }) => {
129
130
		const { theme, Message_TimeAndDateFormat } = this.props;
		const time = moment(item.ts).format(Message_TimeAndDateFormat);
131
132
133
		if (!item?.user?.username) {
			return null;
		}
Diego Mello's avatar
Diego Mello committed
134
		return (
Diego Mello's avatar
Diego Mello committed
135
			<View style={[styles.itemContainer, { backgroundColor: themes[theme].backgroundColor }]}>
136
				<Avatar text={item.user.username} size={40} />
Diego Mello's avatar
Diego Mello committed
137
138
				<View style={styles.infoContainer}>
					<View style={styles.item}>
139
						<Text style={[styles.name, { color: themes[theme].titleText }]}>{item?.user?.name}</Text>
140
						<Text style={[styles.time, { color: themes[theme].auxiliaryText }]}>{time}</Text>
Diego Mello's avatar
Diego Mello committed
141
					</View>
142
143
144
145
146
147
148
					<Text
						style={[
							styles.username,
							{
								color: themes[theme].auxiliaryText
							}
						]}>{`@${item.user.username}`}</Text>
Diego Mello's avatar
Diego Mello committed
149
150
151
				</View>
			</View>
		);
152
	};
Diego Mello's avatar
Diego Mello committed
153
154
155

	render() {
		const { receipts, loading } = this.state;
Diego Mello's avatar
Diego Mello committed
156
		const { theme } = this.props;
Diego Mello's avatar
Diego Mello committed
157
158

		return (
159
160
			<SafeAreaView testID='read-receipt-view'>
				<StatusBar />
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
				<FlatList
					data={receipts}
					renderItem={this.renderItem}
					ItemSeparatorComponent={List.Separator}
					ListEmptyComponent={this.renderEmpty}
					contentContainerStyle={List.styles.contentContainerStyleFlatList}
					style={[
						styles.list,
						{
							backgroundColor: themes[theme].chatComponentBackground,
							borderColor: themes[theme].separatorColor
						}
					]}
					refreshControl={<RefreshControl refreshing={loading} onRefresh={this.load} tintColor={themes[theme].auxiliaryText} />}
					keyExtractor={item => item._id}
				/>
Diego Mello's avatar
Diego Mello committed
177
178
179
180
			</SafeAreaView>
		);
	}
}
181

182
const mapStateToProps = (state: any) => ({
183
	Message_TimeAndDateFormat: state.settings.Message_TimeAndDateFormat
184
185
});

Diego Mello's avatar
Diego Mello committed
186
export default connect(mapStateToProps)(withTheme(ReadReceiptView));