diff --git a/features/joinroom/impl/build.gradle.kts b/features/joinroom/impl/build.gradle.kts index 10b95789ec..00095d1401 100644 --- a/features/joinroom/impl/build.gradle.kts +++ b/features/joinroom/impl/build.gradle.kts @@ -50,6 +50,8 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.features.invite.test) + testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt index 3aaef1568e..777de024c5 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt @@ -32,8 +32,8 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoomInfo +import org.jetbrains.annotations.VisibleForTesting import java.util.Optional -import kotlin.jvm.optionals.getOrNull class JoinRoomPresenter @AssistedInject constructor( @Assisted private val roomId: RoomId, @@ -49,8 +49,6 @@ class JoinRoomPresenter @AssistedInject constructor( @Composable override fun present(): JoinRoomState { val roomInfo by matrixClient.getRoomInfoFlow(roomId).collectAsState(initial = Optional.empty()) - val joinAuthorisationStatus = joinAuthorisationStatus(roomInfo) - val acceptDeclineInviteState = acceptDeclineInvitePresenter.present() val contentState by produceState>(initialValue = AsyncData.Uninitialized, key1 = roomInfo) { value = when { roomInfo.isPresent -> { @@ -61,20 +59,25 @@ class JoinRoomPresenter @AssistedInject constructor( val contentState = roomDescription.get().toContentState() AsyncData.Success(contentState) } - else -> AsyncData.Uninitialized + else -> { + AsyncData.Uninitialized + } } } + val acceptDeclineInviteState = acceptDeclineInvitePresenter.present() fun handleEvents(event: JoinRoomEvents) { when (event) { JoinRoomEvents.AcceptInvite, JoinRoomEvents.JoinRoom -> { + val inviteData = contentState.toInviteData() ?: return acceptDeclineInviteState.eventSink( - AcceptDeclineInviteEvents.AcceptInvite(contentState.toInviteData()) + AcceptDeclineInviteEvents.AcceptInvite(inviteData) ) } JoinRoomEvents.DeclineInvite -> { + val inviteData = contentState.toInviteData() ?: return acceptDeclineInviteState.eventSink( - AcceptDeclineInviteEvents.DeclineInvite(contentState.toInviteData()) + AcceptDeclineInviteEvents.DeclineInvite(inviteData) ) } } @@ -82,66 +85,69 @@ class JoinRoomPresenter @AssistedInject constructor( return JoinRoomState( contentState = contentState, - joinAuthorisationStatus = joinAuthorisationStatus, acceptDeclineInviteState = acceptDeclineInviteState, eventSink = ::handleEvents ) } +} - private fun RoomDescription.toContentState(): ContentState { - return ContentState( - roomId = roomId, - name = name, - description = description, - numberOfMembers = numberOfMembers, - isDirect = false, - roomAvatarUrl = avatarUrl - ) - } - - private fun MatrixRoomInfo.toContentState(): ContentState { - fun title(): String { - return name ?: canonicalAlias ?: roomId.value - } - - fun description(): String? { - val topic = topic - val alias = canonicalAlias - val name = name - return when { - topic != null -> topic - name != null && alias != null -> alias - name == null && alias == null -> null - else -> roomId.value - } +@VisibleForTesting +internal fun RoomDescription.toContentState(): ContentState { + return ContentState( + roomId = roomId, + name = name, + description = description, + numberOfMembers = numberOfMembers, + isDirect = false, + roomAvatarUrl = avatarUrl, + joinAuthorisationStatus = when (joinRule) { + RoomDescription.JoinRule.KNOCK -> JoinAuthorisationStatus.CanKnock + RoomDescription.JoinRule.PUBLIC -> JoinAuthorisationStatus.CanJoin + else -> JoinAuthorisationStatus.Unknown } + ) +} - return ContentState( - roomId = roomId, - name = title(), - description = description(), - numberOfMembers = activeMembersCount, - isDirect = isDirect, - roomAvatarUrl = avatarUrl - ) +@VisibleForTesting +internal fun MatrixRoomInfo.toContentState(): ContentState { + fun title(): String { + return name ?: canonicalAlias ?: id } - private fun AsyncData.toInviteData(): InviteData { - return dataOrNull().let { - InviteData( - roomId = roomId, - roomName = it?.name ?: "", - isDirect = it?.isDirect ?: false - ) + fun description(): String? { + val topic = topic + val alias = canonicalAlias + val name = name + return when { + topic != null -> topic + name != null && alias != null -> alias + name == null && alias == null -> null + else -> id } } - @Composable - private fun joinAuthorisationStatus(roomInfo: Optional): JoinAuthorisationStatus { - val userMembership = roomInfo.getOrNull()?.currentUserMembership - return when { - userMembership == CurrentUserMembership.INVITED -> return JoinAuthorisationStatus.IsInvited + return ContentState( + roomId = RoomId(id), + name = title(), + description = description(), + numberOfMembers = activeMembersCount, + isDirect = isDirect, + roomAvatarUrl = avatarUrl, + joinAuthorisationStatus = when { + currentUserMembership == CurrentUserMembership.INVITED -> JoinAuthorisationStatus.IsInvited + isPublic -> JoinAuthorisationStatus.CanJoin else -> JoinAuthorisationStatus.Unknown } + ) +} + +@VisibleForTesting +internal fun AsyncData.toInviteData(): InviteData? { + return dataOrNull()?.let { contentState -> + InviteData( + roomId = contentState.roomId, + roomName = contentState.name, + isDirect = contentState.isDirect + ) } } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt index 73218bf7ba..c8211feb0d 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt @@ -26,10 +26,11 @@ import io.element.android.libraries.matrix.api.core.RoomId @Immutable data class JoinRoomState( val contentState: AsyncData, - val joinAuthorisationStatus: JoinAuthorisationStatus, val acceptDeclineInviteState: AcceptDeclineInviteState, val eventSink: (JoinRoomEvents) -> Unit -) +) { + val joinAuthorisationStatus = contentState.dataOrNull()?.joinAuthorisationStatus ?: JoinAuthorisationStatus.Unknown +} data class ContentState( val roomId: RoomId, @@ -38,6 +39,7 @@ data class ContentState( val numberOfMembers: Long?, val isDirect: Boolean, val roomAvatarUrl: String?, + val joinAuthorisationStatus: JoinAuthorisationStatus, ) { val showMemberCount = numberOfMembers != null diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt index a1c77a7de2..994f914a19 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt @@ -29,34 +29,49 @@ open class JoinRoomStateProvider : PreviewParameterProvider { contentState = AsyncData.Uninitialized ), aJoinRoomState( - joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin + contentState = AsyncData.Success( + aContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin) + ) ), aJoinRoomState( - joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock + contentState = AsyncData.Success( + aContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock) + ) ), aJoinRoomState( - joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited + contentState = AsyncData.Success( + aContentState(joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited) + ) ), ) } +fun aContentState( + roomId: RoomId = RoomId("@exa:matrix.org"), + name: String = "Element x android", + description: String? = "#exa:matrix.org", + numberOfMembers: Long? = null, + isDirect: Boolean = false, + roomAvatarUrl: String? = null, + joinAuthorisationStatus: JoinAuthorisationStatus = JoinAuthorisationStatus.Unknown +) = ContentState( + roomId = roomId, + name = name, + description = description, + numberOfMembers = numberOfMembers, + isDirect = isDirect, + roomAvatarUrl = roomAvatarUrl, + joinAuthorisationStatus = joinAuthorisationStatus +) + fun aJoinRoomState( contentState: AsyncData = AsyncData.Success( - ContentState( - roomId = RoomId("@exa:matrix.org"), - name = "Element x android", - description = "#exa:matrix.org", - numberOfMembers = null, - isDirect = false, - roomAvatarUrl = null - ) + aContentState() ), - joinAuthorisationStatus: JoinAuthorisationStatus = JoinAuthorisationStatus.Unknown, acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(), eventSink: (JoinRoomEvents) -> Unit = {} ) = JoinRoomState( contentState = contentState, - joinAuthorisationStatus = joinAuthorisationStatus, acceptDeclineInviteState = acceptDeclineInviteState, eventSink = eventSink ) diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt index ca16b12880..5cef755af2 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt @@ -109,8 +109,7 @@ private fun JoinRoomFooter( ) } } - // TODO handle all cases properly - else -> { + JoinAuthorisationStatus.CanJoin -> { Button( text = stringResource(CommonStrings.action_join), onClick = onJoinRoom, @@ -118,6 +117,18 @@ private fun JoinRoomFooter( size = ButtonSize.Medium, ) } + JoinAuthorisationStatus.CanKnock -> { + //TODO knock + /* + Button( + text = stringResource(CommonStrings.action_knock), + onClick = onJoinRoom, + modifier = modifier.fillMaxWidth(), + size = ButtonSize.Medium, + ) + */ + } + JoinAuthorisationStatus.Unknown -> Unit } } @@ -154,8 +165,8 @@ private fun JoinRoomContent( Column( modifier = modifier - .fillMaxWidth() - .padding(all = 16.dp), + .fillMaxWidth() + .padding(all = 16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { when (asyncContentState) { @@ -191,9 +202,9 @@ private fun JoinRoomMembersCount(memberCount: Long) { Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier - .background(color = ElementTheme.colors.bgSubtleSecondary, shape = CircleShape) - .widthIn(min = 48.dp) - .padding(all = 2.dp), + .background(color = ElementTheme.colors.bgSubtleSecondary, shape = CircleShape) + .widthIn(min = 48.dp) + .padding(all = 2.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp) ) { diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt new file mode 100644 index 0000000000..45dc4361c5 --- /dev/null +++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt @@ -0,0 +1,274 @@ +/* + * 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.joinroom.impl + +import com.google.common.truth.Truth.assertThat +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.anAcceptDeclineInviteState +import io.element.android.features.roomdirectory.api.RoomDescription +import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.CurrentUserMembership +import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_ROOM_NAME +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value +import io.element.android.tests.testutils.test +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test +import java.util.Optional + +class JoinRoomPresenterTest { + + @get:Rule + val warmUpRule = WarmUpRule() + + @Test + fun `present - initial state`() = runTest { + val presenter = createJoinRoomPresenter() + presenter.test { + awaitItem().also { state -> + assertThat(state.contentState).isInstanceOf(AsyncData.Uninitialized::class.java) + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.Unknown) + assertThat(state.acceptDeclineInviteState).isEqualTo(anAcceptDeclineInviteState()) + } + } + } + + @Test + fun `present - when room is joined then content state is filled with his data`() = runTest { + val roomInfo = aRoomInfo() + val matrixClient = FakeMatrixClient().apply { + getRoomInfoFlowLambda = { _ -> + flowOf(Optional.of(roomInfo)) + } + } + val presenter = createJoinRoomPresenter( + matrixClient = matrixClient + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.contentState).isInstanceOf(AsyncData.Success::class.java) + val contentState = state.contentState.dataOrNull()!! + assertThat(contentState.roomId).isEqualTo(A_ROOM_ID) + assertThat(contentState.name).isEqualTo(roomInfo.name) + assertThat(contentState.description).isEqualTo(roomInfo.topic) + assertThat(contentState.numberOfMembers).isEqualTo(roomInfo.activeMembersCount) + assertThat(contentState.isDirect).isEqualTo(roomInfo.isDirect) + assertThat(contentState.roomAvatarUrl).isEqualTo(roomInfo.avatarUrl) + } + } + } + + @Test + fun `present - when room is invited then join authorization is equal to invited`() = runTest { + val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.INVITED) + val matrixClient = FakeMatrixClient().apply { + getRoomInfoFlowLambda = { _ -> + flowOf(Optional.of(roomInfo)) + } + } + val presenter = createJoinRoomPresenter( + matrixClient = matrixClient + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.IsInvited) + } + } + } + + @Test + fun `present - when room is invited then accept and decline events are sent to acceptDeclinePresenter`() = runTest { + val eventSinkRecorder = lambdaRecorder { _: AcceptDeclineInviteEvents -> } + val acceptDeclinePresenter = Presenter { + anAcceptDeclineInviteState(eventSink = eventSinkRecorder) + } + val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.INVITED) + val matrixClient = FakeMatrixClient().apply { + getRoomInfoFlowLambda = { _ -> + flowOf(Optional.of(roomInfo)) + } + } + val presenter = createJoinRoomPresenter( + matrixClient = matrixClient, + acceptDeclineInvitePresenter = acceptDeclinePresenter + ) + presenter.test { + skipItems(1) + + awaitItem().also { state -> + state.eventSink(JoinRoomEvents.AcceptInvite) + state.eventSink(JoinRoomEvents.DeclineInvite) + + val inviteData = state.contentState.toInviteData()!! + + assert(eventSinkRecorder) + .isCalledExactly(2) + .withSequence( + listOf(value(AcceptDeclineInviteEvents.AcceptInvite(inviteData))), + listOf(value(AcceptDeclineInviteEvents.DeclineInvite(inviteData))), + ) + + } + } + } + + @Test + fun `present - when room is left and public then join authorization is equal to canJoin`() = runTest { + val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.LEFT, isPublic = true) + val matrixClient = FakeMatrixClient().apply { + getRoomInfoFlowLambda = { _ -> + flowOf(Optional.of(roomInfo)) + } + } + val presenter = createJoinRoomPresenter( + matrixClient = matrixClient + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.CanJoin) + } + } + } + + @Test + fun `present - when room is left and not public then join authorization is equal to unknown`() = runTest { + val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.LEFT, isPublic = false) + val matrixClient = FakeMatrixClient().apply { + getRoomInfoFlowLambda = { _ -> + flowOf(Optional.of(roomInfo)) + } + } + val presenter = createJoinRoomPresenter( + matrixClient = matrixClient + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.Unknown) + } + } + } + + @Test + fun `present - when room description is provided and room is not found then content state is filled with data`() = runTest { + val roomDescription = aRoomDescription() + val presenter = createJoinRoomPresenter( + roomDescription = Optional.of(roomDescription) + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.contentState).isInstanceOf(AsyncData.Success::class.java) + val contentState = state.contentState.dataOrNull()!! + assertThat(contentState.roomId).isEqualTo(A_ROOM_ID) + assertThat(contentState.name).isEqualTo(roomDescription.name) + assertThat(contentState.description).isEqualTo(roomDescription.description) + assertThat(contentState.numberOfMembers).isEqualTo(roomDescription.numberOfMembers) + assertThat(contentState.isDirect).isFalse() + assertThat(contentState.roomAvatarUrl).isEqualTo(roomDescription.avatarUrl) + } + } + } + + @Test + fun `present - when room description join rule is Knock then join authorization is equal to canKnock`() = runTest { + val roomDescription = aRoomDescription(joinRule = RoomDescription.JoinRule.KNOCK) + val presenter = createJoinRoomPresenter( + roomDescription = Optional.of(roomDescription) + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.CanKnock) + } + } + } + + @Test + fun `present - when room description join rule is Public then join authorization is equal to canJoin`() = runTest { + val roomDescription = aRoomDescription(joinRule = RoomDescription.JoinRule.PUBLIC) + val presenter = createJoinRoomPresenter( + roomDescription = Optional.of(roomDescription) + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.CanJoin) + } + } + } + + @Test + fun `present - when room description join rule is Unknown then join authorization is equal to unknown`() = runTest { + val roomDescription = aRoomDescription(joinRule = RoomDescription.JoinRule.UNKNOWN) + val presenter = createJoinRoomPresenter( + roomDescription = Optional.of(roomDescription) + ) + presenter.test { + skipItems(1) + awaitItem().also { state -> + assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.Unknown) + } + } + } + + private fun createJoinRoomPresenter( + roomId: RoomId = A_ROOM_ID, + roomDescription: Optional = Optional.empty(), + matrixClient: MatrixClient = FakeMatrixClient(), + acceptDeclineInvitePresenter: Presenter = Presenter { anAcceptDeclineInviteState() } + ): JoinRoomPresenter { + return JoinRoomPresenter( + roomId = roomId, + roomDescription = roomDescription, + matrixClient = matrixClient, + acceptDeclineInvitePresenter = acceptDeclineInvitePresenter + ) + } + + private fun aRoomDescription( + roomId: RoomId = A_ROOM_ID, + name: String = A_ROOM_NAME, + description: String = "A room about something", + avatarUrl: String? = null, + joinRule: RoomDescription.JoinRule = RoomDescription.JoinRule.UNKNOWN, + numberOfMembers: Long = 2L + ): RoomDescription { + return RoomDescription( + roomId = roomId, + name = name, + description = description, + avatarUrl = avatarUrl, + joinRule = joinRule, + numberOfMembers = numberOfMembers + ) + } +} diff --git a/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDescription.kt b/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDescription.kt index bc0e9f48c1..a0a0e45a54 100644 --- a/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDescription.kt +++ b/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDescription.kt @@ -28,10 +28,18 @@ data class RoomDescription( val name: String, val description: String, val avatarUrl: String?, - val canBeJoined: Boolean, + val joinRule: JoinRule, val numberOfMembers: Long, ) : Parcelable { + enum class JoinRule { + PUBLIC, + KNOCK, + UNKNOWN + } + + fun canBeJoined() = joinRule == JoinRule.PUBLIC || joinRule == JoinRule.KNOCK + fun avatarData(size: AvatarSize) = AvatarData( id = roomId.value, name = name, diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryStateProvider.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryStateProvider.kt index 3178a06322..ccfdd4c1f1 100644 --- a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryStateProvider.kt +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryStateProvider.kt @@ -70,7 +70,7 @@ fun aRoomDescriptionList(): ImmutableList { name = "Element X Android", description = "Element X is a secure, private and decentralized messenger.", avatarUrl = null, - canBeJoined = true, + joinRule = RoomDescription.JoinRule.PUBLIC, numberOfMembers = 2765, ), RoomDescription( @@ -78,7 +78,7 @@ fun aRoomDescriptionList(): ImmutableList { name = "Element X iOS", description = "Element X is a secure, private and decentralized messenger.", avatarUrl = null, - canBeJoined = false, + joinRule = RoomDescription.JoinRule.UNKNOWN, numberOfMembers = 356, ) ) diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryView.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryView.kt index 6fe326bfb6..f1ea915c17 100644 --- a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryView.kt +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/RoomDirectoryView.kt @@ -274,7 +274,7 @@ private fun RoomDirectoryRoomRow( Row( modifier = modifier .fillMaxWidth() - .clickable(enabled = roomDescription.canBeJoined, onClick = onClick) + .clickable(onClick = onClick) .padding( top = 12.dp, bottom = 12.dp, @@ -306,7 +306,7 @@ private fun RoomDirectoryRoomRow( overflow = TextOverflow.Ellipsis, ) } - if (roomDescription.canBeJoined) { + if (roomDescription.canBeJoined()) { Text( text = stringResource(id = CommonStrings.action_join), color = ElementTheme.colors.textSuccessPrimary, diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/model/RoomDescription.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/model/RoomDescription.kt index 5ace7645aa..eec9f6acf9 100644 --- a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/model/RoomDescription.kt +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/root/model/RoomDescription.kt @@ -44,6 +44,10 @@ fun MatrixRoomDescription.toFeatureModel(): RoomDescription { description = description(), avatarUrl = avatarUrl, numberOfMembers = numberOfMembers, - canBeJoined = joinRule == MatrixRoomDescription.JoinRule.PUBLIC, + joinRule = when (joinRule) { + MatrixRoomDescription.JoinRule.PUBLIC -> RoomDescription.JoinRule.PUBLIC + MatrixRoomDescription.JoinRule.KNOCK -> RoomDescription.JoinRule.KNOCK + MatrixRoomDescription.JoinRule.UNKNOWN -> RoomDescription.JoinRule.UNKNOWN + } ) }