Create a new room when inviting people in a DM (#6756)
* Create a new room when inviting people to a DM * Improve screenshot tests * Update screenshots --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
parent
f55b4d1283
commit
f678dffaed
26 changed files with 220 additions and 34 deletions
|
|
@ -263,7 +263,20 @@ class RoomDetailsFlowNode(
|
|||
}
|
||||
|
||||
NavTarget.InviteMembers -> {
|
||||
createNode<RoomInviteMembersNode>(buildContext)
|
||||
val callback = object : RoomInviteMembersNode.Callback {
|
||||
override fun openCreatedRoom(roomId: RoomId) {
|
||||
navigateUp()
|
||||
room.roomCoroutineScope.launch {
|
||||
callback.navigateToRoom(
|
||||
roomId = roomId,
|
||||
serverNames = emptyList(),
|
||||
// Remove the invite screen from the backstack to avoid navigating back to it after the new room has been created
|
||||
clearBackStack = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
createNode<RoomInviteMembersNode>(buildContext, plugins = listOf(callback))
|
||||
}
|
||||
|
||||
is NavTarget.RoomNotificationSettings -> {
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ fun aDmRoomDetailsState(
|
|||
roomName = roomName,
|
||||
isPublic = false,
|
||||
isEncrypted = isEncrypted,
|
||||
canInvite = true,
|
||||
roomType = RoomDetailsType.Dm(otherMember = aDmRoomMember(isIgnored = isDmMemberIgnored)),
|
||||
roomMemberDetailsState = aUserProfileState(
|
||||
isBlocked = AsyncData.Success(isDmMemberIgnored),
|
||||
|
|
|
|||
|
|
@ -208,8 +208,15 @@ fun RoomDetailsView(
|
|||
onClick = onSecurityAndPrivacyClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
state.roomMemberDetailsState?.let { dmMemberDetails ->
|
||||
state.roomMemberDetailsState?.let { dmMemberDetails ->
|
||||
if (state.canInvite) {
|
||||
PreferenceCategory {
|
||||
InviteItem(onClick = invitePeople)
|
||||
}
|
||||
}
|
||||
PreferenceCategory {
|
||||
ProfileItem(
|
||||
verificationState = dmMemberDetails.verificationState,
|
||||
onClick = { onProfileClick(dmMemberDetails.userId) }
|
||||
|
|
@ -374,14 +381,14 @@ private fun MainActionsSection(
|
|||
onClick = { onCall(CallIntent.VIDEO) },
|
||||
)
|
||||
}
|
||||
if (state.canInvite && state.roomType !is RoomDetailsType.Dm) {
|
||||
MainActionButton(
|
||||
title = stringResource(CommonStrings.action_invite),
|
||||
imageVector = CompoundIcons.UserAdd(),
|
||||
onClick = onInvitePeople,
|
||||
)
|
||||
}
|
||||
if (state.roomType is RoomDetailsType.Room) {
|
||||
if (state.canInvite) {
|
||||
MainActionButton(
|
||||
title = stringResource(CommonStrings.action_invite),
|
||||
imageVector = CompoundIcons.UserAdd(),
|
||||
onClick = onInvitePeople,
|
||||
)
|
||||
}
|
||||
// Share CTA should be hidden for DMs
|
||||
MainActionButton(
|
||||
title = stringResource(CommonStrings.action_share),
|
||||
|
|
@ -693,6 +700,17 @@ private fun MembersItem(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InviteItem(
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_details_invite_title)) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.UserAdd())),
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PinnedMessagesItem(
|
||||
pinnedMessagesCount: Int?,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package io.element.android.features.roomdetails.impl.invite
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.bumble.appyx.core.lifecycle.subscribe
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
|
|
@ -19,10 +20,16 @@ import dev.zacsweers.metro.Assisted
|
|||
import dev.zacsweers.metro.AssistedInject
|
||||
import im.vector.app.features.analytics.plan.MobileScreen
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.invitepeople.api.InvitePeopleEvents
|
||||
import io.element.android.features.invitepeople.api.InvitePeoplePresenter
|
||||
import io.element.android.features.invitepeople.api.InvitePeopleRenderer
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
|
||||
@ContributesNode(RoomScope::class)
|
||||
|
|
@ -35,6 +42,10 @@ class RoomInviteMembersNode(
|
|||
room: JoinedRoom,
|
||||
invitePeoplePresenterFactory: InvitePeoplePresenter.Factory,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
interface Callback : Plugin {
|
||||
fun openCreatedRoom(roomId: RoomId)
|
||||
}
|
||||
|
||||
init {
|
||||
lifecycle.subscribe(
|
||||
onResume = {
|
||||
|
|
@ -48,6 +59,8 @@ class RoomInviteMembersNode(
|
|||
roomId = room.roomId,
|
||||
)
|
||||
|
||||
private val callback = plugins.callback<Callback>()
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = invitePeoplePresenter.present()
|
||||
|
|
@ -59,6 +72,19 @@ class RoomInviteMembersNode(
|
|||
}
|
||||
}
|
||||
|
||||
AsyncActionView(
|
||||
async = state.createRoomFromDmAction,
|
||||
onSuccess = { roomId ->
|
||||
callback.openCreatedRoom(roomId)
|
||||
},
|
||||
progressDialog = {
|
||||
ProgressDialog(text = stringResource(CommonStrings.common_creating_room))
|
||||
},
|
||||
onErrorDismiss = {
|
||||
state.eventSink(InvitePeopleEvents.ClearError)
|
||||
}
|
||||
)
|
||||
|
||||
RoomInviteMembersView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class DefaultRoomDetailsEntryPointTest {
|
|||
val callback = object : RoomDetailsEntryPoint.Callback {
|
||||
override fun navigateToGlobalNotificationSettings() = lambdaError()
|
||||
override fun navigateToDeveloperSettings() = lambdaError()
|
||||
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) = lambdaError()
|
||||
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>, clearBackStack: Boolean) = lambdaError()
|
||||
override fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError()
|
||||
override fun startForwardEventFlow(eventId: EventId, fromPinnedEvents: Boolean) = lambdaError()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ package io.element.android.features.roomdetails.impl
|
|||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.AndroidComposeUiTest
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onLast
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performClick
|
||||
|
|
@ -339,6 +341,25 @@ class RoomDetailsViewTest {
|
|||
clickOn(R.string.screen_room_details_profile_row_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Config(qualifiers = "h1024dp")
|
||||
@Test
|
||||
fun `click on invite invokes the expected callback`() = runAndroidComposeUiTest {
|
||||
ensureCalledOnce { callback ->
|
||||
setRoomDetailView(
|
||||
state = aRoomDetailsState(
|
||||
eventSink = EventsRecorder(expectEvents = false),
|
||||
roomType = RoomDetailsType.Dm(
|
||||
aDmRoomMember(userId = UserId("@other:local.org")),
|
||||
),
|
||||
roomMemberDetailsState = aUserProfileState(userId = A_USER_ID),
|
||||
canInvite = true,
|
||||
),
|
||||
invitePeople = callback,
|
||||
)
|
||||
onAllNodesWithText(activity!!.getString(R.string.screen_room_details_invite_title)).onLast().performClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun AndroidComposeUiTest<ComponentActivity>.setRoomDetailView(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue