Cette seconde et dernière partie du didacticiel est divisée en plusieurs sections :
Remarque : dans certains cas, les exemples de code pour JavaScript et TypeScript sont identiques et sont donc combinés.
Prérequis
Assurez-vous d'avoir terminé la première partie de ce didacticiel relative aux Salles de chat.
S'abonner aux événements des messages de chat
L'instance ChatRoom
utilise des événements pour communiquer lorsque des événements se produisent dans une salle de chat. Pour commencer à mettre en œuvre l'expérience de chat, vous devez montrer à vos utilisateurs quand d'autres personnes envoient un message dans la salle à laquelle ils sont connectés.
Ici, vous vous abonnez aux événements des messages de chat. Plus tard, nous vous montrerons comment mettre à jour une liste de messages que vous créez, qui est mise à jour à chaque message/événement.
Dans votre App
, dans le hook useEffect
, abonnez-vous à tous les événements de message :
TypeScript/JavaScript :
// App.tsx / App.jsx useEffect(() => { // ... const unsubscribeOnMessageReceived = room.addListener('message', (message) => {}); return () => { // ... unsubscribeOnMessageReceived(); }; }, []);
Afficher les messages reçus
La réception de messages est au cœur de l'expérience de chat. À l'aide du kit SDK Chat JS, vous pouvez configurer votre code pour recevoir facilement les événements des autres utilisateurs connectés à une salle de chat.
Plus tard, nous vous montrerons comment effectuer des actions dans une salle de chat qui tirent parti des composants que vous créez ici.
Dans votre App
, définissez un état nommé messages
avec un type de tableau ChatMessage
nommé messages
:
// App.tsx // ... import { ChatRoom, ChatMessage, ConnectionState } from 'amazon-ivs-chat-messaging'; export default function App() { const [messages, setMessages] = useState<ChatMessage[]>([]); //... }
Ensuite, dans la fonction d'écouteur message
, ajoutez message
au tableau messages
:
TypeScript/JavaScript :
// App.tsx / App.jsx // ... const unsubscribeOnMessageReceived = room.addListener('message', (message) => { setMessages((msgs) => [...msgs, message]); }); // ...
Ci-dessous, nous passons en revue les tâches pour afficher les messages reçus :
Créer un composant de message
Le composant Message
est chargé de rendre le contenu d'un message reçu par votre salle de chat. Dans cette section, vous créez un composant de messages pour afficher les messages de chat individuels dans l'App
.
Dans le répertoire src
, créez un fichier nommé Message
. Transmettez le type ChatMessage
de ce composant et transmettez la chaîne content
provenant des propriétés ChatMessage
pour afficher le texte du message reçu des écouteurs de messages de la salle de chat. Dans le navigateur de projets, accédez à Message
.
// Message.tsx import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { ChatMessage } from 'amazon-ivs-chat-messaging'; type Props = { message: ChatMessage; } export const Message = ({ message }: Props) => { return ( <View style={styles.root}> <Text>{message.sender.userId}</Text> <Text style={styles.textContent}>{message.content}</Text> </View> ); }; const styles = StyleSheet.create({ root: { backgroundColor: 'silver', padding: 6, borderRadius: 10, marginHorizontal: 12, marginVertical: 5, marginRight: 50, }, textContent: { fontSize: 17, fontWeight: '500', flexShrink: 1, }, });
Conseil : utilisez ce composant pour stocker les différentes propriétés que vous souhaitez afficher dans les lignes de vos messages, par exemple, les URL des avatars, les noms d'utilisateur et les horodatages de l'envoi du message.
Reconnaître les messages envoyés par l'utilisateur actuel
Pour reconnaître le message envoyé par l'utilisateur actuel, nous modifions le code et créons un contexte React pour stocker le userId
de l'utilisateur actuel.
Dans le répertoire src
, créez un fichier nommé UserContext
:
// UserContext.tsx import React from 'react'; const UserContext = React.createContext<string | undefined>(undefined); export const useUserContext = () => { const context = React.useContext(UserContext); if (context === undefined) { throw new Error('useUserContext must be within UserProvider'); } return context; }; export const UserProvider = UserContext.Provider;
Remarque : ici, nous avons utilisé le hook useState
pour stocker la valeur userId
. Dorénavant, vous pourrez utiliser setUserId
pour modifier le contexte de l'utilisateur ou à des fins de connexion.
Ensuite, remplacez userId
dans le premier paramètre transmis à tokenProvider
, en utilisant le contexte créé précédemment. Assurez-vous d'ajouter la capacité SEND_MESSAGE
à votre fournisseur de jetons, comme indiqué ci-dessous ; elle est requise pour envoyer des messages.
// App.tsx // ... import { useUserContext } from './UserContext'; // ... export default function App() { const [messages, setMessages] = useState<ChatMessage[]>([]); const userId = useUserContext(); const [room] = useState( () => new ChatRoom({ regionOrUrl: process.env.REGION, tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE']), }), ); // ... }
Dans votre composant Message
, utilisez le UserContext
créé auparavant, déclarez la variable isMine
, associez le userId
de l'expéditeur au userId
du contexte et appliquez différents styles de messages à l'utilisateur actuel.
// Message.tsx import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { ChatMessage } from 'amazon-ivs-chat-messaging'; import { useUserContext } from './UserContext'; type Props = { message: ChatMessage; } export const Message = ({ message }: Props) => { const userId = useUserContext(); const isMine = message.sender.userId === userId; return ( <View style={[styles.root, isMine && styles.mine]}> {!isMine && <Text>{message.sender.userId}</Text>} <Text style={styles.textContent}>{message.content}</Text> </View> ); }; const styles = StyleSheet.create({ root: { backgroundColor: 'silver', padding: 6, borderRadius: 10, marginHorizontal: 12, marginVertical: 5, marginRight: 50, }, textContent: { fontSize: 17, fontWeight: '500', flexShrink: 1, }, mine: { flexDirection: 'row-reverse', backgroundColor: 'lightblue', }, });
Afficher une liste de messages de chat
Maintenant, répertoriez les messages à l'aide des composants FlatList
et Message
:
// App.tsx // ... const renderItem = useCallback<ListRenderItem<ChatMessage>>(({ item }) => { return ( <Message key={item.id} message={item} /> ); }, []); return ( <SafeAreaView style={styles.root}> <Text>Connection State: {connectionState}</Text> <FlatList inverted data={messages} renderItem={renderItem} /> <View style={styles.messageBar}> <MessageInput value={messageToSend} onMessageChange={setMessageToSend} /> <SendButton disabled={isSendDisabled} onPress={onMessageSend} /> </View> </SafeAreaView> ); // ...
Toutes les pièces du puzzle sont maintenant en place pour que votre App
commence à afficher les messages reçus par votre salle de chat. Continuez ci-dessous pour découvrir comment réaliser des actions dans une salle de chat qui tirent parti des composants que vous avez créés.
Effectuer des actions dans une salle de chat
L'envoi de messages et l'exécution d'actions de modérateur sont quelques-uns des principaux moyens d'interagir avec une salle de chat. Vous apprendrez ici comment utiliser divers objets de demande de chat pour effectuer des actions courantes dans Chatterbox, telles que l'envoi d'un message, la suppression d'un message et la déconnexion d'autres utilisateurs.
Toutes les actions d'une salle de chat suivent un schéma commun : à chaque action que vous effectuez dans une salle de chat, il existe un objet de demande correspondant. Pour chaque demande, il existe un objet de réponse correspondant que vous recevez lors de la confirmation de la demande.
Tant que vos utilisateurs disposent des capacités appropriées lorsque vous créez un jeton de chat, ils peuvent effectuer avec succès la ou les actions correspondantes à l'aide des objets de demande pour voir quelles demandes vous pouvez effectuer dans une salle de chat.
Ci-dessous, nous expliquons comment envoyer un message et supprimer un message.
Envoi d'un message
La classe SendMessageRequest
permet d'envoyer des messages dans une salle de chat. Ici, vous modifiez votre App
pour envoyer une demande de message à l'aide du composant que vous avez créé dans Créer une entrée de message (dans la première partie de ce didacticiel).
Pour commencer, définissez une nouvelle propriété booléenne nommée isSending
avec le hook useState
. Utilisez cette nouvelle propriété pour activer l'état désactivé de votre élément button
à l'aide de la constante isSendDisabled
. Dans le gestionnaire d'événements correspondant à votre SendButton
, effacez la valeur de messageToSend
et définissez isSending
sur true (vrai).
Comme vous allez passer un appel d'API à partir de ce bouton, l'ajout du booléen isSending
permet d'éviter que plusieurs appels d'API ne se produisent en même temps, en désactivant les interactions utilisateur sur votre SendButton
jusqu'à ce que la demande soit complète.
Remarque : l'envoi de messages ne fonctionne que si vous avez ajouté la capacité SEND_MESSAGE
à votre fournisseur de jetons, comme indiqué ci-dessus dans la rubrique Reconnaître les messages envoyés par l'utilisateur actuel.
TypeScript/JavaScript :
// App.tsx / App.jsx // ... const [isSending, setIsSending] = useState(false); // ... const onMessageSend = () => { setIsSending(true); setMessageToSend(''); }; // ... const isSendDisabled = connectionState !== 'connected' || isSending; // ...
Préparez la demande en créant une instance SendMessageRequest
et en transmettant le contenu du message au constructeur. Après avoir défini les états isSending
et messageToSend
, appelez la méthode sendMessage
qui envoie la demande à la salle de chat. Enfin, effacez l'indicateur isSending
lors de la réception de la confirmation ou du rejet de la demande.
TypeScript/JavaScript :
// App.tsx / App.jsx // ... import { ChatRoom, ConnectionState, SendMessageRequest } from 'amazon-ivs-chat-messaging' // ... const onMessageSend = async () => { const request = new SendMessageRequest(messageToSend); setIsSending(true); setMessageToSend(''); try { const response = await room.sendMessage(request); } catch (e) { console.log(e); // handle the chat error here... } finally { setIsSending(false); } }; // ...
Essayez Chatterbox : essayez d'envoyer un message en rédigeant un message avec votre MessageBar
et en appuyant sur votre SendButton
. Vous devriez voir le message que vous avez envoyé s'afficher dans la MessageList
que vous avez créée précédemment.
Supprimer un message
Pour supprimer un message d'une salle de chat, vous devez disposer de la capacité appropriée. Les capacités sont accordées lors de l'initialisation du jeton de chat que vous utilisez pour vous authentifier dans une salle de chat. Pour les besoins de cette section, le formulaire ServerApp
de la section Configurer un serveur d'authentification/d'autorisation local (dans la partie 1 de ce didacticiel) vous permet de spécifier les capacités des modérateurs. Cela se fait dans votre application à l'aide de l'objet tokenProvider
que vous avez créé dans la section Créer un fournisseur de jetons (également dans la partie 1).
Vous pouvez ici modifier votre Message
en ajoutant une fonction pour supprimer le message.
Tout d'abord, ouvrez le App.tsx
et ajoutez la fonctionnalité DELETE_MESSAGE
. (capabilities
est le deuxième paramètre de votre fonction tokenProvider
.)
Remarque : c'est de cette manière que votre ServerApp
informe les API IVS Chat que l'utilisateur associé au jeton de chat obtenu peut supprimer des messages dans une salle de chat. Dans une situation réelle, vous aurez probablement une logique backend plus complexe pour gérer les capacités des utilisateurs dans l'infrastructure de votre application serveur.
TypeScript/JavaScript :
// App.tsx / App.jsx // ... const [room] = useState(() => new ChatRoom({ regionOrUrl: process.env.REGION, tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE', 'DELETE_MESSAGE']), }), ); // ...
Au cours des étapes suivantes, vous mettrez à jour votre Message
pour afficher un bouton de suppression.
Définissez une nouvelle fonction appelée onDelete
qui accepte une chaîne comme paramètre et renvoie Promise
. Pour le paramètre de chaîne, transmettez l'ID du message de votre composant.
// Message.tsx import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { ChatMessage } from 'amazon-ivs-chat-messaging'; import { useUserContext } from './UserContext'; export type Props = { message: ChatMessage; onDelete(id: string): Promise<void>; }; export const Message = ({ message, onDelete }: Props) => { const userId = useUserContext(); const isMine = message.sender.userId === userId; const handleDelete = () => onDelete(message.id); return ( <View style={[styles.root, isMine && styles.mine]}> {!isMine && <Text>{message.sender.userId}</Text>} <View style={styles.content}> <Text style={styles.textContent}>{message.content}</Text> <TouchableOpacity onPress={handleDelete}> <Text>Delete<Text/> </TouchableOpacity> </View> </View> ); }; const styles = StyleSheet.create({ root: { backgroundColor: 'silver', padding: 6, borderRadius: 10, marginHorizontal: 12, marginVertical: 5, marginRight: 50, }, content: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', }, textContent: { fontSize: 17, fontWeight: '500', flexShrink: 1, }, mine: { flexDirection: 'row-reverse', backgroundColor: 'lightblue', }, });
Ensuite, mettez à jour votre composant renderItem
pour qu'il reflète les dernières modifications apportées à votre composant FlatList
.
Dans App
, définissez une fonction nommée handleDeleteMessage
et transmettez-la à la propriété MessageList onDelete
:
// App.tsx // ... const handleDeleteMessage = async (id: string) => {}; const renderItem = useCallback<ListRenderItem<ChatMessage>>(({ item }) => { return ( <Message key={item.id} message={item} onDelete={handleDeleteMessage} /> ); }, [handleDeleteMessage]); // ...
Préparez une demande en créant une instance de DeleteMessageRequest
, en transmettant l'ID de message correspondant au paramètre du constructeur et en appelant deleteMessage
qui accepte la demande préparée ci-dessus :
// App.tsx // ... const handleDeleteMessage = async (id: string) => { const request = new DeleteMessageRequest(id); await room.deleteMessage(request); }; // ...
Ensuite, vous mettez à jour votre état messages
pour refléter une nouvelle liste de messages qui omet le message que vous venez de supprimer.
Dans le hook useEffect
, écoutez l'événement messageDelete
et mettez à jour votre tableau d'états messages
en supprimant le message dont l'ID correspond au paramètre message
.
Remarque : l'événement messageDelete
peut être déclenché en cas de suppression de messages par l'utilisateur actuel ou par tout autre utilisateur présent dans la salle. Le gérer dans le gestionnaire d'événements (plutôt qu'à côté de la demande deleteMessage
) vous permet d'unifier la gestion des messages de suppression.
TypeScript/JavaScript :
// App.tsx / App.jsx // ... const unsubscribeOnMessageDeleted = room.addListener('messageDelete', (deleteMessageEvent) => { setMessages((prev) => prev.filter((message) => message.id !== deleteMessageEvent.id)); }); return () => { // ... unsubscribeOnMessageDeleted(); }; // ...
Vous pouvez désormais supprimer des utilisateurs d'une salle de chat dans votre application de chat.
Étapes suivantes
À titre expérimental, essayez de mettre en œuvre d'autres actions dans une salle, par exemple la déconnexion d'un autre utilisateur.