Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It's not possible to join room from the RoomDirectory screen anymore. #2839

Merged
merged 2 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,7 +30,6 @@ interface RoomDirectoryEntryPoint : FeatureEntryPoint {
}

interface Callback : Plugin {
fun onRoomJoined(roomId: RoomId)
fun onResultClicked(roomDescription: RoomDescription)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,27 @@ 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
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
Expand All @@ -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
Expand All @@ -87,31 +76,17 @@ class RoomDirectoryPresenter @Inject constructor(
is RoomDirectoryEvents.Search -> {
searchQuery = event.query
}
is RoomDirectoryEvents.JoinRoom -> {
coroutineScope.joinRoom(joinRoomAction, event.roomId)
}
RoomDirectoryEvents.JoinRoomDismissError -> {
joinRoomAction.value = AsyncAction.Uninitialized
}
}
}

return RoomDirectoryState(
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -37,30 +36,18 @@ 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")),
),
)
}

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,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -70,7 +68,6 @@ import kotlinx.collections.immutable.ImmutableList
fun RoomDirectoryView(
state: RoomDirectoryState,
onResultClicked: (RoomDescription) -> Unit,
onRoomJoined: (RoomId) -> Unit,
onBackPressed: () -> Unit,
modifier: Modifier = Modifier,
) {
Expand All @@ -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)
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -259,23 +246,23 @@ 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),
modifier = Modifier.align(Alignment.CenterVertically)
)
Column(
modifier = Modifier
.weight(1f)
.padding(horizontal = 16.dp)
.weight(1f)
.padding(horizontal = 16.dp)
) {
Text(
text = roomDescription.computedName,
Expand All @@ -301,7 +288,6 @@ internal fun RoomDirectoryViewPreview(@PreviewParameter(RoomDirectoryStateProvid
RoomDirectoryView(
state = state,
onResultClicked = {},
onRoomJoined = {},
onBackPressed = {},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
}
Expand Down Expand Up @@ -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,
)
}
Expand Down
Loading
Loading