Eventos de bate-papo
Anteriormente, você criou uma conversa na CLI da Vonage e adicionou os dois usuários a essa conversa. As conversas são o meio pelo qual os usuários se comunicarão. Você pode saber mais sobre conversas na Documentação da Conversation API. Eventos de bate-papo, ou ConversationEvent Os objetos são enviados por meio da conversa que você criou; portanto, para receber eventos de chat, primeiro você precisará entrar na conversa. Para implementar isso, atualize o ChatViewModel classe.
Adicione o getMemberIDIfNeeded função:
class ChatViewModel(application: Application) : AndroidViewModel(application = application) {
private var memberID = ""
...
suspend fun getMemberIDIfNeeded(){
if(memberID.isNotEmpty()) return else getMemberID()
}
}
Isso verificará se o memberID, que é gerado quando você entra em uma conversa, ainda não foi definido. Caso contrário, ele chama getMemberID. Criar 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() ?: ""
}
}
}
Essa função tenta, em primeiro lugar, obter o ID de membro desse usuário com getConversationMember, se não der certo, ele entrará na conversa com joinConversation que retorna o ID do membro.
Agora que se tem a certeza de que esse usuário faz parte da conversa, você pode obter os eventos da conversa usando o cliente. Crie uma função chamada 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 recebe um ID de conversa e GetConversationEventsParameters. Os parâmetros permitem que você personalize a forma como os eventos são exibidos. Essa função retorna uma resposta paginada. Para saber mais sobre paginação, você pode ler o guia de paginação. Para exibir os eventos, crie uma função auxiliar que transforme os objetos de evento em uma string de exibição:
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
}
}
}
}
Os três eventos utilizados neste tutorial são MemberJoinedConversationEvent, MemberLeftConversationEvent, e MessageTextEvent. No caso de MessageTextEvent a função utiliza o memberID propriedade para determinar se a mensagem foi enviada pelo usuário atualmente conectado. Isso permitirá que a interface do usuário fixe as mensagens enviadas pelo usuário à direita e as mensagens recebidas à esquerda.
O ConversationEventListener
O aplicativo também precisa reagir aos eventos que ocorrem em uma conversa após o carregamento inicial; portanto, é necessário implementar um ConversationEventListener. Atualize seu método de login para definir esse ouvinte assim que a sessão for criada, da seguinte forma:
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
}
}
}
}
Quando um novo evento é recebido, ele é anexado à events que é publicado automaticamente, de modo que a interface do usuário seja atualizada.
Atualização da interface do usuário
Agora que o ChatViewModel é possível recuperar e monitorar novos eventos de conversa, atualizar o código da visualização para exibi-los, em MainActivity.kt Atualize o ChatScreen Componível:
@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()
}
}
Agora, o LazyColumn pega a lista de eventos e gera um Text elemento para cada um; aqui, chamamos de generateDisplayText para que o texto seja exibido e para verificar se esse evento pertence ou não ao usuário conectado. Por fim, adicionamos um runBlocking bloco para obter o ID do membro e, em seguida, recuperar os eventos de conversa assim que a visualização for carregada pela primeira vez.
Criação de um aplicativo de bate-papo para Android
Crie um aplicativo para Android que permita que os usuários troquem mensagens entre si usando o Client SDK do Android e Kotlin.