diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt index ae601bb0f3..949ac4cdb9 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModel.kt @@ -23,7 +23,11 @@ import im.vector.riotx.core.utils.LiveEvent import io.reactivex.Observable import io.reactivex.Single -abstract class VectorViewModel(initialState: S) +interface VectorViewModelAction + +object EmptyAction : VectorViewModelAction + +abstract class VectorViewModel(initialState: S) : BaseMvRxViewModel(initialState, false) { // Generic handling of any request error @@ -52,4 +56,6 @@ abstract class VectorViewModel(initialState: S) .onErrorReturn { Fail(it) } .doOnNext { setState { stateReducer(it) } } } + + abstract fun handle(action: A) } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeyBackupSettingsActions.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeyBackupSettingsActions.kt new file mode 100644 index 0000000000..5ced274b21 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeyBackupSettingsActions.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2019 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.riotx.features.crypto.keysbackup.settings + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class KeyBackupSettingsActions : VectorViewModelAction { + object Init : KeyBackupSettingsActions() + object GetKeyBackupTrust : KeyBackupSettingsActions() + object DeleteKeyBackup : KeyBackupSettingsActions() +} diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt index a58c99992d..0d0ce551aa 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt @@ -51,7 +51,7 @@ class KeysBackupManageActivity : SimpleFragmentActivity() { super.initUiAndData() if (supportFragmentManager.fragments.isEmpty()) { replaceFragment(R.id.container, KeysBackupSettingsFragment::class.java) - viewModel.init() + viewModel.handle(KeyBackupSettingsActions.Init) } // Observe the deletion of keys backup diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt index 288d862413..d281cd253f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt @@ -66,7 +66,7 @@ class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSetti .setMessage(R.string.keys_backup_settings_delete_confirm_message) .setCancelable(false) .setPositiveButton(R.string.keys_backup_settings_delete_confirm_title) { _, _ -> - viewModel.deleteCurrentBackup() + viewModel.handle(KeyBackupSettingsActions.DeleteKeyBackup) } .setNegativeButton(R.string.cancel, null) .setCancelable(true) @@ -75,10 +75,10 @@ class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSetti } override fun loadTrustData() { - viewModel.getKeysBackupTrust() + viewModel.handle(KeyBackupSettingsActions.GetKeyBackupTrust) } override fun loadKeysBackupState() { - viewModel.init() + viewModel.handle(KeyBackupSettingsActions.Init) } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index 67690b838a..95b761291c 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -15,13 +15,7 @@ */ package im.vector.riotx.features.crypto.keysbackup.settings -import com.airbnb.mvrx.ActivityViewModelContext -import com.airbnb.mvrx.Fail -import com.airbnb.mvrx.Loading -import com.airbnb.mvrx.MvRxViewModelFactory -import com.airbnb.mvrx.Success -import com.airbnb.mvrx.Uninitialized -import com.airbnb.mvrx.ViewModelContext +import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback @@ -34,8 +28,8 @@ import im.vector.riotx.core.platform.VectorViewModel class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, session: Session -) : VectorViewModel(initialState), - KeysBackupStateListener { +) : VectorViewModel(initialState), + KeysBackupStateListener { @AssistedInject.Factory interface Factory { @@ -64,11 +58,19 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS getKeysBackupTrust() } - fun init() { + override fun handle(action: KeyBackupSettingsActions) { + when (action) { + KeyBackupSettingsActions.Init -> init() + KeyBackupSettingsActions.GetKeyBackupTrust -> getKeysBackupTrust() + KeyBackupSettingsActions.DeleteKeyBackup -> deleteCurrentBackup() + } + } + + private fun init() { keysBackupService.forceUsingLastVersion(object : MatrixCallback {}) } - fun getKeysBackupTrust() = withState { state -> + private fun getKeysBackupTrust() = withState { state -> val versionResult = keysBackupService.keysBackupVersion if (state.keysBackupVersionTrust is Uninitialized && versionResult != null) { @@ -116,7 +118,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS getKeysBackupTrust() } - fun deleteCurrentBackup() { + private fun deleteCurrentBackup() { val keysBackupService = keysBackupService if (keysBackupService.currentBackupVersion != null) { @@ -153,6 +155,6 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS val currentBackupState = keysBackupService.state return currentBackupState == KeysBackupState.Unknown - || currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver + || currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt new file mode 100644 index 0000000000..189a1e8aeb --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2019 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.riotx.features.home + +import im.vector.riotx.core.platform.VectorViewModelAction +import im.vector.riotx.features.home.room.list.RoomListFragment + +sealed class HomeDetailAction : VectorViewModelAction { + data class SwitchDisplayMode(val displayMode: RoomListFragment.DisplayMode) : HomeDetailAction() +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt index c6b7280f0c..944d323306 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt @@ -141,7 +141,7 @@ class HomeDetailFragment @Inject constructor( R.id.bottom_action_rooms -> RoomListFragment.DisplayMode.ROOMS else -> RoomListFragment.DisplayMode.HOME } - viewModel.switchDisplayMode(displayMode) + viewModel.handle(HomeDetailAction.SwitchDisplayMode(displayMode)) true } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt index 585ecf126e..ca552dc234 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt @@ -27,7 +27,6 @@ import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.group.SelectedGroupDataSource -import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.ui.UiStateRepository import io.reactivex.schedulers.Schedulers @@ -41,7 +40,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho private val selectedGroupStore: SelectedGroupDataSource, private val homeRoomListStore: HomeRoomListDataSource, private val stringProvider: StringProvider) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -70,13 +69,19 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho observeRoomSummaries() } - fun switchDisplayMode(displayMode: RoomListFragment.DisplayMode) = withState { state -> - if (state.displayMode != displayMode) { + override fun handle(action: HomeDetailAction) { + when (action) { + is HomeDetailAction.SwitchDisplayMode -> handleSwitchDisplayMode(action) + } + } + + private fun handleSwitchDisplayMode(action: HomeDetailAction.SwitchDisplayMode) = withState { state -> + if (state.displayMode != action.displayMode) { setState { - copy(displayMode = displayMode) + copy(displayMode = action.displayMode) } - uiStateRepository.storeDisplayMode(displayMode) + uiStateRepository.storeDisplayMode(action.displayMode) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActions.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActions.kt index 3b0b36df34..17aadcff35 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActions.kt @@ -17,8 +17,9 @@ package im.vector.riotx.features.home.createdirect import im.vector.matrix.android.api.session.user.model.User +import im.vector.riotx.core.platform.VectorViewModelAction -sealed class CreateDirectRoomActions { +sealed class CreateDirectRoomActions : VectorViewModelAction { object CreateRoomAndInviteSelectedUsers : CreateDirectRoomActions() data class FilterKnownUsers(val value: String) : CreateDirectRoomActions() data class SearchDirectoryUsers(val value: String) : CreateDirectRoomActions() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomViewModel.kt index aef2340478..776a044230 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomViewModel.kt @@ -51,7 +51,7 @@ data class SelectUserAction( class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted initialState: CreateDirectRoomViewState, private val session: Session) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -79,7 +79,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted observeDirectoryUsers() } - fun handle(action: CreateDirectRoomActions) { + override fun handle(action: CreateDirectRoomActions) { when (action) { is CreateDirectRoomActions.CreateRoomAndInviteSelectedUsers -> createRoomAndInviteSelectedUsers() is CreateDirectRoomActions.FilterKnownUsers -> knownUsersFilter.accept(Option.just(action.value)) diff --git a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListActions.kt b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListActions.kt index 7e0a36d032..74fc7ec76b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListActions.kt @@ -17,8 +17,8 @@ package im.vector.riotx.features.home.group import im.vector.matrix.android.api.session.group.model.GroupSummary +import im.vector.riotx.core.platform.VectorViewModelAction -sealed class GroupListActions { - +sealed class GroupListActions : VectorViewModelAction { data class SelectGroup(val groupSummary: GroupSummary) : GroupListActions() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListFragment.kt index 9972e7ac1c..d5951830b2 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListFragment.kt @@ -62,6 +62,6 @@ class GroupListFragment @Inject constructor( } override fun onGroupSelected(groupSummary: GroupSummary) { - viewModel.accept(GroupListActions.SelectGroup(groupSummary)) + viewModel.handle(GroupListActions.SelectGroup(groupSummary)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt index ac12113d66..715bb857b4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt @@ -42,7 +42,7 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro private val selectedGroupStore: SelectedGroupDataSource, private val session: Session, private val stringProvider: StringProvider -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -81,7 +81,7 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro } } - fun accept(action: GroupListActions) { + override fun handle(action: GroupListActions) { when (action) { is GroupListActions.SelectGroup -> handleSelectGroup(action) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActions.kt index 9169183da1..45d08820e4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActions.kt @@ -21,9 +21,9 @@ import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.model.message.MessageFileContent import im.vector.matrix.android.api.session.room.timeline.Timeline import im.vector.matrix.android.api.session.room.timeline.TimelineEvent +import im.vector.riotx.core.platform.VectorViewModelAction -sealed class RoomDetailActions { - +sealed class RoomDetailActions : VectorViewModelAction { data class SaveDraft(val draft: String) : RoomDetailActions() data class SendMessage(val text: String, val autoMarkdown: Boolean) : RoomDetailActions() data class SendMedia(val attachments: List) : RoomDetailActions() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 473b131348..1090dedd8a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -278,8 +278,8 @@ class RoomDetailFragment @Inject constructor( if (savedInstanceState == null) { when (val sharedData = roomDetailArgs.sharedData) { - is SharedData.Text -> roomDetailViewModel.process(RoomDetailActions.SendMessage(sharedData.text, false)) - is SharedData.Attachments -> roomDetailViewModel.process(RoomDetailActions.SendMedia(sharedData.attachmentData)) + is SharedData.Text -> roomDetailViewModel.handle(RoomDetailActions.SendMessage(sharedData.text, false)) + is SharedData.Attachments -> roomDetailViewModel.handle(RoomDetailActions.SendMedia(sharedData.attachmentData)) null -> Timber.v("No share data to process") } } @@ -323,7 +323,7 @@ class RoomDetailFragment @Inject constructor( private fun setupNotificationView() { notificationAreaView.delegate = object : NotificationAreaView.Delegate { override fun onTombstoneEventClicked(tombstoneEvent: Event) { - roomDetailViewModel.process(RoomDetailActions.HandleTombstoneEvent(tombstoneEvent)) + roomDetailViewModel.handle(RoomDetailActions.HandleTombstoneEvent(tombstoneEvent)) } override fun resendUnsentEvents() { @@ -355,11 +355,11 @@ class RoomDetailFragment @Inject constructor( // This a temporary option during dev as it is not super stable // Cancel all pending actions in room queue and post a dummy // Then mark all sending events as undelivered - roomDetailViewModel.process(RoomDetailActions.ClearSendQueue) + roomDetailViewModel.handle(RoomDetailActions.ClearSendQueue) return true } if (item.itemId == R.id.resend_all) { - roomDetailViewModel.process(RoomDetailActions.ResendAll) + roomDetailViewModel.handle(RoomDetailActions.ResendAll) return true } return super.onOptionsItemSelected(item) @@ -427,7 +427,7 @@ class RoomDetailFragment @Inject constructor( notificationDrawerManager.setCurrentRoom(null) - roomDetailViewModel.process(RoomDetailActions.SaveDraft(composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailActions.SaveDraft(composerLayout.composerEditText.text.toString())) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -440,7 +440,7 @@ class RoomDetailFragment @Inject constructor( val reaction = data.getStringExtra(EmojiReactionPickerActivity.EXTRA_REACTION_RESULT) ?: return // TODO check if already reacted with that? - roomDetailViewModel.process(RoomDetailActions.SendReaction(eventId, reaction)) + roomDetailViewModel.handle(RoomDetailActions.SendReaction(eventId, reaction)) } } } @@ -498,7 +498,7 @@ class RoomDetailFragment @Inject constructor( override fun performQuickReplyOnHolder(model: EpoxyModel<*>) { (model as? AbsMessageItem)?.attributes?.informationData?.let { val eventId = it.eventId - roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailActions.EnterReplyMode(eventId, composerLayout.composerEditText.text.toString())) } } @@ -601,11 +601,11 @@ class RoomDetailFragment @Inject constructor( val textMessage = composerLayout.composerEditText.text.toString() if (textMessage.isNotBlank()) { lockSendButton = true - roomDetailViewModel.process(RoomDetailActions.SendMessage(textMessage, vectorPreferences.isMarkdownEnabled())) + roomDetailViewModel.handle(RoomDetailActions.SendMessage(textMessage, vectorPreferences.isMarkdownEnabled())) } } composerLayout.composerRelatedMessageCloseButton.setOnClickListener { - roomDetailViewModel.process(RoomDetailActions.ExitSpecialMode(composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailActions.ExitSpecialMode(composerLayout.composerEditText.text.toString())) } composerLayout.callback = object : TextComposerView.Callback { override fun onRichContentSelected(contentUri: Uri): Boolean { @@ -760,7 +760,7 @@ class RoomDetailFragment @Inject constructor( .setView(layout) .setPositiveButton(R.string.report_content_custom_submit) { _, _ -> val reason = input.text.toString() - roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, reason)) + roomDetailViewModel.handle(RoomDetailActions.ReportContent(action.eventId, action.senderId, reason)) } .setNegativeButton(R.string.cancel, null) .show() @@ -785,7 +785,7 @@ class RoomDetailFragment @Inject constructor( .setMessage(R.string.content_reported_as_spam_content) .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.block_user) { _, _ -> - roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) + roomDetailViewModel.handle(RoomDetailActions.IgnoreUser(data.senderId)) } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) @@ -796,7 +796,7 @@ class RoomDetailFragment @Inject constructor( .setMessage(R.string.content_reported_as_inappropriate_content) .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.block_user) { _, _ -> - roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) + roomDetailViewModel.handle(RoomDetailActions.IgnoreUser(data.senderId)) } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) @@ -807,7 +807,7 @@ class RoomDetailFragment @Inject constructor( .setMessage(R.string.content_reported_content) .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.block_user) { _, _ -> - roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) + roomDetailViewModel.handle(RoomDetailActions.IgnoreUser(data.senderId)) } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) @@ -831,7 +831,7 @@ class RoomDetailFragment @Inject constructor( showSnackWithMessage(getString(R.string.navigate_to_room_when_already_in_the_room)) } else { // Highlight and scroll to this event - roomDetailViewModel.process(RoomDetailActions.NavigateToEvent(eventId, true)) + roomDetailViewModel.handle(RoomDetailActions.NavigateToEvent(eventId, true)) } return true } @@ -859,11 +859,11 @@ class RoomDetailFragment @Inject constructor( } override fun onEventVisible(event: TimelineEvent) { - roomDetailViewModel.process(RoomDetailActions.TimelineEventTurnsVisible(event)) + roomDetailViewModel.handle(RoomDetailActions.TimelineEventTurnsVisible(event)) } override fun onEventInvisible(event: TimelineEvent) { - roomDetailViewModel.process(RoomDetailActions.TimelineEventTurnsInvisible(event)) + roomDetailViewModel.handle(RoomDetailActions.TimelineEventTurnsInvisible(event)) } override fun onEncryptedMessageClicked(informationData: MessageInformationData, view: View) { @@ -902,7 +902,7 @@ class RoomDetailFragment @Inject constructor( val action = RoomDetailActions.DownloadFile(eventId, messageFileContent) // We need WRITE_EXTERNAL permission if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_DOWNLOAD_FILE)) { - roomDetailViewModel.process(action) + roomDetailViewModel.handle(action) } else { roomDetailViewModel.pendingAction = action } @@ -915,7 +915,7 @@ class RoomDetailFragment @Inject constructor( val action = roomDetailViewModel.pendingAction if (action != null) { roomDetailViewModel.pendingAction = null - roomDetailViewModel.process(action) + roomDetailViewModel.handle(action) } } PERMISSION_REQUEST_CODE_INCOMING_URI -> { @@ -946,7 +946,7 @@ class RoomDetailFragment @Inject constructor( } override fun onLoadMore(direction: Timeline.Direction) { - roomDetailViewModel.process(RoomDetailActions.LoadMoreTimelineEvents(direction)) + roomDetailViewModel.handle(RoomDetailActions.LoadMoreTimelineEvents(direction)) } override fun onEventCellClicked(informationData: MessageInformationData, messageContent: MessageContent?, view: View) { @@ -976,10 +976,10 @@ class RoomDetailFragment @Inject constructor( override fun onClickOnReactionPill(informationData: MessageInformationData, reaction: String, on: Boolean) { if (on) { // we should test the current real state of reaction on this event - roomDetailViewModel.process(RoomDetailActions.SendReaction(informationData.eventId, reaction)) + roomDetailViewModel.handle(RoomDetailActions.SendReaction(informationData.eventId, reaction)) } else { // I need to redact a reaction - roomDetailViewModel.process(RoomDetailActions.UndoReaction(informationData.eventId, reaction)) + roomDetailViewModel.handle(RoomDetailActions.UndoReaction(informationData.eventId, reaction)) } } @@ -1027,14 +1027,14 @@ class RoomDetailFragment @Inject constructor( } } if (nextReadMarkerId != null) { - roomDetailViewModel.process(RoomDetailActions.SetReadMarkerAction(nextReadMarkerId)) + roomDetailViewModel.handle(RoomDetailActions.SetReadMarkerAction(nextReadMarkerId)) } } // AutocompleteUserPresenter.Callback override fun onQueryUsers(query: CharSequence?) { - textComposerViewModel.process(TextComposerActions.QueryUsers(query)) + textComposerViewModel.handle(TextComposerActions.QueryUsers(query)) } private fun handleActions(action: EventSharedAction) { @@ -1053,7 +1053,7 @@ class RoomDetailFragment @Inject constructor( showSnackWithMessage(msg, Snackbar.LENGTH_SHORT) } is EventSharedAction.Delete -> { - roomDetailViewModel.process(RoomDetailActions.RedactAction(action.eventId, context?.getString(R.string.event_redacted_by_user_reason))) + roomDetailViewModel.handle(RoomDetailActions.RedactAction(action.eventId, context?.getString(R.string.event_redacted_by_user_reason))) } is EventSharedAction.Share -> { // TODO current data communication is too limited @@ -1110,16 +1110,16 @@ class RoomDetailFragment @Inject constructor( } is EventSharedAction.QuickReact -> { // eventId,ClickedOn,Add - roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) + roomDetailViewModel.handle(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } is EventSharedAction.Edit -> { - roomDetailViewModel.process(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) } is EventSharedAction.Quote -> { - roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) } is EventSharedAction.Reply -> { - roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.composerEditText.text.toString())) } is EventSharedAction.CopyPermalink -> { val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) @@ -1127,17 +1127,17 @@ class RoomDetailFragment @Inject constructor( showSnackWithMessage(requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) } is EventSharedAction.Resend -> { - roomDetailViewModel.process(RoomDetailActions.ResendMessage(action.eventId)) + roomDetailViewModel.handle(RoomDetailActions.ResendMessage(action.eventId)) } is EventSharedAction.Remove -> { - roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId)) + roomDetailViewModel.handle(RoomDetailActions.RemoveFailedEcho(action.eventId)) } is EventSharedAction.ReportContentSpam -> { - roomDetailViewModel.process(RoomDetailActions.ReportContent( + roomDetailViewModel.handle(RoomDetailActions.ReportContent( action.eventId, action.senderId, "This message is spam", spam = true)) } is EventSharedAction.ReportContentInappropriate -> { - roomDetailViewModel.process(RoomDetailActions.ReportContent( + roomDetailViewModel.handle(RoomDetailActions.ReportContent( action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) } is EventSharedAction.ReportContentCustom -> { @@ -1210,22 +1210,22 @@ class RoomDetailFragment @Inject constructor( override fun onAcceptInvite() { notificationDrawerManager.clearMemberShipNotificationForRoom(roomDetailArgs.roomId) - roomDetailViewModel.process(RoomDetailActions.AcceptInvite) + roomDetailViewModel.handle(RoomDetailActions.AcceptInvite) } override fun onRejectInvite() { notificationDrawerManager.clearMemberShipNotificationForRoom(roomDetailArgs.roomId) - roomDetailViewModel.process(RoomDetailActions.RejectInvite) + roomDetailViewModel.handle(RoomDetailActions.RejectInvite) } // JumpToReadMarkerView.Callback override fun onJumpToReadMarkerClicked(readMarkerId: String) { - roomDetailViewModel.process(RoomDetailActions.NavigateToEvent(readMarkerId, false)) + roomDetailViewModel.handle(RoomDetailActions.NavigateToEvent(readMarkerId, false)) } override fun onClearReadMarkerClicked() { - roomDetailViewModel.process(RoomDetailActions.MarkAllAsRead) + roomDetailViewModel.handle(RoomDetailActions.MarkAllAsRead) } // AttachmentTypeSelectorView.Callback @@ -1252,7 +1252,7 @@ class RoomDetailFragment @Inject constructor( // AttachmentsHelper.Callback override fun onContentAttachmentsReady(attachments: List) { - roomDetailViewModel.process(RoomDetailActions.SendMedia(attachments)) + roomDetailViewModel.handle(RoomDetailActions.SendMedia(attachments)) } override fun onAttachmentsProcessFailed() { @@ -1262,6 +1262,6 @@ class RoomDetailFragment @Inject constructor( override fun onContactAttachmentReady(contactAttachment: ContactAttachment) { super.onContactAttachmentReady(contactAttachment) val formattedContact = contactAttachment.toHumanReadable() - roomDetailViewModel.process(RoomDetailActions.SendMessage(formattedContact, false)) + roomDetailViewModel.handle(RoomDetailActions.SendMessage(formattedContact, false)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index 4965de4438..c3b3edde65 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -69,7 +69,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private val vectorPreferences: VectorPreferences, private val stringProvider: StringProvider, private val session: Session -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { private val room = session.getRoom(initialState.roomId)!! private val eventId = initialState.eventId @@ -129,7 +129,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro setState { copy(timeline = this@RoomDetailViewModel.timeline) } } - fun process(action: RoomDetailActions) { + override fun handle(action: RoomDetailActions) { when (action) { is RoomDetailActions.SaveDraft -> handleSaveDraft(action) is RoomDetailActions.SendMessage -> handleSendMessage(action) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerActions.kt index faf94b130b..1e5fccfe49 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerActions.kt @@ -16,6 +16,8 @@ package im.vector.riotx.features.home.room.detail.composer -sealed class TextComposerActions { +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class TextComposerActions : VectorViewModelAction { data class QueryUsers(val query: CharSequence?) : TextComposerActions() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerViewModel.kt index 69ecc30583..5915ffa9db 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerViewModel.kt @@ -36,7 +36,7 @@ typealias AutocompleteUserQuery = CharSequence class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: TextComposerViewState, private val session: Session -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { private val room = session.getRoom(initialState.roomId)!! private val roomId = initialState.roomId @@ -52,7 +52,7 @@ class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: @JvmStatic override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel? { - val fragment : RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() + val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() return fragment.textComposerViewModelFactory.create(state) } } @@ -61,7 +61,7 @@ class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: observeUsersQuery() } - fun process(action: TextComposerActions) { + override fun handle(action: TextComposerActions) { when (action) { is TextComposerActions.QueryUsers -> handleQueryUsers(action) } @@ -84,8 +84,7 @@ class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: users } else { users.filter { - it.displayName?.startsWith(prefix = filter, ignoreCase = true) - ?: false + it.displayName?.startsWith(prefix = filter, ignoreCase = true) ?: false } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index 479a9dd05c..b98d74a8b4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -72,7 +72,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override fun didSelectMenuAction(eventAction: EventSharedAction) { if (eventAction is EventSharedAction.ReportContent) { // Toggle report menu - viewModel.toggleReportMenu() + viewModel.handle(MessageActionActions.ToggleReportMenu) } else { messageActionsStore.post(eventAction) dismiss() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 42d0c1d201..a65323f412 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -37,13 +37,13 @@ import im.vector.matrix.rx.unwrap import im.vector.riotx.R import im.vector.riotx.core.extensions.canReact import im.vector.riotx.core.platform.VectorViewModel +import im.vector.riotx.core.platform.VectorViewModelAction import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData import im.vector.riotx.features.html.EventHtmlRenderer import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale +import java.util.* /** * Quick reactions state @@ -77,8 +77,12 @@ data class MessageActionState( fun canReact() = timelineEvent()?.canReact() == true } +sealed class MessageActionActions : VectorViewModelAction { + object ToggleReportMenu : MessageActionActions() +} + /** - * Information related to an event and used to display preview in contextual bottomsheet. + * Information related to an event and used to display preview in contextual bottom sheet. */ class MessageActionsViewModel @AssistedInject constructor(@Assisted initialState: MessageActionState, @@ -86,7 +90,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted private val session: Session, private val noticeEventFormatter: NoticeEventFormatter, private val stringProvider: StringProvider -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { private val eventId = initialState.eventId private val informationData = initialState.informationData @@ -113,7 +117,13 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted observeEventAction() } - fun toggleReportMenu() = withState { + override fun handle(action: MessageActionActions) { + when (action) { + MessageActionActions.ToggleReportMenu -> toggleReportMenu() + } + } + + private fun toggleReportMenu() = withState { setState { copy( expendedReportContentMenu = it.expendedReportContentMenu.not() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt index 93e7709b55..c1cccbef7a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt @@ -26,11 +26,12 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.message.MessageContent import im.vector.matrix.android.api.session.room.model.message.isReply import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult -import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.date.VectorDateFormatter +import im.vector.riotx.core.platform.EmptyAction +import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import timber.log.Timber -import java.util.UUID +import java.util.* data class ViewEditHistoryViewState( val eventId: String, @@ -46,7 +47,7 @@ class ViewEditHistoryViewModel @AssistedInject constructor(@Assisted initialState: ViewEditHistoryViewState, val session: Session, val dateFormatter: VectorDateFormatter -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { private val roomId = initialState.roomId private val eventId = initialState.eventId @@ -115,4 +116,8 @@ class ViewEditHistoryViewModel @AssistedInject constructor(@Assisted } }) } + + override fun handle(action: EmptyAction) { + // No op + } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt index 208e126022..9ec45b03b9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt @@ -16,20 +16,16 @@ package im.vector.riotx.features.home.room.detail.timeline.reactions -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext -import com.airbnb.mvrx.MvRxState -import com.airbnb.mvrx.MvRxViewModelFactory -import com.airbnb.mvrx.Uninitialized -import com.airbnb.mvrx.ViewModelContext +import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.room.model.ReactionAggregatedSummary import im.vector.matrix.rx.RxRoom import im.vector.matrix.rx.unwrap -import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.date.VectorDateFormatter +import im.vector.riotx.core.platform.EmptyAction +import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import io.reactivex.Observable import io.reactivex.Single @@ -55,15 +51,15 @@ data class ReactionInfo( * Used to display the list of members that reacted to a given event */ class ViewReactionsViewModel @AssistedInject constructor(@Assisted - initialState: DisplayReactionsViewState, + initialState: DisplayReactionsViewState, private val session: Session, private val dateFormatter: VectorDateFormatter -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { private val roomId = initialState.roomId private val eventId = initialState.eventId private val room = session.getRoom(roomId) - ?: throw IllegalStateException("Shouldn't use this ViewModel without a room") + ?: throw IllegalStateException("Shouldn't use this ViewModel without a room") @AssistedInject.Factory interface Factory { @@ -103,7 +99,7 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted .fromIterable(summary.sourceEvents) .map { val event = room.getTimeLineEvent(it) - ?: throw RuntimeException("Your eventId is not valid") + ?: throw RuntimeException("Your eventId is not valid") ReactionInfo( event.root.eventId!!, summary.key, @@ -115,4 +111,8 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted } }.toList() } + + override fun handle(action: EmptyAction) { + // No op + } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListActions.kt index 7fce5bf99f..25308dc3f9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListActions.kt @@ -18,8 +18,9 @@ package im.vector.riotx.features.home.room.list import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.notification.RoomNotificationState +import im.vector.riotx.core.platform.VectorViewModelAction -sealed class RoomListActions { +sealed class RoomListActions : VectorViewModelAction { data class SelectRoom(val roomSummary: RoomSummary) : RoomListActions() data class ToggleCategory(val category: RoomCategory) : RoomListActions() data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListActions() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt index f2bd02f9a3..f177847448 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt @@ -85,7 +85,7 @@ class RoomListFragment @Inject constructor( override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_home_mark_all_as_read -> { - roomListViewModel.accept(RoomListActions.MarkAllRoomsRead) + roomListViewModel.handle(RoomListActions.MarkAllRoomsRead) return true } } @@ -183,7 +183,7 @@ class RoomListFragment @Inject constructor( // Scroll the list to top roomListEpoxyRecyclerView.scrollToPosition(0) - roomListViewModel.accept(RoomListActions.FilterWith(filter)) + roomListViewModel.handle(RoomListActions.FilterWith(filter)) } override fun openRoomDirectory(initialFilter: String) { @@ -219,16 +219,16 @@ class RoomListFragment @Inject constructor( private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) { when (quickAction) { is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) + roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) } is RoomListQuickActionsSharedAction.NotificationsAll -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) + roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) } is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) + roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) } is RoomListQuickActionsSharedAction.NotificationsMute -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) + roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) } is RoomListQuickActionsSharedAction.Settings -> { vectorBaseActivity.notImplemented("Opening room settings") @@ -238,7 +238,7 @@ class RoomListFragment @Inject constructor( .setTitle(R.string.room_participants_leave_prompt_title) .setMessage(R.string.room_participants_leave_prompt_msg) .setPositiveButton(R.string.leave) { _, _ -> - roomListViewModel.accept(RoomListActions.LeaveRoom(quickAction.roomId)) + roomListViewModel.handle(RoomListActions.LeaveRoom(quickAction.roomId)) } .setNegativeButton(R.string.cancel, null) .show() @@ -342,7 +342,7 @@ class RoomListFragment @Inject constructor( // RoomSummaryController.Callback ************************************************************** override fun onRoomClicked(room: RoomSummary) { - roomListViewModel.accept(RoomListActions.SelectRoom(room)) + roomListViewModel.handle(RoomListActions.SelectRoom(room)) } override fun onRoomLongClicked(room: RoomSummary): Boolean { @@ -354,16 +354,16 @@ class RoomListFragment @Inject constructor( override fun onAcceptRoomInvitation(room: RoomSummary) { notificationDrawerManager.clearMemberShipNotificationForRoom(room.roomId) - roomListViewModel.accept(RoomListActions.AcceptInvitation(room)) + roomListViewModel.handle(RoomListActions.AcceptInvitation(room)) } override fun onRejectRoomInvitation(room: RoomSummary) { notificationDrawerManager.clearMemberShipNotificationForRoom(room.roomId) - roomListViewModel.accept(RoomListActions.RejectInvitation(room)) + roomListViewModel.handle(RoomListActions.RejectInvitation(room)) } override fun onToggleRoomCategory(roomCategory: RoomCategory) { - roomListViewModel.accept(RoomListActions.ToggleCategory(roomCategory)) + roomListViewModel.handle(RoomListActions.ToggleCategory(roomCategory)) } override fun createRoom(initialName: String) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt index ae8654d561..8094f42afb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt @@ -36,7 +36,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, private val roomSummariesSource: DataSource>, private val alphabeticalRoomComparator: AlphabeticalRoomComparator, private val chronologicalRoomComparator: ChronologicalRoomComparator) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { interface Factory { fun create(initialState: RoomListViewState): RoomListViewModel @@ -61,7 +61,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, observeRoomSummaries() } - fun accept(action: RoomListActions) { + override fun handle(action: RoomListActions) { when (action) { is RoomListActions.SelectRoom -> handleSelectRoom(action) is RoomListActions.ToggleCategory -> handleToggleCategory(action) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsViewModel.kt index 0eeef64a78..7f7a1f41c4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsViewModel.kt @@ -15,17 +15,20 @@ */ package im.vector.riotx.features.home.room.list.actions -import com.airbnb.mvrx.* +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session import im.vector.matrix.rx.rx import im.vector.matrix.rx.unwrap +import im.vector.riotx.core.platform.EmptyAction import im.vector.riotx.core.platform.VectorViewModel class RoomListQuickActionsViewModel @AssistedInject constructor(@Assisted initialState: RoomListQuickActionsState, session: Session -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -65,4 +68,8 @@ class RoomListQuickActionsViewModel @AssistedInject constructor(@Assisted initia copy(roomSummary = it) } } + + override fun handle(action: EmptyAction) { + // No op + } } diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt index 2c44737058..628c75e483 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt @@ -17,9 +17,9 @@ package im.vector.riotx.features.login import im.vector.matrix.android.api.auth.data.Credentials +import im.vector.riotx.core.platform.VectorViewModelAction -sealed class LoginActions { - +sealed class LoginActions : VectorViewModelAction { data class UpdateHomeServer(val homeServerUrl: String) : LoginActions() data class Login(val login: String, val password: String) : LoginActions() data class SsoLoginSuccess(val credentials: Credentials) : LoginActions() diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt index 0a324df6b9..5890e71b32 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginViewModel.kt @@ -42,7 +42,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi private val activeSessionHolder: ActiveSessionHolder, private val pushRuleTriggerListener: PushRuleTriggerListener, private val sessionListener: SessionListener) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -67,7 +67,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi private var homeServerConnectionConfig: HomeServerConnectionConfig? = null private var currentTask: Cancelable? = null - fun handle(action: LoginActions) { + override fun handle(action: LoginActions) { when (action) { is LoginActions.InitWith -> handleInitWith(action) is LoginActions.UpdateHomeServer -> handleUpdateHomeserver(action) diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiReactionPickerActivity.kt index cd5d5e3e74..83d3077708 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiReactionPickerActivity.kt @@ -63,7 +63,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), @Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider - val searchResultViewModel: EmojiSearchResultViewModel by viewModel() + private val searchResultViewModel: EmojiSearchResultViewModel by viewModel() private var tabLayoutSelectionListener = object : TabLayout.OnTabSelectedListener { override fun onTabReselected(tab: TabLayout.Tab) { @@ -201,7 +201,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), tabLayout.isVisible = false emojiPickerWholeListFragmentContainer.isVisible = false emojiPickerFilteredListFragmentContainer.isVisible = true - searchResultViewModel.updateQuery(query) + searchResultViewModel.handle(EmojiSearchActions.UpdateQuery(query)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchActions.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchActions.kt new file mode 100644 index 0000000000..43fe45f2e3 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchActions.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2019 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.riotx.features.reactions + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class EmojiSearchActions : VectorViewModelAction { + data class UpdateQuery(val queryString: String) : EmojiSearchActions() +} diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultViewModel.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultViewModel.kt index d11c25a1e3..d89d1fa22e 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultViewModel.kt @@ -26,17 +26,23 @@ data class EmojiSearchResultViewState( ) : MvRxState class EmojiSearchResultViewModel(val dataSource: EmojiDataSource, initialState: EmojiSearchResultViewState) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { - fun updateQuery(queryString: String) { + override fun handle(action: EmojiSearchActions) { + when (action) { + is EmojiSearchActions.UpdateQuery -> updateQuery(action) + } + } + + private fun updateQuery(action: EmojiSearchActions.UpdateQuery) { setState { copy( - query = queryString, + query = action.queryString, results = dataSource.rawData?.emojis?.toList() ?.map { it.second } ?.filter { - it.name.contains(queryString, true) - || queryString.split("\\s".toRegex()).fold(true, { prev, q -> + it.name.contains(action.queryString, true) + || action.queryString.split("\\s".toRegex()).fold(true, { prev, q -> prev && (it.keywords?.any { it.contains(q, true) } ?: false) }) } ?: emptyList() diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt index 2840dc7e89..b0198b39c4 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt @@ -66,7 +66,7 @@ class PublicRoomsFragment @Inject constructor( publicRoomsFilter.queryTextChanges() .debounce(500, TimeUnit.MILLISECONDS) .subscribeBy { - viewModel.filterWith(it.toString()) + viewModel.handle(RoomDirectoryActions.FilterWith(it.toString())) } .disposeOnDestroy() @@ -130,14 +130,14 @@ class PublicRoomsFragment @Inject constructor( override fun onPublicRoomJoin(publicRoom: PublicRoom) { Timber.v("PublicRoomJoinClicked: $publicRoom") - viewModel.joinRoom(publicRoom) + viewModel.handle(RoomDirectoryActions.JoinRoom(publicRoom)) } override fun loadMore() { - viewModel.loadMore() + viewModel.handle(RoomDirectoryActions.LoadMore) } - var initialValueSet = false + private var initialValueSet = false override fun invalidate() = withState(viewModel) { state -> if (!initialValueSet) { diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt new file mode 100644 index 0000000000..198426bc1d --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2019 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.riotx.features.roomdirectory + +import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom +import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class RoomDirectoryActions : VectorViewModelAction { + data class SetRoomDirectoryData(val roomDirectoryData: RoomDirectoryData) : RoomDirectoryActions() + data class FilterWith(val filter: String) : RoomDirectoryActions() + object LoadMore : RoomDirectoryActions() + data class JoinRoom(val publicRoom: PublicRoom) : RoomDirectoryActions() +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActivity.kt index b0b1a86275..574b461b16 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActivity.kt @@ -26,6 +26,7 @@ import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.features.roomdirectory.createroom.CreateRoomActions import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.createroom.CreateRoomViewModel import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment @@ -50,7 +51,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) if (isFirstCreation()) { - roomDirectoryViewModel.filterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "") + roomDirectoryViewModel.handle(RoomDirectoryActions.FilterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "")) } actionViewModel.observe() @@ -66,7 +67,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { roomDirectoryViewModel.selectSubscribe(this, PublicRoomsViewState::currentFilter) { currentFilter -> // Transmit the filter to the createRoomViewModel - createRoomViewModel.setName(currentFilter) + createRoomViewModel.handle(CreateRoomActions.SetName(currentFilter)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt index b0a47199d9..d092453ba8 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt @@ -25,7 +25,6 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.room.model.Membership -import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsFilter import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsParams import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoomsResponse @@ -40,7 +39,8 @@ import timber.log.Timber private const val PUBLIC_ROOMS_LIMIT = 20 class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: PublicRoomsViewState, - private val session: Session) : VectorViewModel(initialState) { + private val session: Session) + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -103,23 +103,32 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: .disposeOnClear() } - fun setRoomDirectoryData(roomDirectoryData: RoomDirectoryData) { - if (this.roomDirectoryData == roomDirectoryData) { + override fun handle(action: RoomDirectoryActions) { + when (action) { + is RoomDirectoryActions.SetRoomDirectoryData -> setRoomDirectoryData(action) + is RoomDirectoryActions.FilterWith -> filterWith(action) + RoomDirectoryActions.LoadMore -> loadMore() + is RoomDirectoryActions.JoinRoom -> joinRoom(action) + } + } + + private fun setRoomDirectoryData(action: RoomDirectoryActions.SetRoomDirectoryData) { + if (this.roomDirectoryData == action.roomDirectoryData) { return } - this.roomDirectoryData = roomDirectoryData + this.roomDirectoryData = action.roomDirectoryData reset("") load("") } - fun filterWith(filter: String) = withState { state -> - if (state.currentFilter != filter) { + private fun filterWith(action: RoomDirectoryActions.FilterWith) = withState { state -> + if (state.currentFilter != action.filter) { currentTask?.cancel() - reset(filter) - load(filter) + reset(action.filter) + load(action.filter) } } @@ -138,7 +147,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: } } - fun loadMore() = withState { state -> + private fun loadMore() = withState { state -> if (currentTask == null) { setState { copy( @@ -192,8 +201,10 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: }) } - fun joinRoom(publicRoom: PublicRoom) = withState { state -> - if (state.joiningRoomsIds.contains(publicRoom.roomId)) { + private fun joinRoom(action: RoomDirectoryActions.JoinRoom) = withState { state -> + val roomId = action.publicRoom.roomId + + if (state.joiningRoomsIds.contains(roomId)) { // Request already sent, should not happen Timber.w("Try to join an already joining room. Should not happen") return@withState @@ -201,11 +212,11 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: setState { copy( - joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { add(publicRoom.roomId) } + joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { add(roomId) } ) } - session.joinRoom(publicRoom.roomId, emptyList(), object : MatrixCallback { + session.joinRoom(roomId, emptyList(), object : MatrixCallback { override fun onSuccess(data: Unit) { // 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 @@ -217,8 +228,8 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: setState { copy( - joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { remove(publicRoom.roomId) }, - joiningErrorRoomsIds = joiningErrorRoomsIds.toMutableSet().apply { add(publicRoom.roomId) } + joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { remove(roomId) }, + joiningErrorRoomsIds = joiningErrorRoomsIds.toMutableSet().apply { add(roomId) } ) } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActions.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActions.kt new file mode 100644 index 0000000000..7c07143a53 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActions.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2019 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.riotx.features.roomdirectory.createroom + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class CreateRoomActions : VectorViewModelAction { + data class SetName(val name: String) : CreateRoomActions() + data class SetIsPublic(val isPublic: Boolean) : CreateRoomActions() + data class SetIsInRoomDirectory(val isInRoomDirectory: Boolean) : CreateRoomActions() + object Create : CreateRoomActions() +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActivity.kt index 4d0938814a..1e91a7224f 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -49,7 +49,7 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun initUiAndData() { if (isFirstCreation()) { addFragment(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) - createRoomViewModel.setName(intent?.getStringExtra(INITIAL_NAME) ?: "") + createRoomViewModel.handle(CreateRoomActions.SetName(intent?.getStringExtra(INITIAL_NAME) ?: "")) } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomFragment.kt index a421398322..285276ca7d 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -31,7 +31,7 @@ import kotlinx.android.synthetic.main.fragment_create_room.* import timber.log.Timber import javax.inject.Inject -class CreateRoomFragment @Inject constructor(private val createRoomController: CreateRoomController): VectorBaseFragment(), CreateRoomController.Listener { +class CreateRoomFragment @Inject constructor(private val createRoomController: CreateRoomController) : VectorBaseFragment(), CreateRoomController.Listener { private lateinit var actionViewModel: RoomDirectorySharedActionViewModel private val viewModel: CreateRoomViewModel by activityViewModel() @@ -53,7 +53,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_create_room -> { - viewModel.doCreateRoom() + viewModel.handle(CreateRoomActions.Create) true } else -> @@ -71,20 +71,20 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C } override fun onNameChange(newName: String) { - viewModel.setName(newName) + viewModel.handle(CreateRoomActions.SetName(newName)) } override fun setIsPublic(isPublic: Boolean) { - viewModel.setIsPublic(isPublic) + viewModel.handle(CreateRoomActions.SetIsPublic(isPublic)) } override fun setIsInRoomDirectory(isInRoomDirectory: Boolean) { - viewModel.setIsInRoomDirectory(isInRoomDirectory) + viewModel.handle(CreateRoomActions.SetIsInRoomDirectory(isInRoomDirectory)) } override fun retry() { Timber.v("Retry") - viewModel.doCreateRoom() + viewModel.handle(CreateRoomActions.Create) } override fun invalidate() = withState(viewModel) { state -> diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomViewModel.kt index 28185e91c1..3e794bceac 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomViewModel.kt @@ -30,7 +30,7 @@ import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: CreateRoomViewState, private val session: Session -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -51,13 +51,22 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr } } - fun setName(newName: String) = setState { copy(roomName = newName) } + override fun handle(action: CreateRoomActions) { + when (action) { + is CreateRoomActions.SetName -> setName(action) + is CreateRoomActions.SetIsPublic -> setIsPublic(action) + is CreateRoomActions.SetIsInRoomDirectory -> setIsInRoomDirectory(action) + is CreateRoomActions.Create -> doCreateRoom() + } + } - fun setIsPublic(isPublic: Boolean) = setState { copy(isPublic = isPublic) } + private fun setName(action: CreateRoomActions.SetName) = setState { copy(roomName = action.name) } - fun setIsInRoomDirectory(isInRoomDirectory: Boolean) = setState { copy(isInRoomDirectory = isInRoomDirectory) } + private fun setIsPublic(action: CreateRoomActions.SetIsPublic) = setState { copy(isPublic = action.isPublic) } - fun doCreateRoom() = withState { state -> + private fun setIsInRoomDirectory(action: CreateRoomActions.SetIsInRoomDirectory) = setState { copy(isInRoomDirectory = action.isInRoomDirectory) } + + private fun doCreateRoom() = withState { state -> if (state.asyncCreateRoomRequest is Loading || state.asyncCreateRoomRequest is Success) { return@withState } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerActions.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerActions.kt new file mode 100644 index 0000000000..fe07ce4ac3 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerActions.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2019 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.riotx.features.roomdirectory.picker + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class RoomDirectoryPickerActions : VectorViewModelAction { + object Retry : RoomDirectoryPickerActions() +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt index 18be8498da..f2daacb576 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt @@ -27,6 +27,7 @@ import com.airbnb.mvrx.withState import im.vector.matrix.android.api.session.room.model.thirdparty.RoomDirectoryData import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.roomdirectory.RoomDirectoryActions import im.vector.riotx.features.roomdirectory.RoomDirectorySharedAction import im.vector.riotx.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.riotx.features.roomdirectory.RoomDirectoryViewModel @@ -86,14 +87,14 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onRoomDirectoryClicked(roomDirectoryData: RoomDirectoryData) { Timber.v("onRoomDirectoryClicked: $roomDirectoryData") - viewModel.setRoomDirectoryData(roomDirectoryData) + viewModel.handle(RoomDirectoryActions.SetRoomDirectoryData(roomDirectoryData)) actionViewModel.post(RoomDirectorySharedAction.Back) } override fun retry() { Timber.v("Retry") - pickerViewModel.load() + pickerViewModel.handle(RoomDirectoryPickerActions.Retry) } override fun invalidate() = withState(pickerViewModel) { state -> diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt index 6cc96a1f70..92abdb0b98 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt @@ -16,11 +16,7 @@ package im.vector.riotx.features.roomdirectory.picker -import com.airbnb.mvrx.Fail -import com.airbnb.mvrx.FragmentViewModelContext -import com.airbnb.mvrx.MvRxViewModelFactory -import com.airbnb.mvrx.Success -import com.airbnb.mvrx.ViewModelContext +import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback @@ -29,7 +25,8 @@ import im.vector.matrix.android.api.session.room.model.thirdparty.ThirdPartyProt import im.vector.riotx.core.platform.VectorViewModel class RoomDirectoryPickerViewModel @AssistedInject constructor(@Assisted initialState: RoomDirectoryPickerViewState, - private val session: Session) : VectorViewModel(initialState) { + private val session: Session) + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -49,7 +46,7 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor(@Assisted initial load() } - fun load() { + private fun load() { session.getThirdPartyProtocol(object : MatrixCallback> { override fun onSuccess(data: Map) { setState { @@ -64,4 +61,10 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor(@Assisted initial } }) } + + override fun handle(action: RoomDirectoryPickerActions) { + when (action) { + RoomDirectoryPickerActions.Retry -> load() + } + } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActions.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActions.kt new file mode 100644 index 0000000000..ceedaba274 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActions.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2019 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.riotx.features.roomdirectory.roompreview + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class RoomPreviewActions : VectorViewModelAction { + object Join : RoomPreviewActions() +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt index aff89e3b09..7bb2655605 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt @@ -72,7 +72,7 @@ class RoomPreviewNoPreviewFragment @Inject constructor( roomPreviewNoPreviewJoin.callback = object : ButtonStateView.Callback { override fun onButtonClicked() { - roomPreviewViewModel.joinRoom() + roomPreviewViewModel.handle(RoomPreviewActions.Join) } override fun onRetryClicked() { diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 2bd75c2b90..f1f3bc98ed 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -30,7 +30,8 @@ import im.vector.riotx.features.roomdirectory.JoinState import timber.log.Timber class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: RoomPreviewViewState, - private val session: Session) : VectorViewModel(initialState) { + private val session: Session) + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -76,7 +77,13 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R .disposeOnClear() } - fun joinRoom() = withState { state -> + override fun handle(action: RoomPreviewActions) { + when (action) { + RoomPreviewActions.Join -> joinRoom() + } + } + + private fun joinRoom() = withState { state -> if (state.roomJoinState == JoinState.JOINING) { // Request already sent, should not happen Timber.w("Try to join an already joining room. Should not happen") diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersViewModel.kt index a9f142058d..e77660746c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersViewModel.kt @@ -25,18 +25,20 @@ import im.vector.matrix.android.api.session.user.model.User import im.vector.matrix.rx.rx import im.vector.riotx.core.extensions.postLiveEvent import im.vector.riotx.core.platform.VectorViewModel +import im.vector.riotx.core.platform.VectorViewModelAction data class IgnoredUsersViewState( val ignoredUsers: List = emptyList(), val unIgnoreRequest: Async = Uninitialized ) : MvRxState -sealed class IgnoredUsersAction { +sealed class IgnoredUsersAction : VectorViewModelAction { data class UnIgnore(val userId: String) : IgnoredUsersAction() } class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: IgnoredUsersViewState, - private val session: Session) : VectorViewModel(initialState) { + private val session: Session) + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -66,7 +68,7 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: } } - fun handle(action: IgnoredUsersAction) { + override fun handle(action: IgnoredUsersAction) { when (action) { is IgnoredUsersAction.UnIgnore -> handleUnIgnore(action) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysViewModel.kt index c51da409cf..dd773f4c22 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysViewModel.kt @@ -16,17 +16,13 @@ package im.vector.riotx.features.settings.push -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext -import com.airbnb.mvrx.MvRxState -import com.airbnb.mvrx.MvRxViewModelFactory -import com.airbnb.mvrx.Uninitialized -import com.airbnb.mvrx.ViewModelContext +import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.pushers.Pusher import im.vector.matrix.rx.RxSession +import im.vector.riotx.core.platform.EmptyAction import im.vector.riotx.core.platform.VectorViewModel data class PushGatewayViewState( @@ -34,7 +30,8 @@ data class PushGatewayViewState( ) : MvRxState class PushGatewaysViewModel @AssistedInject constructor(@Assisted initialState: PushGatewayViewState, - private val session: Session) : VectorViewModel(initialState) { + private val session: Session) + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -60,4 +57,8 @@ class PushGatewaysViewModel @AssistedInject constructor(@Assisted initialState: copy(pushGateways = it) } } + + override fun handle(action: EmptyAction) { + // No op + } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/push/PushRulesViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/push/PushRulesViewModel.kt index d651deaf80..e376b7ed6f 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/push/PushRulesViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/push/PushRulesViewModel.kt @@ -20,13 +20,15 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.riotx.core.di.HasScreenInjector +import im.vector.riotx.core.platform.EmptyAction import im.vector.riotx.core.platform.VectorViewModel data class PushRulesViewState( val rules: List = emptyList() ) : MvRxState -class PushRulesViewModel(initialState: PushRulesViewState) : VectorViewModel(initialState) { +class PushRulesViewModel(initialState: PushRulesViewState) + : VectorViewModel(initialState) { companion object : MvRxViewModelFactory { @@ -36,4 +38,8 @@ class PushRulesViewModel(initialState: PushRulesViewState) : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -70,4 +71,8 @@ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState: } .disposeOnClear() } + + override fun handle(action: EmptyAction) { + // No op + } }