android 如何在发送消息时更新Jetpack Compose聊天应用中所有用户的状态?

2nc8po8w  于 2023-06-04  发布在  Android
关注(0)|答案(1)|浏览(192)

Jetpack合成。更新状态时出现问题。只有消息的发送者被更新,其他人都不会被更新。我使用MVI架构
在我的viewModel中有两个用于聊天屏幕的函数,当我在launchedEffect中使用Unit键打开聊天时,getMessages()会立即触发,即getMessages()然后运行一个协程,我在那里更新状态。每个用户的屏幕在那一刻刷新,显示消息。但是当我发送消息时,会触发一个事件,调用viewModel中的sendMessage(),在那里我更新状态,我发现你甚至可以这样更新它,协同程序中的getMessages()再次运行并更新状态。但是,问题是只有消息的发送者更新状态,而其他用户不更新,他们要么需要在键盘上做一些事情,要么重新启动聊天,以便更新状态。
ViewModel中的sendMessage()

@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("SimpleDateFormat")
private fun sendMessage(text: String) {
    val calendar: Calendar = Calendar.getInstance()
    val currentDate = LocalDate.now()

    val time = SimpleDateFormat("HH:mm")
    val currentMonthName = currentDate.month.getDisplayName(
        TextStyle.FULL, Locale.getDefault()
    )

    val message = MessageModel(
        name = Firebase.auth.currentUser?.displayName.toString(),
        text = text,
        time = time.format(calendar.time),
        isMine = false,
        sender = Firebase.auth.currentUser?.uid.toString(),
        date = currentDate.dayOfMonth.toString() + " " + currentMonthName,
        isNewDate = false
    )

    viewModelScope.launch {
        repository.addMessage(message)

        _uiState.value.counter += 1
    }
}

ViewModel中的getMessages()

private fun getMessages() {
    _uiState.update { currentState ->
        currentState.copy(
            isLoading = true
        )
    }

    viewModelScope.launch {
        var i = 0
        repository.getMessages()
            .map { messages ->
                _messagesItemsSenders.add(messages.get(0).sender)
                _messagesDates.add(messages.get(0).date)
                _messagesPaddingMineAfterLastOther.add(messages.get(0).isMine)

                // Check for new sender
                if ((_messagesItemsSenders.size > 1) && (!messages.get(0).isMine) and
                        (_messagesItemsSenders[i] == _messagesItemsSenders[i-1])) {
                    messages.get(0).isMoreOne = true
                }

                // Check for new date
                messages.get(0).isNewDate =
                    !((_messagesDates.size > 1) && (_messagesDates[i] == _messagesDates[i-1]))

                // Set padding for first message that called "isMine"
                messages.get(0).isPaddingMine = (_messagesPaddingMineAfterLastOther.size > 1) &&
                        (messages.get(0).isMine) and
                        (_messagesPaddingMineAfterLastOther[i]
                                != _messagesPaddingMineAfterLastOther[i-1])

                i += 1
                ChatViewState(messages = messages, isLoading = false)
            }
            .collect() { newState ->
                _uiState.value = newState
            }
    }
c3frrgcw

c3frrgcw1#

将接收到的消息存储在一个mutableStateList中,然后在您想要显示消息的任何地方引用该列表。当列表被更新时,(已接收到新消息)调用列表的可组合项将重新组合。

相关问题