Refactor some modules + add dependency management (still WIP)
This commit is contained in:
parent
d1c80438d5
commit
6f0d8936eb
89 changed files with 854 additions and 580 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
4
features/roomlist/src/main/AndroidManifest.xml
Normal file
4
features/roomlist/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package io.element.android.x.features.roomlist
|
||||
|
||||
data class MatrixUser(
|
||||
val username: String? = null,
|
||||
val avatarUrl: String? = null,
|
||||
)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package io.element.android.x.features.roomlist
|
||||
|
||||
sealed interface RoomListActions {
|
||||
object LoadMore : RoomListActions
|
||||
object Logout : RoomListActions
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue