Kotlin

Chat-Ereignisse

Zuvor haben Sie in der Vonage-Befehlszeilenschnittstelle eine Unterhaltung erstellt und die beiden Benutzer zu dieser Unterhaltung hinzugefügt. Konversationen sind die Art und Weise, wie die Benutzer miteinander kommunizieren. Weitere Informationen zu Konversationen finden Sie in der Conversation API-Dokumentation. Chat-Ereignisse, oder ConversationEvent Objekte werden über die von Ihnen erstellte Konversation gesendet. Um ein Chat-Ereignis zu erhalten, müssen Sie also zunächst der Konversation beitreten. Um dies zu implementieren, aktualisieren Sie die ChatViewModel Klasse.

Fügen Sie die getMemberIDIfNeeded Funktion:

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

Damit wird geprüft, ob die memberIDdie generiert wird, wenn Sie einer Unterhaltung beitreten, noch nicht festgelegt wurde. Wenn nicht, ruft es getMemberID. erstellen 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() ?: ""
        }
    }
}

Diese Funktion versucht zunächst, die Mitglieds-ID dieses Benutzers mit getConversationMemberWenn es nicht klappt, wird es sich an der Unterhaltung mit joinConversation die die Mitglieds-ID zurückgibt.

Nun, da dieser Benutzer garantiert ein Mitglied der Konversation ist, können Sie die Konversationsereignisse über den Client abrufen. Erstellen Sie eine Funktion namens 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 nimmt eine Gesprächs-ID und GetConversationEventsParameters. Mit den Parametern können Sie festlegen, wie die Ereignisse an Sie zurückgegeben werden sollen. Diese Funktion gibt eine paginierte Antwort zurück. Um mehr über Paginierung zu erfahren, lesen Sie bitte die Paginierungsanleitung. Um die Ereignisse anzuzeigen, erstellen Sie eine Hilfsfunktion, die die Ereignisobjekte in einen Anzeige-String umwandelt:

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
            }
        }
    }
}

Die drei Ereignisse, die in diesem Lernprogramm verwendet werden, sind MemberJoinedConversationEvent, MemberLeftConversationEventund MessageTextEvent. Im Fall von MessageTextEvent verwendet die Funktion die memberID Eigenschaft, um festzustellen, ob die Nachricht vom aktuell angemeldeten Benutzer gesendet wurde. Dadurch kann die Benutzeroberfläche die gesendeten Nachrichten des Benutzers rechts und die empfangenen Nachrichten links anordnen.

Die ConversationEventListener

Die Anwendung muss auch auf Ereignisse in einer Konversation nach dem anfänglichen Laden reagieren, daher müssen Sie eine ConversationEventListener. Aktualisieren Sie Ihre Anmeldemethode, um diesen Listener zu setzen, sobald eine Sitzung erstellt wurde:

    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
                }
            }
        }
    }

Wenn ein neues Ereignis empfangen wird, wird es an die events die automatisch veröffentlicht wird, damit die Benutzeroberfläche aktualisiert werden kann.

Aktualisierung der Benutzeroberfläche

Nun, da die ChatViewModel kann neue Konversationsereignisse abrufen und abwarten, den Ansichtscode aktualisieren, um sie anzuzeigen, in MainActivity.kt Aktualisieren Sie die ChatScreen Zusammensetzbar:

@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()
    }
}

Jetzt ist die LazyColumn nimmt die Ereignisliste und erzeugt eine Text Element für jedes, hier nennen wir generateDisplayText um den anzuzeigenden Text zu erhalten und festzustellen, ob das Ereignis dem angemeldeten Benutzer gehört oder nicht. Schließlich fügen wir eine runBlocking Block, um die Mitglieds-ID zu erhalten und dann die Konversationsereignisse zu erhalten, wenn die Ansicht zum ersten Mal geladen wird.