From fe0332957b6efb943df53ba26c14774fde2397f8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 14:53:25 +0200 Subject: [PATCH 01/11] Add API documentation --- .../org/matrix/android/sdk/api/session/user/UserService.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt index cd4fb216d3..063abdb5a0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt @@ -75,11 +75,14 @@ interface UserService { /** * Ignore users + * Note: once done, for the change to take effect, you have to request an initial sync. + * This may be improved in the future */ suspend fun ignoreUserIds(userIds: List) /** * Un-ignore some users + * Note: once done, for the change to take effect, you have to request an initial sync. */ suspend fun unIgnoreUserIds(userIds: List) } From 04045d2b307f6616d3c006bb92429dd9dbd87c59 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 14:55:02 +0200 Subject: [PATCH 02/11] Improve dialog when un-ignoring user. Add title and change button labels --- .../settings/ignored/VectorSettingsIgnoredUsersFragment.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index 7128639c81..f86d0aba9c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -80,11 +80,12 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( override fun onUserIdClicked(userId: String) { MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.room_participants_action_unignore_title) .setMessage(getString(R.string.settings_unignore_user, userId)) - .setPositiveButton(R.string.yes) { _, _ -> + .setPositiveButton(R.string.unignore) { _, _ -> viewModel.handle(IgnoredUsersAction.UnIgnore(userId)) } - .setNegativeButton(R.string.no, null) + .setNegativeButton(R.string.action_cancel, null) .show() } From 1468edd2f9ef067ec968080c32754f440cd0d767 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 15:09:26 +0200 Subject: [PATCH 03/11] One class per file --- .../settings/ignored/IgnoredUsersAction.kt | 23 ++++++++++++++++ .../settings/ignored/IgnoredUsersViewModel.kt | 21 +++------------ .../settings/ignored/IgnoredUsersViewState.kt | 27 +++++++++++++++++++ 3 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt new file mode 100644 index 0000000000..48199e557b --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 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 im.vector.app.features.settings.ignored + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class IgnoredUsersAction : VectorViewModelAction { + data class UnIgnore(val userId: String) : IgnoredUsersAction() +} diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index b2a7b2cbd1..a9b7e0c4ce 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -16,37 +16,24 @@ package im.vector.app.features.settings.ignored -import com.airbnb.mvrx.Async import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading -import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success -import com.airbnb.mvrx.Uninitialized import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel -import im.vector.app.core.platform.VectorViewModelAction import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.flow.flow -data class IgnoredUsersViewState( - val ignoredUsers: List = emptyList(), - val unIgnoreRequest: Async = Uninitialized -) : MavericksState - -sealed class IgnoredUsersAction : VectorViewModelAction { - data class UnIgnore(val userId: String) : IgnoredUsersAction() -} - -class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: IgnoredUsersViewState, - private val session: Session) : - VectorViewModel(initialState) { +class IgnoredUsersViewModel @AssistedInject constructor( + @Assisted initialState: IgnoredUsersViewState, + private val session: Session +) : VectorViewModel(initialState) { @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt new file mode 100644 index 0000000000..c402636dc8 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 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 im.vector.app.features.settings.ignored + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MavericksState +import com.airbnb.mvrx.Uninitialized +import org.matrix.android.sdk.api.session.user.model.User + +data class IgnoredUsersViewState( + val ignoredUsers: List = emptyList(), + val unIgnoreRequest: Async = Uninitialized +) : MavericksState From 1b95cd537bbc29663a83fdf64c9335a20135c234 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 15:11:46 +0200 Subject: [PATCH 04/11] Simplify ViewState --- .../settings/ignored/IgnoredUsersViewModel.kt | 16 ++-------------- .../settings/ignored/IgnoredUsersViewState.kt | 4 +--- .../VectorSettingsIgnoredUsersFragment.kt | 12 +----------- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index a9b7e0c4ce..f51d53fb07 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -16,10 +16,7 @@ package im.vector.app.features.settings.ignored -import com.airbnb.mvrx.Fail -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.Success import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -63,19 +60,10 @@ class IgnoredUsersViewModel @AssistedInject constructor( } private fun handleUnIgnore(action: IgnoredUsersAction.UnIgnore) { - setState { - copy( - unIgnoreRequest = Loading() - ) - } - + setState { copy(isLoading = true) } viewModelScope.launch { val result = runCatching { session.unIgnoreUserIds(listOf(action.userId)) } - setState { - copy( - unIgnoreRequest = result.fold(::Success, ::Fail) - ) - } + setState { copy(isLoading = false) } result.onFailure { _viewEvents.post(IgnoredUsersViewEvents.Failure(it)) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt index c402636dc8..3dc1bfe795 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt @@ -16,12 +16,10 @@ package im.vector.app.features.settings.ignored -import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState -import com.airbnb.mvrx.Uninitialized import org.matrix.android.sdk.api.session.user.model.User data class IgnoredUsersViewState( val ignoredUsers: List = emptyList(), - val unIgnoreRequest: Async = Uninitialized + val isLoading: Boolean = false ) : MavericksState diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index f86d0aba9c..57fa357387 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -22,8 +22,6 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -95,14 +93,6 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( override fun invalidate() = withState(viewModel) { state -> ignoredUsersController.update(state) - - handleUnIgnoreRequestStatus(state.unIgnoreRequest) - } - - private fun handleUnIgnoreRequestStatus(unIgnoreRequest: Async) { - views.waitingView.root.isVisible = when (unIgnoreRequest) { - is Loading -> true - else -> false - } + views.waitingView.root.isVisible = state.isLoading } } From 6d741c384477dfa1b8dc2ec9d43e0810e1021fb9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 15:17:29 +0200 Subject: [PATCH 05/11] Perform an initial sync after un-ignoring a user (#3439) --- .../features/settings/ignored/IgnoredUsersViewEvents.kt | 1 + .../features/settings/ignored/IgnoredUsersViewModel.kt | 9 +++++++-- .../ignored/VectorSettingsIgnoredUsersFragment.kt | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt index 2b2c3eb49d..8d597a9189 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt @@ -25,4 +25,5 @@ import im.vector.app.core.platform.VectorViewEvents sealed class IgnoredUsersViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : IgnoredUsersViewEvents() data class Failure(val throwable: Throwable) : IgnoredUsersViewEvents() + object Success : IgnoredUsersViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index f51d53fb07..14f7cd9230 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -62,9 +62,14 @@ class IgnoredUsersViewModel @AssistedInject constructor( private fun handleUnIgnore(action: IgnoredUsersAction.UnIgnore) { setState { copy(isLoading = true) } viewModelScope.launch { - val result = runCatching { session.unIgnoreUserIds(listOf(action.userId)) } + val viewEvent = try { + session.unIgnoreUserIds(listOf(action.userId)) + IgnoredUsersViewEvents.Success + } catch (throwable: Throwable) { + IgnoredUsersViewEvents.Failure(throwable) + } setState { copy(isLoading = false) } - result.onFailure { _viewEvents.post(IgnoredUsersViewEvents.Failure(it)) } + _viewEvents.post(viewEvent) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index 57fa357387..66fa690b82 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -30,6 +30,8 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.plan.MobileScreen import javax.inject.Inject @@ -60,10 +62,16 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( when (it) { is IgnoredUsersViewEvents.Loading -> showLoading(it.message) is IgnoredUsersViewEvents.Failure -> showFailure(it.throwable) + IgnoredUsersViewEvents.Success -> handleSuccess() } } } + private fun handleSuccess() { + // A user has been un-ignored, perform a initial sync + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } + override fun onDestroyView() { ignoredUsersController.callback = null views.genericRecyclerView.cleanup() From 9c132a32443034ff2ce89046e9d82e9f3adb842a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 15:26:36 +0200 Subject: [PATCH 06/11] Perform an initial sync after un-ignoring a user, from the room member screen (#3439) --- .../roommemberprofile/RoomMemberProfileFragment.kt | 11 ++++++++++- .../roommemberprofile/RoomMemberProfileViewEvents.kt | 2 +- .../roommemberprofile/RoomMemberProfileViewModel.kt | 2 +- vector/src/main/res/values/strings.xml | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index 760bbe9353..5fee420b21 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -47,6 +47,8 @@ import im.vector.app.databinding.DialogBaseEditTextBinding import im.vector.app.databinding.DialogShareQrCodeBinding import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.ViewStubRoomMemberProfileHeaderBinding +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.displayname.getBestName @@ -131,13 +133,20 @@ class RoomMemberProfileFragment @Inject constructor( is RoomMemberProfileViewEvents.OnKickActionSuccess -> Unit is RoomMemberProfileViewEvents.OnSetPowerLevelSuccess -> Unit is RoomMemberProfileViewEvents.OnBanActionSuccess -> Unit - is RoomMemberProfileViewEvents.OnIgnoreActionSuccess -> Unit + is RoomMemberProfileViewEvents.OnIgnoreActionSuccess -> handleOnIgnoreActionSuccess(it) is RoomMemberProfileViewEvents.OnInviteActionSuccess -> Unit } } setupLongClicks() } + private fun handleOnIgnoreActionSuccess(action: RoomMemberProfileViewEvents.OnIgnoreActionSuccess) { + if (action.shouldPerformInitialSync) { + // A user has been un-ignored, perform a initial sync + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } + } + private fun setupLongClicks() { headerViews.memberProfileNameView.copyOnLongClick() headerViews.memberProfileIdView.copyOnLongClick() diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt index efe23eeff0..1857f5cdc4 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt @@ -25,7 +25,7 @@ sealed class RoomMemberProfileViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : RoomMemberProfileViewEvents() data class Failure(val throwable: Throwable) : RoomMemberProfileViewEvents() - object OnIgnoreActionSuccess : RoomMemberProfileViewEvents() + data class OnIgnoreActionSuccess(val shouldPerformInitialSync: Boolean) : RoomMemberProfileViewEvents() object OnSetPowerLevelSuccess : RoomMemberProfileViewEvents() object OnInviteActionSuccess : RoomMemberProfileViewEvents() object OnKickActionSuccess : RoomMemberProfileViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 4bcf9ef55d..addc2c71ef 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -390,7 +390,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor( } else { session.ignoreUserIds(listOf(state.userId)) } - RoomMemberProfileViewEvents.OnIgnoreActionSuccess + RoomMemberProfileViewEvents.OnIgnoreActionSuccess(isIgnored) } catch (failure: Throwable) { RoomMemberProfileViewEvents.Failure(failure) } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 551983637c..ffd4333071 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -634,7 +634,7 @@ Ignore Unignore user - Unignoring this user will show all messages from them again. + Unignoring this user will show all messages from them again.\n\nNote that this action will restart the app and it may take some time. Unignore Cancel invite From a712ffee689224a5577b1c27f4e752c748de6d25 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 15:34:50 +0200 Subject: [PATCH 07/11] data class --- .../room/detail/composer/MessageComposerViewEvents.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt index c1af838795..0b8ab1fe04 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt @@ -30,13 +30,13 @@ sealed class MessageComposerViewEvents : VectorViewEvents { object MessageSent : SendMessageResult() data class JoinRoomCommandSuccess(val roomId: String) : SendMessageResult() - class SlashCommandError(val command: Command) : SendMessageResult() - class SlashCommandUnknown(val command: String) : SendMessageResult() - class SlashCommandNotSupportedInThreads(val command: Command) : SendMessageResult() + data class SlashCommandError(val command: Command) : SendMessageResult() + data class SlashCommandUnknown(val command: String) : SendMessageResult() + data class SlashCommandNotSupportedInThreads(val command: Command) : SendMessageResult() data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() object SlashCommandLoading : SendMessageResult() data class SlashCommandResultOk(@StringRes val messageRes: Int? = null) : SendMessageResult() - class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() + data class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() data class OpenRoomMemberProfile(val userId: String) : MessageComposerViewEvents() From 8da5016767f8666d7c2081d8ee8359e19aeb2573 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 15:50:58 +0200 Subject: [PATCH 08/11] Rename val --- .../composer/MessageComposerViewModel.kt | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index aabc319ee2..9a82d26416 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -195,7 +195,7 @@ class MessageComposerViewModel @AssistedInject constructor( } when (state.sendMode) { is SendMode.Regular -> { - when (val slashCommandResult = commandParser.parseSlashCommand( + when (val parsedCommand = commandParser.parseSlashCommand( textMessage = action.text, isInThreadTimeline = state.isInThreadTimeline())) { is ParsedCommand.ErrorNotACommand -> { @@ -213,93 +213,93 @@ class MessageComposerViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.ErrorSyntax -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandError(slashCommandResult.command)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandError(parsedCommand.command)) } is ParsedCommand.ErrorEmptySlashCommand -> { _viewEvents.post(MessageComposerViewEvents.SlashCommandUnknown("/")) } is ParsedCommand.ErrorUnknownSlashCommand -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandUnknown(slashCommandResult.slashCommand)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandUnknown(parsedCommand.slashCommand)) } is ParsedCommand.ErrorCommandNotSupportedInThreads -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandNotSupportedInThreads(slashCommandResult.command)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandNotSupportedInThreads(parsedCommand.command)) } is ParsedCommand.SendPlainText -> { // Send the text message to the room, without markdown if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, autoMarkdown = false) } else { - room.sendTextMessage(slashCommandResult.message, autoMarkdown = false) + room.sendTextMessage(parsedCommand.message, autoMarkdown = false) } _viewEvents.post(MessageComposerViewEvents.MessageSent) popDraft() } is ParsedCommand.ChangeRoomName -> { - handleChangeRoomNameSlashCommand(slashCommandResult) + handleChangeRoomNameSlashCommand(parsedCommand) } is ParsedCommand.Invite -> { - handleInviteSlashCommand(slashCommandResult) + handleInviteSlashCommand(parsedCommand) } is ParsedCommand.Invite3Pid -> { - handleInvite3pidSlashCommand(slashCommandResult) + handleInvite3pidSlashCommand(parsedCommand) } is ParsedCommand.SetUserPowerLevel -> { - handleSetUserPowerLevel(slashCommandResult) + handleSetUserPowerLevel(parsedCommand) } is ParsedCommand.ClearScalarToken -> { // TODO _viewEvents.post(MessageComposerViewEvents.SlashCommandNotImplemented) } is ParsedCommand.SetMarkdown -> { - vectorPreferences.setMarkdownEnabled(slashCommandResult.enable) + vectorPreferences.setMarkdownEnabled(parsedCommand.enable) _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk( - if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) + if (parsedCommand.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) popDraft() } is ParsedCommand.BanUser -> { - handleBanSlashCommand(slashCommandResult) + handleBanSlashCommand(parsedCommand) } is ParsedCommand.UnbanUser -> { - handleUnbanSlashCommand(slashCommandResult) + handleUnbanSlashCommand(parsedCommand) } is ParsedCommand.IgnoreUser -> { - handleIgnoreSlashCommand(slashCommandResult) + handleIgnoreSlashCommand(parsedCommand) } is ParsedCommand.UnignoreUser -> { - handleUnignoreSlashCommand(slashCommandResult) + handleUnignoreSlashCommand(parsedCommand) } is ParsedCommand.RemoveUser -> { - handleRemoveSlashCommand(slashCommandResult) + handleRemoveSlashCommand(parsedCommand) } is ParsedCommand.JoinRoom -> { - handleJoinToAnotherRoomSlashCommand(slashCommandResult) + handleJoinToAnotherRoomSlashCommand(parsedCommand) popDraft() } is ParsedCommand.PartRoom -> { - handlePartSlashCommand(slashCommandResult) + handlePartSlashCommand(parsedCommand) } is ParsedCommand.SendEmote -> { if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) } else { - room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) + room.sendTextMessage(parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) } _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendRainbow -> { - val message = slashCommandResult.message.toString() + val message = parsedCommand.message.toString() if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, formattedText = rainbowGenerator.generate(message)) } else { room.sendFormattedTextMessage(message, rainbowGenerator.generate(message)) @@ -308,11 +308,11 @@ class MessageComposerViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.SendRainbowEmote -> { - val message = slashCommandResult.message.toString() + val message = parsedCommand.message.toString() if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, formattedText = rainbowGenerator.generate(message)) } else { @@ -323,8 +323,8 @@ class MessageComposerViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.SendSpoiler -> { - val text = "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})" - val formattedText = "${slashCommandResult.message}" + val text = "[${stringProvider.getString(R.string.spoiler)}](${parsedCommand.message})" + val formattedText = "${parsedCommand.message}" if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, @@ -339,38 +339,38 @@ class MessageComposerViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.SendShrug -> { - sendPrefixedMessage("¯\\_(ツ)_/¯", slashCommandResult.message, state.rootThreadEventId) + sendPrefixedMessage("¯\\_(ツ)_/¯", parsedCommand.message, state.rootThreadEventId) _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendLenny -> { - sendPrefixedMessage("( ͡° ͜ʖ ͡°)", slashCommandResult.message, state.rootThreadEventId) + sendPrefixedMessage("( ͡° ͜ʖ ͡°)", parsedCommand.message, state.rootThreadEventId) _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendChatEffect -> { - sendChatEffect(slashCommandResult) + sendChatEffect(parsedCommand) _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.ChangeTopic -> { - handleChangeTopicSlashCommand(slashCommandResult) + handleChangeTopicSlashCommand(parsedCommand) } is ParsedCommand.ChangeDisplayName -> { - handleChangeDisplayNameSlashCommand(slashCommandResult) + handleChangeDisplayNameSlashCommand(parsedCommand) } is ParsedCommand.ChangeDisplayNameForRoom -> { - handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) + handleChangeDisplayNameForRoomSlashCommand(parsedCommand) } is ParsedCommand.ChangeRoomAvatar -> { - handleChangeRoomAvatarSlashCommand(slashCommandResult) + handleChangeRoomAvatarSlashCommand(parsedCommand) } is ParsedCommand.ChangeAvatarForRoom -> { - handleChangeAvatarForRoomSlashCommand(slashCommandResult) + handleChangeAvatarForRoomSlashCommand(parsedCommand) } is ParsedCommand.ShowUser -> { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) - handleWhoisSlashCommand(slashCommandResult) + handleWhoisSlashCommand(parsedCommand) popDraft() } is ParsedCommand.DiscardSession -> { @@ -391,8 +391,8 @@ class MessageComposerViewModel @AssistedInject constructor( viewModelScope.launch(Dispatchers.IO) { try { val params = CreateSpaceParams().apply { - name = slashCommandResult.name - invitedUserIds.addAll(slashCommandResult.invitees) + name = parsedCommand.name + invitedUserIds.addAll(parsedCommand.invitees) } val spaceId = session.spaceService().createSpace(params) session.spaceService().getSpace(spaceId) @@ -414,7 +414,7 @@ class MessageComposerViewModel @AssistedInject constructor( _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { - session.spaceService().getSpace(slashCommandResult.spaceId) + session.spaceService().getSpace(parsedCommand.spaceId) ?.addChildren( room.roomId, null, @@ -433,7 +433,7 @@ class MessageComposerViewModel @AssistedInject constructor( _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { - session.spaceService().joinSpace(slashCommandResult.spaceIdOrAlias) + session.spaceService().joinSpace(parsedCommand.spaceIdOrAlias) popDraft() _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { @@ -445,7 +445,7 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.LeaveRoom -> { viewModelScope.launch(Dispatchers.IO) { try { - session.leaveRoom(slashCommandResult.roomId) + session.leaveRoom(parsedCommand.roomId) popDraft() _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { @@ -457,7 +457,7 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.UpgradeRoom -> { _viewEvents.post( MessageComposerViewEvents.ShowRoomUpgradeDialog( - slashCommandResult.newVersion, + parsedCommand.newVersion, room.roomSummary()?.isPublic ?: false ) ) From 0bc557640a4e2050f84b77dbc6c7e8a9c6e42cd7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 16:36:40 +0200 Subject: [PATCH 09/11] Perform an initial sync after un-ignoring a user, from the slash command (#3439) --- .../home/room/detail/TimelineFragment.kt | 74 ++++++++++++----- .../detail/composer/MessageComposerAction.kt | 2 + .../composer/MessageComposerViewEvents.kt | 5 +- .../composer/MessageComposerViewModel.kt | 79 +++++++++++-------- 4 files changed, 106 insertions(+), 54 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index a722729629..d3c70b01c0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -119,6 +119,8 @@ import im.vector.app.core.utils.startInstallFromSourceIntent import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogReportContentBinding import im.vector.app.databinding.FragmentTimelineBinding +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.extensions.toAnalyticsInteraction import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.analytics.plan.MobileScreen @@ -136,6 +138,7 @@ import im.vector.app.features.call.conference.ConferenceEventObserver import im.vector.app.features.call.conference.JitsiCallViewModel import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.command.Command +import im.vector.app.features.command.ParsedCommand import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.home.AvatarRenderer @@ -437,6 +440,7 @@ class TimelineFragment @Inject constructor( messageComposerViewModel.observeViewEvents { when (it) { is MessageComposerViewEvents.JoinRoomCommandSuccess -> handleJoinedToAnotherRoom(it) + is MessageComposerViewEvents.SlashCommandConfirmationRequest -> handleSlashCommandConfirmationRequest(it) is MessageComposerViewEvents.SendMessageResult -> renderSendMessageResult(it) is MessageComposerViewEvents.ShowMessage -> showSnackWithMessage(it.message) is MessageComposerViewEvents.ShowRoomUpgradeDialog -> handleShowRoomUpgradeDialog(it) @@ -495,6 +499,25 @@ class TimelineFragment @Inject constructor( } } + private fun handleSlashCommandConfirmationRequest(action: MessageComposerViewEvents.SlashCommandConfirmationRequest) { + when (action.parsedCommand) { + is ParsedCommand.UnignoreUser -> promptUnignoreUser(action.parsedCommand) + else -> TODO("Add case for ${action.parsedCommand.javaClass.simpleName}") + } + lockSendButton = false + } + + private fun promptUnignoreUser(command: ParsedCommand.UnignoreUser) { + MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.room_participants_action_unignore_title) + .setMessage(getString(R.string.settings_unignore_user, command.userId)) + .setPositiveButton(R.string.unignore) { _, _ -> + messageComposerViewModel.handle(MessageComposerAction.SlashCommandConfirmed(command)) + } + .setNegativeButton(R.string.action_cancel, null) + .show() + } + private fun renderVoiceMessageMode(content: String) { ContentAttachmentData.fromJsonString(content)?.let { audioAttachmentData -> views.voiceMessageRecorderView.isVisible = true @@ -1679,9 +1702,7 @@ class TimelineFragment @Inject constructor( displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command)) } is MessageComposerViewEvents.SlashCommandResultOk -> { - dismissLoadingDialog() - views.composerLayout.setTextIfDifferent("") - sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) } + handleSlashCommandResultOk(sendMessageResult.parsedCommand) } is MessageComposerViewEvents.SlashCommandResultError -> { dismissLoadingDialog() @@ -1698,6 +1719,21 @@ class TimelineFragment @Inject constructor( lockSendButton = false } + private fun handleSlashCommandResultOk(parsedCommand: ParsedCommand) { + dismissLoadingDialog() + views.composerLayout.setTextIfDifferent("") + when (parsedCommand) { + is ParsedCommand.SetMarkdown -> { + showSnackWithMessage(getString(if (parsedCommand.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) + } + is ParsedCommand.UnignoreUser -> { + // A user has been un-ignored, perform a initial sync + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } + else -> Unit + } + } + private fun displayCommandError(message: String) { MaterialAlertDialogBuilder(requireActivity()) .setTitle(R.string.command_error) @@ -2411,23 +2447,23 @@ class TimelineFragment @Inject constructor( } private fun displayThreadsBetaOptInDialog() { - activity?.let { - MaterialAlertDialogBuilder(it) - .setTitle(R.string.threads_beta_enable_notice_title) - .setMessage(threadsManager.getBetaEnableThreadsMessage()) - .setCancelable(true) - .setNegativeButton(R.string.action_not_now) { _, _ -> } - .setPositiveButton(R.string.action_try_it_out) { _, _ -> - threadsManager.enableThreadsAndRestart(it) - } - .show() - ?.findViewById(android.R.id.message) - ?.apply { - linksClickable = true - movementMethod = LinkMovementMethod.getInstance() - } - } + activity?.let { + MaterialAlertDialogBuilder(it) + .setTitle(R.string.threads_beta_enable_notice_title) + .setMessage(threadsManager.getBetaEnableThreadsMessage()) + .setCancelable(true) + .setNegativeButton(R.string.action_not_now) { _, _ -> } + .setPositiveButton(R.string.action_try_it_out) { _, _ -> + threadsManager.enableThreadsAndRestart(it) + } + .show() + ?.findViewById(android.R.id.message) + ?.apply { + linksClickable = true + movementMethod = LinkMovementMethod.getInstance() + } } + } /** * Navigate to Threads list for the current room diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt index dca698ee52..0da324ffc2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.detail.composer import im.vector.app.core.platform.VectorViewModelAction +import im.vector.app.features.command.ParsedCommand import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageRecorderView import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent @@ -30,6 +31,7 @@ sealed class MessageComposerAction : VectorViewModelAction { data class UserIsTyping(val isTyping: Boolean) : MessageComposerAction() data class OnTextChanged(val text: CharSequence) : MessageComposerAction() data class OnEntersBackground(val composerText: String) : MessageComposerAction() + data class SlashCommandConfirmed(val parsedCommand: ParsedCommand) : MessageComposerAction() // Voice Message data class InitializeVoiceRecorder(val attachmentData: ContentAttachmentData) : MessageComposerAction() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt index 0b8ab1fe04..fd302005c6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt @@ -19,6 +19,7 @@ package im.vector.app.features.home.room.detail.composer import androidx.annotation.StringRes import im.vector.app.core.platform.VectorViewEvents import im.vector.app.features.command.Command +import im.vector.app.features.command.ParsedCommand sealed class MessageComposerViewEvents : VectorViewEvents { @@ -35,9 +36,11 @@ sealed class MessageComposerViewEvents : VectorViewEvents { data class SlashCommandNotSupportedInThreads(val command: Command) : SendMessageResult() data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() object SlashCommandLoading : SendMessageResult() - data class SlashCommandResultOk(@StringRes val messageRes: Int? = null) : SendMessageResult() + data class SlashCommandResultOk(val parsedCommand: ParsedCommand) : SendMessageResult() data class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() + data class SlashCommandConfirmationRequest(val parsedCommand: ParsedCommand) : MessageComposerViewEvents() + data class OpenRoomMemberProfile(val userId: String) : MessageComposerViewEvents() // TODO Remove diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index 9a82d26416..9c81a39941 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -110,6 +110,7 @@ class MessageComposerViewModel @AssistedInject constructor( is MessageComposerAction.VoiceWaveformTouchedUp -> handleVoiceWaveformTouchedUp(action) is MessageComposerAction.VoiceWaveformMovedTo -> handleVoiceWaveformMovedTo(action) is MessageComposerAction.AudioSeekBarMovedTo -> handleAudioSeekBarMovedTo(action) + is MessageComposerAction.SlashCommandConfirmed -> handleSlashCommandConfirmed(action) } } @@ -255,8 +256,7 @@ class MessageComposerViewModel @AssistedInject constructor( } is ParsedCommand.SetMarkdown -> { vectorPreferences.setMarkdownEnabled(parsedCommand.enable) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk( - if (parsedCommand.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.BanUser -> { @@ -291,7 +291,7 @@ class MessageComposerViewModel @AssistedInject constructor( } else { room.sendTextMessage(parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendRainbow -> { @@ -304,7 +304,7 @@ class MessageComposerViewModel @AssistedInject constructor( } else { room.sendFormattedTextMessage(message, rainbowGenerator.generate(message)) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendRainbowEmote -> { @@ -319,7 +319,7 @@ class MessageComposerViewModel @AssistedInject constructor( room.sendFormattedTextMessage(message, rainbowGenerator.generate(message), MessageType.MSGTYPE_EMOTE) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendSpoiler -> { @@ -335,22 +335,22 @@ class MessageComposerViewModel @AssistedInject constructor( text, formattedText) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendShrug -> { sendPrefixedMessage("¯\\_(ツ)_/¯", parsedCommand.message, state.rootThreadEventId) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendLenny -> { sendPrefixedMessage("( ͡° ͜ʖ ͡°)", parsedCommand.message, state.rootThreadEventId) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendChatEffect -> { sendChatEffect(parsedCommand) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.ChangeTopic -> { @@ -369,17 +369,17 @@ class MessageComposerViewModel @AssistedInject constructor( handleChangeAvatarForRoomSlashCommand(parsedCommand) } is ParsedCommand.ShowUser -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) handleWhoisSlashCommand(parsedCommand) popDraft() } is ParsedCommand.DiscardSession -> { if (room.isEncrypted()) { session.cryptoService().discardOutboundSession(room.roomId) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } else { - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) _viewEvents.post( MessageComposerViewEvents .ShowMessage(stringProvider.getString(R.string.command_description_discard_session_not_handled)) @@ -403,7 +403,7 @@ class MessageComposerViewModel @AssistedInject constructor( true ) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -422,7 +422,7 @@ class MessageComposerViewModel @AssistedInject constructor( false ) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -435,7 +435,7 @@ class MessageComposerViewModel @AssistedInject constructor( try { session.spaceService().joinSpace(parsedCommand.spaceIdOrAlias) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -447,7 +447,7 @@ class MessageComposerViewModel @AssistedInject constructor( try { session.leaveRoom(parsedCommand.roomId) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -461,7 +461,7 @@ class MessageComposerViewModel @AssistedInject constructor( room.roomSummary()?.isPublic ?: false ) ) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } } @@ -644,19 +644,19 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeTopic) { room.updateTopic(changeTopic.topic) } } private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(invite) { room.invite(invite.userId, invite.reason) } } private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(invite) { room.invite3pid(invite.threePid) } } @@ -669,19 +669,19 @@ class MessageComposerViewModel @AssistedInject constructor( ?.toContent() ?: return - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(setUserPowerLevel) { room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent) } } private fun handleChangeDisplayNameSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayName) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeDisplayName) { session.setDisplayName(session.myUserId, changeDisplayName.displayName) } } private fun handlePartSlashCommand(command: ParsedCommand.PartRoom) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(command) { if (command.roomAlias == null) { // Leave the current room room @@ -697,25 +697,25 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleRemoveSlashCommand(removeUser: ParsedCommand.RemoveUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(removeUser) { room.remove(removeUser.userId, removeUser.reason) } } private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(ban) { room.ban(ban.userId, ban.reason) } } private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(unban) { room.unban(unban.userId, unban.reason) } } private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeRoomName) { room.updateName(changeRoomName.name) } } @@ -727,7 +727,7 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeDisplayName) { getMyRoomMemberContent() ?.copy(displayName = changeDisplayName.displayName) ?.toContent() @@ -738,13 +738,13 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeAvatar) { room.sendStateEvent(EventType.STATE_ROOM_AVATAR, stateKey = "", RoomAvatarContent(changeAvatar.url).toContent()) } } private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeAvatar) { getMyRoomMemberContent() ?.copy(avatarUrl = changeAvatar.url) ?.toContent() @@ -755,13 +755,24 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleIgnoreSlashCommand(ignore: ParsedCommand.IgnoreUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(ignore) { session.ignoreUserIds(listOf(ignore.userId)) } } private fun handleUnignoreSlashCommand(unignore: ParsedCommand.UnignoreUser) { - launchSlashCommandFlowSuspendable { + _viewEvents.post(MessageComposerViewEvents.SlashCommandConfirmationRequest(unignore)) + } + + private fun handleSlashCommandConfirmed(action: MessageComposerAction.SlashCommandConfirmed) { + when (action.parsedCommand) { + is ParsedCommand.UnignoreUser -> handleUnignoreSlashCommandConfirmed(action.parsedCommand) + else -> TODO("Not handled yet") + } + } + + private fun handleUnignoreSlashCommandConfirmed(unignore: ParsedCommand.UnignoreUser) { + launchSlashCommandFlowSuspendable(unignore) { session.unIgnoreUserIds(listOf(unignore.userId)) } } @@ -900,13 +911,13 @@ class MessageComposerViewModel @AssistedInject constructor( } } - private fun launchSlashCommandFlowSuspendable(block: suspend () -> Unit) { + private fun launchSlashCommandFlowSuspendable(parsedCommand: ParsedCommand, block: suspend () -> Unit) { _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch { val event = try { block() popDraft() - MessageComposerViewEvents.SlashCommandResultOk() + MessageComposerViewEvents.SlashCommandResultOk(parsedCommand) } catch (failure: Throwable) { MessageComposerViewEvents.SlashCommandResultError(failure) } From 7b7c5097967c6932ef45286b2164482330d2a6ea Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 16:47:04 +0200 Subject: [PATCH 10/11] Changelog --- changelog.d/5767.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5767.bugfix diff --git a/changelog.d/5767.bugfix b/changelog.d/5767.bugfix new file mode 100644 index 0000000000..2a34fbf4b3 --- /dev/null +++ b/changelog.d/5767.bugfix @@ -0,0 +1 @@ +Unignoring a user will perform an initial sync \ No newline at end of file From b1cff1a5e850715fa6c7935c8d59a7e9161892bc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Apr 2022 16:47:34 +0200 Subject: [PATCH 11/11] Remove unused code --- .../home/room/detail/composer/MessageComposerViewEvents.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt index fd302005c6..e1f6923d21 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt @@ -16,7 +16,6 @@ package im.vector.app.features.home.room.detail.composer -import androidx.annotation.StringRes import im.vector.app.core.platform.VectorViewEvents import im.vector.app.features.command.Command import im.vector.app.features.command.ParsedCommand @@ -34,7 +33,6 @@ sealed class MessageComposerViewEvents : VectorViewEvents { data class SlashCommandError(val command: Command) : SendMessageResult() data class SlashCommandUnknown(val command: String) : SendMessageResult() data class SlashCommandNotSupportedInThreads(val command: Command) : SendMessageResult() - data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() object SlashCommandLoading : SendMessageResult() data class SlashCommandResultOk(val parsedCommand: ParsedCommand) : SendMessageResult() data class SlashCommandResultError(val throwable: Throwable) : SendMessageResult()