Combining Views and View Models

Last Edit: Oct 28 2020

ChannelHeaderView, MessageListView, MessageInputView, and corresponding ViewModels are separate components that usually will be displayed on the same screen. They work great without knowing about each other, but some of the chat features require passing data between different components

Connecting MessageListViewModel with MessageInputViewModel

MessageListViewModel contains information about the current mode which can be changed by interacting with its view. On the other hand, MessageInputViewModel needs information about the current mode to properly send the message. You can combine those view models in the following way:


messageListViewModel.getMode().observe(lifecycleOwner, mode -> {
    if (mode instanceof MessageListViewModel.Mode.Thread) {
        messageInputViewModel.setActiveThread(((MessageListViewModel.Mode.Thread) mode).getParentMessage());
    } else if (mode instanceof MessageListViewModel.Mode.Normal) {
        messageInputViewModel.resetThread();
    }
});
                    

messageListViewModel.mode.observe(lifecycleOwner) { mode ->
    when (mode) {
        is MessageListViewModel.Mode.Thread -> messageInputViewModel.setActiveThread(mode.parentMessage)
        is MessageListViewModel.Mode.Normal -> messageInputViewModel.resetThread()
    }
}
                    

Connecting MessageListView with MessageInputViewModel

MessageListView gives a possibility to set OnMessageEditHandler which will be invoked when the user wants to edit a message. On the other hand, MessageInputViewModel needs this information to properly send edited message:


messageListView.setOnMessageEditHandler((message) -> {
    messageInputViewModel.getEditMessage().postValue(message);
    return Unit.INSTANCE;
});
                    

messageListView.setOnMessageEditHandler {
    messageInputViewModel.editMessage.postValue(it)
}
                    

Connecting ChannelHeaderView with MessageListViewModel

ChannelHeaderView contains a back button which behaviour should be overridden. On the other hand, MessageListViewModel provides a mechanism for handling the back button when user is inside a thread. You can easily combine those two components in the following way:


channelHeaderView.setOnBackClick(() -> {
    messageListViewModel.onEvent(MessageListViewModel.Event.BackButtonPressed.INSTANCE);
    return Unit.INSTANCE; 
});
                    

channelHeaderView.onBackClick =
    { messageListViewModel.onEvent(MessageListViewModel.Event.BackButtonPressed) }