Start implementing logic for room summary list
This commit is contained in:
parent
7975ea16e4
commit
a609433a50
20 changed files with 423 additions and 119 deletions
|
|
@ -12,17 +12,19 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.compose.collectAsState
|
||||
import com.airbnb.mvrx.compose.mavericksViewModel
|
||||
import io.element.android.x.ui.theme.components.Avatar
|
||||
import org.matrix.rustcomponents.sdk.Room
|
||||
import io.element.android.x.designsystem.components.Avatar
|
||||
import io.element.android.x.matrix.core.RoomId
|
||||
import io.element.android.x.matrix.room.RoomSummary
|
||||
|
||||
@Composable
|
||||
fun RoomListScreen(
|
||||
viewModel: RoomListViewModel = mavericksViewModel(),
|
||||
onRoomClicked: (String) -> Unit = { },
|
||||
onLogoutClicked: () -> Unit = { },
|
||||
onRoomClicked: (RoomId) -> Unit = { }
|
||||
) {
|
||||
val state by viewModel.collectAsState()
|
||||
RoomListContent(state, onRoomClicked, onLogoutClicked)
|
||||
|
|
@ -31,8 +33,8 @@ fun RoomListScreen(
|
|||
@Composable
|
||||
fun RoomListContent(
|
||||
state: RoomListViewState,
|
||||
onRoomClicked: (String) -> Unit,
|
||||
onLogoutClicked: () -> Unit
|
||||
onRoomClicked: (RoomId) -> Unit,
|
||||
onLogoutClicked: () -> Unit,
|
||||
) {
|
||||
Surface(color = MaterialTheme.colorScheme.background) {
|
||||
Column(
|
||||
|
|
@ -62,7 +64,8 @@ fun RoomListTopBar(state: RoomListViewState, onLogoutClicked: () -> Unit) {
|
|||
TopAppBar(
|
||||
title = {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val matrixUser = state.user
|
||||
Avatar(data = matrixUser.avatarData)
|
||||
|
|
@ -83,19 +86,24 @@ fun RoomListTopBar(state: RoomListViewState, onLogoutClicked: () -> Unit) {
|
|||
@Composable
|
||||
private fun RoomItem(
|
||||
modifier: Modifier = Modifier,
|
||||
room: Room,
|
||||
onClick: (String) -> Unit
|
||||
room: RoomSummary,
|
||||
onClick: (RoomId) -> Unit
|
||||
) {
|
||||
if (room !is RoomSummary.Filled) {
|
||||
return
|
||||
}
|
||||
val details = room.details
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier
|
||||
.clickable {
|
||||
onClick(room.id())
|
||||
onClick(room.details.roomId)
|
||||
}
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp)
|
||||
) {
|
||||
Column(modifier = modifier.padding(8.dp)) {
|
||||
Text(text = "Room: ${room.name() ?: room.id()}")
|
||||
Text(text = if (room.isDirect()) "Direct" else "Room")
|
||||
Text(fontSize = 18.sp, text = details.name.orEmpty())
|
||||
Text(text = details.lastMessage?.toString().orEmpty(), maxLines = 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,19 +4,14 @@ 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.tryOrNull
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
import io.element.android.x.matrix.MatrixInstance
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.rustcomponents.sdk.Room
|
||||
import org.matrix.rustcomponents.sdk.StoppableSpawn
|
||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
||||
import org.matrix.rustcomponents.sdk.mediaSourceFromUrl
|
||||
|
||||
class RoomListViewModel(initialState: RoomListViewState) :
|
||||
MavericksViewModel<RoomListViewState>(initialState), MatrixClient.SlidingSyncListener {
|
||||
MavericksViewModel<RoomListViewState>(initialState) {
|
||||
|
||||
private var sync: StoppableSpawn? = null
|
||||
private val matrix = MatrixInstance.getInstance()
|
||||
|
||||
init {
|
||||
|
|
@ -33,18 +28,26 @@ class RoomListViewModel(initialState: RoomListViewState) :
|
|||
private fun handleInit() {
|
||||
viewModelScope.launch {
|
||||
val client = getClient()
|
||||
val url = client.avatarUrl()
|
||||
val mediaSource = mediaSourceFromUrl(url)
|
||||
client.startSync()
|
||||
val userAvatarUrl = client.loadUserAvatarURLString().getOrNull()
|
||||
val userDisplayName = client.loadUserDisplayName().getOrNull()
|
||||
val avatarData = userAvatarUrl?.let {
|
||||
mediaSourceFromUrl(it)
|
||||
}?.let {
|
||||
client.loadMediaContentForSource(it)
|
||||
}
|
||||
setState {
|
||||
copy(
|
||||
user = MatrixUser(
|
||||
username = tryOrNull { client.username() } ?: "Room list",
|
||||
avatarUrl = mediaSource.url(),
|
||||
avatarData = client.loadMedia2(url)
|
||||
username = userDisplayName,
|
||||
avatarUrl = userAvatarUrl,
|
||||
avatarData = avatarData?.getOrNull()
|
||||
)
|
||||
)
|
||||
}
|
||||
sync = client.slidingSync(listener = this@RoomListViewModel)
|
||||
client.roomSummaryDataSource().roomSummaries().execute {
|
||||
copy(rooms = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,31 +67,7 @@ class RoomListViewModel(initialState: RoomListViewState) :
|
|||
return matrix.restoreSession()!!
|
||||
}
|
||||
|
||||
override fun onSyncUpdate(
|
||||
summary: UpdateSummary,
|
||||
rooms: List<Room>
|
||||
) = withState { state ->
|
||||
val list = state.rooms().orEmpty().toMutableList()
|
||||
rooms.forEach { room ->
|
||||
// Either replace or add the room
|
||||
val idx = list.indexOfFirst { it.id() == room.id() }
|
||||
if (idx == -1) {
|
||||
list.add(room)
|
||||
} else {
|
||||
list[idx] = room
|
||||
}
|
||||
}
|
||||
|
||||
setState {
|
||||
copy(
|
||||
rooms = Success(list),
|
||||
summary = Success(summary)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
sync?.cancel()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,13 +3,13 @@ package io.element.android.x.features.roomlist
|
|||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import io.element.android.x.matrix.room.RoomSummary
|
||||
import org.matrix.rustcomponents.sdk.Room
|
||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
||||
|
||||
data class RoomListViewState(
|
||||
val user: MatrixUser = MatrixUser(),
|
||||
val rooms: Async<List<Room>> = Uninitialized,
|
||||
val summary: Async<UpdateSummary> = Uninitialized,
|
||||
val rooms: Async<List<RoomSummary>> = Uninitialized,
|
||||
val canLoadMore: Boolean = false,
|
||||
val logoutAction: Async<Unit> = Uninitialized,
|
||||
) : MavericksState
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue