Room navigation : some clean up
This commit is contained in:
parent
c0918bd965
commit
8b80b2859f
28 changed files with 107 additions and 142 deletions
|
|
@ -18,17 +18,16 @@ package io.element.android.features.invite.impl.invitelist
|
||||||
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import io.element.android.features.invite.api.response.AcceptDeclineInviteState
|
import io.element.android.features.invite.api.response.AcceptDeclineInviteState
|
||||||
import io.element.android.features.invite.impl.model.InviteListInviteSummary
|
|
||||||
import io.element.android.features.invite.impl.model.InviteSender
|
|
||||||
import io.element.android.features.invite.api.response.AcceptDeclineInviteStateProvider
|
import io.element.android.features.invite.api.response.AcceptDeclineInviteStateProvider
|
||||||
import io.element.android.features.invite.api.response.anAcceptDeclineInviteState
|
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.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
open class InviteListStateProvider : PreviewParameterProvider<InviteListState> {
|
open class InviteListStateProvider : PreviewParameterProvider<InviteListState> {
|
||||||
|
|
||||||
private val acceptDeclineInviteStateProvider = AcceptDeclineInviteStateProvider()
|
private val acceptDeclineInviteStateProvider = AcceptDeclineInviteStateProvider()
|
||||||
|
|
||||||
override val values: Sequence<InviteListState>
|
override val values: Sequence<InviteListState>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
|
||||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||||
import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents
|
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.AcceptDeclineInviteState
|
||||||
|
|
@ -32,7 +31,6 @@ import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||||
import io.element.android.libraries.architecture.runUpdatingState
|
import io.element.android.libraries.architecture.runUpdatingState
|
||||||
import io.element.android.libraries.di.SessionScope
|
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
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.RoomId
|
||||||
import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
|
import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
|
||||||
|
|
@ -49,10 +47,8 @@ class AcceptDeclineInvitePresenter @Inject constructor(
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
private val notificationDrawerManager: NotificationDrawerManager,
|
private val notificationDrawerManager: NotificationDrawerManager,
|
||||||
) : Presenter<AcceptDeclineInviteState> {
|
) : Presenter<AcceptDeclineInviteState> {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): AcceptDeclineInviteState {
|
override fun present(): AcceptDeclineInviteState {
|
||||||
|
|
||||||
val localCoroutineScope = rememberCoroutineScope()
|
val localCoroutineScope = rememberCoroutineScope()
|
||||||
val acceptedAction: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
val acceptedAction: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||||
val declinedAction: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
val declinedAction: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import javax.inject.Inject
|
||||||
|
|
||||||
@ContributesBinding(SessionScope::class)
|
@ContributesBinding(SessionScope::class)
|
||||||
class AcceptDeclineInviteViewWrapper @Inject constructor() : AcceptDeclineInviteView {
|
class AcceptDeclineInviteViewWrapper @Inject constructor() : AcceptDeclineInviteView {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Render(
|
override fun Render(
|
||||||
state: AcceptDeclineInviteState,
|
state: AcceptDeclineInviteState,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ package io.element.android.features.invite.impl.response
|
||||||
|
|
||||||
import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents
|
import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents
|
||||||
|
|
||||||
sealed interface InternalAcceptDeclineInviteEvents: AcceptDeclineInviteEvents {
|
sealed interface InternalAcceptDeclineInviteEvents : AcceptDeclineInviteEvents {
|
||||||
data object ConfirmDeclineInvite : InternalAcceptDeclineInviteEvents
|
data object ConfirmDeclineInvite : InternalAcceptDeclineInviteEvents
|
||||||
data object CancelDeclineInvite : InternalAcceptDeclineInviteEvents
|
data object CancelDeclineInvite : InternalAcceptDeclineInviteEvents
|
||||||
data object DismissAcceptError : InternalAcceptDeclineInviteEvents
|
data object DismissAcceptError : InternalAcceptDeclineInviteEvents
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,7 @@ import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.invite.api.SeenInvitesStore
|
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.AcceptDeclineInviteState
|
||||||
import io.element.android.features.invite.api.response.anAcceptDeclineInviteState
|
import io.element.android.features.invite.api.response.anAcceptDeclineInviteState
|
||||||
import io.element.android.features.invite.impl.invitelist.InviteListEvents
|
|
||||||
import io.element.android.features.invite.impl.invitelist.InviteListPresenter
|
|
||||||
import io.element.android.features.invite.impl.invitelist.InviteListState
|
|
||||||
import io.element.android.features.invite.test.FakeSeenInvitesStore
|
import io.element.android.features.invite.test.FakeSeenInvitesStore
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||||
|
|
@ -43,14 +39,9 @@ import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
import io.element.android.libraries.matrix.test.A_USER_NAME
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
|
||||||
import io.element.android.libraries.matrix.test.room.aRoomMember
|
import io.element.android.libraries.matrix.test.room.aRoomMember
|
||||||
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails
|
import io.element.android.libraries.matrix.test.room.aRoomSummaryDetails
|
||||||
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
|
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
|
||||||
import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
|
|
||||||
import io.element.android.libraries.push.test.notifications.FakeNotificationDrawerManager
|
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ import org.junit.Test
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
class AcceptDeclineInvitePresenterTest {
|
class AcceptDeclineInvitePresenterTest {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
interface JoinRoomEntryPoint : FeatureEntryPoint {
|
interface JoinRoomEntryPoint : FeatureEntryPoint {
|
||||||
|
|
||||||
fun createNode(parentNode: Node, buildContext: BuildContext, inputs: Inputs): Node
|
fun createNode(parentNode: Node, buildContext: BuildContext, inputs: Inputs): Node
|
||||||
|
|
||||||
data class Inputs(
|
data class Inputs(
|
||||||
|
|
@ -33,4 +32,3 @@ interface JoinRoomEntryPoint : FeatureEntryPoint {
|
||||||
val roomDescription: Optional<RoomDescription>,
|
val roomDescription: Optional<RoomDescription>,
|
||||||
) : NodeInputs
|
) : NodeInputs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ dependencies {
|
||||||
implementation(projects.features.roomdirectory.api)
|
implementation(projects.features.roomdirectory.api)
|
||||||
implementation(projects.libraries.uiStrings)
|
implementation(projects.libraries.uiStrings)
|
||||||
|
|
||||||
|
|
||||||
testImplementation(libs.test.junit)
|
testImplementation(libs.test.junit)
|
||||||
testImplementation(libs.coroutines.test)
|
testImplementation(libs.coroutines.test)
|
||||||
testImplementation(libs.molecule.runtime)
|
testImplementation(libs.molecule.runtime)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import javax.inject.Inject
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultJoinRoomEntryPoint @Inject constructor() : JoinRoomEntryPoint {
|
class DefaultJoinRoomEntryPoint @Inject constructor() : JoinRoomEntryPoint {
|
||||||
|
|
||||||
override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: JoinRoomEntryPoint.Inputs): Node {
|
override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: JoinRoomEntryPoint.Inputs): Node {
|
||||||
return parentNode.createNode<JoinRoomNode>(
|
return parentNode.createNode<JoinRoomNode>(
|
||||||
buildContext = buildContext,
|
buildContext = buildContext,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
package io.element.android.features.joinroom.impl
|
package io.element.android.features.joinroom.impl
|
||||||
|
|
||||||
sealed interface JoinRoomEvents {
|
sealed interface JoinRoomEvents {
|
||||||
data object JoinRoom: JoinRoomEvents
|
data object JoinRoom : JoinRoomEvents
|
||||||
data object AcceptInvite : JoinRoomEvents
|
data object AcceptInvite : JoinRoomEvents
|
||||||
data object DeclineInvite : JoinRoomEvents
|
data object DeclineInvite : JoinRoomEvents
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ class JoinRoomNode @AssistedInject constructor(
|
||||||
presenterFactory: JoinRoomPresenter.Factory,
|
presenterFactory: JoinRoomPresenter.Factory,
|
||||||
private val acceptDeclineInviteView: AcceptDeclineInviteView,
|
private val acceptDeclineInviteView: AcceptDeclineInviteView,
|
||||||
) : Node(buildContext, plugins = plugins) {
|
) : Node(buildContext, plugins = plugins) {
|
||||||
|
|
||||||
private val inputs: JoinRoomEntryPoint.Inputs = inputs()
|
private val inputs: JoinRoomEntryPoint.Inputs = inputs()
|
||||||
private val presenter = presenterFactory.create(inputs.roomId, inputs.roomDescription)
|
private val presenter = presenterFactory.create(inputs.roomId, inputs.roomDescription)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ class JoinRoomPresenter @AssistedInject constructor(
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
private val acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
|
private val acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
|
||||||
) : Presenter<JoinRoomState> {
|
) : Presenter<JoinRoomState> {
|
||||||
|
|
||||||
interface Factory {
|
interface Factory {
|
||||||
fun create(roomId: RoomId, roomDescription: Optional<RoomDescription>): JoinRoomPresenter
|
fun create(roomId: RoomId, roomDescription: Optional<RoomDescription>): JoinRoomPresenter
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ data class JoinRoomState(
|
||||||
val acceptDeclineInviteState: AcceptDeclineInviteState,
|
val acceptDeclineInviteState: AcceptDeclineInviteState,
|
||||||
val eventSink: (JoinRoomEvents) -> Unit
|
val eventSink: (JoinRoomEvents) -> Unit
|
||||||
) {
|
) {
|
||||||
val joinAuthorisationStatus = when(contentState) {
|
val joinAuthorisationStatus = when (contentState) {
|
||||||
is ContentState.Loaded -> contentState.joinAuthorisationStatus
|
is ContentState.Loaded -> contentState.joinAuthorisationStatus
|
||||||
else -> JoinAuthorisationStatus.Unknown
|
else -> JoinAuthorisationStatus.Unknown
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,4 +75,3 @@ fun aJoinRoomState(
|
||||||
acceptDeclineInviteState = acceptDeclineInviteState,
|
acceptDeclineInviteState = acceptDeclineInviteState,
|
||||||
eventSink = eventSink
|
eventSink = eventSink
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.element.android.features.joinroom.impl
|
package io.element.android.features.joinroom.impl
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -32,7 +31,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
|
@ -138,59 +136,56 @@ private fun JoinRoomContent(
|
||||||
contentState: ContentState,
|
contentState: ContentState,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
when (contentState) {
|
||||||
Column(
|
is ContentState.Loaded -> {
|
||||||
modifier = modifier.fillMaxWidth(),
|
ContentScaffold(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
modifier = modifier,
|
||||||
) {
|
avatar = {
|
||||||
when (contentState) {
|
Avatar(contentState.avatarData(AvatarSize.RoomHeader))
|
||||||
is ContentState.Loaded -> {
|
},
|
||||||
ContentScaffold(
|
title = {
|
||||||
avatar = {
|
Title(contentState.computedTitle)
|
||||||
Avatar(contentState.avatarData(AvatarSize.RoomHeader))
|
},
|
||||||
},
|
subtitle = {
|
||||||
title = {
|
Subtitle(contentState.computedSubtitle)
|
||||||
Title(contentState.computedTitle)
|
},
|
||||||
},
|
description = {
|
||||||
subtitle = {
|
Description(contentState.topic ?: "")
|
||||||
Subtitle(contentState.computedSubtitle)
|
},
|
||||||
},
|
memberCount = {
|
||||||
description = {
|
if (contentState.showMemberCount) {
|
||||||
Description(contentState.topic ?: "")
|
MembersCount(memberCount = contentState.numberOfMembers ?: 0)
|
||||||
},
|
|
||||||
memberCount = {
|
|
||||||
if (contentState.showMemberCount) {
|
|
||||||
MembersCount(memberCount = contentState.numberOfMembers ?: 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
is ContentState.UnknownRoom -> {
|
}
|
||||||
ContentScaffold(
|
is ContentState.UnknownRoom -> {
|
||||||
avatar = {
|
ContentScaffold(
|
||||||
PlaceholderAtom(width = AvatarSize.RoomHeader.dp, height = AvatarSize.RoomHeader.dp)
|
modifier = modifier,
|
||||||
},
|
avatar = {
|
||||||
title = {
|
PlaceholderAtom(width = AvatarSize.RoomHeader.dp, height = AvatarSize.RoomHeader.dp)
|
||||||
Title(stringResource(R.string.screen_join_room_title_no_preview))
|
},
|
||||||
},
|
title = {
|
||||||
subtitle = {
|
Title(stringResource(R.string.screen_join_room_title_no_preview))
|
||||||
Subtitle(stringResource(R.string.screen_join_room_subtitle_no_preview))
|
},
|
||||||
},
|
subtitle = {
|
||||||
)
|
Subtitle(stringResource(R.string.screen_join_room_subtitle_no_preview))
|
||||||
}
|
},
|
||||||
is ContentState.Loading -> {
|
)
|
||||||
ContentScaffold(
|
}
|
||||||
avatar = {
|
is ContentState.Loading -> {
|
||||||
PlaceholderAtom(width = AvatarSize.RoomHeader.dp, height = AvatarSize.RoomHeader.dp)
|
ContentScaffold(
|
||||||
},
|
modifier = modifier,
|
||||||
title = {
|
avatar = {
|
||||||
PlaceholderAtom(width = 200.dp, height = 22.dp)
|
PlaceholderAtom(width = AvatarSize.RoomHeader.dp, height = AvatarSize.RoomHeader.dp)
|
||||||
},
|
},
|
||||||
subtitle = {
|
title = {
|
||||||
PlaceholderAtom(width = 140.dp, height = 20.dp)
|
PlaceholderAtom(width = 200.dp, height = 22.dp)
|
||||||
},
|
},
|
||||||
)
|
subtitle = {
|
||||||
}
|
PlaceholderAtom(width = 140.dp, height = 20.dp)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -200,23 +195,29 @@ private fun ContentScaffold(
|
||||||
avatar: @Composable () -> Unit,
|
avatar: @Composable () -> Unit,
|
||||||
title: @Composable () -> Unit,
|
title: @Composable () -> Unit,
|
||||||
subtitle: @Composable () -> Unit,
|
subtitle: @Composable () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
description: @Composable (() -> Unit)? = null,
|
description: @Composable (() -> Unit)? = null,
|
||||||
memberCount: @Composable (() -> Unit)? = null,
|
memberCount: @Composable (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
avatar()
|
Column(
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
modifier = modifier.fillMaxWidth(),
|
||||||
title()
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
) {
|
||||||
subtitle()
|
avatar()
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
if (memberCount != null) {
|
title()
|
||||||
memberCount()
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
subtitle()
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
if (memberCount != null) {
|
||||||
|
memberCount()
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
if (description != null) {
|
||||||
|
description()
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
if (description != null) {
|
|
||||||
description()
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -256,12 +257,11 @@ private fun Description(description: String, modifier: Modifier = Modifier) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun MembersCount(memberCount: Long) {
|
private fun MembersCount(memberCount: Long) {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(color = ElementTheme.colors.bgSubtleSecondary, shape = CircleShape)
|
.background(color = ElementTheme.colors.bgSubtleSecondary, shape = CircleShape)
|
||||||
.widthIn(min = 48.dp)
|
.widthIn(min = 48.dp)
|
||||||
.padding(all = 2.dp),
|
.padding(all = 2.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ import org.junit.Test
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
|
||||||
class JoinRoomPresenterTest {
|
class JoinRoomPresenterTest {
|
||||||
|
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
|
|
@ -136,7 +135,6 @@ class JoinRoomPresenterTest {
|
||||||
listOf(value(AcceptDeclineInviteEvents.AcceptInvite(inviteData))),
|
listOf(value(AcceptDeclineInviteEvents.AcceptInvite(inviteData))),
|
||||||
listOf(value(AcceptDeclineInviteEvents.DeclineInvite(inviteData))),
|
listOf(value(AcceptDeclineInviteEvents.DeclineInvite(inviteData))),
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ class LeaveRoomPresenterImplTest {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom().apply {
|
result = FakeMatrixRoom().apply {
|
||||||
this.leaveRoomLambda = { Result.failure(RuntimeException("Blimey!"))}
|
this.leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +210,7 @@ class LeaveRoomPresenterImplTest {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom().apply {
|
result = FakeMatrixRoom().apply {
|
||||||
this.leaveRoomLambda = { Result.failure(RuntimeException("Blimey!"))}
|
this.leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,9 @@ package io.element.android.features.location.impl.common.actions
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.location.api.Location
|
import io.element.android.features.location.api.Location
|
||||||
import org.junit.Ignore
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
@Ignore
|
|
||||||
internal class AndroidLocationActionsTest {
|
internal class AndroidLocationActionsTest {
|
||||||
// We use an Android-native encoder in the actual app, switch to an equivalent JVM one for the tests
|
// We use an Android-native encoder in the actual app, switch to an equivalent JVM one for the tests
|
||||||
private fun urlEncoder(input: String) = URLEncoder.encode(input, "US-ASCII")
|
private fun urlEncoder(input: String) = URLEncoder.encode(input, "US-ASCII")
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
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.RoomId
|
||||||
|
import kotlinx.parcelize.IgnoredOnParcel
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
|
@ -34,15 +35,16 @@ data class RoomDescription(
|
||||||
val joinRule: JoinRule,
|
val joinRule: JoinRule,
|
||||||
val numberOfMembers: Long,
|
val numberOfMembers: Long,
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
enum class JoinRule {
|
enum class JoinRule {
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
KNOCK,
|
KNOCK,
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoredOnParcel
|
||||||
val computedName = name ?: alias ?: roomId.value
|
val computedName = name ?: alias ?: roomId.value
|
||||||
|
|
||||||
|
@IgnoredOnParcel
|
||||||
val computedDescription: String
|
val computedDescription: String
|
||||||
get() {
|
get() {
|
||||||
return when {
|
return when {
|
||||||
|
|
@ -53,7 +55,8 @@ data class RoomDescription(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canBeJoined() = joinRule == JoinRule.PUBLIC || joinRule == JoinRule.KNOCK
|
@IgnoredOnParcel
|
||||||
|
val canJoinOrKnock = joinRule == JoinRule.PUBLIC || joinRule == JoinRule.KNOCK
|
||||||
|
|
||||||
fun avatarData(size: AvatarSize) = AvatarData(
|
fun avatarData(size: AvatarSize) = AvatarData(
|
||||||
id = roomId.value,
|
id = roomId.value,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ class RoomDirectoryNode @AssistedInject constructor(
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
private val presenter: RoomDirectoryPresenter,
|
private val presenter: RoomDirectoryPresenter,
|
||||||
) : Node(buildContext, plugins = plugins) {
|
) : Node(buildContext, plugins = plugins) {
|
||||||
|
|
||||||
private fun onResultClicked(roomDescription: RoomDescription) {
|
private fun onResultClicked(roomDescription: RoomDescription) {
|
||||||
plugins<RoomDirectoryEntryPoint.Callback>().forEach {
|
plugins<RoomDirectoryEntryPoint.Callback>().forEach {
|
||||||
it.onResultClicked(roomDescription)
|
it.onResultClicked(roomDescription)
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,8 @@ fun RoomDirectoryView(
|
||||||
onResultClicked = onResultClicked,
|
onResultClicked = onResultClicked,
|
||||||
onJoinClicked = ::joinRoom,
|
onJoinClicked = ::joinRoom,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
.padding(padding)
|
||||||
.consumeWindowInsets(padding)
|
.consumeWindowInsets(padding)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -199,10 +199,10 @@ private fun RoomDirectoryRoomList(
|
||||||
@Composable
|
@Composable
|
||||||
private fun LoadMoreIndicator(modifier: Modifier = Modifier) {
|
private fun LoadMoreIndicator(modifier: Modifier = Modifier) {
|
||||||
Box(
|
Box(
|
||||||
modifier
|
modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
.padding(24.dp),
|
.padding(24.dp),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
|
|
@ -273,14 +273,14 @@ private fun RoomDirectoryRoomRow(
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable(onClick = onClick)
|
.clickable(onClick = onClick)
|
||||||
.padding(
|
.padding(
|
||||||
top = 12.dp,
|
top = 12.dp,
|
||||||
bottom = 12.dp,
|
bottom = 12.dp,
|
||||||
start = 16.dp,
|
start = 16.dp,
|
||||||
)
|
)
|
||||||
.height(IntrinsicSize.Min),
|
.height(IntrinsicSize.Min),
|
||||||
) {
|
) {
|
||||||
Avatar(
|
Avatar(
|
||||||
avatarData = roomDescription.avatarData(AvatarSize.RoomDirectoryItem),
|
avatarData = roomDescription.avatarData(AvatarSize.RoomDirectoryItem),
|
||||||
|
|
@ -288,8 +288,8 @@ private fun RoomDirectoryRoomRow(
|
||||||
)
|
)
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(start = 16.dp)
|
.padding(start = 16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = roomDescription.computedName,
|
text = roomDescription.computedName,
|
||||||
|
|
@ -306,15 +306,15 @@ private fun RoomDirectoryRoomRow(
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (roomDescription.canBeJoined()) {
|
if (roomDescription.canJoinOrKnock) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = CommonStrings.action_join),
|
text = stringResource(id = CommonStrings.action_join),
|
||||||
color = ElementTheme.colors.textSuccessPrimary,
|
color = ElementTheme.colors.textSuccessPrimary,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
.clickable(onClick = onJoinClick)
|
.clickable(onClick = onJoinClick)
|
||||||
.padding(start = 4.dp, end = 12.dp)
|
.padding(start = 4.dp, end = 12.dp)
|
||||||
.testTag(TestTags.callToAction.value)
|
.testTag(TestTags.callToAction.value)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Spacer(modifier = Modifier.width(24.dp))
|
Spacer(modifier = Modifier.width(24.dp))
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import io.element.android.features.roomdirectory.api.RoomDescription
|
||||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomDescription as MatrixRoomDescription
|
import io.element.android.libraries.matrix.api.roomdirectory.RoomDescription as MatrixRoomDescription
|
||||||
|
|
||||||
fun MatrixRoomDescription.toFeatureModel(): RoomDescription {
|
fun MatrixRoomDescription.toFeatureModel(): RoomDescription {
|
||||||
|
|
||||||
return RoomDescription(
|
return RoomDescription(
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
name = name,
|
name = name,
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,9 @@
|
||||||
package io.element.android.features.roomdirectory.impl.root
|
package io.element.android.features.roomdirectory.impl.root
|
||||||
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||||
import androidx.compose.ui.test.onAllNodesWithTag
|
import androidx.compose.ui.test.onAllNodesWithTag
|
||||||
import androidx.compose.ui.test.onAllNodesWithText
|
|
||||||
import androidx.compose.ui.test.onChild
|
|
||||||
import androidx.compose.ui.test.onFirst
|
import androidx.compose.ui.test.onFirst
|
||||||
import androidx.compose.ui.test.onNodeWithTag
|
import androidx.compose.ui.test.onNodeWithTag
|
||||||
import androidx.compose.ui.test.onNodeWithText
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
|
|
@ -33,7 +30,6 @@ import io.element.android.features.roomdirectory.api.RoomDescription
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.testtags.TestTags
|
import io.element.android.libraries.testtags.TestTags
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
|
||||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||||
import io.element.android.tests.testutils.EnsureNeverCalledWithParam
|
import io.element.android.tests.testutils.EnsureNeverCalledWithParam
|
||||||
import io.element.android.tests.testutils.EventsRecorder
|
import io.element.android.tests.testutils.EventsRecorder
|
||||||
|
|
@ -74,7 +70,7 @@ class RoomDirectoryViewTest {
|
||||||
state = state,
|
state = state,
|
||||||
onResultClicked = callback,
|
onResultClicked = callback,
|
||||||
)
|
)
|
||||||
rule.onNodeWithText(clickedRoom.name).performClick()
|
rule.onNodeWithText(clickedRoom.computedName).performClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param modifier Classical modifier.
|
* @param modifier Classical modifier.
|
||||||
|
* @param paddingValues padding values to apply to the content.
|
||||||
* @param background optional background component.
|
* @param background optional background component.
|
||||||
* @param topBar optional topBar.
|
* @param topBar optional topBar.
|
||||||
* @param header optional header.
|
* @param header optional header.
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import io.element.android.libraries.matrix.api.notification.NotificationService
|
||||||
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
|
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
|
||||||
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
|
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
|
||||||
import io.element.android.libraries.matrix.api.pusher.PushersService
|
import io.element.android.libraries.matrix.api.pusher.PushersService
|
||||||
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
|
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||||
|
|
@ -100,4 +99,3 @@ interface MatrixClient : Closeable {
|
||||||
suspend fun trackRecentlyVisitedRoom(roomId: RoomId): Result<Unit>
|
suspend fun trackRecentlyVisitedRoom(roomId: RoomId): Result<Unit>
|
||||||
suspend fun getRecentlyVisitedRooms(): Result<List<RoomId>>
|
suspend fun getRecentlyVisitedRooms(): Result<List<RoomId>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,11 +79,8 @@ interface RoomListService {
|
||||||
* The state of the service as a flow.
|
* The state of the service as a flow.
|
||||||
*/
|
*/
|
||||||
val state: StateFlow<State>
|
val state: StateFlow<State>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RoomList.loadedStateFlow(): Flow<RoomList.LoadingState.Loaded> {
|
fun RoomList.loadedStateFlow(): Flow<RoomList.LoadingState.Loaded> {
|
||||||
return loadingState.filterIsInstance()
|
return loadingState.filterIsInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -276,5 +276,4 @@ class FakeMatrixClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRoomInfoFlow(roomId: RoomId) = getRoomInfoFlowLambda(roomId)
|
override fun getRoomInfoFlow(roomId: RoomId) = getRoomInfoFlowLambda(roomId)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ object TestTags {
|
||||||
val searchTextField = TestTag("search_text_field")
|
val searchTextField = TestTag("search_text_field")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic call to action
|
* Generic call to action.
|
||||||
*/
|
*/
|
||||||
val callToAction = TestTag("call_to_action")
|
val callToAction = TestTag("call_to_action")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue