diff --git a/changelog.d/437.feature b/changelog.d/437.feature new file mode 100644 index 0000000000..3aa3eb97f0 --- /dev/null +++ b/changelog.d/437.feature @@ -0,0 +1 @@ +Handle "Invite people" action in the start a chat flow diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 2026ac5214..3c98921d2a 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.elementresources) implementation(projects.libraries.uiStrings) + implementation(projects.libraries.androidutils) implementation(projects.features.userlist.api) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt index 33691009ed..7d8211aea5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt @@ -19,7 +19,6 @@ package io.element.android.features.createroom.impl.root import io.element.android.libraries.matrix.api.user.MatrixUser sealed interface CreateRoomRootEvents { - object InvitePeople : CreateRoomRootEvents data class StartDM(val matrixUser: MatrixUser) : CreateRoomRootEvents object CancelStartDM : CreateRoomRootEvents } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt index 596255dc15..6b5ac667c5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt @@ -16,8 +16,10 @@ package io.element.android.features.createroom.impl.root +import android.content.Context import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin @@ -25,14 +27,22 @@ 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.libraries.androidutils.system.startSharePlainTextIntent +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 +import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder +import io.element.android.libraries.ui.strings.R +import timber.log.Timber @ContributesNode(SessionScope::class) class CreateRoomRootNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, private val presenter: CreateRoomRootPresenter, + private val matrixClient: MatrixClient, + private val buildMeta: BuildMeta, ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { @@ -53,12 +63,31 @@ class CreateRoomRootNode @AssistedInject constructor( @Composable override fun View(modifier: Modifier) { val state = presenter.present() + val context = LocalContext.current CreateRoomRootView( state = state, modifier = modifier, onClosePressed = this::navigateUp, onNewRoomClicked = callback::onCreateNewRoom, onOpenDM = callback::onStartChatSuccess, + onInviteFriendsClicked = { invitePeople(context) } ) } + + private fun invitePeople(context: Context) { + val permalinkResult = PermalinkBuilder.permalinkForUser(matrixClient.sessionId) + permalinkResult.onSuccess { permalink -> + val appName = buildMeta.applicationName + startSharePlainTextIntent( + context = context, + activityResultLauncher = null, + chooserTitle = context.getString(R.string.action_invite_friends), + text = context.getString(R.string.invite_friends_text, appName, permalink), + extraTitle = context.getString(R.string.invite_friends_rich_title, appName), + noActivityFoundMessage = context.getString(io.element.android.libraries.androidutils.R.string.error_no_compatible_app_found) + ) + }.onFailure { + Timber.e(it) + } + } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt index 0ac9611fc7..07f075c2d6 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt @@ -78,7 +78,6 @@ class CreateRoomRootPresenter @Inject constructor( when (event) { is CreateRoomRootEvents.StartDM -> startDm(event.matrixUser) CreateRoomRootEvents.CancelStartDM -> startDmAction.value = Async.Uninitialized - CreateRoomRootEvents.InvitePeople -> Unit // Todo Handle invite people action } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt index 8d78311dc1..493f201802 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -62,6 +62,7 @@ fun CreateRoomRootView( onClosePressed: () -> Unit = {}, onNewRoomClicked: () -> Unit = {}, onOpenDM: (RoomId) -> Unit = {}, + onInviteFriendsClicked: () -> Unit = {}, ) { if (state.startDmAction is Async.Success) { LaunchedEffect(state.startDmAction) { @@ -93,7 +94,7 @@ fun CreateRoomRootView( if (!state.userListState.isSearchActive) { CreateRoomActionButtonsList( onNewRoomClicked = onNewRoomClicked, - onInvitePeopleClicked = { state.eventSink(CreateRoomRootEvents.InvitePeople) }, + onInvitePeopleClicked = onInviteFriendsClicked, ) } } diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt index 2a06278934..61883719fb 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt @@ -62,16 +62,6 @@ class CreateRoomRootPresenterTests { } } - @Test - fun `present - trigger action buttons`() = runTest { - moleculeFlow(RecompositionClock.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - initialState.eventSink(CreateRoomRootEvents.InvitePeople) // Not implemented yet - } - } - @Test fun `present - trigger create DM action`() = runTest { moleculeFlow(RecompositionClock.Immediate) { diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 156261f66a..393052591f 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -6,9 +6,11 @@ "Already a member" "Already invited" + "An error occurred when updating the room details" "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them." "Message encryption enabled" "Share room" + "Updating room…" "Pending" "Room members" "Block" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 849f306133..5eab29b711 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -23,6 +23,7 @@ "Edit" "Enable" "Invite" + "Invite friends" "Invite friends to %1$s" "Invites" "Learn more" @@ -69,6 +70,7 @@ "File" "GIF" "Image" + "Leaving room" "Link copied to clipboard" "Loading…" "Message" @@ -88,26 +90,28 @@ "Search results" "Security" "Select your server" - "Sending…" - "Server not supported" - "Server URL" - "Settings" + "Sending…" + "Server not supported" + "Server URL" + "Settings" "Starting chat…" - "Sticker" - "Success" - "Suggestions" - "Topic" - "Unable to decrypt" - "Unsupported event" - "Username" - "Verification cancelled" - "Verification complete" - "Video" - "Waiting…" - "Confirmation" - "Warning" - "Activities" - "Flags" + "Sticker" + "Success" + "Suggestions" + "Topic" + "Unable to decrypt" + "We were unable to successfully send invites to one or more users." + "Unable to send invite(s)" + "Unsupported event" + "Username" + "Verification cancelled" + "Verification complete" + "Video" + "Waiting…" + "Confirmation" + "Warning" + "Activities" + "Flags" "Food & Drink" "Animals & Nature" "Objects" @@ -118,6 +122,7 @@ "Failed loading messages" "Some messages have not been sent" "Sorry, an error occurred" + "🔐️ Join me on %1$s" "Hey, talk to me on %1$s: %2$s" "Are you sure that you want to leave this room? You are the only person here. If you leave, no one will be able to join in the future, including you." "Are you sure that you want to leave this room? This room is not public and you will not be able to rejoin without an invite."