#3771: When accepting an invite, expecting to see the room (#5247)

Open the room when user accepts an invite from the room list
This commit is contained in:
ClaireG 2022-02-18 16:45:01 +01:00 committed by GitHub
parent 6fec56eeaa
commit 95b3afd148
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 38 additions and 28 deletions

1
changelog.d/3771.feature Normal file
View File

@ -0,0 +1 @@
Open the room when user accepts an invite from the room list

View File

@ -29,7 +29,7 @@ import java.io.File
* Transient events for RoomDetail * Transient events for RoomDetail
*/ */
sealed class RoomDetailViewEvents : VectorViewEvents { sealed class RoomDetailViewEvents : VectorViewEvents {
data class Failure(val throwable: Throwable) : RoomDetailViewEvents() data class Failure(val throwable: Throwable, val showInDialog: Boolean = false) : RoomDetailViewEvents()
data class OnNewTimelineEvents(val eventIds: List<String>) : RoomDetailViewEvents() data class OnNewTimelineEvents(val eventIds: List<String>) : RoomDetailViewEvents()
data class ActionSuccess(val action: RoomDetailAction) : RoomDetailViewEvents() data class ActionSuccess(val action: RoomDetailAction) : RoomDetailViewEvents()

View File

@ -49,6 +49,7 @@ data class JitsiState(
data class RoomDetailViewState( data class RoomDetailViewState(
val roomId: String, val roomId: String,
val eventId: String?, val eventId: String?,
val isInviteAlreadyAccepted: Boolean,
val myRoomMember: Async<RoomMemberSummary> = Uninitialized, val myRoomMember: Async<RoomMemberSummary> = Uninitialized,
val asyncInviter: Async<RoomMemberSummary> = Uninitialized, val asyncInviter: Async<RoomMemberSummary> = Uninitialized,
val asyncRoomSummary: Async<RoomSummary> = Uninitialized, val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
@ -77,6 +78,7 @@ data class RoomDetailViewState(
constructor(args: TimelineArgs) : this( constructor(args: TimelineArgs) : this(
roomId = args.roomId, roomId = args.roomId,
eventId = args.eventId, eventId = args.eventId,
isInviteAlreadyAccepted = args.isInviteAlreadyAccepted,
// Also highlight the target event, if any // Also highlight the target event, if any
highlightedEventId = args.eventId, highlightedEventId = args.eventId,
switchToParentSpace = args.switchToParentSpace, switchToParentSpace = args.switchToParentSpace,

View File

@ -448,7 +448,7 @@ class TimelineFragment @Inject constructor(
timelineViewModel.observeViewEvents { timelineViewModel.observeViewEvents {
when (it) { when (it) {
is RoomDetailViewEvents.Failure -> showErrorInSnackbar(it.throwable) is RoomDetailViewEvents.Failure -> displayErrorMessage(it)
is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds) is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds)
is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it) is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it)
is RoomDetailViewEvents.ActionFailure -> displayRoomDetailActionFailure(it) is RoomDetailViewEvents.ActionFailure -> displayRoomDetailActionFailure(it)
@ -623,6 +623,10 @@ class TimelineFragment @Inject constructor(
) )
} }
private fun displayErrorMessage(error: RoomDetailViewEvents.Failure) {
if (error.showInDialog) displayErrorDialog(error.throwable) else showErrorInSnackbar(error.throwable)
}
private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) { private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) {
val tag = RoomWidgetPermissionBottomSheet::class.java.name val tag = RoomWidgetPermissionBottomSheet::class.java.name
val dFrag = childFragmentManager.findFragmentByTag(tag) as? RoomWidgetPermissionBottomSheet val dFrag = childFragmentManager.findFragmentByTag(tag) as? RoomWidgetPermissionBottomSheet
@ -2374,12 +2378,10 @@ class TimelineFragment @Inject constructor(
// VectorInviteView.Callback // VectorInviteView.Callback
override fun onAcceptInvite() { override fun onAcceptInvite() {
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) }
timelineViewModel.handle(RoomDetailAction.AcceptInvite) timelineViewModel.handle(RoomDetailAction.AcceptInvite)
} }
override fun onRejectInvite() { override fun onRejectInvite() {
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) }
timelineViewModel.handle(RoomDetailAction.RejectInvite) timelineViewModel.handle(RoomDetailAction.RejectInvite)
} }

View File

@ -53,6 +53,7 @@ import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandle
import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
import im.vector.app.features.home.room.typing.TypingHelper import im.vector.app.features.home.room.typing.TypingHelper
import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.session.coroutineScope import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorDataStore
@ -123,6 +124,7 @@ class TimelineViewModel @AssistedInject constructor(
private val analyticsTracker: AnalyticsTracker, private val analyticsTracker: AnalyticsTracker,
private val activeConferenceHolder: JitsiActiveConferenceHolder, private val activeConferenceHolder: JitsiActiveConferenceHolder,
private val decryptionFailureTracker: DecryptionFailureTracker, private val decryptionFailureTracker: DecryptionFailureTracker,
private val notificationDrawerManager: NotificationDrawerManager,
timelineFactory: TimelineFactory, timelineFactory: TimelineFactory,
appStateHandler: AppStateHandler appStateHandler: AppStateHandler
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState), ) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState),
@ -190,6 +192,11 @@ class TimelineViewModel @AssistedInject constructor(
prepareForEncryption() prepareForEncryption()
} }
// If the user had already accepted the invitation in the room list
if (initialState.isInviteAlreadyAccepted) {
handleAcceptInvite()
}
if (initialState.switchToParentSpace) { if (initialState.switchToParentSpace) {
// We are coming from a notification, try to switch to the most relevant space // We are coming from a notification, try to switch to the most relevant space
// so that when hitting back the room will appear in the list // so that when hitting back the room will appear in the list
@ -800,16 +807,24 @@ class TimelineViewModel @AssistedInject constructor(
} }
private fun handleRejectInvite() { private fun handleRejectInvite() {
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(initialState.roomId) }
viewModelScope.launch { viewModelScope.launch {
tryOrNull { session.leaveRoom(room.roomId) } try {
session.leaveRoom(room.roomId)
} catch (throwable: Throwable) {
_viewEvents.post(RoomDetailViewEvents.Failure(throwable, showInDialog = true))
}
} }
} }
private fun handleAcceptInvite() { private fun handleAcceptInvite() {
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(initialState.roomId) }
viewModelScope.launch { viewModelScope.launch {
tryOrNull { try {
session.joinRoom(room.roomId) session.joinRoom(room.roomId)
analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom())
} catch (throwable: Throwable) {
_viewEvents.post(RoomDetailViewEvents.Failure(throwable, showInDialog = true))
} }
} }
} }

View File

@ -28,5 +28,6 @@ data class TimelineArgs(
val sharedData: SharedData? = null, val sharedData: SharedData? = null,
val openShareSpaceForId: String? = null, val openShareSpaceForId: String? = null,
val threadTimelineArgs: ThreadTimelineArgs? = null, val threadTimelineArgs: ThreadTimelineArgs? = null,
val switchToParentSpace: Boolean = false val switchToParentSpace: Boolean = false,
val isInviteAlreadyAccepted: Boolean = false
) : Parcelable ) : Parcelable

View File

@ -121,7 +121,7 @@ class RoomListFragment @Inject constructor(
when (it) { when (it) {
is RoomListViewEvents.Loading -> showLoading(it.message) is RoomListViewEvents.Loading -> showLoading(it.message)
is RoomListViewEvents.Failure -> showFailure(it.throwable) is RoomListViewEvents.Failure -> showFailure(it.throwable)
is RoomListViewEvents.SelectRoom -> handleSelectRoom(it) is RoomListViewEvents.SelectRoom -> handleSelectRoom(it, it.isInviteAlreadyAccepted)
is RoomListViewEvents.Done -> Unit is RoomListViewEvents.Done -> Unit
is RoomListViewEvents.NavigateToMxToBottomSheet -> handleShowMxToLink(it.link) is RoomListViewEvents.NavigateToMxToBottomSheet -> handleShowMxToLink(it.link)
}.exhaustive }.exhaustive
@ -184,8 +184,8 @@ class RoomListFragment @Inject constructor(
super.onDestroyView() super.onDestroyView()
} }
private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom) { private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom, isInviteAlreadyAccepted: Boolean) {
navigator.openRoom(requireActivity(), event.roomSummary.roomId) navigator.openRoom(context = requireActivity(), roomId = event.roomSummary.roomId, isInviteAlreadyAccepted = isInviteAlreadyAccepted)
} }
private fun setupCreateRoomButton() { private fun setupCreateRoomButton() {

View File

@ -27,7 +27,7 @@ sealed class RoomListViewEvents : VectorViewEvents {
data class Loading(val message: CharSequence? = null) : RoomListViewEvents() data class Loading(val message: CharSequence? = null) : RoomListViewEvents()
data class Failure(val throwable: Throwable) : RoomListViewEvents() data class Failure(val throwable: Throwable) : RoomListViewEvents()
data class SelectRoom(val roomSummary: RoomSummary) : RoomListViewEvents() data class SelectRoom(val roomSummary: RoomSummary, val isInviteAlreadyAccepted: Boolean = false) : RoomListViewEvents()
object Done : RoomListViewEvents() object Done : RoomListViewEvents()
data class NavigateToMxToBottomSheet(val link: String) : RoomListViewEvents() data class NavigateToMxToBottomSheet(val link: String) : RoomListViewEvents()
} }

View File

@ -33,7 +33,6 @@ import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
import im.vector.app.features.displayname.getBestName import im.vector.app.features.displayname.getBestName
import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
@ -174,7 +173,7 @@ class RoomListViewModel @AssistedInject constructor(
// PRIVATE METHODS ***************************************************************************** // PRIVATE METHODS *****************************************************************************
private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState { private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState {
_viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary)) _viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary, false))
} }
private fun handleToggleSection(roomSection: RoomsSection) { private fun handleToggleSection(roomSection: RoomsSection) {
@ -208,6 +207,7 @@ class RoomListViewModel @AssistedInject constructor(
Timber.w("Try to join an already joining room. Should not happen") Timber.w("Try to join an already joining room. Should not happen")
return@withState return@withState
} }
_viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary, true))
// quick echo // quick echo
setState { setState {
@ -221,18 +221,6 @@ class RoomListViewModel @AssistedInject constructor(
} }
) )
} }
viewModelScope.launch {
try {
session.joinRoom(roomId)
analyticsTracker.capture(action.roomSummary.toAnalyticsJoinedRoom())
// We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data.
// Instead, we wait for the room to be joined
} catch (failure: Throwable) {
// Notify the user
_viewEvents.post(RoomListViewEvents.Failure(failure))
}
}
} }
private fun handleRejectInvitation(action: RoomListAction.RejectInvitation) = withState { state -> private fun handleRejectInvitation(action: RoomListAction.RejectInvitation) = withState { state ->

View File

@ -147,13 +147,14 @@ class DefaultNavigator @Inject constructor(
context: Context, context: Context,
roomId: String, roomId: String,
eventId: String?, eventId: String?,
buildTask: Boolean buildTask: Boolean,
isInviteAlreadyAccepted: Boolean
) { ) {
if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) { if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) {
fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast()) fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast())
return return
} }
val args = TimelineArgs(roomId, eventId) val args = TimelineArgs(roomId = roomId, eventId = eventId, isInviteAlreadyAccepted = isInviteAlreadyAccepted)
val intent = RoomDetailActivity.newIntent(context, args) val intent = RoomDetailActivity.newIntent(context, args)
startActivity(context, intent, buildTask) startActivity(context, intent, buildTask)
} }

View File

@ -50,7 +50,7 @@ interface Navigator {
fun softLogout(context: Context) fun softLogout(context: Context)
fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false) fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false, isInviteAlreadyAccepted: Boolean = false)
sealed class PostSwitchSpaceAction { sealed class PostSwitchSpaceAction {
object None : PostSwitchSpaceAction() object None : PostSwitchSpaceAction()