Start filling MatrixRoom class and use it in MessagesScreen

This commit is contained in:
ganfra 2022-11-04 17:56:14 +01:00
parent d04d847521
commit 11b74c0279
11 changed files with 202 additions and 74 deletions

View file

@ -2,6 +2,7 @@
package io.element.android.x.features.messages
import Avatar
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.*
@ -12,18 +13,23 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.core.data.LogCompositions
import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.features.messages.model.MessagesViewState
@Composable
fun MessagesScreen(roomId: String) {
val viewModel: MessagesViewModel = mavericksViewModel(argsFactory = { roomId })
LogCompositions(tag = "MessagesScreen", msg = "Root")
val roomTitle by viewModel.collectAsState(prop1 = MessagesViewState::roomTitle)
MessagesContent(roomTitle)
val roomTitle by viewModel.collectAsState(MessagesViewState::roomName)
val roomAvatar by viewModel.collectAsState(MessagesViewState::roomAvatar)
MessagesContent(roomTitle, roomAvatar)
}
@Composable
fun MessagesContent(roomTitle: String) {
fun MessagesContent(
roomTitle: String?,
roomAvatar: AvatarData?
) {
val appBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(appBarState)
LogCompositions(tag = "RoomListScreen", msg = "Content")
@ -31,7 +37,14 @@ fun MessagesContent(roomTitle: String) {
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
title = { Text(text = roomTitle) }
navigationIcon = {
if (roomAvatar != null) {
IconButton(onClick = {}) {
Avatar(roomAvatar)
}
}
},
title = { Text(text = roomTitle ?: "") }
)
},
content = { padding ->

View file

@ -1,48 +1,69 @@
package io.element.android.x.features.messages
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.Success
import io.element.android.x.core.data.parallelMap
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.designsystem.components.avatar.AvatarSize
import io.element.android.x.features.messages.model.MessagesViewState
import io.element.android.x.matrix.MatrixClient
import io.element.android.x.matrix.MatrixInstance
import io.element.android.x.matrix.room.RoomSummary
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import io.element.android.x.matrix.room.MatrixRoom
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.rustcomponents.sdk.mediaSourceFromUrl
class MessagesViewModel(initialState: MessagesViewState) :
class MessagesViewModel(
private val client: MatrixClient,
private val room: MatrixRoom,
private val initialState: MessagesViewState
) :
MavericksViewModel<MessagesViewState>(initialState) {
private val matrix = MatrixInstance.getInstance()
companion object : MavericksViewModelFactory<MessagesViewModel, MessagesViewState> {
override fun create(
viewModelContext: ViewModelContext,
state: MessagesViewState
): MessagesViewModel? {
val matrix = MatrixInstance.getInstance()
val client = matrix.activeClient()
val room = client.getRoom(state.roomId) ?: return null
return MessagesViewModel(client, room, state)
}
}
init {
handleInit()
}
private fun handleInit() {
viewModelScope.launch {
}
room.syncUpdateFlow()
.onEach {
val avatarData =
loadAvatarData(room.name ?: room.roomId.value, room.avatarUrl, AvatarSize.SMALL)
setState {
copy(
roomName = room.name, roomAvatar = avatarData,
)
}
}.launchIn(viewModelScope)
}
private suspend fun loadAvatarData(
client: MatrixClient,
name: String,
url: String?,
size: AvatarSize = AvatarSize.MEDIUM
): AvatarData {
val mediaContent = url?.let {
val mediaSource = mediaSourceFromUrl(it)
client.loadMediaThumbnailForSource(mediaSource, size.value.toLong(), size.value.toLong())
client.loadMediaThumbnailForSource(
mediaSource,
size.value.toLong(),
size.value.toLong()
)
}
return mediaContent?.fold(
{ it },
@ -52,10 +73,6 @@ class MessagesViewModel(initialState: MessagesViewState) :
}
}
private suspend fun getClient(): MatrixClient {
return matrix.matrixClient().first().get()
}
override fun onCleared() {
super.onCleared()
}

View file

@ -2,15 +2,14 @@ package io.element.android.x.features.messages.model
import com.airbnb.mvrx.MavericksState
import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.matrix.core.RoomId
data class MessagesViewState(
val roomId: String,
val roomTitle: String = "",
val roomName: String? = null,
val roomAvatar: AvatarData? = null
) : MavericksState {
@Suppress("unused")
constructor(roomId: String) : this(roomId = roomId, roomTitle = "", roomAvatar = null)
constructor(roomId: String) : this(roomId = roomId, roomName = null, roomAvatar = null)
}

View file

@ -131,7 +131,7 @@ class RoomListViewModel(initialState: RoomListViewState) :
}
private suspend fun getClient(): MatrixClient {
return matrix.matrixClient().first().get()
return matrix.client().first().get()
}
override fun onCleared() {