Browse Source

Add screen to render Spaces (they are not supported yet)

pull/2752/head
Benoit Marty 3 weeks ago committed by Benoit Marty
parent
commit
2c2bf7c687
  1. 10
      appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt
  2. 3
      features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt
  3. 1
      features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt
  4. 10
      features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt
  5. 36
      features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
  6. 3
      features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/JoinRoomModule.kt
  7. 2
      features/joinroom/impl/src/main/res/values/localazy.xml
  8. 5
      features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt
  9. 16
      features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt
  10. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewSubtitleAtom.kt

10
appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt

@ -128,7 +128,15 @@ class RoomFlowNode @AssistedInject constructor( @@ -128,7 +128,15 @@ class RoomFlowNode @AssistedInject constructor(
Timber.d("Room membership: ${roomInfo.map { it.currentUserMembership }}")
val info = roomInfo.getOrNull()
if (info?.currentUserMembership == CurrentUserMembership.JOINED) {
backstack.newRoot(NavTarget.JoinedRoom(roomId))
if (info.isSpace) {
// It should not happen, but probably due to an issue in the sliding sync,
// we can have a space here in case the space has just been joined.
// So navigate to the JoinRoom target for now, which will
// handle the space not supported screen
backstack.newRoot(NavTarget.JoinRoom(roomId))
} else {
backstack.newRoot(NavTarget.JoinedRoom(roomId))
}
} else {
backstack.newRoot(NavTarget.JoinRoom(roomId))
}

3
features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt

@ -37,6 +37,7 @@ import io.element.android.features.roomdirectory.api.RoomDescription @@ -37,6 +37,7 @@ import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
@ -57,6 +58,7 @@ class JoinRoomPresenter @AssistedInject constructor( @@ -57,6 +58,7 @@ class JoinRoomPresenter @AssistedInject constructor(
private val matrixClient: MatrixClient,
private val knockRoom: KnockRoom,
private val acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
private val buildMeta: BuildMeta,
) : Presenter<JoinRoomState> {
interface Factory {
fun create(
@ -135,6 +137,7 @@ class JoinRoomPresenter @AssistedInject constructor( @@ -135,6 +137,7 @@ class JoinRoomPresenter @AssistedInject constructor(
contentState = contentState,
acceptDeclineInviteState = acceptDeclineInviteState,
knockAction = knockAction.value,
applicationName = buildMeta.applicationName,
eventSink = ::handleEvents
)
}

1
features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt

@ -32,6 +32,7 @@ data class JoinRoomState( @@ -32,6 +32,7 @@ data class JoinRoomState(
val contentState: ContentState,
val acceptDeclineInviteState: AcceptDeclineInviteState,
val knockAction: AsyncAction<Unit>,
val applicationName: String,
val eventSink: (JoinRoomEvents) -> Unit
) {
val joinAuthorisationStatus = when (contentState) {

10
features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt

@ -75,6 +75,15 @@ open class JoinRoomStateProvider : PreviewParameterProvider<JoinRoomState> { @@ -75,6 +75,15 @@ open class JoinRoomStateProvider : PreviewParameterProvider<JoinRoomState> {
aJoinRoomState(
contentState = aFailureContentState(roomIdOrAlias = A_ROOM_ALIAS.toRoomIdOrAlias())
),
aJoinRoomState(
contentState = aLoadedContentState(
roomId = RoomId("!aSpaceId:domain"),
name = "A space",
alias = null,
topic = "This is the topic of a space",
roomType = RoomType.Space,
)
),
)
}
@ -122,6 +131,7 @@ fun aJoinRoomState( @@ -122,6 +131,7 @@ fun aJoinRoomState(
contentState = contentState,
acceptDeclineInviteState = acceptDeclineInviteState,
knockAction = knockAction,
applicationName = "AppName",
eventSink = eventSink
)

36
features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt

@ -20,8 +20,10 @@ import androidx.compose.foundation.layout.Arrangement @@ -20,8 +20,10 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@ -33,6 +35,7 @@ import androidx.compose.ui.text.font.FontStyle @@ -33,6 +35,7 @@ import androidx.compose.ui.text.font.FontStyle
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.libraries.designsystem.atomic.atoms.PlaceholderAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescriptionAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewSubtitleAtom
@ -55,6 +58,7 @@ import io.element.android.libraries.designsystem.theme.components.OutlinedButton @@ -55,6 +58,7 @@ import io.element.android.libraries.designsystem.theme.components.OutlinedButton
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.RoomIdOrAlias
import io.element.android.libraries.matrix.api.room.RoomType
import io.element.android.libraries.matrix.ui.components.InviteSenderView
import io.element.android.libraries.ui.strings.CommonStrings
@ -76,7 +80,10 @@ fun JoinRoomView( @@ -76,7 +80,10 @@ fun JoinRoomView(
JoinRoomTopBar(onBackClicked = onBackPressed)
},
content = {
JoinRoomContent(contentState = state.contentState)
JoinRoomContent(
contentState = state.contentState,
applicationName = state.applicationName,
)
},
footer = {
JoinRoomFooter(
@ -95,7 +102,8 @@ fun JoinRoomView( @@ -95,7 +102,8 @@ fun JoinRoomView(
},
onRetry = {
state.eventSink(JoinRoomEvents.RetryFetchingContent)
}
},
onGoBack = onBackPressed,
)
}
)
@ -116,6 +124,7 @@ private fun JoinRoomFooter( @@ -116,6 +124,7 @@ private fun JoinRoomFooter(
onJoinRoom: () -> Unit,
onKnockRoom: () -> Unit,
onRetry: () -> Unit,
onGoBack: () -> Unit,
modifier: Modifier = Modifier,
) {
if (state.contentState is ContentState.Failure) {
@ -125,6 +134,13 @@ private fun JoinRoomFooter( @@ -125,6 +134,13 @@ private fun JoinRoomFooter(
modifier = modifier.fillMaxWidth(),
size = ButtonSize.Large,
)
} else if (state.contentState is ContentState.Loaded && state.contentState.roomType == RoomType.Space) {
Button(
text = stringResource(CommonStrings.action_go_back),
onClick = onGoBack,
modifier = modifier.fillMaxWidth(),
size = ButtonSize.Large,
)
} else {
val joinAuthorisationStatus = state.joinAuthorisationStatus
when (joinAuthorisationStatus) {
@ -171,6 +187,7 @@ private fun JoinRoomFooter( @@ -171,6 +187,7 @@ private fun JoinRoomFooter(
@Composable
private fun JoinRoomContent(
contentState: ContentState,
applicationName: String,
modifier: Modifier = Modifier,
) {
when (contentState) {
@ -211,6 +228,21 @@ private fun JoinRoomContent( @@ -211,6 +228,21 @@ private fun JoinRoomContent(
InviteSenderView(inviteSender = inviteSender)
}
RoomPreviewDescriptionAtom(contentState.topic ?: "")
if (contentState.roomType == RoomType.Space) {
Spacer(modifier = Modifier.height(24.dp))
Text(
text = stringResource(R.string.screen_join_room_space_not_supported_title),
textAlign = TextAlign.Center,
style = ElementTheme.typography.fontBodyLgMedium,
color = MaterialTheme.colorScheme.primary,
)
Text(
text = stringResource(R.string.screen_join_room_space_not_supported_description, applicationName),
textAlign = TextAlign.Center,
style = ElementTheme.typography.fontBodyMdRegular,
color = MaterialTheme.colorScheme.secondary,
)
}
}
},
memberCount = {

3
features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/di/JoinRoomModule.kt

@ -23,6 +23,7 @@ import io.element.android.features.invite.api.response.AcceptDeclineInviteState @@ -23,6 +23,7 @@ import io.element.android.features.invite.api.response.AcceptDeclineInviteState
import io.element.android.features.joinroom.impl.JoinRoomPresenter
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
@ -37,6 +38,7 @@ object JoinRoomModule { @@ -37,6 +38,7 @@ object JoinRoomModule {
client: MatrixClient,
knockRoom: KnockRoom,
acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
buildMeta: BuildMeta,
): JoinRoomPresenter.Factory {
return object : JoinRoomPresenter.Factory {
override fun create(
@ -51,6 +53,7 @@ object JoinRoomModule { @@ -51,6 +53,7 @@ object JoinRoomModule {
matrixClient = client,
knockRoom = knockRoom,
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
buildMeta = buildMeta,
)
}
}

2
features/joinroom/impl/src/main/res/values/localazy.xml

@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_join_action">"Join room"</string>
<string name="screen_join_room_knock_action">"Knock to join"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s does not support spaces yet. You can access spaces on web."</string>
<string name="screen_join_room_space_not_supported_title">"Spaces are not supported yet"</string>
<string name="screen_join_room_subtitle_knock">"Click the button below and a room administrator will be notified. You’ll be able to join the conversation once approved."</string>
<string name="screen_join_room_subtitle_no_preview">"You must be a member of this room to view the message history."</string>
<string name="screen_join_room_title_knock">"Want to join this room?"</string>

5
features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt

@ -24,6 +24,7 @@ import io.element.android.features.joinroom.impl.di.KnockRoom @@ -24,6 +24,7 @@ import io.element.android.features.joinroom.impl.di.KnockRoom
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
@ -36,6 +37,7 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION @@ -36,6 +37,7 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION
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.core.aBuildMeta
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.ui.model.toInviteSender
@ -62,6 +64,7 @@ class JoinRoomPresenterTest { @@ -62,6 +64,7 @@ class JoinRoomPresenterTest {
assertThat(state.contentState).isEqualTo(ContentState.Loading(A_ROOM_ID.toRoomIdOrAlias()))
assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.Unknown)
assertThat(state.acceptDeclineInviteState).isEqualTo(anAcceptDeclineInviteState())
assertThat(state.applicationName).isEqualTo("AppName")
cancelAndIgnoreRemainingEvents()
}
}
@ -414,6 +417,7 @@ class JoinRoomPresenterTest { @@ -414,6 +417,7 @@ class JoinRoomPresenterTest {
roomDescription: Optional<RoomDescription> = Optional.empty(),
matrixClient: MatrixClient = FakeMatrixClient(),
knockRoom: KnockRoom = FakeKnockRoom(),
buildMeta: BuildMeta = aBuildMeta(applicationName = "AppName"),
acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState> = Presenter { anAcceptDeclineInviteState() }
): JoinRoomPresenter {
return JoinRoomPresenter(
@ -422,6 +426,7 @@ class JoinRoomPresenterTest { @@ -422,6 +426,7 @@ class JoinRoomPresenterTest {
roomDescription = roomDescription,
matrixClient = matrixClient,
knockRoom = knockRoom,
buildMeta = buildMeta,
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter
)
}

16
features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomViewTest.kt

@ -21,6 +21,7 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule @@ -21,6 +21,7 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.room.RoomType
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.tests.testutils.EnsureNeverCalled
import io.element.android.tests.testutils.EventsRecorder
@ -128,6 +129,21 @@ class JoinRoomViewTest { @@ -128,6 +129,21 @@ class JoinRoomViewTest {
rule.clickOn(CommonStrings.action_retry)
eventsRecorder.assertSingle(JoinRoomEvents.RetryFetchingContent)
}
@Test
fun `clicking on Go back when a space is displayed invokes the expected callback`() {
val eventsRecorder = EventsRecorder<JoinRoomEvents>(expectEvents = false)
ensureCalledOnce {
rule.setJoinRoomView(
aJoinRoomState(
contentState = aLoadedContentState(roomType = RoomType.Space),
eventSink = eventsRecorder,
),
onBackPressed = it
)
rule.clickOn(CommonStrings.action_go_back)
}
}
}
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setJoinRoomView(

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewSubtitleAtom.kt

@ -27,7 +27,7 @@ fun RoomPreviewSubtitleAtom(subtitle: String, modifier: Modifier = Modifier) { @@ -27,7 +27,7 @@ fun RoomPreviewSubtitleAtom(subtitle: String, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
text = subtitle,
style = ElementTheme.typography.fontBodyLgRegular,
style = ElementTheme.typography.fontBodyMdRegular,
textAlign = TextAlign.Center,
color = ElementTheme.colors.textSecondary,
)

Loading…
Cancel
Save