From 807bd362fea6569aeda2e4cb3faa89017d8a6233 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Apr 2024 11:41:55 +0200 Subject: [PATCH] Invite : remove invitelist entry points --- .../android/appnav/LoggedInFlowNode.kt | 52 ----- .../invite/api/InviteListEntryPoint.kt | 38 ---- .../features/invite/api/SeenInvitesStore.kt | 25 --- .../impl/DefaultInviteListEntryPoint.kt | 45 ---- .../invite/impl/DefaultSeenInvitesStore.kt | 56 ----- .../impl/components/InviteSummaryRow.kt | 195 ------------------ .../impl/invitelist/InviteListEvents.kt | 24 --- .../invite/impl/invitelist/InviteListNode.kt | 61 ------ .../impl/invitelist/InviteListPresenter.kt | 157 -------------- .../invite/impl/invitelist/InviteListState.kt | 29 --- .../invitelist/InviteListStateProvider.kt | 77 ------- .../invite/impl/invitelist/InviteListView.kt | 148 ------------- .../impl/model/InviteListInviteSummary.kt | 40 ---- .../model/InviteListInviteSummaryProvider.kt | 41 ---- .../invitelist/InviteListPresenterTests.kt | 1 - .../invite/test/FakeSeenInvitesStore.kt | 1 - .../roomlist/api/RoomListEntryPoint.kt | 1 - .../roomlist/impl/InvitesEntryPointView.kt | 81 -------- .../impl/RoomListContentStateProvider.kt | 6 +- .../features/roomlist/impl/RoomListNode.kt | 5 - .../roomlist/impl/RoomListPresenter.kt | 9 +- .../features/roomlist/impl/RoomListState.kt | 3 +- .../roomlist/impl/RoomListStateProvider.kt | 2 - .../features/roomlist/impl/RoomListView.kt | 10 +- .../impl/components/RoomListContentView.kt | 46 +---- .../DefaultInviteStateDataSource.kt | 72 ------- .../impl/datasource/InviteStateDataSource.kt | 25 --- .../roomlist/impl/RoomListPresenterTests.kt | 1 - .../android/samples/minimal/RoomListScreen.kt | 2 - 29 files changed, 16 insertions(+), 1237 deletions(-) delete mode 100644 features/invite/api/src/main/kotlin/io/element/android/features/invite/api/InviteListEntryPoint.kt delete mode 100644 features/invite/api/src/main/kotlin/io/element/android/features/invite/api/SeenInvitesStore.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultInviteListEntryPoint.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultSeenInvitesStore.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/components/InviteSummaryRow.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListEvents.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListNode.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenter.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListState.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListStateProvider.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListView.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummary.kt delete mode 100644 features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummaryProvider.kt delete mode 100644 features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/InvitesEntryPointView.kt delete mode 100644 features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/DefaultInviteStateDataSource.kt delete mode 100644 features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/InviteStateDataSource.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 0f6da36e26..092a4d8888 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -33,7 +33,6 @@ import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.navmodel.backstack.BackStack -import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.push import com.bumble.appyx.navmodel.backstack.operation.replace import com.bumble.appyx.navmodel.backstack.operation.singleTop @@ -48,7 +47,6 @@ import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.ftue.api.FtueEntryPoint import io.element.android.features.ftue.api.state.FtueService import io.element.android.features.ftue.api.state.FtueState -import io.element.android.features.invite.api.InviteListEntryPoint import io.element.android.features.lockscreen.api.LockScreenEntryPoint import io.element.android.features.lockscreen.api.LockScreenLockState import io.element.android.features.lockscreen.api.LockScreenService @@ -62,7 +60,6 @@ import io.element.android.features.securebackup.api.SecureBackupEntryPoint import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.createNode -import io.element.android.libraries.architecture.waitForChildAttached import io.element.android.libraries.deeplink.DeeplinkData import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.di.AppScope @@ -70,7 +67,6 @@ import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.MAIN_SPACE import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.push.api.notifications.NotificationDrawerManager import io.element.android.services.appnavstate.api.AppNavigationStateService @@ -95,7 +91,6 @@ class LoggedInFlowNode @AssistedInject constructor( private val createRoomEntryPoint: CreateRoomEntryPoint, private val appNavigationStateService: AppNavigationStateService, private val secureBackupEntryPoint: SecureBackupEntryPoint, - private val inviteListEntryPoint: InviteListEntryPoint, private val ftueEntryPoint: FtueEntryPoint, private val coroutineScope: CoroutineScope, private val networkMonitor: NetworkMonitor, @@ -160,23 +155,6 @@ class LoggedInFlowNode @AssistedInject constructor( } ) observeSyncStateAndNetworkStatus() - observeInvitesLoadingState() - } - - private fun observeInvitesLoadingState() { - lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - matrixClient.roomListService.invites.loadingState - .collect { inviteState -> - when (inviteState) { - is RoomList.LoadingState.Loaded -> if (inviteState.numberOfRooms == 0) { - backstack.removeLast(NavTarget.InviteList) - } - RoomList.LoadingState.NotLoaded -> Unit - } - } - } - } } @OptIn(FlowPreview::class) @@ -233,9 +211,6 @@ class LoggedInFlowNode @AssistedInject constructor( val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root ) : NavTarget - @Parcelize - data object InviteList : NavTarget - @Parcelize data object Ftue : NavTarget @@ -272,10 +247,6 @@ class LoggedInFlowNode @AssistedInject constructor( backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey)) } - override fun onInvitesClicked() { - backstack.push(NavTarget.InviteList) - } - override fun onRoomSettingsClicked(roomId: RoomId) { backstack.push(NavTarget.Room(roomId, initialElement = RoomNavigationTarget.Details)) } @@ -351,25 +322,6 @@ class LoggedInFlowNode @AssistedInject constructor( .params(SecureBackupEntryPoint.Params(initialElement = navTarget.initialElement)) .build() } - NavTarget.InviteList -> { - val callback = object : InviteListEntryPoint.Callback { - override fun onBackClicked() { - backstack.pop() - } - - override fun onInviteClicked(roomId: RoomId) { - backstack.push(NavTarget.Room(roomId)) - } - - override fun onInviteAccepted(roomId: RoomId) { - backstack.push(NavTarget.Room(roomId)) - } - } - - inviteListEntryPoint.nodeBuilder(this, buildContext) - .callback(callback) - .build() - } NavTarget.Ftue -> { ftueEntryPoint.nodeBuilder(this, buildContext) .callback(object : FtueEntryPoint.Callback { @@ -414,10 +366,6 @@ class LoggedInFlowNode @AssistedInject constructor( if (!canShowRoomList()) return@withContext notificationDrawerManager.clearMembershipNotificationForSession(deeplinkData.sessionId) backstack.singleTop(NavTarget.RoomList) - backstack.push(NavTarget.InviteList) - waitForChildAttached { navTarget -> - navTarget is NavTarget.InviteList - } } private fun canShowRoomList(): Boolean { diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/InviteListEntryPoint.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/InviteListEntryPoint.kt deleted file mode 100644 index c5063cdbc8..0000000000 --- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/InviteListEntryPoint.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.invite.api - -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 InviteListEntryPoint : FeatureEntryPoint { - fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder - - interface NodeBuilder { - fun callback(callback: Callback): NodeBuilder - fun build(): Node - } - - interface Callback : Plugin { - fun onBackClicked() - fun onInviteClicked(roomId: RoomId) - fun onInviteAccepted(roomId: RoomId) - } -} diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/SeenInvitesStore.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/SeenInvitesStore.kt deleted file mode 100644 index e34b17cee8..0000000000 --- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/SeenInvitesStore.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.invite.api - -import io.element.android.libraries.matrix.api.core.RoomId -import kotlinx.coroutines.flow.Flow - -interface SeenInvitesStore { - fun seenRoomIds(): Flow> - suspend fun markAsSeen(roomIds: Set) -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultInviteListEntryPoint.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultInviteListEntryPoint.kt deleted file mode 100644 index 5e464a79bc..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultInviteListEntryPoint.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.invite.impl - -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.bumble.appyx.core.plugin.Plugin -import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.features.invite.api.InviteListEntryPoint -import io.element.android.features.invite.impl.invitelist.InviteListNode -import io.element.android.libraries.architecture.createNode -import io.element.android.libraries.di.AppScope -import javax.inject.Inject - -@ContributesBinding(AppScope::class) -class DefaultInviteListEntryPoint @Inject constructor() : InviteListEntryPoint { - override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): InviteListEntryPoint.NodeBuilder { - val plugins = ArrayList() - - return object : InviteListEntryPoint.NodeBuilder { - override fun callback(callback: InviteListEntryPoint.Callback): InviteListEntryPoint.NodeBuilder { - plugins += callback - return this - } - - override fun build(): Node { - return parentNode.createNode(buildContext, plugins) - } - } - } -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultSeenInvitesStore.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultSeenInvitesStore.kt deleted file mode 100644 index bf0423914e..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/DefaultSeenInvitesStore.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.invite.impl - -import android.content.Context -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.stringSetPreferencesKey -import androidx.datastore.preferences.preferencesDataStore -import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.features.invite.api.SeenInvitesStore -import io.element.android.libraries.di.ApplicationContext -import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.core.RoomId -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map -import javax.inject.Inject - -private val Context.dataStore: DataStore by preferencesDataStore(name = "elementx_seeninvites") -private val seenInvitesKey = stringSetPreferencesKey("seenInvites") - -@ContributesBinding(SessionScope::class) -class DefaultSeenInvitesStore @Inject constructor( - @ApplicationContext context: Context -) : SeenInvitesStore { - private val store = context.dataStore - - override fun seenRoomIds(): Flow> = - store.data.map { prefs -> - prefs[seenInvitesKey] - .orEmpty() - .map { RoomId(it) } - .toSet() - } - - override suspend fun markAsSeen(roomIds: Set) { - store.edit { prefs -> - prefs[seenInvitesKey] = roomIds.map { it.value }.toSet() - } - } -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/components/InviteSummaryRow.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/components/InviteSummaryRow.kt deleted file mode 100644 index 0987f6cf57..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/components/InviteSummaryRow.kt +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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.invite.impl.components - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.features.invite.impl.R -import io.element.android.features.invite.impl.model.InviteListInviteSummary -import io.element.android.features.invite.impl.model.InviteListInviteSummaryProvider -import io.element.android.features.invite.impl.model.InviteSender -import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom -import io.element.android.libraries.designsystem.components.avatar.Avatar -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.Button -import io.element.android.libraries.designsystem.theme.components.ButtonSize -import io.element.android.libraries.designsystem.theme.components.OutlinedButton -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.ui.strings.CommonStrings - -private val minHeight = 72.dp - -@Composable -internal fun InviteSummaryRow( - invite: InviteListInviteSummary, - onAcceptClicked: () -> Unit, - onDeclineClicked: () -> Unit, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier - .fillMaxWidth() - .heightIn(min = minHeight) - ) { - DefaultInviteSummaryRow( - invite = invite, - onAcceptClicked = onAcceptClicked, - onDeclineClicked = onDeclineClicked, - ) - } -} - -@Composable -private fun DefaultInviteSummaryRow( - invite: InviteListInviteSummary, - onAcceptClicked: () -> Unit, - onDeclineClicked: () -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - .height(IntrinsicSize.Min), - verticalAlignment = Alignment.Top - ) { - Avatar( - invite.roomAvatarData, - ) - - Column( - modifier = Modifier - .padding(start = 16.dp, end = 4.dp) - .alignByBaseline() - .weight(1f) - ) { - val bonusPadding = if (invite.isNew) 12.dp else 0.dp - - // Name - Text( - text = invite.roomName, - color = MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = ElementTheme.typography.fontBodyLgMedium, - modifier = Modifier.padding(end = bonusPadding), - ) - - // ID or Alias - invite.roomAlias?.let { - Text( - style = ElementTheme.typography.fontBodyMdRegular, - text = it, - color = MaterialTheme.colorScheme.secondary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(end = bonusPadding), - ) - } - - // Sender - invite.sender?.let { sender -> - SenderRow(sender = sender) - } - - // CTAs - Row(Modifier.padding(top = 12.dp)) { - OutlinedButton( - text = stringResource(CommonStrings.action_decline), - onClick = onDeclineClicked, - modifier = Modifier.weight(1f), - size = ButtonSize.Medium, - ) - - Spacer(modifier = Modifier.width(12.dp)) - - Button( - text = stringResource(CommonStrings.action_accept), - onClick = onAcceptClicked, - modifier = Modifier.weight(1f), - size = ButtonSize.Medium, - ) - } - } - - UnreadIndicatorAtom(isVisible = invite.isNew) - } -} - -@Composable -private fun SenderRow(sender: InviteSender) { - Row( - horizontalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier.padding(top = 6.dp), - ) { - Avatar( - avatarData = sender.avatarData, - ) - Text( - text = stringResource(R.string.screen_invites_invited_you, sender.displayName, sender.userId.value).let { text -> - val senderNameStart = LocalContext.current.getString(R.string.screen_invites_invited_you).indexOf("%1\$s") - AnnotatedString( - text = text, - spanStyles = listOf( - AnnotatedString.Range( - SpanStyle( - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.primary - ), - start = senderNameStart, - end = senderNameStart + sender.displayName.length - ) - ) - ) - }, - style = ElementTheme.typography.fontBodyMdRegular, - color = MaterialTheme.colorScheme.secondary, - ) - } -} - -@PreviewsDayNight -@Composable -internal fun InviteSummaryRowPreview(@PreviewParameter(InviteListInviteSummaryProvider::class) data: InviteListInviteSummary) = ElementPreview { - InviteSummaryRow( - invite = data, - onAcceptClicked = {}, - onDeclineClicked = {}, - ) -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListEvents.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListEvents.kt deleted file mode 100644 index f4ba30844a..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListEvents.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2024 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.invite.impl.invitelist - -import io.element.android.features.invite.impl.model.InviteListInviteSummary - -sealed interface InviteListEvents { - data class AcceptInvite(val invite: InviteListInviteSummary) : InviteListEvents - data class DeclineInvite(val invite: InviteListInviteSummary) : InviteListEvents -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListNode.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListNode.kt deleted file mode 100644 index fe491b157e..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListNode.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2024 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.invite.impl.invitelist - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.bumble.appyx.core.plugin.Plugin -import com.bumble.appyx.core.plugin.plugins -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import io.element.android.anvilannotations.ContributesNode -import io.element.android.features.invite.api.InviteListEntryPoint -import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.core.RoomId - -@ContributesNode(SessionScope::class) -class InviteListNode @AssistedInject constructor( - @Assisted buildContext: BuildContext, - @Assisted plugins: List, - private val presenter: InviteListPresenter, -) : Node(buildContext, plugins = plugins) { - private fun onBackClicked() { - plugins().forEach { it.onBackClicked() } - } - - private fun onInviteAccepted(roomId: RoomId) { - plugins().forEach { it.onInviteAccepted(roomId) } - } - - private fun onInviteClicked(roomId: RoomId) { - plugins().forEach { it.onInviteClicked(roomId) } - } - - @Composable - override fun View(modifier: Modifier) { - val state = presenter.present() - InviteListView( - state = state, - onBackClicked = ::onBackClicked, - onInviteAccepted = ::onInviteAccepted, - onInviteDeclined = {}, - onInviteClicked = ::onInviteClicked, - ) - } -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenter.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenter.kt deleted file mode 100644 index 9d9a33ef13..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenter.kt +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2024 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.invite.impl.invitelist - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import io.element.android.features.invite.api.SeenInvitesStore -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.invite.impl.model.InviteListInviteSummary -import io.element.android.features.invite.impl.model.InviteSender -import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.roomlist.RoomSummary -import kotlinx.collections.immutable.toPersistentList -import kotlinx.coroutines.flow.first -import javax.inject.Inject - -class InviteListPresenter @Inject constructor( - private val client: MatrixClient, - private val store: SeenInvitesStore, - private val acceptDeclineInvitePresenter: Presenter, -) : Presenter { - @Composable - override fun present(): InviteListState { - val invites by client - .roomListService - .invites - .summaries - .collectAsState(initial = emptyList()) - - var seenInvites by remember { mutableStateOf>(emptySet()) } - - LaunchedEffect(Unit) { - seenInvites = store.seenRoomIds().first() - } - - LaunchedEffect(invites) { - store.markAsSeen( - invites - .filterIsInstance() - .map { it.details.roomId } - .toSet() - ) - } - - val acceptDeclineInviteState = acceptDeclineInvitePresenter.present() - - fun handleEvent(event: InviteListEvents) { - when (event) { - is InviteListEvents.AcceptInvite -> { - acceptDeclineInviteState.eventSink( - AcceptDeclineInviteEvents.AcceptInvite(event.invite.toInviteData()) - ) - } - - is InviteListEvents.DeclineInvite -> { - acceptDeclineInviteState.eventSink( - AcceptDeclineInviteEvents.DeclineInvite(event.invite.toInviteData()) - ) - } - } - } - - val inviteList = remember(seenInvites, invites) { - invites - .filterIsInstance() - .map { - it.toInviteSummary(seenInvites.contains(it.details.roomId)) - } - .toPersistentList() - } - - return InviteListState( - inviteList = inviteList, - acceptDeclineInviteState = acceptDeclineInviteState, - eventSink = ::handleEvent - ) - } - - private fun RoomSummary.Filled.toInviteSummary(seen: Boolean) = details.run { - val i = inviter - val avatarData = if (isDirect && i != null) { - AvatarData( - id = i.userId.value, - name = i.displayName, - url = i.avatarUrl, - size = AvatarSize.RoomInviteItem, - ) - } else { - AvatarData( - id = roomId.value, - name = name, - url = avatarUrl, - size = AvatarSize.RoomInviteItem, - ) - } - - val alias = if (isDirect) { - inviter?.userId?.value - } else { - canonicalAlias - } - - InviteListInviteSummary( - roomId = roomId, - roomName = name, - roomAlias = alias, - roomAvatarData = avatarData, - isDirect = isDirect, - isNew = !seen, - sender = inviter - ?.takeIf { !isDirect } - ?.run { - InviteSender( - userId = userId, - displayName = displayName ?: "", - avatarData = AvatarData( - id = userId.value, - name = displayName, - url = avatarUrl, - size = AvatarSize.InviteSender, - ), - ) - }, - ) - } - - private fun InviteListInviteSummary.toInviteData() = InviteData( - roomId = roomId, - roomName = roomName, - isDirect = isDirect, - ) -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListState.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListState.kt deleted file mode 100644 index 8a3cd69923..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListState.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2024 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.invite.impl.invitelist - -import androidx.compose.runtime.Immutable -import io.element.android.features.invite.api.response.AcceptDeclineInviteState -import io.element.android.features.invite.impl.model.InviteListInviteSummary -import kotlinx.collections.immutable.ImmutableList - -@Immutable -data class InviteListState( - val inviteList: ImmutableList, - val acceptDeclineInviteState: AcceptDeclineInviteState, - val eventSink: (InviteListEvents) -> Unit -) diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListStateProvider.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListStateProvider.kt deleted file mode 100644 index 9814b1b20d..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListStateProvider.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2024 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.invite.impl.invitelist - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.invite.api.response.AcceptDeclineInviteState -import io.element.android.features.invite.api.response.AcceptDeclineInviteStateProvider -import io.element.android.features.invite.api.response.anAcceptDeclineInviteState -import io.element.android.features.invite.impl.model.InviteListInviteSummary -import io.element.android.features.invite.impl.model.InviteSender -import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.core.UserId -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf - -open class InviteListStateProvider : PreviewParameterProvider { - private val acceptDeclineInviteStateProvider = AcceptDeclineInviteStateProvider() - - override val values: Sequence - get() = sequenceOf( - anInviteListState(), - anInviteListState(inviteList = persistentListOf()), - ) + acceptDeclineInviteStateProvider.values.map { acceptDeclineInviteState -> - anInviteListState(acceptDeclineInviteState = acceptDeclineInviteState) - } -} - -internal fun anInviteListState( - inviteList: ImmutableList = aInviteListInviteSummaryList(), - acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(), - eventSink: (InviteListEvents) -> Unit = {} -) = InviteListState( - inviteList = inviteList, - acceptDeclineInviteState = acceptDeclineInviteState, - eventSink = eventSink, -) - -internal fun aInviteListInviteSummaryList(): ImmutableList { - return persistentListOf( - InviteListInviteSummary( - roomId = RoomId("!id1:example.com"), - roomName = "Room 1", - roomAlias = "#room:example.org", - sender = InviteSender( - userId = UserId("@alice:example.org"), - displayName = "Alice" - ), - ), - InviteListInviteSummary( - roomId = RoomId("!id2:example.com"), - roomName = "Room 2", - sender = InviteSender( - userId = UserId("@bob:example.org"), - displayName = "Bob" - ), - ), - InviteListInviteSummary( - roomId = RoomId("!id3:example.com"), - roomName = "Alice", - roomAlias = "@alice:example.com" - ), - ) -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListView.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListView.kt deleted file mode 100644 index 16031d558c..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/invitelist/InviteListView.kt +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2024 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.invite.impl.invitelist - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.consumeWindowInsets -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.features.invite.impl.R -import io.element.android.features.invite.impl.components.InviteSummaryRow -import io.element.android.features.invite.impl.response.AcceptDeclineInviteView -import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.aliasScreenTitle -import io.element.android.libraries.designsystem.theme.components.HorizontalDivider -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.TopAppBar -import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -fun InviteListView( - state: InviteListState, - onBackClicked: () -> Unit, - onInviteAccepted: (RoomId) -> Unit, - onInviteDeclined: (RoomId) -> Unit, - onInviteClicked: (RoomId) -> Unit, - modifier: Modifier = Modifier, -) { - InviteListContent( - state = state, - modifier = modifier, - onInviteClicked = onInviteClicked, - onBackClicked = onBackClicked, - ) - AcceptDeclineInviteView( - state = state.acceptDeclineInviteState, - onInviteAccepted = onInviteAccepted, - onInviteDeclined = onInviteDeclined, - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun InviteListContent( - state: InviteListState, - onBackClicked: () -> Unit, - onInviteClicked: (RoomId) -> Unit, - modifier: Modifier = Modifier, -) { - Scaffold( - modifier = modifier, - topBar = { - TopAppBar( - navigationIcon = { - BackButton(onClick = onBackClicked) - }, - title = { - Text( - text = stringResource(CommonStrings.action_invites_list), - style = ElementTheme.typography.aliasScreenTitle, - ) - } - ) - }, - content = { padding -> - Column( - modifier = Modifier - .padding(padding) - .consumeWindowInsets(padding) - ) { - if (state.inviteList.isEmpty()) { - Spacer(Modifier.size(80.dp)) - - Text( - text = stringResource(R.string.screen_invites_empty_list), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.tertiary, - modifier = Modifier.fillMaxWidth() - ) - } else { - LazyColumn( - modifier = Modifier.weight(1f) - ) { - itemsIndexed( - items = state.inviteList, - ) { index, invite -> - InviteSummaryRow( - modifier = Modifier.clickable( - onClick = { onInviteClicked(invite.roomId) } - ), - invite = invite, - onAcceptClicked = { state.eventSink(InviteListEvents.AcceptInvite(invite)) }, - onDeclineClicked = { state.eventSink(InviteListEvents.DeclineInvite(invite)) }, - ) - - if (index != state.inviteList.lastIndex) { - HorizontalDivider() - } - } - } - } - } - } - ) -} - -@PreviewsDayNight -@Composable -internal fun InviteListViewPreview(@PreviewParameter(InviteListStateProvider::class) state: InviteListState) = ElementPreview { - InviteListView( - state = state, - onBackClicked = {}, - onInviteAccepted = {}, - onInviteDeclined = {}, - onInviteClicked = {}, - ) -} diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummary.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummary.kt deleted file mode 100644 index e17dcc997c..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummary.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.invite.impl.model - -import androidx.compose.runtime.Immutable -import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.core.UserId - -@Immutable -data class InviteListInviteSummary( - val roomId: RoomId, - val roomName: String = "", - val roomAlias: String? = null, - val roomAvatarData: AvatarData = AvatarData(roomId.value, roomName, size = AvatarSize.RoomInviteItem), - val sender: InviteSender? = null, - val isDirect: Boolean = false, - val isNew: Boolean = false, -) - -data class InviteSender( - val userId: UserId, - val displayName: String, - val avatarData: AvatarData = AvatarData(userId.value, displayName, size = AvatarSize.InviteSender), -) diff --git a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummaryProvider.kt b/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummaryProvider.kt deleted file mode 100644 index 11f6742345..0000000000 --- a/features/invite/impl/src/main/kotlin/io/element/android/features/invite/impl/model/InviteListInviteSummaryProvider.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.invite.impl.model - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.core.UserId - -open class InviteListInviteSummaryProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - aInviteListInviteSummary(), - aInviteListInviteSummary().copy(roomAlias = "#someroom-with-a-long-alias:example.com"), - aInviteListInviteSummary().copy(roomAlias = "#someroom-with-a-long-alias:example.com", isNew = true), - aInviteListInviteSummary().copy(roomName = "Alice", sender = null), - aInviteListInviteSummary().copy(isNew = true) - ) -} - -fun aInviteListInviteSummary() = InviteListInviteSummary( - roomId = RoomId("!room1:example.com"), - roomName = "Some room with a long name that will truncate", - sender = InviteSender( - userId = UserId("@alice-with-a-long-mxid:example.org"), - displayName = "Alice with a long name" - ), -) diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenterTests.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenterTests.kt index c984e9c5fb..ae982e0358 100644 --- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenterTests.kt +++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/invitelist/InviteListPresenterTests.kt @@ -21,7 +21,6 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.TurbineTestContext import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.response.AcceptDeclineInviteState import io.element.android.features.invite.api.response.anAcceptDeclineInviteState import io.element.android.features.invite.test.FakeSeenInvitesStore diff --git a/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/FakeSeenInvitesStore.kt b/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/FakeSeenInvitesStore.kt index f2a21ac768..c148eca159 100644 --- a/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/FakeSeenInvitesStore.kt +++ b/features/invite/test/src/main/kotlin/io/element/android/features/invite/test/FakeSeenInvitesStore.kt @@ -16,7 +16,6 @@ package io.element.android.features.invite.test -import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.libraries.matrix.api.core.RoomId import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow 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 b5d1c1299f..f4e2ca7b01 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 @@ -34,7 +34,6 @@ interface RoomListEntryPoint : FeatureEntryPoint { fun onCreateRoomClicked() fun onSettingsClicked() fun onSessionConfirmRecoveryKeyClicked() - fun onInvitesClicked() fun onRoomSettingsClicked(roomId: RoomId) fun onReportBugClicked() fun onRoomDirectorySearchClicked() diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/InvitesEntryPointView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/InvitesEntryPointView.kt deleted file mode 100644 index ea2b5d71a3..0000000000 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/InvitesEntryPointView.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -fun InvitesEntryPointView( - onInvitesClicked: () -> Unit, - state: InvitesState, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier.fillMaxWidth(), - ) { - Row( - modifier = Modifier - .clip(RoundedCornerShape(8.dp)) - .clickable(role = Role.Button, onClick = onInvitesClicked) - .padding(start = 24.dp, end = 16.dp) - .align(Alignment.CenterEnd) - .heightIn(min = 40.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = stringResource(CommonStrings.action_invites_list), - style = ElementTheme.typography.fontBodyMdMedium, - ) - - if (state == InvitesState.NewInvites) { - Spacer(Modifier.width(8.dp)) - UnreadIndicatorAtom() - } - } - } -} - -@PreviewsDayNight -@Composable -internal fun InvitesEntryPointViewPreview(@PreviewParameter(InvitesStateProvider::class) state: InvitesState) = ElementPreview { - InvitesEntryPointView( - onInvitesClicked = {}, - state = state, - ) -} diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt index 284abb5d0f..5581615a2e 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt @@ -33,11 +33,9 @@ open class RoomListContentStateProvider : PreviewParameterProvider = aRoomListRoomSummaryList(), ) = RoomListContentState.Rooms( - invitesState = invitesState, securityBannerState = securityBannerState, summaries = summaries, ) @@ -46,6 +44,4 @@ internal fun aMigrationContentState() = RoomListContentState.Migration internal fun aSkeletonContentState() = RoomListContentState.Skeleton(16) -internal fun anEmptyContentState( - invitesState: InvitesState = InvitesState.NoInvites, -) = RoomListContentState.Empty(invitesState) +internal fun anEmptyContentState() = RoomListContentState.Empty 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 c2051ceff3..912c45eb30 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 @@ -70,10 +70,6 @@ class RoomListNode @AssistedInject constructor( plugins().forEach { it.onSessionConfirmRecoveryKeyClicked() } } - private fun onInvitesClicked() { - plugins().forEach { it.onInvitesClicked() } - } - private fun onRoomSettingsClicked(roomId: RoomId) { plugins().forEach { it.onRoomSettingsClicked(roomId) } } @@ -103,7 +99,6 @@ class RoomListNode @AssistedInject constructor( onSettingsClicked = this::onOpenSettings, onCreateRoomClicked = this::onCreateRoomClicked, onConfirmRecoveryKeyClicked = this::onSessionConfirmRecoveryKeyClicked, - onInvitesClicked = this::onInvitesClicked, onRoomSettingsClicked = this::onRoomSettingsClicked, onMenuActionClicked = { onMenuActionClicked(activity, it) }, onRoomDirectorySearchClicked = this::onRoomDirectorySearchClicked, 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 ce6097b512..d58398a831 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 @@ -40,7 +40,6 @@ import io.element.android.features.leaveroom.api.LeaveRoomPresenter import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.preferences.api.store.SessionPreferencesStore -import io.element.android.features.roomlist.impl.datasource.InviteStateDataSource 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 @@ -83,7 +82,6 @@ class RoomListPresenter @Inject constructor( private val client: MatrixClient, private val networkMonitor: NetworkMonitor, private val snackbarDispatcher: SnackbarDispatcher, - private val inviteStateDataSource: InviteStateDataSource, private val leaveRoomPresenter: LeaveRoomPresenter, private val roomListDataSource: RoomListDataSource, private val featureFlagService: FeatureFlagService, @@ -209,16 +207,11 @@ class RoomListPresenter @Inject constructor( } return when { showMigration -> RoomListContentState.Migration - showEmpty -> { - val invitesState = inviteStateDataSource.inviteState() - RoomListContentState.Empty(invitesState) - } + showEmpty -> RoomListContentState.Empty showSkeleton -> RoomListContentState.Skeleton(count = 16) else -> { - val invitesState = inviteStateDataSource.inviteState() val securityBannerState by securityBannerState(securityBannerDismissed) RoomListContentState.Rooms( - invitesState = invitesState, securityBannerState = securityBannerState, summaries = roomSummaries.dataOrNull().orEmpty().toPersistentList() ) 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 0305f43bfc..ed72c622c7 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 @@ -72,9 +72,8 @@ enum class SecurityBannerState { sealed interface RoomListContentState { data object Migration : RoomListContentState data class Skeleton(val count: Int) : RoomListContentState - data class Empty(val invitesState: InvitesState) : RoomListContentState + data object Empty : RoomListContentState data class Rooms( - val invitesState: InvitesState, val securityBannerState: SecurityBannerState, val summaries: ImmutableList, ) : RoomListContentState 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 372a14f7a7..745d14164a 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 @@ -44,8 +44,6 @@ open class RoomListStateProvider : PreviewParameterProvider { aRoomListState(), aRoomListState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)), aRoomListState(hasNetworkConnection = false), - aRoomListState(contentState = aRoomsContentState(invitesState = InvitesState.SeenInvites)), - aRoomListState(contentState = aRoomsContentState(invitesState = InvitesState.NewInvites)), aRoomListState(contextMenu = aContextMenuShown(roomName = "A nice room name")), aRoomListState(contextMenu = aContextMenuShown(isFavorite = true)), aRoomListState(contentState = aRoomsContentState(securityBannerState = SecurityBannerState.RecoveryKeyConfirmation)), 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 212894f521..d4652cb975 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,7 +32,6 @@ 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 @@ -56,12 +55,11 @@ fun RoomListView( onSettingsClicked: () -> Unit, onConfirmRecoveryKeyClicked: () -> Unit, onCreateRoomClicked: () -> Unit, - onInvitesClicked: () -> Unit, onRoomSettingsClicked: (roomId: RoomId) -> Unit, onMenuActionClicked: (RoomListMenuAction) -> Unit, onRoomDirectorySearchClicked: () -> Unit, modifier: Modifier = Modifier, - acceptDeclineInviteView: @Composable ()->Unit, + acceptDeclineInviteView: @Composable () -> Unit, ) { ConnectivityIndicatorContainer( modifier = modifier, @@ -80,14 +78,13 @@ fun RoomListView( LeaveRoomView(state = state.leaveRoomState) RoomListScaffold( - modifier = Modifier.padding(top = topPadding), state = state, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = onRoomClicked, onOpenSettings = onSettingsClicked, onCreateRoomClicked = onCreateRoomClicked, - onInvitesClicked = onInvitesClicked, onMenuActionClicked = onMenuActionClicked, + modifier = Modifier.padding(top = topPadding), ) // This overlaid view will only be visible when state.displaySearchResults is true RoomListSearchView( @@ -114,7 +111,6 @@ private fun RoomListScaffold( onRoomClicked: (RoomId) -> Unit, onOpenSettings: () -> Unit, onCreateRoomClicked: () -> Unit, - onInvitesClicked: () -> Unit, onMenuActionClicked: (RoomListMenuAction) -> Unit, modifier: Modifier = Modifier, ) { @@ -150,7 +146,6 @@ private fun RoomListScaffold( onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = ::onRoomClicked, onCreateRoomClicked = onCreateRoomClicked, - onInvitesClicked = onInvitesClicked, modifier = Modifier .padding(padding) .consumeWindowInsets(padding) @@ -186,7 +181,6 @@ internal fun RoomListViewPreview(@PreviewParameter(RoomListStateProvider::class) onSettingsClicked = {}, onConfirmRecoveryKeyClicked = {}, onCreateRoomClicked = {}, - onInvitesClicked = {}, onRoomSettingsClicked = {}, onMenuActionClicked = {}, onRoomDirectorySearchClicked = {}, 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 f49d879e02..1b1c760889 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 @@ -44,8 +44,6 @@ import androidx.compose.ui.unit.Velocity 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.InvitesEntryPointView -import io.element.android.features.roomlist.impl.InvitesState import io.element.android.features.roomlist.impl.R import io.element.android.features.roomlist.impl.RoomListContentState import io.element.android.features.roomlist.impl.RoomListContentStateProvider @@ -76,7 +74,6 @@ fun RoomListContentView( onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomListRoomSummary) -> Unit, onCreateRoomClicked: () -> Unit, - onInvitesClicked: () -> Unit, modifier: Modifier = Modifier, ) { Box(modifier = modifier) { @@ -91,8 +88,6 @@ fun RoomListContentView( } is RoomListContentState.Empty -> { EmptyView( - state = contentState, - onInvitesClicked = onInvitesClicked, onCreateRoomClicked = onCreateRoomClicked, ) } @@ -103,7 +98,6 @@ fun RoomListContentView( eventSink = eventSink, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = onRoomClicked, - onInvitesClicked = onInvitesClicked, ) } } @@ -126,30 +120,21 @@ private fun SkeletonView(count: Int, modifier: Modifier = Modifier) { @Composable private fun EmptyView( - state: RoomListContentState.Empty, onCreateRoomClicked: () -> Unit, - onInvitesClicked: () -> Unit, modifier: Modifier = Modifier ) { - Box( + EmptyScaffold( + title = R.string.screen_roomlist_empty_title, + subtitle = R.string.screen_roomlist_empty_message, + action = { + Button( + text = stringResource(CommonStrings.action_start_chat), + leadingIcon = IconSource.Vector(CompoundIcons.Compose()), + onClick = onCreateRoomClicked, + ) + }, modifier = modifier.fillMaxSize(), - ) { - if (state.invitesState != InvitesState.NoInvites) { - InvitesEntryPointView(onInvitesClicked, state.invitesState) - } - EmptyScaffold( - title = R.string.screen_roomlist_empty_title, - subtitle = R.string.screen_roomlist_empty_message, - action = { - Button( - text = stringResource(CommonStrings.action_start_chat), - leadingIcon = IconSource.Vector(CompoundIcons.Compose()), - onClick = onCreateRoomClicked, - ) - }, - modifier = Modifier.fillMaxSize(), - ) - } + ) } @Composable @@ -159,7 +144,6 @@ private fun RoomsView( eventSink: (RoomListEvents) -> Unit, onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomListRoomSummary) -> Unit, - onInvitesClicked: () -> Unit, modifier: Modifier = Modifier, ) { if (state.summaries.isEmpty() && filtersState.hasAnyFilterSelected) { @@ -173,7 +157,6 @@ private fun RoomsView( eventSink = eventSink, onConfirmRecoveryKeyClicked = onConfirmRecoveryKeyClicked, onRoomClicked = onRoomClicked, - onInvitesClicked = onInvitesClicked, modifier = modifier.fillMaxSize(), ) } @@ -185,7 +168,6 @@ private fun RoomsViewList( eventSink: (RoomListEvents) -> Unit, onConfirmRecoveryKeyClicked: () -> Unit, onRoomClicked: (RoomListRoomSummary) -> Unit, - onInvitesClicked: () -> Unit, modifier: Modifier = Modifier, ) { val lazyListState = rememberLazyListState() @@ -223,11 +205,6 @@ private fun RoomsViewList( else -> Unit } - if (state.invitesState != InvitesState.NoInvites) { - item { - InvitesEntryPointView(onInvitesClicked, state.invitesState) - } - } // Note: do not use a key for the LazyColumn, or the scroll will not behave as expected if a room // is moved to the top of the list. itemsIndexed( @@ -301,6 +278,5 @@ internal fun RoomListContentViewPreview(@PreviewParameter(RoomListContentStatePr onConfirmRecoveryKeyClicked = {}, onRoomClicked = {}, onCreateRoomClicked = {}, - onInvitesClicked = {} ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/DefaultInviteStateDataSource.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/DefaultInviteStateDataSource.kt deleted file mode 100644 index 16baf4e41b..0000000000 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/DefaultInviteStateDataSource.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.datasource - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.features.invite.api.SeenInvitesStore -import io.element.android.features.roomlist.impl.InvitesState -import io.element.android.libraries.core.coroutine.CoroutineDispatchers -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.roomlist.RoomSummary -import kotlinx.coroutines.withContext -import javax.inject.Inject - -@ContributesBinding(SessionScope::class) -class DefaultInviteStateDataSource @Inject constructor( - private val client: MatrixClient, - private val seenInvitesStore: SeenInvitesStore, - private val coroutineDispatchers: CoroutineDispatchers, -) : InviteStateDataSource { - @Composable - override fun inviteState(): InvitesState { - val invites by client - .roomListService - .invites - .summaries - .collectAsState(initial = emptyList()) - - val seenInvites by seenInvitesStore - .seenRoomIds() - .collectAsState(initial = emptySet()) - - var state by remember { mutableStateOf(InvitesState.NoInvites) } - - LaunchedEffect(invites, seenInvites) { - withContext(coroutineDispatchers.computation) { - state = when { - invites.isEmpty() -> InvitesState.NoInvites - seenInvites.containsAll(invites.roomIds) -> InvitesState.SeenInvites - else -> InvitesState.NewInvites - } - } - } - - return state - } -} - -private val List.roomIds: Collection - get() = filterIsInstance().map { it.details.roomId } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/InviteStateDataSource.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/InviteStateDataSource.kt deleted file mode 100644 index 866bed1efd..0000000000 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/InviteStateDataSource.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.datasource - -import androidx.compose.runtime.Composable -import io.element.android.features.roomlist.impl.InvitesState - -interface InviteStateDataSource { - @Composable - fun inviteState(): InvitesState -} diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt index 0f2c288a63..9bcbf64d7d 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt @@ -28,7 +28,6 @@ import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.features.preferences.api.store.SessionPreferencesStore import io.element.android.features.roomlist.impl.datasource.FakeInviteDataSource -import io.element.android.features.roomlist.impl.datasource.InviteStateDataSource import io.element.android.features.roomlist.impl.datasource.RoomListDataSource import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory import io.element.android.features.roomlist.impl.filters.RoomListFiltersState 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 48f629af4d..a7916a13da 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 @@ -20,12 +20,10 @@ import android.content.Context import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier -import io.element.android.features.invite.impl.DefaultSeenInvitesStore import io.element.android.features.leaveroom.impl.LeaveRoomPresenterImpl import io.element.android.features.networkmonitor.impl.NetworkMonitorImpl import io.element.android.features.roomlist.impl.RoomListPresenter import io.element.android.features.roomlist.impl.RoomListView -import io.element.android.features.roomlist.impl.datasource.DefaultInviteStateDataSource import io.element.android.features.roomlist.impl.datasource.RoomListDataSource import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory import io.element.android.features.roomlist.impl.filters.RoomListFiltersPresenter