change(room directory) : move the the room directory entry from room list filter to start chat screen.

This commit is contained in:
ganfra 2025-03-03 16:25:15 +01:00
parent 908fc43a91
commit 6af226dc00
24 changed files with 91 additions and 158 deletions

View file

@ -21,15 +21,19 @@ interface CreateRoomNavigator : Plugin {
fun onCreateNewRoom()
fun onShowJoinRoomByAddress()
fun onDismissJoinRoomByAddress()
fun onOpenRoomDirectory()
}
class DefaultCreateRoomNavigator(
private val backstack: BackStack<NavTarget>,
private val overlay: Overlay<NavTarget>,
private val openRoom: (RoomIdOrAlias, List<String>) -> Unit,
private val openRoomDirectory: () -> Unit,
) : CreateRoomNavigator {
override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) = openRoom(roomIdOrAlias, serverNames)
override fun onOpenRoomDirectory() = openRoomDirectory()
override fun onCreateNewRoom() {
backstack.push(NavTarget.NewRoom)
}

View file

@ -60,6 +60,9 @@ class CreateRoomFlowNode @AssistedInject constructor(
overlay = overlay,
openRoom = { roomIdOrAlias, viaServers ->
plugins<CreateRoomEntryPoint.Callback>().forEach { it.onOpenRoom(roomIdOrAlias, viaServers) }
},
openRoomDirectory = {
plugins<CreateRoomEntryPoint.Callback>().forEach { it.onOpenRoomDirectory() }
}
)

View file

@ -55,7 +55,8 @@ class CreateRoomRootNode @AssistedInject constructor(
navigator.onOpenRoom(roomIdOrAlias = it.toRoomIdOrAlias(), serverNames = emptyList())
},
onJoinByAddressClick = navigator::onShowJoinRoomByAddress,
onInviteFriendsClick = { invitePeople(activity) }
onInviteFriendsClick = { invitePeople(activity) },
onRoomDirectorySearchClick = navigator::onOpenRoomDirectory
)
}

View file

@ -9,6 +9,8 @@ package io.element.android.features.createroom.impl.root
import androidx.compose.runtime.Composable
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
@ -20,6 +22,8 @@ import io.element.android.features.createroom.impl.userlist.UserListPresenterArg
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.usersearch.api.UserRepository
import kotlinx.coroutines.launch
@ -31,6 +35,7 @@ class CreateRoomRootPresenter @Inject constructor(
userListDataStore: UserListDataStore,
private val startDMAction: StartDMAction,
private val buildMeta: BuildMeta,
private val featureFlagService: FeatureFlagService,
) : Presenter<CreateRoomRootState> {
private val presenter = presenterFactory.create(
UserListPresenterArgs(
@ -47,6 +52,8 @@ class CreateRoomRootPresenter @Inject constructor(
val localCoroutineScope = rememberCoroutineScope()
val startDmActionState: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val isRoomDirectorySearchEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.RoomDirectorySearch).collectAsState(initial = false)
fun handleEvents(event: CreateRoomRootEvents) {
when (event) {
is CreateRoomRootEvents.StartDM -> localCoroutineScope.launch {
@ -64,6 +71,7 @@ class CreateRoomRootPresenter @Inject constructor(
applicationName = buildMeta.applicationName,
userListState = userListState,
startDmAction = startDmActionState.value,
isRoomDirectorySearchEnabled = isRoomDirectorySearchEnabled,
eventSink = ::handleEvents,
)
}

View file

@ -15,5 +15,6 @@ data class CreateRoomRootState(
val applicationName: String,
val userListState: UserListState,
val startDmAction: AsyncAction<RoomId>,
val isRoomDirectorySearchEnabled: Boolean,
val eventSink: (CreateRoomRootEvents) -> Unit,
)

View file

@ -53,6 +53,9 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider<CreateRoomRoot
aCreateRoomRootState(
startDmAction = ConfirmingStartDmWithMatrixUser(aMatrixUser()),
),
aCreateRoomRootState(
isRoomDirectorySearchEnabled = true,
),
)
}
@ -60,10 +63,12 @@ fun aCreateRoomRootState(
applicationName: String = "Element X Preview",
userListState: UserListState = aUserListState(),
startDmAction: AsyncAction<RoomId> = AsyncAction.Uninitialized,
isRoomDirectorySearchEnabled: Boolean = false,
eventSink: (CreateRoomRootEvents) -> Unit = {},
) = CreateRoomRootState(
applicationName = applicationName,
userListState = userListState,
startDmAction = startDmAction,
isRoomDirectorySearchEnabled = isRoomDirectorySearchEnabled,
eventSink = eventSink,
)

View file

@ -56,6 +56,7 @@ fun CreateRoomRootView(
onOpenDM: (RoomId) -> Unit,
onInviteFriendsClick: () -> Unit,
onJoinByAddressClick: () -> Unit,
onRoomDirectorySearchClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Scaffold(
@ -91,6 +92,7 @@ fun CreateRoomRootView(
onNewRoomClick = onNewRoomClick,
onInvitePeopleClick = onInviteFriendsClick,
onJoinByAddressClick = onJoinByAddressClick,
onRoomDirectorySearchClick = onRoomDirectorySearchClick,
onDmClick = onOpenDM,
)
}
@ -156,6 +158,7 @@ private fun CreateRoomActionButtonsList(
onNewRoomClick: () -> Unit,
onInvitePeopleClick: () -> Unit,
onJoinByAddressClick: () -> Unit,
onRoomDirectorySearchClick: () -> Unit,
onDmClick: (RoomId) -> Unit,
) {
LazyColumn {
@ -166,6 +169,15 @@ private fun CreateRoomActionButtonsList(
onClick = onNewRoomClick,
)
}
if (state.isRoomDirectorySearchEnabled) {
item {
CreateRoomActionButton(
iconRes = CompoundDrawables.ic_compound_list_bulleted,
text = stringResource(id = R.string.screen_room_directory_search_title),
onClick = onRoomDirectorySearchClick,
)
}
}
item {
CreateRoomActionButton(
iconRes = CompoundDrawables.ic_compound_share_android,
@ -242,5 +254,6 @@ internal fun CreateRoomRootViewPreview(@PreviewParameter(CreateRoomRootStateProv
onOpenDM = {},
onJoinByAddressClick = {},
onInviteFriendsClick = {},
onRoomDirectorySearchClick = {},
)
}

View file

@ -19,6 +19,7 @@ You can change this anytime in room settings."</string>
<string name="screen_create_room_room_visibility_section_title">"Room visibility"</string>
<string name="screen_create_room_title">"Create a room"</string>
<string name="screen_create_room_topic_label">"Topic (optional)"</string>
<string name="screen_room_directory_search_title">"Room directory"</string>
<string name="screen_start_chat_error_starting_chat">"An error occurred when trying to start a chat"</string>
<string name="screen_start_chat_join_room_by_address_action">"Join room by address"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Not a valid address"</string>

View file

@ -15,7 +15,8 @@ class FakeCreateRoomNavigator(
private val createNewRoomLambda: () -> Unit = {},
private val showJoinRoomByAddressLambda: () -> Unit = {},
private val dismissJoinRoomByAddressLambda: () -> Unit = {},
) : CreateRoomNavigator {
private val openRoomDirectoryLambda: () -> Unit = {},
) : CreateRoomNavigator {
override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) {
openRoomLambda(roomIdOrAlias, serverNames)
}
@ -31,4 +32,8 @@ class FakeCreateRoomNavigator(
override fun onDismissJoinRoomByAddress() {
dismissJoinRoomByAddressLambda()
}
override fun onOpenRoomDirectory() {
openRoomDirectoryLambda()
}
}

View file

@ -19,6 +19,8 @@ import io.element.android.features.createroom.impl.userlist.FakeUserListPresente
import io.element.android.features.createroom.impl.userlist.UserListDataStore
import io.element.android.features.createroom.test.FakeStartDMAction
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.MatrixUser
@ -163,14 +165,34 @@ class CreateRoomRootPresenterTest {
}
}
@Test
fun `present - room directory search`() = runTest {
val presenter = createCreateRoomRootPresenter(isRoomDirectorySearchEnabled = true)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
awaitItem().let { state ->
assertThat(state.isRoomDirectorySearchEnabled).isTrue()
}
}
}
private fun createCreateRoomRootPresenter(
startDMAction: StartDMAction = FakeStartDMAction(),
isRoomDirectorySearchEnabled: Boolean = false,
): CreateRoomRootPresenter {
val featureFlagService = FakeFeatureFlagService(
initialState = mapOf(
FeatureFlags.RoomDirectorySearch.key to isRoomDirectorySearchEnabled,
),
)
return CreateRoomRootPresenter(
presenterFactory = FakeUserListPresenterFactory(FakeUserListPresenter()),
userRepository = FakeUserRepository(),
userListDataStore = UserListDataStore(),
startDMAction = startDMAction,
featureFlagService = featureFlagService,
buildMeta = aBuildMeta(),
)
}

View file

@ -116,6 +116,21 @@ class CreateRoomRootViewTest {
rule.clickOn(R.string.screen_start_chat_join_room_by_address_action)
}
}
@Test
fun `clicking on room directory invokes the expected callback`() {
val eventsRecorder = EventsRecorder<CreateRoomRootEvents>(expectEvents = false)
ensureCalledOnce {
rule.setCreateRoomRootView(
aCreateRoomRootState(
eventSink = eventsRecorder,
isRoomDirectorySearchEnabled = true
),
onRoomDirectorySearchClick = it
)
rule.clickOn(R.string.screen_room_directory_search_title)
}
}
}
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCreateRoomRootView(
@ -125,6 +140,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCreat
onOpenDM: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
onInviteFriendsClick: () -> Unit = EnsureNeverCalled(),
onJoinRoomByAddressClick: () -> Unit = EnsureNeverCalled(),
onRoomDirectorySearchClick: () -> Unit = EnsureNeverCalled(),
) {
setContent {
CreateRoomRootView(
@ -133,7 +149,8 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCreat
onNewRoomClick = onNewRoomClick,
onOpenDM = onOpenDM,
onInviteFriendsClick = onInviteFriendsClick,
onJoinByAddressClick = onJoinRoomByAddressClick
onJoinByAddressClick = onJoinRoomByAddressClick,
onRoomDirectorySearchClick = onRoomDirectorySearchClick,
)
}
}