-
COURTES Guillaume authoredCOURTES Guillaume authored
MessagesScreen.js 6.57 KiB
import React from 'react';
import { View, Text, StyleSheet, ActivityIndicator } from 'react-native';
import { GiftedChat, utils, Bubble, Send } from 'react-native-gifted-chat';
import AsyncStorage from '@react-native-async-storage/async-storage';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
const { isSameUser, isSameDay } = utils
require('dayjs/locale/fr');
class MessagesScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
messages: [],
user: null,
isLoading: true
}
this.onSend = this.onSend.bind(this);
}
async getMessages() {
let status = null;
//get user from asyncStorage
try {
const user = await AsyncStorage.getItem('@user');
if (user !== null) {
await this.setState({ user: JSON.parse(user) });
}
else {
this.props.logoutAuthentication();
}
} catch (error) {
console.warn(error);
}
//get messages from API
try {
const token = await AsyncStorage.getItem('@token');
//if token is stored, user is logged in
if (token !== null) {
fetch("http://163.172.178.146:3000/rooms/" + this.props.route.params.item._id + "/messages", {
method: 'GET',
headers: {
Authorization: "Bearer " + token
}
})
.then(response => {
status = response.status;
return response.json();
})
.then(async (json) => {
//OK Status : we update message state with room messages from API
if (status == 200) {
let messages = [];
json.forEach(message => {
messages.push(
{
_id: message._id,
text: message.body,
createdAt: message.date,
user: {
_id: message.author._id,
name: message.author.username,
avatar: 'https://placeimg.com/140/140/any',
},
},
);
});
this.setState({ messages: messages });
}
//Unauthorized status : token has expired, we force user to login to continue
else if (status == 401) {
this.props.logoutAuthentication();
}
//Handled error status
else if ("error" in json) {
console.warn(json.error);
}
//Unhandled error status
else {
console.warn("Unhandled error");
}
})
.catch(async (error) => {
//Error fetching url
});
}
//token is not stored, user is not logged in
else {
this.props.logoutAuthentication();
}
} catch (error) {
//Error fetching data
}
this.setState({ isLoading: false })
}
componentDidMount() {
this.getMessages();
const { navigation } = this.props;
this.focusListener = navigation.addListener("focus", async () => {
this.getMessages();
});
}
async onSend(messages = []) {
let status = null;
//post message in room with API
try {
const token = await AsyncStorage.getItem('@token');
//if token is stored, user is logged in
if (token !== null) {
fetch('http://163.172.178.146:3000/messages', {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: "Bearer " + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
body: messages[0].text,
roomId: this.props.route.params.item._id,
})
})
.then(response => {
status = response.status;
return response.json();
})
.then(async (json) => {
//OK Status : we update messages state with the message we post
if (status == 200) {
this.setState((previousState) => {
return {
messages: GiftedChat.append(previousState.messages, messages),
};
});
}
//Unauthorized status : token has expired, we force user to login to continue
else if (status == 401) {
this.props.logoutAuthentication();
}
//Handled error status
else if ("error" in json) {
console.warn(json.error);
}
//Unhandled error status
else {
console.warn("Unhandled error");
}
})
.catch(async (error) => {
//Error fetching url
});
}
//token is not stored, user is not logged in
else {
this.props.logoutAuthentication();
}
} catch (error) {
//Error fetching data
}
}
renderBubble(props) {
if (props.position == "right" || (isSameUser(props.currentMessage, props.previousMessage) && isSameDay(props.currentMessage, props.previousMessage))) {
return (
<Bubble
{...props}
wrapperStyle={{
left: {
backgroundColor: '#fff',
}
}}
/>
);
}
else {
return (
<View>
<Text style={styles.username}>{props.currentMessage.user.name}</Text>
<Bubble
{...props}
wrapperStyle={{
left: {
backgroundColor: '#fff',
}
}}
/>
</View>
);
}
}
renderSend(props) {
return (
<Send
{...props}
containerStyle={{
height: 45,
width: 45,
justifyContent: 'center',
alignItems: 'center',
}}
>
<FontAwesome5 name={'paper-plane'} solid color={'dodgerblue'} size={25} />
</Send>
);
}
render() {
if (this.state.isLoading)
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator size="large" />
</View>
)
else
return (
<GiftedChat
renderBubble={this.renderBubble}
messages={this.state.messages}
onSend={this.onSend}
user={{
_id: this.state.user.id,
}}
locale={'fr'}
placeholder="Écrivez un message..."
renderSend={this.renderSend}
/>
)
}
};
const styles = StyleSheet.create({
username: {
color: '#aaa'
}
});
export default MessagesScreen;