Open the room when user accepts an invite from the room list
This commit is contained in:
parent
6fec56eeaa
commit
95b3afd148
1
changelog.d/3771.feature
Normal file
1
changelog.d/3771.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Open the room when user accepts an invite from the room list
|
@ -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()
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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 ->
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user