diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index 82980ebe9d..d479fd5331 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -311,7 +311,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration { private fun migrateTo15(realm: DynamicRealm) { Timber.d("Step 14 -> 15") realm.schema.get("HomeServerCapabilitiesEntity") - ?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSION_JSON, String::class.java) + ?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java) ?.transform { obj -> // Schedule a refresh of the capabilities obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) diff --git a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt index 9e9fe9b8a0..463d94b288 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt @@ -26,6 +26,7 @@ import androidx.core.content.ContextCompat import androidx.core.text.italic import im.vector.app.R import im.vector.app.core.error.ResourceLimitErrorFormatter +import im.vector.app.core.extensions.exhaustive import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.ViewNotificationAreaBinding import im.vector.app.features.themes.ThemeUtils @@ -69,12 +70,13 @@ class NotificationAreaView @JvmOverloads constructor( cleanUp() state = newState when (newState) { + State.Initial -> Unit is State.Default -> renderDefault() is State.Hidden -> renderHidden() is State.NoPermissionToPost -> renderNoPermissionToPost() - is State.Tombstone -> renderTombstone(newState) + is State.Tombstone -> renderTombstone() is State.ResourceLimitExceededError -> renderResourceLimitExceededError(newState) - } + }.exhaustive } // PRIVATE METHODS **************************************************************************************************************************************** @@ -125,7 +127,7 @@ class NotificationAreaView @JvmOverloads constructor( setBackgroundColor(ContextCompat.getColor(context, backgroundColor)) } - private fun renderTombstone(state: State.Tombstone) { + private fun renderTombstone() { visibility = View.VISIBLE views.roomNotificationIcon.setImageResource(R.drawable.ic_warning_badge) val message = span { @@ -133,7 +135,7 @@ class NotificationAreaView @JvmOverloads constructor( +"\n" span(resources.getString(R.string.room_tombstone_continuation_link)) { textDecorationLine = "underline" - onClick = { delegate?.onTombstoneEventClicked(state.tombstoneEvent) } + onClick = { delegate?.onTombstoneEventClicked() } } } views.roomNotificationMessage.movementMethod = BetterLinkMovementMethod.getInstance() @@ -177,6 +179,6 @@ class NotificationAreaView @JvmOverloads constructor( * An interface to delegate some actions to another object */ interface Delegate { - fun onTombstoneEventClicked(tombstoneEvent: Event) + fun onTombstoneEventClicked() } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt index 972162645d..54681366e0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt @@ -25,7 +25,6 @@ import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.parentFragmentViewModel -import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.epoxy.ClickListener @@ -58,16 +57,14 @@ class JoinReplacementRoomBottomSheet : views.roomUpgradeButton.retryClicked = object : ClickListener { override fun invoke(view: View) { - withState(viewModel) { it.tombstoneEvent }?.let { - viewModel.handle(RoomDetailAction.HandleTombstoneEvent(it)) - } + viewModel.handle(RoomDetailAction.JoinAndOpenReplacementRoom) } } - viewModel.selectSubscribe(this, RoomDetailViewState::tombstoneEventHandling) { joinState -> + viewModel.selectSubscribe(this, RoomDetailViewState::joinUpgradedRoomAsync) { joinState -> when (joinState) { // it should never be Uninitialized - Uninitialized -> views.roomUpgradeButton.render(ButtonStateView.State.Loaded) + Uninitialized, is Loading -> { views.roomUpgradeButton.render(ButtonStateView.State.Loading) views.descriptionText.setText(R.string.it_may_take_some_time) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt index 0e090256d3..c88c247a65 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt @@ -44,7 +44,7 @@ sealed class RoomDetailAction : VectorViewModelAction { data class NavigateToEvent(val eventId: String, val highlight: Boolean) : RoomDetailAction() object MarkAllAsRead : RoomDetailAction() data class DownloadOrOpen(val eventId: String, val senderId: String?, val messageFileContent: MessageWithAttachmentContent) : RoomDetailAction() - data class HandleTombstoneEvent(val event: Event) : RoomDetailAction() + object JoinAndOpenReplacementRoom : RoomDetailAction() object AcceptInvite : RoomDetailAction() object RejectInvite : RoomDetailAction() @@ -108,5 +108,5 @@ sealed class RoomDetailAction : VectorViewModelAction { // Failed messages object RemoveAllFailedMessages : RoomDetailAction() - data class RoomUpgradeSuccess(val replacementRoom: String): RoomDetailAction() + data class RoomUpgradeSuccess(val replacementRoomId: String): RoomDetailAction() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index d7e8f4d369..910a2eaf6c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -179,7 +179,6 @@ import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.commonmark.parser.Parser import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentAttachmentData -import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -359,10 +358,6 @@ class RoomDetailFragment @Inject constructor( invalidateOptionsMenu() }) - roomDetailViewModel.selectSubscribe(this, RoomDetailViewState::tombstoneEventHandling, uniqueOnly("tombstoneEventHandling")) { - renderTombstoneEventHandling(it) - } - roomDetailViewModel.selectSubscribe(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ -> updateJumpToReadMarkerViewVisibility() } @@ -498,6 +493,9 @@ class RoomDetailFragment @Inject constructor( private fun handleOpenRoom(openRoom: RoomDetailViewEvents.OpenRoom) { navigator.openRoom(requireContext(), openRoom.roomId, null) + if (openRoom.closeCurrentRoom) { + requireActivity().finish() + } } private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) { @@ -802,8 +800,8 @@ class RoomDetailFragment @Inject constructor( private fun setupNotificationView() { views.notificationAreaView.delegate = object : NotificationAreaView.Delegate { - override fun onTombstoneEventClicked(tombstoneEvent: Event) { - roomDetailViewModel.handle(RoomDetailAction.HandleTombstoneEvent(tombstoneEvent)) + override fun onTombstoneEventClicked() { + roomDetailViewModel.handle(RoomDetailAction.JoinAndOpenReplacementRoom) } } } @@ -1338,21 +1336,6 @@ class RoomDetailFragment @Inject constructor( } } - private fun renderTombstoneEventHandling(async: Async) { - when (async) { - is Loading -> { - // shown in bottom sheet - } - is Success -> { - navigator.openRoom(vectorBaseActivity, async()) - vectorBaseActivity.finish() - } - is Fail -> { - // shown in bottom sheet - } - } - } - private fun renderSendMessageResult(sendMessageResult: RoomDetailViewEvents.SendMessageResult) { when (sendMessageResult) { is RoomDetailViewEvents.SlashCommandHandled -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index 458549bbac..d62c5f6003 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -41,7 +41,7 @@ sealed class RoomDetailViewEvents : VectorViewEvents { data class ShowInfoOkDialog(val message: String) : RoomDetailViewEvents() data class ShowE2EErrorMessage(val withHeldCode: WithHeldCode?) : RoomDetailViewEvents() - data class OpenRoom(val roomId: String) : RoomDetailViewEvents() + data class OpenRoom(val roomId: String, val closeCurrentRoom: Boolean = false) : RoomDetailViewEvents() data class NavigateToEvent(val eventId: String) : RoomDetailViewEvents() data class JoinJitsiConference(val widget: Widget, val withVideo: Boolean) : RoomDetailViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 1a031e9b07..50ffd72444 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -281,7 +281,7 @@ class RoomDetailViewModel @AssistedInject constructor( is RoomDetailAction.EnterReplyMode -> handleReplyAction(action) is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action) is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action) - is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action) + is RoomDetailAction.JoinAndOpenReplacementRoom -> handleJoinAndOpenReplacementRoom() is RoomDetailAction.ResendMessage -> handleResendEvent(action) is RoomDetailAction.RemoveFailedEcho -> handleRemove(action) is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead() @@ -322,8 +322,9 @@ class RoomDetailViewModel @AssistedInject constructor( RoomDetailAction.ResendAll -> handleResendAll() is RoomDetailAction.RoomUpgradeSuccess -> { setState { - copy(tombstoneEventHandling = Success(action.replacementRoom)) + copy(joinUpgradedRoomAsync = Success(action.replacementRoomId)) } + _viewEvents.post(RoomDetailViewEvents.OpenRoom(action.replacementRoomId, closeCurrentRoom = true)) } }.exhaustive } @@ -578,21 +579,22 @@ class RoomDetailViewModel @AssistedInject constructor( } } - private fun handleTombstoneEvent(action: RoomDetailAction.HandleTombstoneEvent) { - val tombstoneContent = action.event.getClearContent().toModel() ?: return + private fun handleJoinAndOpenReplacementRoom() = withState { state -> + val tombstoneContent = state.tombstoneEvent?.getClearContent()?.toModel() ?: return@withState val roomId = tombstoneContent.replacementRoomId ?: "" val isRoomJoined = session.getRoom(roomId)?.roomSummary()?.membership == Membership.JOIN if (isRoomJoined) { - setState { copy(tombstoneEventHandling = Success(roomId)) } + setState { copy(joinUpgradedRoomAsync = Success(roomId)) } + _viewEvents.post(RoomDetailViewEvents.OpenRoom(roomId, closeCurrentRoom = true)) } else { - val viaServers = MatrixPatterns.extractServerNameFromId(action.event.senderId) + val viaServers = MatrixPatterns.extractServerNameFromId(state.tombstoneEvent.senderId) ?.let { listOf(it) } .orEmpty() // need to provide feedback as joining could take some time _viewEvents.post(RoomDetailViewEvents.RoomReplacementStarted) setState { - copy(tombstoneEventHandling = Loading()) + copy(joinUpgradedRoomAsync = Loading()) } viewModelScope.launch { val result = runCatchingToAsync { @@ -600,7 +602,10 @@ class RoomDetailViewModel @AssistedInject constructor( roomId } setState { - copy(tombstoneEventHandling = result) + copy(joinUpgradedRoomAsync = result) + } + if (result is Success) { + _viewEvents.post(RoomDetailViewEvents.OpenRoom(roomId, closeCurrentRoom = true)) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt index 1ead34fadd..d10456b7c2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt @@ -65,7 +65,7 @@ data class RoomDetailViewState( val typingMessage: String? = null, val sendMode: SendMode = SendMode.REGULAR("", false), val tombstoneEvent: Event? = null, - val tombstoneEventHandling: Async = Uninitialized, + val joinUpgradedRoomAsync: Async = Uninitialized, val syncState: SyncState = SyncState.Idle, val highlightedEventId: String? = null, val unreadState: UnreadState = UnreadState.Unknown, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt index 0de905d059..81b2d04139 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt @@ -61,7 +61,6 @@ class MigrateRoomBottomSheet : } override fun invalidate() = withState(viewModel) { state -> - views.headerText.setText(if (state.isPublic) R.string.upgrade_public_room else R.string.upgrade_private_room) views.upgradeFromTo.text = getString(R.string.upgrade_public_room_from_to, state.currentVersion, state.newVersion) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt index d01888c78b..231bb319f0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt @@ -84,16 +84,6 @@ class MigrateRoomViewModel @AssistedInject constructor( } } - val upgradingProgress: ((indeterminate: Boolean, progress: Int, total: Int) -> Unit) = { indeterminate, progress, total -> - setState { - copy( - upgradingProgress = progress, - upgradingProgressTotal = total, - upgradingProgressIndeterminate = indeterminate - ) - } - } - private fun handleUpgradeRoom() = withState { state -> val summary = session.getRoomSummary(state.roomId) setState { @@ -105,7 +95,15 @@ class MigrateRoomViewModel @AssistedInject constructor( newVersion = state.newVersion, userIdsToAutoInvite = summary?.otherMemberIds?.takeIf { state.shouldIssueInvites } ?: emptyList(), parentSpaceToUpdate = summary?.flattenParentIds?.takeIf { state.shouldUpdateKnownParents } ?: emptyList(), - progressReporter = upgradingProgress + progressReporter = { indeterminate, progress, total -> + setState { + copy( + upgradingProgress = progress, + upgradingProgressTotal = total, + upgradingProgressIndeterminate = indeterminate + ) + } + } )) setState { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index 106062f7b3..be026894b6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -108,7 +108,7 @@ class RoomProfileController @Inject constructor( genericPositiveButtonItem { id("migrate_button") - text(host.stringProvider.getString(R.string.room_upgrade_to_recommened_version)) + text(host.stringProvider.getString(R.string.room_upgrade_to_recommended_version)) buttonClickAction { host.callback?.doMigrateToVersion(data.recommendedRoomVersion) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index 9fee87880a..d35e8f3ad5 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -84,6 +84,7 @@ class RoomProfileViewModel @AssistedInject constructor( .execute { async -> copy( roomCreateContent = async, + // This is a shortcut, we should do the next lines elsewhere, but keep it like that for the moment. recommendedRoomVersion = room.getRecommendedVersion(), isUsingUnstableRoomVersion = room.isUsingUnstableRoomVersion(), canUpgradeRoom = room.userMayUpgradeRoom(session.myUserId), diff --git a/vector/src/main/res/layout/activity_bug_report.xml b/vector/src/main/res/layout/activity_bug_report.xml index f9e290f29e..8943912ca4 100644 --- a/vector/src/main/res/layout/activity_bug_report.xml +++ b/vector/src/main/res/layout/activity_bug_report.xml @@ -39,7 +39,7 @@ @@ -26,8 +26,8 @@ android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:gravity="start" - android:textColor="?vctr_content_secondary" - android:text="@string/upgrade_room_warning" /> + android:text="@string/upgrade_room_warning" + android:textColor="?vctr_content_secondary" /> -