Refactor some modules + add dependency management (still WIP)

This commit is contained in:
ganfra 2022-10-27 19:24:57 +02:00
parent d1c80438d5
commit 6f0d8936eb
89 changed files with 854 additions and 580 deletions

View file

@ -0,0 +1,24 @@
package io.element.android.x.features.roomlist
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("io.element.android.x.features.roomlist.test", appContext.packageName)
}
}

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View file

@ -0,0 +1,6 @@
package io.element.android.x.features.roomlist
data class MatrixUser(
val username: String? = null,
val avatarUrl: String? = null,
)

View file

@ -0,0 +1,6 @@
package io.element.android.x.features.roomlist
sealed interface RoomListActions {
object LoadMore : RoomListActions
object Logout : RoomListActions
}

View file

@ -0,0 +1,70 @@
package io.element.android.x.features.roomlist
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import org.matrix.rustcomponents.sdk.Room
@Composable
fun RoomListScreen(
viewModel: RoomListViewModel = mavericksViewModel(),
onRoomClicked: (String) -> Unit = { }
) {
val state by viewModel.collectAsState()
RoomListContent(state, onRoomClicked)
}
@Composable
fun RoomListContent(
state: RoomListViewState,
onRoomClicked: (String) -> Unit
) {
Surface(color = MaterialTheme.colorScheme.background) {
Column(
modifier = Modifier.fillMaxSize()
) {
val rooms = state.rooms
if (rooms is Success) {
LazyColumn {
items(rooms()) { room ->
RoomItem(room = room) {
onRoomClicked(it)
}
}
}
}
}
}
}
@Composable
private fun RoomItem(
modifier: Modifier = Modifier,
room: Room,
onClick: (String) -> Unit
) {
Row(verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.clickable {
onClick(room.id())
}
.fillMaxWidth()
) {
Column(modifier = modifier.padding(8.dp)) {
Text(text = "Room: ${room.name() ?: room.id()}")
Text(text = if (room.isDirect()) "Direct" else "Room")
}
}
}

View file

@ -0,0 +1,90 @@
package io.element.android.x.features.roomlist
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.sdk.matrix.MatrixClient
import io.element.android.x.sdk.matrix.MatrixInstance
import kotlinx.coroutines.launch
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.StoppableSpawn
import org.matrix.rustcomponents.sdk.UpdateSummary
class RoomListViewModel(initialState: RoomListViewState) :
MavericksViewModel<RoomListViewState>(initialState), MatrixClient.SlidingSyncListener {
private var sync: StoppableSpawn? = null
private val matrix = MatrixInstance.getInstance()
init {
handleInit()
}
fun handle(action: RoomListActions) {
when (action) {
RoomListActions.LoadMore -> TODO()
RoomListActions.Logout -> handleLogout()
}
}
private fun handleInit() {
viewModelScope.launch {
val client = getClient()
setState {
copy(
user = MatrixUser(
tryOrNull { client.username() } ?: "Room list",
tryOrNull { client.avatarUrl() } ?: "https://previews.123rf.com/images/lkeskinen/lkeskinen1802/lkeskinen180208322/95731150-exemple-de-tampon-%C3%A9tiquette-typographique-timbre-ou-ic%C3%B4ne.jpg",
)
)
}
sync = client.slidingSync(listener = this@RoomListViewModel)
}
}
private fun handleLogout() {
viewModelScope.launch {
setState { copy(logoutAction = Loading()) }
try {
getClient().logout()
setState { copy(logoutAction = Success(Unit)) }
} catch (throwable: Throwable) {
setState { copy(logoutAction = Fail(throwable)) }
}
}
}
private suspend fun getClient(): MatrixClient {
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()
}
}

View file

@ -0,0 +1,15 @@
package io.element.android.x.features.roomlist
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized
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 canLoadMore: Boolean = false,
val logoutAction: Async<Unit> = Uninitialized,
) : MavericksState

View file

@ -0,0 +1,17 @@
package io.element.android.x.features.roomlist
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}