From c102c5b436a00a9f398e9dd2b621647d5397ee74 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 15 Apr 2024 22:04:23 +0200 Subject: [PATCH] RoomList: branch accept/decline invite actions --- .../features/roomlist/impl/RoomListEvents.kt | 2 ++ .../features/roomlist/impl/RoomListNode.kt | 11 ++++++- .../roomlist/impl/RoomListPresenter.kt | 23 +++++++++++++ .../features/roomlist/impl/RoomListState.kt | 2 ++ .../roomlist/impl/RoomListStateProvider.kt | 4 +++ .../features/roomlist/impl/RoomListView.kt | 14 +++----- .../impl/components/RoomListContentView.kt | 8 +---- .../impl/components/RoomSummaryRow.kt | 32 +++++++++++++------ .../impl/search/RoomListSearchView.kt | 11 ++++--- 9 files changed, 75 insertions(+), 32 deletions(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt index cad5dd3311..aa1e8e2832 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListEvents.kt @@ -24,6 +24,8 @@ sealed interface RoomListEvents { data object DismissRequestVerificationPrompt : RoomListEvents data object DismissRecoveryKeyPrompt : RoomListEvents data object ToggleSearchResults : RoomListEvents + data class AcceptInvite(val roomListRoomSummary: RoomListRoomSummary) : RoomListEvents + data class DeclineInvite(val roomListRoomSummary: RoomListRoomSummary) : RoomListEvents data class ShowContextMenu(val roomListRoomSummary: RoomListRoomSummary) : RoomListEvents sealed interface ContextMenuEvents : RoomListEvents 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 e9af66d331..c2051ceff3 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 @@ -29,6 +29,7 @@ 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.features.invite.api.response.AcceptDeclineInviteView 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 @@ -43,6 +44,7 @@ class RoomListNode @AssistedInject constructor( private val presenter: RoomListPresenter, private val inviteFriendsUseCase: InviteFriendsUseCase, private val analyticsService: AnalyticsService, + private val acceptDeclineInviteView: AcceptDeclineInviteView, ) : Node(buildContext, plugins = plugins) { init { lifecycle.subscribe( @@ -106,6 +108,13 @@ class RoomListNode @AssistedInject constructor( onMenuActionClicked = { onMenuActionClicked(activity, it) }, onRoomDirectorySearchClicked = this::onRoomDirectorySearchClicked, modifier = modifier, - ) + ) { + acceptDeclineInviteView.Render( + state = state.acceptDeclineInviteState, + onInviteAccepted = this::onRoomClicked, + onInviteDeclined = { }, + modifier = Modifier + ) + } } } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt index 98d8d0ae0e..ce6097b512 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt @@ -32,6 +32,9 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import im.vector.app.features.analytics.plan.Interaction +import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents +import io.element.android.features.invite.api.response.AcceptDeclineInviteState +import io.element.android.features.invite.api.response.InviteData import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomPresenter import io.element.android.features.networkmonitor.api.NetworkMonitor @@ -41,6 +44,7 @@ import io.element.android.features.roomlist.impl.datasource.InviteStateDataSourc import io.element.android.features.roomlist.impl.datasource.RoomListDataSource import io.element.android.features.roomlist.impl.filters.RoomListFiltersState import io.element.android.features.roomlist.impl.migration.MigrationScreenState +import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.search.RoomListSearchEvents import io.element.android.features.roomlist.impl.search.RoomListSearchState import io.element.android.libraries.architecture.AsyncData @@ -89,6 +93,7 @@ class RoomListPresenter @Inject constructor( private val migrationScreenPresenter: Presenter, private val sessionPreferencesStore: SessionPreferencesStore, private val analyticsService: AnalyticsService, + private val acceptDeclineInvitePresenter: Presenter, ) : Presenter { private val encryptionService: EncryptionService = client.encryptionService() private val syncService: SyncService = client.syncService() @@ -101,6 +106,7 @@ class RoomListPresenter @Inject constructor( val networkConnectionStatus by networkMonitor.connectivity.collectAsState() val filtersState = filtersPresenter.present() val searchState = searchPresenter.present() + val acceptDeclineInviteState = acceptDeclineInvitePresenter.present() LaunchedEffect(Unit) { roomListDataSource.launchIn(this) @@ -131,6 +137,16 @@ class RoomListPresenter @Inject constructor( is RoomListEvents.SetRoomIsFavorite -> coroutineScope.setRoomIsFavorite(event.roomId, event.isFavorite) is RoomListEvents.MarkAsRead -> coroutineScope.markAsRead(event.roomId) is RoomListEvents.MarkAsUnread -> coroutineScope.markAsUnread(event.roomId) + is RoomListEvents.AcceptInvite -> { + acceptDeclineInviteState.eventSink( + AcceptDeclineInviteEvents.AcceptInvite(event.roomListRoomSummary.toInviteData()) + ) + } + is RoomListEvents.DeclineInvite -> { + acceptDeclineInviteState.eventSink( + AcceptDeclineInviteEvents.DeclineInvite(event.roomListRoomSummary.toInviteData()) + ) + } } } @@ -148,6 +164,7 @@ class RoomListPresenter @Inject constructor( filtersState = filtersState, searchState = searchState, contentState = contentState, + acceptDeclineInviteState = acceptDeclineInviteState, eventSink = ::handleEvents, ) } @@ -282,4 +299,10 @@ class RoomListPresenter @Inject constructor( val extendedRange = IntRange(extendedRangeStart, extendedRangeEnd) client.roomListService.updateAllRoomsVisibleRange(extendedRange) } + + private fun RoomListRoomSummary.toInviteData() = InviteData( + roomId = roomId, + roomName = name, + isDirect = isDirect, + ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt index 62f59b4eaa..0305f43bfc 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt @@ -17,6 +17,7 @@ package io.element.android.features.roomlist.impl import androidx.compose.runtime.Immutable +import io.element.android.features.invite.api.response.AcceptDeclineInviteState import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.roomlist.impl.filters.RoomListFiltersState import io.element.android.features.roomlist.impl.model.RoomListRoomSummary @@ -37,6 +38,7 @@ data class RoomListState( val filtersState: RoomListFiltersState, val searchState: RoomListSearchState, val contentState: RoomListContentState, + val acceptDeclineInviteState: AcceptDeclineInviteState, val eventSink: (RoomListEvents) -> Unit, ) { val displayFilters = filtersState.isFeatureEnabled && contentState is RoomListContentState.Rooms diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt index 8085ed9e58..372a14f7a7 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt @@ -17,6 +17,8 @@ package io.element.android.features.roomlist.impl import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.invite.api.response.AcceptDeclineInviteState +import io.element.android.features.invite.api.response.anAcceptDeclineInviteState import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.leaveroom.api.aLeaveRoomState import io.element.android.features.roomlist.impl.filters.RoomListFiltersState @@ -65,6 +67,7 @@ internal fun aRoomListState( searchState: RoomListSearchState = aRoomListSearchState(), filtersState: RoomListFiltersState = aRoomListFiltersState(isFeatureEnabled = false), contentState: RoomListContentState = aRoomsContentState(), + acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(), eventSink: (RoomListEvents) -> Unit = {} ) = RoomListState( matrixUser = matrixUser, @@ -76,6 +79,7 @@ internal fun aRoomListState( filtersState = filtersState, searchState = searchState, contentState = contentState, + acceptDeclineInviteState = acceptDeclineInviteState, eventSink = eventSink, ) 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 1dee95cbc2..212894f521 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 @@ -32,6 +32,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.invite.api.response.AcceptDeclineInviteView import io.element.android.features.leaveroom.api.LeaveRoomView import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer import io.element.android.features.roomlist.impl.components.RoomListContentView @@ -60,17 +61,13 @@ fun RoomListView( onMenuActionClicked: (RoomListMenuAction) -> Unit, onRoomDirectorySearchClicked: () -> Unit, modifier: Modifier = Modifier, + acceptDeclineInviteView: @Composable ()->Unit, ) { ConnectivityIndicatorContainer( modifier = modifier, isOnline = state.hasNetworkConnection, ) { topPadding -> Box { - fun onRoomLongClicked( - roomListRoomSummary: RoomListRoomSummary - ) { - state.eventSink(RoomListEvents.ShowContextMenu(roomListRoomSummary)) - } if (state.contextMenu is RoomListState.ContextMenu.Shown) { RoomListContextMenu( @@ -87,7 +84,6 @@ fun RoomListView( state = state, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = onRoomClicked, - onRoomLongClicked = { onRoomLongClicked(it) }, onOpenSettings = onSettingsClicked, onCreateRoomClicked = onCreateRoomClicked, onInvitesClicked = onInvitesClicked, @@ -96,8 +92,8 @@ fun RoomListView( // This overlaid view will only be visible when state.displaySearchResults is true RoomListSearchView( state = state.searchState, + eventSink = state.eventSink, onRoomClicked = onRoomClicked, - onRoomLongClicked = { onRoomLongClicked(it) }, onRoomDirectorySearchClicked = onRoomDirectorySearchClicked, modifier = Modifier .statusBarsPadding() @@ -105,6 +101,7 @@ fun RoomListView( .fillMaxSize() .background(MaterialTheme.colorScheme.background) ) + acceptDeclineInviteView() } } } @@ -115,7 +112,6 @@ private fun RoomListScaffold( state: RoomListState, onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomId) -> Unit, - onRoomLongClicked: (RoomListRoomSummary) -> Unit, onOpenSettings: () -> Unit, onCreateRoomClicked: () -> Unit, onInvitesClicked: () -> Unit, @@ -153,7 +149,6 @@ private fun RoomListScaffold( eventSink = state.eventSink, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = ::onRoomClicked, - onRoomLongClicked = onRoomLongClicked, onCreateRoomClicked = onCreateRoomClicked, onInvitesClicked = onInvitesClicked, modifier = Modifier @@ -195,5 +190,6 @@ internal fun RoomListViewPreview(@PreviewParameter(RoomListStateProvider::class) onRoomSettingsClicked = {}, onMenuActionClicked = {}, onRoomDirectorySearchClicked = {}, + acceptDeclineInviteView = {}, ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt index 552ff008a0..f49d879e02 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt @@ -75,7 +75,6 @@ fun RoomListContentView( eventSink: (RoomListEvents) -> Unit, onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomListRoomSummary) -> Unit, - onRoomLongClicked: (RoomListRoomSummary) -> Unit, onCreateRoomClicked: () -> Unit, onInvitesClicked: () -> Unit, modifier: Modifier = Modifier, @@ -104,7 +103,6 @@ fun RoomListContentView( eventSink = eventSink, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = onRoomClicked, - onRoomLongClicked = onRoomLongClicked, onInvitesClicked = onInvitesClicked, ) } @@ -161,7 +159,6 @@ private fun RoomsView( eventSink: (RoomListEvents) -> Unit, onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomListRoomSummary) -> Unit, - onRoomLongClicked: (RoomListRoomSummary) -> Unit, onInvitesClicked: () -> Unit, modifier: Modifier = Modifier, ) { @@ -176,7 +173,6 @@ private fun RoomsView( eventSink = eventSink, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = onRoomClicked, - onRoomLongClicked = onRoomLongClicked, onInvitesClicked = onInvitesClicked, modifier = modifier.fillMaxSize(), ) @@ -189,7 +185,6 @@ private fun RoomsViewList( eventSink: (RoomListEvents) -> Unit, onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomListRoomSummary) -> Unit, - onRoomLongClicked: (RoomListRoomSummary) -> Unit, onInvitesClicked: () -> Unit, modifier: Modifier = Modifier, ) { @@ -242,7 +237,7 @@ private fun RoomsViewList( RoomSummaryRow( room = room, onClick = onRoomClicked, - onLongClick = onRoomLongClicked, + eventSink = eventSink, ) if (index != state.summaries.lastIndex) { HorizontalDivider() @@ -305,7 +300,6 @@ internal fun RoomListContentViewPreview(@PreviewParameter(RoomListContentStatePr eventSink = {}, onConfirmRecoveryKeyClicked = {}, onRoomClicked = {}, - onRoomLongClicked = {}, onCreateRoomClicked = {}, onInvitesClicked = {} ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt index 0acda82c45..ecc9b0bd83 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.roomlist.impl.RoomListEvents import io.element.android.features.roomlist.impl.model.DisplayType import io.element.android.features.roomlist.impl.model.InviteSender import io.element.android.features.roomlist.impl.model.RoomListRoomSummary @@ -66,6 +67,7 @@ import io.element.android.libraries.designsystem.theme.roomListRoomName import io.element.android.libraries.designsystem.theme.unreadIndicator import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.ui.strings.CommonStrings +import timber.log.Timber internal val minHeight = 84.dp @@ -73,7 +75,7 @@ internal val minHeight = 84.dp internal fun RoomSummaryRow( room: RoomListRoomSummary, onClick: (RoomListRoomSummary) -> Unit, - onLongClick: (RoomListRoomSummary) -> Unit, + eventSink: (RoomListEvents) -> Unit, modifier: Modifier = Modifier, ) { when (room.type) { @@ -84,7 +86,9 @@ internal fun RoomSummaryRow( RoomSummaryScaffoldRow( room = room, onClick = onClick, - onLongClick = onLongClick, + onLongClick = { + Timber.d("Long click on invite room") + }, modifier = modifier ) { InviteNameAndIndicatorRow(name = room.name) @@ -94,14 +98,22 @@ internal fun RoomSummaryRow( InviteSenderRow(sender = room.inviteSender) } Spacer(modifier = Modifier.height(12.dp)) - InviteButtonsRow(onAcceptClicked = { }, onDeclineClicked = { }) + InviteButtonsRow( + onAcceptClicked = { + eventSink(RoomListEvents.AcceptInvite(room)) + }, + onDeclineClicked = { + eventSink(RoomListEvents.DeclineInvite(room)) + }) } } DisplayType.ROOM -> { RoomSummaryScaffoldRow( room = room, onClick = onClick, - onLongClick = onLongClick, + onLongClick = { + eventSink(RoomListEvents.ShowContextMenu(room)) + }, modifier = modifier ) { NameAndTimestampRow( @@ -133,11 +145,11 @@ private fun RoomSummaryScaffoldRow( Row( modifier = modifier - .fillMaxWidth() - .heightIn(min = minHeight) - .then(clickModifier) - .padding(horizontal = 16.dp, vertical = 11.dp) - .height(IntrinsicSize.Min), + .fillMaxWidth() + .heightIn(min = minHeight) + .then(clickModifier) + .padding(horizontal = 16.dp, vertical = 11.dp) + .height(IntrinsicSize.Min), ) { Avatar(room.avatarData) Spacer(modifier = Modifier.width(16.dp)) @@ -357,6 +369,6 @@ internal fun RoomSummaryRowPreview(@PreviewParameter(RoomListRoomSummaryProvider RoomSummaryRow( room = data, onClick = {}, - onLongClick = {} + eventSink = {}, ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchView.kt index 80657ed4fc..a3640d2d77 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearchView.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.roomlist.impl.R +import io.element.android.features.roomlist.impl.RoomListEvents import io.element.android.features.roomlist.impl.components.RoomSummaryRow import io.element.android.features.roomlist.impl.contentType import io.element.android.features.roomlist.impl.model.RoomListRoomSummary @@ -65,8 +66,8 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable internal fun RoomListSearchView( state: RoomListSearchState, + eventSink: (RoomListEvents) -> Unit, onRoomClicked: (RoomId) -> Unit, - onRoomLongClicked: (RoomListRoomSummary) -> Unit, onRoomDirectorySearchClicked: () -> Unit, modifier: Modifier = Modifier, ) { @@ -90,7 +91,7 @@ internal fun RoomListSearchView( RoomListSearchContent( state = state, onRoomClicked = onRoomClicked, - onRoomLongClicked = onRoomLongClicked, + eventSink = eventSink, onRoomDirectorySearchClicked = onRoomDirectorySearchClicked, ) } @@ -102,8 +103,8 @@ internal fun RoomListSearchView( @Composable private fun RoomListSearchContent( state: RoomListSearchState, + eventSink: (RoomListEvents) -> Unit, onRoomClicked: (RoomId) -> Unit, - onRoomLongClicked: (RoomListRoomSummary) -> Unit, onRoomDirectorySearchClicked: () -> Unit, ) { val borderColor = MaterialTheme.colorScheme.tertiary @@ -193,7 +194,7 @@ private fun RoomListSearchContent( RoomSummaryRow( room = room, onClick = ::onRoomClicked, - onLongClick = onRoomLongClicked, + eventSink = eventSink, ) } } @@ -220,7 +221,7 @@ internal fun RoomListSearchResultContentPreview(@PreviewParameter(RoomListSearch RoomListSearchContent( state = state, onRoomClicked = {}, - onRoomLongClicked = {}, + eventSink = {}, onRoomDirectorySearchClicked = {}, ) }