Room list: tweak UI and add overflow menu with report bug and invite friends action.

Extract invite friends action to a use case to avoid copy paste.
This commit is contained in:
Benoit Marty 2023-06-21 14:50:00 +02:00 committed by Benoit Marty
parent e7e225dd3a
commit 82e566175a
12 changed files with 180 additions and 38 deletions

View file

@ -222,6 +222,10 @@ class LoggedInFlowNode @AssistedInject constructor(
override fun onRoomSettingsClicked(roomId: RoomId) { override fun onRoomSettingsClicked(roomId: RoomId) {
backstack.push(NavTarget.Room(roomId, initialElement = RoomFlowNode.NavTarget.RoomDetails)) backstack.push(NavTarget.Room(roomId, initialElement = RoomFlowNode.NavTarget.RoomDetails))
} }
override fun onReportBugClicked() {
plugins<Callback>().forEach { it.onOpenBugReport() }
}
} }
roomListEntryPoint roomListEntryPoint
.nodeBuilder(this, buildContext) .nodeBuilder(this, buildContext)

View file

@ -45,6 +45,7 @@ dependencies {
implementation(projects.libraries.designsystem) implementation(projects.libraries.designsystem)
implementation(projects.libraries.uiStrings) implementation(projects.libraries.uiStrings)
implementation(projects.libraries.androidutils) implementation(projects.libraries.androidutils)
implementation(projects.libraries.deeplink)
implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediapickers.api)
implementation(projects.libraries.mediaupload.api) implementation(projects.libraries.mediaupload.api)
implementation(projects.libraries.usersearch.impl) implementation(projects.libraries.usersearch.impl)

View file

@ -16,7 +16,7 @@
package io.element.android.features.createroom.impl.root package io.element.android.features.createroom.impl.root
import android.content.Context import android.app.Activity
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -29,24 +29,18 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.SessionScope 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.core.RoomId
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import timber.log.Timber
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class CreateRoomRootNode @AssistedInject constructor( class CreateRoomRootNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: CreateRoomRootPresenter, private val presenter: CreateRoomRootPresenter,
private val matrixClient: MatrixClient,
private val buildMeta: BuildMeta,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
private val inviteFriendsUseCase: InviteFriendsUseCase,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
interface Callback : Plugin { interface Callback : Plugin {
@ -73,31 +67,18 @@ class CreateRoomRootNode @AssistedInject constructor(
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val state = presenter.present() val state = presenter.present()
val context = LocalContext.current val activity = LocalContext.current as Activity
CreateRoomRootView( CreateRoomRootView(
state = state, state = state,
modifier = modifier, modifier = modifier,
onClosePressed = this::navigateUp, onClosePressed = this::navigateUp,
onNewRoomClicked = callback::onCreateNewRoom, onNewRoomClicked = callback::onCreateNewRoom,
onOpenDM = callback::onStartChatSuccess, onOpenDM = callback::onStartChatSuccess,
onInviteFriendsClicked = { invitePeople(context) }, onInviteFriendsClicked = { invitePeople(activity) }
) )
} }
private fun invitePeople(context: Context) { private fun invitePeople(activity: Activity) {
val permalinkResult = PermalinkBuilder.permalinkForUser(matrixClient.sessionId) inviteFriendsUseCase.execute(activity)
permalinkResult.onSuccess { permalink ->
val appName = buildMeta.applicationName
startSharePlainTextIntent(
context = context,
activityResultLauncher = null,
chooserTitle = context.getString(CommonStrings.action_invite_friends),
text = context.getString(CommonStrings.invite_friends_text, appName, permalink),
extraTitle = context.getString(CommonStrings.invite_friends_rich_title, appName),
noActivityFoundMessage = context.getString(io.element.android.libraries.androidutils.R.string.error_no_compatible_app_found)
)
}.onFailure {
Timber.e(it)
}
} }
} }

View file

@ -37,6 +37,7 @@ interface RoomListEntryPoint : FeatureEntryPoint {
fun onSessionVerificationClicked() fun onSessionVerificationClicked()
fun onInvitesClicked() fun onInvitesClicked()
fun onRoomSettingsClicked(roomId: RoomId) fun onRoomSettingsClicked(roomId: RoomId)
fun onReportBugClicked()
} }
} }

View file

@ -48,6 +48,7 @@ dependencies {
implementation(projects.libraries.uiStrings) implementation(projects.libraries.uiStrings)
implementation(projects.libraries.dateformatter.api) implementation(projects.libraries.dateformatter.api)
implementation(projects.libraries.eventformatter.api) implementation(projects.libraries.eventformatter.api)
implementation(projects.libraries.deeplink)
implementation(projects.features.invitelist.api) implementation(projects.features.invitelist.api)
implementation(projects.features.networkmonitor.api) implementation(projects.features.networkmonitor.api)
implementation(projects.features.leaveroom.api) implementation(projects.features.leaveroom.api)

View file

@ -16,8 +16,10 @@
package io.element.android.features.roomlist.impl package io.element.android.features.roomlist.impl
import android.app.Activity
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
@ -26,6 +28,8 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.roomlist.api.RoomListEntryPoint import io.element.android.features.roomlist.api.RoomListEntryPoint
import io.element.android.features.roomlist.impl.components.RoomListMenuAction
import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@ -33,7 +37,8 @@ import io.element.android.libraries.matrix.api.core.RoomId
class RoomListNode @AssistedInject constructor( class RoomListNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: RoomListPresenter, private val presenter: RoomListPresenter,
private val inviteFriendsUseCase: InviteFriendsUseCase,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
private fun onRoomClicked(roomId: RoomId) { private fun onRoomClicked(roomId: RoomId) {
@ -60,9 +65,21 @@ class RoomListNode @AssistedInject constructor(
plugins<RoomListEntryPoint.Callback>().forEach { it.onRoomSettingsClicked(roomId) } plugins<RoomListEntryPoint.Callback>().forEach { it.onRoomSettingsClicked(roomId) }
} }
private fun onMenuActionClicked(activity: Activity, roomListMenuAction: RoomListMenuAction) {
when (roomListMenuAction) {
RoomListMenuAction.InviteFriends -> {
inviteFriendsUseCase.execute(activity)
}
RoomListMenuAction.ReportBug -> {
plugins<RoomListEntryPoint.Callback>().forEach { it.onReportBugClicked() }
}
}
}
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val state = presenter.present() val state = presenter.present()
val activity = LocalContext.current as Activity
RoomListView( RoomListView(
state = state, state = state,
onRoomClicked = this::onRoomClicked, onRoomClicked = this::onRoomClicked,
@ -71,6 +88,7 @@ class RoomListNode @AssistedInject constructor(
onVerifyClicked = this::onSessionVerificationClicked, onVerifyClicked = this::onSessionVerificationClicked,
onInvitesClicked = this::onInvitesClicked, onInvitesClicked = this::onInvitesClicked,
onRoomSettingsClicked = this::onRoomSettingsClicked, onRoomSettingsClicked = this::onRoomSettingsClicked,
onMenuActionClicked = { onMenuActionClicked(activity, it) },
modifier = modifier, modifier = modifier,
) )
} }

View file

@ -63,6 +63,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import io.element.android.features.leaveroom.api.LeaveRoomView import io.element.android.features.leaveroom.api.LeaveRoomView
import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView
import io.element.android.features.roomlist.impl.components.RoomListMenuAction
import io.element.android.features.roomlist.impl.components.RoomListTopBar import io.element.android.features.roomlist.impl.components.RoomListTopBar
import io.element.android.features.roomlist.impl.components.RoomSummaryRow import io.element.android.features.roomlist.impl.components.RoomSummaryRow
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
@ -95,6 +96,7 @@ fun RoomListView(
onCreateRoomClicked: () -> Unit, onCreateRoomClicked: () -> Unit,
onInvitesClicked: () -> Unit, onInvitesClicked: () -> Unit,
onRoomSettingsClicked: (roomId: RoomId) -> Unit, onRoomSettingsClicked: (roomId: RoomId) -> Unit,
onMenuActionClicked: (RoomListMenuAction) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier = modifier) { Column(modifier = modifier) {
@ -118,12 +120,13 @@ fun RoomListView(
RoomListContent( RoomListContent(
state = state, state = state,
onVerifyClicked = onVerifyClicked,
onRoomClicked = onRoomClicked, onRoomClicked = onRoomClicked,
onRoomLongClicked = { onRoomLongClicked(it) }, onRoomLongClicked = { onRoomLongClicked(it) },
onOpenSettings = onSettingsClicked, onOpenSettings = onSettingsClicked,
onVerifyClicked = onVerifyClicked,
onCreateRoomClicked = onCreateRoomClicked, onCreateRoomClicked = onCreateRoomClicked,
onInvitesClicked = onInvitesClicked, onInvitesClicked = onInvitesClicked,
onMenuActionClicked = onMenuActionClicked,
) )
// This overlaid view will only be visible when state.displaySearchResults is true // This overlaid view will only be visible when state.displaySearchResults is true
RoomListSearchResultView( RoomListSearchResultView(
@ -143,12 +146,13 @@ fun RoomListView(
fun RoomListContent( fun RoomListContent(
state: RoomListState, state: RoomListState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onVerifyClicked: () -> Unit = {}, onVerifyClicked: () -> Unit,
onRoomClicked: (RoomId) -> Unit = {}, onRoomClicked: (RoomId) -> Unit,
onRoomLongClicked: (RoomListRoomSummary) -> Unit = {}, onRoomLongClicked: (RoomListRoomSummary) -> Unit,
onOpenSettings: () -> Unit = {}, onOpenSettings: () -> Unit,
onCreateRoomClicked: () -> Unit = {}, onCreateRoomClicked: () -> Unit,
onInvitesClicked: () -> Unit = {}, onInvitesClicked: () -> Unit,
onMenuActionClicked: (RoomListMenuAction) -> Unit,
) { ) {
fun onRoomClicked(room: RoomListRoomSummary) { fun onRoomClicked(room: RoomListRoomSummary) {
onRoomClicked(room.roomId) onRoomClicked(room.roomId)
@ -190,6 +194,7 @@ fun RoomListContent(
areSearchResultsDisplayed = state.displaySearchResults, areSearchResultsDisplayed = state.displaySearchResults,
onFilterChanged = { state.eventSink(RoomListEvents.UpdateFilter(it)) }, onFilterChanged = { state.eventSink(RoomListEvents.UpdateFilter(it)) },
onToggleSearch = { state.eventSink(RoomListEvents.ToggleSearchResults) }, onToggleSearch = { state.eventSink(RoomListEvents.ToggleSearchResults) },
onMenuActionClicked = onMenuActionClicked,
onOpenSettings = onOpenSettings, onOpenSettings = onOpenSettings,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
@ -369,7 +374,8 @@ private fun ContentToPreview(state: RoomListState) {
onVerifyClicked = {}, onVerifyClicked = {},
onCreateRoomClicked = {}, onCreateRoomClicked = {},
onInvitesClicked = {}, onInvitesClicked = {},
onRoomSettingsClicked = {} onRoomSettingsClicked = {},
onMenuActionClicked = {},
) )
} }

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 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.roomlist.impl.components
enum class RoomListMenuAction {
InviteFriends,
ReportBug
}

View file

@ -19,23 +19,33 @@ package io.element.android.features.roomlist.impl.components
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.BugReport
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.rememberTopAppBarState import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.features.roomlist.impl.R import io.element.android.features.roomlist.impl.R
import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Icon
@ -57,6 +67,7 @@ fun RoomListTopBar(
areSearchResultsDisplayed: Boolean, areSearchResultsDisplayed: Boolean,
onFilterChanged: (String) -> Unit, onFilterChanged: (String) -> Unit,
onToggleSearch: () -> Unit, onToggleSearch: () -> Unit,
onMenuActionClicked: (RoomListMenuAction) -> Unit,
onOpenSettings: () -> Unit, onOpenSettings: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior, scrollBehavior: TopAppBarScrollBehavior,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -79,6 +90,7 @@ fun RoomListTopBar(
matrixUser = matrixUser, matrixUser = matrixUser,
onOpenSettings = onOpenSettings, onOpenSettings = onOpenSettings,
onSearchClicked = onToggleSearch, onSearchClicked = onToggleSearch,
onMenuActionClicked = onMenuActionClicked,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
modifier = modifier, modifier = modifier,
) )
@ -90,15 +102,19 @@ private fun DefaultRoomListTopBar(
matrixUser: MatrixUser?, matrixUser: MatrixUser?,
scrollBehavior: TopAppBarScrollBehavior, scrollBehavior: TopAppBarScrollBehavior,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onOpenSettings: () -> Unit = {}, onOpenSettings: () -> Unit,
onSearchClicked: () -> Unit = {}, onSearchClicked: () -> Unit,
onMenuActionClicked: (RoomListMenuAction) -> Unit,
) { ) {
var showMenu by remember { mutableStateOf(false) }
MediumTopAppBar( MediumTopAppBar(
modifier = modifier modifier = modifier
.nestedScroll(scrollBehavior.nestedScrollConnection), .nestedScroll(scrollBehavior.nestedScrollConnection),
title = { title = {
val fontSize = if (scrollBehavior.state.collapsedFraction > 0.5) 20.sp else 22.sp
Text( Text(
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.headlineMedium.copy(fontSize = fontSize),
text = stringResource(id = R.string.screen_roomlist_main_space_title) text = stringResource(id = R.string.screen_roomlist_main_space_title)
) )
}, },
@ -108,7 +124,11 @@ private fun DefaultRoomListTopBar(
modifier = Modifier.testTag(TestTags.homeScreenSettings), modifier = Modifier.testTag(TestTags.homeScreenSettings),
onClick = onOpenSettings onClick = onOpenSettings
) { ) {
val avatarData by remember { derivedStateOf { matrixUser.getAvatarData() } } val avatarData by remember {
derivedStateOf {
matrixUser.getAvatarData(size = AvatarSize.Custom(28.dp))
}
}
Avatar(avatarData, contentDescription = stringResource(CommonStrings.common_settings)) Avatar(avatarData, contentDescription = stringResource(CommonStrings.common_settings))
} }
} }
@ -119,6 +139,32 @@ private fun DefaultRoomListTopBar(
) { ) {
Icon(Icons.Default.Search, contentDescription = stringResource(CommonStrings.action_search)) Icon(Icons.Default.Search, contentDescription = stringResource(CommonStrings.action_search))
} }
IconButton(
onClick = { showMenu = !showMenu }
) {
Icon(Icons.Default.MoreVert, contentDescription = null)
}
DropdownMenu(
expanded = showMenu,
onDismissRequest = { showMenu = false }
) {
DropdownMenuItem(
onClick = {
showMenu = false
onMenuActionClicked(RoomListMenuAction.InviteFriends)
},
text = { Text(stringResource(id = CommonStrings.action_invite)) },
leadingIcon = { Icon(Icons.Default.Share, contentDescription = null) }
)
DropdownMenuItem(
onClick = {
showMenu = false
onMenuActionClicked(RoomListMenuAction.ReportBug)
},
text = { Text(stringResource(id = CommonStrings.common_report_a_bug)) },
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) }
)
}
}, },
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
windowInsets = WindowInsets(0.dp), windowInsets = WindowInsets(0.dp),
@ -139,5 +185,8 @@ private fun DefaultRoomListTopBarPreview() {
DefaultRoomListTopBar( DefaultRoomListTopBar(
matrixUser = MatrixUser(UserId("@id:domain"), "Alice"), matrixUser = MatrixUser(UserId("@id:domain"), "Alice"),
scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()), scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
onOpenSettings = {},
onSearchClicked = {},
onMenuActionClicked = {},
) )
} }

View file

@ -30,8 +30,12 @@ dependencies {
implementation(projects.libraries.di) implementation(projects.libraries.di)
implementation(libs.dagger) implementation(libs.dagger)
implementation(libs.androidx.corektx) implementation(libs.androidx.corektx)
implementation(projects.libraries.core)
implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrix.api)
implementation(projects.libraries.androidutils)
implementation(projects.libraries.architecture) implementation(projects.libraries.architecture)
implementation(projects.libraries.uiStrings)
implementation(projects.services.toolbox.api)
testImplementation(libs.test.junit) testImplementation(libs.test.junit)
testImplementation(libs.test.truth) testImplementation(libs.test.truth)

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2023 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.libraries.deeplink.usecase
import android.app.Activity
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.services.toolbox.api.strings.StringProvider
import timber.log.Timber
import javax.inject.Inject
import io.element.android.libraries.androidutils.R as AndroidUtilsR
import io.element.android.libraries.ui.strings.CommonStrings
class InviteFriendsUseCase @Inject constructor(
private val stringProvider: StringProvider,
private val matrixClient: MatrixClient,
private val buildMeta: BuildMeta,
) {
fun execute(activity: Activity) {
val permalinkResult = PermalinkBuilder.permalinkForUser(matrixClient.sessionId)
permalinkResult.fold(
onSuccess = { permalink ->
val appName = buildMeta.applicationName
startSharePlainTextIntent(
context = activity,
activityResultLauncher = null,
chooserTitle = stringProvider.getString(CommonStrings.action_invite_friends),
text = stringProvider.getString(CommonStrings.invite_friends_text, appName, permalink),
extraTitle = stringProvider.getString(CommonStrings.invite_friends_rich_title, appName),
noActivityFoundMessage = stringProvider.getString(AndroidUtilsR.string.error_no_compatible_app_found)
)
},
onFailure = {
Timber.e(it)
}
)
}
}

View file

@ -103,6 +103,7 @@ class RoomListScreen(
onCreateRoomClicked = {}, onCreateRoomClicked = {},
onInvitesClicked = {}, onInvitesClicked = {},
onRoomSettingsClicked = {}, onRoomSettingsClicked = {},
onMenuActionClicked = {},
modifier = modifier, modifier = modifier,
) )