Merge pull request #2342 from vector-im/feature/ons/open_existing_dm

Navigate to an existing DM instead of creating a new one.
This commit is contained in:
Benoit Marty 2020-11-06 11:29:20 +01:00 committed by GitHub
commit 0753ba3495
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 11 deletions

View File

@ -5,7 +5,7 @@ Features ✨:
-
Improvements 🙌:
-
- Open an existing DM instead of creating a new one (#2319)
Bugfix 🐛:
- Fix issue when updating the avatar of a room

View File

@ -20,5 +20,8 @@ import im.vector.app.core.platform.VectorViewModelAction
import im.vector.app.features.userdirectory.PendingInvitee
sealed class CreateDirectRoomAction : VectorViewModelAction {
data class CreateRoomAndInviteSelectedUsers(val invitees: Set<PendingInvitee>) : CreateDirectRoomAction()
data class CreateRoomAndInviteSelectedUsers(
val invitees: Set<PendingInvitee>,
val existingDmRoomId: String?
) : CreateDirectRoomAction()
}

View File

@ -91,7 +91,8 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
KnownUsersFragment::class.java,
KnownUsersFragmentArgs(
title = getString(R.string.fab_menu_create_chat),
menuResId = R.menu.vector_create_direct_room
menuResId = R.menu.vector_create_direct_room,
isCreatingRoom = true
)
)
}
@ -121,7 +122,10 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
private fun onMenuItemSelected(action: UserDirectorySharedAction.OnMenuItemSelected) {
if (action.itemId == R.id.action_create_direct_room) {
viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(action.invitees))
viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(
action.invitees,
action.existingDmRoomId
))
}
}

View File

@ -19,6 +19,7 @@ package im.vector.app.features.createdirect
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
@ -56,7 +57,22 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
override fun handle(action: CreateDirectRoomAction) {
when (action) {
is CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers -> createRoomAndInviteSelectedUsers(action.invitees)
is CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers -> onSubmitInvitees(action)
}.exhaustive
}
/**
* If users already have a DM room then navigate to it instead of creating a new room.
*/
private fun onSubmitInvitees(action: CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers) {
if (action.existingDmRoomId != null) {
// Do not create a new DM, just tell that the creation is successful by passing the existing roomId
setState {
copy(createAndInviteState = Success(action.existingDmRoomId))
}
} else {
// Create the DM
createRoomAndInviteSelectedUsers(action.invitees)
}
}

View File

@ -91,13 +91,20 @@ class KnownUsersFragment @Inject constructor(
val showMenuItem = it.pendingInvitees.isNotEmpty()
menu.forEach { menuItem ->
menuItem.isVisible = showMenuItem
if (args.isCreatingRoom) {
menuItem.setTitle(if (it.existingDmRoomId != null) R.string.action_open else R.string.create_room_action_create)
}
}
}
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) {
sharedActionViewModel.post(UserDirectorySharedAction.OnMenuItemSelected(item.itemId, it.pendingInvitees))
sharedActionViewModel.post(UserDirectorySharedAction.OnMenuItemSelected(
item.itemId,
it.pendingInvitees,
it.existingDmRoomId
))
return@withState true
}

View File

@ -23,5 +23,6 @@ import kotlinx.android.parcel.Parcelize
data class KnownUsersFragmentArgs(
val title: String,
val menuResId: Int,
val excludedUserIds: Set<String>? = null
val excludedUserIds: Set<String>? = null,
val isCreatingRoom: Boolean = false
) : Parcelable

View File

@ -23,5 +23,7 @@ sealed class UserDirectorySharedAction : VectorSharedAction {
object OpenPhoneBook : UserDirectorySharedAction()
object Close : UserDirectorySharedAction()
object GoBack : UserDirectorySharedAction()
data class OnMenuItemSelected(val itemId: Int, val invitees: Set<PendingInvitee>) : UserDirectorySharedAction()
data class OnMenuItemSelected(val itemId: Int,
val invitees: Set<PendingInvitee>,
val existingDmRoomId: String?) : UserDirectorySharedAction()
}

View File

@ -87,14 +87,32 @@ class UserDirectoryViewModel @AssistedInject constructor(@Assisted
private fun handleRemoveSelectedUser(action: UserDirectoryAction.RemovePendingInvitee) = withState { state ->
val selectedUsers = state.pendingInvitees.minus(action.pendingInvitee)
setState { copy(pendingInvitees = selectedUsers) }
setState {
copy(
pendingInvitees = selectedUsers,
existingDmRoomId = getExistingDmRoomId(selectedUsers)
)
}
}
private fun handleSelectUser(action: UserDirectoryAction.SelectPendingInvitee) = withState { state ->
// Reset the filter asap
directoryUsersSearch.accept("")
val selectedUsers = state.pendingInvitees.toggle(action.pendingInvitee)
setState { copy(pendingInvitees = selectedUsers) }
setState {
copy(
pendingInvitees = selectedUsers,
existingDmRoomId = getExistingDmRoomId(selectedUsers)
)
}
}
private fun getExistingDmRoomId(selectedUsers: Set<PendingInvitee>): String? {
return selectedUsers
.takeIf { it.size == 1 }
?.filterIsInstance(PendingInvitee.UserPendingInvitee::class.java)
?.firstOrNull()
?.let { invitee -> session.getExistingDirectRoomWithUser(invitee.user.userId) }
}
private fun observeDirectoryUsers() = withState { state ->

View File

@ -30,7 +30,8 @@ data class UserDirectoryViewState(
val pendingInvitees: Set<PendingInvitee> = emptySet(),
val createAndInviteState: Async<String> = Uninitialized,
val directorySearchTerm: String = "",
val filterKnownUsersValue: Option<String> = Option.empty()
val filterKnownUsersValue: Option<String> = Option.empty(),
val existingDmRoomId: String? = null
) : MvRxState {
constructor(args: KnownUsersFragmentArgs) : this(excludedUserIds = args.excludedUserIds)