Kotlin

Événements de chat

Plus tôt, vous avez créé une conversation dans le CLI de Vonage et ajouté les deux utilisateurs à cette conversation. Les conversations sont le moyen de communication des utilisateurs. Vous pouvez en savoir plus sur les conversations dans la section Documentation sur l'API Conversation. Événements de chat, ou ConversationEvent sont envoyés en utilisant la conversation que vous avez créée, donc pour obtenir l'événement de chat, vous devez d'abord rejoindre la conversation. Pour ce faire, mettez à jour le fichier ChatViewModel classe.

Ajouter le getMemberIDIfNeeded fonction :

class ChatViewModel(application: Application) : AndroidViewModel(application = application) {
    private var memberID = "" 
    ...
    
    suspend fun getMemberIDIfNeeded(){
        if(memberID.isNotEmpty()) return else getMemberID()
    }
}

Cela permet de vérifier si le memberIDqui est généré lorsque vous participez à une conversation, a été défini. Si ce n'est pas le cas, il appelle getMemberID. Créer getMemberID:

class ChatViewModel(application: Application) : AndroidViewModel(application = application) {
    ...
    
    private suspend fun getMemberID() {
        try {
            val member = client.getConversationMember(conversationID,  "me")
            memberID = member.id
        }
        catch (e: VGError) {
            //User not yet a member of the conversation
            memberID = client.joinConversation(conversationID)
        }
        catch (err:Error) {
            isError = true
            error = err.localizedMessage?.toString() ?: ""
        }
    }
}

Cette fonction tente d'abord d'obtenir l'identifiant de membre de cet utilisateur avec getConversationMembers'il échoue, il rejoindra la conversation avec joinConversation qui renvoie l'identifiant du membre.

Maintenant que cet utilisateur est assuré d'être un membre de la conversation, vous pouvez obtenir les événements de la conversation à l'aide du client. Créez une fonction appelée getConversationEvents:

class ChatViewModel(application: Application) : AndroidViewModel(application = application) {
    ...
    suspend fun getConversationEvents(){
        val params = GetConversationEventsParameters(PresentingOrder.ASC,100)
        try {
            val eventsPage = client.getConversationEvents(conversationID, params)
            events.clear()
            events.addAll(eventsPage.events.toMutableStateList())
        }
        catch (err:Error) {
            isError = true
            error = err.localizedMessage?.toString() ?: ""
        }
    }
}

getConversationEvents prend un identifiant de conversation et GetConversationEventsParameters. Les paramètres vous permettent de personnaliser la façon dont les événements vous sont renvoyés. Cette fonction renvoie une réponse paginée. Pour en savoir plus sur la pagination, vous pouvez consulter la page guide de pagination. Pour afficher les événements, créez une fonction d'aide qui transforme les objets d'événement en une chaîne d'affichage :

class ChatViewModel(application: Application) : AndroidViewModel(application = application) {
    ...
    fun generateDisplayedText(event: PersistentConversationEvent): Pair<String, Boolean>{
        var from = "System"
        return when(event){
            is MemberJoinedConversationEvent -> {
                val from = event.body.user.name
                "$from joined" to false
            }
            is MemberLeftConversationEvent -> {
                val from = event.body.user.name
                "$from left" to false
            }
            is MessageTextEvent -> {
                var isUser = false
                val userInfo = event.from as EmbeddedInfo
                isUser = userInfo.memberId == memberID
                from = if(isUser) "" else "${userInfo.user.name}: "
                "$from ${event.body.text}" to isUser
            }
            else -> {
                "" to false
            }
        }
    }
}

Les trois événements utilisés dans ce tutoriel sont les suivants MemberJoinedConversationEvent, MemberLeftConversationEventet MessageTextEvent. Dans le cas de MessageTextEvent la fonction utilise le memberID pour déterminer si le message a été envoyé par l'utilisateur actuellement connecté. Cela permettra à l'interface utilisateur d'épingler les messages envoyés par l'utilisateur à droite et les messages reçus à gauche.

Les ConversationEventListener

L'application doit également réagir aux événements d'une conversation après son chargement initial. ConversationEventListener. Mettez à jour votre méthode de connexion pour définir cet auditeur une fois qu'une session est créée, comme par exemple :

    fun login(username: String) {
        val jwt = if(username == "Alice") aliceJwt else bobJwt
        client.createSession(jwt) { err, sessionId ->
            when {
                err != null -> {
                    isError = true
                    error = err.localizedMessage?.toString() ?: ""
                }
                else -> {
                    client.setOnConversationEventListener {
                        events.add(it as PersistentConversationEvent)
                    }
                    isLoggedIn = true
                }
            }
        }
    }

Lorsqu'un nouvel événement est reçu, il est ajouté à la liste des événements. events qui est automatiquement publiée pour que l'interface utilisateur soit mise à jour.

Mise à jour de l'interface utilisateur

Maintenant que la ChatViewModel peut récupérer et écouter les nouveaux événements de conversation, mettre à jour le code de la vue pour les afficher, en MainActivity.kt Mettre à jour le ChatScreen Composable :

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChatScreen() {
    val vm = LocalChatState.current
    var text by remember { mutableStateOf("") }

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Bottom
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxWidth()
        ) {
            items(vm.events) { event ->
                val (text, isUser) = vm.generateDisplayedText(event)
                val textAlightment = if (isUser) TextAlign.Right else TextAlign.Left
                val textColor = if (isUser) Color.Blue else Color.Black
                Text(
                    text = text,
                    fontSize = 20.sp,
                    textAlign = textAlightment,
                    color = textColor
                )
            }
        }
        Row(){
            TextField(
                value = text,
                onValueChange = { text = it },
                label = { Text("Message") }
            )
            Button(onClick = {}
            }) {
                Text("Send")
            }
        }
    }

    runBlocking {
        vm.getMemberIDIfNeeded()
        vm.getConversationEvents()
    }
}

Aujourd'hui, le LazyColumn prend la liste des événements et génère un Text pour chacun d'entre eux, que nous appelons ici generateDisplayText pour obtenir le texte à afficher, et si cet événement appartient à l'utilisateur connecté ou non. Enfin, nous ajoutons un élément runBlocking pour obtenir l'identifiant du membre, puis les événements de conversation lors du premier chargement de la vue.