Merge pull request #2839 from element-hq/feature/bma/removeDeadCode

It's not possible to join room from the RoomDirectory screen anymore.
This commit is contained in:
Benoit Marty
2024-05-14 11:14:25 +02:00
committed by GitHub
14 changed files with 16 additions and 161 deletions

View File

@@ -370,10 +370,6 @@ class LoggedInFlowNode @AssistedInject constructor(
NavTarget.RoomDirectorySearch -> {
roomDirectoryEntryPoint.nodeBuilder(this, buildContext)
.callback(object : RoomDirectoryEntryPoint.Callback {
override fun onRoomJoined(roomId: RoomId) {
backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias()))
}
override fun onResultClicked(roomDescription: RoomDescription) {
backstack.push(NavTarget.Room(roomDescription.roomId.toRoomIdOrAlias(), roomDescription))
}

View File

@@ -20,7 +20,6 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.RoomId
interface RoomDirectoryEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
@@ -31,7 +30,6 @@ interface RoomDirectoryEntryPoint : FeatureEntryPoint {
}
interface Callback : Plugin {
fun onRoomJoined(roomId: RoomId)
fun onResultClicked(roomDescription: RoomDescription)
}
}

View File

@@ -16,11 +16,7 @@
package io.element.android.features.roomdirectory.impl.root
import io.element.android.libraries.matrix.api.core.RoomId
sealed interface RoomDirectoryEvents {
data class JoinRoom(val roomId: RoomId) : RoomDirectoryEvents
data class Search(val query: String) : RoomDirectoryEvents
data object LoadMore : RoomDirectoryEvents
data object JoinRoomDismissError : RoomDirectoryEvents
}

View File

@@ -28,7 +28,6 @@ import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId
@ContributesNode(SessionScope::class)
class RoomDirectoryNode @AssistedInject constructor(
@@ -42,18 +41,11 @@ class RoomDirectoryNode @AssistedInject constructor(
}
}
private fun onRoomJoined(roomId: RoomId) {
plugins<RoomDirectoryEntryPoint.Callback>().forEach {
it.onRoomJoined(roomId)
}
}
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
RoomDirectoryView(
state = state,
onRoomJoined = ::onRoomJoined,
onResultClicked = ::onResultClicked,
onBackPressed = ::navigateUp,
modifier = modifier

View File

@@ -18,7 +18,6 @@ package io.element.android.features.roomdirectory.impl.root
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -26,27 +25,20 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import io.element.android.features.roomdirectory.impl.root.di.JoinRoom
import io.element.android.features.roomdirectory.impl.root.model.RoomDirectoryListState
import io.element.android.features.roomdirectory.impl.root.model.toFeatureModel
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryList
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import javax.inject.Inject
class RoomDirectoryPresenter @Inject constructor(
private val dispatchers: CoroutineDispatchers,
private val joinRoom: JoinRoom,
private val roomDirectoryService: RoomDirectoryService,
) : Presenter<RoomDirectoryState> {
@Composable
@@ -62,9 +54,6 @@ class RoomDirectoryPresenter @Inject constructor(
roomDirectoryService.createRoomDirectoryList(coroutineScope)
}
val listState by roomDirectoryList.collectState()
val joinRoomAction: MutableState<AsyncAction<RoomId>> = remember {
mutableStateOf(AsyncAction.Uninitialized)
}
LaunchedEffect(searchQuery) {
if (searchQuery == null) return@LaunchedEffect
// cancel load more right away
@@ -87,12 +76,6 @@ class RoomDirectoryPresenter @Inject constructor(
is RoomDirectoryEvents.Search -> {
searchQuery = event.query
}
is RoomDirectoryEvents.JoinRoom -> {
coroutineScope.joinRoom(joinRoomAction, event.roomId)
}
RoomDirectoryEvents.JoinRoomDismissError -> {
joinRoomAction.value = AsyncAction.Uninitialized
}
}
}
@@ -100,18 +83,10 @@ class RoomDirectoryPresenter @Inject constructor(
query = searchQuery.orEmpty(),
roomDescriptions = listState.items,
displayLoadMoreIndicator = listState.hasMoreToLoad,
joinRoomAction = joinRoomAction.value,
eventSink = ::handleEvents
)
}
private fun CoroutineScope.joinRoom(state: MutableState<AsyncAction<RoomId>>, roomId: RoomId) = launch {
state.runUpdatingState {
joinRoom(roomId)
.map { roomId }
}
}
@Composable
private fun RoomDirectoryList.collectState() = remember {
state.map {

View File

@@ -17,15 +17,12 @@
package io.element.android.features.roomdirectory.impl.root
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
data class RoomDirectoryState(
val query: String,
val roomDescriptions: ImmutableList<RoomDescription>,
val displayLoadMoreIndicator: Boolean,
val joinRoomAction: AsyncAction<RoomId>,
val eventSink: (RoomDirectoryEvents) -> Unit
) {
val displayEmptyState = roomDescriptions.isEmpty() && !displayLoadMoreIndicator

View File

@@ -18,7 +18,6 @@ package io.element.android.features.roomdirectory.impl.root
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
@@ -37,16 +36,6 @@ open class RoomDirectoryStateProvider : PreviewParameterProvider<RoomDirectorySt
roomDescriptions = aRoomDescriptionList(),
displayLoadMoreIndicator = true,
),
aRoomDirectoryState(
query = "Element",
roomDescriptions = aRoomDescriptionList(),
joinRoomAction = AsyncAction.Loading,
),
aRoomDirectoryState(
query = "Element",
roomDescriptions = aRoomDescriptionList(),
joinRoomAction = AsyncAction.Failure(Exception("Failed to join room")),
),
)
}
@@ -54,13 +43,11 @@ fun aRoomDirectoryState(
query: String = "",
displayLoadMoreIndicator: Boolean = false,
roomDescriptions: ImmutableList<RoomDescription> = persistentListOf(),
joinRoomAction: AsyncAction<RoomId> = AsyncAction.Uninitialized,
eventSink: (RoomDirectoryEvents) -> Unit = {},
) = RoomDirectoryState(
query = query,
roomDescriptions = roomDescriptions,
displayLoadMoreIndicator = displayLoadMoreIndicator,
joinRoomAction = joinRoomAction,
eventSink = eventSink,
)

View File

@@ -47,7 +47,6 @@ import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.features.roomdirectory.impl.R
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
@@ -61,7 +60,6 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextField
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList
@@ -70,7 +68,6 @@ import kotlinx.collections.immutable.ImmutableList
fun RoomDirectoryView(
state: RoomDirectoryState,
onResultClicked: (RoomDescription) -> Unit,
onRoomJoined: (RoomId) -> Unit,
onBackPressed: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -84,21 +81,11 @@ fun RoomDirectoryView(
state = state,
onResultClicked = onResultClicked,
modifier = Modifier
.padding(padding)
.consumeWindowInsets(padding)
.padding(padding)
.consumeWindowInsets(padding)
)
}
)
AsyncActionView(
async = state.joinRoomAction,
onSuccess = onRoomJoined,
onErrorDismiss = {
state.eventSink(RoomDirectoryEvents.JoinRoomDismissError)
},
errorMessage = {
stringResource(id = CommonStrings.error_unknown)
}
)
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -186,10 +173,10 @@ private fun RoomDirectoryRoomList(
@Composable
private fun LoadMoreIndicator(modifier: Modifier = Modifier) {
Box(
modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(24.dp),
modifier = modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(24.dp),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator(
@@ -259,14 +246,14 @@ private fun RoomDirectoryRoomRow(
) {
Row(
modifier = modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(
top = 12.dp,
bottom = 12.dp,
start = 16.dp,
)
.height(IntrinsicSize.Min),
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(
top = 12.dp,
bottom = 12.dp,
start = 16.dp,
)
.height(IntrinsicSize.Min),
) {
Avatar(
avatarData = roomDescription.avatarData(AvatarSize.RoomDirectoryItem),
@@ -274,8 +261,8 @@ private fun RoomDirectoryRoomRow(
)
Column(
modifier = Modifier
.weight(1f)
.padding(horizontal = 16.dp)
.weight(1f)
.padding(horizontal = 16.dp)
) {
Text(
text = roomDescription.computedName,
@@ -301,7 +288,6 @@ internal fun RoomDirectoryViewPreview(@PreviewParameter(RoomDirectoryStateProvid
RoomDirectoryView(
state = state,
onResultClicked = {},
onRoomJoined = {},
onBackPressed = {},
)
}

View File

@@ -17,12 +17,8 @@
package io.element.android.features.roomdirectory.impl.root
import com.google.common.truth.Truth.assertThat
import io.element.android.features.roomdirectory.impl.root.di.JoinRoom
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryList
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.roomdirectory.FakeRoomDirectoryList
import io.element.android.libraries.matrix.test.roomdirectory.FakeRoomDirectoryService
import io.element.android.libraries.matrix.test.roomdirectory.aRoomDescription
@@ -47,7 +43,6 @@ import org.junit.Test
val initialState = awaitItem()
assertThat(initialState.query).isEmpty()
assertThat(initialState.displayEmptyState).isFalse()
assertThat(initialState.joinRoomAction).isEqualTo(AsyncAction.Uninitialized)
assertThat(initialState.roomDescriptions).isEmpty()
assertThat(initialState.displayLoadMoreIndicator).isTrue()
}
@@ -136,46 +131,13 @@ import org.junit.Test
.withNoParameter()
}
@Test
fun `present - emit join room event`() = runTest {
val joinRoomSuccess = lambdaRecorder { _: RoomId ->
Result.success(Unit)
}
val joinRoomFailure = lambdaRecorder { roomId: RoomId ->
Result.failure<Unit>(RuntimeException("Failed to join room $roomId"))
}
val fakeJoinRoom = FakeJoinRoom(joinRoomSuccess)
val presenter = createRoomDirectoryPresenter(joinRoom = fakeJoinRoom)
presenter.test {
awaitItem().also { state ->
state.eventSink(RoomDirectoryEvents.JoinRoom(A_ROOM_ID))
}
awaitItem().also { state ->
assertThat(state.joinRoomAction).isEqualTo(AsyncAction.Success(A_ROOM_ID))
fakeJoinRoom.lambda = joinRoomFailure
state.eventSink(RoomDirectoryEvents.JoinRoom(A_ROOM_ID))
}
awaitItem().also { state ->
assertThat(state.joinRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
}
}
assert(joinRoomSuccess)
.isCalledOnce()
.with(value(A_ROOM_ID))
assert(joinRoomFailure)
.isCalledOnce()
.with(value(A_ROOM_ID))
}
private fun TestScope.createRoomDirectoryPresenter(
roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(
createRoomDirectoryListFactory = { FakeRoomDirectoryList() }
),
joinRoom: JoinRoom = FakeJoinRoom { Result.success(Unit) },
): RoomDirectoryPresenter {
return RoomDirectoryPresenter(
dispatchers = testCoroutineDispatchers(),
joinRoom = joinRoom,
roomDirectoryService = roomDirectoryService,
)
}

View File

@@ -25,8 +25,6 @@ import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextInput
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.testtags.TestTags
import io.element.android.tests.testutils.EnsureNeverCalled
import io.element.android.tests.testutils.EnsureNeverCalledWithParam
@@ -82,37 +80,17 @@ class RoomDirectoryViewTest {
rule.setRoomDirectoryView(state = state)
eventsRecorder.assertSingle(RoomDirectoryEvents.LoadMore)
}
@Test
fun `when joining room with success then onRoomJoined lambda is called once`() {
val eventsRecorder = EventsRecorder<RoomDirectoryEvents>(expectEvents = false)
val roomDescriptions = aRoomDescriptionList()
val joinedRoomId = roomDescriptions.first().roomId
val state = aRoomDirectoryState(
joinRoomAction = AsyncAction.Success(joinedRoomId),
roomDescriptions = roomDescriptions,
eventSink = eventsRecorder,
)
ensureCalledOnceWithParam(joinedRoomId) { callback ->
rule.setRoomDirectoryView(
state = state,
onRoomJoined = callback,
)
}
}
}
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomDirectoryView(
state: RoomDirectoryState,
onBackPressed: () -> Unit = EnsureNeverCalled(),
onResultClicked: (RoomDescription) -> Unit = EnsureNeverCalledWithParam(),
onRoomJoined: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
) {
setContent {
RoomDirectoryView(
state = state,
onResultClicked = onResultClicked,
onRoomJoined = onRoomJoined,
onBackPressed = onBackPressed,
)
}