From 82e566175a7b2235b59d7ea4f35101491204187c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 21 Jun 2023 14:50:00 +0200 Subject: [PATCH] Room list: tweak UI and add overflow menu with report bug and invite friends action. Extract invite friends action to a use case to avoid copy paste. --- .../android/appnav/LoggedInFlowNode.kt | 4 ++ features/createroom/impl/build.gradle.kts | 1 + .../impl/root/CreateRoomRootNode.kt | 33 +++-------- .../roomlist/api/RoomListEntryPoint.kt | 1 + features/roomlist/impl/build.gradle.kts | 1 + .../features/roomlist/impl/RoomListNode.kt | 20 ++++++- .../features/roomlist/impl/RoomListView.kt | 22 +++++--- .../impl/components/RoomListMenuAction.kt | 22 ++++++++ .../impl/components/RoomListTopBar.kt | 55 ++++++++++++++++++- libraries/deeplink/build.gradle.kts | 4 ++ .../deeplink/usecase/InviteFriendsUseCase.kt | 54 ++++++++++++++++++ .../android/samples/minimal/RoomListScreen.kt | 1 + 12 files changed, 180 insertions(+), 38 deletions(-) create mode 100644 features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListMenuAction.kt create mode 100644 libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 7a4d51f0ee..da223d0ea5 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -222,6 +222,10 @@ class LoggedInFlowNode @AssistedInject constructor( override fun onRoomSettingsClicked(roomId: RoomId) { backstack.push(NavTarget.Room(roomId, initialElement = RoomFlowNode.NavTarget.RoomDetails)) } + + override fun onReportBugClicked() { + plugins().forEach { it.onOpenBugReport() } + } } roomListEntryPoint .nodeBuilder(this, buildContext) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 983be1a14a..8bb343c10a 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.uiStrings) implementation(projects.libraries.androidutils) + implementation(projects.libraries.deeplink) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) implementation(projects.libraries.usersearch.impl) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt index 5a2dde7661..597c5d0d01 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt @@ -16,7 +16,7 @@ package io.element.android.features.createroom.impl.root -import android.content.Context +import android.app.Activity import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -29,24 +29,18 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.anvilannotations.ContributesNode -import io.element.android.libraries.androidutils.system.startSharePlainTextIntent -import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder -import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.api.AnalyticsService -import timber.log.Timber @ContributesNode(SessionScope::class) class CreateRoomRootNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, private val presenter: CreateRoomRootPresenter, - private val matrixClient: MatrixClient, - private val buildMeta: BuildMeta, private val analyticsService: AnalyticsService, + private val inviteFriendsUseCase: InviteFriendsUseCase, ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { @@ -73,31 +67,18 @@ class CreateRoomRootNode @AssistedInject constructor( @Composable override fun View(modifier: Modifier) { val state = presenter.present() - val context = LocalContext.current + val activity = LocalContext.current as Activity CreateRoomRootView( state = state, modifier = modifier, onClosePressed = this::navigateUp, onNewRoomClicked = callback::onCreateNewRoom, onOpenDM = callback::onStartChatSuccess, - onInviteFriendsClicked = { invitePeople(context) }, + onInviteFriendsClicked = { invitePeople(activity) } ) } - private fun invitePeople(context: Context) { - val permalinkResult = PermalinkBuilder.permalinkForUser(matrixClient.sessionId) - permalinkResult.onSuccess { permalink -> - val appName = buildMeta.applicationName - startSharePlainTextIntent( - context = context, - activityResultLauncher = null, - chooserTitle = context.getString(CommonStrings.action_invite_friends), - text = context.getString(CommonStrings.invite_friends_text, appName, permalink), - extraTitle = context.getString(CommonStrings.invite_friends_rich_title, appName), - noActivityFoundMessage = context.getString(io.element.android.libraries.androidutils.R.string.error_no_compatible_app_found) - ) - }.onFailure { - Timber.e(it) - } + private fun invitePeople(activity: Activity) { + inviteFriendsUseCase.execute(activity) } } diff --git a/features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/RoomListEntryPoint.kt b/features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/RoomListEntryPoint.kt index eeefa15c02..7fe01aa64e 100644 --- a/features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/RoomListEntryPoint.kt +++ b/features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/RoomListEntryPoint.kt @@ -37,6 +37,7 @@ interface RoomListEntryPoint : FeatureEntryPoint { fun onSessionVerificationClicked() fun onInvitesClicked() fun onRoomSettingsClicked(roomId: RoomId) + fun onReportBugClicked() } } diff --git a/features/roomlist/impl/build.gradle.kts b/features/roomlist/impl/build.gradle.kts index ff25720aa5..be5ac09484 100644 --- a/features/roomlist/impl/build.gradle.kts +++ b/features/roomlist/impl/build.gradle.kts @@ -48,6 +48,7 @@ dependencies { implementation(projects.libraries.uiStrings) implementation(projects.libraries.dateformatter.api) implementation(projects.libraries.eventformatter.api) + implementation(projects.libraries.deeplink) implementation(projects.features.invitelist.api) implementation(projects.features.networkmonitor.api) implementation(projects.features.leaveroom.api) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListNode.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListNode.kt index 3eb2ab848d..55903fb961 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListNode.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListNode.kt @@ -16,8 +16,10 @@ package io.element.android.features.roomlist.impl +import android.app.Activity import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin @@ -26,6 +28,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode import io.element.android.features.roomlist.api.RoomListEntryPoint +import io.element.android.features.roomlist.impl.components.RoomListMenuAction +import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.RoomId @@ -33,7 +37,8 @@ import io.element.android.libraries.matrix.api.core.RoomId class RoomListNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, - private val presenter: RoomListPresenter, + private val presenter: RoomListPresenter, + private val inviteFriendsUseCase: InviteFriendsUseCase, ) : Node(buildContext, plugins = plugins) { private fun onRoomClicked(roomId: RoomId) { @@ -60,9 +65,21 @@ class RoomListNode @AssistedInject constructor( plugins().forEach { it.onRoomSettingsClicked(roomId) } } + private fun onMenuActionClicked(activity: Activity, roomListMenuAction: RoomListMenuAction) { + when (roomListMenuAction) { + RoomListMenuAction.InviteFriends -> { + inviteFriendsUseCase.execute(activity) + } + RoomListMenuAction.ReportBug -> { + plugins().forEach { it.onReportBugClicked() } + } + } + } + @Composable override fun View(modifier: Modifier) { val state = presenter.present() + val activity = LocalContext.current as Activity RoomListView( state = state, onRoomClicked = this::onRoomClicked, @@ -71,6 +88,7 @@ class RoomListNode @AssistedInject constructor( onVerifyClicked = this::onSessionVerificationClicked, onInvitesClicked = this::onInvitesClicked, onRoomSettingsClicked = this::onRoomSettingsClicked, + onMenuActionClicked = { onMenuActionClicked(activity, it) }, modifier = modifier, ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index 849378518d..9816ede5e0 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -63,6 +63,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.features.leaveroom.api.LeaveRoomView import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView +import io.element.android.features.roomlist.impl.components.RoomListMenuAction import io.element.android.features.roomlist.impl.components.RoomListTopBar import io.element.android.features.roomlist.impl.components.RoomSummaryRow import io.element.android.features.roomlist.impl.model.RoomListRoomSummary @@ -95,6 +96,7 @@ fun RoomListView( onCreateRoomClicked: () -> Unit, onInvitesClicked: () -> Unit, onRoomSettingsClicked: (roomId: RoomId) -> Unit, + onMenuActionClicked: (RoomListMenuAction) -> Unit, modifier: Modifier = Modifier, ) { Column(modifier = modifier) { @@ -118,12 +120,13 @@ fun RoomListView( RoomListContent( state = state, + onVerifyClicked = onVerifyClicked, onRoomClicked = onRoomClicked, onRoomLongClicked = { onRoomLongClicked(it) }, onOpenSettings = onSettingsClicked, - onVerifyClicked = onVerifyClicked, onCreateRoomClicked = onCreateRoomClicked, onInvitesClicked = onInvitesClicked, + onMenuActionClicked = onMenuActionClicked, ) // This overlaid view will only be visible when state.displaySearchResults is true RoomListSearchResultView( @@ -143,12 +146,13 @@ fun RoomListView( fun RoomListContent( state: RoomListState, modifier: Modifier = Modifier, - onVerifyClicked: () -> Unit = {}, - onRoomClicked: (RoomId) -> Unit = {}, - onRoomLongClicked: (RoomListRoomSummary) -> Unit = {}, - onOpenSettings: () -> Unit = {}, - onCreateRoomClicked: () -> Unit = {}, - onInvitesClicked: () -> Unit = {}, + onVerifyClicked: () -> Unit, + onRoomClicked: (RoomId) -> Unit, + onRoomLongClicked: (RoomListRoomSummary) -> Unit, + onOpenSettings: () -> Unit, + onCreateRoomClicked: () -> Unit, + onInvitesClicked: () -> Unit, + onMenuActionClicked: (RoomListMenuAction) -> Unit, ) { fun onRoomClicked(room: RoomListRoomSummary) { onRoomClicked(room.roomId) @@ -190,6 +194,7 @@ fun RoomListContent( areSearchResultsDisplayed = state.displaySearchResults, onFilterChanged = { state.eventSink(RoomListEvents.UpdateFilter(it)) }, onToggleSearch = { state.eventSink(RoomListEvents.ToggleSearchResults) }, + onMenuActionClicked = onMenuActionClicked, onOpenSettings = onOpenSettings, scrollBehavior = scrollBehavior, ) @@ -369,7 +374,8 @@ private fun ContentToPreview(state: RoomListState) { onVerifyClicked = {}, onCreateRoomClicked = {}, onInvitesClicked = {}, - onRoomSettingsClicked = {} + onRoomSettingsClicked = {}, + onMenuActionClicked = {}, ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListMenuAction.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListMenuAction.kt new file mode 100644 index 0000000000..9e598d8824 --- /dev/null +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListMenuAction.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.roomlist.impl.components + +enum class RoomListMenuAction { + InviteFriends, + ReportBug +} diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index 10b02084b9..5cfc0f782d 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -19,23 +19,33 @@ package io.element.android.features.roomlist.impl.components import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.WindowInsets import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.BugReport +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Search +import androidx.compose.material.icons.filled.Share +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import io.element.android.features.roomlist.impl.R import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.Icon @@ -57,6 +67,7 @@ fun RoomListTopBar( areSearchResultsDisplayed: Boolean, onFilterChanged: (String) -> Unit, onToggleSearch: () -> Unit, + onMenuActionClicked: (RoomListMenuAction) -> Unit, onOpenSettings: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, modifier: Modifier = Modifier, @@ -79,6 +90,7 @@ fun RoomListTopBar( matrixUser = matrixUser, onOpenSettings = onOpenSettings, onSearchClicked = onToggleSearch, + onMenuActionClicked = onMenuActionClicked, scrollBehavior = scrollBehavior, modifier = modifier, ) @@ -90,15 +102,19 @@ private fun DefaultRoomListTopBar( matrixUser: MatrixUser?, scrollBehavior: TopAppBarScrollBehavior, modifier: Modifier = Modifier, - onOpenSettings: () -> Unit = {}, - onSearchClicked: () -> Unit = {}, + onOpenSettings: () -> Unit, + onSearchClicked: () -> Unit, + onMenuActionClicked: (RoomListMenuAction) -> Unit, ) { + var showMenu by remember { mutableStateOf(false) } MediumTopAppBar( modifier = modifier .nestedScroll(scrollBehavior.nestedScrollConnection), title = { + val fontSize = if (scrollBehavior.state.collapsedFraction > 0.5) 20.sp else 22.sp Text( fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.headlineMedium.copy(fontSize = fontSize), text = stringResource(id = R.string.screen_roomlist_main_space_title) ) }, @@ -108,7 +124,11 @@ private fun DefaultRoomListTopBar( modifier = Modifier.testTag(TestTags.homeScreenSettings), onClick = onOpenSettings ) { - val avatarData by remember { derivedStateOf { matrixUser.getAvatarData() } } + val avatarData by remember { + derivedStateOf { + matrixUser.getAvatarData(size = AvatarSize.Custom(28.dp)) + } + } Avatar(avatarData, contentDescription = stringResource(CommonStrings.common_settings)) } } @@ -119,6 +139,32 @@ private fun DefaultRoomListTopBar( ) { Icon(Icons.Default.Search, contentDescription = stringResource(CommonStrings.action_search)) } + IconButton( + onClick = { showMenu = !showMenu } + ) { + Icon(Icons.Default.MoreVert, contentDescription = null) + } + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClicked(RoomListMenuAction.InviteFriends) + }, + text = { Text(stringResource(id = CommonStrings.action_invite)) }, + leadingIcon = { Icon(Icons.Default.Share, contentDescription = null) } + ) + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClicked(RoomListMenuAction.ReportBug) + }, + text = { Text(stringResource(id = CommonStrings.common_report_a_bug)) }, + leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) } + ) + } }, scrollBehavior = scrollBehavior, windowInsets = WindowInsets(0.dp), @@ -139,5 +185,8 @@ private fun DefaultRoomListTopBarPreview() { DefaultRoomListTopBar( matrixUser = MatrixUser(UserId("@id:domain"), "Alice"), scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()), + onOpenSettings = {}, + onSearchClicked = {}, + onMenuActionClicked = {}, ) } diff --git a/libraries/deeplink/build.gradle.kts b/libraries/deeplink/build.gradle.kts index 08ec84c227..2ee61eb509 100644 --- a/libraries/deeplink/build.gradle.kts +++ b/libraries/deeplink/build.gradle.kts @@ -30,8 +30,12 @@ dependencies { implementation(projects.libraries.di) implementation(libs.dagger) implementation(libs.androidx.corektx) + implementation(projects.libraries.core) implementation(projects.libraries.matrix.api) + implementation(projects.libraries.androidutils) implementation(projects.libraries.architecture) + implementation(projects.libraries.uiStrings) + implementation(projects.services.toolbox.api) testImplementation(libs.test.junit) testImplementation(libs.test.truth) diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt new file mode 100644 index 0000000000..67f7330a0c --- /dev/null +++ b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/usecase/InviteFriendsUseCase.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.deeplink.usecase + +import android.app.Activity +import io.element.android.libraries.androidutils.system.startSharePlainTextIntent +import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder +import io.element.android.services.toolbox.api.strings.StringProvider +import timber.log.Timber +import javax.inject.Inject +import io.element.android.libraries.androidutils.R as AndroidUtilsR +import io.element.android.libraries.ui.strings.CommonStrings + +class InviteFriendsUseCase @Inject constructor( + private val stringProvider: StringProvider, + private val matrixClient: MatrixClient, + private val buildMeta: BuildMeta, +) { + fun execute(activity: Activity) { + val permalinkResult = PermalinkBuilder.permalinkForUser(matrixClient.sessionId) + permalinkResult.fold( + onSuccess = { permalink -> + val appName = buildMeta.applicationName + startSharePlainTextIntent( + context = activity, + activityResultLauncher = null, + chooserTitle = stringProvider.getString(CommonStrings.action_invite_friends), + text = stringProvider.getString(CommonStrings.invite_friends_text, appName, permalink), + extraTitle = stringProvider.getString(CommonStrings.invite_friends_rich_title, appName), + noActivityFoundMessage = stringProvider.getString(AndroidUtilsR.string.error_no_compatible_app_found) + ) + }, + onFailure = { + Timber.e(it) + } + ) + } +} diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt index 5d8e0bfd1c..cd70a8a49b 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt @@ -103,6 +103,7 @@ class RoomListScreen( onCreateRoomClicked = {}, onInvitesClicked = {}, onRoomSettingsClicked = {}, + onMenuActionClicked = {}, modifier = modifier, )