From 9762d5be40d9d88ad8e0f42d7acb6ee5b98b4dc1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 23 Oct 2019 19:05:59 +0200 Subject: [PATCH 001/117] Room list actions: start creating all the components --- .../vector/riotx/core/di/ScreenComponent.kt | 3 + .../home/room/list/RoomListFragment.kt | 10 +- .../home/room/list/RoomSummaryController.kt | 3 +- .../home/room/list/RoomSummaryItem.kt | 6 +- .../home/room/list/RoomSummaryItemFactory.kt | 13 ++- .../room/list/actions/RoomListQuickActions.kt | 24 +++++ .../RoomListQuickActionsBottomSheet.kt | 92 +++++++++++++++++++ .../RoomListQuickActionsEpoxyController.kt | 57 ++++++++++++ .../list/actions/RoomListQuickActionsState.kt | 32 +++++++ .../actions/RoomListQuickActionsViewModel.kt | 54 +++++++++++ 10 files changed, 288 insertions(+), 6 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsViewModel.kt diff --git a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt index da9daac68d..cb9dcf375e 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt @@ -45,6 +45,7 @@ import im.vector.riotx.features.home.room.detail.timeline.action.* import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.invite.VectorInviteView import im.vector.riotx.features.link.LinkHandlerActivity @@ -186,6 +187,8 @@ interface ScreenComponent { fun inject(incomingShareActivity: IncomingShareActivity) + fun inject(roomListActionsBottomSheet: RoomListQuickActionsBottomSheet) + @Component.Factory interface Factory { fun create(vectorComponent: VectorComponent, 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 a705c91a9e..76e4ff9e3b 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 @@ -39,6 +39,7 @@ import im.vector.riotx.core.extensions.observeEventFirstThrottle import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData @@ -298,10 +299,17 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O // RoomSummaryController.Callback ************************************************************** - override fun onRoomSelected(room: RoomSummary) { + override fun onRoomClicked(room: RoomSummary) { roomListViewModel.accept(RoomListActions.SelectRoom(room)) } + override fun onRoomLongClicked(room: RoomSummary): Boolean { + RoomListQuickActionsBottomSheet + .newInstance(room.roomId) + .show(requireActivity().supportFragmentManager, "ROOM_LIST_QUICK_ACTIONS") + return true + } + override fun onAcceptRoomInvitation(room: RoomSummary) { notificationDrawerManager.clearMemberShipNotificationForRoom(room.roomId) roomListViewModel.accept(RoomListActions.AcceptInvitation(room)) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt index 6d786cde5e..9f73d24c6d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt @@ -138,7 +138,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri interface Listener : FilteredRoomFooterItem.FilteredRoomFooterItemListener { fun onToggleRoomCategory(roomCategory: RoomCategory) - fun onRoomSelected(room: RoomSummary) + fun onRoomClicked(room: RoomSummary) + fun onRoomLongClicked(room: RoomSummary): Boolean fun onRejectRoomInvitation(room: RoomSummary) fun onAcceptRoomInvitation(room: RoomSummary) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt index 812ad463f5..fe208a3085 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItem.kt @@ -41,11 +41,13 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { @EpoxyAttribute var hasUnreadMessage: Boolean = false @EpoxyAttribute var hasDraft: Boolean = false @EpoxyAttribute var showHighlighted: Boolean = false - @EpoxyAttribute var listener: (() -> Unit)? = null + @EpoxyAttribute var itemLongClickListener: View.OnLongClickListener? = null + @EpoxyAttribute var itemClickListener: View.OnClickListener? = null override fun bind(holder: Holder) { super.bind(holder) - holder.rootView.setOnClickListener { listener?.invoke() } + holder.rootView.setOnClickListener(itemClickListener) + holder.rootView.setOnLongClickListener(itemLongClickListener) holder.titleView.text = roomName holder.lastEventTimeView.text = lastEventTime holder.lastEventView.text = lastFormattedEvent diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt index 0ad3b10159..c38c5cfd37 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.home.room.list +import android.view.View import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership @@ -28,6 +29,7 @@ import im.vector.riotx.core.extensions.localDateTime import im.vector.riotx.core.resources.ColorProvider import im.vector.riotx.core.resources.DateProvider import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.core.utils.DebouncedClickListener import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter import im.vector.riotx.features.home.room.detail.timeline.helper.senderName @@ -79,7 +81,7 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte .rejectListener { listener?.onRejectRoomInvitation(roomSummary) } .roomName(roomSummary.displayName) .avatarUrl(roomSummary.avatarUrl) - .listener { listener?.onRoomSelected(roomSummary) } + .listener { listener?.onRoomClicked(roomSummary) } } private fun createRoomItem(roomSummary: RoomSummary, listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> { @@ -134,6 +136,13 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte .unreadNotificationCount(unreadCount) .hasUnreadMessage(roomSummary.hasUnreadMessages) .hasDraft(roomSummary.userDrafts.isNotEmpty()) - .listener { listener?.onRoomSelected(roomSummary) } + .itemLongClickListener { _ -> + listener?.onRoomLongClicked(roomSummary) ?: false + } + .itemClickListener( + DebouncedClickListener(View.OnClickListener { _ -> + listener?.onRoomClicked(roomSummary) + }) + ) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt new file mode 100644 index 0000000000..c07d88f85a --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.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.room.list.actions + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes + +sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { + +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt new file mode 100644 index 0000000000..19fe10de39 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -0,0 +1,92 @@ +/* + * 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.room.list.actions + +import android.os.Bundle +import android.os.Parcelable +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import butterknife.BindView +import butterknife.ButterKnife +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.riotx.R +import im.vector.riotx.core.di.ScreenComponent +import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment +import kotlinx.android.parcel.Parcelize +import javax.inject.Inject + +@Parcelize +data class RoomListActionsArgs( + val roomId: String +) : Parcelable + +/** + * Bottom sheet fragment that shows room information with list of contextual actions + */ +class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { + + @Inject lateinit var roomListActionsViewModelFactory: RoomListActionsViewModel.Factory + @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController + + private val viewModel: RoomListActionsViewModel by fragmentViewModel(RoomListActionsViewModel::class) + + @BindView(R.id.bottomSheetRecyclerView) + lateinit var recyclerView: RecyclerView + + override val showExpanded = true + + override fun injectWith(screenComponent: ScreenComponent) { + screenComponent.inject(this) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + val view = inflater.inflate(R.layout.bottom_sheet_generic_list, container, false) + ButterKnife.bind(this, view) + return view + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) + recyclerView.adapter = roomListActionsEpoxyController.adapter + // Disable item animation + recyclerView.itemAnimator = null + roomListActionsEpoxyController.listener = this + } + + + override fun invalidate() = withState(viewModel) { + roomListActionsEpoxyController.setData(it) + super.invalidate() + } + + override fun didSelectMenuAction(quickActions: RoomListQuickActions) { + vectorBaseActivity.notImplemented("RoomListQuickActions") + } + + companion object { + fun newInstance(roomId: String): RoomListQuickActionsBottomSheet { + return RoomListQuickActionsBottomSheet().apply { + setArguments(RoomListActionsArgs(roomId)) + } + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt new file mode 100644 index 0000000000..f4cc774092 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -0,0 +1,57 @@ +/* + * 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.room.list.actions + +import android.view.View +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.riotx.EmojiCompatFontProvider +import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.features.home.AvatarRenderer +import im.vector.riotx.features.home.room.detail.timeline.action.bottomSheetItemAction +import im.vector.riotx.features.home.room.detail.timeline.action.bottomSheetItemSeparator +import javax.inject.Inject + +/** + * Epoxy controller for room list actions + */ +class RoomListQuickActionsEpoxyController @Inject constructor(private val stringProvider: StringProvider, + private val avatarRenderer: AvatarRenderer, + private val fontProvider: EmojiCompatFontProvider) : TypedEpoxyController() { + + var listener: Listener? = null + + override fun buildModels(state: RoomListQuickActionsState) { + + // Separator + bottomSheetItemSeparator { + id("actions_separator") + } + + // Actions + state.quickActions()?.forEachIndexed { index, action -> + bottomSheetItemAction { + id("action_$index") + iconRes(action.iconResId) + textRes(action.titleRes) + listener(View.OnClickListener { listener?.didSelectMenuAction(action) }) + } + } + } + + interface Listener { + fun didSelectMenuAction(quickActions: RoomListQuickActions) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt new file mode 100644 index 0000000000..adefe24341 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt @@ -0,0 +1,32 @@ +/* + * 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.room.list.actions + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized +import im.vector.matrix.android.api.session.room.model.RoomSummary + +data class RoomListQuickActionsState( + val roomId: String, + val quickActions: Async> = Uninitialized, + val timelineEvent: Async = Uninitialized +) : MvRxState { + + constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) + +} 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 new file mode 100644 index 0000000000..079c43041f --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsViewModel.kt @@ -0,0 +1,54 @@ +/* + * 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.room.list.actions + +import com.airbnb.mvrx.* +import com.squareup.inject.assisted.Assisted +import com.squareup.inject.assisted.AssistedInject +import dagger.Lazy +import im.vector.matrix.android.api.session.Session +import im.vector.riotx.core.platform.VectorViewModel +import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter +import im.vector.riotx.features.html.EventHtmlRenderer + +class RoomListActionsViewModel @AssistedInject constructor(@Assisted + initialState: RoomListQuickActionsState, + private val eventHtmlRenderer: Lazy, + private val session: Session, + private val noticeEventFormatter: NoticeEventFormatter, + private val stringProvider: StringProvider +) : VectorViewModel(initialState) { + + @AssistedInject.Factory + interface Factory { + fun create(initialState: RoomListQuickActionsState): RoomListActionsViewModel + } + + companion object : MvRxViewModelFactory { + + override fun create(viewModelContext: ViewModelContext, state: RoomListQuickActionsState): RoomListActionsViewModel? { + val fragment: RoomListQuickActionsBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() + return fragment.roomListActionsViewModelFactory.create(state) + } + } + + init { + + } + + +} From b766bce07d352802b49cd927174becc3cfcfff76 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 14:40:31 +0200 Subject: [PATCH 002/117] Version++ --- CHANGES.md | 21 +++++++++++++++++++++ vector/build.gradle | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 48d0be34cd..b05300f94b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,24 @@ +Changes in RiotX 0.8.0 (2019-XX-XX) +=================================================== + +Features ✨: + - + +Improvements 🙌: + - + +Other changes: + - + +Bugfix 🐛: + - + +Translations 🗣: + - + +Build 🧱: + - + Changes in RiotX 0.7.0 (2019-10-24) =================================================== diff --git a/vector/build.gradle b/vector/build.gradle index 3ef125d331..34c01c028e 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -15,7 +15,7 @@ androidExtensions { } ext.versionMajor = 0 -ext.versionMinor = 7 +ext.versionMinor = 8 ext.versionPatch = 0 static def getGitTimestamp() { From 9e8d8ce8784ff6e3fbe4f9ac8d9aef66057d4dea Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 15:52:40 +0200 Subject: [PATCH 003/117] Build and run test on CI --- .buildkite/pipeline.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index cf1cd5b9ff..9a4c4b17a9 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -3,9 +3,19 @@ # https://github.com/buildkite-plugins/docker-buildkite-plugin/releases # We propagate the environment to the container (sse https://github.com/buildkite-plugins/docker-buildkite-plugin#propagate-environment-optional-boolean) -# Build debug version of the RiotX application, from the develop branch and the features branches - steps: + - label: "Unit test" + agents: + # We use a medium sized instance instead of the normal small ones because + # gradle build is long + queue: "medium" + commands: + - "./gradlew clean test --stacktrace" + plugins: + - docker#v3.1.0: + image: "runmymind/docker-android-sdk" + propagate-environment: true + - label: "Assemble GPlay Debug version" agents: # We use a medium sized instance instead of the normal small ones because From 2cf63ea92a7e3359fa3ecc501e6612b2b93eefcd Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Thu, 24 Oct 2019 14:53:10 +0100 Subject: [PATCH 004/117] Remove `import java.util.*` from kotlin files. Signed-off-by: Dominic Fischer --- .../matrix/android/api/session/events/model/LocalEcho.kt | 2 +- .../android/internal/database/mapper/RoomSummaryMapper.kt | 2 +- .../android/internal/network/NetworkConnectivityChecker.kt | 2 +- .../homeserver/DefaultGetHomeServerCapabilitiesTask.kt | 2 +- .../internal/session/pushers/DefaultPusherService.kt | 2 +- .../internal/session/room/timeline/DefaultTimeline.kt | 3 ++- .../internal/session/securestorage/SecretStoringUtils.kt | 2 +- .../im/vector/matrix/android/internal/util/CompatUtil.kt | 2 +- .../im/vector/matrix/android/internal/util/StringUtils.kt | 2 +- vector/src/main/java/im/vector/riotx/VectorApplication.kt | 3 ++- .../main/java/im/vector/riotx/core/linkify/VectorLinkify.kt | 3 +-- .../core/platform/VectorBaseBottomSheetDialogFragment.kt | 2 +- .../java/im/vector/riotx/core/pushers/PushersManager.kt | 2 +- .../java/im/vector/riotx/core/resources/LocaleProvider.kt | 2 +- .../im/vector/riotx/core/utils/DebouncedClickListener.kt | 2 +- .../im/vector/riotx/core/utils/ExternalApplicationsUtil.kt | 3 ++- .../src/main/java/im/vector/riotx/core/utils/SystemUtils.kt | 2 +- .../src/main/java/im/vector/riotx/core/utils/TextUtils.kt | 2 +- .../riotx/features/configuration/VectorConfiguration.kt | 2 +- .../settings/KeysBackupSettingsRecyclerViewController.kt | 2 +- .../timeline/edithistory/ViewEditHistoryEpoxyController.kt | 2 +- .../detail/timeline/edithistory/ViewEditHistoryViewModel.kt | 2 +- .../riotx/features/notifications/NotifiableEventResolver.kt | 2 +- .../features/notifications/NotificationBroadcastReceiver.kt | 2 +- .../riotx/features/notifications/NotificationUtils.kt | 6 +++--- .../java/im/vector/riotx/features/rageshake/BugReporter.kt | 2 +- .../im/vector/riotx/features/rageshake/VectorFileLogger.kt | 4 +++- .../features/settings/VectorSettingsGeneralFragment.kt | 1 - .../settings/VectorSettingsSecurityPrivacyFragment.kt | 3 ++- .../main/java/im/vector/riotx/features/themes/ThemeUtils.kt | 1 - 30 files changed, 36 insertions(+), 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt index ca75871cda..1dbee475e0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt @@ -16,7 +16,7 @@ package im.vector.matrix.android.api.session.events.model -import java.util.* +import java.util.UUID object LocalEcho { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt index 5db062b000..0d0143d318 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt @@ -22,7 +22,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.database.model.RoomSummaryEntity -import java.util.* +import java.util.UUID import javax.inject.Inject internal class RoomSummaryMapper @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkConnectivityChecker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkConnectivityChecker.kt index bfc37d733d..3d850c223a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkConnectivityChecker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/NetworkConnectivityChecker.kt @@ -22,7 +22,7 @@ import com.novoda.merlin.MerlinsBeard import im.vector.matrix.android.internal.di.MatrixScope import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import timber.log.Timber -import java.util.* +import java.util.Collections import javax.inject.Inject import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt index 98ab0b5389..45571286b9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt @@ -23,7 +23,7 @@ import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.util.awaitTransaction -import java.util.* +import java.util.Date import javax.inject.Inject internal interface GetHomeServerCapabilitiesTask : Task diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt index 243e4d4b03..8c7e9fb263 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt @@ -32,7 +32,7 @@ import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.worker.WorkManagerUtil import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder import im.vector.matrix.android.internal.worker.WorkerParamsFactory -import java.util.* +import java.util.UUID import java.util.concurrent.TimeUnit import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt index 606c20e8cb..4127e43540 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt @@ -52,7 +52,8 @@ import io.realm.RealmQuery import io.realm.RealmResults import io.realm.Sort import timber.log.Timber -import java.util.* +import java.util.Collections +import java.util.UUID import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference import kotlin.collections.ArrayList diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/securestorage/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/securestorage/SecretStoringUtils.kt index 260f98d97f..592191975e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/securestorage/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/securestorage/SecretStoringUtils.kt @@ -31,7 +31,7 @@ import java.security.KeyPairGenerator import java.security.KeyStore import java.security.KeyStoreException import java.security.SecureRandom -import java.util.* +import java.util.Calendar import javax.crypto.* import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.IvParameterSpec diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt index 058a862bc8..2df2bd2bf2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt @@ -36,7 +36,7 @@ import java.security.* import java.security.cert.CertificateException import java.security.spec.AlgorithmParameterSpec import java.security.spec.RSAKeyGenParameterSpec -import java.util.* +import java.util.Calendar import java.util.zip.GZIPOutputStream import javax.crypto.* import javax.crypto.spec.GCMParameterSpec diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/StringUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/StringUtils.kt index 4a46a43f03..31da372bbe 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/StringUtils.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/StringUtils.kt @@ -18,7 +18,7 @@ package im.vector.matrix.android.internal.util import im.vector.matrix.android.api.MatrixPatterns import timber.log.Timber -import java.util.* +import java.util.Locale /** * Convert a string to an UTF8 String diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index b1fd6a8485..20a17e55d4 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -55,7 +55,8 @@ import im.vector.riotx.features.version.VersionProvider import im.vector.riotx.push.fcm.FcmHelper import timber.log.Timber import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale import javax.inject.Inject class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.Provider, androidx.work.Configuration.Provider { diff --git a/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt b/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt index 358fff6092..0d6a71f701 100644 --- a/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt +++ b/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt @@ -19,7 +19,6 @@ import android.text.Spannable import android.text.style.URLSpan import android.text.util.Linkify import androidx.core.text.util.LinkifyCompat -import java.util.* object VectorLinkify { /** @@ -108,7 +107,7 @@ object VectorLinkify { } private fun pruneOverlaps(links: ArrayList) { - Collections.sort(links, COMPARATOR) + links.sortWith(COMPARATOR) var len = links.size var i = 0 while (i < len - 1) { diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt index 8d40d55a7a..1b07d739b5 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -30,7 +30,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import im.vector.riotx.core.di.DaggerScreenComponent import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.utils.DimensionConverter -import java.util.* +import java.util.UUID /** * Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment) diff --git a/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt index 41287d4e38..ceae3a2b76 100644 --- a/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt +++ b/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt @@ -22,7 +22,7 @@ import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.resources.AppNameProvider import im.vector.riotx.core.resources.LocaleProvider import im.vector.riotx.core.resources.StringProvider -import java.util.* +import java.util.UUID import javax.inject.Inject private const val DEFAULT_PUSHER_FILE_TAG = "mobile" diff --git a/vector/src/main/java/im/vector/riotx/core/resources/LocaleProvider.kt b/vector/src/main/java/im/vector/riotx/core/resources/LocaleProvider.kt index 74861a65cc..c78a5a99b8 100644 --- a/vector/src/main/java/im/vector/riotx/core/resources/LocaleProvider.kt +++ b/vector/src/main/java/im/vector/riotx/core/resources/LocaleProvider.kt @@ -18,7 +18,7 @@ package im.vector.riotx.core.resources import android.content.res.Resources import androidx.core.os.ConfigurationCompat -import java.util.* +import java.util.Locale import javax.inject.Inject class LocaleProvider @Inject constructor(private val resources: Resources) { diff --git a/vector/src/main/java/im/vector/riotx/core/utils/DebouncedClickListener.kt b/vector/src/main/java/im/vector/riotx/core/utils/DebouncedClickListener.kt index 958f642565..230b11f14d 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/DebouncedClickListener.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/DebouncedClickListener.kt @@ -16,7 +16,7 @@ package im.vector.riotx.core.utils import android.view.View -import java.util.* +import java.util.WeakHashMap /** * Simple Debounced OnClickListener diff --git a/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt b/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt index 9572b07216..78242d58de 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/ExternalApplicationsUtil.kt @@ -32,7 +32,8 @@ import im.vector.riotx.R import timber.log.Timber import java.io.File import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale /** * Open a url in the internet browser of the system diff --git a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt index 12371fe72d..ba0b99762b 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt @@ -31,7 +31,7 @@ import im.vector.riotx.R import im.vector.riotx.features.notifications.NotificationUtils import im.vector.riotx.features.settings.VectorLocale import timber.log.Timber -import java.util.* +import java.util.Locale /** * Tells if the application ignores battery optimizations. diff --git a/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt index 0b5df0d2e0..75f6893c7c 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/TextUtils.kt @@ -19,7 +19,7 @@ package im.vector.riotx.core.utils import android.content.Context import android.os.Build import android.text.format.Formatter -import java.util.* +import java.util.TreeMap object TextUtils { diff --git a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt index ec8f1c7fa2..adf8421842 100644 --- a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt @@ -24,7 +24,7 @@ import im.vector.riotx.features.settings.FontScale import im.vector.riotx.features.settings.VectorLocale import im.vector.riotx.features.themes.ThemeUtils import timber.log.Timber -import java.util.* +import java.util.Locale import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt index 6b01a7dffa..7b60cb2f9b 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt @@ -31,7 +31,7 @@ import im.vector.riotx.core.epoxy.loadingItem import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.core.ui.list.GenericItem import im.vector.riotx.core.ui.list.genericItem -import java.util.* +import java.util.UUID import javax.inject.Inject class KeysBackupSettingsRecyclerViewController @Inject constructor(private val stringProvider: StringProvider, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt index d36e98f67c..32abc0384b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt @@ -38,7 +38,7 @@ import im.vector.riotx.features.html.EventHtmlRenderer import me.gujun.android.span.span import name.fraser.neil.plaintext.diff_match_patch import timber.log.Timber -import java.util.* +import java.util.Calendar /** * Epoxy controller for edit history list 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 e2b976b273..93e7709b55 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 @@ -30,7 +30,7 @@ import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.date.VectorDateFormatter import im.vector.riotx.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import timber.log.Timber -import java.util.* +import java.util.UUID data class ViewEditHistoryViewState( val eventId: String, diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt index 06108e07fe..786fabfca2 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt @@ -33,7 +33,7 @@ import im.vector.riotx.R import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter import timber.log.Timber -import java.util.* +import java.util.UUID import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt index e26395641d..63cd1c5ce6 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationBroadcastReceiver.kt @@ -27,7 +27,7 @@ import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.extensions.vectorComponent import timber.log.Timber -import java.util.* +import java.util.UUID import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationUtils.kt index 1a5385663b..7d8e43d0be 100755 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotificationUtils.kt @@ -45,9 +45,9 @@ import im.vector.riotx.features.home.room.detail.RoomDetailActivity import im.vector.riotx.features.home.room.detail.RoomDetailArgs import im.vector.riotx.features.settings.VectorPreferences import timber.log.Timber -import java.util.* import javax.inject.Inject import javax.inject.Singleton +import kotlin.random.Random /** * Util class for creating notifications. @@ -299,7 +299,7 @@ class NotificationUtils @Inject constructor(private val context: Context, // use a generator for the private requestCode. // When using 0, the intent is not created/launched when the user taps on the notification. // - val pendingIntent = stackBuilder.getPendingIntent(Random().nextInt(1000), PendingIntent.FLAG_UPDATE_CURRENT) + val pendingIntent = stackBuilder.getPendingIntent(Random.nextInt(1000), PendingIntent.FLAG_UPDATE_CURRENT) builder.setContentIntent(pendingIntent) @@ -599,7 +599,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val intent = HomeActivity.newIntent(context, clearNotification = true) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP intent.data = Uri.parse("foobar://tapSummary") - return PendingIntent.getActivity(context, Random().nextInt(1000), intent, PendingIntent.FLAG_UPDATE_CURRENT) + return PendingIntent.getActivity(context, Random.nextInt(1000), intent, PendingIntent.FLAG_UPDATE_CURRENT) } /* diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt index 9a7707d063..b96542a8ce 100755 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt @@ -46,7 +46,7 @@ import org.json.JSONObject import timber.log.Timber import java.io.* import java.net.HttpURLConnection -import java.util.* +import java.util.Locale import java.util.zip.GZIPOutputStream import javax.inject.Inject import javax.inject.Singleton diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt index 0b9cb5798c..95053790c8 100644 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt @@ -24,7 +24,9 @@ import java.io.File import java.io.PrintWriter import java.io.StringWriter import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale +import java.util.TimeZone import java.util.logging.* import java.util.logging.Formatter import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt index 331b6e935a..ff76c61754 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt @@ -51,7 +51,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File -import java.util.* class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 2f52cdef13..a78529f06c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -56,7 +56,8 @@ import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActiv import timber.log.Timber import java.text.DateFormat import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale import javax.inject.Inject class VectorSettingsSecurityPrivacyFragment : VectorSettingsBaseFragment() { diff --git a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt index 2edb59104b..076b5d6ea2 100644 --- a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt @@ -28,7 +28,6 @@ import androidx.core.graphics.drawable.DrawableCompat import androidx.preference.PreferenceManager import im.vector.riotx.R import timber.log.Timber -import java.util.* /** * Util class for managing themes. From 5ab975cc5ceaa914baa001e2bc2e196c2c2b6b29 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Thu, 24 Oct 2019 14:53:44 +0100 Subject: [PATCH 005/117] General kotlinification. Signed-off-by: Dominic Fischer --- .../internal/crypto/DeviceListManager.kt | 2 +- .../crypto/OutgoingRoomKeyRequestManager.kt | 2 +- .../DefaultSasVerificationService.kt | 6 ++--- .../core/linkify/VectorAutoLinkPatterns.kt | 6 ++--- .../riotx/core/linkify/VectorLinkify.kt | 2 +- .../riotx/core/pushers/PushersManager.kt | 3 ++- .../java/im/vector/riotx/core/utils/Emoji.kt | 7 ++--- .../ViewEditHistoryEpoxyController.kt | 2 +- .../riotx/features/themes/ThemeUtils.kt | 26 +++++++------------ 9 files changed, 23 insertions(+), 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt index 7f2a23e4c2..b2002f0916 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DeviceListManager.kt @@ -66,7 +66,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM if (':' in userId) { try { synchronized(notReadyToRetryHS) { - res = !notReadyToRetryHS.contains(userId.substring(userId.lastIndexOf(":") + 1)) + res = !notReadyToRetryHS.contains(userId.substringAfterLast(':')) } } catch (e: Exception) { Timber.e(e, "## canRetryKeysDownload() failed") diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt index 89a27c9463..86e8a1825c 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt @@ -216,7 +216,7 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor( sendMessageToDevices(requestMessage, request.recipients, request.requestId, object : MatrixCallback { private fun onDone(state: OutgoingRoomKeyRequest.RequestState) { if (request.state !== OutgoingRoomKeyRequest.RequestState.UNSENT) { - Timber.v("## sendOutgoingRoomKeyRequest() : Cannot update room key request from UNSENT as it was already updated to " + request.state) + Timber.v("## sendOutgoingRoomKeyRequest() : Cannot update room key request from UNSENT as it was already updated to ${request.state}") } else { request.state = state cryptoStore.updateOutgoingRoomKeyRequest(request) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index ca1157e583..3115eafc45 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -342,10 +342,8 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre private fun addTransaction(tx: VerificationTransaction) { tx.otherUserId.let { otherUserId -> synchronized(txMap) { - if (txMap[otherUserId] == null) { - txMap[otherUserId] = HashMap() - } - txMap[otherUserId]?.set(tx.transactionId, tx) + val txInnerMap = txMap.getOrPut(otherUserId) { HashMap() } + txInnerMap[tx.transactionId] = tx dispatchTxAdded(tx) tx.addListener(this) } diff --git a/vector/src/main/java/im/vector/riotx/core/linkify/VectorAutoLinkPatterns.kt b/vector/src/main/java/im/vector/riotx/core/linkify/VectorAutoLinkPatterns.kt index e6eb886e02..ae4131b5e9 100644 --- a/vector/src/main/java/im/vector/riotx/core/linkify/VectorAutoLinkPatterns.kt +++ b/vector/src/main/java/im/vector/riotx/core/linkify/VectorAutoLinkPatterns.kt @@ -15,8 +15,6 @@ */ package im.vector.riotx.core.linkify -import java.util.regex.Pattern - /** * Better support for geo URi */ @@ -26,7 +24,7 @@ object VectorAutoLinkPatterns { private const val LAT_OR_LONG_OR_ALT_NUMBER = "-?\\d+(?:\\.\\d+)?" private const val COORDINATE_SYSTEM = ";crs=[\\w-]+" - val GEO_URI: Pattern = Pattern.compile("(?:geo:)?" + + val GEO_URI: Regex = Regex("(?:geo:)?" + "(" + LAT_OR_LONG_OR_ALT_NUMBER + ")" + "," + "(" + LAT_OR_LONG_OR_ALT_NUMBER + ")" + @@ -35,5 +33,5 @@ object VectorAutoLinkPatterns { "(?:" + ";u=\\d+(?:\\.\\d+)?" + ")?" + // uncertainty in meters "(?:" + ";[\\w-]+=(?:[\\w-_.!~*'()]|%[\\da-f][\\da-f])+" + // dafuk - ")*", Pattern.CASE_INSENSITIVE) + ")*", RegexOption.IGNORE_CASE) } diff --git a/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt b/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt index 0d6a71f701..99b0316cbe 100644 --- a/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt +++ b/vector/src/main/java/im/vector/riotx/core/linkify/VectorLinkify.kt @@ -94,7 +94,7 @@ object VectorLinkify { createdSpans.add(LinkSpec(URLSpan(urlSpan.url), start, end)) } - LinkifyCompat.addLinks(spannable, VectorAutoLinkPatterns.GEO_URI, "geo:", arrayOf("geo:"), geoMatchFilter, null) + LinkifyCompat.addLinks(spannable, VectorAutoLinkPatterns.GEO_URI.toPattern(), "geo:", arrayOf("geo:"), geoMatchFilter, null) spannable.forEachSpanIndexed { _, urlSpan, start, end -> spannable.removeSpan(urlSpan) createdSpans.add(LinkSpec(URLSpan(urlSpan.url), start, end)) diff --git a/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt index ceae3a2b76..e2c08a1fe8 100644 --- a/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt +++ b/vector/src/main/java/im/vector/riotx/core/pushers/PushersManager.kt @@ -24,6 +24,7 @@ import im.vector.riotx.core.resources.LocaleProvider import im.vector.riotx.core.resources.StringProvider import java.util.UUID import javax.inject.Inject +import kotlin.math.abs private const val DEFAULT_PUSHER_FILE_TAG = "mobile" @@ -36,7 +37,7 @@ class PushersManager @Inject constructor( fun registerPusherWithFcmKey(pushKey: String): UUID { val currentSession = activeSessionHolder.getActiveSession() - var profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + Math.abs(currentSession.myUserId.hashCode()) + val profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(currentSession.myUserId.hashCode()) return currentSession.addHttpPusher( pushKey, diff --git a/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt b/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt index c65fcafb16..a5babcc885 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt @@ -59,9 +59,10 @@ fun initKnownEmojiHashSet(context: Context, done: (() -> Unit)? = null) { val jsonAdapter = moshi.adapter(EmojiDataSource.EmojiData::class.java) val inputAsString = input.bufferedReader().use { it.readText() } val source = jsonAdapter.fromJson(inputAsString) - knownEmojiSet = HashSet() - source?.emojis?.values?.forEach { - knownEmojiSet?.add(it.emojiString()) + knownEmojiSet = HashSet().also { + source?.emojis?.mapTo(it) { (_, value) -> + value.emojiString() + } } done?.invoke() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt index 32abc0384b..4661d8f8cd 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt @@ -94,7 +94,7 @@ class ViewEditHistoryEpoxyController(private val context: Context, val body = cContent.second?.let { eventHtmlRenderer.render(it) } ?: cContent.first - val nextEvent = if (index + 1 <= sourceEvents.lastIndex) sourceEvents[index + 1] else null + val nextEvent = sourceEvents.getOrNull(index + 1) var spannedDiff: Spannable? = null if (nextEvent != null && cContent.second == null /*No diff for html*/) { diff --git a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt index 076b5d6ea2..40a14b3e6f 100644 --- a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt @@ -130,24 +130,16 @@ object ThemeUtils { */ @ColorInt fun getColor(c: Context, @AttrRes colorAttribute: Int): Int { - if (mColorByAttr.containsKey(colorAttribute)) { - return mColorByAttr[colorAttribute] as Int + return mColorByAttr.getOrPut(colorAttribute) { + try { + val color = TypedValue() + c.theme.resolveAttribute(colorAttribute, color, true) + color.data + } catch (e: Exception) { + Timber.e(e, "Unable to get color") + ContextCompat.getColor(c, android.R.color.holo_red_dark) + } } - - var matchedColor: Int - - try { - val color = TypedValue() - c.theme.resolveAttribute(colorAttribute, color, true) - matchedColor = color.data - } catch (e: Exception) { - Timber.e(e, "Unable to get color") - matchedColor = ContextCompat.getColor(c, android.R.color.holo_red_dark) - } - - mColorByAttr[colorAttribute] = matchedColor - - return matchedColor } fun getAttribute(c: Context, @AttrRes attribute: Int): TypedValue? { From 1ac99e92a6ce025dac9106a973430a5b90153ea9 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Thu, 24 Oct 2019 14:58:11 +0100 Subject: [PATCH 006/117] Light refactoring. Signed-off-by: Dominic Fischer --- .../DefaultSasVerificationService.kt | 114 ++++++++---------- .../room/send/LocalEchoEventFactory.kt | 2 +- .../im/vector/riotx/core/files/FileSaver.kt | 26 ++-- .../im/vector/riotx/core/images/ImageTools.kt | 25 ++-- .../im/vector/riotx/core/intent/Filename.kt | 21 +--- .../features/crypto/keys/KeysExporter.kt | 32 ++--- .../features/crypto/keys/KeysImporter.kt | 37 ++---- .../setup/KeysBackupSetupStep3Fragment.kt | 4 +- .../action/MessageActionsViewModel.kt | 3 +- 9 files changed, 103 insertions(+), 161 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index 3115eafc45..e0cd47e0e0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -43,6 +43,7 @@ import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import timber.log.Timber +import java.lang.Exception import java.util.UUID import javax.inject.Inject import kotlin.collections.HashMap @@ -166,72 +167,59 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre return } // Download device keys prior to everything - checkKeysAreDownloaded( - otherUserId!!, - startReq, - success = { - Timber.v("## SAS onStartRequestReceived ${startReq.transactionID!!}") - val tid = startReq.transactionID!! - val existing = getExistingTransaction(otherUserId, tid) - val existingTxs = getExistingTransactionsForUser(otherUserId) - if (existing != null) { - // should cancel both! - Timber.v("## SAS onStartRequestReceived - Request exist with same if ${startReq.transactionID!!}") - existing.cancel(CancelCode.UnexpectedMessage) - cancelTransaction(tid, otherUserId, startReq.fromDevice!!, CancelCode.UnexpectedMessage) - } else if (existingTxs?.isEmpty() == false) { - Timber.v("## SAS onStartRequestReceived - There is already a transaction with this user ${startReq.transactionID!!}") - // Multiple keyshares between two devices: any two devices may only have at most one key verification in flight at a time. - existingTxs.forEach { - it.cancel(CancelCode.UnexpectedMessage) - } - cancelTransaction(tid, otherUserId, startReq.fromDevice!!, CancelCode.UnexpectedMessage) - } else { - // Ok we can create - if (KeyVerificationStart.VERIF_METHOD_SAS == startReq.method) { - Timber.v("## SAS onStartRequestReceived - request accepted ${startReq.transactionID!!}") - val tx = IncomingSASVerificationTransaction( - this, - setDeviceVerificationAction, - credentials, - cryptoStore, - sendToDeviceTask, - taskExecutor, - myDeviceInfoHolder.get().myDevice.fingerprint()!!, - startReq.transactionID!!, - otherUserId) - addTransaction(tx) - tx.acceptToDeviceEvent(otherUserId, startReq) - } else { - Timber.e("## SAS onStartRequestReceived - unknown method ${startReq.method}") - cancelTransaction(tid, otherUserId, startReq.fromDevice - ?: event.getSenderKey()!!, CancelCode.UnknownMethod) - } - } - }, - error = { - cancelTransaction(startReq.transactionID!!, otherUserId, startReq.fromDevice!!, CancelCode.UnexpectedMessage) - }) + if (checkKeysAreDownloaded(otherUserId!!, startReq) != null) { + Timber.v("## SAS onStartRequestReceived ${startReq.transactionID!!}") + val tid = startReq.transactionID!! + val existing = getExistingTransaction(otherUserId, tid) + val existingTxs = getExistingTransactionsForUser(otherUserId) + if (existing != null) { + // should cancel both! + Timber.v("## SAS onStartRequestReceived - Request exist with same if ${startReq.transactionID!!}") + existing.cancel(CancelCode.UnexpectedMessage) + cancelTransaction(tid, otherUserId, startReq.fromDevice!!, CancelCode.UnexpectedMessage) + } else if (existingTxs?.isEmpty() == false) { + Timber.v("## SAS onStartRequestReceived - There is already a transaction with this user ${startReq.transactionID!!}") + // Multiple keyshares between two devices: any two devices may only have at most one key verification in flight at a time. + existingTxs.forEach { + it.cancel(CancelCode.UnexpectedMessage) + } + cancelTransaction(tid, otherUserId, startReq.fromDevice!!, CancelCode.UnexpectedMessage) + } else { + // Ok we can create + if (KeyVerificationStart.VERIF_METHOD_SAS == startReq.method) { + Timber.v("## SAS onStartRequestReceived - request accepted ${startReq.transactionID!!}") + val tx = IncomingSASVerificationTransaction( + this, + setDeviceVerificationAction, + credentials, + cryptoStore, + sendToDeviceTask, + taskExecutor, + myDeviceInfoHolder.get().myDevice.fingerprint()!!, + startReq.transactionID!!, + otherUserId) + addTransaction(tx) + tx.acceptToDeviceEvent(otherUserId, startReq) + } else { + Timber.e("## SAS onStartRequestReceived - unknown method ${startReq.method}") + cancelTransaction(tid, otherUserId, startReq.fromDevice + ?: event.getSenderKey()!!, CancelCode.UnknownMethod) + } + } + } else { + cancelTransaction(startReq.transactionID!!, otherUserId, startReq.fromDevice!!, CancelCode.UnexpectedMessage) + } } private suspend fun checkKeysAreDownloaded(otherUserId: String, - startReq: KeyVerificationStart, - success: (MXUsersDevicesMap) -> Unit, - error: () -> Unit) { - runCatching { - deviceListManager.downloadKeys(listOf(otherUserId), true) - }.fold( - { - if (it.getUserDeviceIds(otherUserId)?.contains(startReq.fromDevice) == true) { - success(it) - } else { - error() - } - }, - { - error() - } - ) + startReq: KeyVerificationStart): MXUsersDevicesMap? { + return try { + val keys = deviceListManager.downloadKeys(listOf(otherUserId), true) + val deviceIds = keys.getUserDeviceIds(otherUserId) ?: return null + keys.takeIf { deviceIds.contains(startReq.fromDevice) } + } catch (e: Exception) { + null + } } private suspend fun onCancelReceived(event: Event) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt index 49c813ece6..a9406c8bff 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt @@ -39,7 +39,7 @@ import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.util.StringProvider import org.commonmark.parser.Parser import org.commonmark.renderer.html.HtmlRenderer -import java.util.* +import java.util.UUID import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt b/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt index c1f58306a4..677f7894e8 100644 --- a/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt +++ b/vector/src/main/java/im/vector/riotx/core/files/FileSaver.kt @@ -30,15 +30,10 @@ import java.io.File */ @WorkerThread fun writeToFile(str: String, file: File): Try { - return Try { - val sink = file.sink() - - val bufferedSink = sink.buffer() - - bufferedSink.writeString(str, Charsets.UTF_8) - - bufferedSink.close() - sink.close() + return Try { + file.sink().buffer().use { + it.writeString(str, Charsets.UTF_8) + } } } @@ -47,15 +42,10 @@ fun writeToFile(str: String, file: File): Try { */ @WorkerThread fun writeToFile(data: ByteArray, file: File): Try { - return Try { - val sink = file.sink() - - val bufferedSink = sink.buffer() - - bufferedSink.write(data) - - bufferedSink.close() - sink.close() + return Try { + file.sink().buffer().use { + it.write(data) + } } } diff --git a/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt b/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt index b6ae2be20b..84cba7392f 100644 --- a/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt +++ b/vector/src/main/java/im/vector/riotx/core/images/ImageTools.kt @@ -17,7 +17,6 @@ package im.vector.riotx.core.images import android.content.Context -import android.database.Cursor import android.net.Uri import android.provider.MediaStore import androidx.exifinterface.media.ExifInterface @@ -37,26 +36,24 @@ class ImageTools @Inject constructor(private val context: Context) { if (uri.scheme == "content") { val proj = arrayOf(MediaStore.Images.Media.DATA) - var cursor: Cursor? = null try { - cursor = context.contentResolver.query(uri, proj, null, null, null) - if (cursor != null && cursor.count > 0) { - cursor.moveToFirst() - val idxData = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) - val path = cursor.getString(idxData) - if (path.isNullOrBlank()) { - Timber.w("Cannot find path in media db for uri $uri") - return orientation + val cursor = context.contentResolver.query(uri, proj, null, null, null) + cursor?.use { + if (it.moveToFirst()) { + val idxData = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) + val path = it.getString(idxData) + if (path.isNullOrBlank()) { + Timber.w("Cannot find path in media db for uri $uri") + return orientation + } + val exif = ExifInterface(path) + orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED) } - val exif = ExifInterface(path) - orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED) } } catch (e: Exception) { // eg SecurityException from com.google.android.apps.photos.content.GooglePhotosImageProvider URIs // eg IOException from trying to parse the returned path as a file when it is an http uri. Timber.e(e, "Cannot get orientation for bitmap") - } finally { - cursor?.close() } } else if (uri.scheme == "file") { try { diff --git a/vector/src/main/java/im/vector/riotx/core/intent/Filename.kt b/vector/src/main/java/im/vector/riotx/core/intent/Filename.kt index 9e9f0ae508..2b6740f62f 100644 --- a/vector/src/main/java/im/vector/riotx/core/intent/Filename.kt +++ b/vector/src/main/java/im/vector/riotx/core/intent/Filename.kt @@ -17,28 +17,17 @@ package im.vector.riotx.core.intent import android.content.Context -import android.database.Cursor import android.net.Uri import android.provider.OpenableColumns fun getFilenameFromUri(context: Context?, uri: Uri): String? { - var result: String? = null if (context != null && uri.scheme == "content") { - val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null) - try { - if (cursor != null && cursor.moveToFirst()) { - result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)) + val cursor = context.contentResolver.query(uri, null, null, null, null) + cursor?.use { + if (it.moveToFirst()) { + return it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) } - } finally { - cursor?.close() } } - if (result == null) { - result = uri.path - val cut = result?.lastIndexOf('/') ?: -1 - if (cut != -1) { - result = result?.substring(cut + 1) - } - } - return result + return uri.path?.substringAfterLast('/') } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt index 54e3a34744..9642c2d8c6 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysExporter.kt @@ -18,10 +18,10 @@ package im.vector.riotx.features.crypto.keys import android.content.Context import android.os.Environment -import arrow.core.Try import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.internal.extensions.foldToCallback +import im.vector.matrix.android.internal.util.awaitCallback import im.vector.riotx.core.files.addEntryToDownloadManager import im.vector.riotx.core.files.writeToFile import kotlinx.coroutines.Dispatchers @@ -36,28 +36,20 @@ class KeysExporter(private val session: Session) { * Export keys and return the file path with the callback */ fun export(context: Context, password: String, callback: MatrixCallback) { - session.exportRoomKeys(password, object : MatrixCallback { - override fun onSuccess(data: ByteArray) { - GlobalScope.launch(Dispatchers.Main) { - withContext(Dispatchers.IO) { - Try { - val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) - val file = File(parentDir, "riotx-keys-" + System.currentTimeMillis() + ".txt") + GlobalScope.launch(Dispatchers.Main) { + runCatching { + val data = awaitCallback { session.exportRoomKeys(password, it) } + withContext(Dispatchers.IO) { + val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + val file = File(parentDir, "riotx-keys-" + System.currentTimeMillis() + ".txt") - writeToFile(data, file) + writeToFile(data, file) - addEntryToDownloadManager(context, file, "text/plain") + addEntryToDownloadManager(context, file, "text/plain") - file.absolutePath - } - } - .foldToCallback(callback) + file.absolutePath } - } - - override fun onFailure(failure: Throwable) { - callback.onFailure(failure) - } - }) + }.foldToCallback(callback) + } } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysImporter.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysImporter.kt index 74b2a86bc1..b60e25af04 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysImporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keys/KeysImporter.kt @@ -18,10 +18,11 @@ package im.vector.riotx.features.crypto.keys import android.content.Context import android.net.Uri -import arrow.core.Try import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult +import im.vector.matrix.android.internal.extensions.foldToCallback +import im.vector.matrix.android.internal.util.awaitCallback import im.vector.riotx.core.intent.getMimeTypeFromUri import im.vector.riotx.core.resources.openResource import kotlinx.coroutines.Dispatchers @@ -41,8 +42,8 @@ class KeysImporter(private val session: Session) { password: String, callback: MatrixCallback) { GlobalScope.launch(Dispatchers.Main) { - withContext(Dispatchers.IO) { - Try { + runCatching { + withContext(Dispatchers.IO) { val resource = openResource(context, uri, mimetype ?: getMimeTypeFromUri(context, uri)) if (resource?.mContentStream == null) { @@ -51,33 +52,17 @@ class KeysImporter(private val session: Session) { val data: ByteArray try { - data = ByteArray(resource.mContentStream!!.available()) - resource.mContentStream!!.read(data) - resource.mContentStream!!.close() - - data + data = resource.mContentStream!!.use { it.readBytes() } } catch (e: Exception) { - try { - resource.mContentStream!!.close() - } catch (e2: Exception) { - Timber.e(e2, "## importKeys()") - } - + Timber.e(e, "## importKeys()") throw e } + + awaitCallback { + session.importRoomKeys(data, password, null, it) + } } - } - .fold( - { - callback.onFailure(it) - }, - { byteArray -> - session.importRoomKeys(byteArray, - password, - null, - callback) - } - ) + }.foldToCallback(callback) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index 7b61ca2c0f..a5cc0510da 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -170,8 +170,8 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() { private fun exportRecoveryKeyToFile(data: String) { GlobalScope.launch(Dispatchers.Main) { - withContext(Dispatchers.IO) { - Try { + Try { + withContext(Dispatchers.IO) { val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) val file = File(parentDir, "recovery-key-" + System.currentTimeMillis() + ".txt") 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 135496264d..63a4919763 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 @@ -42,7 +42,8 @@ import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventForm 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.* +import java.util.Date +import java.util.Locale /** * Quick reactions state From 7c567b04bbf89e30c76cd4bf8b090ba557ddfdfd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 16:36:12 +0200 Subject: [PATCH 007/117] Make test compile and pass --- .../api/pushrules/PushRuleActionsTest.kt | 23 ++++++++----------- .../api/pushrules/PushrulesConditionTest.kt | 4 ++++ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt index f98af53333..17543e9d25 100644 --- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt +++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushRuleActionsTest.kt @@ -18,7 +18,7 @@ package im.vector.matrix.android.api.pushrules import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.matrix.android.internal.di.MoshiProvider -import org.junit.Assert +import org.junit.Assert.* import org.junit.Test class PushRuleActionsTest { @@ -63,22 +63,17 @@ class PushRuleActionsTest { val pushRule = MoshiProvider.providesMoshi().adapter(PushRule::class.java).fromJson(rawPushRule) - Assert.assertNotNull("Should have parsed the rule", pushRule) - Assert.assertNotNull("Failed to parse actions", Action.mapFrom(pushRule!!)) + assertNotNull("Should have parsed the rule", pushRule) - val actions = Action.mapFrom(pushRule) - Assert.assertEquals(3, actions!!.size) + val actions = pushRule!!.getActions() + assertEquals(3, actions.size) - Assert.assertEquals("First action should be notify", Action.Type.NOTIFY, actions[0].type) + assertTrue("First action should be notify", actions[0] is Action.Notify) - Assert.assertEquals("Second action should be tweak", Action.Type.SET_TWEAK, actions[1].type) - Assert.assertEquals("Second action tweak key should be sound", "sound", actions[1].tweak_action) - Assert.assertEquals("Second action should have default as stringValue", "default", actions[1].stringValue) - Assert.assertNull("Second action boolValue should be null", actions[1].boolValue) + assertTrue("Second action should be sound", actions[1] is Action.Sound) + assertEquals("Second action should have default sound", "default", (actions[1] as Action.Sound).sound) - Assert.assertEquals("Third action should be tweak", Action.Type.SET_TWEAK, actions[2].type) - Assert.assertEquals("Third action tweak key should be highlight", "highlight", actions[2].tweak_action) - Assert.assertEquals("Third action tweak param should be false", false, actions[2].boolValue) - Assert.assertNull("Third action stringValue should be null", actions[2].stringValue) + assertTrue("Third action should be highlight", actions[2] is Action.Highlight) + assertEquals("Third action tweak param should be false", false, (actions[2] as Action.Highlight).highlight) } } diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt index 42e7e850b3..7651b32d20 100644 --- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt @@ -199,6 +199,10 @@ class PushrulesConditionTest { } class MockRoom(override val roomId: String, val _numberOfJoinedMembers: Int) : Room { + override fun reportContent(eventId: String, score: Int, reason: String, callback: MatrixCallback): Cancelable { + TODO("not implemented") // To change body of created functions use File | Settings | File Templates. + } + override fun getReadMarkerLive(): LiveData> { TODO("not implemented") // To change body of created functions use File | Settings | File Templates. } From 8422c6de1752503ce6ced5fe671ac0ee8e21cb4c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 17:21:19 +0200 Subject: [PATCH 008/117] Remove test sample --- .../matrix/rx/ExampleInstrumentedTest.java | 42 ------------------- .../im/vector/matrix/rx/ExampleUnitTest.java | 33 --------------- .../vector/riotx/ExampleInstrumentedTest.kt | 40 ------------------ .../java/im/vector/riotx/ExampleUnitTest.kt | 33 --------------- 4 files changed, 148 deletions(-) delete mode 100644 matrix-sdk-android-rx/src/androidTest/java/im/vector/matrix/rx/ExampleInstrumentedTest.java delete mode 100644 matrix-sdk-android-rx/src/test/java/im/vector/matrix/rx/ExampleUnitTest.java delete mode 100644 vector/src/androidTest/java/im/vector/riotx/ExampleInstrumentedTest.kt delete mode 100644 vector/src/test/java/im/vector/riotx/ExampleUnitTest.kt diff --git a/matrix-sdk-android-rx/src/androidTest/java/im/vector/matrix/rx/ExampleInstrumentedTest.java b/matrix-sdk-android-rx/src/androidTest/java/im/vector/matrix/rx/ExampleInstrumentedTest.java deleted file mode 100644 index 986d40d1a9..0000000000 --- a/matrix-sdk-android-rx/src/androidTest/java/im/vector/matrix/rx/ExampleInstrumentedTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.matrix.rx; - -import android.content.Context; -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("im.vector.matrix.rx.test", appContext.getPackageName()); - } -} diff --git a/matrix-sdk-android-rx/src/test/java/im/vector/matrix/rx/ExampleUnitTest.java b/matrix-sdk-android-rx/src/test/java/im/vector/matrix/rx/ExampleUnitTest.java deleted file mode 100644 index 6b7fcfe7e6..0000000000 --- a/matrix-sdk-android-rx/src/test/java/im/vector/matrix/rx/ExampleUnitTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.matrix.rx; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/vector/src/androidTest/java/im/vector/riotx/ExampleInstrumentedTest.kt b/vector/src/androidTest/java/im/vector/riotx/ExampleInstrumentedTest.kt deleted file mode 100644 index afed0c783a..0000000000 --- a/vector/src/androidTest/java/im/vector/riotx/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 - -import androidx.test.InstrumentationRegistry -import androidx.test.runner.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getTargetContext() - assertEquals("im.vector.riotx", appContext.packageName) - } -} diff --git a/vector/src/test/java/im/vector/riotx/ExampleUnitTest.kt b/vector/src/test/java/im/vector/riotx/ExampleUnitTest.kt deleted file mode 100644 index c51f642a1b..0000000000 --- a/vector/src/test/java/im/vector/riotx/ExampleUnitTest.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} From 2929b8f6173023b5484896a32a46cf2d63b862ea Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 17:24:42 +0200 Subject: [PATCH 009/117] Ensure Android tests compile and fix warnings --- .buildkite/pipeline.yml | 14 +++++++++++++- .../im/vector/matrix/android/InstrumentedTest.kt | 4 ++-- .../matrix/android/auth/AuthenticatorTest.kt | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 9a4c4b17a9..9d8be1e0ef 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -4,7 +4,7 @@ # We propagate the environment to the container (sse https://github.com/buildkite-plugins/docker-buildkite-plugin#propagate-environment-optional-boolean) steps: - - label: "Unit test" + - label: "Compile and run Unit tests" agents: # We use a medium sized instance instead of the normal small ones because # gradle build is long @@ -16,6 +16,18 @@ steps: image: "runmymind/docker-android-sdk" propagate-environment: true + - label: "Compile Android tests" + agents: + # We use a medium sized instance instead of the normal small ones because + # gradle build is long + queue: "medium" + commands: + - "./gradlew clean assembleAndroidTest --stacktrace" + plugins: + - docker#v3.1.0: + image: "runmymind/docker-android-sdk" + propagate-environment: true + - label: "Assemble GPlay Debug version" agents: # We use a medium sized instance instead of the normal small ones because diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt index 3cd47d4998..99fe7d29b4 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/InstrumentedTest.kt @@ -17,12 +17,12 @@ package im.vector.matrix.android import android.content.Context -import androidx.test.InstrumentationRegistry +import androidx.test.core.app.ApplicationProvider import java.io.File interface InstrumentedTest { fun context(): Context { - return InstrumentationRegistry.getTargetContext() + return ApplicationProvider.getApplicationContext() } fun cacheDir(): File { diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt index 7d33fae4d8..5c86f5ad22 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt @@ -17,8 +17,8 @@ package im.vector.matrix.android.auth import androidx.test.annotation.UiThreadTest +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.GrantPermissionRule -import androidx.test.runner.AndroidJUnit4 import im.vector.matrix.android.InstrumentedTest import im.vector.matrix.android.OkReplayRuleChainNoActivity import im.vector.matrix.android.api.auth.Authenticator From 6cca242f77a71013b52035d48760694e7b1c5e91 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 17:32:16 +0200 Subject: [PATCH 010/117] Fix Android test compilation issue --- matrix-sdk-android-rx/build.gradle | 2 ++ matrix-sdk-android/build.gradle | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android-rx/build.gradle b/matrix-sdk-android-rx/build.gradle index 31f928c241..1d8e81e44f 100644 --- a/matrix-sdk-android-rx/build.gradle +++ b/matrix-sdk-android-rx/build.gradle @@ -11,6 +11,8 @@ android { versionCode 1 versionName "1.0" + // Multidex is useful for tests + multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 3e6d3ea88b..ab5f122dbc 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -155,7 +155,8 @@ dependencies { testImplementation 'junit:junit:4.12' testImplementation 'org.robolectric:robolectric:4.3' //testImplementation 'org.robolectric:shadows-support-v4:3.0' - testImplementation 'io.mockk:mockk:1.9.3.kotlin12' + // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281 + testImplementation 'io.mockk:mockk:1.9.2.kotlin12' testImplementation 'org.amshove.kluent:kluent-android:1.44' testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" @@ -165,7 +166,8 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' androidTestImplementation 'org.amshove.kluent:kluent-android:1.44' - androidTestImplementation 'io.mockk:mockk-android:1.9.3.kotlin12' + // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281 + androidTestImplementation 'io.mockk:mockk-android:1.9.2.kotlin12' androidTestImplementation "androidx.arch.core:core-testing:$lifecycle_version" androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" From 0040f8e924d13a0b55a22e343621109ed3e64a58 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 18:51:47 +0200 Subject: [PATCH 011/117] Fix crash reported by Rageshake, stateKey can be null --- .../android/internal/session/room/membership/RoomMembers.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomMembers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomMembers.kt index b50424b343..9fba1d8f02 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomMembers.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomMembers.kt @@ -73,6 +73,7 @@ internal class RoomMembers(private val realm: Realm, return EventEntity .where(realm, roomId, EventType.STATE_ROOM_MEMBER) .sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING) + .isNotNull(EventEntityFields.STATE_KEY) .distinct(EventEntityFields.STATE_KEY) .isNotNull(EventEntityFields.CONTENT) } From fbf73c7c8eb41a75b591f3ecafb6baee23ccca94 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 24 Oct 2019 18:52:34 +0200 Subject: [PATCH 012/117] shorter code --- .../home/room/detail/composer/TextComposerViewModel.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) 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 84917d682b..69ecc30583 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 @@ -76,11 +76,8 @@ class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: Observable.combineLatest, Option, List>( room.rx().liveRoomMemberIds(), usersQueryObservable.throttleLast(300, TimeUnit.MILLISECONDS), - BiFunction { roomMembers, query -> - val users = roomMembers - .mapNotNull { - session.getUser(it) - } + BiFunction { roomMemberIds, query -> + val users = roomMemberIds.mapNotNull { session.getUser(it) } val filter = query.orNull() if (filter.isNullOrBlank()) { From cb275aee37e92c7dff90fc3270f807b45d900b8c Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 24 Oct 2019 19:11:49 +0200 Subject: [PATCH 013/117] Room list actions: start showing items and refact a bit RxStore --- .../riotx/ActiveSessionObservableStore.kt | 4 +- .../vector/riotx/core/di/ViewModelModule.kt | 14 ----- .../bottomsheet}/BottomSheetItemAction.kt | 5 +- .../BottomSheetItemMessagePreview.kt | 12 ++-- .../BottomSheetItemQuickReactions.kt | 5 +- .../bottomsheet/BottomSheetItemRoomPreview.kt | 57 +++++++++++++++++++ .../bottomsheet}/BottomSheetItemSendState.kt | 5 +- .../bottomsheet}/BottomSheetItemSeparator.kt | 5 +- .../riotx/core/mvrx/NavigationViewModel.kt | 34 ----------- .../riotx/core/platform/VectorViewModel.kt | 1 + .../im/vector/riotx/core/utils/RxStore.kt | 34 ++++++++++- .../riotx/features/home/HomeActivity.kt | 20 ++++--- .../riotx/features/home/HomeDetailFragment.kt | 2 +- .../features/home/HomeNavigationViewModel.kt | 8 ++- .../home/HomeRoomListObservableStore.kt | 4 +- .../createdirect/CreateDirectRoomActivity.kt | 17 +++--- .../CreateDirectRoomDirectoryUsersFragment.kt | 4 +- .../CreateDirectRoomKnownUsersFragment.kt | 2 +- .../CreateDirectRoomNavigationViewModel.kt | 8 ++- .../features/home/group/GroupListFragment.kt | 2 +- .../features/home/group/SelectedGroupStore.kt | 4 +- .../home/room/detail/RoomDetailFragment.kt | 15 +++-- .../action/MessageActionsBottomSheet.kt | 6 +- .../action/MessageActionsEpoxyController.kt | 9 ++- ...tionsHandler.kt => MessageActionsStore.kt} | 17 ++---- .../home/room/list/RoomListActions.kt | 2 + .../home/room/list/RoomListFragment.kt | 21 +++++++ .../home/room/list/RoomListViewModel.kt | 25 ++++++-- .../room/list/actions/RoomListQuickActions.kt | 20 +++++++ .../RoomListQuickActionsBottomSheet.kt | 8 ++- .../RoomListQuickActionsEpoxyController.kt | 47 +++++++++++---- .../list/actions/RoomListQuickActionsState.kt | 3 +- .../list/actions/RoomListQuickActionsStore.kt | 28 +++++++++ .../actions/RoomListQuickActionsViewModel.kt | 23 ++++++-- .../features/navigation/DefaultNavigator.kt | 5 ++ .../riotx/features/navigation/Navigator.kt | 3 + .../roomdirectory/PublicRoomsFragment.kt | 4 +- .../roomdirectory/RoomDirectoryActivity.kt | 18 +++--- .../RoomDirectoryNavigationViewModel.kt | 8 ++- .../createroom/CreateRoomActivity.kt | 14 +++-- .../createroom/CreateRoomFragment.kt | 4 +- .../picker/RoomDirectoryPickerFragment.kt | 2 +- .../res/drawable/ic_room_actions_leave.xml | 47 +++++++++++++++ .../ic_room_actions_notifications_all.xml | 39 +++++++++++++ ...c_room_actions_notifications_all_noisy.xml | 39 +++++++++++++ ...ic_room_actions_notifications_mentions.xml | 47 +++++++++++++++ .../ic_room_actions_notifications_mutes.xml | 47 +++++++++++++++ .../res/drawable/ic_room_actions_settings.xml | 39 +++++++++++++ .../layout/item_bottom_sheet_room_preview.xml | 57 +++++++++++++++++++ vector/src/main/res/values/strings_riotX.xml | 7 ++- 50 files changed, 683 insertions(+), 168 deletions(-) rename vector/src/main/java/im/vector/riotx/{features/home/room/detail/timeline/action => core/epoxy/bottomsheet}/BottomSheetItemAction.kt (94%) rename vector/src/main/java/im/vector/riotx/{features/home/room/detail/timeline/action => core/epoxy/bottomsheet}/BottomSheetItemMessagePreview.kt (84%) rename vector/src/main/java/im/vector/riotx/{features/home/room/detail/timeline/action => core/epoxy/bottomsheet}/BottomSheetItemQuickReactions.kt (96%) create mode 100644 vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemRoomPreview.kt rename vector/src/main/java/im/vector/riotx/{features/home/room/detail/timeline/action => core/epoxy/bottomsheet}/BottomSheetItemSendState.kt (93%) rename vector/src/main/java/im/vector/riotx/{features/home/room/detail/timeline/action => core/epoxy/bottomsheet}/BottomSheetItemSeparator.kt (88%) delete mode 100644 vector/src/main/java/im/vector/riotx/core/mvrx/NavigationViewModel.kt rename vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/{ActionsHandler.kt => MessageActionsStore.kt} (65%) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt create mode 100644 vector/src/main/res/drawable/ic_room_actions_leave.xml create mode 100644 vector/src/main/res/drawable/ic_room_actions_notifications_all.xml create mode 100644 vector/src/main/res/drawable/ic_room_actions_notifications_all_noisy.xml create mode 100644 vector/src/main/res/drawable/ic_room_actions_notifications_mentions.xml create mode 100644 vector/src/main/res/drawable/ic_room_actions_notifications_mutes.xml create mode 100644 vector/src/main/res/drawable/ic_room_actions_settings.xml create mode 100644 vector/src/main/res/layout/item_bottom_sheet_room_preview.xml diff --git a/vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt b/vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt index fd6a92e820..cb89497577 100644 --- a/vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt @@ -19,9 +19,9 @@ package im.vector.riotx import arrow.core.Option import im.vector.matrix.android.api.session.Session -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.BehaviorStore import javax.inject.Inject import javax.inject.Singleton @Singleton -class ActiveSessionObservableStore @Inject constructor() : RxStore>() +class ActiveSessionObservableStore @Inject constructor() : BehaviorStore>() diff --git a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt index 98c89c421a..83aa7103d9 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt @@ -76,16 +76,6 @@ interface ViewModelModule { @ViewModelKey(KeysBackupRestoreFromPassphraseViewModel::class) fun bindKeysBackupRestoreFromPassphraseViewModel(viewModel: KeysBackupRestoreFromPassphraseViewModel): ViewModel - @Binds - @IntoMap - @ViewModelKey(RoomDirectoryNavigationViewModel::class) - fun bindRoomDirectoryNavigationViewModel(viewModel: RoomDirectoryNavigationViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(HomeNavigationViewModel::class) - fun bindHomeNavigationViewModel(viewModel: HomeNavigationViewModel): ViewModel - @Binds @IntoMap @ViewModelKey(KeysBackupSetupSharedViewModel::class) @@ -96,8 +86,4 @@ interface ViewModelModule { @ViewModelKey(ConfigurationViewModel::class) fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel - @Binds - @IntoMap - @ViewModelKey(CreateDirectRoomNavigationViewModel::class) - fun bindCreateDirectRoomNavigationViewModel(viewModel: CreateDirectRoomNavigationViewModel): ViewModel } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemAction.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt similarity index 94% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemAction.kt rename to vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt index d0d5b1deea..1099243ace 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemAction.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt @@ -5,15 +5,16 @@ * 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 + * 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.room.detail.timeline.action +package im.vector.riotx.core.epoxy.bottomsheet import android.view.View import android.widget.ImageView diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemMessagePreview.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemMessagePreview.kt similarity index 84% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemMessagePreview.kt rename to vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemMessagePreview.kt index d37aa43770..999068b289 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemMessagePreview.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemMessagePreview.kt @@ -5,15 +5,16 @@ * 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 + * 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.room.detail.timeline.action +package im.vector.riotx.core.epoxy.bottomsheet import android.widget.ImageView import android.widget.TextView @@ -24,7 +25,6 @@ import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel import im.vector.riotx.core.extensions.setTextOrHide import im.vector.riotx.features.home.AvatarRenderer -import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData /** * A message preview for bottom sheet. @@ -35,7 +35,9 @@ abstract class BottomSheetItemMessagePreview : VectorEpoxyModel() { + + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + @EpoxyAttribute + lateinit var avatarUrl: String + @EpoxyAttribute + lateinit var roomId: String + @EpoxyAttribute + var roomName: String? = null + @EpoxyAttribute var settingsClickListener: View.OnClickListener? = null + + override fun bind(holder: Holder) { + avatarRenderer.render(avatarUrl, roomId, roomName, holder.avatar) + holder.roomName.setTextOrHide(roomName) + holder.roomSettings.setOnClickListener(settingsClickListener) + } + + class Holder : VectorEpoxyHolder() { + val avatar by bind(R.id.bottomSheetRoomPreviewAvatar) + val roomName by bind(R.id.bottomSheetRoomPreviewName) + val roomSettings by bind(R.id.bottomSheetRoomPreviewSettings) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemSendState.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemSendState.kt similarity index 93% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemSendState.kt rename to vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemSendState.kt index 86a5512349..08d727cfa9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemSendState.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemSendState.kt @@ -5,15 +5,16 @@ * 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 + * 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.room.detail.timeline.action +package im.vector.riotx.core.epoxy.bottomsheet import android.view.View import android.widget.TextView diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemSeparator.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemSeparator.kt similarity index 88% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemSeparator.kt rename to vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemSeparator.kt index f09f68b714..fddf507bf9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/BottomSheetItemSeparator.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemSeparator.kt @@ -5,15 +5,16 @@ * 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 + * 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.room.detail.timeline.action +package im.vector.riotx.core.epoxy.bottomsheet import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R diff --git a/vector/src/main/java/im/vector/riotx/core/mvrx/NavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/core/mvrx/NavigationViewModel.kt deleted file mode 100644 index 3491f8d340..0000000000 --- a/vector/src/main/java/im/vector/riotx/core/mvrx/NavigationViewModel.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.core.mvrx - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import im.vector.riotx.core.extensions.postLiveEvent -import im.vector.riotx.core.utils.LiveEvent - -abstract class NavigationViewModel : ViewModel() { - - private val _navigateTo = MutableLiveData>() - val navigateTo: LiveData> - get() = _navigateTo - - fun goTo(navigation: NavigationClass) { - _navigateTo.postLiveEvent(navigation) - } -} 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 9679c20efb..7f04f184a8 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 @@ -44,4 +44,5 @@ abstract class VectorViewModel(initialState: S) .onErrorReturn { Fail(it) } .doOnNext { setState { stateReducer(it) } } } + } diff --git a/vector/src/main/java/im/vector/riotx/core/utils/RxStore.kt b/vector/src/main/java/im/vector/riotx/core/utils/RxStore.kt index b539ade931..0bac82e58e 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/RxStore.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/RxStore.kt @@ -17,18 +17,30 @@ package im.vector.riotx.core.utils import com.jakewharton.rxrelay2.BehaviorRelay +import com.jakewharton.rxrelay2.PublishRelay import io.reactivex.Observable import io.reactivex.schedulers.Schedulers -open class RxStore(private val defaultValue: T? = null) { +/** + * An interface to handle InMemory Rx Store from which you can post or observe values. + */ +interface RxStore { + fun observe(): Observable + fun post(value: T) +} + +/** + * This store emits the most recent value it has observed and all subsequent observed values to each subscriber. + */ +open class BehaviorStore(private val defaultValue: T? = null) : RxStore { private val storeRelay = createRelay() - fun observe(): Observable { + override fun observe(): Observable { return storeRelay.hide().observeOn(Schedulers.computation()) } - fun post(value: T) { + override fun post(value: T) { storeRelay.accept(value) } @@ -40,3 +52,19 @@ open class RxStore(private val defaultValue: T? = null) { } } } + +/** + * This store only emits all subsequent observed values to each subscriber. + */ +open class PublishStore : RxStore { + + private val storeRelay = PublishRelay.create() + + override fun observe(): Observable { + return storeRelay.hide() + } + + override fun post(value: T) { + storeRelay.accept(value) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index af367164fc..e552af0095 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -85,16 +85,18 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { replaceFragment(homeDrawerFragment, R.id.homeDrawerFragmentContainer) } - navigationViewModel.navigateTo.observeEvent(this) { navigation -> - when (navigation) { - is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) - is Navigation.OpenGroup -> { - drawerLayout.closeDrawer(GravityCompat.START) - val homeDetailFragment = HomeDetailFragment.newInstance() - replaceFragment(homeDetailFragment, R.id.homeDetailFragmentContainer) + navigationViewModel.observe() + .subscribe { navigation -> + when (navigation) { + is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) + is Navigation.OpenGroup -> { + drawerLayout.closeDrawer(GravityCompat.START) + val homeDetailFragment = HomeDetailFragment.newInstance() + replaceFragment(homeDetailFragment, R.id.homeDetailFragmentContainer) + } + } } - } - } + .disposeOnDestroy() if (intent.getBooleanExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION, false)) { notificationDrawerManager.clearAllEvents() 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 844fd4f5b2..5bb427188e 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 @@ -133,7 +133,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { } groupToolbar.title = "" groupToolbarAvatarImageView.setOnClickListener { - navigationViewModel.goTo(HomeActivity.Navigation.OpenDrawer) + navigationViewModel.post(HomeActivity.Navigation.OpenDrawer) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt index e1ab437060..122eee1833 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt @@ -16,7 +16,9 @@ package im.vector.riotx.features.home -import im.vector.riotx.core.mvrx.NavigationViewModel -import javax.inject.Inject +import androidx.lifecycle.ViewModel +import im.vector.riotx.core.utils.PublishStore +import im.vector.riotx.core.utils.RxStore -class HomeNavigationViewModel @Inject constructor() : NavigationViewModel() +class HomeNavigationViewModel(private val store: RxStore = PublishStore()) + : ViewModel(), RxStore by store diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt index df8cd411bb..6b43af4bfc 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt @@ -17,9 +17,9 @@ package im.vector.riotx.features.home import im.vector.matrix.android.api.session.room.model.RoomSummary -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.BehaviorStore import javax.inject.Inject import javax.inject.Singleton @Singleton -class HomeRoomListObservableStore @Inject constructor() : RxStore>() +class HomeRoomListObservableStore @Inject constructor() : BehaviorStore>() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index a94b2b85da..2b4322a87c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -59,13 +59,16 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { super.onCreate(savedInstanceState) toolbar.visibility = View.GONE navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) - navigationViewModel.navigateTo.observeEvent(this) { navigation -> - when (navigation) { - is Navigation.UsersDirectory -> addFragmentToBackstack(CreateDirectRoomDirectoryUsersFragment(), R.id.container) - Navigation.Close -> finish() - Navigation.Previous -> onBackPressed() - } - } + navigationViewModel + .observe() + .subscribe { navigation -> + when (navigation) { + is Navigation.UsersDirectory -> addFragmentToBackstack(CreateDirectRoomDirectoryUsersFragment(), R.id.container) + Navigation.Close -> finish() + Navigation.Previous -> onBackPressed() + } + } + .disposeOnDestroy() if (isFirstCreation()) { addFragment(CreateDirectRoomKnownUsersFragment(), R.id.container) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 6125d1b6b9..ca4b26ced8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -74,7 +74,7 @@ class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), DirectoryUs private fun setupCloseView() { createDirectRoomClose.setOnClickListener { - navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.Previous) + navigationViewModel.post(CreateDirectRoomActivity.Navigation.Previous) } } @@ -85,7 +85,7 @@ class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), DirectoryUs override fun onItemClick(user: User) { view?.hideKeyboard() viewModel.handle(CreateDirectRoomActions.SelectUser(user)) - navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.Previous) + navigationViewModel.post(CreateDirectRoomActivity.Navigation.Previous) } override fun retryDirectoryUsersRequest() { diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 04e8d16fd7..124ca018d1 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -96,7 +96,7 @@ class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersContr private fun setupAddByMatrixIdView() { addByMatrixId.setOnClickListener { - navigationViewModel.goTo(CreateDirectRoomActivity.Navigation.UsersDirectory) + navigationViewModel.post(CreateDirectRoomActivity.Navigation.UsersDirectory) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt index e57d58a137..d120c306fb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt @@ -16,7 +16,9 @@ package im.vector.riotx.features.home.createdirect -import im.vector.riotx.core.mvrx.NavigationViewModel -import javax.inject.Inject +import androidx.lifecycle.ViewModel +import im.vector.riotx.core.utils.PublishStore +import im.vector.riotx.core.utils.RxStore -class CreateDirectRoomNavigationViewModel @Inject constructor(): NavigationViewModel() +class CreateDirectRoomNavigationViewModel(private val store: RxStore = PublishStore()) + : ViewModel(), RxStore by store 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 54c2044ae4..77f34d7854 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 @@ -60,7 +60,7 @@ class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback groupListEpoxyRecyclerView.setController(groupController) viewModel.subscribe { renderState(it) } viewModel.openGroupLiveData.observeEvent(this) { - navigationViewModel.goTo(HomeActivity.Navigation.OpenGroup) + navigationViewModel.post(HomeActivity.Navigation.OpenGroup) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt b/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt index a6291ecbb5..a74f24c1d5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt @@ -18,9 +18,9 @@ package im.vector.riotx.features.home.group import arrow.core.Option import im.vector.matrix.android.api.session.group.model.GroupSummary -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.BehaviorStore import javax.inject.Inject import javax.inject.Singleton @Singleton -class SelectedGroupStore @Inject constructor() : RxStore>(Option.empty()) +class SelectedGroupStore @Inject constructor() : BehaviorStore>(Option.empty()) 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 7c4437d6f0..a525e7acc6 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 @@ -100,8 +100,8 @@ import im.vector.riotx.features.home.room.detail.composer.TextComposerViewModel import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController -import im.vector.riotx.features.home.room.detail.timeline.action.ActionsHandler import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet +import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsStore import im.vector.riotx.features.home.room.detail.timeline.action.SimpleAction import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.item.* @@ -202,7 +202,7 @@ class RoomDetailFragment : override fun getMenuRes() = R.menu.menu_timeline - private lateinit var actionViewModel: ActionsHandler + private lateinit var messageActionsStore: MessageActionsStore private lateinit var layoutManager: LinearLayoutManager private lateinit var attachmentsHelper: AttachmentsHelper private lateinit var keyboardStateUtils: KeyboardStateUtils @@ -219,7 +219,7 @@ class RoomDetailFragment : override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java) + messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsStore::class.java) attachmentsHelper = AttachmentsHelper.create(this, this).register() keyboardStateUtils = KeyboardStateUtils(requireActivity()) setupToolbar(roomToolbar) @@ -238,9 +238,12 @@ class RoomDetailFragment : val message = requireContext().getString(pair.first, *pair.second.toTypedArray()) showSnackWithMessage(message, Snackbar.LENGTH_LONG) } - actionViewModel.actionCommandEvent.observeEvent(this) { - handleActions(it) - } + messageActionsStore + .observe() + .subscribe { + handleActions(it) + } + .disposeOnDestroy() roomDetailViewModel.navigateToEvent.observeEvent(this) { val scrollPosition = timelineEventController.searchPositionOfEvent(it) 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 8aaa7643c2..2f0e3fab65 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 @@ -47,7 +47,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override val showExpanded = true - private lateinit var actionHandlerModel: ActionsHandler + private lateinit var messageActionsStore: MessageActionsStore override fun injectWith(screenComponent: ScreenComponent) { screenComponent.inject(this) @@ -61,7 +61,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionHandlerModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java) + messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsStore::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = messageActionsEpoxyController.adapter // Disable item animation @@ -74,7 +74,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message // Toggle report menu viewModel.toggleReportMenu() } else { - actionHandlerModel.fireAction(simpleAction) + messageActionsStore.post(simpleAction) dismiss() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index d9119f08b3..7fdb286c26 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -20,6 +20,12 @@ import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Success import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.R +import im.vector.riotx.core.epoxy.bottomsheet.BottomSheetItemQuickReactions +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemAction +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemMessagePreview +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemQuickReactions +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemSendState +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemSeparator import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.AvatarRenderer import javax.inject.Inject @@ -40,7 +46,8 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid bottomSheetItemMessagePreview { id("preview") avatarRenderer(avatarRenderer) - informationData(state.informationData) + avatarUrl(state.informationData.avatarUrl ?: "") + senderId(state.informationData.senderId) senderName(state.senderName()) body(body) time(state.time()) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsStore.kt similarity index 65% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsStore.kt index c9284b6ece..5c4c6fed80 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ActionsHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsStore.kt @@ -15,20 +15,13 @@ */ package im.vector.riotx.features.home.room.detail.timeline.action -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import im.vector.riotx.core.extensions.postLiveEvent -import im.vector.riotx.core.utils.LiveEvent -import javax.inject.Inject +import im.vector.riotx.core.utils.PublishStore +import im.vector.riotx.core.utils.RxStore /** * Activity shared view model to handle message actions */ -class ActionsHandler @Inject constructor() : ViewModel() { - - val actionCommandEvent = MutableLiveData>() - - fun fireAction(action: SimpleAction) { - actionCommandEvent.postLiveEvent(action) - } -} +class MessageActionsStore constructor( + private val store: RxStore = PublishStore() +) : ViewModel(), RxStore by store 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 8271086421..81b26a99d4 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 @@ -24,5 +24,7 @@ sealed class RoomListActions { data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListActions() data class RejectInvitation(val roomSummary: RoomSummary) : RoomListActions() data class FilterWith(val filter: String) : RoomListActions() + data class ChangeNotificationMode(val notificationMode: String) : RoomListActions() + data class LeaveRoom(val roomId: String) : RoomListActions() object MarkAllRoomsRead : 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 76e4ff9e3b..22415fd792 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 @@ -23,6 +23,7 @@ import android.view.MenuItem import androidx.annotation.StringRes import androidx.core.content.ContextCompat import androidx.core.view.isVisible +import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.* @@ -39,7 +40,9 @@ import im.vector.riotx.core.extensions.observeEventFirstThrottle import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActions import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsStore import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData @@ -71,6 +74,7 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O } } + private lateinit var quickActionsDispatcher: RoomListQuickActionsStore private val roomListParams: RoomListParams by args() @Inject lateinit var roomController: RoomSummaryController @Inject lateinit var roomListViewModelFactory: RoomListViewModel.Factory @@ -106,6 +110,7 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) + quickActionsDispatcher = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsStore::class.java) setupCreateRoomButton() setupRecyclerView() roomListViewModel.subscribe { renderState(it) } @@ -126,6 +131,11 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O .show() } } + + quickActionsDispatcher + .observe() + .subscribe { handleQuickActions(it) } + .disposeOnDestroy() } private fun setupCreateRoomButton() { @@ -204,6 +214,17 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O } } + private fun handleQuickActions(quickActions: RoomListQuickActions) { + when (quickActions) { + is RoomListQuickActions.NotificationsAllNoisy -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) + is RoomListQuickActions.NotificationsAll -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) + is RoomListQuickActions.NotificationsMentionsOnly -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) + is RoomListQuickActions.NotificationsMute -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) + is RoomListQuickActions.Settings -> navigator.openRoomSettings(requireContext(), quickActions.roomId) + is RoomListQuickActions.Leave -> roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) + } + } + private fun renderState(state: RoomListViewState) { when (state.asyncFilteredRooms) { is Incomplete -> renderLoading() 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 b7a10edd49..c6010f89f0 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 @@ -73,12 +73,14 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room fun accept(action: RoomListActions) { when (action) { - is RoomListActions.SelectRoom -> handleSelectRoom(action) - is RoomListActions.ToggleCategory -> handleToggleCategory(action) - is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action) - is RoomListActions.RejectInvitation -> handleRejectInvitation(action) - is RoomListActions.FilterWith -> handleFilter(action) - is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead() + is RoomListActions.SelectRoom -> handleSelectRoom(action) + is RoomListActions.ToggleCategory -> handleToggleCategory(action) + is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action) + is RoomListActions.RejectInvitation -> handleRejectInvitation(action) + is RoomListActions.FilterWith -> handleFilter(action) + is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead() + is RoomListActions.LeaveRoom -> handleLeaveRoom(action) + is RoomListActions.ChangeNotificationMode -> handleChangeNotificationMode(action) } } @@ -203,6 +205,17 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room ?.let { session.markAllAsRead(it, object : MatrixCallback {}) } } + private fun handleChangeNotificationMode(action: RoomListActions.ChangeNotificationMode) { + //TODO handle this + Timber.v("Not handled yet: $action") + } + + private fun handleLeaveRoom(action: RoomListActions.LeaveRoom) { + session.getRoom(action.roomId)?.also { + it.leave(object : MatrixCallback {}) + } + } + private fun buildRoomSummaries(rooms: List): RoomSummaries { val invites = ArrayList() val favourites = ArrayList() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt index c07d88f85a..30d4abff36 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt @@ -18,7 +18,27 @@ package im.vector.riotx.features.home.room.list.actions import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import im.vector.riotx.R sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { + data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions(R.string.room_settings_all_messages_noisy, R.drawable.ic_room_actions_notifications_all_noisy) + data class NotificationsAll(val roomId: String) : RoomListQuickActions(R.string.room_settings_all_messages, R.drawable.ic_room_actions_notifications_all) + data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActions(R.string.room_settings_mention_only, R.drawable.ic_room_actions_notifications_mentions) + data class NotificationsMute(val roomId: String) : RoomListQuickActions(R.string.room_settings_mute, R.drawable.ic_room_actions_notifications_mutes) + data class Settings(val roomId: String) : RoomListQuickActions(R.string.room_sliding_menu_settings, R.drawable.ic_room_actions_settings) + data class Leave(val roomId: String) : RoomListQuickActions(R.string.leave, R.drawable.ic_room_actions_leave) + + companion object { + fun all(roomId: String): List { + return listOf( + NotificationsAllNoisy(roomId), + NotificationsAll(roomId), + NotificationsMentionsOnly(roomId), + NotificationsMute(roomId), + Settings(roomId), + Leave(roomId) + ) + } + } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 19fe10de39..03e661eb20 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -21,6 +21,7 @@ import android.os.Parcelable import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import butterknife.BindView @@ -30,6 +31,7 @@ import com.airbnb.mvrx.withState import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.riotx.features.navigation.Navigator import kotlinx.android.parcel.Parcelize import javax.inject.Inject @@ -43,8 +45,10 @@ data class RoomListActionsArgs( */ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { + private lateinit var actionsDispatcher: RoomListQuickActionsStore @Inject lateinit var roomListActionsViewModelFactory: RoomListActionsViewModel.Factory @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController + @Inject lateinit var navigator: Navigator private val viewModel: RoomListActionsViewModel by fragmentViewModel(RoomListActionsViewModel::class) @@ -65,6 +69,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) + actionsDispatcher = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsStore::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = roomListActionsEpoxyController.adapter // Disable item animation @@ -79,7 +84,8 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R } override fun didSelectMenuAction(quickActions: RoomListQuickActions) { - vectorBaseActivity.notImplemented("RoomListQuickActions") + actionsDispatcher.post(quickActions) + dismiss() } companion object { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index f4cc774092..f2c71868df 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -18,10 +18,12 @@ package im.vector.riotx.features.home.room.list.actions import android.view.View import com.airbnb.epoxy.TypedEpoxyController import im.vector.riotx.EmojiCompatFontProvider +import im.vector.riotx.core.date.VectorDateFormatter +import im.vector.riotx.core.epoxy.bottomsheet.BottomSheetItemAction_ +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemRoomPreview +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemSeparator import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.AvatarRenderer -import im.vector.riotx.features.home.room.detail.timeline.action.bottomSheetItemAction -import im.vector.riotx.features.home.room.detail.timeline.action.bottomSheetItemSeparator import javax.inject.Inject /** @@ -29,26 +31,47 @@ import javax.inject.Inject */ class RoomListQuickActionsEpoxyController @Inject constructor(private val stringProvider: StringProvider, private val avatarRenderer: AvatarRenderer, + private val dateFormatter: VectorDateFormatter, private val fontProvider: EmojiCompatFontProvider) : TypedEpoxyController() { var listener: Listener? = null override fun buildModels(state: RoomListQuickActionsState) { + val roomSummary = state.roomSummary() ?: return - // Separator + // Preview + bottomSheetItemRoomPreview { + id("preview") + avatarRenderer(avatarRenderer) + roomName(roomSummary.displayName) + avatarUrl(roomSummary.avatarUrl) + roomId(roomSummary.roomId) + settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickActions.Settings(roomSummary.roomId)) }) + } + + // Notifications bottomSheetItemSeparator { - id("actions_separator") + id("notifications_separator") } + RoomListQuickActions.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0) + RoomListQuickActions.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1) + RoomListQuickActions.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2) + RoomListQuickActions.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3) - // Actions - state.quickActions()?.forEachIndexed { index, action -> - bottomSheetItemAction { - id("action_$index") - iconRes(action.iconResId) - textRes(action.titleRes) - listener(View.OnClickListener { listener?.didSelectMenuAction(action) }) - } + // Leave + bottomSheetItemSeparator { + id("leave_separator") } + RoomListQuickActions.Leave(roomSummary.roomId).toBottomSheetItem(5) + } + + private fun RoomListQuickActions.toBottomSheetItem(index: Int) { + return BottomSheetItemAction_() + .id("action_$index") + .iconRes(iconResId) + .textRes(titleRes) + .listener(View.OnClickListener { listener?.didSelectMenuAction(this) }) + .addTo(this@RoomListQuickActionsEpoxyController) } interface Listener { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt index adefe24341..b15b91e6c0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt @@ -23,8 +23,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary data class RoomListQuickActionsState( val roomId: String, - val quickActions: Async> = Uninitialized, - val timelineEvent: Async = Uninitialized + val roomSummary: Async = Uninitialized ) : MvRxState { constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt new file mode 100644 index 0000000000..ce0479ac92 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.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.home.room.list.actions + +import androidx.lifecycle.ViewModel +import im.vector.riotx.core.utils.PublishStore +import im.vector.riotx.core.utils.RxStore + +/** + * Activity shared view model to handle room list quick actions + */ +class RoomListQuickActionsStore constructor( + private val store: RxStore = PublishStore() +) : ViewModel(), RxStore by store 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 079c43041f..9569f2c434 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 @@ -19,18 +19,19 @@ import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import dagger.Lazy +import im.vector.matrix.android.api.MatrixCallback 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.VectorViewModel import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter import im.vector.riotx.features.html.EventHtmlRenderer +import timber.log.Timber class RoomListActionsViewModel @AssistedInject constructor(@Assisted initialState: RoomListQuickActionsState, - private val eventHtmlRenderer: Lazy, - private val session: Session, - private val noticeEventFormatter: NoticeEventFormatter, - private val stringProvider: StringProvider + session: Session ) : VectorViewModel(initialState) { @AssistedInject.Factory @@ -46,8 +47,20 @@ class RoomListActionsViewModel @AssistedInject constructor(@Assisted } } - init { + private val room = session.getRoom(initialState.roomId)!! + init { + observeRoomSummary() + } + + private fun observeRoomSummary() { + room + .rx() + .liveRoomSummary() + .unwrap() + .execute { + copy(roomSummary = it) + } } diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt index a3f9c009ed..f0958b5b35 100644 --- a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt @@ -112,4 +112,9 @@ class DefaultNavigator @Inject constructor() : Navigator { override fun openUserDetail(userId: String, context: Context) { Timber.v("Open user detail $userId") } + + override fun openRoomSettings(context: Context, roomId: String) { + Timber.v("Open room settings$roomId") + + } } diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt index 4112dbbfc8..8bd5f520c1 100644 --- a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt @@ -50,4 +50,7 @@ interface Navigator { fun openGroupDetail(groupId: String, context: Context) fun openUserDetail(userId: String, context: Context) + + fun openRoomSettings(context: Context, roomId: String) + } 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 955713c0f8..3545b1cb71 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 @@ -76,7 +76,7 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback .disposeOnDestroy() publicRoomsCreateNewRoom.setOnClickListener { - navigationViewModel.goTo(RoomDirectoryActivity.Navigation.CreateRoom) + navigationViewModel.post(RoomDirectoryActivity.Navigation.CreateRoom) } viewModel.joinRoomErrorLiveData.observeEvent(this) { throwable -> @@ -88,7 +88,7 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_room_directory_change_protocol -> { - navigationViewModel.goTo(RoomDirectoryActivity.Navigation.ChangeProtocol) + navigationViewModel.post(RoomDirectoryActivity.Navigation.ChangeProtocol) true } else -> 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 b2dd13e59a..e8914970ff 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 @@ -62,14 +62,16 @@ class RoomDirectoryActivity : VectorBaseActivity() { roomDirectoryViewModel.filterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "") } - navigationViewModel.navigateTo.observeEvent(this) { navigation -> - when (navigation) { - is Navigation.Back -> onBackPressed() - is Navigation.CreateRoom -> addFragmentToBackstack(CreateRoomFragment(), R.id.simpleFragmentContainer) - is Navigation.ChangeProtocol -> addFragmentToBackstack(RoomDirectoryPickerFragment(), R.id.simpleFragmentContainer) - is Navigation.Close -> finish() - } - } + navigationViewModel.observe() + .subscribe { navigation -> + when (navigation) { + is Navigation.Back -> onBackPressed() + is Navigation.CreateRoom -> addFragmentToBackstack(CreateRoomFragment(), R.id.simpleFragmentContainer) + is Navigation.ChangeProtocol -> addFragmentToBackstack(RoomDirectoryPickerFragment(), R.id.simpleFragmentContainer) + is Navigation.Close -> finish() + } + } + .disposeOnDestroy() roomDirectoryViewModel.selectSubscribe(this, PublicRoomsViewState::currentFilter) { currentFilter -> // Transmit the filter to the createRoomViewModel diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt index c87da6bd50..cb26ff0c54 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt @@ -16,7 +16,9 @@ package im.vector.riotx.features.roomdirectory -import im.vector.riotx.core.mvrx.NavigationViewModel -import javax.inject.Inject +import androidx.lifecycle.ViewModel +import im.vector.riotx.core.utils.PublishStore +import im.vector.riotx.core.utils.RxStore -class RoomDirectoryNavigationViewModel @Inject constructor(): NavigationViewModel() +class RoomDirectoryNavigationViewModel(private val store: RxStore = PublishStore()) + : ViewModel(), RxStore by store 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 9a3e903954..00bd42901a 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 @@ -63,12 +63,14 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryNavigationViewModel::class.java) - navigationViewModel.navigateTo.observeEvent(this) { navigation -> - when (navigation) { - is RoomDirectoryActivity.Navigation.Back, - is RoomDirectoryActivity.Navigation.Close -> finish() - } - } + navigationViewModel.observe() + .subscribe { navigation -> + when (navigation) { + is RoomDirectoryActivity.Navigation.Back, + is RoomDirectoryActivity.Navigation.Close -> finish() + } + } + .disposeOnDestroy() } companion object { 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 acea19b49a..8abf52328f 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 @@ -52,7 +52,7 @@ class CreateRoomFragment : VectorBaseFragment(), CreateRoomController.Listener { navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { - navigationViewModel.goTo(RoomDirectoryActivity.Navigation.Back) + navigationViewModel.post(RoomDirectoryActivity.Navigation.Back) } } @@ -99,7 +99,7 @@ class CreateRoomFragment : VectorBaseFragment(), CreateRoomController.Listener { // Navigate to freshly created room navigator.openRoom(requireActivity(), async()) - navigationViewModel.goTo(RoomDirectoryActivity.Navigation.Close) + navigationViewModel.post(RoomDirectoryActivity.Navigation.Close) } else { // Populate list with Epoxy createRoomController.setData(state) 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 f338c71bbf..2367bc8d21 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 @@ -94,7 +94,7 @@ class RoomDirectoryPickerFragment : VectorBaseFragment(), RoomDirectoryPickerCon Timber.v("onRoomDirectoryClicked: $roomDirectoryData") viewModel.setRoomDirectoryData(roomDirectoryData) - navigationViewModel.goTo(RoomDirectoryActivity.Navigation.Back) + navigationViewModel.post(RoomDirectoryActivity.Navigation.Back) } override fun retry() { diff --git a/vector/src/main/res/drawable/ic_room_actions_leave.xml b/vector/src/main/res/drawable/ic_room_actions_leave.xml new file mode 100644 index 0000000000..346defac7c --- /dev/null +++ b/vector/src/main/res/drawable/ic_room_actions_leave.xml @@ -0,0 +1,47 @@ + + + + + + + diff --git a/vector/src/main/res/drawable/ic_room_actions_notifications_all.xml b/vector/src/main/res/drawable/ic_room_actions_notifications_all.xml new file mode 100644 index 0000000000..5bf7226c59 --- /dev/null +++ b/vector/src/main/res/drawable/ic_room_actions_notifications_all.xml @@ -0,0 +1,39 @@ + + + + + + diff --git a/vector/src/main/res/drawable/ic_room_actions_notifications_all_noisy.xml b/vector/src/main/res/drawable/ic_room_actions_notifications_all_noisy.xml new file mode 100644 index 0000000000..0eec24a115 --- /dev/null +++ b/vector/src/main/res/drawable/ic_room_actions_notifications_all_noisy.xml @@ -0,0 +1,39 @@ + + + + + + diff --git a/vector/src/main/res/drawable/ic_room_actions_notifications_mentions.xml b/vector/src/main/res/drawable/ic_room_actions_notifications_mentions.xml new file mode 100644 index 0000000000..6bdf317097 --- /dev/null +++ b/vector/src/main/res/drawable/ic_room_actions_notifications_mentions.xml @@ -0,0 +1,47 @@ + + + + + + + diff --git a/vector/src/main/res/drawable/ic_room_actions_notifications_mutes.xml b/vector/src/main/res/drawable/ic_room_actions_notifications_mutes.xml new file mode 100644 index 0000000000..89bbc832cb --- /dev/null +++ b/vector/src/main/res/drawable/ic_room_actions_notifications_mutes.xml @@ -0,0 +1,47 @@ + + + + + + + diff --git a/vector/src/main/res/drawable/ic_room_actions_settings.xml b/vector/src/main/res/drawable/ic_room_actions_settings.xml new file mode 100644 index 0000000000..c80dfe0409 --- /dev/null +++ b/vector/src/main/res/drawable/ic_room_actions_settings.xml @@ -0,0 +1,39 @@ + + + + + + diff --git a/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml b/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml new file mode 100644 index 0000000000..410e6ea1ab --- /dev/null +++ b/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml @@ -0,0 +1,57 @@ + + + + + + + + + + diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 71fbc22acf..9b12db5e7f 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,6 +2,11 @@ - + "All messages (noisy)" + "All messages" + "Mentions only" + "Mute" + "Settings" + "Leave" From a04802b238035e8a393374bcf6a5fa3de9c3b0a6 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 25 Oct 2019 11:14:17 +0200 Subject: [PATCH 014/117] CI / upgrade queue to xlarge --- .buildkite/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index cf1cd5b9ff..e0d4d6ac49 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -10,7 +10,7 @@ steps: agents: # We use a medium sized instance instead of the normal small ones because # gradle build is long - queue: "medium" + queue: "xlarge" commands: - "./gradlew clean lintGplayRelease assembleGplayDebug --stacktrace" artifact_paths: @@ -25,7 +25,7 @@ steps: agents: # We use a medium sized instance instead of the normal small ones because # gradle build is long - queue: "medium" + queue: "xlarge" commands: - "./gradlew clean lintFdroidRelease assembleFdroidDebug --stacktrace" artifact_paths: @@ -40,7 +40,7 @@ steps: agents: # We use a medium sized instance instead of the normal small ones because # gradle build is long - queue: "medium" + queue: "xlarge" commands: - "./gradlew clean assembleGplayRelease --stacktrace" artifact_paths: From 00ca5dc70af2ef8c559b4c0f4ea4ea3b37e551ce Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 25 Oct 2019 18:23:47 +0200 Subject: [PATCH 015/117] RoomListActions: handle room notification state. Still need to branch UI --- .../main/java/im/vector/matrix/rx/RxRoom.kt | 5 + .../matrix/android/api/pushrules/Action.kt | 26 ++++- .../android/api/pushrules/PushRuleService.kt | 4 + .../matrix/android/api/session/room/Room.kt | 4 +- .../notification/RoomNotificationState.kt | 42 ++++++++ .../room/notification/RoomPushRuleService.kt | 29 +++++ .../internal/database/model/PushRuleEntity.kt | 5 + .../internal/database/query/PushersQueries.kt | 13 ++- .../notification/DefaultPushRuleService.kt | 20 ++++ .../session/pushers/AddPushRuleTask.kt | 39 +++++++ .../internal/session/pushers/PushersModule.kt | 11 ++ .../session/pushers/RemovePushRuleTask.kt | 39 +++++++ .../internal/session/room/DefaultRoom.kt | 7 +- .../internal/session/room/RoomFactory.kt | 8 +- .../DefaultRoomPushRuleService.kt | 73 +++++++++++++ .../session/room/notification/RoomPushRule.kt | 25 +++++ .../room/notification/RoomPushRuleMapper.kt | 102 ++++++++++++++++++ .../SetRoomNotificationStateTask.kt | 54 ++++++++++ .../home/room/list/RoomListActions.kt | 3 +- .../home/room/list/RoomListFragment.kt | 25 +++-- .../home/room/list/RoomListViewModel.kt | 23 ++-- .../list/actions/RoomListQuickActionsState.kt | 4 +- .../actions/RoomListQuickActionsViewModel.kt | 10 ++ 23 files changed, 544 insertions(+), 27 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomNotificationState.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddPushRuleTask.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/RemovePushRuleTask.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRule.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/SetRoomNotificationStateTask.kt diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt index e058b2716c..6793d6249d 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt @@ -20,6 +20,7 @@ import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState import im.vector.matrix.android.api.session.room.send.UserDraft import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.util.Optional @@ -67,6 +68,10 @@ class RxRoom(private val room: Room) { fun liveDrafts(): Observable> { return room.getDraftsLive().asObservable() } + + fun liveNotificationState(): Observable { + return room.getLiveRoomNotificationState().asObservable() + } } fun Room.rx(): RxRoom { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt index d135504055..d1e5b3c868 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt @@ -21,7 +21,7 @@ import timber.log.Timber sealed class Action { object Notify : Action() object DoNotNotify : Action() - data class Sound(val sound: String) : Action() + data class Sound(val sound: String = ACTION_OBJECT_VALUE_VALUE_DEFAULT) : Action() data class Highlight(val highlight: Boolean) : Action() } @@ -63,6 +63,30 @@ private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default" * * */ + +@Suppress("IMPLICIT_CAST_TO_ANY") +fun List.toJson(): List { + return map { action -> + when (action) { + is Action.Notify -> ACTION_NOTIFY + is Action.DoNotNotify -> ACTION_DONT_NOTIFY + is Action.Sound -> { + mapOf( + ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_SOUND, + ACTION_OBJECT_VALUE_KEY to action.sound + ) + } + is Action.Highlight -> { + mapOf( + ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT, + ACTION_OBJECT_VALUE_KEY to action.highlight + ) + } + } + } +} + + fun PushRule.getActions(): List { val result = ArrayList() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt index aa277ea8bd..0ef70eb99b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/PushRuleService.kt @@ -34,6 +34,10 @@ interface PushRuleService { fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback): Cancelable + fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback): Cancelable + + fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback): Cancelable + fun addPushRuleListener(listener: PushRuleListener) fun removePushRuleListener(listener: PushRuleListener) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt index 70c9c6e36c..90790a6ab0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt @@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.room.crypto.RoomCryptoService import im.vector.matrix.android.api.session.room.members.MembershipService import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.relation.RelationService +import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService import im.vector.matrix.android.api.session.room.reporting.ReportingService import im.vector.matrix.android.api.session.room.read.ReadService import im.vector.matrix.android.api.session.room.send.DraftService @@ -41,7 +42,8 @@ interface Room : StateService, ReportingService, RelationService, - RoomCryptoService { + RoomCryptoService, + RoomPushRuleService { /** * The roomId of this room diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomNotificationState.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomNotificationState.kt new file mode 100644 index 0000000000..a638b2710c --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomNotificationState.kt @@ -0,0 +1,42 @@ +/* + * 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.matrix.android.api.session.room.notification + +/** + * Defines the room notification state + */ +enum class RoomNotificationState { + /** + * All the messages will trigger a noisy notification + */ + ALL_MESSAGES_NOISY, + + /** + * All the messages will trigger a notification + */ + ALL_MESSAGES, + + /** + * Only the messages with user display name / user name will trigger notifications + */ + MENTIONS_ONLY, + + /** + * No notifications + */ + MUTE +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt new file mode 100644 index 0000000000..7b3e88240b --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt @@ -0,0 +1,29 @@ +/* + * 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.matrix.android.api.session.room.notification + +import androidx.lifecycle.LiveData +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.util.Cancelable + +interface RoomPushRuleService { + + fun getLiveRoomNotificationState(): LiveData + + fun setRoomNotificationState(roomNotificationState: RoomNotificationState, matrixCallback: MatrixCallback): Cancelable + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/PushRuleEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/PushRuleEntity.kt index 4744c8d053..1ef65d9dea 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/PushRuleEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/PushRuleEntity.kt @@ -17,6 +17,8 @@ package im.vector.matrix.android.internal.database.model import io.realm.RealmList import io.realm.RealmObject +import io.realm.RealmResults +import io.realm.annotations.LinkingObjects internal open class PushRuleEntity( // Required. The actions to perform when this rule is matched. @@ -33,5 +35,8 @@ internal open class PushRuleEntity( var pattern: String? = null ) : RealmObject() { + @LinkingObjects("pushRules") + val parent: RealmResults? = null + companion object } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt index 4ecb40a7e1..a97ed8d415 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt @@ -16,10 +16,10 @@ package im.vector.matrix.android.internal.database.query import im.vector.matrix.android.api.pushrules.RuleKind +import im.vector.matrix.android.internal.database.model.* +import im.vector.matrix.android.internal.database.model.PushRuleEntity import im.vector.matrix.android.internal.database.model.PushRulesEntity -import im.vector.matrix.android.internal.database.model.PushRulesEntityFields import im.vector.matrix.android.internal.database.model.PusherEntity -import im.vector.matrix.android.internal.database.model.PusherEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where @@ -41,3 +41,12 @@ internal fun PushRulesEntity.Companion.where(realm: Realm, .equalTo(PushRulesEntityFields.SCOPE, scope) .equalTo(PushRulesEntityFields.KIND_STR, kind.name) } + +internal fun PushRuleEntity.Companion.where(realm: Realm, + scope: String, + ruleId: String): RealmQuery { + return realm.where() + .equalTo("${PushRuleEntityFields.PARENT}.${PushRulesEntityFields.SCOPE}", scope) + .equalTo(PushRuleEntityFields.RULE_ID, ruleId) +} + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt index 82b928fc54..9121202649 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt @@ -28,7 +28,9 @@ import im.vector.matrix.android.internal.database.mapper.PushRulesMapper import im.vector.matrix.android.internal.database.model.PushRulesEntity import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.session.SessionScope +import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask +import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask import im.vector.matrix.android.internal.session.pushers.UpdatePushRuleEnableStatusTask import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith @@ -38,6 +40,8 @@ import javax.inject.Inject @SessionScope internal class DefaultPushRuleService @Inject constructor(private val getPushRulesTask: GetPushRulesTask, private val updatePushRuleEnableStatusTask: UpdatePushRuleEnableStatusTask, + private val addPushRuleTask: AddPushRuleTask, + private val removePushRuleTask: RemovePushRuleTask, private val taskExecutor: TaskExecutor, private val monarchy: Monarchy ) : PushRuleService { @@ -98,6 +102,22 @@ internal class DefaultPushRuleService @Inject constructor(private val getPushRul .executeBy(taskExecutor) } + override fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback): Cancelable { + return addPushRuleTask + .configureWith(AddPushRuleTask.Params(kind, pushRule)) { + this.callback = callback + } + .executeBy(taskExecutor) + } + + override fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback): Cancelable { + return removePushRuleTask + .configureWith(RemovePushRuleTask.Params(kind, pushRule)) { + this.callback = callback + } + .executeBy(taskExecutor) + } + override fun removePushRuleListener(listener: PushRuleService.PushRuleListener) { synchronized(listeners) { listeners.remove(listener) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddPushRuleTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddPushRuleTask.kt new file mode 100644 index 0000000000..99992ef4dc --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddPushRuleTask.kt @@ -0,0 +1,39 @@ +/* + * 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.matrix.android.internal.session.pushers + +import im.vector.matrix.android.api.pushrules.RuleKind +import im.vector.matrix.android.api.pushrules.rest.PushRule +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.task.Task +import javax.inject.Inject + +internal interface AddPushRuleTask : Task { + data class Params( + val kind: RuleKind, + val pushRule: PushRule + ) +} + +internal class DefaultAddPushRuleTask @Inject constructor(private val pushRulesApi: PushRulesApi) + : AddPushRuleTask { + + override suspend fun execute(params: AddPushRuleTask.Params) { + return executeRequest { + apiCall = pushRulesApi.addRule(params.kind.value, params.pushRule.ruleId, params.pushRule) + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/PushersModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/PushersModule.kt index 7aa06c0275..1564363e1b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/PushersModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/PushersModule.kt @@ -25,6 +25,8 @@ import im.vector.matrix.android.api.session.pushers.PushersService import im.vector.matrix.android.internal.session.notification.DefaultProcessEventForPushTask import im.vector.matrix.android.internal.session.notification.DefaultPushRuleService import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask +import im.vector.matrix.android.internal.session.room.notification.DefaultSetRoomNotificationStateTask +import im.vector.matrix.android.internal.session.room.notification.SetRoomNotificationStateTask import retrofit2.Retrofit @Module @@ -67,6 +69,15 @@ internal abstract class PushersModule { @Binds abstract fun bindUpdatePushRuleEnableStatusTask(updatePushRuleEnableStatusTask: DefaultUpdatePushRuleEnableStatusTask): UpdatePushRuleEnableStatusTask + @Binds + abstract fun bindAddPushRuleTask(addPushRuleTask: DefaultAddPushRuleTask): AddPushRuleTask + + @Binds + abstract fun bindRemovePushRuleTask(removePushRuleTask: DefaultRemovePushRuleTask): RemovePushRuleTask + + @Binds + abstract fun bindSetRoomNotificationStateTask(setRoomNotificationStateTask: DefaultSetRoomNotificationStateTask): SetRoomNotificationStateTask + @Binds abstract fun bindPushRuleService(pushRuleService: DefaultPushRuleService): PushRuleService diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/RemovePushRuleTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/RemovePushRuleTask.kt new file mode 100644 index 0000000000..c4938fa0cc --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/RemovePushRuleTask.kt @@ -0,0 +1,39 @@ +/* + * 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.matrix.android.internal.session.pushers + +import im.vector.matrix.android.api.pushrules.RuleKind +import im.vector.matrix.android.api.pushrules.rest.PushRule +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.task.Task +import javax.inject.Inject + +internal interface RemovePushRuleTask : Task { + data class Params( + val kind: RuleKind, + val pushRule: PushRule + ) +} + +internal class DefaultRemovePushRuleTask @Inject constructor(private val pushRulesApi: PushRulesApi) + : RemovePushRuleTask { + + override suspend fun execute(params: RemovePushRuleTask.Params) { + return executeRequest { + apiCall = pushRulesApi.deleteRule(params.kind.value, params.pushRule.ruleId) + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index fea827fd25..cca20fc5fc 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt @@ -24,6 +24,7 @@ import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.members.MembershipService import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.relation.RelationService +import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService import im.vector.matrix.android.api.session.room.reporting.ReportingService import im.vector.matrix.android.api.session.room.read.ReadService import im.vector.matrix.android.api.session.room.send.DraftService @@ -49,7 +50,8 @@ internal class DefaultRoom @Inject constructor(override val roomId: String, private val readService: ReadService, private val cryptoService: CryptoService, private val relationService: RelationService, - private val roomMembersService: MembershipService) : + private val roomMembersService: MembershipService, + private val roomPushRuleService: RoomPushRuleService) : Room, TimelineService by timelineService, SendService by sendService, @@ -58,7 +60,8 @@ internal class DefaultRoom @Inject constructor(override val roomId: String, ReportingService by reportingService, ReadService by readService, RelationService by relationService, - MembershipService by roomMembersService { + MembershipService by roomMembersService, + RoomPushRuleService by roomPushRuleService { override fun getRoomSummaryLive(): LiveData> { val liveData = monarchy.findAllMappedWithChanges( diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt index e2199782f4..2c441762dd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt @@ -19,9 +19,11 @@ package im.vector.matrix.android.internal.session.room import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.room.Room +import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper import im.vector.matrix.android.internal.session.room.draft.DefaultDraftService import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService +import im.vector.matrix.android.internal.session.room.notification.DefaultRoomPushRuleService import im.vector.matrix.android.internal.session.room.read.DefaultReadService import im.vector.matrix.android.internal.session.room.relation.DefaultRelationService import im.vector.matrix.android.internal.session.room.reporting.DefaultReportingService @@ -44,7 +46,8 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona private val reportingServiceFactory: DefaultReportingService.Factory, private val readServiceFactory: DefaultReadService.Factory, private val relationServiceFactory: DefaultRelationService.Factory, - private val membershipServiceFactory: DefaultMembershipService.Factory) : + private val membershipServiceFactory: DefaultMembershipService.Factory, + private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory) : RoomFactory { override fun create(roomId: String): Room { @@ -60,7 +63,8 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona readServiceFactory.create(roomId), cryptoService, relationServiceFactory.create(roomId), - membershipServiceFactory.create(roomId) + membershipServiceFactory.create(roomId), + roomPushRuleServiceFactory.create(roomId) ) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt new file mode 100644 index 0000000000..a27cdb1007 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt @@ -0,0 +1,73 @@ +/* + * 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.matrix.android.internal.session.room.notification + +import androidx.lifecycle.LiveData +import androidx.lifecycle.Transformations +import com.squareup.inject.assisted.Assisted +import com.squareup.inject.assisted.AssistedInject +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.pushrules.RuleScope +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState +import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService +import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.internal.database.model.PushRuleEntity +import im.vector.matrix.android.internal.database.query.where +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith + +internal class DefaultRoomPushRuleService @AssistedInject constructor(@Assisted private val roomId: String, + private val setRoomNotificationStateTask: SetRoomNotificationStateTask, + private val monarchy: Monarchy, + private val taskExecutor: TaskExecutor) + : RoomPushRuleService { + + @AssistedInject.Factory + interface Factory { + fun create(roomId: String): RoomPushRuleService + } + + override fun getLiveRoomNotificationState(): LiveData { + return Transformations.map(getPushRuleForRoom()) { + it?.toRoomNotificationState() ?: RoomNotificationState.ALL_MESSAGES + } + } + + override fun setRoomNotificationState(roomNotificationState: RoomNotificationState, matrixCallback: MatrixCallback): Cancelable { + return setRoomNotificationStateTask + .configureWith(SetRoomNotificationStateTask.Params(roomId, roomNotificationState)) { + this.callback = callback + } + .executeBy(taskExecutor) + } + + private fun getPushRuleForRoom(): LiveData { + val liveData = monarchy.findAllMappedWithChanges( + { realm -> + PushRuleEntity.where(realm, scope = RuleScope.GLOBAL, ruleId = roomId) + }, + { result -> + result.toRoomPushRule() + } + ) + return Transformations.map(liveData) { results -> + results.firstOrNull() + } + } + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRule.kt new file mode 100644 index 0000000000..b07f94f0f3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRule.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.matrix.android.internal.session.room.notification + +import im.vector.matrix.android.api.pushrules.RuleKind +import im.vector.matrix.android.api.pushrules.rest.PushRule + +internal data class RoomPushRule( + val kind: RuleKind, + val rule: PushRule +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt new file mode 100644 index 0000000000..159eb511ee --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt @@ -0,0 +1,102 @@ +/* + * 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.matrix.android.internal.session.room.notification + +import im.vector.matrix.android.api.pushrules.* +import im.vector.matrix.android.api.pushrules.rest.PushCondition +import im.vector.matrix.android.api.pushrules.rest.PushRule +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState +import im.vector.matrix.android.internal.database.mapper.PushRulesMapper +import im.vector.matrix.android.internal.database.model.PushRuleEntity + +internal fun PushRuleEntity.toRoomPushRule(): RoomPushRule? { + val kind = parent?.firstOrNull()?.kind + val pushRule = when (kind) { + RuleSetKey.OVERRIDE -> { + PushRulesMapper.map(this) + } + RuleSetKey.ROOM -> { + PushRulesMapper.mapRoomRule(this) + } + else -> null + } + return if (pushRule == null || kind == null) { + null + } else { + RoomPushRule(kind, pushRule) + } +} + +internal fun RoomNotificationState.toRoomPushRule(roomId: String): RoomPushRule? { + return when { + this == RoomNotificationState.ALL_MESSAGES -> null + this == RoomNotificationState.ALL_MESSAGES_NOISY -> { + val rule = PushRule( + actions = listOf(Action.Notify, Action.Sound()).toJson(), + enabled = true, + ruleId = roomId + ) + return RoomPushRule(RuleSetKey.ROOM, rule) + } + else -> { + val condition = PushCondition( + kind = Condition.Kind.event_match.value, + key = "room_id", + pattern = roomId + ) + val rule = PushRule( + actions = listOf(Action.DoNotNotify).toJson(), + enabled = true, + ruleId = roomId, + conditions = listOf(condition) + ) + val kind = if (this == RoomNotificationState.MUTE) { + RuleSetKey.OVERRIDE + } else { + RuleSetKey.ROOM + } + return RoomPushRule(kind, rule) + } + } +} + +internal fun RoomPushRule.toRoomNotificationState(): RoomNotificationState { + return if (rule.enabled) { + val actions = rule.getActions() + if (actions.contains(Action.DoNotNotify)) { + if (kind == RuleSetKey.OVERRIDE) { + RoomNotificationState.MUTE + } else { + RoomNotificationState.MENTIONS_ONLY + } + } else if (actions.contains(Action.Notify)) { + val hasSoundAction = actions.find { + it is Action.Sound + } != null + if (hasSoundAction) { + RoomNotificationState.ALL_MESSAGES_NOISY + } else { + RoomNotificationState.ALL_MESSAGES + } + } else { + RoomNotificationState.ALL_MESSAGES + } + } else { + RoomNotificationState.ALL_MESSAGES + } +} + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/SetRoomNotificationStateTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/SetRoomNotificationStateTask.kt new file mode 100644 index 0000000000..0362a6607f --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/SetRoomNotificationStateTask.kt @@ -0,0 +1,54 @@ +/* + * 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.matrix.android.internal.session.room.notification + +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.pushrules.RuleScope +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState +import im.vector.matrix.android.internal.database.model.PushRuleEntity +import im.vector.matrix.android.internal.database.query.where +import im.vector.matrix.android.internal.session.pushers.AddPushRuleTask +import im.vector.matrix.android.internal.session.pushers.RemovePushRuleTask +import im.vector.matrix.android.internal.task.Task +import io.realm.Realm +import javax.inject.Inject + +internal interface SetRoomNotificationStateTask : Task { + data class Params( + val roomId: String, + val roomNotificationState: RoomNotificationState + ) +} + +internal class DefaultSetRoomNotificationStateTask @Inject constructor(private val monarchy: Monarchy, + private val removePushRuleTask: RemovePushRuleTask, + private val addPushRuleTask: AddPushRuleTask) + : SetRoomNotificationStateTask { + + override suspend fun execute(params: SetRoomNotificationStateTask.Params) { + val currentRoomPushRule = Realm.getInstance(monarchy.realmConfiguration).use { + PushRuleEntity.where(it, scope = RuleScope.GLOBAL, ruleId = params.roomId).findFirst()?.toRoomPushRule() + } + if (currentRoomPushRule != null) { + removePushRuleTask.execute(RemovePushRuleTask.Params(currentRoomPushRule.kind, currentRoomPushRule.rule)) + } + val newRoomPushRule = params.roomNotificationState.toRoomPushRule(params.roomId) + if (newRoomPushRule != null) { + addPushRuleTask.execute(AddPushRuleTask.Params(newRoomPushRule.kind, newRoomPushRule.rule)) + } + } +} 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 81b26a99d4..7fce5bf99f 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 @@ -17,6 +17,7 @@ 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 sealed class RoomListActions { data class SelectRoom(val roomSummary: RoomSummary) : RoomListActions() @@ -24,7 +25,7 @@ sealed class RoomListActions { data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListActions() data class RejectInvitation(val roomSummary: RoomSummary) : RoomListActions() data class FilterWith(val filter: String) : RoomListActions() - data class ChangeNotificationMode(val notificationMode: String) : RoomListActions() + data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : RoomListActions() data class LeaveRoom(val roomId: String) : RoomListActions() object MarkAllRoomsRead : 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 22415fd792..3eb9f99f75 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 @@ -31,6 +31,7 @@ import com.google.android.material.snackbar.Snackbar import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer @@ -216,12 +217,24 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O private fun handleQuickActions(quickActions: RoomListQuickActions) { when (quickActions) { - is RoomListQuickActions.NotificationsAllNoisy -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) - is RoomListQuickActions.NotificationsAll -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) - is RoomListQuickActions.NotificationsMentionsOnly -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) - is RoomListQuickActions.NotificationsMute -> roomListViewModel.accept(RoomListActions.ChangeNotificationMode("")) - is RoomListQuickActions.Settings -> navigator.openRoomSettings(requireContext(), quickActions.roomId) - is RoomListQuickActions.Leave -> roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) + is RoomListQuickActions.NotificationsAllNoisy -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) + } + is RoomListQuickActions.NotificationsAll -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.ALL_MESSAGES)) + } + is RoomListQuickActions.NotificationsMentionsOnly -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MENTIONS_ONLY)) + } + is RoomListQuickActions.NotificationsMute -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MUTE)) + } + is RoomListQuickActions.Settings -> { + navigator.openRoomSettings(requireContext(), quickActions.roomId) + } + is RoomListQuickActions.Leave -> { + roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) + } } } 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 c6010f89f0..32061b9cbf 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 @@ -73,14 +73,14 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room fun accept(action: RoomListActions) { when (action) { - is RoomListActions.SelectRoom -> handleSelectRoom(action) - is RoomListActions.ToggleCategory -> handleToggleCategory(action) - is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action) - is RoomListActions.RejectInvitation -> handleRejectInvitation(action) - is RoomListActions.FilterWith -> handleFilter(action) - is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead() - is RoomListActions.LeaveRoom -> handleLeaveRoom(action) - is RoomListActions.ChangeNotificationMode -> handleChangeNotificationMode(action) + is RoomListActions.SelectRoom -> handleSelectRoom(action) + is RoomListActions.ToggleCategory -> handleToggleCategory(action) + is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action) + is RoomListActions.RejectInvitation -> handleRejectInvitation(action) + is RoomListActions.FilterWith -> handleFilter(action) + is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead() + is RoomListActions.LeaveRoom -> handleLeaveRoom(action) + is RoomListActions.ChangeRoomNotificationState -> handleChangeNotificationMode(action) } } @@ -205,9 +205,10 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room ?.let { session.markAllAsRead(it, object : MatrixCallback {}) } } - private fun handleChangeNotificationMode(action: RoomListActions.ChangeNotificationMode) { - //TODO handle this - Timber.v("Not handled yet: $action") + private fun handleChangeNotificationMode(action: RoomListActions.ChangeRoomNotificationState) { + session.getRoom(action.roomId)?.also { + it.setRoomNotificationState(action.notificationState, object : MatrixCallback {}) + } } private fun handleLeaveRoom(action: RoomListActions.LeaveRoom) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt index b15b91e6c0..e8e40c30e2 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt @@ -20,10 +20,12 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.Uninitialized import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState data class RoomListQuickActionsState( val roomId: String, - val roomSummary: Async = Uninitialized + val roomSummary: Async = Uninitialized, + val roomNotificationState: Async = Uninitialized ) : MvRxState { constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) 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 9569f2c434..422a1097f2 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 @@ -51,6 +51,16 @@ class RoomListActionsViewModel @AssistedInject constructor(@Assisted init { observeRoomSummary() + observeNotificationState() + } + + private fun observeNotificationState() { + room + .rx() + .liveNotificationState() + .execute { + copy(roomNotificationState = it) + } } private fun observeRoomSummary() { From 199456487c3050d7cc57d9032d4e8ec609a9c274 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 28 Oct 2019 14:36:15 +0100 Subject: [PATCH 016/117] Search reaction by name/keywords --- CHANGES.md | 2 +- .../vector/riotx/core/di/ScreenComponent.kt | 3 + .../reactions/EmojiChooserFragment.kt | 3 +- .../reactions/EmojiChooserViewModel.kt | 2 +- .../reactions/EmojiReactionPickerActivity.kt | 64 +++++++++++++-- .../reactions/EmojiSearchResultController.kt | 77 +++++++++++++++++++ .../reactions/EmojiSearchResultFragment.kt | 69 +++++++++++++++++ .../reactions/EmojiSearchResultItem.kt | 60 +++++++++++++++ .../reactions/EmojiSearchResultViewModel.kt | 54 +++++++++++++ .../layout/activity_emoji_reaction_picker.xml | 8 ++ .../src/main/res/layout/item_emoji_result.xml | 51 ++++++++++++ .../res/menu/menu_emoji_reaction_picker.xml | 1 + vector/src/main/res/values/strings.xml | 1 + 13 files changed, 385 insertions(+), 10 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultViewModel.kt create mode 100644 vector/src/main/res/layout/item_emoji_result.xml diff --git a/CHANGES.md b/CHANGES.md index b05300f94b..da1c26e425 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Improvements 🙌: - - + - Search reaction by name or keyword in emoji picker Other changes: - diff --git a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt index 0efbc0e173..79e496c141 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt @@ -59,6 +59,7 @@ import im.vector.riotx.features.rageshake.BugReportActivity import im.vector.riotx.features.rageshake.BugReporter import im.vector.riotx.features.rageshake.RageShake import im.vector.riotx.features.reactions.EmojiReactionPickerActivity +import im.vector.riotx.features.reactions.EmojiSearchResultFragment import im.vector.riotx.features.reactions.widget.ReactionButton import im.vector.riotx.features.roomdirectory.PublicRoomsFragment import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity @@ -197,6 +198,8 @@ interface ScreenComponent { fun inject(incomingShareActivity: IncomingShareActivity) + fun inject(emojiSearchResultFragment: EmojiSearchResultFragment) + @Component.Factory interface Factory { fun create(vectorComponent: VectorComponent, diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index 8aec8231db..36b1a52b27 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -36,12 +36,11 @@ class EmojiChooserFragment : VectorBaseFragment() { viewModel = activity?.run { ViewModelProviders.of(this, viewModelFactory).get(EmojiChooserViewModel::class.java) } ?: throw Exception("Invalid Activity") - viewModel.initWithContect(context!!) + viewModel.initWithContext(context!!) (view as? RecyclerView)?.let { it.adapter = viewModel.adapter it.adapter?.notifyDataSetChanged() } -// val ds = EmojiDataSource(this.context!!) } } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserViewModel.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserViewModel.kt index 16aecd0906..bbde2ac54c 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserViewModel.kt @@ -39,7 +39,7 @@ class EmojiChooserViewModel @Inject constructor() : ViewModel() { } } - fun initWithContect(context: Context) { + fun initWithContext(context: Context) { // TODO load async val emojiDataSource = EmojiDataSource(context) emojiSourceLiveData.value = emojiDataSource 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 0a4e05a4c8..7de38602cb 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 @@ -25,15 +25,22 @@ import android.view.MenuInflater import android.view.MenuItem import android.widget.SearchView import androidx.appcompat.widget.Toolbar +import androidx.core.view.isInvisible +import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders +import com.airbnb.mvrx.viewModel import com.google.android.material.tabs.TabLayout import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.VectorBaseActivity +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.android.synthetic.main.activity_emoji_reaction_picker.* +import timber.log.Timber +import java.util.concurrent.TimeUnit import javax.inject.Inject /** @@ -41,9 +48,9 @@ import javax.inject.Inject * TODO: Loading indicator while getting emoji data source? * TODO: migrate to MvRx * TODO: Finish Refactor to vector base activity - * TODO: Move font request to app */ -class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvider.FontProviderListener { +class EmojiReactionPickerActivity : VectorBaseActivity(), + EmojiCompatFontProvider.FontProviderListener { private lateinit var tabLayout: TabLayout @@ -57,6 +64,8 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide @Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider + val searchResultViewModel: EmojiSearchResultViewModel by viewModel() + private var tabLayoutSelectionListener = object : TabLayout.OnTabSelectedListener { override fun onTabReselected(tab: TabLayout.Tab) { } @@ -121,10 +130,15 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide finish() } } + + supportFragmentManager.findFragmentById(R.id.fragment)?.view?.isVisible = true + supportFragmentManager.findFragmentById(R.id.searchFragment)?.view?.isInvisible = true + tabLayout.isVisible = true } override fun compatibilityFontUpdate(typeface: Typeface?) { EmojiDrawView.configureTextPaint(this, typeface) + searchResultViewModel.dataSource } override fun onDestroy() { @@ -137,11 +151,11 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide inflater.inflate(getMenuRes(), menu) val searchItem = menu.findItem(R.id.search) - (searchItem.actionView as? SearchView)?.let { + (searchItem.actionView as? SearchView)?.let { searchView -> searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { override fun onMenuItemActionExpand(p0: MenuItem?): Boolean { - it.isIconified = false - it.requestFocusFromTouch() + searchView.isIconified = false + searchView.requestFocusFromTouch() // we want to force the tool bar as visible even if hidden with scroll flags findViewById(R.id.toolbar)?.minimumHeight = getActionBarSize() return true @@ -150,10 +164,35 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide override fun onMenuItemActionCollapse(p0: MenuItem?): Boolean { // when back, clear all search findViewById(R.id.toolbar)?.minimumHeight = 0 - it.setQuery("", true) + searchView.setQuery("", true) return true } }) + + val searchObservable = Observable.create { emitter -> + + searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + override fun onQueryTextSubmit(query: String?): Boolean { + query?.let { emitter.onNext(it) } + return true + } + + override fun onQueryTextChange(newText: String?): Boolean { + Timber.d("onQueryTextChange $newText") + newText?.let { emitter.onNext(it) } + return true + } + + }) + } + + searchObservable + .throttleWithTimeout(600, TimeUnit.MILLISECONDS) + .doOnError { err -> Timber.e(err) } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { query -> + onQueryText(query) + } } return true @@ -171,6 +210,19 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvide } } + private fun onQueryText(query: String) { + if (query.isEmpty()) { + supportFragmentManager.findFragmentById(R.id.fragment)?.view?.isVisible = true + supportFragmentManager.findFragmentById(R.id.searchFragment)?.view?.isInvisible = true + tabLayout.isVisible = true + } else { + tabLayout.isVisible = false + supportFragmentManager.findFragmentById(R.id.fragment)?.view?.isInvisible = true + supportFragmentManager.findFragmentById(R.id.searchFragment)?.view?.isVisible = true + searchResultViewModel.updateQuery(query) + } + } + companion object { const val EXTRA_EVENT_ID = "EXTRA_EVENT_ID" diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt new file mode 100644 index 0000000000..41bcfe7be5 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt @@ -0,0 +1,77 @@ +/* + * 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 android.graphics.Typeface +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.riotx.EmojiCompatFontProvider +import im.vector.riotx.R +import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.core.ui.list.genericFooterItem +import javax.inject.Inject + + +class EmojiSearchResultController @Inject constructor(val stringProvider: StringProvider, + fontProvider: EmojiCompatFontProvider) + : TypedEpoxyController() { + + + var emojiTypeface: Typeface? = fontProvider.typeface + + init { + fontProvider.addListener(object : EmojiCompatFontProvider.FontProviderListener { + override fun compatibilityFontUpdate(typeface: Typeface?) { + emojiTypeface = typeface + } + }) + } + + + var listener: ReactionClickListener? = null + + override fun buildModels(data: EmojiSearchResultViewState?) { + val results = data?.results ?: return + + if (results.isEmpty()) { + if (data.query.isEmpty()) { + //display 'Type something to find' + genericFooterItem { + id("type.query.item") + text(stringProvider.getString(R.string.reaction_search_type_hint)) + } + } else { + //Display no search Results + genericFooterItem { + id("no.results.item") + text(stringProvider.getString(R.string.no_result_placeholder)) + } + } + } else { + //Build the search results + results.forEach { + emojiSearchResultItem { + id(it.name) + emojiItem(it) + emojiTypeFace(emojiTypeface) + currentQuery(data.query) + onClickListener(listener) + } + } + + } + } + +} diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt new file mode 100644 index 0000000000..a4f443de1e --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt @@ -0,0 +1,69 @@ +/* + * 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 android.os.Bundle +import androidx.lifecycle.ViewModelProviders +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.airbnb.epoxy.EpoxyRecyclerView +import com.airbnb.mvrx.activityViewModel +import com.airbnb.mvrx.withState +import im.vector.riotx.R +import im.vector.riotx.core.di.ScreenComponent +import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.core.utils.LiveEvent +import javax.inject.Inject + +class EmojiSearchResultFragment : VectorBaseFragment() { + + override fun getLayoutResId(): Int = R.layout.fragment_generic_recycler_epoxy + + val viewModel: EmojiSearchResultViewModel by activityViewModel() + + var sharedViewModel: EmojiChooserViewModel? = null + + @Inject lateinit var epoxyController: EmojiSearchResultController + + override fun injectWith(injector: ScreenComponent) { + injector.inject(this) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + + sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(EmojiChooserViewModel::class.java) + + epoxyController.listener = object : ReactionClickListener { + override fun onReactionSelected(reaction: String) { + sharedViewModel?.selectedReaction = reaction + sharedViewModel?.navigateEvent?.value = LiveEvent(EmojiChooserViewModel.NAVIGATE_FINISH) + } + } + + val lmgr = LinearLayoutManager(context, RecyclerView.VERTICAL, false) + val epoxyRecyclerView = view as? EpoxyRecyclerView ?: return + epoxyRecyclerView.layoutManager = lmgr + val dividerItemDecoration = DividerItemDecoration(epoxyRecyclerView.context, lmgr.orientation) + epoxyRecyclerView.addItemDecoration(dividerItemDecoration) + epoxyRecyclerView.setController(epoxyController) + } + + override fun invalidate() = withState(viewModel) { state -> + epoxyController.setData(state) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt new file mode 100644 index 0000000000..4a9380d452 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt @@ -0,0 +1,60 @@ +/* + * 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 android.graphics.Typeface +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.airbnb.epoxy.EpoxyModelWithHolder +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.VectorEpoxyHolder + + +@EpoxyModelClass(layout = R.layout.item_emoji_result) +abstract class EmojiSearchResultItem : EpoxyModelWithHolder() { + + @EpoxyAttribute + lateinit var emojiItem: EmojiDataSource.EmojiItem + + @EpoxyAttribute + var currentQuery: String? = null + + @EpoxyAttribute + var onClickListener: ReactionClickListener? = null + + @EpoxyAttribute + var emojiTypeFace: Typeface? = null + + override fun bind(holder: Holder) { + super.bind(holder) + //TODO use query string to highlight the matched query in name and keywords? + holder.emojiText.text = emojiItem.emojiString() + holder.emojiText.typeface = emojiTypeFace ?: Typeface.DEFAULT + holder.emojiNameText.text = emojiItem.name + holder.emojiKeywordText.text = emojiItem.keywords?.joinToString(", ") + holder.view.setOnClickListener { + onClickListener?.onReactionSelected(emojiItem.emojiString()) + } + } + + class Holder : VectorEpoxyHolder() { + val emojiText by bind(R.id.item_emoji_tv) + val emojiNameText by bind(R.id.item_emoji_name) + val emojiKeywordText by bind(R.id.item_emoji_keyword) + } +} + 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 new file mode 100644 index 0000000000..e0c9453e4c --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultViewModel.kt @@ -0,0 +1,54 @@ +/* + * 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 com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.ViewModelContext +import im.vector.riotx.core.platform.VectorViewModel + +data class EmojiSearchResultViewState( + val query: String = "", + val results: List = emptyList() +) : MvRxState + +class EmojiSearchResultViewModel(val dataSource: EmojiDataSource, initialState: EmojiSearchResultViewState) + : VectorViewModel(initialState) { + + fun updateQuery(queryString: String) { + setState { + copy( + query = queryString, + results = dataSource.rawData?.emojis?.toList() + ?.map { it.second } + ?.filter { + it.name.contains(queryString, true) + || queryString.split("\\s".toRegex()).fold(true, { prev, q -> + prev && (it.keywords?.any { it.contains(q, true) } ?: false) + }) + } ?: emptyList() + ) + } + } + + companion object : MvRxViewModelFactory { + + override fun create(viewModelContext: ViewModelContext, state: EmojiSearchResultViewState): EmojiSearchResultViewModel? { + //TODO get the data source from activity? share it with other fragment + return EmojiSearchResultViewModel(EmojiDataSource(viewModelContext.activity), state) + } + } +} diff --git a/vector/src/main/res/layout/activity_emoji_reaction_picker.xml b/vector/src/main/res/layout/activity_emoji_reaction_picker.xml index ccaf149732..d56198d341 100644 --- a/vector/src/main/res/layout/activity_emoji_reaction_picker.xml +++ b/vector/src/main/res/layout/activity_emoji_reaction_picker.xml @@ -14,6 +14,14 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:layout="@layout/emoji_chooser_fragment" /> + + + + + + + + + + + + + + + + diff --git a/vector/src/main/res/menu/menu_emoji_reaction_picker.xml b/vector/src/main/res/menu/menu_emoji_reaction_picker.xml index 98242f57bb..87135d64ea 100644 --- a/vector/src/main/res/menu/menu_emoji_reaction_picker.xml +++ b/vector/src/main/res/menu/menu_emoji_reaction_picker.xml @@ -4,6 +4,7 @@ diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 83ce65783f..eb1eaf1368 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1528,6 +1528,7 @@ Why choose Riot.im? Add Reaction View Reactions Reactions + Type keywords to find a reaction. Event deleted by user Event moderated by room admin From de4c389c76dd4cf928bf04dbb67ee00ba235a5a1 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 28 Oct 2019 15:12:49 +0100 Subject: [PATCH 017/117] klint cleaning --- .../riotx/features/reactions/EmojiChooserFragment.kt | 1 - .../features/reactions/EmojiReactionPickerActivity.kt | 1 - .../features/reactions/EmojiSearchResultController.kt | 11 +++-------- .../riotx/features/reactions/EmojiSearchResultItem.kt | 4 +--- .../features/reactions/EmojiSearchResultViewModel.kt | 2 +- 5 files changed, 5 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index 36b1a52b27..77cad5643f 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -41,6 +41,5 @@ class EmojiChooserFragment : VectorBaseFragment() { it.adapter = viewModel.adapter it.adapter?.notifyDataSetChanged() } - } } 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 7de38602cb..a0acd7b5e8 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 @@ -182,7 +182,6 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), newText?.let { emitter.onNext(it) } return true } - }) } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt index 41bcfe7be5..82f8cdf3be 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt @@ -23,12 +23,10 @@ import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.core.ui.list.genericFooterItem import javax.inject.Inject - class EmojiSearchResultController @Inject constructor(val stringProvider: StringProvider, fontProvider: EmojiCompatFontProvider) : TypedEpoxyController() { - var emojiTypeface: Typeface? = fontProvider.typeface init { @@ -39,7 +37,6 @@ class EmojiSearchResultController @Inject constructor(val stringProvider: String }) } - var listener: ReactionClickListener? = null override fun buildModels(data: EmojiSearchResultViewState?) { @@ -47,20 +44,20 @@ class EmojiSearchResultController @Inject constructor(val stringProvider: String if (results.isEmpty()) { if (data.query.isEmpty()) { - //display 'Type something to find' + // display 'Type something to find' genericFooterItem { id("type.query.item") text(stringProvider.getString(R.string.reaction_search_type_hint)) } } else { - //Display no search Results + // Display no search Results genericFooterItem { id("no.results.item") text(stringProvider.getString(R.string.no_result_placeholder)) } } } else { - //Build the search results + // Build the search results results.forEach { emojiSearchResultItem { id(it.name) @@ -70,8 +67,6 @@ class EmojiSearchResultController @Inject constructor(val stringProvider: String onClickListener(listener) } } - } } - } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt index 4a9380d452..1b117035d9 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultItem.kt @@ -23,7 +23,6 @@ import com.airbnb.epoxy.EpoxyModelWithHolder import im.vector.riotx.R import im.vector.riotx.core.epoxy.VectorEpoxyHolder - @EpoxyModelClass(layout = R.layout.item_emoji_result) abstract class EmojiSearchResultItem : EpoxyModelWithHolder() { @@ -41,7 +40,7 @@ abstract class EmojiSearchResultItem : EpoxyModelWithHolder(R.id.item_emoji_keyword) } } - 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 e0c9453e4c..d11c25a1e3 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 @@ -47,7 +47,7 @@ class EmojiSearchResultViewModel(val dataSource: EmojiDataSource, initialState: companion object : MvRxViewModelFactory { override fun create(viewModelContext: ViewModelContext, state: EmojiSearchResultViewState): EmojiSearchResultViewModel? { - //TODO get the data source from activity? share it with other fragment + // TODO get the data source from activity? share it with other fragment return EmojiSearchResultViewModel(EmojiDataSource(viewModelContext.activity), state) } } From 57b640622bf43765ef26e06e7387e32a1c252008 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 28 Oct 2019 16:48:55 +0100 Subject: [PATCH 018/117] Sender Name: we should use disambiguated display name over senderName. PrevContent fallback is now handled in SDK --- .../session/room/timeline/TimelineEvent.kt | 12 +++++--- .../helper/TimelineEventEntityHelper.kt | 28 ++++++++++++++++--- .../room/send/LocalEchoEventFactory.kt | 2 +- .../home/room/detail/RoomDetailFragment.kt | 2 +- .../timeline/factory/EncryptionItemFactory.kt | 8 ++---- .../factory/MergedHeaderItemFactory.kt | 6 ++-- .../timeline/format/NoticeEventFormatter.kt | 27 ++++++++++++------ .../helper/TimelineDisplayableEvents.kt | 19 ------------- .../home/room/list/RoomSummaryItemFactory.kt | 5 ++-- .../notifications/NotifiableEventResolver.kt | 4 +-- vector/src/main/res/values/strings_riotX.xml | 2 +- 11 files changed, 64 insertions(+), 51 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt index 43c1544ffd..ac3e2dea43 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt @@ -62,15 +62,18 @@ data class TimelineEvent( } fun getDisambiguatedDisplayName(): String { - return if (isUniqueDisplayName) { + val disambiguated = if (isUniqueDisplayName) { senderName } else { senderName?.let { name -> "$name (${root.senderId})" } } - ?: root.senderId - ?: "" + return if (disambiguated.isNullOrBlank()) { + root.senderId ?: "" + } else { + disambiguated + } } /** @@ -113,7 +116,8 @@ fun TimelineEvent.getLastMessageBody(): String? { val lastMessageContent = getLastMessageContent() if (lastMessageContent != null) { - return lastMessageContent.newContent?.toModel()?.body ?: lastMessageContent.body + return lastMessageContent.newContent?.toModel()?.body + ?: lastMessageContent.body } return null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt index 24765c120d..daee1fadec 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.internal.database.helper +import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.RoomMember @@ -39,14 +40,17 @@ internal fun TimelineEventEntity.updateSenderData() { val isUnlinked = chunkEntity.isUnlinked() var senderMembershipEvent: EventEntity? var senderRoomMemberContent: String? + var senderRoomMemberPrevContent: String? when { stateIndex <= 0 -> { senderMembershipEvent = chunkEntity.timelineEvents.buildQuery(senderId, isUnlinked).next(from = stateIndex)?.root senderRoomMemberContent = senderMembershipEvent?.prevContent + senderRoomMemberPrevContent = senderMembershipEvent?.content } else -> { senderMembershipEvent = chunkEntity.timelineEvents.buildQuery(senderId, isUnlinked).prev(since = stateIndex)?.root senderRoomMemberContent = senderMembershipEvent?.content + senderRoomMemberPrevContent = senderMembershipEvent?.prevContent } } @@ -58,11 +62,27 @@ internal fun TimelineEventEntity.updateSenderData() { .equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_MEMBER) .prev(since = stateIndex) senderRoomMemberContent = senderMembershipEvent?.content + senderRoomMemberPrevContent = senderMembershipEvent?.prevContent + } + + ContentMapper.map(senderRoomMemberContent).toModel()?.also { + this.senderAvatar = it.avatarUrl + this.senderName = it.displayName + this.isUniqueDisplayName = RoomMembers(realm, roomId).isUniqueDisplayName(it.displayName) + } + + // We try to fallback on prev content if we got a room member state events with null fields + if (root?.type == EventType.STATE_ROOM_MEMBER) { + ContentMapper.map(senderRoomMemberPrevContent).toModel()?.also { + if (this.senderAvatar == null && it.avatarUrl != null) { + this.senderAvatar = it.avatarUrl + } + if (this.senderName == null && it.displayName != null) { + this.senderName = it.displayName + this.isUniqueDisplayName = RoomMembers(realm, roomId).isUniqueDisplayName(it.displayName) + } + } } - val senderRoomMember: RoomMember? = ContentMapper.map(senderRoomMemberContent).toModel() - this.senderAvatar = senderRoomMember?.avatarUrl - this.senderName = senderRoomMember?.displayName - this.isUniqueDisplayName = RoomMembers(realm, roomId).isUniqueDisplayName(senderRoomMember?.displayName) this.senderMembershipEvent = senderMembershipEvent } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt index 49c813ece6..dae1b043ba 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt @@ -119,7 +119,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use permalink, stringProvider.getString(R.string.message_reply_to_prefix), userLink, - originalEvent.senderName ?: originalEvent.root.senderId, + originalEvent.getDisambiguatedDisplayName(), body.takeFormatted(), createTextContent(newBodyText, newBodyAutoMarkdown).takeFormatted() ) 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 7c4437d6f0..35bcd388fd 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 @@ -409,7 +409,7 @@ class RoomDetailFragment : composerLayout.composerRelatedMessageActionIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), iconRes)) composerLayout.sendButton.setContentDescription(getString(descriptionRes)) - avatarRenderer.render(event.senderAvatar, event.root.senderId ?: "", event.senderName, composerLayout.composerRelatedMessageAvatar) + avatarRenderer.render(event.senderAvatar, event.root.senderId ?: "", event.getDisambiguatedDisplayName(), composerLayout.composerRelatedMessageAvatar) composerLayout.expand { // need to do it here also when not using quick reply focusComposerAndShowKeyboard() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt index 12f49c2e74..3f234fcd3e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt @@ -27,8 +27,6 @@ import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.helper.AvatarSizeProvider -import im.vector.riotx.features.home.room.detail.timeline.helper.senderAvatar -import im.vector.riotx.features.home.room.detail.timeline.helper.senderName import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_ @@ -41,13 +39,13 @@ class EncryptionItemFactory @Inject constructor(private val stringProvider: Stri fun create(event: TimelineEvent, highlight: Boolean, callback: TimelineEventController.Callback?): NoticeItem? { - val text = buildNoticeText(event.root, event.senderName) ?: return null + val text = buildNoticeText(event.root, event.getDisambiguatedDisplayName()) ?: return null val informationData = MessageInformationData( eventId = event.root.eventId ?: "?", senderId = event.root.senderId ?: "", sendState = event.root.sendState, - avatarUrl = event.senderAvatar(), - memberName = event.senderName(), + avatarUrl = event.senderAvatar, + memberName = event.getDisambiguatedDisplayName(), showInformation = false ) val attributes = NoticeItem.Attributes( diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 1df885cd35..1d98595c4d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -64,12 +64,12 @@ class MergedHeaderItemFactory @Inject constructor(private val sessionHolder: Act if (!showReadMarker && mergedEvent.hasReadMarker && readMarkerVisible) { showReadMarker = true } - val senderAvatar = mergedEvent.senderAvatar() - val senderName = mergedEvent.senderName() + val senderAvatar = mergedEvent.senderAvatar + val senderName = mergedEvent.getDisambiguatedDisplayName() val data = MergedHeaderItem.Data( userId = mergedEvent.root.senderId ?: "", avatarUrl = senderAvatar, - memberName = senderName ?: "", + memberName = senderName , localId = mergedEvent.localId, eventId = mergedEvent.root.eventId ?: "" ) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 2d116e4a90..9a86420277 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -19,13 +19,17 @@ package im.vector.riotx.features.home.room.detail.timeline.format import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel -import im.vector.matrix.android.api.session.room.model.* +import im.vector.matrix.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility +import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent +import im.vector.matrix.android.api.session.room.model.RoomMember +import im.vector.matrix.android.api.session.room.model.RoomNameContent +import im.vector.matrix.android.api.session.room.model.RoomTopicContent import im.vector.matrix.android.api.session.room.model.call.CallInviteContent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.resources.StringProvider -import im.vector.riotx.features.home.room.detail.timeline.helper.senderName import timber.log.Timber import javax.inject.Inject @@ -36,7 +40,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active return when (val type = timelineEvent.root.getClearType()) { EventType.STATE_ROOM_NAME -> formatRoomNameEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) EventType.STATE_ROOM_TOPIC -> formatRoomTopicEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) - EventType.STATE_ROOM_MEMBER -> formatRoomMemberEvent(timelineEvent.root, timelineEvent.senderName()) + EventType.STATE_ROOM_MEMBER -> formatRoomMemberEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) EventType.STATE_HISTORY_VISIBILITY -> formatRoomHistoryVisibilityEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(timelineEvent.getDisambiguatedDisplayName()) EventType.CALL_INVITE, @@ -96,7 +100,8 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } private fun formatRoomHistoryVisibilityEvent(event: Event, senderName: String?): CharSequence? { - val historyVisibility = event.getClearContent().toModel()?.historyVisibility ?: return null + val historyVisibility = event.getClearContent().toModel()?.historyVisibility + ?: return null val formattedVisibility = when (historyVisibility) { RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared) @@ -135,7 +140,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } } - private fun buildProfileNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? { + private fun buildProfileNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String { val displayText = StringBuilder() // Check display name has been changed if (eventContent?.displayName != prevEventContent?.displayName) { @@ -146,7 +151,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active stringProvider.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) else -> stringProvider.getString(R.string.notice_display_name_changed_from, - event.senderId, prevEventContent?.displayName, eventContent?.displayName) + event.senderId, prevEventContent?.displayName, eventContent?.displayName) } displayText.append(displayNameText) } @@ -160,6 +165,11 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active } displayText.append(displayAvatarText) } + if (displayText.isEmpty()) { + displayText.append( + stringProvider.getString(R.string.notice_member_no_changes, senderName) + ) + } return displayText.toString() } @@ -171,9 +181,10 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId when { eventContent.thirdPartyInvite != null -> { - val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey + val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid + ?: event.stateKey stringProvider.getString(R.string.notice_room_third_party_registered_invite, - userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) + userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) } event.stateKey == selfUserId -> stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index a75ac86c1b..0b2a111e7e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -47,25 +47,6 @@ object TimelineDisplayableEvents { ) } -fun TimelineEvent.senderAvatar(): String? { - // We might have no avatar when user leave, so we try to get it from prevContent - return senderAvatar - ?: if (root.type == EventType.STATE_ROOM_MEMBER) { - root.prevContent.toModel()?.avatarUrl - } else { - null - } -} - -fun TimelineEvent.senderName(): String? { - // We might have no senderName when user leave, so we try to get it from prevContent - return when { - senderName != null -> getDisambiguatedDisplayName() - root.type == EventType.STATE_ROOM_MEMBER -> root.prevContent.toModel()?.displayName - else -> null - } -} - fun TimelineEvent.canBeMerged(): Boolean { return root.getClearType() == EventType.STATE_ROOM_MEMBER } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt index 0ad3b10159..1e5067923b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt @@ -30,7 +30,6 @@ import im.vector.riotx.core.resources.DateProvider import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter -import im.vector.riotx.features.home.room.detail.timeline.helper.senderName import me.gujun.android.span.span import javax.inject.Inject @@ -97,10 +96,10 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte && latestEvent.root.mxDecryptionResult == null) { stringProvider.getString(R.string.encrypted_message) } else if (latestEvent.root.getClearType() == EventType.MESSAGE) { - val senderName = latestEvent.senderName() ?: latestEvent.root.senderId + val senderName = latestEvent.getDisambiguatedDisplayName() val content = latestEvent.root.getClearContent()?.toModel() val message = content?.body ?: "" - if (roomSummary.isDirect.not() && senderName != null) { + if (roomSummary.isDirect.not()) { span { text = senderName textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_primary) diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt index 06108e07fe..fc555b5735 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/NotifiableEventResolver.kt @@ -94,7 +94,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St event.getLastMessageBody() ?: stringProvider.getString(R.string.notification_unknown_new_event) val roomName = stringProvider.getString(R.string.notification_unknown_room_name) - val senderDisplayName = event.senderName ?: event.root.senderId + val senderDisplayName = event.getDisambiguatedDisplayName() val notifiableEvent = NotifiableMessageEvent( eventId = event.root.eventId!!, @@ -128,7 +128,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St val body = event.getLastMessageBody() ?: stringProvider.getString(R.string.notification_unknown_new_event) val roomName = room.roomSummary()?.displayName ?: "" - val senderDisplayName = event.senderName ?: event.root.senderId + val senderDisplayName = event.getDisambiguatedDisplayName() val notifiableEvent = NotifiableMessageEvent( eventId = event.root.eventId!!, diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 71fbc22acf..20fc234fc8 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,6 +2,6 @@ - + "%1$s made no changes" From 035359cb355ae80495e41c866998cca3d7ac1f48 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 28 Oct 2019 17:01:41 +0100 Subject: [PATCH 019/117] Update CHANGES and clean code --- CHANGES.md | 2 +- .../internal/database/helper/TimelineEventEntityHelper.kt | 1 - .../room/detail/timeline/factory/MergedHeaderItemFactory.kt | 2 +- .../room/detail/timeline/helper/TimelineDisplayableEvents.kt | 2 -- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b05300f94b..212d1543f9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ Other changes: - Bugfix 🐛: - - + - Fix issues with some member events rendering (#498) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt index daee1fadec..36ed2f7edf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/TimelineEventEntityHelper.kt @@ -16,7 +16,6 @@ package im.vector.matrix.android.internal.database.helper -import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.RoomMember diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 1d98595c4d..51364e24c9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -69,7 +69,7 @@ class MergedHeaderItemFactory @Inject constructor(private val sessionHolder: Act val data = MergedHeaderItem.Data( userId = mergedEvent.root.senderId ?: "", avatarUrl = senderAvatar, - memberName = senderName , + memberName = senderName, localId = mergedEvent.localId, eventId = mergedEvent.root.eventId ?: "" ) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index 0b2a111e7e..f40b8e6f6d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -17,8 +17,6 @@ package im.vector.riotx.features.home.room.detail.timeline.helper import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.api.session.events.model.toModel -import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.riotx.core.extensions.localDateTime From 7272343e6d818978029401038a6b44af85264096 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 14:32:05 +0100 Subject: [PATCH 020/117] Update comment --- .buildkite/pipeline.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index a76d06ad5c..de434d0122 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -7,7 +7,7 @@ steps: - label: "Compile and run Unit tests" agents: # We use a medium sized instance instead of the normal small ones because - # gradle build is long + # gradle build can be memory hungry queue: "medium" commands: - "./gradlew clean test --stacktrace" @@ -19,7 +19,7 @@ steps: - label: "Compile Android tests" agents: # We use a medium sized instance instead of the normal small ones because - # gradle build is long + # gradle build can be memory hungry queue: "medium" commands: - "./gradlew clean assembleAndroidTest --stacktrace" @@ -30,8 +30,8 @@ steps: - label: "Assemble GPlay Debug version" agents: - # We use a medium sized instance instead of the normal small ones because - # gradle build is long + # We use a xlarge sized instance instead of the normal small ones because + # gradle build can be memory hungry queue: "xlarge" commands: - "./gradlew clean lintGplayRelease assembleGplayDebug --stacktrace" @@ -45,8 +45,8 @@ steps: - label: "Assemble FDroid Debug version" agents: - # We use a medium sized instance instead of the normal small ones because - # gradle build is long + # We use a xlarge sized instance instead of the normal small ones because + # gradle build can be memory hungry queue: "xlarge" commands: - "./gradlew clean lintFdroidRelease assembleFdroidDebug --stacktrace" @@ -60,8 +60,8 @@ steps: - label: "Build Google Play unsigned APK" agents: - # We use a medium sized instance instead of the normal small ones because - # gradle build is long + # We use a xlarge sized instance instead of the normal small ones because + # gradle build can be memory hungry queue: "xlarge" commands: - "./gradlew clean assembleGplayRelease --stacktrace" From 361427488ff65bf2640c1cb8f91d61f31609661b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 14:38:04 +0100 Subject: [PATCH 021/117] Passphrase does not match (Export room keys) (Fixes #644) --- CHANGES.md | 2 +- .../java/im/vector/riotx/core/dialogs/ExportKeysDialog.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b05300f94b..50e8a8e94a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ Other changes: - Bugfix 🐛: - - + - Passphrase does not match (Export room keys) (#644) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/riotx/core/dialogs/ExportKeysDialog.kt b/vector/src/main/java/im/vector/riotx/core/dialogs/ExportKeysDialog.kt index fb320afded..1cb6c5406a 100644 --- a/vector/src/main/java/im/vector/riotx/core/dialogs/ExportKeysDialog.kt +++ b/vector/src/main/java/im/vector/riotx/core/dialogs/ExportKeysDialog.kt @@ -44,15 +44,15 @@ class ExportKeysDialog { val textWatcher = object : SimpleTextWatcher() { override fun afterTextChanged(s: Editable) { when { - passPhrase1EditText.text.isNullOrEmpty() -> { + passPhrase1EditText.text.isNullOrEmpty() -> { exportButton.isEnabled = false passPhrase2Til.error = null } - passPhrase1EditText.text == passPhrase2EditText.text -> { + passPhrase1EditText.text.toString() == passPhrase2EditText.text.toString() -> { exportButton.isEnabled = true passPhrase2Til.error = null } - else -> { + else -> { exportButton.isEnabled = false passPhrase2Til.error = activity.getString(R.string.passphrase_passphrase_does_not_match) } From 6567c5e6c76a21a46fd09e0b240110ce31614b87 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 16:20:22 +0100 Subject: [PATCH 022/117] Small kotlin improvement --- .../riotx/features/command/CommandParser.kt | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index ac79ed8b40..9cf6510fdb 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -44,12 +44,11 @@ object CommandParser { return ParsedCommand.ErrorNotACommand } - var messageParts: List? = null - - try { - messageParts = textMessage.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() } + val messageParts = try { + textMessage.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() } } catch (e: Exception) { Timber.e(e, "## manageSplashCommand() : split failed") + null } // test if the string cut fails @@ -57,10 +56,8 @@ object CommandParser { return ParsedCommand.ErrorEmptySlashCommand } - val slashCommand = messageParts[0] - - when (slashCommand) { - Command.CHANGE_DISPLAY_NAME.command -> { + when (val slashCommand = messageParts.first()) { + Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() return if (newDisplayName.isNotEmpty()) { @@ -69,7 +66,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) } } - Command.TOPIC.command -> { + Command.TOPIC.command -> { val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() return if (newTopic.isNotEmpty()) { @@ -78,12 +75,12 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.TOPIC) } } - Command.EMOTE.command -> { + Command.EMOTE.command -> { val message = textMessage.substring(Command.EMOTE.command.length).trim() return ParsedCommand.SendEmote(message) } - Command.JOIN_ROOM.command -> { + Command.JOIN_ROOM.command -> { val roomAlias = textMessage.substring(Command.JOIN_ROOM.command.length).trim() return if (roomAlias.isNotEmpty()) { @@ -92,7 +89,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } - Command.PART.command -> { + Command.PART.command -> { val roomAlias = textMessage.substring(Command.PART.command.length).trim() return if (roomAlias.isNotEmpty()) { @@ -101,7 +98,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PART) } } - Command.INVITE.command -> { + Command.INVITE.command -> { return if (messageParts.size == 2) { val userId = messageParts[1] @@ -114,7 +111,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.INVITE) } } - Command.KICK_USER.command -> { + Command.KICK_USER.command -> { return if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -130,7 +127,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.KICK_USER) } } - Command.BAN_USER.command -> { + Command.BAN_USER.command -> { return if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -146,7 +143,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.BAN_USER) } } - Command.UNBAN_USER.command -> { + Command.UNBAN_USER.command -> { return if (messageParts.size == 2) { val userId = messageParts[1] @@ -159,7 +156,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } } - Command.SET_USER_POWER_LEVEL.command -> { + Command.SET_USER_POWER_LEVEL.command -> { return if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -192,25 +189,25 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.MARKDOWN.command -> { + Command.MARKDOWN.command -> { return if (messageParts.size == 2) { when { - "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) + "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) "off".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(false) - else -> ParsedCommand.ErrorSyntax(Command.MARKDOWN) + else -> ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } else { ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } - Command.CLEAR_SCALAR_TOKEN.command -> { + Command.CLEAR_SCALAR_TOKEN.command -> { return if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } - else -> { + else -> { // Unknown command return ParsedCommand.ErrorUnknownSlashCommand(slashCommand) } From 7496a88dcd8c5a6acaf7049f944fbcff774f05ad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 16:22:12 +0100 Subject: [PATCH 023/117] Markdown set to off by default (Fixes #412) --- CHANGES.md | 2 +- .../java/im/vector/riotx/features/settings/VectorPreferences.kt | 2 +- vector/src/main/res/xml/vector_settings_preferences.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 50e8a8e94a..3b94ab0390 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Other changes: - - + - Markdown set to off by default (#412) Bugfix 🐛: - Passphrase does not match (Export room keys) (#644) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt index f9601265d3..a593bb6e96 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt @@ -576,7 +576,7 @@ class VectorPreferences @Inject constructor(private val context: Context) { * @return true if the markdown is enabled */ fun isMarkdownEnabled(): Boolean { - return defaultPrefs.getBoolean(SETTINGS_ENABLE_MARKDOWN_KEY, true) + return defaultPrefs.getBoolean(SETTINGS_ENABLE_MARKDOWN_KEY, false) } /** diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml index 11209b5345..96471cfebe 100644 --- a/vector/src/main/res/xml/vector_settings_preferences.xml +++ b/vector/src/main/res/xml/vector_settings_preferences.xml @@ -39,7 +39,7 @@ android:title="@string/settings_send_typing_notifs" /> From 118870bc41d7c24efe1d84365f618d5b998a4cb7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 17:02:55 +0100 Subject: [PATCH 024/117] ktlint cleanup --- .../android/internal/session/room/send/LocalEchoEventFactory.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt index a9406c8bff..d73f72ff55 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt @@ -39,7 +39,6 @@ import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.util.StringProvider import org.commonmark.parser.Parser import org.commonmark.renderer.html.HtmlRenderer -import java.util.UUID import javax.inject.Inject /** From 351787315676f7ed5dfe0e19f82fa1371a6ccfc1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 29 Oct 2019 19:08:48 +0100 Subject: [PATCH 025/117] Timeline: Start handling code blocks. [WIP] --- vector/build.gradle | 6 +- .../timeline/factory/MessageItemFactory.kt | 37 ++-- .../timeline/item/MessageBlockCodeItem.kt | 44 +++++ .../vector/riotx/features/html/CodeVisitor.kt | 56 ++++++ .../riotx/features/html/EventHtmlRenderer.kt | 164 +++--------------- .../riotx/features/html/FontTagHandler.kt | 43 ++--- .../riotx/features/html/MxLinkTagHandler.kt | 65 +++++++ .../riotx/features/html/MxReplyTagHandler.kt | 44 +++++ .../res/layout/item_timeline_event_base.xml | 8 + .../item_timeline_event_code_block_stub.xml | 40 +++++ 10 files changed, 328 insertions(+), 179 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/html/MxLinkTagHandler.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/html/MxReplyTagHandler.kt create mode 100644 vector/src/main/res/layout/item_timeline_event_code_block_stub.xml diff --git a/vector/build.gradle b/vector/build.gradle index 34c01c028e..d639b4c3e8 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -219,7 +219,7 @@ dependencies { def epoxy_version = '3.8.0' def arrow_version = "0.8.2" def coroutines_version = "1.3.2" - def markwon_version = '3.1.0' + def markwon_version = '4.1.2' def big_image_viewer_version = '1.5.6' def glide_version = '4.10.0' def moshi_version = '1.8.0' @@ -283,8 +283,8 @@ dependencies { implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.google.android.material:material:1.1.0-beta01' implementation 'me.gujun.android:span:1.7' - implementation "ru.noties.markwon:core:$markwon_version" - implementation "ru.noties.markwon:html:$markwon_version" + implementation "io.noties.markwon:core:$markwon_version" + implementation "io.noties.markwon:html:$markwon_version" implementation 'me.saket:better-link-movement-method:2.2.0' implementation 'com.google.android:flexbox:1.1.1' diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 0bb5c3a1d8..cc00ba9fb6 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -46,9 +46,11 @@ import im.vector.riotx.features.home.room.detail.timeline.TimelineEventControlle import im.vector.riotx.features.home.room.detail.timeline.helper.* import im.vector.riotx.features.home.room.detail.timeline.item.* import im.vector.riotx.features.html.EventHtmlRenderer +import im.vector.riotx.features.html.CodeVisitor import im.vector.riotx.features.media.ImageContentRenderer import im.vector.riotx.features.media.VideoContentRenderer import me.gujun.android.span.span +import org.commonmark.node.Document import javax.inject.Inject class MessageItemFactory @Inject constructor( @@ -234,22 +236,33 @@ class MessageItemFactory @Inject constructor( highlight: Boolean, callback: TimelineEventController.Callback?, attributes: AbsMessageItem.Attributes): MessageTextItem? { + val isFormatted = messageContent.formattedBody.isNullOrBlank().not() - val bodyToUse = messageContent.formattedBody?.let { - htmlRenderer.get().render(it.trim()) - } ?: messageContent.body + val bodyToUse = if (isFormatted) { + val formattedBody = htmlRenderer.get().parse(messageContent.body) as Document + val codeVisitor = CodeVisitor() + codeVisitor.visit(formattedBody) + if (codeVisitor.codeKind == CodeVisitor.Kind.NONE) { + messageContent.formattedBody.let { + htmlRenderer.get().render(it!!.trim()) + } + } else { + htmlRenderer.get().render(formattedBody) + } + } else { + messageContent.body + } val linkifiedBody = linkifyBody(bodyToUse, callback) - return MessageTextItem_() - .apply { - if (informationData.hasBeenEdited) { - val spannable = annotateWithEdited(linkifiedBody, callback, informationData) - message(spannable) - } else { - message(linkifiedBody) - } - } + return MessageTextItem_().apply { + if (informationData.hasBeenEdited) { + val spannable = annotateWithEdited(linkifiedBody, callback, informationData) + message(spannable) + } else { + message(linkifiedBody) + } + } .useBigFont(linkifiedBody.length <= MAX_NUMBER_OF_EMOJI_FOR_BIG_FONT * 2 && containsOnlyEmojis(linkifiedBody.toString())) .searchForPills(isFormatted) .leftGuideline(avatarSizeProvider.leftGuideline) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt new file mode 100644 index 0000000000..1ac35181ce --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt @@ -0,0 +1,44 @@ +/* + * 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.room.detail.timeline.item + +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.riotx.R +import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController + +@EpoxyModelClass(layout = R.layout.item_timeline_event_base) +abstract class MessageBlockCodeItem : AbsMessageItem() { + + @EpoxyAttribute + var message: CharSequence? = null + + override fun bind(holder: Holder) { + super.bind(holder) + + } + + override fun getViewType() = STUB_ID + + class Holder : AbsMessageItem.Holder(STUB_ID) { + + } + + companion object { + private const val STUB_ID = R.id.messageContentCodeBlockStub + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt b/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt new file mode 100644 index 0000000000..009d74818a --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt @@ -0,0 +1,56 @@ +/* + * 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.html + +import org.commonmark.node.AbstractVisitor +import org.commonmark.node.Code +import org.commonmark.node.FencedCodeBlock +import org.commonmark.node.IndentedCodeBlock + +/** + * This class is in charge of visiting nodes and tells if we have some code nodes (inline or block). + */ +class CodeVisitor : AbstractVisitor() { + + var codeKind: Kind = Kind.NONE + private set + + override fun visit(fencedCodeBlock: FencedCodeBlock?) { + if (codeKind == Kind.NONE) { + codeKind = Kind.BLOCK + } + } + + override fun visit(indentedCodeBlock: IndentedCodeBlock?) { + if (codeKind == Kind.NONE) { + codeKind = Kind.BLOCK + } + } + + override fun visit(code: Code?) { + if (codeKind == Kind.NONE) { + codeKind = Kind.INLINE + } + } + + enum class Kind { + NONE, + INLINE, + BLOCK + } + +} diff --git a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt index 06af8ebca5..4e387a5b12 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt @@ -17,171 +17,47 @@ package im.vector.riotx.features.html import android.content.Context -import android.text.style.URLSpan -import im.vector.matrix.android.api.permalinks.PermalinkData -import im.vector.matrix.android.api.permalinks.PermalinkParser import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.glide.GlideApp -import im.vector.riotx.core.glide.GlideRequests import im.vector.riotx.features.home.AvatarRenderer -import org.commonmark.node.BlockQuote -import org.commonmark.node.HtmlBlock -import org.commonmark.node.HtmlInline +import io.noties.markwon.Markwon +import io.noties.markwon.html.HtmlPlugin +import io.noties.markwon.html.TagHandlerNoOp import org.commonmark.node.Node -import ru.noties.markwon.* -import ru.noties.markwon.html.HtmlTag -import ru.noties.markwon.html.MarkwonHtmlParserImpl -import ru.noties.markwon.html.MarkwonHtmlRenderer -import ru.noties.markwon.html.TagHandler -import ru.noties.markwon.html.tag.* -import java.util.Arrays.asList import javax.inject.Inject import javax.inject.Singleton @Singleton class EventHtmlRenderer @Inject constructor(context: Context, - avatarRenderer: AvatarRenderer, - sessionHolder: ActiveSessionHolder) { + htmlConfigure: MatrixHtmlPluginConfigure) { + private val markwon = Markwon.builder(context) - .usePlugin(MatrixPlugin.create(GlideApp.with(context), context, avatarRenderer, sessionHolder)) + .usePlugin(HtmlPlugin.create(htmlConfigure)) .build() + fun parse(text: String): Node { + return markwon.parse(text) + } + fun render(text: String): CharSequence { return markwon.toMarkdown(text) } - fun render(node: Node) : CharSequence { + fun render(node: Node): CharSequence { return markwon.render(node) } } -private class MatrixPlugin private constructor(private val glideRequests: GlideRequests, - private val context: Context, - private val avatarRenderer: AvatarRenderer, - private val session: ActiveSessionHolder) : AbstractMarkwonPlugin() { +class MatrixHtmlPluginConfigure @Inject constructor(private val context: Context, + private val avatarRenderer: AvatarRenderer, + private val session: ActiveSessionHolder) : HtmlPlugin.HtmlConfigure { - override fun configureConfiguration(builder: MarkwonConfiguration.Builder) { - builder.htmlParser(MarkwonHtmlParserImpl.create()) + override fun configureHtml(plugin: HtmlPlugin) { + plugin + .addHandler(TagHandlerNoOp.create("a")) + .addHandler(FontTagHandler()) + .addHandler(MxLinkTagHandler(GlideApp.with(context), context, avatarRenderer, session)) + .addHandler(MxReplyTagHandler()) } - override fun configureHtmlRenderer(builder: MarkwonHtmlRenderer.Builder) { - builder - .setHandler( - "img", - ImageHandler.create()) - .setHandler( - "a", - MxLinkHandler(glideRequests, context, avatarRenderer, session)) - .setHandler( - "blockquote", - BlockquoteHandler()) - .setHandler( - "font", - FontTagHandler()) - .setHandler( - "sub", - SubScriptHandler()) - .setHandler( - "sup", - SuperScriptHandler()) - .setHandler( - asList("b", "strong"), - StrongEmphasisHandler()) - .setHandler( - asList("s", "del"), - StrikeHandler()) - .setHandler( - asList("u", "ins"), - UnderlineHandler()) - .setHandler( - asList("ul", "ol"), - ListHandler()) - .setHandler( - asList("i", "em", "cite", "dfn"), - EmphasisHandler()) - .setHandler( - asList("h1", "h2", "h3", "h4", "h5", "h6"), - HeadingHandler()) - .setHandler("mx-reply", - MxReplyTagHandler()) - } - - override fun afterRender(node: Node, visitor: MarkwonVisitor) { - val configuration = visitor.configuration() - configuration.htmlRenderer().render(visitor, configuration.htmlParser()) - } - - override fun configureVisitor(builder: MarkwonVisitor.Builder) { - builder - .on(HtmlBlock::class.java) { visitor, htmlBlock -> visitHtml(visitor, htmlBlock.literal) } - .on(HtmlInline::class.java) { visitor, htmlInline -> visitHtml(visitor, htmlInline.literal) } - } - - private fun visitHtml(visitor: MarkwonVisitor, html: String?) { - if (html != null) { - visitor.configuration().htmlParser().processFragment(visitor.builder(), html) - } - } - - companion object { - - fun create(glideRequests: GlideRequests, context: Context, avatarRenderer: AvatarRenderer, session: ActiveSessionHolder): MatrixPlugin { - return MatrixPlugin(glideRequests, context, avatarRenderer, session) - } - } -} - -private class MxLinkHandler(private val glideRequests: GlideRequests, - private val context: Context, - private val avatarRenderer: AvatarRenderer, - private val sessionHolder: ActiveSessionHolder) : TagHandler() { - - private val linkHandler = LinkHandler() - - override fun handle(visitor: MarkwonVisitor, renderer: MarkwonHtmlRenderer, tag: HtmlTag) { - val link = tag.attributes()["href"] - if (link != null) { - val permalinkData = PermalinkParser.parse(link) - when (permalinkData) { - is PermalinkData.UserLink -> { - val user = sessionHolder.getSafeActiveSession()?.getUser(permalinkData.userId) - val span = PillImageSpan(glideRequests, avatarRenderer, context, permalinkData.userId, user) - SpannableBuilder.setSpans( - visitor.builder(), - span, - tag.start(), - tag.end() - ) - // also add clickable span - SpannableBuilder.setSpans( - visitor.builder(), - URLSpan(link), - tag.start(), - tag.end() - ) - } - else -> linkHandler.handle(visitor, renderer, tag) - } - } else { - linkHandler.handle(visitor, renderer, tag) - } - } -} - -private class MxReplyTagHandler : TagHandler() { - - override fun handle(visitor: MarkwonVisitor, renderer: MarkwonHtmlRenderer, tag: HtmlTag) { - val configuration = visitor.configuration() - val factory = configuration.spansFactory().get(BlockQuote::class.java) - if (factory != null) { - SpannableBuilder.setSpans( - visitor.builder(), - factory.getSpans(configuration, visitor.renderProps()), - tag.start(), - tag.end() - ) - val replyText = visitor.builder().removeFromEnd(tag.end()) - visitor.builder().append("\n\n").append(replyText) - } - } } diff --git a/vector/src/main/java/im/vector/riotx/features/html/FontTagHandler.kt b/vector/src/main/java/im/vector/riotx/features/html/FontTagHandler.kt index f4fa1737c9..e5733dd849 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/FontTagHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/FontTagHandler.kt @@ -17,15 +17,18 @@ package im.vector.riotx.features.html import android.graphics.Color import android.text.style.ForegroundColorSpan -import ru.noties.markwon.MarkwonConfiguration -import ru.noties.markwon.RenderProps -import ru.noties.markwon.html.HtmlTag -import ru.noties.markwon.html.tag.SimpleTagHandler +import io.noties.markwon.MarkwonConfiguration +import io.noties.markwon.RenderProps +import io.noties.markwon.html.HtmlTag +import io.noties.markwon.html.tag.SimpleTagHandler /** * custom to matrix for IRC-style font coloring */ class FontTagHandler : SimpleTagHandler() { + + override fun supportedTags() = listOf("font") + override fun getSpans(configuration: MarkwonConfiguration, renderProps: RenderProps, tag: HtmlTag): Any? { val colorString = tag.attributes()["color"]?.let { parseColor(it) } ?: Color.BLACK return ForegroundColorSpan(colorString) @@ -37,23 +40,23 @@ class FontTagHandler : SimpleTagHandler() { } catch (e: Exception) { // try other w3c colors? return when (color_name) { - "white" -> Color.WHITE - "yellow" -> Color.YELLOW + "white" -> Color.WHITE + "yellow" -> Color.YELLOW "fuchsia" -> Color.parseColor("#FF00FF") - "red" -> Color.RED - "silver" -> Color.parseColor("#C0C0C0") - "gray" -> Color.GRAY - "olive" -> Color.parseColor("#808000") - "purple" -> Color.parseColor("#800080") - "maroon" -> Color.parseColor("#800000") - "aqua" -> Color.parseColor("#00FFFF") - "lime" -> Color.parseColor("#00FF00") - "teal" -> Color.parseColor("#008080") - "green" -> Color.GREEN - "blue" -> Color.BLUE - "orange" -> Color.parseColor("#FFA500") - "navy" -> Color.parseColor("#000080") - else -> Color.BLACK + "red" -> Color.RED + "silver" -> Color.parseColor("#C0C0C0") + "gray" -> Color.GRAY + "olive" -> Color.parseColor("#808000") + "purple" -> Color.parseColor("#800080") + "maroon" -> Color.parseColor("#800000") + "aqua" -> Color.parseColor("#00FFFF") + "lime" -> Color.parseColor("#00FF00") + "teal" -> Color.parseColor("#008080") + "green" -> Color.GREEN + "blue" -> Color.BLUE + "orange" -> Color.parseColor("#FFA500") + "navy" -> Color.parseColor("#000080") + else -> Color.BLACK } } } diff --git a/vector/src/main/java/im/vector/riotx/features/html/MxLinkTagHandler.kt b/vector/src/main/java/im/vector/riotx/features/html/MxLinkTagHandler.kt new file mode 100644 index 0000000000..fdcbb12cd7 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/html/MxLinkTagHandler.kt @@ -0,0 +1,65 @@ +/* + * 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.html + +import android.content.Context +import android.text.style.URLSpan +import im.vector.matrix.android.api.permalinks.PermalinkData +import im.vector.matrix.android.api.permalinks.PermalinkParser +import im.vector.riotx.core.di.ActiveSessionHolder +import im.vector.riotx.core.glide.GlideRequests +import im.vector.riotx.features.home.AvatarRenderer +import io.noties.markwon.MarkwonVisitor +import io.noties.markwon.SpannableBuilder +import io.noties.markwon.html.HtmlTag +import io.noties.markwon.html.MarkwonHtmlRenderer +import io.noties.markwon.html.tag.LinkHandler + +class MxLinkTagHandler(private val glideRequests: GlideRequests, + private val context: Context, + private val avatarRenderer: AvatarRenderer, + private val sessionHolder: ActiveSessionHolder) : LinkHandler() { + + override fun handle(visitor: MarkwonVisitor, renderer: MarkwonHtmlRenderer, tag: HtmlTag) { + val link = tag.attributes()["href"] + if (link != null) { + val permalinkData = PermalinkParser.parse(link) + when (permalinkData) { + is PermalinkData.UserLink -> { + val user = sessionHolder.getSafeActiveSession()?.getUser(permalinkData.userId) + val span = PillImageSpan(glideRequests, avatarRenderer, context, permalinkData.userId, user) + SpannableBuilder.setSpans( + visitor.builder(), + span, + tag.start(), + tag.end() + ) + // also add clickable span + SpannableBuilder.setSpans( + visitor.builder(), + URLSpan(link), + tag.start(), + tag.end() + ) + } + else -> super.handle(visitor, renderer, tag) + } + } else { + super.handle(visitor, renderer, tag) + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/html/MxReplyTagHandler.kt b/vector/src/main/java/im/vector/riotx/features/html/MxReplyTagHandler.kt new file mode 100644 index 0000000000..f999e253c7 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/html/MxReplyTagHandler.kt @@ -0,0 +1,44 @@ +/* + * 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.html + +import io.noties.markwon.MarkwonVisitor +import io.noties.markwon.SpannableBuilder +import io.noties.markwon.html.HtmlTag +import io.noties.markwon.html.MarkwonHtmlRenderer +import io.noties.markwon.html.TagHandler +import org.commonmark.node.BlockQuote + +class MxReplyTagHandler : TagHandler() { + + override fun supportedTags() = listOf("mx-reply") + + override fun handle(visitor: MarkwonVisitor, renderer: MarkwonHtmlRenderer, tag: HtmlTag) { + val configuration = visitor.configuration() + val factory = configuration.spansFactory().get(BlockQuote::class.java) + if (factory != null) { + SpannableBuilder.setSpans( + visitor.builder(), + factory.getSpans(configuration, visitor.renderProps()), + tag.start(), + tag.end() + ) + val replyText = visitor.builder().removeFromEnd(tag.end()) + visitor.builder().append("\n\n").append(replyText) + } + } +} diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml index fbe3b70551..260c309f6f 100644 --- a/vector/src/main/res/layout/item_timeline_event_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -78,6 +78,14 @@ android:layout="@layout/item_timeline_event_text_message_stub" tools:visibility="visible" /> + + + + + + + + + + + + + + + + From 3f447df13cbfb9c08d6e72348709e7aedc41aa4a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 30 Oct 2019 16:59:31 +0100 Subject: [PATCH 026/117] Support local script (imported from https://github.com/vector-im/riot-android/pull/3364) --- .../riotx/features/settings/VectorLocale.kt | 80 ++++++++++++++++--- 1 file changed, 69 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt index 7fef12cddf..93931fe71d 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt @@ -21,12 +21,16 @@ import android.content.res.Configuration import android.os.Build import android.preference.PreferenceManager import androidx.core.content.edit +import im.vector.riotx.BuildConfig import im.vector.riotx.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import timber.log.Timber import java.util.Locale +import kotlin.Comparator +import kotlin.collections.ArrayList +import kotlin.collections.HashSet /** * Object to manage the Locale choice of the user @@ -35,6 +39,7 @@ object VectorLocale { private const val APPLICATION_LOCALE_COUNTRY_KEY = "APPLICATION_LOCALE_COUNTRY_KEY" private const val APPLICATION_LOCALE_VARIANT_KEY = "APPLICATION_LOCALE_VARIANT_KEY" private const val APPLICATION_LOCALE_LANGUAGE_KEY = "APPLICATION_LOCALE_LANGUAGE_KEY" + private const val APPLICATION_LOCALE_SCRIPT_KEY = "APPLICATION_LOCALE_SCRIPT_KEY" private val defaultLocale = Locale("en", "US") @@ -106,6 +111,15 @@ object VectorLocale { } else { putString(APPLICATION_LOCALE_VARIANT_KEY, variant) } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val script = locale.script + if (script.isEmpty()) { + remove(APPLICATION_LOCALE_SCRIPT_KEY) + } else { + putString(APPLICATION_LOCALE_SCRIPT_KEY, script) + } + } } } @@ -159,24 +173,43 @@ object VectorLocale { * @param context the context */ private fun initApplicationLocales(context: Context) { - val knownLocalesSet = HashSet>() + val knownLocalesSet = HashSet>() try { val availableLocales = Locale.getAvailableLocales() for (locale in availableLocales) { - knownLocalesSet.add(Pair(getString(context, locale, R.string.resources_language), - getString(context, locale, R.string.resources_country_code))) + knownLocalesSet.add( + Triple( + getString(context, locale, R.string.resources_language), + getString(context, locale, R.string.resources_country_code), + getString(context, locale, R.string.resources_script) + ) + ) } } catch (e: Exception) { Timber.e(e, "## getApplicationLocales() : failed") - knownLocalesSet.add(Pair(context.getString(R.string.resources_language), context.getString(R.string.resources_country_code))) + knownLocalesSet.add( + Triple( + context.getString(R.string.resources_language), + context.getString(R.string.resources_country_code), + context.getString(R.string.resources_script) + ) + ) } supportedLocales.clear() - knownLocalesSet.mapTo(supportedLocales) { (language, country) -> - Locale(language, country) + knownLocalesSet.mapTo(supportedLocales) { (language, country, script) -> + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Locale.Builder() + .setLanguage(language) + .setRegion(country) + .setScript(script) + .build() + } else { + Locale(language, country) + } } // sort by human display names @@ -190,12 +223,37 @@ object VectorLocale { * @return the string */ fun localeToLocalisedString(locale: Locale): String { - var res = locale.getDisplayLanguage(locale) + return buildString { + append(locale.getDisplayLanguage(locale)) - if (locale.getDisplayCountry(locale).isNotEmpty()) { - res += " (" + locale.getDisplayCountry(locale) + ")" + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP + && locale.script != "Latn" + && locale.getDisplayScript(locale).isNotEmpty()) { + append(" - ") + append(locale.getDisplayScript(locale)) + } + + if (locale.getDisplayCountry(locale).isNotEmpty()) { + append(" (") + append(locale.getDisplayCountry(locale)) + append(")") + } + + // In debug mode, also display information about the locale in the current locale. + if (BuildConfig.DEBUG) { + append("\n[") + append(locale.displayLanguage) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && locale.script != "Latn") { + append(" - ") + append(locale.displayScript) + } + if (locale.displayCountry.isNotEmpty()) { + append(" (") + append(locale.displayCountry) + append(")") + } + append("]") + } } - - return res } } From b4ae331086db25b09b753bb89df3c3af6f8472c2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 30 Oct 2019 19:00:00 +0100 Subject: [PATCH 027/117] Timeline: render inline and block code --- .../core/platform/MaxHeightScrollView.kt | 31 +------ .../home/room/detail/RoomDetailFragment.kt | 2 +- .../timeline/factory/MessageItemFactory.kt | 85 ++++++++++++------- .../timeline/item/MessageBlockCodeItem.kt | 18 +++- .../main/res/layout/fragment_room_detail.xml | 2 +- .../item_timeline_event_code_block_stub.xml | 54 +++++------- 6 files changed, 97 insertions(+), 95 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/MaxHeightScrollView.kt b/vector/src/main/java/im/vector/riotx/core/platform/MaxHeightScrollView.kt index fc09ad0f75..b8587750a3 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/MaxHeightScrollView.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/MaxHeightScrollView.kt @@ -16,17 +16,15 @@ package im.vector.riotx.core.platform -import android.annotation.TargetApi import android.content.Context -import android.os.Build import android.util.AttributeSet -import android.widget.ScrollView - +import androidx.core.widget.NestedScrollView import im.vector.riotx.R private const val DEFAULT_MAX_HEIGHT = 200 -class MaxHeightScrollView : ScrollView { +class MaxHeightScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) + : NestedScrollView(context, attrs, defStyle) { var maxHeight: Int = 0 set(value) { @@ -34,28 +32,7 @@ class MaxHeightScrollView : ScrollView { requestLayout() } - constructor(context: Context) : super(context) {} - - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { - if (!isInEditMode) { - init(context, attrs) - } - } - - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { - if (!isInEditMode) { - init(context, attrs) - } - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) { - if (!isInEditMode) { - init(context, attrs) - } - } - - private fun init(context: Context, attrs: AttributeSet?) { + init { if (attrs != null) { val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView) maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_maxHeight, DEFAULT_MAX_HEIGHT) 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 7c4437d6f0..9a83b331c3 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 @@ -480,7 +480,7 @@ class RoomDetailFragment : jumpToReadMarkerView.render(show, readMarkerId) } } - recyclerView.setController(timelineEventController) + recyclerView.adapter = timelineEventController.adapter recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { if (recyclerView.scrollState == RecyclerView.SCROLL_STATE_IDLE) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt index cc00ba9fb6..364d0285cc 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -99,16 +99,8 @@ class MessageItemFactory @Inject constructor( // val all = event.root.toContent() // val ev = all.toModel() return when (messageContent) { - is MessageEmoteContent -> buildEmoteMessageItem(messageContent, - informationData, - highlight, - callback, - attributes) - is MessageTextContent -> buildTextMessageItem(messageContent, - informationData, - highlight, - callback, - attributes) + is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes) is MessageImageContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes) is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes) is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes) @@ -231,29 +223,43 @@ class MessageItemFactory @Inject constructor( .clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) } } - private fun buildTextMessageItem(messageContent: MessageTextContent, + private fun buildItemForTextContent(messageContent: MessageTextContent, + informationData: MessageInformationData, + highlight: Boolean, + callback: TimelineEventController.Callback?, + attributes: AbsMessageItem.Attributes): VectorEpoxyModel<*>? { + + val isFormatted = messageContent.formattedBody.isNullOrBlank().not() + return if (isFormatted) { + val localFormattedBody = htmlRenderer.get().parse(messageContent.body) as Document + val codeVisitor = CodeVisitor() + codeVisitor.visit(localFormattedBody) + when (codeVisitor.codeKind) { + CodeVisitor.Kind.BLOCK -> { + val codeFormattedBlock = htmlRenderer.get().render(localFormattedBody) + buildCodeBlockItem(codeFormattedBlock, informationData, highlight, callback, attributes) + } + CodeVisitor.Kind.INLINE -> { + val codeFormatted = htmlRenderer.get().render(localFormattedBody) + buildMessageTextItem(codeFormatted, false, informationData, highlight, callback, attributes) + } + CodeVisitor.Kind.NONE -> { + val formattedBody = htmlRenderer.get().render(messageContent.formattedBody!!) + buildMessageTextItem(formattedBody, true, informationData, highlight, callback, attributes) + } + } + } else { + buildMessageTextItem(messageContent.body, false, informationData, highlight, callback, attributes) + } + } + + private fun buildMessageTextItem(body: CharSequence, + isFormatted: Boolean, informationData: MessageInformationData, highlight: Boolean, callback: TimelineEventController.Callback?, attributes: AbsMessageItem.Attributes): MessageTextItem? { - - val isFormatted = messageContent.formattedBody.isNullOrBlank().not() - val bodyToUse = if (isFormatted) { - val formattedBody = htmlRenderer.get().parse(messageContent.body) as Document - val codeVisitor = CodeVisitor() - codeVisitor.visit(formattedBody) - if (codeVisitor.codeKind == CodeVisitor.Kind.NONE) { - messageContent.formattedBody.let { - htmlRenderer.get().render(it!!.trim()) - } - } else { - htmlRenderer.get().render(formattedBody) - } - } else { - messageContent.body - } - - val linkifiedBody = linkifyBody(bodyToUse, callback) + val linkifiedBody = linkifyBody(body, callback) return MessageTextItem_().apply { if (informationData.hasBeenEdited) { @@ -269,7 +275,26 @@ class MessageItemFactory @Inject constructor( .attributes(attributes) .highlighted(highlight) .urlClickCallback(callback) - // click on the text + } + + private fun buildCodeBlockItem(formattedBody: CharSequence, + informationData: MessageInformationData, + highlight: Boolean, + callback: TimelineEventController.Callback?, + attributes: AbsMessageItem.Attributes): MessageBlockCodeItem? { + + + return MessageBlockCodeItem_() + .apply { + if (informationData.hasBeenEdited) { + val spannable = annotateWithEdited("", callback, informationData) + editedSpan(spannable) + } + } + .leftGuideline(avatarSizeProvider.leftGuideline) + .attributes(attributes) + .highlighted(highlight) + .message(formattedBody) } private fun annotateWithEdited(linkifiedBody: CharSequence, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt index 1ac35181ce..62042eb54d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt @@ -16,26 +16,38 @@ package im.vector.riotx.features.home.room.detail.timeline.item +import android.widget.TextView +import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R -import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController +import im.vector.riotx.core.extensions.setTextOrHide +import me.saket.bettermovementmethod.BetterLinkMovementMethod + @EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageBlockCodeItem : AbsMessageItem() { @EpoxyAttribute var message: CharSequence? = null + @EpoxyAttribute + var editedSpan: CharSequence? = null override fun bind(holder: Holder) { super.bind(holder) - + holder.messageView.text = message + renderSendState(holder.messageView, holder.messageView) + holder.messageView.setOnClickListener(attributes.itemClickListener) + holder.messageView.setOnLongClickListener(attributes.itemLongClickListener) + holder.editedView.movementMethod = BetterLinkMovementMethod.getInstance() + holder.editedView.setTextOrHide(editedSpan) } override fun getViewType() = STUB_ID class Holder : AbsMessageItem.Holder(STUB_ID) { - + val messageView by bind(R.id.codeBlockTextView) + val editedView by bind(R.id.codeBlockEditedView) } companion object { diff --git a/vector/src/main/res/layout/fragment_room_detail.xml b/vector/src/main/res/layout/fragment_room_detail.xml index ab2c40c313..6661674edb 100644 --- a/vector/src/main/res/layout/fragment_room_detail.xml +++ b/vector/src/main/res/layout/fragment_room_detail.xml @@ -86,7 +86,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/roomToolbar" /> - - + android:orientation="vertical"> - + + + + + + + android:layout_marginTop="4dp" /> - - - - - - - - - + \ No newline at end of file From 5ab31a0ef5130a579c404f6132314836e437ed80 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 30 Oct 2019 19:00:56 +0100 Subject: [PATCH 028/117] Fix klint --- .../home/room/detail/timeline/factory/MessageItemFactory.kt | 3 --- .../home/room/detail/timeline/item/MessageBlockCodeItem.kt | 2 -- .../src/main/java/im/vector/riotx/features/html/CodeVisitor.kt | 1 - .../java/im/vector/riotx/features/html/EventHtmlRenderer.kt | 1 - 4 files changed, 7 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 364d0285cc..eacd702b7d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -228,7 +228,6 @@ class MessageItemFactory @Inject constructor( highlight: Boolean, callback: TimelineEventController.Callback?, attributes: AbsMessageItem.Attributes): VectorEpoxyModel<*>? { - val isFormatted = messageContent.formattedBody.isNullOrBlank().not() return if (isFormatted) { val localFormattedBody = htmlRenderer.get().parse(messageContent.body) as Document @@ -282,8 +281,6 @@ class MessageItemFactory @Inject constructor( highlight: Boolean, callback: TimelineEventController.Callback?, attributes: AbsMessageItem.Attributes): MessageBlockCodeItem? { - - return MessageBlockCodeItem_() .apply { if (informationData.hasBeenEdited) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt index 62042eb54d..82a6a4db6f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageBlockCodeItem.kt @@ -17,14 +17,12 @@ package im.vector.riotx.features.home.room.detail.timeline.item import android.widget.TextView -import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R import im.vector.riotx.core.extensions.setTextOrHide import me.saket.bettermovementmethod.BetterLinkMovementMethod - @EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageBlockCodeItem : AbsMessageItem() { diff --git a/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt b/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt index 009d74818a..ed8db94fc3 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/CodeVisitor.kt @@ -52,5 +52,4 @@ class CodeVisitor : AbstractVisitor() { INLINE, BLOCK } - } diff --git a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt index 4e387a5b12..dc9e21e440 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt @@ -59,5 +59,4 @@ class MatrixHtmlPluginConfigure @Inject constructor(private val context: Context .addHandler(MxLinkTagHandler(GlideApp.with(context), context, avatarRenderer, session)) .addHandler(MxReplyTagHandler()) } - } From 30b2e530029d97c93dc118eeb7bb8a4bcdb545da Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 30 Oct 2019 19:02:44 +0100 Subject: [PATCH 029/117] Update CHANGES --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 50e8a8e94a..b39140aa2d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Improvements 🙌: - - + - Handle code tags (#567) Other changes: - From 101057520b279e47e3bbf1ea353689c73b242210 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 30 Oct 2019 19:25:24 +0100 Subject: [PATCH 030/117] Fix disambiguated with empty senderName --- .../session/room/timeline/TimelineEvent.kt | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt index ac3e2dea43..c05383de4e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt @@ -62,17 +62,10 @@ data class TimelineEvent( } fun getDisambiguatedDisplayName(): String { - val disambiguated = if (isUniqueDisplayName) { - senderName - } else { - senderName?.let { name -> - "$name (${root.senderId})" - } - } - return if (disambiguated.isNullOrBlank()) { - root.senderId ?: "" - } else { - disambiguated + return when { + senderName.isNullOrBlank() -> root.senderId ?: "" + isUniqueDisplayName -> senderName + else -> "$senderName (${root.senderId})" } } @@ -107,7 +100,7 @@ fun TimelineEvent.getEditedEventId(): String? { * Get last MessageContent, after a possible edition */ fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSummary?.aggregatedContent?.toModel() - ?: root.getClearContent().toModel() + ?: root.getClearContent().toModel() /** * Get last Message body, after a possible edition @@ -117,7 +110,7 @@ fun TimelineEvent.getLastMessageBody(): String? { if (lastMessageContent != null) { return lastMessageContent.newContent?.toModel()?.body - ?: lastMessageContent.body + ?: lastMessageContent.body } return null From 33e35368fce8fe1f142388c0f2ca50ea172d9994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 31 Oct 2019 06:36:28 +0100 Subject: [PATCH 031/117] a11y: better presentation for file type selector buttons to screen reader users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Vágner --- .../res/layout/view_attachment_type_selector.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/layout/view_attachment_type_selector.xml b/vector/src/main/res/layout/view_attachment_type_selector.xml index 2af86d6c0d..f713561084 100644 --- a/vector/src/main/res/layout/view_attachment_type_selector.xml +++ b/vector/src/main/res/layout/view_attachment_type_selector.xml @@ -30,10 +30,12 @@ android:id="@+id/attachmentCameraButton" style="@style/AttachmentTypeSelectorButton" android:src="@drawable/ic_attachment_camera_white_24dp" + android:contentDescription="@string/attachment_type_camera" tools:background="@color/colorAccent" /> @@ -50,10 +52,12 @@ android:id="@+id/attachmentGalleryButton" style="@style/AttachmentTypeSelectorButton" android:src="@drawable/ic_attachment_gallery_white_24dp" + android:contentDescription="@string/attachment_type_gallery" tools:background="@color/colorAccent" /> @@ -70,10 +74,12 @@ android:id="@+id/attachmentFileButton" style="@style/AttachmentTypeSelectorButton" android:src="@drawable/ic_attachment_file_white_24dp" + android:contentDescription="@string/attachment_type_file" tools:background="@color/colorAccent" /> @@ -99,10 +105,12 @@ android:id="@+id/attachmentAudioButton" style="@style/AttachmentTypeSelectorButton" android:src="@drawable/ic_attachment_audio_white_24dp" + android:contentDescription="@string/attachment_type_audio" tools:background="@color/colorAccent" /> @@ -119,10 +127,12 @@ android:id="@+id/attachmentContactButton" style="@style/AttachmentTypeSelectorButton" android:src="@drawable/ic_attachment_contact_white_24dp" + android:contentDescription="@string/attachment_type_contact" tools:background="@color/colorAccent" /> @@ -139,14 +149,16 @@ android:id="@+id/attachmentStickersButton" style="@style/AttachmentTypeSelectorButton" android:src="@drawable/ic_attachment_stickers_white_24dp" + android:contentDescription="@string/attachment_type_sticker" tools:background="@color/colorAccent" /> - \ No newline at end of file + From e355a7f6ddab9effb9d9f8e86ac7802407d638e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Thu, 31 Oct 2019 07:58:08 +0100 Subject: [PATCH 032/117] Changelog entry --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 6ebe743405..56155efc38 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Other changes: - - + - Accessibility improvements to the attachment file type chooser Bugfix 🐛: - Fix issues with some member events rendering (#498) From fb1ff77ec4c946c7a7cd3f76d26ded2becc4c75e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 31 Oct 2019 10:09:27 +0100 Subject: [PATCH 033/117] Add string from Riot-Android --- tools/import_from_riot.sh | 1 + vector/src/main/res/values-sr/strings.xml | 113 ++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 vector/src/main/res/values-sr/strings.xml diff --git a/tools/import_from_riot.sh b/tools/import_from_riot.sh index 2e4b332a3c..3f93615d19 100755 --- a/tools/import_from_riot.sh +++ b/tools/import_from_riot.sh @@ -102,6 +102,7 @@ cp ../riot-android/vector/src/main/res/values-ro/strings.xml ./vector/src cp ../riot-android/vector/src/main/res/values-ru/strings.xml ./vector/src/main/res/values-ru/strings.xml cp ../riot-android/vector/src/main/res/values-sk/strings.xml ./vector/src/main/res/values-sk/strings.xml cp ../riot-android/vector/src/main/res/values-sq/strings.xml ./vector/src/main/res/values-sq/strings.xml +cp ../riot-android/vector/src/main/res/values-sr/strings.xml ./vector/src/main/res/values-sr/strings.xml cp ../riot-android/vector/src/main/res/values-te/strings.xml ./vector/src/main/res/values-te/strings.xml cp ../riot-android/vector/src/main/res/values-th/strings.xml ./vector/src/main/res/values-th/strings.xml cp ../riot-android/vector/src/main/res/values-tlh/strings.xml ./vector/src/main/res/values-tlh/strings.xml diff --git a/vector/src/main/res/values-sr/strings.xml b/vector/src/main/res/values-sr/strings.xml new file mode 100644 index 0000000000..121589a6cd --- /dev/null +++ b/vector/src/main/res/values-sr/strings.xml @@ -0,0 +1,113 @@ + + + sr + RS + Cyrl + + Светла тема + Тамна тема + Црна тема + Status.im тема + + Иницијализација сервиса + Синхронизација у току… + Бучна обавештења + Тиха обавештења + + Поруке + Соба + Подешавања + Подаци о члану + Историјски + Пријава грешке + Пошаљи налепницу + Резервна копија кључева + Користи резервну копију кључева + Верификуј уређај + + Креирање резервне копије кључева се није завршило, молим сачекајте… + Изгубићете ваше шифроване поруке ако се сад одјавите + Креирање резервне копије кључева је у току. Ако се одјавите сад, изгубићете приступ вашим шифрованим порукама. + Сигурносна копија кључева би требало да буде активна на свим вашим уређајима како би избегли губитак приступа вашим шифрованим порукама. + Не желим моје шифроване поруке + Прављење резервне копије кључева у току… + Користи резервну копију кључева + Да ли сте сигурни\? + Изгубићете приступ вашим шифрованим порукама уколико не направите резервну копију кључева пре него што се одјавите. + + Учитавање… + + У реду + Откажи + Сачувај + Напусти + Остани + Пошаљи + Копирај + Пошаљи поново + Уклони + Подели + Прихвати + Прескочи + Готово + Обустави + Игнориши + Прегледај + Одбаци + + Изађи + Акције + Одјави се + Да ли сте сигурни да желите да се одјавите\? + Гласовни позив + Видео позив + Глобална претрага + Означи све као прочитано + Брзи одговор + Означи као прочитано + Отвори + Затвори + Онемогући + + Потврда + Упозорење + Грешка + + Омиљено + Људи + Собе + Позивнице + Низак приоритет + Разговори + Локални адресар + Листа корисника + Само Matrix контакти + Нема резултата + Нема подешених сервера идентитета. + + Собе + Листа соба + Нема соба + Пошаљи позивницу + Опишите ваш проблем овде + Прочитај + + Придружи се соби + Корисничко име + Направи налог + Пријави се + Одјави се + Пошаљи налепницу + Направи фотографију или видео снимак + Направи фотографију + Направи видео снимак + + Пријави се + Пријави се помоћу single sign-on + Направи налог + Прескочи + Адреса електронске поште или корисничко име + Лозинка + Нова лозинка + Корисничко име + From 4324f6abbd85e9474752022f218805515cfea96b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 31 Oct 2019 11:11:03 +0100 Subject: [PATCH 034/117] Add paragraph about a11y --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d64dd7110e..45834afa21 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,6 +86,10 @@ Also, if possible, please test your change on a real device. Testing on Android When adding new string resources, please only add new entries in file `value/strings.xml`. Translations will be added later by the community of translators with a specific tool named [Weblate](https://translate.riot.im/projects/riot-android/). Do not hesitate to use plurals when appropriate. +### Accessibility + +Please consider accessibility as an important point. As a minimum requirement, in layout XML files please use attributes such as `android:contentDescription` and `android:importantForAccessibility`, and test with a screen reader if it's working well. You can add new string resources, dedicated to accessibility, in this case, please prefix theirs id with `a11y_`. + ### Layout When adding or editing layouts, make sure the layout will render correctly if device uses a RTL (Right To Left) language. From 3483debcc177b22e07b7b185975f03da36445ce4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 31 Oct 2019 12:08:55 +0100 Subject: [PATCH 035/117] Little cleanup --- vector/src/main/res/layout/item_timeline_event_base.xml | 1 - .../src/main/res/layout/item_timeline_event_code_block_stub.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml index 260c309f6f..50ed0aae23 100644 --- a/vector/src/main/res/layout/item_timeline_event_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -82,7 +82,6 @@ android:id="@+id/messageContentCodeBlockStub" style="@style/TimelineContentStubBaseParams" android:layout_height="wrap_content" - android:inflatedId="@id/messageTextView" android:layout="@layout/item_timeline_event_code_block_stub" tools:visibility="visible" /> diff --git a/vector/src/main/res/layout/item_timeline_event_code_block_stub.xml b/vector/src/main/res/layout/item_timeline_event_code_block_stub.xml index 804c02940a..4738f331b1 100644 --- a/vector/src/main/res/layout/item_timeline_event_code_block_stub.xml +++ b/vector/src/main/res/layout/item_timeline_event_code_block_stub.xml @@ -13,7 +13,6 @@ android:id="@+id/codeBlockTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="4dp" android:fontFamily="monospace" android:textSize="14sp" /> From 43fd794c966cfc81bc8fd6c0e6a5c3ab53b5283a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 31 Oct 2019 15:47:40 +0100 Subject: [PATCH 036/117] Ask for permission to write external storage when uri comes from the keyboard (#658) --- CHANGES.md | 1 + .../riotx/core/utils/PermissionsTools.kt | 1 + .../home/room/detail/RoomDetailFragment.kt | 61 +++++++++++++------ .../home/room/detail/RoomDetailViewModel.kt | 3 + 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cdc9250841..37850e5bed 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Other changes: Bugfix 🐛: - Fix issues with some member events rendering (#498) - Passphrase does not match (Export room keys) (#644) + - Ask for permission to write external storage when uri comes from the keyboard (#658) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt index 8f97ef0247..f8cdeb3de6 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/PermissionsTools.kt @@ -67,6 +67,7 @@ const val PERMISSION_REQUEST_CODE_EXPORT_KEYS = 573 const val PERMISSION_REQUEST_CODE_CHANGE_AVATAR = 574 const val PERMISSION_REQUEST_CODE_DOWNLOAD_FILE = 575 const val PERMISSION_REQUEST_CODE_PICK_ATTACHMENT = 576 +const val PERMISSION_REQUEST_CODE_INCOMING_URI = 577 /** * Log the used permissions statuses. 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 3c6625feeb..76d01228b8 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 @@ -81,8 +81,6 @@ import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.JumpToReadMarkerView import im.vector.riotx.core.ui.views.NotificationAreaView import im.vector.riotx.core.utils.* -import im.vector.riotx.core.utils.Debouncer -import im.vector.riotx.core.utils.createUIHandler import im.vector.riotx.features.attachments.AttachmentTypeSelectorView import im.vector.riotx.features.attachments.AttachmentsHelper import im.vector.riotx.features.attachments.ContactAttachment @@ -619,19 +617,27 @@ class RoomDetailFragment : } composerLayout.callback = object : TextComposerView.Callback { override fun onRichContentSelected(contentUri: Uri): Boolean { - val shareIntent = Intent().apply { - action = Intent.ACTION_SEND - data = contentUri + // We need WRITE_EXTERNAL permission + return if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this@RoomDetailFragment, PERMISSION_REQUEST_CODE_INCOMING_URI)) { + sendUri(contentUri) + } else { + roomDetailViewModel.pendingUri = contentUri + // Always intercept when we request some permission + true } - val isHandled = attachmentsHelper.handleShareIntent(shareIntent) - if (!isHandled) { - Toast.makeText(requireContext(), R.string.error_handling_incoming_share, Toast.LENGTH_SHORT).show() - } - return isHandled } } } + private fun sendUri(uri: Uri): Boolean { + val shareIntent = Intent(Intent.ACTION_SEND, uri) + val isHandled = attachmentsHelper.handleShareIntent(shareIntent) + if (!isHandled) { + Toast.makeText(requireContext(), R.string.error_handling_incoming_share, Toast.LENGTH_SHORT).show() + } + return isHandled + } + private fun setupAttachmentButton() { composerLayout.attachmentButton.setOnClickListener { if (!::attachmentTypeSelector.isInitialized) { @@ -906,19 +912,34 @@ class RoomDetailFragment : override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { if (allGranted(grantResults)) { - if (requestCode == PERMISSION_REQUEST_CODE_DOWNLOAD_FILE) { - val action = roomDetailViewModel.pendingAction - if (action != null) { - roomDetailViewModel.pendingAction = null - roomDetailViewModel.process(action) + when (requestCode) { + PERMISSION_REQUEST_CODE_DOWNLOAD_FILE -> { + val action = roomDetailViewModel.pendingAction + if (action != null) { + roomDetailViewModel.pendingAction = null + roomDetailViewModel.process(action) + } } - } else if (requestCode == PERMISSION_REQUEST_CODE_PICK_ATTACHMENT) { - val pendingType = attachmentsHelper.pendingType - if (pendingType != null) { - attachmentsHelper.pendingType = null - launchAttachmentProcess(pendingType) + PERMISSION_REQUEST_CODE_INCOMING_URI -> { + val pendingUri = roomDetailViewModel.pendingUri + if (pendingUri != null) { + roomDetailViewModel.pendingUri = null + sendUri(pendingUri) + } + } + PERMISSION_REQUEST_CODE_PICK_ATTACHMENT -> { + val pendingType = attachmentsHelper.pendingType + if (pendingType != null) { + attachmentsHelper.pendingType = null + launchAttachmentProcess(pendingType) + } } } + } else { + // Reset all pending data + roomDetailViewModel.pendingAction = null + roomDetailViewModel.pendingUri = null + attachmentsHelper.pendingType = null } } 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 f3934f618c..b1c6aa02fb 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 @@ -16,6 +16,7 @@ package im.vector.riotx.features.home.room.detail +import android.net.Uri import androidx.annotation.IdRes import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -95,6 +96,8 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro // Slot to keep a pending action during permission request var pendingAction: RoomDetailActions? = null + // Slot to keep a pending uri during permission request + var pendingUri: Uri? = null @AssistedInject.Factory interface Factory { From 73267442bbdf2cee53d7d7f07b507782c7ac96f2 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 1 Nov 2019 11:28:27 +0100 Subject: [PATCH 037/117] Fix / remove listener --- .../reactions/EmojiSearchResultController.kt | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt index 82f8cdf3be..3e8f1c9769 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultController.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.reactions import android.graphics.Typeface +import androidx.recyclerview.widget.RecyclerView import com.airbnb.epoxy.TypedEpoxyController import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.R @@ -24,17 +25,19 @@ import im.vector.riotx.core.ui.list.genericFooterItem import javax.inject.Inject class EmojiSearchResultController @Inject constructor(val stringProvider: StringProvider, - fontProvider: EmojiCompatFontProvider) + private val fontProvider: EmojiCompatFontProvider) : TypedEpoxyController() { var emojiTypeface: Typeface? = fontProvider.typeface + private val fontProviderListener = object : EmojiCompatFontProvider.FontProviderListener { + override fun compatibilityFontUpdate(typeface: Typeface?) { + emojiTypeface = typeface + } + } + init { - fontProvider.addListener(object : EmojiCompatFontProvider.FontProviderListener { - override fun compatibilityFontUpdate(typeface: Typeface?) { - emojiTypeface = typeface - } - }) + fontProvider.addListener(fontProviderListener) } var listener: ReactionClickListener? = null @@ -69,4 +72,9 @@ class EmojiSearchResultController @Inject constructor(val stringProvider: String } } } + + override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) { + super.onDetachedFromRecyclerView(recyclerView) + fontProvider.removeListener(fontProviderListener) + } } From 151ad0103851988d546470d167f7ea819c9c0b9a Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 1 Nov 2019 11:57:15 +0100 Subject: [PATCH 038/117] Use RxBinding on searchView --- .../reactions/EmojiReactionPickerActivity.kt | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) 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 a0acd7b5e8..a442f5f77e 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 @@ -31,12 +31,12 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.viewModel import com.google.android.material.tabs.TabLayout +import com.jakewharton.rxbinding3.widget.queryTextChanges import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.VectorBaseActivity -import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.android.synthetic.main.activity_emoji_reaction_picker.* import timber.log.Timber @@ -169,31 +169,15 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), } }) - val searchObservable = Observable.create { emitter -> - - searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { - override fun onQueryTextSubmit(query: String?): Boolean { - query?.let { emitter.onNext(it) } - return true - } - - override fun onQueryTextChange(newText: String?): Boolean { - Timber.d("onQueryTextChange $newText") - newText?.let { emitter.onNext(it) } - return true - } - }) - } - - searchObservable + searchView.queryTextChanges() .throttleWithTimeout(600, TimeUnit.MILLISECONDS) .doOnError { err -> Timber.e(err) } .observeOn(AndroidSchedulers.mainThread()) .subscribe { query -> - onQueryText(query) + onQueryText(query.toString()) } + .disposeOnDestroy() } - return true } From 8030c44f4441774a25fcfaa52e12c7141d2d6d65 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 4 Nov 2019 14:31:03 +0100 Subject: [PATCH 039/117] Room list actions: fix some UI issues and render selected notification state --- .../bottomsheet/BottomSheetItemAction.kt | 31 +++++++--- .../home/room/list/RoomListFragment.kt | 2 +- .../RoomListQuickActionsEpoxyController.kt | 22 ++++++-- .../main/res/drawable/ic_check_white_24dp.xml | 4 ++ .../res/layout/item_bottom_sheet_action.xml | 56 +++++++++++++------ 5 files changed, 84 insertions(+), 31 deletions(-) create mode 100644 vector/src/main/res/drawable/ic_check_white_24dp.xml diff --git a/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt index 1099243ace..3dd760a520 100644 --- a/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt @@ -20,12 +20,17 @@ import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.annotation.DrawableRes +import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.DrawableCompat +import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel +import im.vector.riotx.core.resources.ColorProvider +import im.vector.riotx.features.themes.ThemeUtils /** * A action for bottom sheet. @@ -43,6 +48,8 @@ abstract class BottomSheetItemAction : VectorEpoxyModel(R.id.action_start_space) - val icon by bind(R.id.action_icon) - val text by bind(R.id.action_title) - val expand by bind(R.id.action_expand) + val startSpace by bind(R.id.actionStartSpace) + val icon by bind(R.id.actionIcon) + val text by bind(R.id.actionTitle) + val selected by bind(R.id.actionSelected) } } 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 3eb9f99f75..bcd640589c 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 @@ -230,7 +230,7 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MUTE)) } is RoomListQuickActions.Settings -> { - navigator.openRoomSettings(requireContext(), quickActions.roomId) + vectorBaseActivity.notImplemented("Opening room settings") } is RoomListQuickActions.Leave -> { roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index f2c71868df..63b68b4c17 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -17,6 +17,7 @@ package im.vector.riotx.features.home.room.list.actions import android.view.View import com.airbnb.epoxy.TypedEpoxyController +import im.vector.matrix.android.api.session.room.notification.RoomNotificationState import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.core.date.VectorDateFormatter import im.vector.riotx.core.epoxy.bottomsheet.BottomSheetItemAction_ @@ -53,10 +54,12 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val string bottomSheetItemSeparator { id("notifications_separator") } - RoomListQuickActions.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0) - RoomListQuickActions.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1) - RoomListQuickActions.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2) - RoomListQuickActions.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3) + + val selectedRoomState = state.roomNotificationState() + RoomListQuickActions.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) + RoomListQuickActions.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) + RoomListQuickActions.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) + RoomListQuickActions.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) // Leave bottomSheetItemSeparator { @@ -65,9 +68,18 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val string RoomListQuickActions.Leave(roomSummary.roomId).toBottomSheetItem(5) } - private fun RoomListQuickActions.toBottomSheetItem(index: Int) { + private fun RoomListQuickActions.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { + val selected = when (this) { + is RoomListQuickActions.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY + is RoomListQuickActions.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES + is RoomListQuickActions.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY + is RoomListQuickActions.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE + is RoomListQuickActions.Settings, + is RoomListQuickActions.Leave -> false + } return BottomSheetItemAction_() .id("action_$index") + .selected(selected) .iconRes(iconResId) .textRes(titleRes) .listener(View.OnClickListener { listener?.didSelectMenuAction(this) }) diff --git a/vector/src/main/res/drawable/ic_check_white_24dp.xml b/vector/src/main/res/drawable/ic_check_white_24dp.xml new file mode 100644 index 0000000000..0aedb18ddd --- /dev/null +++ b/vector/src/main/res/drawable/ic_check_white_24dp.xml @@ -0,0 +1,4 @@ + + + + diff --git a/vector/src/main/res/layout/item_bottom_sheet_action.xml b/vector/src/main/res/layout/item_bottom_sheet_action.xml index 131ee0e63c..0ad7a211da 100644 --- a/vector/src/main/res/layout/item_bottom_sheet_action.xml +++ b/vector/src/main/res/layout/item_bottom_sheet_action.xml @@ -1,52 +1,72 @@ - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/actionStartSpace" + app:layout_constraintTop_toTopOf="parent" + tools:src="@drawable/ic_room_actions_notifications_all" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/actionSelected" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toEndOf="@id/actionStartSpace" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_default="wrap" + tools:text="zbla azjazjaz s sdkqdskdsqk kqsdkdqsk kdqsksqdk" /> + - + + From 6ebe5532c5e20ef6016fd955be23a9d9c22a58a3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 4 Nov 2019 14:59:12 +0100 Subject: [PATCH 040/117] Room list actions: use new strings --- .../home/room/list/actions/RoomListQuickActions.kt | 12 ++++++------ .../res/layout/item_bottom_sheet_room_preview.xml | 2 ++ vector/src/main/res/values/strings_riotX.xml | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt index 30d4abff36..c0c77e0319 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt @@ -21,12 +21,12 @@ import androidx.annotation.StringRes import im.vector.riotx.R sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { - data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions(R.string.room_settings_all_messages_noisy, R.drawable.ic_room_actions_notifications_all_noisy) - data class NotificationsAll(val roomId: String) : RoomListQuickActions(R.string.room_settings_all_messages, R.drawable.ic_room_actions_notifications_all) - data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActions(R.string.room_settings_mention_only, R.drawable.ic_room_actions_notifications_mentions) - data class NotificationsMute(val roomId: String) : RoomListQuickActions(R.string.room_settings_mute, R.drawable.ic_room_actions_notifications_mutes) - data class Settings(val roomId: String) : RoomListQuickActions(R.string.room_sliding_menu_settings, R.drawable.ic_room_actions_settings) - data class Leave(val roomId: String) : RoomListQuickActions(R.string.leave, R.drawable.ic_room_actions_leave) + data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_all_noisy, R.drawable.ic_room_actions_notifications_all_noisy) + data class NotificationsAll(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_all, R.drawable.ic_room_actions_notifications_all) + data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_mentions, R.drawable.ic_room_actions_notifications_mentions) + data class NotificationsMute(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_mute, R.drawable.ic_room_actions_notifications_mutes) + data class Settings(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_settings, R.drawable.ic_room_actions_settings) + data class Leave(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_leave, R.drawable.ic_room_actions_leave) companion object { fun all(roomId: String): List { diff --git a/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml b/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml index 410e6ea1ab..1a38feface 100644 --- a/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml +++ b/vector/src/main/res/layout/item_bottom_sheet_room_preview.xml @@ -16,6 +16,7 @@ android:layout_marginBottom="8dp" android:adjustViewBounds="true" android:background="@drawable/circle" + android:importantForAccessibility="no" android:contentDescription="@string/avatar" android:scaleType="centerCrop" app:layout_constraintBottom_toBottomOf="parent" @@ -50,6 +51,7 @@ android:background="?attr/selectableItemBackground" android:scaleType="centerInside" android:src="@drawable/ic_room_actions_settings" + android:contentDescription="@string/room_list_quick_actions_settings" app:layout_constraintBottom_toBottomOf="@+id/bottomSheetRoomPreviewAvatar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/bottomSheetRoomPreviewAvatar" /> diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 9b12db5e7f..c627d40eb0 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -6,7 +6,7 @@ "All messages" "Mentions only" "Mute" - "Settings" - "Leave" + "Settings" + "Leave the room" From 5c71cabb5fef560e329ae47166694750ecd2b33a Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 4 Nov 2019 15:08:08 +0100 Subject: [PATCH 041/117] Clean code --- CHANGES.md | 1 + .../matrix/android/api/pushrules/Action.kt | 1 - .../room/notification/RoomPushRuleService.kt | 1 - .../internal/database/query/PushersQueries.kt | 1 - .../internal/session/room/RoomFactory.kt | 1 - .../DefaultRoomPushRuleService.kt | 1 - .../room/notification/RoomPushRuleMapper.kt | 1 - .../vector/riotx/core/di/ViewModelModule.kt | 4 -- .../bottomsheet/BottomSheetItemAction.kt | 1 - .../riotx/core/platform/VectorViewModel.kt | 1 - .../riotx/features/home/HomeActivity.kt | 1 - .../createdirect/CreateDirectRoomActivity.kt | 1 - .../room/list/actions/RoomListQuickActions.kt | 37 +++++++++++++++---- .../RoomListQuickActionsBottomSheet.kt | 5 +-- .../RoomListQuickActionsEpoxyController.kt | 3 +- .../list/actions/RoomListQuickActionsState.kt | 1 - .../actions/RoomListQuickActionsViewModel.kt | 19 +++------- .../features/navigation/DefaultNavigator.kt | 1 - .../riotx/features/navigation/Navigator.kt | 1 - .../roomdirectory/RoomDirectoryActivity.kt | 1 - .../createroom/CreateRoomActivity.kt | 1 - 21 files changed, 40 insertions(+), 44 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8d536dbd97..c52ad4af0d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Improvements: - Mark all messages as read (#396) - Add ability to report content (#515) + Other changes: - Accessibility improvements to read receipts in the room timeline and reactions emoji chooser diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt index d1e5b3c868..a81af2cf21 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/Action.kt @@ -86,7 +86,6 @@ fun List.toJson(): List { } } - fun PushRule.getActions(): List { val result = ArrayList() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt index 7b3e88240b..41cd484ef9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/notification/RoomPushRuleService.kt @@ -25,5 +25,4 @@ interface RoomPushRuleService { fun getLiveRoomNotificationState(): LiveData fun setRoomNotificationState(roomNotificationState: RoomNotificationState, matrixCallback: MatrixCallback): Cancelable - } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt index a97ed8d415..42e7770114 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/PushersQueries.kt @@ -49,4 +49,3 @@ internal fun PushRuleEntity.Companion.where(realm: Realm, .equalTo("${PushRuleEntityFields.PARENT}.${PushRulesEntityFields.SCOPE}", scope) .equalTo(PushRuleEntityFields.RULE_ID, ruleId) } - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt index 2c441762dd..30a2948f68 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt @@ -19,7 +19,6 @@ package im.vector.matrix.android.internal.session.room import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.room.Room -import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper import im.vector.matrix.android.internal.session.room.draft.DefaultDraftService import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt index a27cdb1007..7cb7452244 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/DefaultRoomPushRuleService.kt @@ -69,5 +69,4 @@ internal class DefaultRoomPushRuleService @AssistedInject constructor(@Assisted results.firstOrNull() } } - } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt index 159eb511ee..d08d346a1f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/notification/RoomPushRuleMapper.kt @@ -99,4 +99,3 @@ internal fun RoomPushRule.toRoomNotificationState(): RoomNotificationState { RoomNotificationState.ALL_MESSAGES } } - diff --git a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt index 83aa7103d9..d2b8abb9c4 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt @@ -27,10 +27,7 @@ import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromP import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel import im.vector.riotx.features.crypto.verification.SasVerificationViewModel -import im.vector.riotx.features.home.HomeNavigationViewModel -import im.vector.riotx.features.home.createdirect.CreateDirectRoomNavigationViewModel import im.vector.riotx.features.reactions.EmojiChooserViewModel -import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel import im.vector.riotx.features.workers.signout.SignOutViewModel @Module @@ -85,5 +82,4 @@ interface ViewModelModule { @IntoMap @ViewModelKey(ConfigurationViewModel::class) fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel - } diff --git a/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt index 3dd760a520..e0299f4e65 100644 --- a/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt @@ -29,7 +29,6 @@ import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel -import im.vector.riotx.core.resources.ColorProvider import im.vector.riotx.features.themes.ThemeUtils /** 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 7f04f184a8..9679c20efb 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 @@ -44,5 +44,4 @@ abstract class VectorViewModel(initialState: S) .onErrorReturn { Fail(it) } .doOnNext { setState { stateReducer(it) } } } - } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index e552af0095..01f869c82a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -31,7 +31,6 @@ import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.hideKeyboard -import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index 2b4322a87c..c4e7855c14 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -31,7 +31,6 @@ import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.extensions.addFragmentToBackstack -import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.SimpleFragmentActivity import im.vector.riotx.core.platform.WaitingViewData import kotlinx.android.synthetic.main.activity.* diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt index c0c77e0319..e89b4ebcd0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt @@ -21,12 +21,36 @@ import androidx.annotation.StringRes import im.vector.riotx.R sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { - data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_all_noisy, R.drawable.ic_room_actions_notifications_all_noisy) - data class NotificationsAll(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_all, R.drawable.ic_room_actions_notifications_all) - data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_mentions, R.drawable.ic_room_actions_notifications_mentions) - data class NotificationsMute(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_notifications_mute, R.drawable.ic_room_actions_notifications_mutes) - data class Settings(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_settings, R.drawable.ic_room_actions_settings) - data class Leave(val roomId: String) : RoomListQuickActions(R.string.room_list_quick_actions_leave, R.drawable.ic_room_actions_leave) + + data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions( + R.string.room_list_quick_actions_notifications_all_noisy, + R.drawable.ic_room_actions_notifications_all_noisy + ) + + data class NotificationsAll(val roomId: String) : RoomListQuickActions( + R.string.room_list_quick_actions_notifications_all, + R.drawable.ic_room_actions_notifications_all + ) + + data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActions( + R.string.room_list_quick_actions_notifications_mentions, + R.drawable.ic_room_actions_notifications_mentions + ) + + data class NotificationsMute(val roomId: String) : RoomListQuickActions( + R.string.room_list_quick_actions_notifications_mute, + R.drawable.ic_room_actions_notifications_mutes + ) + + data class Settings(val roomId: String) : RoomListQuickActions( + R.string.room_list_quick_actions_settings, + R.drawable.ic_room_actions_settings + ) + + data class Leave(val roomId: String) : RoomListQuickActions( + R.string.room_list_quick_actions_leave, + R.drawable.ic_room_actions_leave + ) companion object { fun all(roomId: String): List { @@ -40,5 +64,4 @@ sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val ) } } - } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 03e661eb20..560c05771c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -46,11 +46,11 @@ data class RoomListActionsArgs( class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { private lateinit var actionsDispatcher: RoomListQuickActionsStore - @Inject lateinit var roomListActionsViewModelFactory: RoomListActionsViewModel.Factory + @Inject lateinit var roomListActionsViewModelFactory: RoomListQuickActionsViewModel.Factory @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController @Inject lateinit var navigator: Navigator - private val viewModel: RoomListActionsViewModel by fragmentViewModel(RoomListActionsViewModel::class) + private val viewModel: RoomListQuickActionsViewModel by fragmentViewModel(RoomListQuickActionsViewModel::class) @BindView(R.id.bottomSheetRecyclerView) lateinit var recyclerView: RecyclerView @@ -77,7 +77,6 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R roomListActionsEpoxyController.listener = this } - override fun invalidate() = withState(viewModel) { roomListActionsEpoxyController.setData(it) super.invalidate() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index 63b68b4c17..cc6abc42b1 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -33,7 +33,8 @@ import javax.inject.Inject class RoomListQuickActionsEpoxyController @Inject constructor(private val stringProvider: StringProvider, private val avatarRenderer: AvatarRenderer, private val dateFormatter: VectorDateFormatter, - private val fontProvider: EmojiCompatFontProvider) : TypedEpoxyController() { + private val fontProvider: EmojiCompatFontProvider) + : TypedEpoxyController() { var listener: Listener? = null diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt index e8e40c30e2..a943db1804 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsState.kt @@ -29,5 +29,4 @@ data class RoomListQuickActionsState( ) : MvRxState { constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) - } 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 422a1097f2..0eeef64a78 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 @@ -18,30 +18,23 @@ package im.vector.riotx.features.home.room.list.actions import com.airbnb.mvrx.* import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject -import dagger.Lazy -import im.vector.matrix.android.api.MatrixCallback 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.VectorViewModel -import im.vector.riotx.core.resources.StringProvider -import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter -import im.vector.riotx.features.html.EventHtmlRenderer -import timber.log.Timber -class RoomListActionsViewModel @AssistedInject constructor(@Assisted - initialState: RoomListQuickActionsState, - session: Session +class RoomListQuickActionsViewModel @AssistedInject constructor(@Assisted initialState: RoomListQuickActionsState, + session: Session ) : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { - fun create(initialState: RoomListQuickActionsState): RoomListActionsViewModel + fun create(initialState: RoomListQuickActionsState): RoomListQuickActionsViewModel } - companion object : MvRxViewModelFactory { + companion object : MvRxViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: RoomListQuickActionsState): RoomListActionsViewModel? { + override fun create(viewModelContext: ViewModelContext, state: RoomListQuickActionsState): RoomListQuickActionsViewModel? { val fragment: RoomListQuickActionsBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() return fragment.roomListActionsViewModelFactory.create(state) } @@ -72,6 +65,4 @@ class RoomListActionsViewModel @AssistedInject constructor(@Assisted copy(roomSummary = it) } } - - } diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt index f0958b5b35..685fa04fef 100644 --- a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt @@ -115,6 +115,5 @@ class DefaultNavigator @Inject constructor() : Navigator { override fun openRoomSettings(context: Context, roomId: String) { Timber.v("Open room settings$roomId") - } } diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt index 8bd5f520c1..83c4f7ce20 100644 --- a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt @@ -52,5 +52,4 @@ interface Navigator { fun openUserDetail(userId: String, context: Context) fun openRoomSettings(context: Context, roomId: String) - } 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 e8914970ff..43894aa244 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 @@ -25,7 +25,6 @@ import im.vector.riotx.R 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.extensions.observeEvent import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.createroom.CreateRoomViewModel 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 00bd42901a..20843f86cb 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 @@ -25,7 +25,6 @@ import com.airbnb.mvrx.viewModel import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.addFragment -import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity From e66766f41ceb8ed4f3125f35b5c5dfd829162fa9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 4 Nov 2019 15:12:30 +0100 Subject: [PATCH 042/117] Update CHANGES --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 1a29b77427..c53dc349d2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ Changes in RiotX 0.8.0 (2019-XX-XX) =================================================== Features ✨: - - + - Handle long click on room in the room list (#395) Improvements 🙌: - Handle code tags (#567) From e976055253fc21fdc5c01362f7f749b323e9cc0a Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 28 Oct 2019 18:33:15 +0100 Subject: [PATCH 043/117] Support spoilers in messages --- CHANGES.md | 1 + .../detail/timeline/item/MessageTextItem.kt | 21 ++++++--- .../vector/riotx/features/html/SpoilerSpan.kt | 44 +++++++++++++++++++ 3 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt diff --git a/CHANGES.md b/CHANGES.md index 4a7c0c8fdf..093d2c0b86 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Features ✨: Improvements 🙌: - Search reaction by name or keyword in emoji picker - Handle code tags (#567) + - Support spoiler messages Other changes: - Markdown set to off by default (#412) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt index 564adc50f2..e43503aad8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt @@ -31,6 +31,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.saket.bettermovementmethod.BetterLinkMovementMethod +import java.net.URL @EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageTextItem : AbsMessageItem() { @@ -49,15 +50,25 @@ abstract class MessageTextItem : AbsMessageItem() { private val mvmtMethod = BetterLinkMovementMethod.newInstance().also { it.setOnLinkClickListener { _, url -> // Return false to let android manage the click on the link, or true if the link is handled by the application - urlClickCallback?.onUrlClicked(url) == true + try { + (URL(url)) + urlClickCallback?.onUrlClicked(url) == true + } catch (t: Throwable) { + false + } } // We need also to fix the case when long click on link will trigger long click on cell it.setOnLinkLongClickListener { tv, url -> // Long clicks are handled by parent, return true to block android to do something with url - if (urlClickCallback?.onUrlLongClicked(url) == true) { - tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0)) - true - } else { + try { + (URL(url)) + if (urlClickCallback?.onUrlLongClicked(url) == true) { + tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0)) + true + } else { + false + } + } catch (t: Throwable) { false } } diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt new file mode 100644 index 0000000000..f57984c4af --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt @@ -0,0 +1,44 @@ +/* + * 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.html + +import android.content.Context +import android.graphics.Color +import android.text.TextPaint +import android.text.style.ClickableSpan +import android.view.View +import im.vector.riotx.R +import im.vector.riotx.features.themes.ThemeUtils + +class SpoilerSpan(val bgColor: Int, val context: Context) : ClickableSpan() { + + override fun onClick(widget: View) { + isHidden = !isHidden + widget.invalidate() + } + + var isHidden = true + + override fun updateDrawState(tp: TextPaint) { + tp.bgColor = bgColor + if (isHidden) { + tp.color = Color.TRANSPARENT + } else { + tp.color = ThemeUtils.getColor(context, R.attr.riotx_text_primary) + } + } +} From 42e0d0f7696fb7070d43e4cdca55eb3348e37d05 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 15:35:15 +0100 Subject: [PATCH 044/117] Improve code to check url validity --- .../im/vector/riotx/core/utils/UrlUtils.kt | 28 +++++++++++++++++++ .../detail/timeline/item/MessageTextItem.kt | 22 ++++----------- 2 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/core/utils/UrlUtils.kt diff --git a/vector/src/main/java/im/vector/riotx/core/utils/UrlUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/UrlUtils.kt new file mode 100644 index 0000000000..3de555f66e --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/utils/UrlUtils.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.core.utils + +import java.net.URL + +fun String.isValidUrl(): Boolean { + return try { + URL(this) + true + } catch (t: Throwable) { + false + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt index e43503aad8..45a6e2e743 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt @@ -24,6 +24,7 @@ import androidx.core.widget.TextViewCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R +import im.vector.riotx.core.utils.isValidUrl import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.html.PillImageSpan import kotlinx.coroutines.Dispatchers @@ -31,7 +32,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.saket.bettermovementmethod.BetterLinkMovementMethod -import java.net.URL @EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageTextItem : AbsMessageItem() { @@ -50,25 +50,15 @@ abstract class MessageTextItem : AbsMessageItem() { private val mvmtMethod = BetterLinkMovementMethod.newInstance().also { it.setOnLinkClickListener { _, url -> // Return false to let android manage the click on the link, or true if the link is handled by the application - try { - (URL(url)) - urlClickCallback?.onUrlClicked(url) == true - } catch (t: Throwable) { - false - } + url.isValidUrl() && urlClickCallback?.onUrlClicked(url) == true } // We need also to fix the case when long click on link will trigger long click on cell it.setOnLinkLongClickListener { tv, url -> // Long clicks are handled by parent, return true to block android to do something with url - try { - (URL(url)) - if (urlClickCallback?.onUrlLongClicked(url) == true) { - tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0)) - true - } else { - false - } - } catch (t: Throwable) { + if (url.isValidUrl() && urlClickCallback?.onUrlLongClicked(url) == true) { + tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0)) + true + } else { false } } From 86667a6d8aa755e1e75d10a18e06bc1440a76d84 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 29 Oct 2019 15:51:18 +0100 Subject: [PATCH 045/117] Passes text color instead of context --- .../java/im/vector/riotx/features/html/SpoilerSpan.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt index f57984c4af..7dd76dd71b 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt @@ -16,29 +16,26 @@ package im.vector.riotx.features.html -import android.content.Context import android.graphics.Color import android.text.TextPaint import android.text.style.ClickableSpan import android.view.View -import im.vector.riotx.R -import im.vector.riotx.features.themes.ThemeUtils -class SpoilerSpan(val bgColor: Int, val context: Context) : ClickableSpan() { +class SpoilerSpan(private val bgColor: Int, private val textColor: Int) : ClickableSpan() { override fun onClick(widget: View) { isHidden = !isHidden widget.invalidate() } - var isHidden = true + private var isHidden = true override fun updateDrawState(tp: TextPaint) { tp.bgColor = bgColor if (isHidden) { tp.color = Color.TRANSPARENT } else { - tp.color = ThemeUtils.getColor(context, R.attr.riotx_text_primary) + tp.color = textColor } } } From 24f1262005b51963deb9c50746d42ab0170b5ef9 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 1 Nov 2019 12:34:22 +0100 Subject: [PATCH 046/117] Merge refactoring --- .../riotx/features/html/EventHtmlRenderer.kt | 1 + .../vector/riotx/features/html/SpanHandler.kt | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt diff --git a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt index dc9e21e440..136d667c44 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt @@ -58,5 +58,6 @@ class MatrixHtmlPluginConfigure @Inject constructor(private val context: Context .addHandler(FontTagHandler()) .addHandler(MxLinkTagHandler(GlideApp.with(context), context, avatarRenderer, session)) .addHandler(MxReplyTagHandler()) + .addHandler(SpanHandler(context)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt b/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt new file mode 100644 index 0000000000..33d8f87271 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt @@ -0,0 +1,48 @@ +/* + * 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.html + +import android.content.Context +import im.vector.riotx.R +import im.vector.riotx.features.themes.ThemeUtils +import io.noties.markwon.MarkwonVisitor +import io.noties.markwon.SpannableBuilder +import io.noties.markwon.html.HtmlTag +import io.noties.markwon.html.MarkwonHtmlRenderer +import io.noties.markwon.html.TagHandler + +class SpanHandler(context: Context) : TagHandler() { + + override fun supportedTags() = listOf("span") + + private val spoilerBgColor: Int = ThemeUtils.getColor(context, R.attr.vctr_markdown_block_background_color) + + private val textColor: Int = ThemeUtils.getColor(context, R.attr.riotx_text_primary) + + override fun handle(visitor: MarkwonVisitor, renderer: MarkwonHtmlRenderer, tag: HtmlTag) { + val mxSpoiler = tag.attributes()["data-mx-spoiler"] + if (mxSpoiler != null) { + SpannableBuilder.setSpans( + visitor.builder(), + SpoilerSpan(spoilerBgColor, textColor), + tag.start(), + tag.end() + ) + } else { + // default thing? + } + } +} From 3c4c0ed46acd853f717b81f226efb9574c57c2bf Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 1 Nov 2019 12:37:33 +0100 Subject: [PATCH 047/117] Add /spoiler command --- .../java/im/vector/riotx/features/command/Command.kt | 3 ++- .../im/vector/riotx/features/command/CommandParser.kt | 5 +++++ .../im/vector/riotx/features/command/ParsedCommand.kt | 1 + .../features/home/room/detail/RoomDetailViewModel.kt | 10 ++++++++++ vector/src/main/res/values/strings.xml | 2 ++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/riotx/features/command/Command.kt b/vector/src/main/java/im/vector/riotx/features/command/Command.kt index 2d4cecdf26..7d745b925b 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/Command.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/Command.kt @@ -37,5 +37,6 @@ enum class Command(val command: String, val parameters: String, @StringRes val d KICK_USER("/kick", " [reason]", R.string.command_description_kick_user), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick), MARKDOWN("/markdown", "", R.string.command_description_markdown), - CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token); + CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token), + SPOILER("/spoiler", "", R.string.command_description_spoiler); } diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index 9cf6510fdb..d108f56f5a 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -207,6 +207,11 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } + Command.SPOILER.command -> { + val message = textMessage.substring(Command.SPOILER.command.length).trim() + + return ParsedCommand.SendSpoiler(message) + } else -> { // Unknown command return ParsedCommand.ErrorUnknownSlashCommand(slashCommand) diff --git a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt index f6bbed2889..02f5abe540 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt @@ -45,4 +45,5 @@ sealed class ParsedCommand { class ChangeDisplayName(val displayName: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() + class SendSpoiler(val message: String) : ParsedCommand() } 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 b1c6aa02fb..2436b7a8b4 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 @@ -49,6 +49,7 @@ import im.vector.riotx.BuildConfig import im.vector.riotx.R import im.vector.riotx.core.extensions.postLiveEvent import im.vector.riotx.core.platform.VectorViewModel +import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.core.resources.UserPreferencesProvider import im.vector.riotx.core.utils.LiveEvent import im.vector.riotx.core.utils.subscribeLogError @@ -66,6 +67,7 @@ import java.util.concurrent.TimeUnit class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: RoomDetailViewState, userPreferencesProvider: UserPreferencesProvider, private val vectorPreferences: VectorPreferences, + private val stringProvider: StringProvider, private val session: Session ) : VectorViewModel(initialState) { @@ -327,6 +329,14 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled()) popDraft() } + is ParsedCommand.SendSpoiler -> { + room.sendFormattedTextMessage( + "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})", + "${slashCommandResult.message}" + ) + _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled()) + popDraft() + } is ParsedCommand.ChangeTopic -> { handleChangeTopicSlashCommand(slashCommandResult) popDraft() diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index eb1eaf1368..be0d97c147 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1168,6 +1168,8 @@ Changes your display nickname On/Off markdown To fix Matrix Apps management + Sends the given message as a spoiler + Spoiler Markdown has been enabled. Markdown has been disabled. From b3233d3eb7e5b468b37bf05945147889095caef0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Nov 2019 16:46:30 +0100 Subject: [PATCH 048/117] Change spoiler bg colors --- .../main/java/im/vector/riotx/features/html/SpanHandler.kt | 5 +++-- .../main/java/im/vector/riotx/features/html/SpoilerSpan.kt | 7 +++++-- vector/src/main/res/values/attrs.xml | 1 + vector/src/main/res/values/theme_dark.xml | 1 + vector/src/main/res/values/theme_light.xml | 1 + 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt b/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt index 33d8f87271..dbc09cf0a9 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt @@ -28,7 +28,8 @@ class SpanHandler(context: Context) : TagHandler() { override fun supportedTags() = listOf("span") - private val spoilerBgColor: Int = ThemeUtils.getColor(context, R.attr.vctr_markdown_block_background_color) + private val spoilerBgColorHidden: Int = ThemeUtils.getColor(context, R.attr.vctr_spoiler_background_color) + private val spoilerBgColorRevealed: Int = ThemeUtils.getColor(context, R.attr.vctr_markdown_block_background_color) private val textColor: Int = ThemeUtils.getColor(context, R.attr.riotx_text_primary) @@ -37,7 +38,7 @@ class SpanHandler(context: Context) : TagHandler() { if (mxSpoiler != null) { SpannableBuilder.setSpans( visitor.builder(), - SpoilerSpan(spoilerBgColor, textColor), + SpoilerSpan(spoilerBgColorHidden, spoilerBgColorRevealed, textColor), tag.start(), tag.end() ) diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt index 7dd76dd71b..d8236f0746 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt @@ -21,7 +21,9 @@ import android.text.TextPaint import android.text.style.ClickableSpan import android.view.View -class SpoilerSpan(private val bgColor: Int, private val textColor: Int) : ClickableSpan() { +class SpoilerSpan(private val bgColorHidden: Int, + private val bgColorRevealed: Int, + private val textColor: Int) : ClickableSpan() { override fun onClick(widget: View) { isHidden = !isHidden @@ -31,10 +33,11 @@ class SpoilerSpan(private val bgColor: Int, private val textColor: Int) : Clicka private var isHidden = true override fun updateDrawState(tp: TextPaint) { - tp.bgColor = bgColor if (isHidden) { + tp.bgColor = bgColorHidden tp.color = Color.TRANSPARENT } else { + tp.bgColor = bgColorRevealed tp.color = textColor } } diff --git a/vector/src/main/res/values/attrs.xml b/vector/src/main/res/values/attrs.xml index e9a4296add..c30a1d99d9 100644 --- a/vector/src/main/res/values/attrs.xml +++ b/vector/src/main/res/values/attrs.xml @@ -34,6 +34,7 @@ + diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml index f09cb0c874..f61a89482a 100644 --- a/vector/src/main/res/values/theme_dark.xml +++ b/vector/src/main/res/values/theme_dark.xml @@ -101,6 +101,7 @@ #CCC3C3C3 @color/accent_color_dark @android:color/black + #FFFFFFFF #565656 diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml index 1da010b8ff..aa343a11fc 100644 --- a/vector/src/main/res/values/theme_light.xml +++ b/vector/src/main/res/values/theme_light.xml @@ -101,6 +101,7 @@ #333C3C3C @color/accent_color_light #FFEEEEEE + #FF000000 #FFF2F2F2 From 7206d84a6b0eee2992b8a2e4f1c78c2d3cffcd15 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Nov 2019 16:51:45 +0100 Subject: [PATCH 049/117] Add FIXME --- .../main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt index 136d667c44..327677ade1 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt @@ -58,6 +58,7 @@ class MatrixHtmlPluginConfigure @Inject constructor(private val context: Context .addHandler(FontTagHandler()) .addHandler(MxLinkTagHandler(GlideApp.with(context), context, avatarRenderer, session)) .addHandler(MxReplyTagHandler()) + // FIXME (P3) SpanHandler is not recreated when theme is change and it depends on theme colors .addHandler(SpanHandler(context)) } } From e4b829f0cf9459d6525f2007ddb7c2c676ec45fa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Nov 2019 16:53:51 +0100 Subject: [PATCH 050/117] Lift of 'return' --- .../riotx/features/command/CommandParser.kt | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index d108f56f5a..a9c20a9ec5 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -56,11 +56,12 @@ object CommandParser { return ParsedCommand.ErrorEmptySlashCommand } - when (val slashCommand = messageParts.first()) { + + return when (val slashCommand = messageParts.first()) { Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() - return if (newDisplayName.isNotEmpty()) { + if (newDisplayName.isNotEmpty()) { ParsedCommand.ChangeDisplayName(newDisplayName) } else { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) @@ -69,7 +70,7 @@ object CommandParser { Command.TOPIC.command -> { val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() - return if (newTopic.isNotEmpty()) { + if (newTopic.isNotEmpty()) { ParsedCommand.ChangeTopic(newTopic) } else { ParsedCommand.ErrorSyntax(Command.TOPIC) @@ -78,12 +79,12 @@ object CommandParser { Command.EMOTE.command -> { val message = textMessage.substring(Command.EMOTE.command.length).trim() - return ParsedCommand.SendEmote(message) + ParsedCommand.SendEmote(message) } Command.JOIN_ROOM.command -> { val roomAlias = textMessage.substring(Command.JOIN_ROOM.command.length).trim() - return if (roomAlias.isNotEmpty()) { + if (roomAlias.isNotEmpty()) { ParsedCommand.JoinRoom(roomAlias) } else { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) @@ -92,14 +93,14 @@ object CommandParser { Command.PART.command -> { val roomAlias = textMessage.substring(Command.PART.command.length).trim() - return if (roomAlias.isNotEmpty()) { + if (roomAlias.isNotEmpty()) { ParsedCommand.PartRoom(roomAlias) } else { ParsedCommand.ErrorSyntax(Command.PART) } } Command.INVITE.command -> { - return if (messageParts.size == 2) { + if (messageParts.size == 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -112,7 +113,7 @@ object CommandParser { } } Command.KICK_USER.command -> { - return if (messageParts.size >= 2) { + if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { val reason = textMessage.substring(Command.KICK_USER.command.length @@ -128,7 +129,7 @@ object CommandParser { } } Command.BAN_USER.command -> { - return if (messageParts.size >= 2) { + if (messageParts.size >= 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { val reason = textMessage.substring(Command.BAN_USER.command.length @@ -144,7 +145,7 @@ object CommandParser { } } Command.UNBAN_USER.command -> { - return if (messageParts.size == 2) { + if (messageParts.size == 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -157,7 +158,7 @@ object CommandParser { } } Command.SET_USER_POWER_LEVEL.command -> { - return if (messageParts.size == 3) { + if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { val powerLevelsAsString = messageParts[2] @@ -177,7 +178,7 @@ object CommandParser { } } Command.RESET_USER_POWER_LEVEL.command -> { - return if (messageParts.size == 2) { + if (messageParts.size == 2) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -190,7 +191,7 @@ object CommandParser { } } Command.MARKDOWN.command -> { - return if (messageParts.size == 2) { + if (messageParts.size == 2) { when { "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) "off".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(false) @@ -201,7 +202,7 @@ object CommandParser { } } Command.CLEAR_SCALAR_TOKEN.command -> { - return if (messageParts.size == 1) { + if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) @@ -210,11 +211,11 @@ object CommandParser { Command.SPOILER.command -> { val message = textMessage.substring(Command.SPOILER.command.length).trim() - return ParsedCommand.SendSpoiler(message) + ParsedCommand.SendSpoiler(message) } else -> { // Unknown command - return ParsedCommand.ErrorUnknownSlashCommand(slashCommand) + ParsedCommand.ErrorUnknownSlashCommand(slashCommand) } } } From 93df8c56a877cca47398efb1b59e3576840ac2f5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 4 Nov 2019 17:07:23 +0100 Subject: [PATCH 051/117] Fix compilation error and use mockk instead of manual mocking (prone to error) --- .../api/pushrules/PushrulesConditionTest.kt | 271 +++--------------- .../share/ShareRoomListObservableStore.kt | 3 +- 2 files changed, 40 insertions(+), 234 deletions(-) diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt index 7651b32d20..7cb3917195 100644 --- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt @@ -16,23 +16,21 @@ package im.vector.matrix.android.api.pushrules -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import im.vector.matrix.android.api.MatrixCallback -import im.vector.matrix.android.api.session.content.ContentAttachmentData import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.toContent import im.vector.matrix.android.api.session.room.Room import im.vector.matrix.android.api.session.room.RoomService -import im.vector.matrix.android.api.session.room.model.* -import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams +import im.vector.matrix.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.message.MessageTextContent -import im.vector.matrix.android.api.session.room.send.UserDraft -import im.vector.matrix.android.api.session.room.timeline.Timeline -import im.vector.matrix.android.api.session.room.timeline.TimelineEvent -import im.vector.matrix.android.api.session.room.timeline.TimelineSettings -import im.vector.matrix.android.api.util.Cancelable -import im.vector.matrix.android.api.util.Optional +import io.mockk.every +import io.mockk.mockk +import org.amshove.kluent.When +import org.amshove.kluent.any +import org.amshove.kluent.calling +import org.amshove.kluent.itAnswers +import org.amshove.kluent.itReturns +import org.amshove.kluent.mock import org.junit.Assert import org.junit.Test @@ -133,17 +131,20 @@ class PushrulesConditionTest { val conditionEqual3Bis = RoomMemberCountCondition("==3") val conditionLessThan3 = RoomMemberCountCondition("<3") - val session = MockRoomService() + val room2JoinedId = "2joined" + val room3JoinedId = "3joined" - Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "A").toContent(), - originServerTs = 0, - roomId = "2joined").also { - Assert.assertFalse("This room does not have 3 members", conditionEqual3.isSatisfied(it, session)) - Assert.assertFalse("This room does not have 3 members", conditionEqual3Bis.isSatisfied(it, session)) - Assert.assertTrue("This room has less than 3 members", conditionLessThan3.isSatisfied(it, session)) + val roomStub2Joined = mockk { + every { getNumberOfJoinedMembers() } returns 2 + } + + val roomStub3Joined = mockk { + every { getNumberOfJoinedMembers() } returns 3 + } + + val sessionStub = mockk { + every { getRoom(room2JoinedId) } returns roomStub2Joined + every { getRoom(room3JoinedId) } returns roomStub3Joined } Event( @@ -151,10 +152,21 @@ class PushrulesConditionTest { eventId = "mx0", content = MessageTextContent("m.text", "A").toContent(), originServerTs = 0, - roomId = "3joined").also { - Assert.assertTrue("This room has 3 members", conditionEqual3.isSatisfied(it, session)) - Assert.assertTrue("This room has 3 members", conditionEqual3Bis.isSatisfied(it, session)) - Assert.assertFalse("This room has more than 3 members", conditionLessThan3.isSatisfied(it, session)) + roomId = room2JoinedId).also { + Assert.assertFalse("This room does not have 3 members", conditionEqual3.isSatisfied(it, sessionStub)) + Assert.assertFalse("This room does not have 3 members", conditionEqual3Bis.isSatisfied(it, sessionStub)) + Assert.assertTrue("This room has less than 3 members", conditionLessThan3.isSatisfied(it, sessionStub)) + } + + Event( + type = "m.room.message", + eventId = "mx0", + content = MessageTextContent("m.text", "A").toContent(), + originServerTs = 0, + roomId = room3JoinedId).also { + Assert.assertTrue("This room has 3 members", conditionEqual3.isSatisfied(it, sessionStub)) + Assert.assertTrue("This room has 3 members", conditionEqual3Bis.isSatisfied(it, sessionStub)) + Assert.assertFalse("This room has more than 3 members", conditionLessThan3.isSatisfied(it, sessionStub)) } } @@ -172,211 +184,4 @@ class PushrulesConditionTest { } } - class MockRoomService() : RoomService { - override fun createRoom(createRoomParams: CreateRoomParams, callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun joinRoom(roomId: String, viaServers: List, callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getRoom(roomId: String): Room? { - return when (roomId) { - "2joined" -> MockRoom(roomId, 2) - "3joined" -> MockRoom(roomId, 3) - else -> null - } - } - - override fun liveRoomSummaries(): LiveData> { - return MutableLiveData() - } - - override fun markAllAsRead(roomIds: List, callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - } - - class MockRoom(override val roomId: String, val _numberOfJoinedMembers: Int) : Room { - override fun reportContent(eventId: String, score: Int, reason: String, callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getReadMarkerLive(): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getMyReadReceiptLive(): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun resendTextMessage(localEcho: TimelineEvent): Cancelable? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun resendMediaMessage(localEcho: TimelineEvent): Cancelable? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun deleteFailedEcho(localEcho: TimelineEvent) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun clearSendingQueue() { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun resendAllFailedMessages() { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun saveDraft(draft: UserDraft) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun deleteDraft() { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getDraftsLive(): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getEventReadReceiptsLive(eventId: String): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getStateEvent(eventType: String): Event? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun editReply(replyToEdit: TimelineEvent, originalTimelineEvent: TimelineEvent, newBodyText: String, compatibilityBodyText: String): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun fetchEditHistory(eventId: String, callback: MatrixCallback>) { - } - - override fun getTimeLineEventLive(eventId: String): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getNumberOfJoinedMembers(): Int { - return _numberOfJoinedMembers - } - - override fun getRoomSummaryLive(): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun roomSummary(): RoomSummary? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun createTimeline(eventId: String?, settings: TimelineSettings): Timeline { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getTimeLineEvent(eventId: String): TimelineEvent? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun sendTextMessage(text: String, msgType: String, autoMarkdown: Boolean): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun sendFormattedTextMessage(text: String, formattedText: String): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun sendMedia(attachment: ContentAttachmentData): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun sendMedias(attachments: List): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun redactEvent(event: Event, reason: String?): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun markAllAsRead(callback: MatrixCallback) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun setReadReceipt(eventId: String, callback: MatrixCallback) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun isEventRead(eventId: String): Boolean { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun loadRoomMembersIfNeeded(matrixCallback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getRoomMember(userId: String): RoomMember? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getRoomMemberIdsLive(): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun invite(userId: String, callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun join(viaServers: List, callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun leave(callback: MatrixCallback): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun updateTopic(topic: String, callback: MatrixCallback) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun sendReaction(targetEventId: String, reaction: String): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun undoReaction(targetEventId: String, reaction: String): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun editTextMessage(targetEventId: String, msgType: String, newBodyText: String, - newBodyAutoMarkdown: Boolean, compatibilityBodyText: String): Cancelable { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun replyToMessage(eventReplied: TimelineEvent, replyText: String, autoMarkdown: Boolean): Cancelable? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun getEventSummaryLive(eventId: String): LiveData> { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun isEncrypted(): Boolean { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun encryptionAlgorithm(): String? { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - - override fun shouldEncryptForInvitedMembers(): Boolean { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } - } } diff --git a/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt b/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt index c46ec42d64..bf7dde65ab 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt @@ -17,9 +17,10 @@ package im.vector.riotx.features.share import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.riotx.core.utils.BehaviorStore import im.vector.riotx.core.utils.RxStore import javax.inject.Inject import javax.inject.Singleton @Singleton -class ShareRoomListObservableStore @Inject constructor() : RxStore>() +class ShareRoomListObservableStore @Inject constructor() : BehaviorStore>() From bee8c2d159be3a48b4ba6d5a625956de5b4ffbaa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Nov 2019 18:12:24 +0100 Subject: [PATCH 052/117] Ensure color is retrieved from current theme, even when theme change --- .../im/vector/riotx/core/resources/ColorProvider.kt | 5 ++--- .../vector/riotx/features/html/EventHtmlRenderer.kt | 5 +++-- .../im/vector/riotx/features/html/SpanHandler.kt | 13 +++---------- .../im/vector/riotx/features/html/SpoilerSpan.kt | 12 ++++++------ 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/resources/ColorProvider.kt b/vector/src/main/java/im/vector/riotx/core/resources/ColorProvider.kt index aa5fba839b..d19354240c 100644 --- a/vector/src/main/java/im/vector/riotx/core/resources/ColorProvider.kt +++ b/vector/src/main/java/im/vector/riotx/core/resources/ColorProvider.kt @@ -16,15 +16,15 @@ package im.vector.riotx.core.resources +import android.content.Context import androidx.annotation.AttrRes import androidx.annotation.ColorInt import androidx.annotation.ColorRes -import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import im.vector.riotx.features.themes.ThemeUtils import javax.inject.Inject -class ColorProvider @Inject constructor(private val context: AppCompatActivity) { +class ColorProvider @Inject constructor(private val context: Context) { fun getColor(@ColorRes colorRes: Int): Int { return ContextCompat.getColor(context, colorRes) @@ -33,7 +33,6 @@ class ColorProvider @Inject constructor(private val context: AppCompatActivity) /** * Translates color attributes to colors * - * @param c Context * @param colorAttribute Color Attribute * @return Requested Color */ diff --git a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt index 327677ade1..7775de830f 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/EventHtmlRenderer.kt @@ -19,6 +19,7 @@ package im.vector.riotx.features.html import android.content.Context import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.glide.GlideApp +import im.vector.riotx.core.resources.ColorProvider import im.vector.riotx.features.home.AvatarRenderer import io.noties.markwon.Markwon import io.noties.markwon.html.HtmlPlugin @@ -49,6 +50,7 @@ class EventHtmlRenderer @Inject constructor(context: Context, } class MatrixHtmlPluginConfigure @Inject constructor(private val context: Context, + private val colorProvider: ColorProvider, private val avatarRenderer: AvatarRenderer, private val session: ActiveSessionHolder) : HtmlPlugin.HtmlConfigure { @@ -58,7 +60,6 @@ class MatrixHtmlPluginConfigure @Inject constructor(private val context: Context .addHandler(FontTagHandler()) .addHandler(MxLinkTagHandler(GlideApp.with(context), context, avatarRenderer, session)) .addHandler(MxReplyTagHandler()) - // FIXME (P3) SpanHandler is not recreated when theme is change and it depends on theme colors - .addHandler(SpanHandler(context)) + .addHandler(SpanHandler(colorProvider)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt b/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt index dbc09cf0a9..cb6e4dc325 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/SpanHandler.kt @@ -15,30 +15,23 @@ */ package im.vector.riotx.features.html -import android.content.Context -import im.vector.riotx.R -import im.vector.riotx.features.themes.ThemeUtils +import im.vector.riotx.core.resources.ColorProvider import io.noties.markwon.MarkwonVisitor import io.noties.markwon.SpannableBuilder import io.noties.markwon.html.HtmlTag import io.noties.markwon.html.MarkwonHtmlRenderer import io.noties.markwon.html.TagHandler -class SpanHandler(context: Context) : TagHandler() { +class SpanHandler(private val colorProvider: ColorProvider) : TagHandler() { override fun supportedTags() = listOf("span") - private val spoilerBgColorHidden: Int = ThemeUtils.getColor(context, R.attr.vctr_spoiler_background_color) - private val spoilerBgColorRevealed: Int = ThemeUtils.getColor(context, R.attr.vctr_markdown_block_background_color) - - private val textColor: Int = ThemeUtils.getColor(context, R.attr.riotx_text_primary) - override fun handle(visitor: MarkwonVisitor, renderer: MarkwonHtmlRenderer, tag: HtmlTag) { val mxSpoiler = tag.attributes()["data-mx-spoiler"] if (mxSpoiler != null) { SpannableBuilder.setSpans( visitor.builder(), - SpoilerSpan(spoilerBgColorHidden, spoilerBgColorRevealed, textColor), + SpoilerSpan(colorProvider), tag.start(), tag.end() ) diff --git a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt index d8236f0746..5ba464cba4 100644 --- a/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt +++ b/vector/src/main/java/im/vector/riotx/features/html/SpoilerSpan.kt @@ -20,10 +20,10 @@ import android.graphics.Color import android.text.TextPaint import android.text.style.ClickableSpan import android.view.View +import im.vector.riotx.R +import im.vector.riotx.core.resources.ColorProvider -class SpoilerSpan(private val bgColorHidden: Int, - private val bgColorRevealed: Int, - private val textColor: Int) : ClickableSpan() { +class SpoilerSpan(private val colorProvider: ColorProvider) : ClickableSpan() { override fun onClick(widget: View) { isHidden = !isHidden @@ -34,11 +34,11 @@ class SpoilerSpan(private val bgColorHidden: Int, override fun updateDrawState(tp: TextPaint) { if (isHidden) { - tp.bgColor = bgColorHidden + tp.bgColor = colorProvider.getColorFromAttribute(R.attr.vctr_spoiler_background_color) tp.color = Color.TRANSPARENT } else { - tp.bgColor = bgColorRevealed - tp.color = textColor + tp.bgColor = colorProvider.getColorFromAttribute(R.attr.vctr_markdown_block_background_color) + tp.color = colorProvider.getColorFromAttribute(R.attr.riotx_text_primary) } } } From 3013d67c16d8feed2f938e901b1eea50e0ba882a Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 4 Nov 2019 19:33:56 +0100 Subject: [PATCH 053/117] Fragment factory: start including the new version with FragmentFactory [WIP] --- vector/build.gradle | 3 + .../im/vector/riotx/core/di/FragmentKey.kt | 28 ++++++++++ .../im/vector/riotx/core/di/FragmentModule.kt | 55 +++++++++++++++++++ .../vector/riotx/core/di/ScreenComponent.kt | 3 + .../riotx/core/di/VectorFragmentFactory.kt | 45 +++++++++++++++ .../vector/riotx/core/extensions/Fragment.kt | 6 +- .../riotx/core/platform/VectorBaseActivity.kt | 3 +- .../riotx/core/platform/VectorBaseFragment.kt | 6 +- .../riotx/features/home/HomeDetailFragment.kt | 16 ++++-- .../room/filtered/FilteredRoomsActivity.kt | 1 - .../home/room/list/RoomListFragment.kt | 21 +++---- vector/src/main/res/layout/activity_home.xml | 4 +- 12 files changed, 164 insertions(+), 27 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt create mode 100644 vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt create mode 100644 vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt diff --git a/vector/build.gradle b/vector/build.gradle index d639b4c3e8..d0a757d4e0 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -217,6 +217,7 @@ android { dependencies { def epoxy_version = '3.8.0' + def fragment_version = '1.2.0-rc01' def arrow_version = "0.8.2" def coroutines_version = "1.3.2" def markwon_version = '4.1.2' @@ -234,6 +235,8 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation 'androidx.appcompat:appcompat:1.1.0' + implementation "androidx.fragment:fragment:$fragment_version" + implementation "androidx.fragment:fragment-ktx:$fragment_version" //Do not use beta2 at the moment, as it breaks things implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1' implementation 'androidx.core:core-ktx:1.1.0' diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt new file mode 100644 index 0000000000..c20768ba10 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.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.core.di + +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModel +import dagger.MapKey +import kotlin.reflect.KClass + +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) +@Retention(AnnotationRetention.RUNTIME) +@MapKey +annotation class FragmentKey(val value: KClass) diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt new file mode 100644 index 0000000000..b3bb344d5c --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt @@ -0,0 +1,55 @@ +/* + * 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.core.di + +import androidx.fragment.app.FragmentFactory +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import im.vector.riotx.core.platform.ConfigurationViewModel +import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyViewModel +import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel +import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel +import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel +import im.vector.riotx.features.crypto.verification.SasVerificationViewModel +import im.vector.riotx.features.home.HomeNavigationViewModel +import im.vector.riotx.features.home.createdirect.CreateDirectRoomNavigationViewModel +import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.reactions.EmojiChooserViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel +import im.vector.riotx.features.workers.signout.SignOutViewModel + +@Module +interface FragmentModule { + + /** + * Fragments with @IntoMap will be injected by this factory + */ + @Binds + fun bindFragmentFactory(factory: VectorFragmentFactory): FragmentFactory + + + @Binds + @IntoMap + @FragmentKey(RoomListFragment::class) + fun bindRoomListFragment(viewModel: RoomListFragment): ViewModel + + +} diff --git a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt index 79e496c141..a7c236e033 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt @@ -17,6 +17,7 @@ package im.vector.riotx.core.di import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.FragmentFactory import androidx.lifecycle.ViewModelProvider import dagger.BindsInstance import dagger.Component @@ -88,6 +89,8 @@ interface ScreenComponent { fun activeSessionHolder(): ActiveSessionHolder + fun fragmentFactory(): FragmentFactory + fun viewModelFactory(): ViewModelProvider.Factory fun bugReporter(): BugReporter diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt new file mode 100644 index 0000000000..c27509458e --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt @@ -0,0 +1,45 @@ +/* + * 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.core.di + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentFactory +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Provider + +/** + * FragmentFactory which uses Dagger to create the instances. + */ +class VectorFragmentFactory @Inject constructor( + private val creators: @JvmSuppressWildcards Map, Provider> +) : FragmentFactory() { + + override fun instantiate(classLoader: ClassLoader, className: String): Fragment { + val fragmentClass = loadFragmentClass(classLoader, className) + val creator: Provider? = creators[fragmentClass] + return if (creator == null) { + Timber.v("Unknown model class: $className, fallback to default instance") + super.instantiate(classLoader, className) + } else { + creator.get() + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt index 65f8fb2aaa..11ebf56ec9 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt @@ -19,15 +19,15 @@ package im.vector.riotx.core.extensions import androidx.fragment.app.Fragment fun Fragment.addFragment(fragment: Fragment, frameId: Int) { - fragmentManager?.inTransaction { add(frameId, fragment) } + parentFragmentManager.inTransaction { add(frameId, fragment) } } fun Fragment.replaceFragment(fragment: Fragment, frameId: Int) { - fragmentManager?.inTransaction { replace(frameId, fragment) } + parentFragmentManager.inTransaction { replace(frameId, fragment) } } fun Fragment.addFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) { - fragmentManager?.inTransaction { replace(frameId, fragment).addToBackStack(tag) } + parentFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } } fun Fragment.addChildFragment(fragment: Fragment, frameId: Int) { diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt index 9a4f89d13a..3b80d6d794 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt @@ -26,6 +26,7 @@ import androidx.annotation.* import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible +import androidx.fragment.app.FragmentFactory import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider @@ -125,7 +126,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector { } Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms") ThemeUtils.setActivityTheme(this, getOtherThemes()) - + supportFragmentManager.fragmentFactory = screenComponent.fragmentFactory() super.onCreate(savedInstanceState) viewModelFactory = screenComponent.viewModelFactory() configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt index cc0d8940bc..34953bec33 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt @@ -134,7 +134,11 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { } protected fun setArguments(args: Parcelable? = null) { - arguments = args?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } } + arguments = args.toMvRxBundle() + } + + protected fun Parcelable?.toMvRxBundle(): Bundle? { + return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } } } @MainThread 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 844fd4f5b2..38fe491bd3 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 @@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent +import im.vector.riotx.core.extensions.inTransaction import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.KeysBackupBanner @@ -172,14 +173,17 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) { val fragmentTag = "FRAGMENT_TAG_${displayMode.name}" - var fragment = childFragmentManager.findFragmentByTag(fragmentTag) + val fragment = childFragmentManager.findFragmentByTag(fragmentTag) if (fragment == null) { - fragment = RoomListFragment.newInstance(RoomListParams(displayMode)) + childFragmentManager.inTransaction { + replace(R.id.roomListContainer, RoomListFragment::class.java, RoomListParams(displayMode).toMvRxBundle(), fragmentTag).addToBackStack(fragmentTag) + } + } else { + childFragmentManager.inTransaction { + replace(R.id.roomListContainer, fragment, fragmentTag).addToBackStack(fragmentTag) + } } - childFragmentManager.beginTransaction() - .replace(R.id.roomListContainer, fragment, fragmentTag) - .addToBackStack(fragmentTag) - .commit() + } /* ========================================================================================== diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt index 82fd203b87..b9f8579dd5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt @@ -44,7 +44,6 @@ class FilteredRoomsActivity : VectorBaseActivity() { super.onCreate(savedInstanceState) configureToolbar(filteredRoomsToolbar) if (isFirstCreation()) { - roomListFragment = RoomListFragment.newInstance(RoomListParams(RoomListFragment.DisplayMode.FILTERED)) replaceFragment(roomListFragment, R.id.filteredRoomsFragmentContainer, FRAGMENT_TAG) } else { roomListFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as RoomListFragment 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 a705c91a9e..671559b73b 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 @@ -52,7 +52,13 @@ data class RoomListParams( val sharedData: SharedData? = null ) : Parcelable -class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, FabMenuView.Listener { +class RoomListFragment @Inject constructor( + private val roomController: RoomSummaryController, + val roomListViewModelFactory: RoomListViewModel.Factory, + private val errorFormatter: ErrorFormatter, + private val notificationDrawerManager: NotificationDrawerManager + +) : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, FabMenuView.Listener { enum class DisplayMode(@StringRes val titleRes: Int) { HOME(R.string.bottom_action_home), @@ -62,25 +68,14 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O SHARE(/* Not used */ 0) } - companion object { - fun newInstance(roomListParams: RoomListParams): RoomListFragment { - return RoomListFragment().apply { - setArguments(roomListParams) - } - } - } - private val roomListParams: RoomListParams by args() - @Inject lateinit var roomController: RoomSummaryController - @Inject lateinit var roomListViewModelFactory: RoomListViewModel.Factory - @Inject lateinit var errorFormatter: ErrorFormatter - @Inject lateinit var notificationDrawerManager: NotificationDrawerManager private val roomListViewModel: RoomListViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_room_list override fun injectWith(injector: ScreenComponent) { injector.inject(this) + setArguments() } private var hasUnreadRooms = false diff --git a/vector/src/main/res/layout/activity_home.xml b/vector/src/main/res/layout/activity_home.xml index c6f74147d5..0ce124b787 100644 --- a/vector/src/main/res/layout/activity_home.xml +++ b/vector/src/main/res/layout/activity_home.xml @@ -11,7 +11,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - @@ -20,7 +20,7 @@ - Date: Tue, 5 Nov 2019 11:05:29 +0100 Subject: [PATCH 054/117] Import change form https://github.com/matrix-org/matrix-android-sdk/pull/505 --- .../android/internal/crypto/store/db/Helper.kt | 6 ++---- .../internal/crypto/store/db/RealmCryptoStore.kt | 16 +++++++--------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt index 5ef2b9b1a2..81988fe209 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/Helper.kt @@ -41,8 +41,7 @@ fun doWithRealm(realmConfiguration: RealmConfiguration, action: (Realm) -> T */ fun doRealmQueryAndCopy(realmConfiguration: RealmConfiguration, action: (Realm) -> T?): T? { return Realm.getInstance(realmConfiguration).use { realm -> - val result = action.invoke(realm) - result?.let { realm.copyFromRealm(it) } + action.invoke(realm)?.let { realm.copyFromRealm(it) } } } @@ -51,8 +50,7 @@ fun doRealmQueryAndCopy(realmConfiguration: RealmConfiguration */ fun doRealmQueryAndCopyList(realmConfiguration: RealmConfiguration, action: (Realm) -> Iterable): Iterable { return Realm.getInstance(realmConfiguration).use { realm -> - val result = action.invoke(realm) - realm.copyFromRealm(result) + action.invoke(realm).let { realm.copyFromRealm(it) } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt index d88a84de9e..8a3b66dfe5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt @@ -91,7 +91,7 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati realmLocker = Realm.getInstance(realmConfiguration) // Ensure CryptoMetadataEntity is inserted in DB - doWithRealm(realmConfiguration) { realm -> + doRealmTransaction(realmConfiguration) { realm -> var currentMetadata = realm.where().findFirst() var deleteAll = false @@ -109,15 +109,13 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati } if (currentMetadata == null) { - realm.executeTransaction { - if (deleteAll) { - it.deleteAll() - } + if (deleteAll) { + realm.deleteAll() + } - // Metadata not found, or database cleaned, create it - it.createObject(CryptoMetadataEntity::class.java, credentials.userId).apply { - deviceId = credentials.deviceId - } + // Metadata not found, or database cleaned, create it + realm.createObject(CryptoMetadataEntity::class.java, credentials.userId).apply { + deviceId = credentials.deviceId } } } From 10712fd6ab4060df50fa5fcb529833b33db1ccf5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 12:13:06 +0100 Subject: [PATCH 055/117] ktlint --- .../main/java/im/vector/riotx/features/command/CommandParser.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index a9c20a9ec5..3f5808949b 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -56,7 +56,6 @@ object CommandParser { return ParsedCommand.ErrorEmptySlashCommand } - return when (val slashCommand = messageParts.first()) { Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() From 8871280fabb79a90b591e8784693d5cc5002b4f3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 5 Nov 2019 18:12:04 +0100 Subject: [PATCH 056/117] Fragments: use constructor injections in most of the Fragments --- .../im/vector/riotx/core/di/FragmentKey.kt | 1 - .../im/vector/riotx/core/di/FragmentModule.kt | 166 ++++++++++++++++-- .../vector/riotx/core/di/ScreenComponent.kt | 82 +-------- .../riotx/core/di/VectorFragmentFactory.kt | 2 - .../vector/riotx/core/extensions/Activity.kt | 29 ++- .../vector/riotx/core/extensions/Fragment.kt | 50 +++++- .../riotx/core/platform/VectorBaseActivity.kt | 7 +- .../riotx/core/platform/VectorBaseFragment.kt | 3 +- .../core/platform/VectorPreferenceFragment.kt | 54 ------ .../riotx/features/command/CommandParser.kt | 1 - .../restore/KeysBackupRestoreActivity.kt | 20 +-- .../KeysBackupRestoreFromKeyFragment.kt | 12 +- ...KeysBackupRestoreFromPassphraseFragment.kt | 20 +-- .../KeysBackupRestoreSuccessFragment.kt | 8 +- .../settings/KeysBackupManageActivity.kt | 6 +- .../settings/KeysBackupSettingsFragment.kt | 15 +- .../setup/KeysBackupSetupActivity.kt | 13 +- .../setup/KeysBackupSetupStep1Fragment.kt | 8 +- .../setup/KeysBackupSetupStep2Fragment.kt | 22 +-- .../setup/KeysBackupSetupStep3Fragment.kt | 14 +- .../verification/SASVerificationActivity.kt | 65 +++---- .../SASVerificationIncomingFragment.kt | 16 +- .../SASVerificationShortCodeFragment.kt | 9 +- .../SASVerificationStartFragment.kt | 9 +- .../SASVerificationVerifiedFragment.kt | 7 +- .../riotx/features/home/HomeActivity.kt | 9 +- .../riotx/features/home/HomeDetailFragment.kt | 36 ++-- .../riotx/features/home/HomeDrawerFragment.kt | 23 +-- .../riotx/features/home/LoadingFragment.kt | 10 +- .../createdirect/CreateDirectRoomActivity.kt | 4 +- .../CreateDirectRoomDirectoryUsersFragment.kt | 10 +- .../CreateDirectRoomKnownUsersFragment.kt | 15 +- .../features/home/group/GroupListFragment.kt | 19 +- .../home/room/detail/RoomDetailActivity.kt | 3 +- .../home/room/detail/RoomDetailFragment.kt | 44 ++--- .../room/filtered/FilteredRoomsActivity.kt | 13 +- .../home/room/list/RoomListFragment.kt | 6 - .../riotx/features/login/LoginActivity.kt | 4 +- .../riotx/features/login/LoginFragment.kt | 10 +- .../login/LoginSsoFallbackFragment.kt | 8 +- .../reactions/EmojiSearchResultFragment.kt | 11 +- .../roomdirectory/PublicRoomsFragment.kt | 13 +- .../roomdirectory/RoomDirectoryActivity.kt | 6 +- .../createroom/CreateRoomActivity.kt | 8 +- .../createroom/CreateRoomFragment.kt | 8 +- .../picker/RoomDirectoryPickerFragment.kt | 12 +- .../roompreview/RoomPreviewActivity.kt | 4 +- .../RoomPreviewNoPreviewFragment.kt | 21 +-- .../settings/VectorSettingsActivity.kt | 4 +- ...sAdvancedNotificationPreferenceFragment.kt | 13 +- .../VectorSettingsHelpAboutFragment.kt | 11 +- ...rSettingsNotificationPreferenceFragment.kt | 15 +- ...ttingsNotificationsTroubleshootFragment.kt | 23 +-- .../VectorSettingsPreferencesFragment.kt | 13 +- .../VectorSettingsSecurityPrivacyFragment.kt | 11 +- .../settings/push/PushGatewaysFragment.kt | 10 +- .../features/share/IncomingShareActivity.kt | 14 +- 57 files changed, 432 insertions(+), 618 deletions(-) delete mode 100644 vector/src/main/java/im/vector/riotx/core/platform/VectorPreferenceFragment.kt diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt index c20768ba10..57b5c902e5 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt @@ -18,7 +18,6 @@ package im.vector.riotx.core.di import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModel import dagger.MapKey import kotlin.reflect.KClass diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt index b3bb344d5c..df6d2abf88 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt @@ -17,24 +17,33 @@ package im.vector.riotx.core.di +import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentFactory -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider import dagger.Binds import dagger.Module import dagger.multibindings.IntoMap -import im.vector.riotx.core.platform.ConfigurationViewModel -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyViewModel -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel -import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel -import im.vector.riotx.features.crypto.verification.SasVerificationViewModel -import im.vector.riotx.features.home.HomeNavigationViewModel -import im.vector.riotx.features.home.createdirect.CreateDirectRoomNavigationViewModel +import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsFragment +import im.vector.riotx.features.crypto.verification.SASVerificationIncomingFragment +import im.vector.riotx.features.crypto.verification.SASVerificationShortCodeFragment +import im.vector.riotx.features.crypto.verification.SASVerificationStartFragment +import im.vector.riotx.features.crypto.verification.SASVerificationVerifiedFragment +import im.vector.riotx.features.home.HomeDetailFragment +import im.vector.riotx.features.home.HomeDrawerFragment +import im.vector.riotx.features.home.LoadingFragment +import im.vector.riotx.features.home.createdirect.CreateDirectRoomDirectoryUsersFragment +import im.vector.riotx.features.home.createdirect.CreateDirectRoomKnownUsersFragment +import im.vector.riotx.features.home.group.GroupListFragment +import im.vector.riotx.features.home.room.detail.RoomDetailFragment import im.vector.riotx.features.home.room.list.RoomListFragment -import im.vector.riotx.features.reactions.EmojiChooserViewModel -import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel -import im.vector.riotx.features.workers.signout.SignOutViewModel +import im.vector.riotx.features.login.LoginFragment +import im.vector.riotx.features.login.LoginSsoFallbackFragment +import im.vector.riotx.features.reactions.EmojiSearchResultFragment +import im.vector.riotx.features.roomdirectory.PublicRoomsFragment +import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment +import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment +import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment +import im.vector.riotx.features.settings.* +import im.vector.riotx.features.settings.push.PushGatewaysFragment @Module interface FragmentModule { @@ -45,11 +54,138 @@ interface FragmentModule { @Binds fun bindFragmentFactory(factory: VectorFragmentFactory): FragmentFactory - @Binds @IntoMap @FragmentKey(RoomListFragment::class) - fun bindRoomListFragment(viewModel: RoomListFragment): ViewModel + fun bindRoomListFragment(fragment: RoomListFragment): Fragment + @Binds + @IntoMap + @FragmentKey(GroupListFragment::class) + fun bindGroupListFragment(fragment: GroupListFragment): Fragment + @Binds + @IntoMap + @FragmentKey(RoomDetailFragment::class) + fun bindRoomDetailFragment(fragment: RoomDetailFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDirectoryPickerFragment::class) + fun bindRoomDirectoryPickerFragment(fragment: RoomDirectoryPickerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateRoomFragment::class) + fun bindCreateRoomFragment(fragment: CreateRoomFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomPreviewNoPreviewFragment::class) + fun bindRoomPreviewNoPreviewFragment(fragment: RoomPreviewNoPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(KeysBackupSettingsFragment::class) + fun bindKeysBackupSettingsFragment(fragment: KeysBackupSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoadingFragment::class) + fun bindLoadingFragment(fragment: LoadingFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(HomeDrawerFragment::class) + fun bindHomeDrawerFragment(fragment: HomeDrawerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(HomeDetailFragment::class) + fun bindHomeDetailFragment(fragment: HomeDetailFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(EmojiSearchResultFragment::class) + fun bindEmojiSearchResultFragment(fragment: EmojiSearchResultFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragment::class) + fun bindLoginFragment(fragment: LoginFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginSsoFallbackFragment::class) + fun bindLoginSsoFallbackFragment(fragment: LoginSsoFallbackFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateDirectRoomDirectoryUsersFragment::class) + fun bindCreateDirectRoomDirectoryUsersFragment(fragment: CreateDirectRoomDirectoryUsersFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateDirectRoomKnownUsersFragment::class) + fun bindCreateDirectRoomKnownUsersFragment(fragment: CreateDirectRoomKnownUsersFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(PushGatewaysFragment::class) + fun bindPushGatewaysFragment(fragment: PushGatewaysFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) + fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) + fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsNotificationPreferenceFragment::class) + fun bindVectorSettingsNotificationPreferenceFragment(fragment: VectorSettingsNotificationPreferenceFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsPreferencesFragment::class) + fun bindVectorSettingsPreferencesFragment(fragment: VectorSettingsPreferencesFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsSecurityPrivacyFragment::class) + fun bindVectorSettingsSecurityPrivacyFragment(fragment: VectorSettingsSecurityPrivacyFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsHelpAboutFragment::class) + fun bindVectorSettingsHelpAboutFragment(fragment: VectorSettingsHelpAboutFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SASVerificationIncomingFragment::class) + fun bindSASVerificationIncomingFragment(fragment: SASVerificationIncomingFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SASVerificationShortCodeFragment::class) + fun bindSASVerificationShortCodeFragment(fragment: SASVerificationShortCodeFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SASVerificationVerifiedFragment::class) + fun bindSASVerificationVerifiedFragment(fragment: SASVerificationVerifiedFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SASVerificationStartFragment::class) + fun bindSASVerificationStartFragment(fragment: SASVerificationStartFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(PublicRoomsFragment::class) + fun bindPublicRoomsFragment(fragment: PublicRoomsFragment): Fragment } diff --git a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt index a7c236e033..d9d23c1be5 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt @@ -21,38 +21,21 @@ import androidx.fragment.app.FragmentFactory import androidx.lifecycle.ViewModelProvider import dagger.BindsInstance import dagger.Component -import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment import im.vector.riotx.core.preference.UserAvatarPreference import im.vector.riotx.features.MainActivity -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyFragment -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSuccessFragment import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity -import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsFragment -import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupStep1Fragment -import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupStep2Fragment -import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupStep3Fragment -import im.vector.riotx.features.crypto.verification.SASVerificationIncomingFragment import im.vector.riotx.features.home.HomeActivity -import im.vector.riotx.features.home.HomeDetailFragment -import im.vector.riotx.features.home.HomeDrawerFragment import im.vector.riotx.features.home.HomeModule import im.vector.riotx.features.home.createdirect.CreateDirectRoomActivity -import im.vector.riotx.features.home.createdirect.CreateDirectRoomDirectoryUsersFragment -import im.vector.riotx.features.home.createdirect.CreateDirectRoomKnownUsersFragment -import im.vector.riotx.features.home.group.GroupListFragment -import im.vector.riotx.features.home.room.detail.RoomDetailFragment import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity -import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.home.room.list.RoomListModule import im.vector.riotx.features.invite.VectorInviteView import im.vector.riotx.features.link.LinkHandlerActivity import im.vector.riotx.features.login.LoginActivity -import im.vector.riotx.features.login.LoginFragment -import im.vector.riotx.features.login.LoginSsoFallbackFragment import im.vector.riotx.features.media.ImageMediaViewerActivity import im.vector.riotx.features.media.VideoMediaViewerActivity import im.vector.riotx.features.navigation.Navigator @@ -60,16 +43,10 @@ import im.vector.riotx.features.rageshake.BugReportActivity import im.vector.riotx.features.rageshake.BugReporter import im.vector.riotx.features.rageshake.RageShake import im.vector.riotx.features.reactions.EmojiReactionPickerActivity -import im.vector.riotx.features.reactions.EmojiSearchResultFragment import im.vector.riotx.features.reactions.widget.ReactionButton -import im.vector.riotx.features.roomdirectory.PublicRoomsFragment import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity import im.vector.riotx.features.roomdirectory.createroom.CreateRoomActivity -import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment -import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment -import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment import im.vector.riotx.features.settings.* -import im.vector.riotx.features.settings.push.PushGatewaysFragment import im.vector.riotx.features.share.IncomingShareActivity import im.vector.riotx.features.ui.UiStateRepository @@ -80,6 +57,7 @@ import im.vector.riotx.features.ui.UiStateRepository modules = [ AssistedInjectModule::class, ViewModelModule::class, + FragmentModule::class, HomeModule::class, RoomListModule::class ] @@ -103,22 +81,6 @@ interface ScreenComponent { fun inject(activity: HomeActivity) - fun inject(roomDetailFragment: RoomDetailFragment) - - fun inject(roomListFragment: RoomListFragment) - - fun inject(groupListFragment: GroupListFragment) - - fun inject(roomDirectoryPickerFragment: RoomDirectoryPickerFragment) - - fun inject(roomPreviewNoPreviewFragment: RoomPreviewNoPreviewFragment) - - fun inject(keysBackupSettingsFragment: KeysBackupSettingsFragment) - - fun inject(homeDrawerFragment: HomeDrawerFragment) - - fun inject(homeDetailFragment: HomeDetailFragment) - fun inject(messageActionsBottomSheet: MessageActionsBottomSheet) fun inject(viewReactionsBottomSheet: ViewReactionsBottomSheet) @@ -127,30 +89,8 @@ interface ScreenComponent { fun inject(vectorSettingsActivity: VectorSettingsActivity) - fun inject(createRoomFragment: CreateRoomFragment) - fun inject(keysBackupManageActivity: KeysBackupManageActivity) - fun inject(keysBackupRestoreFromKeyFragment: KeysBackupRestoreFromKeyFragment) - - fun inject(keysBackupRestoreFromPassphraseFragment: KeysBackupRestoreFromPassphraseFragment) - - fun inject(keysBackupRestoreSuccessFragment: KeysBackupRestoreSuccessFragment) - - fun inject(keysBackupSetupStep1Fragment: KeysBackupSetupStep1Fragment) - - fun inject(keysBackupSetupStep2Fragment: KeysBackupSetupStep2Fragment) - - fun inject(keysBackupSetupStep3Fragment: KeysBackupSetupStep3Fragment) - - fun inject(publicRoomsFragment: PublicRoomsFragment) - - fun inject(loginFragment: LoginFragment) - - fun inject(loginSsoFallbackFragment: LoginSsoFallbackFragment) - - fun inject(sasVerificationIncomingFragment: SASVerificationIncomingFragment) - fun inject(emojiReactionPickerActivity: EmojiReactionPickerActivity) fun inject(loginActivity: LoginActivity) @@ -173,26 +113,8 @@ interface ScreenComponent { fun inject(videoMediaViewerActivity: VideoMediaViewerActivity) - fun inject(vectorSettingsNotificationPreferenceFragment: VectorSettingsNotificationPreferenceFragment) - - fun inject(vectorSettingsPreferencesFragment: VectorSettingsPreferencesFragment) - - fun inject(vectorSettingsAdvancedNotificationPreferenceFragment: VectorSettingsAdvancedNotificationPreferenceFragment) - - fun inject(vectorSettingsSecurityPrivacyFragment: VectorSettingsSecurityPrivacyFragment) - - fun inject(vectorSettingsHelpAboutFragment: VectorSettingsHelpAboutFragment) - fun inject(userAvatarPreference: UserAvatarPreference) - fun inject(vectorSettingsNotificationsTroubleshootFragment: VectorSettingsNotificationsTroubleshootFragment) - - fun inject(pushGatewaysFragment: PushGatewaysFragment) - - fun inject(createDirectRoomKnownUsersFragment: CreateDirectRoomKnownUsersFragment) - - fun inject(createDirectRoomDirectoryUsersFragment: CreateDirectRoomDirectoryUsersFragment) - fun inject(createDirectRoomActivity: CreateDirectRoomActivity) fun inject(displayReadReceiptsBottomSheet: DisplayReadReceiptsBottomSheet) @@ -201,8 +123,6 @@ interface ScreenComponent { fun inject(incomingShareActivity: IncomingShareActivity) - fun inject(emojiSearchResultFragment: EmojiSearchResultFragment) - @Component.Factory interface Factory { fun create(vectorComponent: VectorComponent, diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt index c27509458e..6b33b9e2a7 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorFragmentFactory.kt @@ -19,8 +19,6 @@ package im.vector.riotx.core.di import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentFactory -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider import timber.log.Timber import javax.inject.Inject import javax.inject.Provider diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt index b4afb569c4..6e4ecf4775 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt @@ -16,21 +16,40 @@ package im.vector.riotx.core.extensions -import androidx.appcompat.app.AppCompatActivity +import android.os.Parcelable import androidx.fragment.app.Fragment +import im.vector.riotx.core.platform.VectorBaseActivity -fun AppCompatActivity.addFragment(fragment: Fragment, frameId: Int) { +fun VectorBaseActivity.addFragment(frameId: Int, fragment: Fragment) { supportFragmentManager.inTransaction { add(frameId, fragment) } } -fun AppCompatActivity.replaceFragment(fragment: Fragment, frameId: Int, tag: String? = null) { +fun VectorBaseActivity.addFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + supportFragmentManager.inTransaction { + add(frameId, fragmentClass, params.toMvRxBundle(), tag) + } +} + +fun VectorBaseActivity.replaceFragment(frameId: Int, fragment: Fragment, tag: String? = null) { supportFragmentManager.inTransaction { replace(frameId, fragment, tag) } } -fun AppCompatActivity.addFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) { +fun VectorBaseActivity.replaceFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + supportFragmentManager.inTransaction { + replace(frameId, fragmentClass, params.toMvRxBundle(), tag) + } +} + +fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { supportFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } } -fun AppCompatActivity.hideKeyboard() { +fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + supportFragmentManager.inTransaction { + replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) + } +} + +fun VectorBaseActivity.hideKeyboard() { currentFocus?.hideKeyboard() } diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt index 11ebf56ec9..e6e83bfd67 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt @@ -16,28 +16,66 @@ package im.vector.riotx.core.extensions +import android.os.Parcelable import androidx.fragment.app.Fragment +import im.vector.riotx.core.platform.VectorBaseFragment -fun Fragment.addFragment(fragment: Fragment, frameId: Int) { +fun VectorBaseFragment.addFragment(frameId: Int, fragment: Fragment) { parentFragmentManager.inTransaction { add(frameId, fragment) } } -fun Fragment.replaceFragment(fragment: Fragment, frameId: Int) { +fun VectorBaseFragment.addFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + parentFragmentManager.inTransaction { + add(frameId, fragmentClass, params.toMvRxBundle(), tag) + } +} + +fun VectorBaseFragment.replaceFragment(frameId: Int, fragment: Fragment) { parentFragmentManager.inTransaction { replace(frameId, fragment) } } -fun Fragment.addFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) { +fun VectorBaseFragment.replaceFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + parentFragmentManager.inTransaction { + replace(frameId, fragmentClass, params.toMvRxBundle(), tag) + } +} + +fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { parentFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } } -fun Fragment.addChildFragment(fragment: Fragment, frameId: Int) { +fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + parentFragmentManager.inTransaction { + replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) + } +} + +fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment) { childFragmentManager.inTransaction { add(frameId, fragment) } } -fun Fragment.replaceChildFragment(fragment: Fragment, frameId: Int) { +fun VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + childFragmentManager.inTransaction { + add(frameId, fragmentClass, params.toMvRxBundle(), tag) + } +} + +fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment) { childFragmentManager.inTransaction { replace(frameId, fragment) } } -fun Fragment.addChildFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) { +fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + childFragmentManager.inTransaction { + replace(frameId, fragmentClass, params.toMvRxBundle(), tag) + } +} + +fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { childFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } } + +fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { + childFragmentManager.inTransaction { + replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) + } +} diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt index 3b80d6d794..ede99e4f28 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt @@ -19,6 +19,7 @@ package im.vector.riotx.core.platform import android.content.Context import android.content.res.Configuration import android.os.Bundle +import android.os.Parcelable import android.view.Menu import android.view.MenuItem import android.view.View @@ -26,7 +27,6 @@ import androidx.annotation.* import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible -import androidx.fragment.app.FragmentFactory import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider @@ -35,6 +35,7 @@ import butterknife.BindView import butterknife.ButterKnife import butterknife.Unbinder import com.airbnb.mvrx.BaseMvRxActivity +import com.airbnb.mvrx.MvRx import com.bumptech.glide.util.Util import com.google.android.material.snackbar.Snackbar import im.vector.riotx.BuildConfig @@ -332,6 +333,10 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector { } } + fun Parcelable?.toMvRxBundle(): Bundle? { + return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } } + } + // ============================================================================================== // Handle loading view (also called waiting view or spinner view) // ============================================================================================== diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt index 34953bec33..206a1bab06 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt @@ -63,6 +63,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity) navigator = screenComponent.navigator() viewModelFactory = screenComponent.viewModelFactory() + childFragmentManager.fragmentFactory = screenComponent.fragmentFactory() injectWith(injector()) super.onAttach(context) } @@ -137,7 +138,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { arguments = args.toMvRxBundle() } - protected fun Parcelable?.toMvRxBundle(): Bundle? { + fun Parcelable?.toMvRxBundle(): Bundle? { return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } } } diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorPreferenceFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorPreferenceFragment.kt deleted file mode 100644 index d534cd2297..0000000000 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorPreferenceFragment.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.core.platform - -import androidx.annotation.CallSuper -import androidx.preference.PreferenceFragmentCompat -import im.vector.riotx.R -import im.vector.riotx.core.utils.toast -import timber.log.Timber - -abstract class VectorPreferenceFragment : PreferenceFragmentCompat() { - - val vectorActivity: VectorBaseActivity by lazy { - activity as VectorBaseActivity - } - - abstract var titleRes: Int - - /* ========================================================================================== - * Life cycle - * ========================================================================================== */ - - @CallSuper - override fun onResume() { - super.onResume() - - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(titleRes) - Timber.v("onResume Fragment ${this.javaClass.simpleName}") - } - - /* ========================================================================================== - * Protected - * ========================================================================================== */ - - protected fun notImplemented() { - // Snackbar cannot be display on PreferenceFragment - // Snackbar.make(view!!, R.string.not_implemented, Snackbar.LENGTH_SHORT) - activity?.toast(R.string.not_implemented) - } -} diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index a9c20a9ec5..3f5808949b 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -56,7 +56,6 @@ object CommandParser { return ParsedCommand.ErrorEmptySlashCommand } - return when (val slashCommand = messageParts.first()) { Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt index d74a9e9f4f..cd5dc38c3d 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt @@ -22,9 +22,10 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders -import im.vector.fragments.keysbackup.restore.KeysBackupRestoreFromPassphraseFragment import im.vector.riotx.R +import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.extensions.observeEvent +import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.SimpleFragmentActivity class KeysBackupRestoreActivity : SimpleFragmentActivity() { @@ -49,13 +50,9 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() { if (keyVersion != null && supportFragmentManager.fragments.isEmpty()) { val isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null if (isBackupCreatedFromPassphrase) { - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupRestoreFromPassphraseFragment.newInstance()) - .commitNow() + replaceFragment(R.id.container, KeysBackupRestoreFromPassphraseFragment::class.java) } else { - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupRestoreFromKeyFragment.newInstance()) - .commitNow() + replaceFragment(R.id.container, KeysBackupRestoreFromKeyFragment::class.java) } } }) @@ -80,16 +77,11 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() { viewModel.navigateEvent.observeEvent(this) { uxStateEvent -> when (uxStateEvent) { KeysBackupRestoreSharedViewModel.NAVIGATE_TO_RECOVER_WITH_KEY -> { - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupRestoreFromKeyFragment.newInstance()) - .addToBackStack(null) - .commit() + addFragmentToBackstack(R.id.container, KeysBackupRestoreFromKeyFragment::class.java) } KeysBackupRestoreSharedViewModel.NAVIGATE_TO_SUCCESS -> { supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupRestoreSuccessFragment.newInstance()) - .commit() + replaceFragment(R.id.container, KeysBackupRestoreSuccessFragment::class.java) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt index 3c9ebc3a50..c30393dd5f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt @@ -28,15 +28,15 @@ import butterknife.OnClick import butterknife.OnTextChanged import com.google.android.material.textfield.TextInputLayout import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.utils.startImportTextFromFileIntent import timber.log.Timber +import javax.inject.Inject -class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() { +class KeysBackupRestoreFromKeyFragment @Inject constructor() + : VectorBaseFragment() { companion object { - fun newInstance() = KeysBackupRestoreFromKeyFragment() private const val REQUEST_TEXT_FILE_GET = 1 } @@ -51,10 +51,6 @@ class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() { @BindView(R.id.keys_restore_key_enter_edittext) lateinit var mKeyTextEdit: EditText - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromKeyViewModel::class.java) @@ -72,7 +68,7 @@ class KeysBackupRestoreFromKeyFragment : VectorBaseFragment() { } mKeyInputLayout.error = viewModel.recoveryCodeErrorText.value - viewModel.recoveryCodeErrorText.observe(this, Observer { newValue -> + viewModel.recoveryCodeErrorText.observe(viewLifecycleOwner, Observer { newValue -> mKeyInputLayout.error = newValue }) } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt index c70796e09d..d4468081b8 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package im.vector.fragments.keysbackup.restore +package im.vector.riotx.features.crypto.keysbackup.restore import android.content.Context import android.os.Bundle @@ -33,13 +33,11 @@ import butterknife.OnClick import butterknife.OnTextChanged import com.google.android.material.textfield.TextInputLayout import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.showPassword import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel -import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel +import javax.inject.Inject -class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() { +class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_passphrase @@ -63,14 +61,6 @@ class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() { viewModel.showPasswordMode.value = !(viewModel.showPasswordMode.value ?: false) } - companion object { - fun newInstance() = KeysBackupRestoreFromPassphraseFragment() - } - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) @@ -79,13 +69,13 @@ class KeysBackupRestoreFromPassphraseFragment : VectorBaseFragment() { ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) } ?: throw Exception("Invalid Activity") - viewModel.passphraseErrorText.observe(this, Observer { newValue -> + viewModel.passphraseErrorText.observe(viewLifecycleOwner, Observer { newValue -> mPassphraseInputLayout.error = newValue }) helperTextWithLink.text = spannableStringForHelperText(context!!) - viewModel.showPasswordMode.observe(this, Observer { + viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer { val shouldBeVisible = it ?: false mPassphraseTextEdit.showPassword(shouldBeVisible) mPassphraseReveal.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index cb55d664ec..25be8ded47 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -21,11 +21,11 @@ import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.utils.LiveEvent +import javax.inject.Inject -class KeysBackupRestoreSuccessFragment : VectorBaseFragment() { +class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_success @@ -36,10 +36,6 @@ class KeysBackupRestoreSuccessFragment : VectorBaseFragment() { private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) sharedViewModel = activity?.run { 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 2dabaa792a..a58c99992d 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 @@ -23,6 +23,7 @@ import com.airbnb.mvrx.Loading import com.airbnb.mvrx.viewModel import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent +import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.SimpleFragmentActivity import im.vector.riotx.core.platform.WaitingViewData import javax.inject.Inject @@ -49,10 +50,7 @@ class KeysBackupManageActivity : SimpleFragmentActivity() { override fun initUiAndData() { super.initUiAndData() if (supportFragmentManager.fragments.isEmpty()) { - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupSettingsFragment.newInstance()) - .commitNow() - + replaceFragment(R.id.container, KeysBackupSettingsFragment::class.java) viewModel.init() } 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 2194ca9871..288d862413 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 @@ -21,29 +21,20 @@ import androidx.appcompat.app.AlertDialog import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity import kotlinx.android.synthetic.main.fragment_keys_backup_settings.* import javax.inject.Inject -class KeysBackupSettingsFragment : VectorBaseFragment(), - KeysBackupSettingsRecyclerViewController.Listener { - - companion object { - fun newInstance() = KeysBackupSettingsFragment() - } +class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController) + : VectorBaseFragment(), + KeysBackupSettingsRecyclerViewController.Listener { override fun getLayoutResId() = R.layout.fragment_keys_backup_settings - @Inject lateinit var keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController private val viewModel: KeysBackupSettingsViewModel by activityViewModel() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 6868fb84bb..8491435d3a 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -26,6 +26,7 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.riotx.R import im.vector.riotx.core.dialogs.ExportKeysDialog import im.vector.riotx.core.extensions.observeEvent +import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.SimpleFragmentActivity import im.vector.riotx.core.utils.* import im.vector.riotx.features.crypto.keys.KeysExporter @@ -39,9 +40,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() { override fun initUiAndData() { super.initUiAndData() if (isFirstCreation()) { - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupSetupStep1Fragment.newInstance()) - .commitNow() + replaceFragment(R.id.container, KeysBackupSetupStep1Fragment::class.java) } viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) @@ -67,15 +66,11 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() { when (uxStateEvent) { KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_2 -> { supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupSetupStep2Fragment.newInstance()) - .commit() + replaceFragment(R.id.container, KeysBackupSetupStep2Fragment::class.java) } KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_3 -> { supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) - supportFragmentManager.beginTransaction() - .replace(R.id.container, KeysBackupSetupStep3Fragment.newInstance()) - .commit() + replaceFragment(R.id.container, KeysBackupSetupStep3Fragment::class.java) } KeysBackupSetupSharedViewModel.NAVIGATE_FINISH -> { val resultIntent = Intent() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index 8ece6af714..fd7a95bff1 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -25,11 +25,11 @@ import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.utils.LiveEvent +import javax.inject.Inject -class KeysBackupSetupStep1Fragment : VectorBaseFragment() { +class KeysBackupSetupStep1Fragment @Inject constructor(): VectorBaseFragment() { companion object { fun newInstance() = KeysBackupSetupStep1Fragment() @@ -45,10 +45,6 @@ class KeysBackupSetupStep1Fragment : VectorBaseFragment() { @BindView(R.id.keys_backup_setup_step1_manualExport) lateinit var manualExportButton: Button - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt index f4717fa7b3..21e4747a4e 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt @@ -30,13 +30,13 @@ import butterknife.OnTextChanged import com.google.android.material.textfield.TextInputLayout import com.nulabinc.zxcvbn.Zxcvbn import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.showPassword import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.PasswordStrengthBar import im.vector.riotx.features.settings.VectorLocale +import javax.inject.Inject -class KeysBackupSetupStep2Fragment : VectorBaseFragment() { +class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step2 @@ -76,10 +76,6 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() { private lateinit var viewModel: KeysBackupSetupSharedViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) @@ -96,7 +92,7 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() { * ========================================================================================== */ private fun bindViewToViewModel() { - viewModel.passwordStrength.observe(this, Observer { strength -> + viewModel.passwordStrength.observe(viewLifecycleOwner, Observer { strength -> if (strength == null) { mPassphraseProgressLevel.strength = 0 mPassphraseInputLayout.error = null @@ -120,7 +116,7 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() { } }) - viewModel.passphrase.observe(this, Observer { newValue -> + viewModel.passphrase.observe(viewLifecycleOwner, Observer { newValue -> if (newValue.isEmpty()) { viewModel.passwordStrength.value = null } else { @@ -135,21 +131,21 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() { mPassphraseTextEdit.setText(viewModel.passphrase.value) - viewModel.passphraseError.observe(this, Observer { + viewModel.passphraseError.observe(viewLifecycleOwner, Observer { TransitionManager.beginDelayedTransition(rootGroup) mPassphraseInputLayout.error = it }) mPassphraseConfirmTextEdit.setText(viewModel.confirmPassphrase.value) - viewModel.showPasswordMode.observe(this, Observer { + viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer { val shouldBeVisible = it ?: false mPassphraseTextEdit.showPassword(shouldBeVisible) mPassphraseConfirmTextEdit.showPassword(shouldBeVisible) mPassphraseReveal.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black) }) - viewModel.confirmPassphraseError.observe(this, Observer { + viewModel.confirmPassphraseError.observe(viewLifecycleOwner, Observer { TransitionManager.beginDelayedTransition(rootGroup) mPassphraseConfirmInputLayout.error = it }) @@ -203,8 +199,4 @@ class KeysBackupSetupStep2Fragment : VectorBaseFragment() { } } } - - companion object { - fun newInstance() = KeysBackupSetupStep2Fragment() - } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index a5cc0510da..008e1b8aef 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -30,7 +30,6 @@ import butterknife.BindView import butterknife.OnClick import com.google.android.material.bottomsheet.BottomSheetDialog import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.files.addEntryToDownloadManager import im.vector.riotx.core.files.writeToFile import im.vector.riotx.core.platform.VectorBaseFragment @@ -40,8 +39,9 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import javax.inject.Inject -class KeysBackupSetupStep3Fragment : VectorBaseFragment() { +class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step3 @@ -54,16 +54,8 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() { @BindView(R.id.keys_backup_setup_step3_line2_text) lateinit var mRecoveryKeyLabel2TextView: TextView - companion object { - fun newInstance() = KeysBackupSetupStep3Fragment() - } - private lateinit var viewModel: KeysBackupSetupSharedViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = activity?.run { @@ -72,7 +64,7 @@ class KeysBackupSetupStep3Fragment : VectorBaseFragment() { viewModel.shouldPromptOnBack = false - viewModel.passphrase.observe(this, Observer { + viewModel.passphrase.observe(viewLifecycleOwner, Observer { if (it.isNullOrBlank()) { // Recovery was generated, so show key and options to save mRecoveryKeyLabel2TextView.text = getString(R.string.keys_backup_setup_step3_text_line2_no_passphrase) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt index a7fb4c67f3..3890479d91 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt @@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTr import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState import im.vector.riotx.R +import im.vector.riotx.core.extensions.inTransaction import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.SimpleFragmentActivity import im.vector.riotx.core.platform.WaitingViewData @@ -102,23 +103,23 @@ class SASVerificationActivity : SimpleFragmentActivity() { IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT, IncomingSasVerificationTransaction.UxState.WAIT_FOR_KEY_AGREEMENT -> { supportActionBar?.setTitle(R.string.sas_incoming_request_title) - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationIncomingFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationIncomingFragment::class.java, null) + } } IncomingSasVerificationTransaction.UxState.WAIT_FOR_VERIFICATION, IncomingSasVerificationTransaction.UxState.SHOW_SAS -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationShortCodeFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) + } } IncomingSasVerificationTransaction.UxState.VERIFIED -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationVerifiedFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) + } } IncomingSasVerificationTransaction.UxState.CANCELLED_BY_ME, IncomingSasVerificationTransaction.UxState.CANCELLED_BY_OTHER -> { @@ -133,23 +134,23 @@ class SASVerificationActivity : SimpleFragmentActivity() { OutgoingSasVerificationRequest.UxState.UNKNOWN, OutgoingSasVerificationRequest.UxState.WAIT_FOR_START, OutgoingSasVerificationRequest.UxState.WAIT_FOR_KEY_AGREEMENT -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationStartFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationStartFragment::class.java, null) + } } OutgoingSasVerificationRequest.UxState.SHOW_SAS, OutgoingSasVerificationRequest.UxState.WAIT_FOR_VERIFICATION -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationShortCodeFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) + } } OutgoingSasVerificationRequest.UxState.VERIFIED -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationVerifiedFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) + } } OutgoingSasVerificationRequest.UxState.CANCELLED_BY_ME, OutgoingSasVerificationRequest.UxState.CANCELLED_BY_OTHER -> { @@ -172,16 +173,16 @@ class SASVerificationActivity : SimpleFragmentActivity() { finish() } SasVerificationViewModel.NAVIGATE_SAS_DISPLAY -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationShortCodeFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) + } } SasVerificationViewModel.NAVIGATE_SUCCESS -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) - .replace(R.id.container, SASVerificationVerifiedFragment.newInstance()) - .commitNow() + supportFragmentManager.inTransaction { + setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) + replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) + } } SasVerificationViewModel.NAVIGATE_CANCELLED -> { val isCancelledByMe = viewModel.transaction?.state == SasVerificationTxState.Cancelled diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt index d8d36e0a1d..9bb3661bd7 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt @@ -24,16 +24,13 @@ import butterknife.BindView import butterknife.OnClick import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.home.AvatarRenderer import javax.inject.Inject -class SASVerificationIncomingFragment : VectorBaseFragment() { - - companion object { - fun newInstance() = SASVerificationIncomingFragment() - } +class SASVerificationIncomingFragment @Inject constructor( + private var avatarRenderer: AvatarRenderer +) : VectorBaseFragment() { @BindView(R.id.sas_incoming_request_user_display_name) lateinit var otherUserDisplayNameTextView: TextView @@ -49,13 +46,8 @@ class SASVerificationIncomingFragment : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_sas_verification_incoming_request - @Inject lateinit var avatarRenderer: AvatarRenderer private lateinit var viewModel: SasVerificationViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) @@ -74,7 +66,7 @@ class SASVerificationIncomingFragment : VectorBaseFragment() { avatarRenderer.render(null, viewModel.otherUserId ?: "", viewModel.otherUserId, avatarImageView) } - viewModel.transactionState.observe(this, Observer { + viewModel.transactionState.observe(viewLifecycleOwner, Observer { val uxState = (viewModel.transaction as? IncomingSasVerificationTransaction)?.uxState when (uxState) { IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt index 1c5488c0cd..da19d48bfe 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt @@ -28,15 +28,12 @@ import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTr import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment +import javax.inject.Inject -class SASVerificationShortCodeFragment : VectorBaseFragment() { +class SASVerificationShortCodeFragment @Inject constructor(): VectorBaseFragment() { private lateinit var viewModel: SasVerificationViewModel - companion object { - fun newInstance() = SASVerificationShortCodeFragment() - } - @BindView(R.id.sas_decimal_code) lateinit var decimalTextView: TextView @@ -120,7 +117,7 @@ class SASVerificationShortCodeFragment : VectorBaseFragment() { } } - viewModel.transactionState.observe(this, Observer { + viewModel.transactionState.observe(viewLifecycleOwner, Observer { if (viewModel.transaction is IncomingSasVerificationTransaction) { val uxState = (viewModel.transaction as IncomingSasVerificationTransaction).uxState when (uxState) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt index c101b8f9b4..97a29d9b7b 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt @@ -31,12 +31,9 @@ import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRe import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseFragment +import javax.inject.Inject -class SASVerificationStartFragment : VectorBaseFragment() { - - companion object { - fun newInstance() = SASVerificationStartFragment() - } +class SASVerificationStartFragment @Inject constructor(): VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_sas_verification_start @@ -57,7 +54,7 @@ class SASVerificationStartFragment : VectorBaseFragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProviders.of(vectorBaseActivity, viewModelFactory).get(SasVerificationViewModel::class.java) - viewModel.transactionState.observe(this, Observer { + viewModel.transactionState.observe(viewLifecycleOwner, Observer { val uxState = (viewModel.transaction as? OutgoingSasVerificationRequest)?.uxState when (uxState) { OutgoingSasVerificationRequest.UxState.WAIT_FOR_KEY_AGREEMENT -> { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt index b9d0546f3a..59825c8282 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt @@ -20,15 +20,12 @@ import androidx.lifecycle.ViewModelProviders import butterknife.OnClick import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment +import javax.inject.Inject -class SASVerificationVerifiedFragment : VectorBaseFragment() { +class SASVerificationVerifiedFragment @Inject constructor() : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_sas_verification_verified - companion object { - fun newInstance() = SASVerificationVerifiedFragment() - } - private lateinit var viewModel: SasVerificationViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index af367164fc..200b79925b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -79,10 +79,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { navigationViewModel = ViewModelProviders.of(this).get(HomeNavigationViewModel::class.java) drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { - val homeDrawerFragment = HomeDrawerFragment.newInstance() - val loadingDetail = LoadingFragment.newInstance() - replaceFragment(loadingDetail, R.id.homeDetailFragmentContainer) - replaceFragment(homeDrawerFragment, R.id.homeDrawerFragmentContainer) + replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) + replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java) } navigationViewModel.navigateTo.observeEvent(this) { navigation -> @@ -90,8 +88,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) is Navigation.OpenGroup -> { drawerLayout.closeDrawer(GravityCompat.START) - val homeDetailFragment = HomeDetailFragment.newInstance() - replaceFragment(homeDetailFragment, R.id.homeDetailFragmentContainer) + replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java) } } } 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 38fe491bd3..874b566e16 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 @@ -29,8 +29,7 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent -import im.vector.riotx.core.extensions.inTransaction +import im.vector.riotx.core.extensions.addChildFragmentToBackstack import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.KeysBackupBanner @@ -46,25 +45,21 @@ private const val INDEX_CATCHUP = 0 private const val INDEX_PEOPLE = 1 private const val INDEX_ROOMS = 2 -class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { +class HomeDetailFragment @Inject constructor( + private val session: Session, + val homeDetailViewModelFactory: HomeDetailViewModel.Factory, + private val avatarRenderer: AvatarRenderer +) : VectorBaseFragment(), KeysBackupBanner.Delegate { private val unreadCounterBadgeViews = arrayListOf() private val viewModel: HomeDetailViewModel by fragmentViewModel() private lateinit var navigationViewModel: HomeNavigationViewModel - @Inject lateinit var session: Session - @Inject lateinit var homeDetailViewModelFactory: HomeDetailViewModel.Factory - @Inject lateinit var avatarRenderer: AvatarRenderer - override fun getLayoutResId(): Int { return R.layout.fragment_home_detail } - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) @@ -100,7 +95,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { model.init(session) - model.keysBackupState.observe(this, Observer { keysBackupState -> + model.keysBackupState.observe(viewLifecycleOwner, Observer { keysBackupState -> when (keysBackupState) { null -> homeKeysBackupBanner.render(KeysBackupBanner.State.Hidden, false) @@ -175,15 +170,11 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { val fragmentTag = "FRAGMENT_TAG_${displayMode.name}" val fragment = childFragmentManager.findFragmentByTag(fragmentTag) if (fragment == null) { - childFragmentManager.inTransaction { - replace(R.id.roomListContainer, RoomListFragment::class.java, RoomListParams(displayMode).toMvRxBundle(), fragmentTag).addToBackStack(fragmentTag) - } + val params = RoomListParams(displayMode) + addChildFragmentToBackstack(R.id.roomListContainer, RoomListFragment::class.java, params, fragmentTag) } else { - childFragmentManager.inTransaction { - replace(R.id.roomListContainer, fragment, fragmentTag).addToBackStack(fragmentTag) - } + addChildFragmentToBackstack(R.id.roomListContainer, fragment, fragmentTag) } - } /* ========================================================================================== @@ -205,11 +196,4 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate { unreadCounterBadgeViews[INDEX_ROOMS].render(UnreadCounterBadgeView.State(it.notificationCountRooms, it.notificationHighlightRooms)) syncStateView.render(it.syncState) } - - companion object { - - fun newInstance(): HomeDetailFragment { - return HomeDetailFragment() - } - } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt index e5f0c5b2d3..5b052f5ff5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt @@ -19,7 +19,6 @@ package im.vector.riotx.features.home import android.os.Bundle import im.vector.matrix.android.api.session.Session import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.observeK import im.vector.riotx.core.extensions.replaceChildFragment import im.vector.riotx.core.platform.VectorBaseFragment @@ -27,29 +26,17 @@ import im.vector.riotx.features.home.group.GroupListFragment import kotlinx.android.synthetic.main.fragment_home_drawer.* import javax.inject.Inject -class HomeDrawerFragment : VectorBaseFragment() { - - companion object { - - fun newInstance(): HomeDrawerFragment { - return HomeDrawerFragment() - } - } - - @Inject lateinit var session: Session - @Inject lateinit var avatarRenderer: AvatarRenderer +class HomeDrawerFragment @Inject constructor( + private val session: Session, + private val avatarRenderer: AvatarRenderer +) : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_home_drawer - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) if (savedInstanceState == null) { - val groupListFragment = GroupListFragment.newInstance() - replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer) + replaceChildFragment(R.id.homeDrawerGroupListContainer, GroupListFragment::class.java) } session.liveUser(session.myUserId).observeK(this) { optionalUser -> val user = optionalUser?.getOrNull() diff --git a/vector/src/main/java/im/vector/riotx/features/home/LoadingFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/LoadingFragment.kt index 379ac69154..e376514955 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/LoadingFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/LoadingFragment.kt @@ -22,15 +22,9 @@ import android.view.View import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment import kotlinx.android.synthetic.main.fragment_loading.* +import javax.inject.Inject -class LoadingFragment : VectorBaseFragment() { - - companion object { - - fun newInstance(): LoadingFragment { - return LoadingFragment() - } - } +class LoadingFragment @Inject constructor(): VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_loading diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index a94b2b85da..af1cfe89a3 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -61,13 +61,13 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) navigationViewModel.navigateTo.observeEvent(this) { navigation -> when (navigation) { - is Navigation.UsersDirectory -> addFragmentToBackstack(CreateDirectRoomDirectoryUsersFragment(), R.id.container) + is Navigation.UsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) Navigation.Close -> finish() Navigation.Previous -> onBackPressed() } } if (isFirstCreation()) { - addFragment(CreateDirectRoomKnownUsersFragment(), R.id.container) + addFragment(R.id.container, CreateDirectRoomKnownUsersFragment::class.java) } viewModel.selectSubscribe(this, CreateDirectRoomViewState::createAndInviteState) { renderCreateAndInviteState(it) diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 6125d1b6b9..3e8f2e0780 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -25,26 +25,22 @@ import com.airbnb.mvrx.withState import com.jakewharton.rxbinding3.widget.textChanges import im.vector.matrix.android.api.session.user.model.User import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.hideKeyboard import im.vector.riotx.core.extensions.setupAsSearch import im.vector.riotx.core.platform.VectorBaseFragment import kotlinx.android.synthetic.main.fragment_create_direct_room_directory_users.* import javax.inject.Inject -class CreateDirectRoomDirectoryUsersFragment : VectorBaseFragment(), DirectoryUsersController.Callback { +class CreateDirectRoomDirectoryUsersFragment @Inject constructor( + private val directRoomController: DirectoryUsersController +) : VectorBaseFragment(), DirectoryUsersController.Callback { override fun getLayoutResId() = R.layout.fragment_create_direct_room_directory_users private val viewModel: CreateDirectRoomViewModel by activityViewModel() - @Inject lateinit var directRoomController: DirectoryUsersController private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigationViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 04e8d16fd7..a05bbf1a21 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -31,33 +31,26 @@ import com.google.android.material.chip.ChipGroup import com.jakewharton.rxbinding3.widget.textChanges import im.vector.matrix.android.api.session.user.model.User import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.hideKeyboard import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.extensions.setupAsSearch import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.utils.DimensionConverter -import im.vector.riotx.features.home.AvatarRenderer import kotlinx.android.synthetic.main.fragment_create_direct_room.* import javax.inject.Inject -class CreateDirectRoomKnownUsersFragment : VectorBaseFragment(), KnownUsersController.Callback { +class CreateDirectRoomKnownUsersFragment @Inject constructor( + private val directRoomController: KnownUsersController, + private val dimensionConverter: DimensionConverter +) : VectorBaseFragment(), KnownUsersController.Callback { override fun getLayoutResId() = R.layout.fragment_create_direct_room override fun getMenuRes() = R.menu.vector_create_direct_room private val viewModel: CreateDirectRoomViewModel by activityViewModel() - - @Inject lateinit var directRoomController: KnownUsersController - @Inject lateinit var avatarRenderer: AvatarRenderer - @Inject lateinit var dimensionConverter: DimensionConverter private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigationViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) 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 54c2044ae4..d3fb40f6dc 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 @@ -23,7 +23,6 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment @@ -32,26 +31,16 @@ import im.vector.riotx.features.home.HomeNavigationViewModel import kotlinx.android.synthetic.main.fragment_group_list.* import javax.inject.Inject -class GroupListFragment : VectorBaseFragment(), GroupSummaryController.Callback { - - companion object { - fun newInstance(): GroupListFragment { - return GroupListFragment() - } - } +class GroupListFragment @Inject constructor( + val groupListViewModelFactory: GroupListViewModel.Factory, + private val groupController: GroupSummaryController +) : VectorBaseFragment(), GroupSummaryController.Callback { private lateinit var navigationViewModel: HomeNavigationViewModel private val viewModel: GroupListViewModel by fragmentViewModel() - @Inject lateinit var groupListViewModelFactory: GroupListViewModel.Factory - @Inject lateinit var groupController: GroupSummaryController - override fun getLayoutResId() = R.layout.fragment_group_list - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigationViewModel = ViewModelProviders.of(requireActivity()).get(HomeNavigationViewModel::class.java) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActivity.kt index 91addb5744..eb8118a0c9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActivity.kt @@ -38,8 +38,7 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable { if (isFirstCreation()) { val roomDetailArgs: RoomDetailArgs = intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS) ?: return - val roomDetailFragment = RoomDetailFragment.newInstance(roomDetailArgs) - replaceFragment(roomDetailFragment, R.id.roomDetailContainer) + replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, roomDetailArgs) } } 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 76d01228b8..667fa9784b 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 @@ -68,7 +68,6 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent import im.vector.matrix.android.api.session.user.model.User import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.dialogs.withColoredButton import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer import im.vector.riotx.core.error.ErrorFormatter @@ -134,7 +133,22 @@ data class RoomDetailArgs( private const val REACTION_SELECT_REQUEST_CODE = 0 -class RoomDetailFragment : +class RoomDetailFragment @Inject constructor( + private val session: Session, + private val avatarRenderer: AvatarRenderer, + private val timelineEventController: TimelineEventController, + private val commandAutocompletePolicy: CommandAutocompletePolicy, + private val autocompleteCommandPresenter: AutocompleteCommandPresenter, + private val autocompleteUserPresenter: AutocompleteUserPresenter, + private val permalinkHandler: PermalinkHandler, + private val notificationDrawerManager: NotificationDrawerManager, + val roomDetailViewModelFactory: RoomDetailViewModel.Factory, + val textComposerViewModelFactory: TextComposerViewModel.Factory, + private val errorFormatter: ErrorFormatter, + private val eventHtmlRenderer: EventHtmlRenderer, + private val vectorPreferences: VectorPreferences, + private val readMarkerHelper: ReadMarkerHelper +) : VectorBaseFragment(), TimelineEventController.Callback, AutocompleteUserPresenter.Callback, @@ -145,12 +159,6 @@ class RoomDetailFragment : companion object { - fun newInstance(args: RoomDetailArgs): RoomDetailFragment { - return RoomDetailFragment().apply { - setArguments(args) - } - } - /**x * Sanitize the display name. * @@ -178,21 +186,6 @@ class RoomDetailFragment : private val debouncer = Debouncer(createUIHandler()) - @Inject lateinit var session: Session - @Inject lateinit var avatarRenderer: AvatarRenderer - @Inject lateinit var timelineEventController: TimelineEventController - @Inject lateinit var commandAutocompletePolicy: CommandAutocompletePolicy - @Inject lateinit var autocompleteCommandPresenter: AutocompleteCommandPresenter - @Inject lateinit var autocompleteUserPresenter: AutocompleteUserPresenter - @Inject lateinit var permalinkHandler: PermalinkHandler - @Inject lateinit var notificationDrawerManager: NotificationDrawerManager - @Inject lateinit var roomDetailViewModelFactory: RoomDetailViewModel.Factory - @Inject lateinit var textComposerViewModelFactory: TextComposerViewModel.Factory - @Inject lateinit var errorFormatter: ErrorFormatter - @Inject lateinit var eventHtmlRenderer: EventHtmlRenderer - @Inject lateinit var vectorPreferences: VectorPreferences - @Inject lateinit var readMarkerHelper: ReadMarkerHelper - private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback private lateinit var scrollOnHighlightedEventCallback: ScrollOnHighlightedEventCallback @@ -211,10 +204,6 @@ class RoomDetailFragment : private var lockSendButton = false - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java) @@ -959,6 +948,7 @@ class RoomDetailFragment : val roomId = roomDetailArgs.roomId this.view?.hideKeyboard() + MessageActionsBottomSheet .newInstance(roomId, informationData) .show(requireActivity().supportFragmentManager, "MESSAGE_CONTEXTUAL_ACTIONS") diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt index b9f8579dd5..a3302d40c3 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt @@ -30,7 +30,10 @@ import kotlinx.android.synthetic.main.activity_filtered_rooms.* class FilteredRoomsActivity : VectorBaseActivity() { - private lateinit var roomListFragment: RoomListFragment + private val roomListFragment: RoomListFragment? + get() { + return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? RoomListFragment + } override fun getLayoutRes(): Int { return R.layout.activity_filtered_rooms @@ -44,18 +47,16 @@ class FilteredRoomsActivity : VectorBaseActivity() { super.onCreate(savedInstanceState) configureToolbar(filteredRoomsToolbar) if (isFirstCreation()) { - replaceFragment(roomListFragment, R.id.filteredRoomsFragmentContainer, FRAGMENT_TAG) - } else { - roomListFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as RoomListFragment + val params = RoomListParams(RoomListFragment.DisplayMode.FILTERED) + replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG) } - filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { return true } override fun onQueryTextChange(newText: String): Boolean { - roomListFragment.filterRoomsWith(newText) + roomListFragment?.filterRoomsWith(newText) return true } }) 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 671559b73b..bd91d09aa7 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 @@ -31,7 +31,6 @@ import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.observeEvent @@ -73,11 +72,6 @@ class RoomListFragment @Inject constructor( override fun getLayoutResId() = R.layout.fragment_room_list - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - setArguments() - } - private var hasUnreadRooms = false override fun getMenuRes() = R.menu.room_list diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt index 2cb28be998..86156bc4d4 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt @@ -51,7 +51,7 @@ class LoginActivity : VectorBaseActivity() { override fun initUiAndData() { if (isFirstCreation()) { - addFragment(LoginFragment(), R.id.simpleFragmentContainer) + addFragment(R.id.simpleFragmentContainer, LoginFragment::class.java) } // Get config extra @@ -62,7 +62,7 @@ class LoginActivity : VectorBaseActivity() { loginViewModel.navigationLiveData.observeEvent(this) { when (it) { - is Navigation.OpenSsoLoginFallback -> addFragmentToBackstack(LoginSsoFallbackFragment(), R.id.simpleFragmentContainer) + is Navigation.OpenSsoLoginFallback -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginSsoFallbackFragment::class.java) is Navigation.GoBack -> supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) } } diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt index 3da21aa1df..7da8a79ac8 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt @@ -26,8 +26,6 @@ import com.airbnb.mvrx.* import com.jakewharton.rxbinding3.view.focusChanges import com.jakewharton.rxbinding3.widget.textChanges import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent -import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.setTextWithColoredPart import im.vector.riotx.core.extensions.showPassword import im.vector.riotx.core.platform.VectorBaseFragment @@ -43,20 +41,14 @@ import javax.inject.Inject * What can be improved: * - When filtering more (when entering new chars), we could filter on result we already have, during the new server request, to avoid empty screen effect */ -class LoginFragment : VectorBaseFragment() { +class LoginFragment @Inject constructor() : VectorBaseFragment() { private val viewModel: LoginViewModel by activityViewModel() private var passwordShown = false - @Inject lateinit var errorFormatter: ErrorFormatter - override fun getLayoutResId() = R.layout.fragment_login - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt index cac981db84..9e0cd611d1 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt @@ -35,17 +35,17 @@ import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.VectorBaseFragment import kotlinx.android.synthetic.main.fragment_login_sso_fallback.* import timber.log.Timber import java.net.URLDecoder +import javax.inject.Inject /** * Only login is supported for the moment */ -class LoginSsoFallbackFragment : VectorBaseFragment(), OnBackPressed { +class LoginSsoFallbackFragment @Inject constructor() : VectorBaseFragment(), OnBackPressed { private val viewModel: LoginViewModel by activityViewModel() @@ -62,10 +62,6 @@ class LoginSsoFallbackFragment : VectorBaseFragment(), OnBackPressed { override fun getLayoutResId() = R.layout.fragment_login_sso_fallback - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt index a4f443de1e..04fc99bbaa 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt @@ -24,12 +24,13 @@ import com.airbnb.epoxy.EpoxyRecyclerView import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.utils.LiveEvent import javax.inject.Inject -class EmojiSearchResultFragment : VectorBaseFragment() { +class EmojiSearchResultFragment @Inject constructor( + private val epoxyController: EmojiSearchResultController +) : VectorBaseFragment() { override fun getLayoutResId(): Int = R.layout.fragment_generic_recycler_epoxy @@ -37,12 +38,6 @@ class EmojiSearchResultFragment : VectorBaseFragment() { var sharedViewModel: EmojiChooserViewModel? = null - @Inject lateinit var epoxyController: EmojiSearchResultController - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) 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 955713c0f8..7de3b1dc1e 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 @@ -28,7 +28,6 @@ import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding3.appcompat.queryTextChanges import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.VectorBaseFragment @@ -42,22 +41,18 @@ import javax.inject.Inject * What can be improved: * - When filtering more (when entering new chars), we could filter on result we already have, during the new server request, to avoid empty screen effect */ -class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback { +class PublicRoomsFragment @Inject constructor( + private val publicRoomsController: PublicRoomsController, + private val errorFormatter: ErrorFormatter +) : VectorBaseFragment(), PublicRoomsController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel - @Inject lateinit var publicRoomsController: PublicRoomsController - @Inject lateinit var errorFormatter: ErrorFormatter - override fun getLayoutResId() = R.layout.fragment_public_rooms override fun getMenuRes() = R.menu.menu_room_directory - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) 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 b2dd13e59a..3bdcfa1c8d 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 @@ -65,8 +65,8 @@ class RoomDirectoryActivity : VectorBaseActivity() { navigationViewModel.navigateTo.observeEvent(this) { navigation -> when (navigation) { is Navigation.Back -> onBackPressed() - is Navigation.CreateRoom -> addFragmentToBackstack(CreateRoomFragment(), R.id.simpleFragmentContainer) - is Navigation.ChangeProtocol -> addFragmentToBackstack(RoomDirectoryPickerFragment(), R.id.simpleFragmentContainer) + is Navigation.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) + is Navigation.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) is Navigation.Close -> finish() } } @@ -79,7 +79,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { override fun initUiAndData() { if (isFirstCreation()) { - addFragment(PublicRoomsFragment(), R.id.simpleFragmentContainer) + addFragment(R.id.simpleFragmentContainer, PublicRoomsFragment::class.java) } } 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 9a3e903954..3cbd033fda 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 @@ -23,7 +23,6 @@ import androidx.appcompat.widget.Toolbar import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.viewModel import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.ToolbarConfigurable @@ -50,16 +49,11 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun initUiAndData() { if (isFirstCreation()) { - addFragment(CreateRoomFragment(), R.id.simpleFragmentContainer) - + addFragment(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) createRoomViewModel.setName(intent?.getStringExtra(INITIAL_NAME) ?: "") } } - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryNavigationViewModel::class.java) 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 acea19b49a..c772d6d15d 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 @@ -24,7 +24,6 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel @@ -32,20 +31,15 @@ import kotlinx.android.synthetic.main.fragment_create_room.* import timber.log.Timber import javax.inject.Inject -class CreateRoomFragment : VectorBaseFragment(), CreateRoomController.Listener { +class CreateRoomFragment @Inject constructor(private val createRoomController: CreateRoomController): VectorBaseFragment(), CreateRoomController.Listener { private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel private val viewModel: CreateRoomViewModel by activityViewModel() - @Inject lateinit var createRoomController: CreateRoomController override fun getLayoutResId() = R.layout.fragment_create_room override fun getMenuRes() = R.menu.vector_room_creation - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) 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 f338c71bbf..ef914f60ca 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 @@ -26,7 +26,6 @@ import com.airbnb.mvrx.fragmentViewModel 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.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel @@ -37,15 +36,14 @@ import javax.inject.Inject // TODO Set title to R.string.select_room_directory // TODO Menu to add custom room directory (not done in RiotWeb so far...) -class RoomDirectoryPickerFragment : VectorBaseFragment(), RoomDirectoryPickerController.Callback { +class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerViewModelFactory: RoomDirectoryPickerViewModel.Factory, + private val roomDirectoryPickerController: RoomDirectoryPickerController +) : VectorBaseFragment(), RoomDirectoryPickerController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel private val pickerViewModel: RoomDirectoryPickerViewModel by fragmentViewModel() - @Inject lateinit var roomDirectoryPickerViewModelFactory: RoomDirectoryPickerViewModel.Factory - @Inject lateinit var roomDirectoryPickerController: RoomDirectoryPickerController - override fun getLayoutResId() = R.layout.fragment_room_directory_picker override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -71,10 +69,6 @@ class RoomDirectoryPickerFragment : VectorBaseFragment(), RoomDirectoryPickerCon return super.onOptionsItemSelected(item) } - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java) diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt index e4fb122f7a..1bd138552e 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -67,9 +67,9 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { if (args.worldReadable) { // TODO Room preview: Note: M does not recommend to use /events anymore, so for now we just display the room preview // TODO the same way if it was not world readable - addFragment(RoomPreviewNoPreviewFragment.newInstance(args), R.id.simpleFragmentContainer) + addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args) } else { - addFragment(RoomPreviewNoPreviewFragment.newInstance(args), R.id.simpleFragmentContainer) + addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args) } } } 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 e919b0096c..aff89e3b09 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 @@ -19,13 +19,11 @@ package im.vector.riotx.features.roomdirectory.roompreview import android.os.Bundle import android.view.View import androidx.core.view.isVisible -import androidx.fragment.app.Fragment import androidx.transition.TransitionManager import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.setTextOrHide import im.vector.riotx.core.platform.ButtonStateView @@ -38,24 +36,15 @@ import javax.inject.Inject /** * Note: this Fragment is also used for world readable room for the moment */ -class RoomPreviewNoPreviewFragment : VectorBaseFragment() { +class RoomPreviewNoPreviewFragment @Inject constructor( + private val errorFormatter: ErrorFormatter, + val roomPreviewViewModelFactory: RoomPreviewViewModel.Factory, + private val avatarRenderer: AvatarRenderer +) : VectorBaseFragment() { - companion object { - fun newInstance(arg: RoomPreviewData): Fragment { - return RoomPreviewNoPreviewFragment().apply { setArguments(arg) } - } - } - - @Inject lateinit var errorFormatter: ErrorFormatter - @Inject lateinit var roomPreviewViewModelFactory: RoomPreviewViewModel.Factory - @Inject lateinit var avatarRenderer: AvatarRenderer private val roomPreviewViewModel: RoomPreviewViewModel by fragmentViewModel() private val roomPreviewData: RoomPreviewData by args() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) setupToolbar(roomPreviewNoPreviewToolbar) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt index cd74dd7016..36536994d5 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt @@ -76,9 +76,9 @@ class VectorSettingsActivity : VectorBaseActivity(), override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean { val oFragment = when { VectorPreferences.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref.key -> - VectorSettingsNotificationsTroubleshootFragment.newInstance() + supportFragmentManager.fragmentFactory.instantiate(classLoader, VectorSettingsNotificationsTroubleshootFragment::class.java.name) VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref.key -> - VectorSettingsAdvancedNotificationPreferenceFragment.newInstance() + supportFragmentManager.fragmentFactory.instantiate(classLoader, VectorSettingsAdvancedNotificationPreferenceFragment::class.java.name) else -> try { pref.fragment?.let { diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt index 380e043ecf..a8328fae52 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt @@ -24,14 +24,15 @@ import androidx.core.content.edit import androidx.preference.Preference import androidx.preference.PreferenceManager import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.preference.BingRule import im.vector.riotx.core.preference.BingRulePreference import im.vector.riotx.core.preference.VectorPreference import im.vector.riotx.features.notifications.NotificationUtils import javax.inject.Inject -class VectorSettingsAdvancedNotificationPreferenceFragment : VectorSettingsBaseFragment() { +class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor( + private val vectorPreferences: VectorPreferences +) : VectorSettingsBaseFragment() { // events listener /* TODO @@ -46,12 +47,6 @@ class VectorSettingsAdvancedNotificationPreferenceFragment : VectorSettingsBaseF override val preferenceXmlRes = R.xml.vector_settings_notification_advanced_preferences - @Inject lateinit var vectorPreferences: VectorPreferences - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun bindPref() { val callNotificationsSystemOptions = findPreference(VectorPreferences.SETTINGS_SYSTEM_CALL_NOTIFICATION_PREFERENCE_KEY)!! if (NotificationUtils.supportNotificationChannels()) { @@ -229,7 +224,5 @@ class VectorSettingsAdvancedNotificationPreferenceFragment : VectorSettingsBaseF VectorPreferences.SETTINGS_CALL_INVITATIONS_PREFERENCE_KEY to BingRule.RULE_ID_CALL, VectorPreferences.SETTINGS_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY to BingRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS ) - - fun newInstance() = VectorSettingsAdvancedNotificationPreferenceFragment() } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsHelpAboutFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsHelpAboutFragment.kt index a05ccb305d..6ce928c05d 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsHelpAboutFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsHelpAboutFragment.kt @@ -23,24 +23,19 @@ import androidx.preference.Preference import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import im.vector.matrix.android.api.Matrix import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.preference.VectorPreference import im.vector.riotx.core.utils.copyToClipboard import im.vector.riotx.core.utils.displayInWebView import im.vector.riotx.features.version.VersionProvider import javax.inject.Inject -class VectorSettingsHelpAboutFragment : VectorSettingsBaseFragment() { +class VectorSettingsHelpAboutFragment @Inject constructor( + private val versionProvider: VersionProvider +) : VectorSettingsBaseFragment() { override var titleRes = R.string.preference_root_help_about override val preferenceXmlRes = R.xml.vector_settings_help_about - @Inject lateinit var versionProvider: VersionProvider - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun bindPref() { // preference to start the App info screen, to facilitate App permissions access findPreference(APP_INFO_LINK_PREFERENCE_KEY)!! diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationPreferenceFragment.kt index cfb4c88259..b397cd1cf6 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationPreferenceFragment.kt @@ -24,22 +24,21 @@ import im.vector.matrix.android.api.pushrules.RuleIds import im.vector.matrix.android.api.pushrules.RuleKind import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.preference.VectorSwitchPreference import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.push.fcm.FcmHelper import javax.inject.Inject // Referenced in vector_settings_preferences_root.xml -class VectorSettingsNotificationPreferenceFragment : VectorSettingsBaseFragment() { +class VectorSettingsNotificationPreferenceFragment @Inject constructor( + private val pushManager: PushersManager, + private val activeSessionHolder: ActiveSessionHolder, + private val vectorPreferences: VectorPreferences +) : VectorSettingsBaseFragment() { override var titleRes: Int = R.string.settings_notifications override val preferenceXmlRes = R.xml.vector_settings_notifications - @Inject lateinit var pushManager: PushersManager - @Inject lateinit var activeSessionHolder: ActiveSessionHolder - @Inject lateinit var vectorPreferences: VectorPreferences - override fun bindPref() { findPreference(VectorPreferences.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY)!!.let { pref -> val pushRuleService = session @@ -57,10 +56,6 @@ class VectorSettingsNotificationPreferenceFragment : VectorSettingsBaseFragment( } } - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onResume() { super.onResume() activeSessionHolder.getSafeActiveSession()?.refreshPushers() diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt index 5737425a3b..6f43114eb4 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt @@ -28,9 +28,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.transition.TransitionManager import butterknife.BindView -import im.vector.matrix.android.api.session.Session import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.rageshake.BugReporter @@ -39,7 +37,10 @@ import im.vector.riotx.features.settings.troubleshoot.TroubleshootTest import im.vector.riotx.push.fcm.NotificationTroubleshootTestManagerFactory import javax.inject.Inject -class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() { +class VectorSettingsNotificationsTroubleshootFragment @Inject constructor( + private val bugReporter: BugReporter, + private val testManagerFactory: NotificationTroubleshootTestManagerFactory +) : VectorBaseFragment() { @BindView(R.id.troubleshoot_test_recycler_view) lateinit var mRecyclerView: RecyclerView @@ -54,18 +55,11 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() { private var testManager: NotificationTroubleshootTestManager? = null // members - @Inject lateinit var session: Session - @Inject lateinit var bugReporter: BugReporter - @Inject lateinit var testManagerFactory: NotificationTroubleshootTestManagerFactory override fun getLayoutResId() = R.layout.fragment_settings_notifications_troubleshoot private var interactionListener: VectorSettingsFragmentInteractionListener? = null - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -73,7 +67,7 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() { mRecyclerView.layoutManager = layoutManager val dividerItemDecoration = DividerItemDecoration(mRecyclerView.context, - layoutManager.orientation) + layoutManager.orientation) mRecyclerView.addItemDecoration(dividerItemDecoration) mSummaryButton.setOnClickListener { @@ -88,7 +82,7 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() { private fun startUI() { mSummaryDescription.text = getString(R.string.settings_troubleshoot_diagnostic_running_status, - 0, 0) + 0, 0) testManager = testManagerFactory.create(this) testManager?.statusListener = { troubleshootTestManager -> if (isAdded) { @@ -167,9 +161,4 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() { interactionListener = context } } - - companion object { - // static constructor - fun newInstance() = VectorSettingsNotificationsTroubleshootFragment() - } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt index ab81e6937e..9c240ad093 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt @@ -25,14 +25,16 @@ import androidx.appcompat.app.AlertDialog import androidx.preference.Preference import androidx.preference.SwitchPreference import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.preference.VectorListPreference import im.vector.riotx.core.preference.VectorPreference import im.vector.riotx.features.configuration.VectorConfiguration import im.vector.riotx.features.themes.ThemeUtils import javax.inject.Inject -class VectorSettingsPreferencesFragment : VectorSettingsBaseFragment() { +class VectorSettingsPreferencesFragment @Inject constructor( + private val vectorConfiguration: VectorConfiguration, + private val vectorPreferences: VectorPreferences +) : VectorSettingsBaseFragment() { override var titleRes = R.string.settings_preferences override val preferenceXmlRes = R.xml.vector_settings_preferences @@ -44,13 +46,6 @@ class VectorSettingsPreferencesFragment : VectorSettingsBaseFragment() { findPreference(VectorPreferences.SETTINGS_INTERFACE_TEXT_SIZE_KEY)!! } - @Inject lateinit var vectorConfiguration: VectorConfiguration - @Inject lateinit var vectorPreferences: VectorPreferences - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun bindPref() { // user interface preferences setUserInterfacePreferences() diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt index a78529f06c..b7ec443ea0 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -40,7 +40,6 @@ import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.dialogs.ExportKeysDialog import im.vector.riotx.core.intent.ExternalIntentData import im.vector.riotx.core.intent.analyseIntent @@ -60,7 +59,9 @@ import java.util.Date import java.util.Locale import javax.inject.Inject -class VectorSettingsSecurityPrivacyFragment : VectorSettingsBaseFragment() { +class VectorSettingsSecurityPrivacyFragment @Inject constructor( + private val vectorPreferences: VectorPreferences +) : VectorSettingsBaseFragment() { override var titleRes = R.string.settings_security_and_privacy override val preferenceXmlRes = R.xml.vector_settings_security_privacy @@ -128,12 +129,6 @@ class VectorSettingsSecurityPrivacyFragment : VectorSettingsBaseFragment() { findPreference(VectorPreferences.SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY)!! } - @Inject lateinit var vectorPreferences: VectorPreferences - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun bindPref() { // Push target refreshPushersList() diff --git a/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysFragment.kt index c20ba2e248..ea23ba2583 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/push/PushGatewaysFragment.kt @@ -24,7 +24,6 @@ import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R -import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.resources.StringProvider @@ -33,11 +32,12 @@ import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.* import javax.inject.Inject // Referenced in vector_settings_notifications.xml -class PushGatewaysFragment : VectorBaseFragment() { +class PushGatewaysFragment @Inject constructor( + val pushGatewaysViewModelFactory: PushGatewaysViewModel.Factory +) : VectorBaseFragment() { override fun getLayoutResId(): Int = R.layout.fragment_generic_recycler_epoxy - @Inject lateinit var pushGatewaysViewModelFactory: PushGatewaysViewModel.Factory private val viewModel: PushGatewaysViewModel by fragmentViewModel(PushGatewaysViewModel::class) private val epoxyController by lazy { PushGateWayController(StringProvider(requireContext().resources)) } @@ -46,10 +46,6 @@ class PushGatewaysFragment : VectorBaseFragment() { (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_notifications_targets) } - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) val lmgr = LinearLayoutManager(context, RecyclerView.VERTICAL, false) diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt index 5e471cf78b..1ec020e1a0 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt @@ -42,9 +42,12 @@ class IncomingShareActivity : @Inject lateinit var sessionHolder: ActiveSessionHolder @Inject lateinit var incomingShareViewModelFactory: IncomingShareViewModel.Factory - private var roomListFragment: RoomListFragment? = null private lateinit var attachmentsHelper: AttachmentsHelper private val incomingShareViewModel: IncomingShareViewModel by viewModel() + private val roomListFragment: RoomListFragment? + get() { + return supportFragmentManager.findFragmentById(R.id.shareRoomListFragmentContainer) as? RoomListFragment + } override fun getLayoutRes(): Int { return R.layout.activity_incoming_share @@ -64,8 +67,7 @@ class IncomingShareActivity : } configureToolbar(incomingShareToolbar) if (isFirstCreation()) { - val loadingDetail = LoadingFragment.newInstance() - replaceFragment(loadingDetail, R.id.shareRoomListFragmentContainer) + replaceFragment(R.id.shareRoomListFragmentContainer, LoadingFragment::class.java) } attachmentsHelper = AttachmentsHelper.create(this, this).register() if (intent?.action == Intent.ACTION_SEND || intent?.action == Intent.ACTION_SEND_MULTIPLE) { @@ -96,8 +98,7 @@ class IncomingShareActivity : override fun onContentAttachmentsReady(attachments: List) { val roomListParams = RoomListParams(RoomListFragment.DisplayMode.SHARE, sharedData = SharedData.Attachments(attachments)) - roomListFragment = RoomListFragment.newInstance(roomListParams) - .also { replaceFragment(it, R.id.shareRoomListFragmentContainer) } + replaceFragment(R.id.shareRoomListFragmentContainer, RoomListFragment::class.java, roomListParams) } override fun onAttachmentsProcessFailed() { @@ -116,8 +117,7 @@ class IncomingShareActivity : false } else { val roomListParams = RoomListParams(RoomListFragment.DisplayMode.SHARE, sharedData = SharedData.Text(sharedText)) - roomListFragment = RoomListFragment.newInstance(roomListParams) - .also { replaceFragment(it, R.id.shareRoomListFragmentContainer) } + replaceFragment(R.id.shareRoomListFragmentContainer, RoomListFragment::class.java, roomListParams) true } } From 219d1383e56c4803028b798d607f1c2b196cec6f Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 5 Nov 2019 18:13:55 +0100 Subject: [PATCH 057/117] Fragments: use FragmentContainerView --- vector/src/main/res/layout/activity.xml | 3 +-- vector/src/main/res/layout/activity_emoji_reaction_picker.xml | 4 ++-- vector/src/main/res/layout/activity_filtered_rooms.xml | 2 +- vector/src/main/res/layout/activity_incoming_share.xml | 2 +- vector/src/main/res/layout/activity_room_detail.xml | 2 +- vector/src/main/res/layout/activity_simple.xml | 2 +- vector/src/main/res/layout/fragment_home_drawer.xml | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/vector/src/main/res/layout/activity.xml b/vector/src/main/res/layout/activity.xml index df0cd3fbea..b5203cd589 100644 --- a/vector/src/main/res/layout/activity.xml +++ b/vector/src/main/res/layout/activity.xml @@ -1,7 +1,6 @@ @@ -13,7 +12,7 @@ android:elevation="4dp" app:layout_constraintTop_toTopOf="parent" /> - - - - - - diff --git a/vector/src/main/res/layout/activity_simple.xml b/vector/src/main/res/layout/activity_simple.xml index 3ffb112b60..8dc41487fe 100644 --- a/vector/src/main/res/layout/activity_simple.xml +++ b/vector/src/main/res/layout/activity_simple.xml @@ -1,5 +1,5 @@ - diff --git a/vector/src/main/res/layout/fragment_home_drawer.xml b/vector/src/main/res/layout/fragment_home_drawer.xml index 72371d251d..4e257eabd4 100644 --- a/vector/src/main/res/layout/fragment_home_drawer.xml +++ b/vector/src/main/res/layout/fragment_home_drawer.xml @@ -81,7 +81,7 @@ - Date: Tue, 5 Nov 2019 18:36:30 +0100 Subject: [PATCH 058/117] Clean code --- .../matrix/android/api/pushrules/PushrulesConditionTest.kt | 7 ------- .../java/im/vector/riotx/features/command/CommandParser.kt | 1 - .../riotx/features/share/ShareRoomListObservableStore.kt | 1 - 3 files changed, 9 deletions(-) diff --git a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt index 7cb3917195..a29f5d5542 100644 --- a/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/im/vector/matrix/android/api/pushrules/PushrulesConditionTest.kt @@ -25,12 +25,6 @@ import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.message.MessageTextContent import io.mockk.every import io.mockk.mockk -import org.amshove.kluent.When -import org.amshove.kluent.any -import org.amshove.kluent.calling -import org.amshove.kluent.itAnswers -import org.amshove.kluent.itReturns -import org.amshove.kluent.mock import org.junit.Assert import org.junit.Test @@ -183,5 +177,4 @@ class PushrulesConditionTest { Assert.assertTrue("Notice", conditionEqual.isSatisfied(it)) } } - } diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index a9c20a9ec5..3f5808949b 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -56,7 +56,6 @@ object CommandParser { return ParsedCommand.ErrorEmptySlashCommand } - return when (val slashCommand = messageParts.first()) { Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() diff --git a/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt b/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt index bf7dde65ab..32b0093b8f 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt @@ -18,7 +18,6 @@ package im.vector.riotx.features.share import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.core.utils.BehaviorStore -import im.vector.riotx.core.utils.RxStore import javax.inject.Inject import javax.inject.Singleton From d0c3271628876980b97d6eb0a3eed62e1db9ecb9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Nov 2019 18:19:37 +0100 Subject: [PATCH 059/117] Import string from Riot-Android and fix #671 --- CHANGES.md | 1 + .../src/main/res/values-bg/strings.xml | 1 + .../src/main/res/values-en-rGB/strings.xml | 5 + .../src/main/res/values-en-rUS/strings.xml | 11 -- .../src/main/res/values-ko/strings.xml | 4 +- .../src/main/res/values/strings.xml | 4 +- tools/import_from_riot.sh | 2 +- vector/src/main/res/values-ca/strings.xml | 12 +- vector/src/main/res/values-de/strings.xml | 72 +++++++-- vector/src/main/res/values-es-rMX/strings.xml | 5 + vector/src/main/res/values-es/strings.xml | 4 +- vector/src/main/res/values-eu/strings.xml | 69 +++++++++ vector/src/main/res/values-fi/strings.xml | 138 ++++++++++++------ vector/src/main/res/values-fr/strings.xml | 71 ++++++++- vector/src/main/res/values-hu/strings.xml | 69 +++++++++ vector/src/main/res/values-it/strings.xml | 69 +++++++++ vector/src/main/res/values-ko/strings.xml | 96 ++++++++++-- vector/src/main/res/values-ru/strings.xml | 5 + vector/src/main/res/values-zh-rTW/strings.xml | 68 +++++++++ vector/src/main/res/values/strings.xml | 3 - vector/src/main/res/values/strings_riotX.xml | 3 + 21 files changed, 616 insertions(+), 96 deletions(-) create mode 100644 matrix-sdk-android/src/main/res/values-en-rGB/strings.xml delete mode 100644 matrix-sdk-android/src/main/res/values-en-rUS/strings.xml diff --git a/CHANGES.md b/CHANGES.md index 093d2c0b86..aaef66fdd6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Bugfix 🐛: - Fix issues with some member events rendering (#498) - Passphrase does not match (Export room keys) (#644) - Ask for permission to write external storage when uri comes from the keyboard (#658) + - Fix issue with english US/GB translation (#671) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/res/values-bg/strings.xml b/matrix-sdk-android/src/main/res/values-bg/strings.xml index 85643c7ade..2566ee780c 100644 --- a/matrix-sdk-android/src/main/res/values-bg/strings.xml +++ b/matrix-sdk-android/src/main/res/values-bg/strings.xml @@ -172,4 +172,5 @@ Изпращане на съобщение… Изчисти опашката за изпращане + %1$s оттегли поканата за присъединяване на %2$s към стаята diff --git a/matrix-sdk-android/src/main/res/values-en-rGB/strings.xml b/matrix-sdk-android/src/main/res/values-en-rGB/strings.xml new file mode 100644 index 0000000000..f457e30ed0 --- /dev/null +++ b/matrix-sdk-android/src/main/res/values-en-rGB/strings.xml @@ -0,0 +1,5 @@ + + + Spanner + Aeroplane + diff --git a/matrix-sdk-android/src/main/res/values-en-rUS/strings.xml b/matrix-sdk-android/src/main/res/values-en-rUS/strings.xml deleted file mode 100644 index 09e9dfc111..0000000000 --- a/matrix-sdk-android/src/main/res/values-en-rUS/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - Wrench - Airplane - - - - diff --git a/matrix-sdk-android/src/main/res/values-ko/strings.xml b/matrix-sdk-android/src/main/res/values-ko/strings.xml index 959ff8a96e..9dfbb6609b 100644 --- a/matrix-sdk-android/src/main/res/values-ko/strings.xml +++ b/matrix-sdk-android/src/main/res/values-ko/strings.xml @@ -12,8 +12,8 @@ %1$s님이 떠났습니다 %1$s님이 초대를 거부했습니다 %1$s님이 %2$s님을 추방했습니다 - %1$s님이 %2$s님의 차단을 풀었습니다 - %1$s님이 %2$s님을 차단했습니다 + %1$s님이 %2$s님의 출입 금지를 풀었습니다 + %1$s님이 %2$s님을 출입 금지했습니다 %1$s님이 %2$s님의 초대를 취소했습니다 %1$s님이 아바타를 변경했습니다 %1$s님이 표시 이름을 %2$s(으)로 설정했습니다 diff --git a/matrix-sdk-android/src/main/res/values/strings.xml b/matrix-sdk-android/src/main/res/values/strings.xml index 604bb13a41..ce26c22137 100644 --- a/matrix-sdk-android/src/main/res/values/strings.xml +++ b/matrix-sdk-android/src/main/res/values/strings.xml @@ -170,7 +170,7 @@ Glasses - Spanner + Wrench Santa @@ -208,7 +208,7 @@ Bicycle - Aeroplane + Airplane Rocket diff --git a/tools/import_from_riot.sh b/tools/import_from_riot.sh index 3f93615d19..271a872a48 100755 --- a/tools/import_from_riot.sh +++ b/tools/import_from_riot.sh @@ -32,7 +32,7 @@ cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-da/strings.xml ./mat cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-de/strings.xml ./matrix-sdk-android/src/main/res/values-de/strings.xml cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-el/strings.xml ./matrix-sdk-android/src/main/res/values-el/strings.xml cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-eo/strings.xml ./matrix-sdk-android/src/main/res/values-eo/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-en-rUS/strings.xml ./matrix-sdk-android/src/main/res/values-en-rUS/strings.xml +cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-en-rGB/strings.xml ./matrix-sdk-android/src/main/res/values-en-rGB/strings.xml cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-es/strings.xml ./matrix-sdk-android/src/main/res/values-es/strings.xml cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-es-rMX/strings.xml ./matrix-sdk-android/src/main/res/values-es-rMX/strings.xml cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-eu/strings.xml ./matrix-sdk-android/src/main/res/values-eu/strings.xml diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index d9af5deb46..9be9a0c077 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -1430,13 +1430,13 @@ Per què triar Riot.im? Ho sentim, els dispositius amb SO Android inferior a 5.0 no suporten trucades multi-usuari amb Jitsi No heu configurat cap administrador d\'integracions. - Un nou dispositiu està sol·licitant claus d\'encriptació. -\nNom del dispositiu: %1$s -\nVist per última vegada: %s$s + Un nou dispositiu està sol·licitant claus d\'encriptació. +\nNom del dispositiu: %1$s +\nVist per última vegada: %2$s \nSi no heu iniciat sessió en un altre dispositiu, ignoreu la sol·licitud. - Un dispositiu no verificat està sol·licitant claus d\'encriptació. -\nNom del dispositiu: %1$s -\nVist per última vegada: %s$s + Un dispositiu no verificat està sol·licitant claus d\'encriptació. +\nNom del dispositiu: %1$s +\nVist per última vegada: %2$s \nSi no heu iniciat sessió en un altre dispositiu, ignoreu la sol·licitud. Verificar diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index b8b86b5081..356e3fdaaa 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -343,7 +343,7 @@ Bist du sicher? Nachrichten konnten nicht gesendet werden. %1$s oder %2$s? Nachrichten wurden nicht gesendet, da unbekannte Geräte anwesend sind. %1$s oder %2$s? Alles erneut senden - Senden abbrechen + alles abbrechen Nicht gesendete Nachrichten erneut senden Nicht gesendete Nachrichten löschen Datei nicht gefunden @@ -445,7 +445,7 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.Hintergrundsynchronisierung Hintergrundsynchronisierung aktivieren Timeout für Synchronisierungsanfragen - Verzögerung zwischen jeder Anfrage + Verzögerung zwischen jeder Synchronisierung Sekunde Sekunden @@ -473,10 +473,10 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.Räume mit ungelesenen Benachrichtigungen anheften Räume mit ungelesenen Nachrichten anheften Geräte - Geräte-Details + Geräte Information ID - Name - Gerätename + Öffentlicher Name + Öffentlichen Namen aktualisieren Zuletzt gesehen %1$s @ %2$s Diese Operation benötigt weitere Authentifizierung. @@ -607,9 +607,9 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.Entschlüsselungsfehler Absendergeräteinformationen - Gerätename - Name - Geräte-ID + Öffentlicher Name + Öffentlicher Name + ID Geräte-Schlüssel Verifizierungsstatus Ed25519-Fingerabdruck @@ -1552,8 +1552,8 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A Überprüfen Sie dieses Gerät, um es als vertrauenswürdig zu markieren. Das Vertrauen auf Geräte von Partnern gibt Ihnen zusätzliche Sicherheit, wenn Sie verschlüsselte End-to-End-Nachrichten verwenden. Das Verifizieren dieses Benutzers wird seine Geräte als \"vertraut\" markieren und dein Gerät bei ihnen als \"vertraut\" markieren. - Verifizieren Sie diesen Benutzer, indem Sie bestätigen, dass folgendes Emoji auf dessen Bildschirm erscheint. - Verifizieren Sie diesen Benutzer, indem Sie bestätigen, dass die folgende Nummer auf dessen Bildschirm erscheint. + Überprüfen Sie dieses Gerät, indem Sie bestätigen, dass das folgende Emoji auf dem Bildschirm des Partners angezeigt wird + Überprüfen Sie dieses Gerät, indem Sie bestätigen, dass die folgenden Zahlen auf dem Bildschirm des Partners angezeigt werden Es ist nichts aufgetaucht\? Noch nicht alle Clients unterstützen die interaktive Verifikation. . Verwenden Sie die Alte-Überprüfung @@ -1656,4 +1656,56 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A app_id: Überprüfung + Keine + Widerrufen + Trennen + Kein Integrationsserver konfiguriert. + + Anruf aufgrund eines falsch konfigurierten Servers fehlgeschlagen + Versuchen Sie es mit %@ + Nicht erneut fragen + + Richten Sie eine E-Mail für die Kontowiederherstellung ein, die später von Personen, die Sie kennen, optional gefunden werden kann. + Richten Sie ein Telefon ein und lassen Sie es später optional von Personen erkennen, die Sie kennen. + Legen Sie eine E-Mail für die Kontowiederherstellung fest. Verwenden Sie eine spätere E-Mail oder ein späteres Telefon, um von Personen, die Sie kennen, optional gefunden zu werden. + Legen Sie eine E-Mail für die Kontowiederherstellung fest. Verwenden Sie eine spätere E-Mail oder ein späteres Telefon, um von Personen, die Sie kennen, optional gefunden zu werden. + Fallback-Call-Assist-Server zulassen + Optimiert für die Batterie + Optimiert für die Echtzeit + Keine Hintergrundsynchronisation + Fehler beim Aktualisieren der Einstellungen. + + + Bevorzugtes Synchronisationsintervall + Discovery + Öffentlicher Name (sichtbar für Personen, mit denen Sie kommunizieren) + Der öffentliche Name eines Geräts ist für Personen sichtbar, mit denen Sie kommunizieren + Um fortzufahren, müssen Sie die Bedingungen dieses Dienstes akzeptieren. + + Sie verwenden keinen Identity Server + Es ist kein Identitätsserver konfiguriert. Sie müssen Ihr Kennwort zurücksetzen. + + Sie versuchen anscheinend, eine Verbindung zu einem anderen Homeserver herzustellen. Möchten Sie sich abmelden\? + + push_key: + app_display_name: + Url: + Nutzungsbedingungen + Nutzungsbedingungen überprüfen + Für andere auffindbar sein + Verwenden Sie Bots, Bridges, Widgets und Sticker-Packs + + Lesen Sie bei + + + Identitätsserver + Trennen Sie den Identitätsserver + Konfigurieren Sie den Identitätsserver + Identitätsserver ändern + Erkennbare E-Mail-Adressen + Erkennungsoptionen werden angezeigt, sobald Sie eine E-Mail hinzugefügt haben. + ausstehend + + Gib einen neuen Identitätsserver ein + Konnte keine Verbindung zum Heimserver herstellen. diff --git a/vector/src/main/res/values-es-rMX/strings.xml b/vector/src/main/res/values-es-rMX/strings.xml index 423ecb5438..313e7737d1 100644 --- a/vector/src/main/res/values-es-rMX/strings.xml +++ b/vector/src/main/res/values-es-rMX/strings.xml @@ -779,4 +779,9 @@ Dispositivos desconocidos: Enviar una respuesta cifrada… Enviar una respuesta (sin cifrar)… + Latn + + Iniciando servicio + Copia de seguridad de la clave + Usar copia de seguridad de la clave diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 894f7e3d47..252acefabc 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -1420,8 +1420,8 @@ Ten en cuenta que esta acción reiniciará la aplicación y puede tardar algo de Firma autocompletar opciones del servidor - Riot ha detectado una configuración personalizada del servidor para el dominio de su ID de usuario \"%s\": -\n%s + Riot ha detectado una configuración personalizada del servidor para el dominio de su ID de usuario \"%1$s\": +\n%2$s Configuración de uso Origen predeterminado de medios diff --git a/vector/src/main/res/values-eu/strings.xml b/vector/src/main/res/values-eu/strings.xml index 9e02bf8103..57eed05cca 100644 --- a/vector/src/main/res/values-eu/strings.xml +++ b/vector/src/main/res/values-eu/strings.xml @@ -1697,4 +1697,73 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada. Orain e-mail helbideak edo telefono zenbakiak partekatzen dituzu %1$s zerbitzarian. %2$s zerbitzarira konektatu beharko zara partekatzeari uzteko. Onartu %s identitate-zerbitzariaren erabilera baldintzak besteek zu e-mail helbidea edo telefonoa erabiliz aurkitzea ahalbidetzeko. + Latn + + Gaitu egunkari xehetsuak. + Amorruz astintzean egunkari xehetsuak bidaltzeak garatzaileei laguntzen diete. Gaituta badago ere, aplikazioak ez ditu mezuen edukiak edo beste datu probaturik gordetzen egunkarian. + + + Saiatu berriro zure hasiera-zerbitzariaren erabilera baldintzak onartu eta gero. + + Badirudi zerbitzariak luze hartu duela erantzuteko, hau konexio kaxkar baten ondorioz izan daiteke edo zerbitzarian errore bat dagoelako. Saiatu berriro geroago. + + Bidali eranskina + + Ireki nabigazio-tiradera + Ireki gela sortzeko menua + Itxi gela sortzeko menua… + Sortu elkarrizketa zuzen berria + Sortu gela berria + Itxi gakoen babes-kopiaren banda + Erakutsi pasahitza + Ezkutatu pasahitza + Jauzi behera + + %1$s, %2$s eta beste %3$d erabiltzailek irakurria + %1$s, %2$s eta%3$s erabiltzaileek irakurria + %1$s eta %2$s erabiltzaileek irakurria + %s erabiltzaileak irakurria + + Erabiltzaile batek irakurria + %d erabiltzailek irakurria + + + \'%1$s\' fitxategia (%2$s) handiegia da igotzeko. Muga %3$s da. + + Errore bat gertatu da eranskina eskuratzean. + Fitxategia + Kontaktua + Kamera + Audioa + Galeria + Eranskailua + Ezin izan dira partekatutako datuak kudeatu + + Spama da + Desegokia da + Salaketa pertsonalizatua + Salatu eduki hau + Eduki hau salatzeko arrazoia + SALATU + BLOKEATU ERABILTZAILEA + + Edukia salatuta + Eduki hau salatu da. +\n +\nEz baduzu erabiltzaile honen eduki gehiago ikusi nahi, bere mezuak ezkutatzeko blokeatu dezakezu + Spam gisa salatua + Eduki hau spam gisa salatu da. +\n +\nEz baduzu erabiltzaile honen eduki gehiago ikusi nahi, bere mezuak ezkutatzeko blokeatu dezakezu + Desegoki gisa salatua + Eduki hau desegoki gisa salatu da. +\n +\nEz baduzu erabiltzaile honen eduki gehiago ikusi nahi, bere mezuak ezkutatzeko blokeatu dezakezu + + Riot-ek zure E2E gakoak diskoan gordetzeko baimena behar du. +\n +\nBaimendu sarbidea hurrengo laster-leihoan zure gakoak eskuz esportatu ahal izateko. + + Ez dago sare konexiorik orain + diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index 3b037a9ead..651978f92f 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -6,7 +6,7 @@ FI - Keskustelut + Viestit Huone Asetukset Jäsenen tiedot @@ -155,7 +155,7 @@ Toista salasana Vahvista uusi salasanasi Väärä käyttäjätunnus ja/tai salasana - Käyttäjätunnus saa koostua vain kirjaimista a-z, numeroista, pisteistä, väliviivoista ja alaviivoista + Käyttäjätunnus saa koostua vain kirjaimista a-z, numeroista, pisteistä, yhdysviivoista ja alaviivoista Liian lyhyt salasana (vähintään 6 merkkiä) Salasana puuttuu Tämä ei näytä oikealta sähköpostiosoitteelta @@ -175,15 +175,15 @@ Kotipalvelin: Identiteettipalvelin: Olen varmistanut sähköpostiosoitteeni - Nollataksesi salasanasi, anna tilisi sähköpostiosoite: - Anna tilisi sähköpostiosoite. + Palauttaaksesi salasanasi, anna tiliisi liitetty sähköpostiosoite: + Anna tiliisi liitetty sähköpostiosoite. Anna uusi salasana. Osoitteeseen %s on lähetetty sähköposti. Kun olet avannut siinä olevan linkin, paina alla olevaa nappia. Sähköpostiosoitteesi vahvistaminen epäonnistui. Varmista, että klikkasit sähköpostissa olevaa linkkiä Salasanasi on vaihdettu.\n\nSinut on kirjauduttu ulos kaikista laitteistasi, etkä enää saa viesti-ilmoituksia. Ottaaksesi käyttöön ilmoitukset uudelleen, kirjaudu sisään uudelleen kaikilla laitteillasi. - URL:n on alettava seuraavasti: http[s]:// + URL-osoitteen on alettava seuraavasti: http[s]:// Kirjautuminen epäonnistui: Verkkovirhe Kirjautuminen epäonnistui Rekisteröityminen epäonnistui: Verkkovirhe @@ -232,7 +232,7 @@ Yhdistetty Yhdistetään… - Puhelu loppu + Puhelu loppui Soitetaan… Saapuva puhelu Saapuva videopuhelu @@ -285,7 +285,7 @@ Hylkää - Hyppää ensimmäiseen lukemattomaan viestiin. + Siirry ensimmäiseen lukemattomaan viestiin. %s on kutsunut sinut huoneeseen @@ -298,7 +298,7 @@ Uusi keskustelu Lisää jäsen - 1 jäsen + yksi jäsen Poistu huoneesta @@ -349,7 +349,7 @@ Lähetä salattu viesti… Lähetä viesti (salaamaton)… Yhteys palvelimeen katkesi. - Viesteja ei lähetetty. %1$s vai %2$s\? + Viestejä ei lähetetty. %1$s vai %2$s\? Viestejä ei lähetetty koska huoneessa on tuntemattomia laitteita. %1$s vai %2$s\? Lähetä kaikki uudelleen Peruuta kaikki @@ -423,7 +423,7 @@ Unohda - Keskustelut + Viestit Asetukset Versio Käyttöehdot @@ -785,9 +785,9 @@ Yhteisöt Ei ryhmiä - Oletko varma, että haluat aloittaa uuden keskustelun käyttäjän %s kanssa\? - Oletko varma että haluat aloittaa äänipuhelun? - Oletko varma, että haluat aloittaa videopuhelun? + Haluatko varmasti aloittaa uuden keskustelun käyttäjän %s kanssa\? + Haluatko varmasti aloittaa äänipuhelun\? + Haluatko varmasti aloittaa videopuhelun\? Ryhmälistaus @@ -933,12 +933,12 @@ Haluatko lisätä paketteja? Avaa otsikko Synkronoidaan… - yksi aktiivinen käyttäjä - %d aktiivista käyttäjää + yksi aktiivinen jäsen + %d aktiivista jäsentä - yksi käyttäjä - %d käyttäjää + yksi jäsen + %d jäsentä 1 s @@ -1136,12 +1136,12 @@ Haluatko lisätä paketteja? Kirjoita tähän… - yksi lukematon viesti - %d lukematonta viestiä + yksi lukematon ilmoitettu viesti + %d lukematonta ilmoitettua viestiä - 1 lukematon viesti - %d lukematonta viestiä + yksi lukematon ilmoitettu viesti + %d lukematonta ilmoitettua viestiä yksi huone @@ -1156,7 +1156,7 @@ Haluatko lisätä paketteja? Parametri ei ole kelvollinen. Käynnistä järjestelmän kamera Riotin kameraruudun sijaan. Käytä näppäimistön rivinvaihtopainiketta viestin lähettämiseen - Tämä vaihtoehto vaatii kolmannen osapuolen sovelluksen viestien tallennukseen. + Tämä valinta vaatii kolmannen osapuolen sovelluksen viestien tallennukseen. Komento ”%s” vaatii enemmän parametreja, tai jotkin parametrit ovat virheellisiä. Näyttää toiminnon @@ -1190,17 +1190,17 @@ Haluatko lisätä paketteja? Jatkaaksesi kotipalvelimen %1$s käyttöä, sinun täytyy hyväksyä palvelun käyttöehdot. Näytä ehdot - Tämä tekee tunnuksestasi lopullisesti käyttökelvottoman. Et voi kirjautua sisään eikä kukaan pysty rekisteröimään tunnusta samalla käyttäjä-ID:llä. Tämä saa tunnuksesi lähtemään kaikista huoneista, joissa se on osallisena, ja se poistaa tunnuksen tiedot identiteettipalvelimelta. Tämä toiminto on peruuttamaton. + Tämä tekee tilistäsi lopullisesti käyttökelvottoman. Et voi kirjautua sisään eikä kukaan pysty rekisteröitymään samalla käyttäjätunnuksella. Tämä saa tilisi poistumaan kaikista huoneista, joissa se on osallisena, ja poistaa tilin tiedot identiteettipalvelimelta. Tämä toiminto on peruuttamaton. \n -\nTunnuksen otto pois käytöstä ei oletuksena saa meitä unohtamaan lähettämiäsi viestejä. Jos haluat meidän unohtavan viestisi, merkitse alapuolella oleva laatikko. +\nTilin deaktivointi ei oletuksena saa meitä unohtamaan lähettämiäsi viestejä. Jos haluat meidän unohtavan viestisi, merkitse alapuolella oleva valintaruutu. \n -\nViestin näkyvyys Matrixissa on samanlainen kuin sähköpostissa. Vaikka unohdamme viestisi, kaikki tahot, joilla viestisi jo on, tulevat pääsemään omaan kopioonsa viesteistäsi. - Unohda kaikki viestit, jotka olen lähittänyt, kun tunnuksesi on deaktivoitu (varoitus: tämä aiheuttaa tulevien käyttäjien näkevän vanhat keskustelusi epätäydellisinä) +\nViestien näkyvyys Matrixissa on samantapainen kuin sähköpostissa. Viestiesi unohtaminen tarkoittaa, että lähettämiäsi viestejä ei näytetä uusille tai rekisteröitymättömille käyttäjille. Ne rekisteröityneet käyttäjät, joilla viestisi jo on, pääsevät kuitenkin näkemään oman kopionsa niistä jatkossakin. + Unohda kaikki viestit, jotka olen lähettänyt, kun tilini on deaktivoitu (Varoitus: tästä seuraa, että tulevat käyttäjät näkevät vanhat keskustelut epätäydellisinä) Syötä käyttäjätunnus. Tämä huone on korvattu toisella huoneella Keskustelu jatkuu täällä Tämä huone on jatkoa toiselle keskustelulle - Täppää tästä nähdäksesi vanhat viestit + Paina tästä nähdäksesi vanhemmat viestit Resurssiraja saavutettu Ota yhteys ylläpitäjään @@ -1227,7 +1227,7 @@ Haluatko lisätä paketteja? Näytä infoalue Aina - Tiedotuksille ja virheille + Viesteille ja virheille Vain virheille %1$s: @@ -1249,7 +1249,7 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Poista salalause, jos haluat Riotin generoivan palautusavaimen. Matrix-istuntoa ei ole saatavilla - Älä ikinä menetä salattuja viestejä + Älä koskaan menetä salattuja viestejä Salatuissa huoneissa viestit ovat suojattuna osapuolten välisellä salauksella. Vain sinä ja vastaanottaja(t) omistavat avaimet näiden viestien lukemiseen. \n \nVarmuuskopioi avaimesi, jotta et menetä niitä. @@ -1258,9 +1258,9 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Tallenna avaimet käsin Turvaa varmuuskopiosi salalauseella. - Tallennamme salatun kopion avaimistasi kotipalvelimellesi. Suojaa varmuuskopiosi salalauseella pitääksesi sen turvattuna. -\n -\nTurvallisuuden takia tämän salalauseen tulisi olla eri tunnuksesi salasanasta. + Tallennamme salatun kopion avaimistasi kotipalvelimellesi. Suojaa varmuuskopiosi salalauseella pitääksesi sen turvattuna. +\n +\nParhaan turvallisuuden takaamiseksi salalauseen tulisi olla eri kuin tilisi salasana. Aseta salalause Luodaan varmuuskopiota Tai, turvaa varmuuskopio palautusavaimella, tallentamalla palautusavain johonkin turvalliseen paikkaan. @@ -1377,7 +1377,7 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Kirjaudu sisään kertakirjautumisella Tämä osoite ei ole saavutettavissa. Tarkistathan osoitteen - Laitteesi käyttää vanhentunutta, haavoittuvaista TLS-protokollan versiota. Turvallisuutesi vuoksi et pysty yhdistämään + Laitteesi käyttää vanhentunutta, haavoittuvaista TLS-protokollan versiota. Turvallisuutesi tähden et voi muodostaa yhteyttä Lähetä viesti enter-näppäimellä Näppäimistön enter-näppäin lähettää viestin sen sijaan, että se lisäisi rivinvaihdon @@ -1387,25 +1387,25 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös %1$s -> %2$s - Keskusteluohjelma, joka on täysin hallinnoitavissasi ja erittäin joustava. Riot sallii sinun kommunikoivan juuri sillä tavalla kuin haluat. [matrix]-sovellus — avoimen ja hajautetun kommunikaation standardi. + Keskustelusovellus, joka on sinun hallinnassasi ja erittäin joustava. Riot antaa sinun viestiä juuri sillä tavalla kuin haluat. Taustalla [matrix] – avoimen ja hajautetun viestinnän standardi. \n -\nKäytä ilmaista matrix.org-tunnusta, hanki oma palvelimesi osoitteesta https://modular.im tai käytä muuta Matrix-palvelinta. +\nHanki ilmainen matrix.org-tili, hanki oma palvelimesi osoitteesta https://modular.im tai käytä muuta Matrix-palvelinta. \n \nMiksi valita Riot.im\? \n -\n• Täydellinen kommunikaatio: rakenna huoneita tiimeillesi, ystävillesi ja yhteisöllesi — juuri niin kuin haluat! Keskustele, jaa tiedostoja, lisää sovelmia ja tee ääni‐ ja videopuheluita — kaikki tämä ilmaiseksi. +\n• Kattavat mahdollisuudet viestintään: rakenna huoneita tiimeillesi, ystävillesi ja yhteisöllesi – juuri niin kuin haluat! Keskustele, jaa tiedostoja, lisää sovelmia ja soita ääni‐ ja videopuheluita – kaikki tämä ilmaiseksi. +\n +\n• Tehokkaat integraatiot: Käytä Riotia tuntemiesi työkalujen kanssa. Riot.im mahdollistaa keskustelut jopa eri keskusteluohjelmia käyttävien ihmisten ja ryhmien kanssa. \n -\n• Tehokkaat integraatiot: Käytä Riotia juuri niillä työkaluilla, jotka tiedät ja joita rakastat. Riot.im jopa mahdollistaa keskustelun henkilöiden kanssa, jotka käyttävät eri keskusteluohjelmia. +\n• Yksityinen ja turvallinen: Pidä keskustelusi salaisina. Nykyaikainen osapuolten välinen salaus pitää huolen, että yksityiset keskustelut pysyvät yksityisinä. \n -\n• Yksityinen ja turvallinen: Pidä keskustelusi salaisina. Nykyaikainen osapuolten välinen salaus pitää huolen, että yksityiset keskustelut pysyvät yksityisenä. +\n• Avoin, ei suljettu: Avointa lähdekoodia ja rakennettu käyttämään Matrixia. Voit omistaa oman datasi ylläpitämällä omaa palvelintasi, tai käyttämällä palvelinta, johon luotat. \n -\n• Avoin, ei suljettu: Avointa koodia, ja rakennettu käyttämään Matrixia. Voit omistaa oman datasi ylläpitämällä omaa palvelintasi, tai käyttämällä palvelinta, johon luotat. -\n -\n• Kaikkialla, missä olet: pysy yhteydessä siellä, missä ikinä oletkin täysin synkronoidulla viestihistorialla kaikkien laitteidesi ja sivun https://riot.im välillä. +\n• Kaikkialla, missä olet: pysy yhteydessä missä ikinä oletkin, täysin synkronoidulla viestihistorialla kaikkien laitteidesi ja https://riot.im-verkkopalvelun välillä. - Uusi avainvarmuuskopio on löydetty. + Uusi avainvarmuuskopio löydetty. \n -\nJos et asettanut uutta palautustapaa, hyökkääjä saattaa yrittää päästä käsiksi tunnukseesi. Vaihda tunnuksesi salasana ja aseta uusi palautustapa asetuksissa välittömästi. +\nJos et asettanut uutta palautustapaa, hyökkääjä saattaa yrittää päästä käsiksi tiliisi. Vaihda tilisi salasana ja aseta uusi palautustapa asetuksissa välittömästi. Epäkelpo kotipalvelimen löytövastaus Automaattitäydennyksen palvelinasetukset Riot löysi mukautetun palvelinasetuksen userId:si domainille ”%1$s”: @@ -1646,7 +1646,7 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Katkaise yhteys identiteettipalvelimeen Määritä identiteettipalvelin Vaihda identiteettipalvelinta - Käytät palvelinta %1$s löytääksesi tuntemiasi ihmisiä ja jotta he löytäisivät sinut. + Käytät palvelinta %1$s löytääksesi tuntemiasi ihmisiä ja ollaksesi heidän löydettävissään. Et käytä tällä hetkellä identiteettipalvelinta. Jotta voit löytää tuntemiasi ihmisiä ja jotta he löytävät sinut, määritä identiteettipalvelin alla. Odottaa @@ -1657,4 +1657,54 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Valitsemallasi identiteettipalvelimella ei ole käyttöehtoja. Jatka vain, jos luotat palvelun omistajaan Jaat sähköpostiosoitteita tai puhelinnumeroita identiteettipalvelimella %1$s. Sinun täytyy yhdistää uudelleen palvelimeen %2$s, jotta voit lopettaa niiden jakamisen. Hyväksy identiteettipalvelimen (%s) käyttöehdot salliaksesi, että sinut voi löytää sähköpostiosoitteen tai puhelinnumeron perusteella. + Aseta sähköposti tilin palauttamista varten. Myöhemmin voit halutessasi antaa ihmisten etsiä sinua sen perusteella. + Salli varalla oleva puhelun apupalvelin + Yhteyden katkaiseminen identiteettipalvelimeesi tarkoittaa, että muut käyttäjät eivät voi etsiä sinua etkä voi kutsua muita sähköpostin tai puhelinnumeron perusteella. + Lähetimme sinulle vahvistussähköpostin osoitteeseen %s, tarkista sähköpostisi ja klikkaa vahvistuslinkkiä + Ota yksityiskohtaiset lokit käyttöön. + Yritä uudelleen, kun olet hyväksynyt kotipalvelimesi käyttöehdot. + + Palvelimen vastaus näyttää viipyvän. Tämä voi johtua kehnosta yhteydestä tai palvelimillamme tapahtuneesta virheestä. Yritä hetken kuluttua uudelleen. + + Lähetä liite + + Luo uusi huone + Näytä salasana + Piilota salasana + Siirry loppuun + + %1$s, %2$s ja %3$d muuta lukivat + %1$s, %2$s ja %3$s lukivat + %1$s ja %2$s lukivat + %s luki + + 1 käyttäjä luki + %d käyttäjää luki + + + Liitettä noudettaessa tapahtui virhe. + Tiedosto + Kamera + Galleria + Tarra + Se on roskapostia + Se on sopimaton + Verkkoyhteyttä ei ole juuri nyt + + Ei mitään + Pyydä kotipalvelimesi (%1$s) ylläpitäjää määrittämään TURN-palvelin, jotta puhelut toimivat luotettavasti. +\n +\nVaihtoehtoisesti voit yrittää käyttää julkista palvelinta osoitteessa %2$s, mutta tämä ei ole yhtä luotettava vaihtoehto ja antaa IP-osoitteesi kyseisen palvelimen tietoon. Voit myös hallita tätä asetuksista. + Kokeile käyttää palvelinta %s + Käyttää palvelinta %s apupalvelimena, jos kotipalvelimesi ei tarjoa sellaista (IP-osoitteesi näkyy palvelimelle puhelun aikana) + Optimoitu akunkestoa varten + Riot synkronoi taustalla laitteen rajallisia resursseja (akkua) säästäen. +\nLaitteesi resurssien tilasta riippuen käyttöjärjestelmä saattaa lykätä synkronointia. + Optimoitu reaaliaikaa varten + Riot synkronoi taustalla täsmällisin aikavälein (säädettävä). +\nTämä vaikuttaa radion ja akun käyttöön. Näet pysyvän ilmoituksen, joka kertoo, että Riot kuuntelee tapahtumia. + Viestimuokkaukset + Ole löydettävissä + Tekstiviesti on lähetetty numeroon %s. Syötä sen sisältämä varmistuskoodi. + diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 1fe493d9d4..6057627163 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -783,7 +783,7 @@ Appareils inconnus : Abandonner le salon Badge - Secouer avec frustration pour signaler un bug + Secouer avec frustration pour signaler une anomalie Actions Synchronisation… @@ -1701,4 +1701,73 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq Vous partagez actuellement des adresse e-mails et des numéros de téléphone sur le serveur d’identité %1$s. Vous devrez vous reconnecter à %2$s pour arrêter de les partager. Acceptez les conditions de service du serveur d’identité (%s) pour vous permettre d’être découvrable avec une adresse e-mail ou un numéro de téléphone. + Latn + + Activer les journaux verbeux. + Les journaux verbeux aideront les développeurs en fournissant plus de journaux quand vous envoyez un rapport d’anomalie. Même si cette option est activée, l’application n’envoie pas le contenu des messages ou toute autre donnée personnelle. + + + Réessayez quand vous aurez accepté les termes et conditions de votre serveur d’accueil. + + On dirait que le serveur mette trop de temps à répondre. Ça peut être dû à une mauvaise connexion ou à une erreur avec nos serveurs. Réessayez plus tard. + + Envoyer une pièce jointe + + Ouvrir le menu de navigation + Ouvrir le menu de création de salon + Fermer le menu de création de salon… + Créer une nouvelle conversation directe + Créer un nouveau salon + Fermer la bannière de sauvegarde des clés + Afficher le mot de passe + Masquer le mot de passe + Sauter en bas de page + + %1$s, %2$s et %3$d autres ont lu + %1$s, %2$s et %3$s ont lu + %1$s et %2$s ont lu + %s a lu + + 1 utilisateur a lu + %d utilisateurs ont lu + + + Le fichier « %1$s » (%2$s) est trop gros pour être envoyé. La limite est %3$s. + + Une erreur est survenue pendant la récupération de la pièce jointe. + Fichier + Contact + Appareil photo + Audio + Galerie + Sticker + Impossible de traiter les données de partage + + C’est du pourriel + C’est inapproprié + Signalement personnalisé + Signaler ce contenu + Motif de signalement de ce contenu + SIGNALER + BLOQUER L’UTILISATEUR + + Contenu signalé + Ce contenu a été signalé. +\n +\nSi vous ne voulez plus voir de contenu de cet utilisateur, vous pouvez le bloquer pour masquer ses messages + Signalé comme pourriel + Ce contenu a été signalé comme pourriel. +\n +\nSi vous ne voulez plus voir de contenu de cet utilisateur, vous pouvez le bloquer pour masquer ses messages + Signalé comme inapproprié + Ce contenu a été signalé comme inapproprié. +\n +\nSi vous ne voulez plus voir de contenu de cet utilisateur, vous pouvez le bloquer pour masquer ses messages + + Riot a besoin de votre permission pour sauvegarder vos clés de chiffrement sur le disque. +\n +\nAutorisez l’accès dans le prochaine fenêtre pour pouvoir exporter vos clés manuellement. + + Il n’y a aucune connexion au réseau pour le moment + diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 2e13eb7531..caca6bd7c8 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -1700,4 +1700,73 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró Az azonosítási szerverrel (%1$s) megosztod az e-mail címeket és telefonszámokat. Újra kell csatlakoznod ehhez: %2$s, hogy megállítsd a megosztást. Egyetértek az azonosítási szerver (%s) Felhasználási feltételeivel ahhoz, hogy megtalálható legyek e-mail címmel vagy telefonszámmal. + Latn + + Kibővített naplózás engedélyezése. + A kiterjesztett naplózás a fejlesztőknek nyújt több információt amikor hibajegyet küldesz. Még bekapcsolva sem naplóz üzenet tartalmat vagy más személyes adatot. + + + Kérlek ismételd meg miután elfogadtad a matrix szervered felhasználási feltételeit. + + Úgy tűnik a szerver sokáig nem válaszol, ennek a bizonytalan kapcsolat vagy egy hiba a szerverünkben lehet az oka. Kicsit később próbáld újra. + + Csatolmány küldése + + Navigációs panel megnyitása + Szoba készítés menü megnyitása + Szoba készítés menü bezárása… + Új közvetlen beszélgetés indítása + Új szoba készítése + Kulcs mentés csík bezárása + Jelszó mutatása + Jelszó elrejtése + Végére ugrás + + %1$s, %2$s és %3$d olvasták + %1$s, %2$s és %3$s olvasták + %1$s és %2$s olvasták + %s olvasta + + 1 felhasználó olvasta + %d felhasználó olvasta + + + \'%1$s\' (%2$s) fájl túl nagy a feltöltéshez. A korlát: %3$s. + + A csatolmány letöltésénél hiba történt. + Fájl + Kapcsolat + Kamera + Hang + Galéria + Matrica + Az adatmegosztást nem sikerül kezelni + + Ez nemkívánt (spam) + Ez nem idevaló + Egyedi jelentés + Tartalom bejelentése + A tartalom bejelentésének oka + JELENTÉS + FELHASZNÁLÓ BLOKKOLÁSA + + Tartalom bejelentve + Ez a tartalom bejelentve. +\n +\nHa nem akarsz ettől a felhasználótól több üzenetet látni akkor blokkolhatod, hogy az üzenetei ne jelenjenek meg számodra + Bejelentve nem kívántként (spam) + Ez a tartalom nem kívántnak (spam) lett bejelentve. +\n +\n Ha nem akarsz ettől a felhasználótól több üzenetet látni akkor blokkolhatod, hogy az üzenetei ne jelenjenek meg számodra + Nem idevalónak bejelentve + Ez a tartalom nem idevalónak lett bejelentve. +\n +\n Ha nem akarsz ettől a felhasználótól több üzenetet látni akkor blokkolhatod, hogy az üzenetei ne jelenjenek meg számodra + + Riotnak engedélyre van szüksége ahhoz, hogy a végponttól végpontig titkosító kulcsokat a lemezre menthesse. +\n +\nKérlek a következő felugró ablakban engedélyezd a hozzáférést, hogy a kulcsokat kézzel kimenthesd. + + Jelenleg nincs hálózati kapcsolat + diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 1c879ad794..d46eaa987b 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -1745,4 +1745,73 @@ Per essere certo di non perdere nulla, mantieni gli aggiornamenti attivi."Attualmente stai condividendo indirizzi email o numeri di telefono sul server di identità %1$s. Dovrai riconnetterti a %2$s per fermarne la condivisione. Accetta le condizioni di servizio del server di identità (%s) per consentire di essere trovabile per email o numero di telefono. + Latn + + Attiva log dettagliati. + I log dettagliati aiuteranno gli sviluppatori fornendo loro più informazioni quando invii una segnalazione. Anche quando attivi, l\'applicazione non registra i contenuti dei messaggi o altri dati personali. + + + Riprova dopo avere accettato i termini e condizioni del tuo homeserver. + + Sembra che il server stia impiegando troppo tempo a rispondere, ciò può essere causato da scarsa connettività o un errore con i nostri server. Riprova fra qualche minuto. + + Invia allegato + + Apri il pannello di navigazione + Apri il menu di creazione stanza + Chiudi il menu di creazione stanza… + Crea una nuova conversazione diretta + Crea una nuova stanza + Chiudi il banner di backup chiavi + Mostra password + Nascondi password + Salta in fondo + + %1$s, %2$s ed altri %3$d hanno letto + %1$s, %2$s e %3$s hanno letto + %1$s e %2$s hanno letto + %s ha letto + + 1 utente ha letto + %d utenti hanno letto + + + Il file \'%1$s\' (%2$s) è troppo grande da inviare. Il limite è %3$s. + + Si è verificato un errore ricevendo l\'allegato. + File + Contatto + Fotocamera + Audio + Galleria + Adesivo + Errore di gestione dati condivisi + + È spam + È inappropriato + Segnalazione personalizzata + Segnala questo contenuto + Motivo della segnalazione + SEGNALA + BLOCCA UTENTE + + Contenuto segnalato + Questo contenuto è stato segnalato. +\n +\nSe non vuoi più vedere contenuti da questo utente, puoi bloccarlo per nascondere i suoi messaggi + Segnalato come spam + Questo contenuto è stato segnalato come spam. +\n +\nSe non vuoi più vedere contenuti da questo utente, puoi bloccarlo per nascondere i suoi messaggi + Segnalato come inappropriato + Questo contenuto è stato segnalato come inappropriato. +\n +\nSe non vuoi più vedere contenuti da questo utente, puoi bloccarlo per nascondere i suoi messaggi + + Riot richiede l\'autorizzazione per salvare le tue chiavi E2E su disco. +\n +\nPermetti l\'accesso nel prossimo pop-up per poter esportare le chiavi manualmente. + + Non c\'è nessuna connessione di rete al momento + diff --git a/vector/src/main/res/values-ko/strings.xml b/vector/src/main/res/values-ko/strings.xml index 7f76e47ea7..3f2469d766 100644 --- a/vector/src/main/res/values-ko/strings.xml +++ b/vector/src/main/res/values-ko/strings.xml @@ -302,8 +302,8 @@ 방 주제 전화 - 오는 전화에 Riot 기본 벨소리를 사용합니다 - 오는 전화 벨소리 + 수신 전화에 Riot 기본 벨소리를 사용합니다 + 수신 전화 벨소리 전화에 사용할 벨소리를 선택하세요: 전화 @@ -311,9 +311,9 @@ 전화 연결 중… 전화 종료됨 전화 중… - 오는 전화 - 오는 영상 통화 - 오는 음성 통화 + 수신 전화 + 수신 영상 통화 + 수신 음성 통화 전화 진행 중… 영상 통화 진행 중… @@ -412,8 +412,8 @@ 초대 이 방 떠나기 이 방에서 삭제하기 - 차단 - 차단 해제 + 출입 금지 + 출입 금지 풀기 추방 일반 사용자로 재 설정 중재자로 하기 @@ -432,7 +432,7 @@ 이 사용자들을 이 대화에서 추방하겠습니까\? - 이 사용자를 이 대화에서 차단하겠습니까\? + 이 사용자를 이 대화에서 출입 금지하겠습니까\? 이유 %s님을 이 대화에 초대하겠습니까\? @@ -720,7 +720,7 @@ 읽은 기록 보이기 세부적인 목록으로 읽은 목록을 클릭하세요. 참가 및 떠남 이벤트 보이기 - 초대, 추방, 그리고 차단은 영향이 없습니다. + 초대, 추방, 그리고 출입 금지은 영향이 없습니다. 계정 이벤트 보이기 아바타와 표시 이름 변경도 포함합니다. 사용자가 언급할 때 진동 @@ -854,7 +854,7 @@ 방의 링크를 아는 누구나, 손님 제외 방의 링크를 아는 누구나, 손님 포함 - 차단한 사용자 + 출입 금지한 사용자 고급 이 방의 내부 ID @@ -1064,8 +1064,8 @@ 인식할 수 없는 명령어: %s \"%s\" 명령어는 더 많은 매개 변수가 필요하거나, 일부 매개 변수가 옳지 않습니다. 활동 표시하기 - 주어진 ID로 사용자 차단하기 - 주어진 ID로 사용자 차단 풀기 + 주어진 ID로 사용자 출입 금지하기 + 주어진 ID로 사용자 출입 금지 풀기 사용자의 권한 등급 정의하기 주어진 ID로 사용자 강등하기 주어진 ID 현재 방에 사용자 초대하기 @@ -1114,7 +1114,7 @@ 커뮤니티 관리자가 이 커뮤니티에 대한 자세한 설명을 제공하지 않았습니다. %2$s님에 의해 %1$s 방에서 추방당했습니다 - %2$s님에 의해 %1$s 방에서 차단당했습니다 + %2$s님에 의해 %1$s 방에서 출입 금지당했습니다 이유: %1$s 다시 참가하기 방 잊어버리기 @@ -1584,7 +1584,7 @@ Riot은 (설정할 수 있는) 특정 시간에 주기적으로 백그라운드에거 동기화됩니다. \n이는 라디오와 배터리 사용에 영향을 주며 Riot이 이벤트를 수신하고 있는 상태라는 알림이 영구적으로 표시됩니다. 백그라운드 동기화 없음 - 앱이 백그라운드에 있을 때 오는 메시지의 알림을 받지 않습니다. + 앱이 백그라운드에 있을 때 수신 메시지의 알림을 받지 않습니다. 설정을 업데이트하는데 실패했습니다. @@ -1623,4 +1623,72 @@ 현재 이메일 주소나 전화번호를 ID 서버 %1$s와 공유하고 있습니다. 공유하기를 중지하려면 %2$s(으)로 다시 연결해야 합니다. ID 서버 (%s)의 서비스 약관에 동의하면 다른 사용자가 당신을 이메일 주소나 전화번호로 찾을 수 있게 됩니다. + Latn + + 상세 로그 켜기. + 상세 로그는 분노의 흔들기를 보낼 때 더 많은 로그를 제공해서 개발자에게 도움을 줍니다. 이 설정을 켜도 애플리케이션은 메시지 내용이나 다른 개인 정보를 기록하지 않습니다. + + + 홈서버의 이용 약관에 동의한 후 다시 시도해주세요. + + 서버의 응답 시간이 지연되고 있습니다. 연결 상태가 좋지 않거나 서버에서 오류가 발생했을지도 모릅니다. 나중에 다시 시도해주세요. + + 첨부 파일 보내기 + + 내비게이션 서랍 열기 + 방 만들기 메뉴 열기 + 방 만들기 메뉴 닫기… + 새 다이렉트 대화 만들기 + 새 방 만들기 + 키 백업 배너 닫기 + 비밀번호 보이기 + 비밀번호 감추기 + 맨 아래로 건너뛰기 + + %1$s님, %2$s님 외 %3$d명이 읽음 + %1$s님, %2$s님 그리고 %3$s님이 읽음 + %1$s님 그리고 %2$s님이 읽음 + %s님이 읽음 + + %d명이 읽음 + + + 파일 \'%1$s\' (%2$s)이(가) 업로드하기에 너무 큽니다. 제한은 %3$s입니다. + + 첨부 파일을 검색하는 중 오류가 발생했습니다. + 파일 + 연락처 + 카메라 + 소리 + 갤러리 + 스티커 + 공유 데이터를 처리할 수 없음 + + 스팸 문자입니다 + 부적절한 문자입니다 + 맞춤 신고 + 이 내용 신고하기 + 이 내용을 신고하는 이유 + 신고 + 사용자 출입 금지 + + 내용 신고됨 + 이 내용을 신고했습니다. +\n +\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 + 스팸 문자로 신고됨 + 이 내용을 스팸 메일로 신고했습니다. +\n +\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 + 부적절한 문자로 신고됨 + 이 내용을 부적절한 문자로 신고했습니다. +\n +\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 + + Riot은 종단간 키를 디스크에 저장하려면 권한이 필요합니다. +\n +\n키를 수동으로 내보내려면 다음 팝업에서 접근을 허용해주세요. + + 현재 네트워크 연결이 없습니다 + diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index eaad9bf4aa..e815f01b9f 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -1792,4 +1792,9 @@ В настоящее время вы делитесь адресами электронной почты или телефонными номерами на сервере идентификации %1$s. Вам нужно повторно подключиться к %2$s, чтобы прекратить делиться ими. Примите Условия обслуживания сервера идентификации (%s), чтобы разрешить обнаружение по адресу электронной почты или номеру телефона. + Включить подробное журнал. + Отправить вложенное + + Откройте навигационный ящик + Откройте меню «Создать комнату» diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index b54c05b784..f7ed5500ea 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -1653,4 +1653,72 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 您目前正在身份識別伺服器 %1$s 上分享電子郵件地址或電話號碼。您將必須重新連線到 %2$s 以停止分享它們。 同意身份識別伺服器 (%s) 的服務條款以允許您被透過電子郵件地址或電話號碼探索。 + 緯度 + + 啟用詳細紀錄。 + 詳細紀錄可以協助開發者在您傳送憤怒搖晃時取得更多紀錄。即使啟用這個設定,應用程式依然不會紀錄訊息內容或任何個人資料。 + + + 請在您接受您家伺服器的條款與條件前繼續重試。 + + 看起來伺服器回應時間似乎太久了,這可能是不良的網路連線或我們的伺服器錯誤所造成。請稍後再試。 + + 傳送附件 + + 開啟導航選單 + 開啟建立聊天室選單 + 關閉建立聊天室選單…… + 建立新的直接對話 + 建立新的聊天室 + 關閉金鑰備份橫幅 + 顯示密碼 + 隱藏密碼 + 跳到底部 + + %1$s、%2$s 與 %3$d 個其他人已閱讀 + %1$s、%2$s 與 %3$d 已閱讀 + %1$s 與 %2$s 已閱讀 + %s 已閱讀 + + %d 個使用者已閱讀 + + + 檔案「%1$s」(%2$s) 太大無法上傳。限制為 %3$s。 + + 在擷取附件時遇到錯誤。 + 檔案 + 聯絡人 + 相機 + 音訊 + 相簿 + 貼圖 + 無法處理分享資料 + + 垃圾訊息 + 不合適 + 自訂回報 + 回報此內容 + 回報此內容的理由 + 回報 + 封鎖使用者 + + 內容已回報 + 此內容已回報。 +\n +\n如果您不想要看到從此使用者而來的更多內容,您可以封鎖他以隱藏他的訊息 + 回報為垃圾訊息 + 此內容已被回報為垃圾訊息。 +\n +\n如果您不想要看到從此使用者而來的更多內容,您可以封鎖他以隱藏他的訊息 + 回報為不合適 + 此內容已被回報為不合適。 +\n +\n如果您不想要看到從此使用者而來的更多內容,您可以封鎖他以隱藏他的訊息 + + Riot 需要權限以在磁碟上儲存您的 E2E 金鑰。 +\n +\n請在下個彈出視窗中允許存取以讓您可以手動匯出您的金鑰。 + + 目前沒有網路連線 + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index be0d97c147..83ce65783f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1168,8 +1168,6 @@ Changes your display nickname On/Off markdown To fix Matrix Apps management - Sends the given message as a spoiler - Spoiler Markdown has been enabled. Markdown has been disabled. @@ -1530,7 +1528,6 @@ Why choose Riot.im? Add Reaction View Reactions Reactions - Type keywords to find a reaction. Event deleted by user Event moderated by room admin diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 20fc234fc8..9f325617ce 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -3,5 +3,8 @@ "%1$s made no changes" + Sends the given message as a spoiler + Spoiler + Type keywords to find a reaction. From c85852262ea6c0cd6e247d131420d19cd0f3cd02 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 Nov 2019 18:28:16 +0100 Subject: [PATCH 060/117] Remove bad value --- vector/src/main/res/values-zh-rTW/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index f7ed5500ea..837e75583a 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -1653,7 +1653,6 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 您目前正在身份識別伺服器 %1$s 上分享電子郵件地址或電話號碼。您將必須重新連線到 %2$s 以停止分享它們。 同意身份識別伺服器 (%s) 的服務條款以允許您被透過電子郵件地址或電話號碼探索。 - 緯度 啟用詳細紀錄。 詳細紀錄可以協助開發者在您傳送憤怒搖晃時取得更多紀錄。即使啟用這個設定,應用程式依然不會紀錄訊息內容或任何個人資料。 From 93ef3edab3155ef5f637178b01bf21c48b185f12 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 6 Nov 2019 18:47:11 +0100 Subject: [PATCH 061/117] Remove some use of sync write in realm --- .../matrix/android/api/auth/Authenticator.kt | 2 +- .../internal/auth/DefaultAuthenticator.kt | 18 +++- .../internal/auth/SessionParamsStore.kt | 6 +- .../auth/db/RealmSessionParamsStore.kt | 42 +++----- .../database/query/FilterEntityQueries.kt | 18 ++-- .../android/internal/di/MatrixModule.kt | 2 +- .../session/filter/DefaultFilterRepository.kt | 99 +++++++------------ .../session/filter/DefaultFilterService.kt | 31 +----- .../session/filter/DefaultSaveFilterTask.kt | 32 ++++-- .../session/filter/FilterRepository.kt | 8 +- .../internal/session/sync/SyncTokenStore.kt | 17 ++-- .../riotx/features/login/LoginViewModel.kt | 9 +- 12 files changed, 130 insertions(+), 154 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt index 77a3cde249..c1dfa465fb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt @@ -67,5 +67,5 @@ interface Authenticator { /** * Create a session after a SSO successful login */ - fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session + fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback): Cancelable } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt index e379090677..0192715ae5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt @@ -112,10 +112,24 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated sessionManager.getOrCreateSession(sessionParams) } - override fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session { + override fun createSessionFromSso(credentials: Credentials, + homeServerConnectionConfig: HomeServerConnectionConfig, + callback: MatrixCallback): Cancelable { + val job = GlobalScope.launch(coroutineDispatchers.main) { + val sessionOrFailure = runCatching { + createSessionFromSso(credentials, homeServerConnectionConfig) + } + sessionOrFailure.foldToCallback(callback) + } + return CancelableCoroutine(job) + + } + + private suspend fun createSessionFromSso(credentials: Credentials, + homeServerConnectionConfig: HomeServerConnectionConfig): Session = withContext(coroutineDispatchers.computation) { val sessionParams = SessionParams(credentials, homeServerConnectionConfig) sessionParamsStore.save(sessionParams) - return sessionManager.getOrCreateSession(sessionParams) + sessionManager.getOrCreateSession(sessionParams) } private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt index e1fef7e2eb..88beb92111 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt @@ -27,9 +27,9 @@ internal interface SessionParamsStore { fun getAll(): List - fun save(sessionParams: SessionParams): Try + suspend fun save(sessionParams: SessionParams) - fun delete(userId: String): Try + suspend fun delete(userId: String) - fun deleteAll(): Try + suspend fun deleteAll() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt index 7ec5d24559..00fde2682e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt @@ -16,9 +16,9 @@ package im.vector.matrix.android.internal.auth.db -import arrow.core.Try import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.internal.auth.SessionParamsStore +import im.vector.matrix.android.internal.database.awaitTransaction import im.vector.matrix.android.internal.di.AuthDatabase import io.realm.Realm import io.realm.RealmConfiguration @@ -62,41 +62,29 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S return sessionParams } - override fun save(sessionParams: SessionParams): Try { - return Try { + override suspend fun save(sessionParams: SessionParams) { + awaitTransaction(realmConfiguration) { val entity = mapper.map(sessionParams) if (entity != null) { - val realm = Realm.getInstance(realmConfiguration) - realm.executeTransaction { - it.insert(entity) - } - realm.close() + it.insert(entity) } } } - override fun delete(userId: String): Try { - return Try { - val realm = Realm.getInstance(realmConfiguration) - realm.executeTransaction { - it.where(SessionParamsEntity::class.java) - .equalTo(SessionParamsEntityFields.USER_ID, userId) - .findAll() - .deleteAllFromRealm() - } - realm.close() + override suspend fun delete(userId: String) { + awaitTransaction(realmConfiguration) { + it.where(SessionParamsEntity::class.java) + .equalTo(SessionParamsEntityFields.USER_ID, userId) + .findAll() + .deleteAllFromRealm() } } - override fun deleteAll(): Try { - return Try { - val realm = Realm.getInstance(realmConfiguration) - realm.executeTransaction { - it.where(SessionParamsEntity::class.java) - .findAll() - .deleteAllFromRealm() - } - realm.close() + override suspend fun deleteAll() { + awaitTransaction(realmConfiguration) { + it.where(SessionParamsEntity::class.java) + .findAll() + .deleteAllFromRealm() } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt index 8fbbb1311e..bcc63dd0ba 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.internal.database.query +import im.vector.matrix.android.internal.database.awaitTransaction import im.vector.matrix.android.internal.database.model.FilterEntity import im.vector.matrix.android.internal.session.filter.FilterFactory import io.realm.Realm @@ -25,18 +26,17 @@ import io.realm.kotlin.where /** * Get the current filter, create one if it does not exist */ -internal fun FilterEntity.Companion.getFilter(realm: Realm): FilterEntity { +internal suspend fun FilterEntity.Companion.getFilter(realm: Realm): FilterEntity { var filter = realm.where().findFirst() if (filter == null) { - realm.executeTransaction { - realm.createObject().apply { - filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString() - roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString() - filterId = "" - } + filter = FilterEntity().apply { + filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString() + roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString() + filterId = "" + } + awaitTransaction(realm.configuration) { + it.insert(filter) } - filter = realm.where().findFirst()!! } - return filter } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt index 811950ac15..c17864b82b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt @@ -36,7 +36,7 @@ internal object MatrixModule { @MatrixScope fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers { return MatrixCoroutineDispatchers(io = Dispatchers.IO, - computation = Dispatchers.IO, + computation = Dispatchers.Default, main = Dispatchers.Main, crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(), sync = Executors.newSingleThreadExecutor().asCoroutineDispatcher() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt index 02e6db189a..d7b742fd2d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt @@ -16,54 +16,46 @@ package im.vector.matrix.android.internal.session.filter +import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.internal.database.model.FilterEntity import im.vector.matrix.android.internal.database.model.FilterEntityFields import im.vector.matrix.android.internal.database.query.getFilter import im.vector.matrix.android.internal.di.SessionDatabase +import im.vector.matrix.android.internal.util.awaitTransaction import io.realm.Realm import io.realm.RealmConfiguration import io.realm.kotlin.where import javax.inject.Inject -internal class DefaultFilterRepository @Inject constructor( - @SessionDatabase private val realmConfiguration: RealmConfiguration -) : FilterRepository { +internal class DefaultFilterRepository @Inject constructor(private val monarchy: Monarchy) : FilterRepository { - override fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean { - val result: Boolean + override suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean { + return Realm.getInstance(monarchy.realmConfiguration).use { realm -> + val filter = FilterEntity.getFilter(realm) + val result = if (filter.filterBodyJson != filterBody.toJSONString()) { + // Filter has changed, store it and reset the filter Id + monarchy.awaitTransaction { + // We manage only one filter for now + val filterBodyJson = filterBody.toJSONString() + val roomEventFilterJson = roomEventFilter.toJSONString() - val realm = Realm.getInstance(realmConfiguration) + val filterEntity = FilterEntity.getFilter(it) - val filter = FilterEntity.getFilter(realm) - - if (filter.filterBodyJson != filterBody.toJSONString()) { - // Filter has changed, store it and reset the filter Id - realm.executeTransaction { - // We manage only one filter for now - val filterBodyJson = filterBody.toJSONString() - val roomEventFilterJson = roomEventFilter.toJSONString() - - val filterEntity = FilterEntity.getFilter(it) - - filterEntity.filterBodyJson = filterBodyJson - filterEntity.roomEventFilterJson = roomEventFilterJson - // Reset filterId - filterEntity.filterId = "" + filterEntity.filterBodyJson = filterBodyJson + filterEntity.roomEventFilterJson = roomEventFilterJson + // Reset filterId + filterEntity.filterId = "" + } + true + } else { + filter.filterId.isBlank() } - result = true - } else { - result = filter.filterId.isBlank() + result } - - realm.close() - - return result } - override fun storeFilterId(filterBody: FilterBody, filterId: String) { - val realm = Realm.getInstance(realmConfiguration) - - realm.executeTransaction { + override suspend fun storeFilterId(filterBody: FilterBody, filterId: String) { + monarchy.awaitTransaction { // We manage only one filter for now val filterBodyJson = filterBody.toJSONString() @@ -73,39 +65,24 @@ internal class DefaultFilterRepository @Inject constructor( ?.findFirst() ?.filterId = filterId } - - realm.close() } - override fun getFilter(): String { - val result: String - - val realm = Realm.getInstance(realmConfiguration) - - val filter = FilterEntity.getFilter(realm) - - result = if (filter.filterId.isBlank()) { - // Use the Json format - filter.filterBodyJson - } else { - // Use FilterId - filter.filterId + override suspend fun getFilter(): String { + return Realm.getInstance(monarchy.realmConfiguration).use { + val filter = FilterEntity.getFilter(it) + if (filter.filterId.isBlank()) { + // Use the Json format + filter.filterBodyJson + } else { + // Use FilterId + filter.filterId + } } - - realm.close() - - return result } - override fun getRoomFilter(): String { - val realm = Realm.getInstance(realmConfiguration) - - val filter = FilterEntity.getFilter(realm) - - val result = filter.roomEventFilterJson - - realm.close() - - return result + override suspend fun getRoomFilter(): String { + return Realm.getInstance(monarchy.realmConfiguration).use { + FilterEntity.getFilter(it).roomEventFilterJson + } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterService.kt index 84e820ebca..c85d949d0a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterService.kt @@ -21,36 +21,13 @@ import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith import javax.inject.Inject -internal class DefaultFilterService @Inject constructor(private val filterRepository: FilterRepository, - private val saveFilterTask: SaveFilterTask, +internal class DefaultFilterService @Inject constructor(private val saveFilterTask: SaveFilterTask, private val taskExecutor: TaskExecutor) : FilterService { // TODO Pass a list of support events instead override fun setFilter(filterPreset: FilterService.FilterPreset) { - val filterBody = when (filterPreset) { - FilterService.FilterPreset.RiotFilter -> { - FilterFactory.createRiotFilterBody() - } - FilterService.FilterPreset.NoFilter -> { - FilterFactory.createDefaultFilterBody() - } - } - - val roomFilter = when (filterPreset) { - FilterService.FilterPreset.RiotFilter -> { - FilterFactory.createRiotRoomFilter() - } - FilterService.FilterPreset.NoFilter -> { - FilterFactory.createDefaultRoomFilter() - } - } - - val updated = filterRepository.storeFilter(filterBody, roomFilter) - - if (updated) { - saveFilterTask - .configureWith(SaveFilterTask.Params(filterBody)) - .executeBy(taskExecutor) - } + saveFilterTask + .configureWith(SaveFilterTask.Params(filterPreset)) + .executeBy(taskExecutor) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultSaveFilterTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultSaveFilterTask.kt index b98049675e..08985bf17d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultSaveFilterTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultSaveFilterTask.kt @@ -16,18 +16,19 @@ package im.vector.matrix.android.internal.session.filter +import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.task.Task import javax.inject.Inject /** - * Save a filter to the server + * Save a filter, in db and if any changes, upload to the server */ internal interface SaveFilterTask : Task { data class Params( - val filter: FilterBody + val filterPreset: FilterService.FilterPreset ) } @@ -37,10 +38,29 @@ internal class DefaultSaveFilterTask @Inject constructor(@UserId private val use ) : SaveFilterTask { override suspend fun execute(params: SaveFilterTask.Params) { - val filterResponse = executeRequest { - // TODO auto retry - apiCall = filterAPI.uploadFilter(userId, params.filter) + val filterBody = when (params.filterPreset) { + FilterService.FilterPreset.RiotFilter -> { + FilterFactory.createRiotFilterBody() + } + FilterService.FilterPreset.NoFilter -> { + FilterFactory.createDefaultFilterBody() + } + } + val roomFilter = when (params.filterPreset) { + FilterService.FilterPreset.RiotFilter -> { + FilterFactory.createRiotRoomFilter() + } + FilterService.FilterPreset.NoFilter -> { + FilterFactory.createDefaultRoomFilter() + } + } + val updated = filterRepository.storeFilter(filterBody, roomFilter) + if (updated) { + val filterResponse = executeRequest { + // TODO auto retry + apiCall = filterAPI.uploadFilter(userId, filterBody) + } + filterRepository.storeFilterId(filterBody, filterResponse.filterId) } - filterRepository.storeFilterId(params.filter, filterResponse.filterId) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/FilterRepository.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/FilterRepository.kt index 092d9ff766..d205ea8a87 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/FilterRepository.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/FilterRepository.kt @@ -21,20 +21,20 @@ internal interface FilterRepository { /** * Return true if the filterBody has changed, or need to be sent to the server */ - fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean + suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean /** * Set the filterId of this filter */ - fun storeFilterId(filterBody: FilterBody, filterId: String) + suspend fun storeFilterId(filterBody: FilterBody, filterId: String) /** * Return filter json or filter id */ - fun getFilter(): String + suspend fun getFilter(): String /** * Return the room filter */ - fun getRoomFilter(): String + suspend fun getRoomFilter(): String } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt index f56ee3352f..3d9052bee6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt @@ -16,27 +16,26 @@ package im.vector.matrix.android.internal.session.sync +import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.internal.database.model.SyncEntity import im.vector.matrix.android.internal.di.SessionDatabase +import im.vector.matrix.android.internal.util.awaitTransaction import io.realm.Realm import io.realm.RealmConfiguration import javax.inject.Inject -internal class SyncTokenStore @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration) { +internal class SyncTokenStore @Inject constructor(private val monarchy: Monarchy) { fun getLastToken(): String? { - val realm = Realm.getInstance(realmConfiguration) - val token = realm.where(SyncEntity::class.java).findFirst()?.nextBatch - realm.close() - return token + return Realm.getInstance(monarchy.realmConfiguration).use { + it.where(SyncEntity::class.java).findFirst()?.nextBatch + } } - fun saveToken(token: String?) { - val realm = Realm.getInstance(realmConfiguration) - realm.executeTransaction { + suspend fun saveToken(token: String?) { + monarchy.awaitTransaction { val sync = SyncEntity(token) it.insertOrUpdate(sync) } - realm.close() } } 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..7d9b53a875 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 @@ -116,7 +116,6 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi private fun onSessionCreated(session: Session) { activeSessionHolder.setActiveSession(session) session.configureAndStart(pushRuleTriggerListener, sessionListener) - setState { copy( asyncLoginAction = Success(Unit) @@ -131,9 +130,11 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi // Should not happen Timber.w("homeServerConnectionConfig is null") } else { - val session = authenticator.createSessionFromSso(action.credentials, homeServerConnectionConfigFinal) - - onSessionCreated(session) + authenticator.createSessionFromSso(action.credentials, homeServerConnectionConfigFinal, object : MatrixCallback { + override fun onSuccess(data: Session) { + onSessionCreated(data) + } + }) } } From 3af7ca9ab009f09212ca6b3909a04148a69f81a7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 6 Nov 2019 20:07:28 +0100 Subject: [PATCH 062/117] Retrofit: lazy init okhttp --- .../android/internal/auth/DefaultAuthenticator.kt | 5 +++-- .../android/internal/network/RetrofitFactory.kt | 11 +++++++++-- .../matrix/android/internal/session/SessionModule.kt | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt index 0192715ae5..1f7caa4fc3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt @@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.auth import android.util.Patterns +import dagger.Lazy import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.api.auth.data.Credentials @@ -42,7 +43,7 @@ import javax.inject.Inject import javax.inject.Provider internal class DefaultAuthenticator @Inject constructor(@Unauthenticated - private val okHttpClient: Provider, + private val okHttpClient: Lazy, private val retrofitFactory: RetrofitFactory, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val sessionParamsStore: SessionParamsStore, @@ -133,7 +134,7 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated } private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI { - val retrofit = retrofitFactory.create(okHttpClient.get(), homeServerConnectionConfig.homeServerUri.toString()) + val retrofit = retrofitFactory.create(okHttpClient, homeServerConnectionConfig.homeServerUri.toString()) return retrofit.create(AuthAPI::class.java) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt index 15e6f76381..44ccd7c941 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt @@ -17,17 +17,24 @@ package im.vector.matrix.android.internal.network import com.squareup.moshi.Moshi +import dagger.Lazy +import okhttp3.Call import okhttp3.OkHttpClient +import okhttp3.Request import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory import javax.inject.Inject class RetrofitFactory @Inject constructor(private val moshi: Moshi) { - fun create(okHttpClient: OkHttpClient, baseUrl: String): Retrofit { + fun create(okHttpClient: Lazy, baseUrl: String): Retrofit { return Retrofit.Builder() .baseUrl(baseUrl) - .client(okHttpClient) + .callFactory(object : Call.Factory { + override fun newCall(request: Request): Call { + return okHttpClient.get().newCall(request) + } + }) .addConverterFactory(UnitConverterFactory) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index d038630a74..0e88894969 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session import android.content.Context import com.zhuinden.monarchy.Monarchy import dagger.Binds +import dagger.Lazy import dagger.Module import dagger.Provides import dagger.multibindings.IntoSet @@ -132,7 +133,7 @@ internal abstract class SessionModule { @JvmStatic @Provides @SessionScope - fun providesRetrofit(@Authenticated okHttpClient: OkHttpClient, + fun providesRetrofit(@Authenticated okHttpClient: Lazy, sessionParams: SessionParams, retrofitFactory: RetrofitFactory): Retrofit { return retrofitFactory From 54f93db632e44dee9968e1f6fd9d879a5cc63bd7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 6 Nov 2019 20:08:19 +0100 Subject: [PATCH 063/117] RoomDetail : enter/exit special mode without waiting for draft to update --- .../home/room/detail/RoomDetailActions.kt | 8 +-- .../home/room/detail/RoomDetailFragment.kt | 53 +++++++++---------- .../home/room/detail/RoomDetailViewModel.kt | 16 +++--- .../room/detail/composer/TextComposerView.kt | 29 +++++++++- 4 files changed, 66 insertions(+), 40 deletions(-) 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 a219d25c09..8dc73be82a 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 @@ -42,10 +42,10 @@ sealed class RoomDetailActions { object AcceptInvite : RoomDetailActions() object RejectInvite : RoomDetailActions() - data class EnterEditMode(val eventId: String, val draft: String) : RoomDetailActions() - data class EnterQuoteMode(val eventId: String, val draft: String) : RoomDetailActions() - data class EnterReplyMode(val eventId: String, val draft: String) : RoomDetailActions() - data class ExitSpecialMode(val draft: String) : RoomDetailActions() + data class EnterEditMode(val eventId: String, val text: String) : RoomDetailActions() + data class EnterQuoteMode(val eventId: String, val text: String) : RoomDetailActions() + data class EnterReplyMode(val eventId: String, val text: String) : RoomDetailActions() + data class ExitSpecialMode(val text: String) : RoomDetailActions() data class ResendMessage(val eventId: String) : RoomDetailActions() data class RemoveFailedEcho(val eventId: String) : 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 76d01228b8..006599c073 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 @@ -223,7 +223,6 @@ class RoomDetailFragment : setupToolbar(roomToolbar) setupRecyclerView() setupComposer() - setupAttachmentButton() setupInviteView() setupNotificationView() setupJumpToReadMarkerView() @@ -601,21 +600,30 @@ class RoomDetailFragment : }) .build() - composerLayout.sendButton.setOnClickListener { - if (lockSendButton) { - Timber.w("Send button is locked") - return@setOnClickListener - } - val textMessage = composerLayout.composerEditText.text.toString() - if (textMessage.isNotBlank()) { - lockSendButton = true - roomDetailViewModel.process(RoomDetailActions.SendMessage(textMessage, vectorPreferences.isMarkdownEnabled())) - } - } - composerLayout.composerRelatedMessageCloseButton.setOnClickListener { - roomDetailViewModel.process(RoomDetailActions.ExitSpecialMode(composerLayout.composerEditText.text.toString())) - } composerLayout.callback = object : TextComposerView.Callback { + + override fun onAddAttachment() { + if (!::attachmentTypeSelector.isInitialized) { + attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@RoomDetailFragment) + } + attachmentTypeSelector.show(composerLayout.attachmentButton, keyboardStateUtils.isKeyboardShowing) + } + + override fun onSendMessage(text: String) { + if (lockSendButton) { + Timber.w("Send button is locked") + return + } + if (text.isNotBlank()) { + lockSendButton = true + roomDetailViewModel.process(RoomDetailActions.SendMessage(text, vectorPreferences.isMarkdownEnabled())) + } + } + + override fun onCloseRelatedMessage() { + roomDetailViewModel.process(RoomDetailActions.ExitSpecialMode(composerLayout.text.toString())) + } + override fun onRichContentSelected(contentUri: Uri): Boolean { // We need WRITE_EXTERNAL permission return if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this@RoomDetailFragment, PERMISSION_REQUEST_CODE_INCOMING_URI)) { @@ -638,15 +646,6 @@ class RoomDetailFragment : return isHandled } - private fun setupAttachmentButton() { - composerLayout.attachmentButton.setOnClickListener { - if (!::attachmentTypeSelector.isInitialized) { - attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this) - } - attachmentTypeSelector.show(composerLayout.attachmentButton, keyboardStateUtils.isKeyboardShowing) - } - } - private fun setupInviteView() { inviteView.callback = this } @@ -1114,13 +1113,13 @@ class RoomDetailFragment : roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } is SimpleAction.Edit -> { - roomDetailViewModel.process(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.process(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.text.toString())) } is SimpleAction.Quote -> { - roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.text.toString())) } is SimpleAction.Reply -> { - roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.text.toString())) } is SimpleAction.CopyPermalink -> { val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) 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 2436b7a8b4..59617dfa0a 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 @@ -520,17 +520,18 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleEditAction(action: RoomDetailActions.EnterEditMode) { - saveCurrentDraft(action.draft) + saveCurrentDraft(action.text) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> timelineEvent.root.eventId?.let { room.saveDraft(UserDraft.EDIT(it, timelineEvent.getTextEditableContent() ?: "")) } + setState { copy(sendMode = SendMode.EDIT(timelineEvent, action.text)) } } } private fun handleQuoteAction(action: RoomDetailActions.EnterQuoteMode) { - saveCurrentDraft(action.draft) + saveCurrentDraft(action.text) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> withState { state -> @@ -539,16 +540,16 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro if (state.sendMode is SendMode.EDIT) { room.saveDraft(UserDraft.QUOTE(it, "")) } else { - room.saveDraft(UserDraft.QUOTE(it, action.draft)) + room.saveDraft(UserDraft.QUOTE(it, action.text)) } } + setState { copy(sendMode = SendMode.QUOTE(timelineEvent, action.text)) } } } } private fun handleReplyAction(action: RoomDetailActions.EnterReplyMode) { - saveCurrentDraft(action.draft) - + saveCurrentDraft(action.text) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> withState { state -> // Save a new draft and keep the previously entered text, if it was not an edit @@ -556,9 +557,10 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro if (state.sendMode is SendMode.EDIT) { room.saveDraft(UserDraft.REPLY(it, "")) } else { - room.saveDraft(UserDraft.REPLY(it, action.draft)) + room.saveDraft(UserDraft.REPLY(it, action.text)) } } + setState { copy(sendMode = SendMode.REPLY(timelineEvent, action.text)) } } } } @@ -584,7 +586,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro room.deleteDraft() } else { // Save a new draft and keep the previously entered text - room.saveDraft(UserDraft.REGULAR(action.draft)) + room.saveDraft(UserDraft.REGULAR(action.text)) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt index 0a6d3dde08..9e3ac7888d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt @@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.detail.composer import android.content.Context import android.net.Uri +import android.text.Editable import android.util.AttributeSet import android.view.ViewGroup import android.widget.ImageButton @@ -31,6 +32,9 @@ import androidx.transition.TransitionManager import butterknife.BindView import butterknife.ButterKnife import im.vector.riotx.R +import im.vector.riotx.features.home.room.detail.RoomDetailActions +import kotlinx.android.synthetic.main.merge_composer_layout.view.* +import timber.log.Timber /** * Encapsulate the timeline composer UX. @@ -39,7 +43,11 @@ import im.vector.riotx.R class TextComposerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr) { - interface Callback : ComposerEditText.Callback + interface Callback : ComposerEditText.Callback { + fun onCloseRelatedMessage() + fun onSendMessage(text: String) + fun onAddAttachment() + } var callback: Callback? = null @@ -62,15 +70,32 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib private val animationDuration = 100L + val text: Editable? + get() = composerEditText.text + init { inflate(context, R.layout.merge_composer_layout, this) ButterKnife.bind(this) collapse(false) - composerEditText.callback = object : Callback, ComposerEditText.Callback { + composerEditText.callback = object : ComposerEditText.Callback { override fun onRichContentSelected(contentUri: Uri): Boolean { return callback?.onRichContentSelected(contentUri) ?: false } } + composerRelatedMessageCloseButton.setOnClickListener { + collapse() + callback?.onCloseRelatedMessage() + } + + sendButton.setOnClickListener { + val textMessage = text?.toString() ?: "" + callback?.onSendMessage(textMessage) + } + + attachmentButton.setOnClickListener { + callback?.onAddAttachment() + } + } fun collapse(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) { From 2027802f82be26e851cf27c2f27924d6713c70d5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Nov 2019 10:37:49 +0100 Subject: [PATCH 064/117] Add debug screen for all SAS emoji --- .../matrix/android/api/crypto/Emojis.kt | 27 ++++++++++ vector/src/debug/AndroidManifest.xml | 1 + .../riotx/features/debug/DebugMenuActivity.kt | 6 +++ .../debug/sas/DebugSasEmojiActivity.kt | 36 +++++++++++++ .../riotx/features/debug/sas/ItemSasEmoji.kt | 51 ++++++++++++++++++ .../features/debug/sas/SasEmojiController.kt | 39 ++++++++++++++ .../debug/res/layout/activity_debug_menu.xml | 7 +++ .../src/debug/res/layout/item_sas_emoji.xml | 54 +++++++++++++++++++ 8 files changed, 221 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt create mode 100644 vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt create mode 100644 vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt create mode 100644 vector/src/debug/java/im/vector/riotx/features/debug/sas/SasEmojiController.kt create mode 100644 vector/src/debug/res/layout/item_sas_emoji.xml diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt new file mode 100644 index 0000000000..943b2c1b10 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt @@ -0,0 +1,27 @@ +/* + * 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.matrix.android.api.crypto + +import im.vector.matrix.android.api.session.crypto.sas.EmojiRepresentation +import im.vector.matrix.android.internal.crypto.verification.getEmojiForCode + +/** + * Provide all the emojis used for SAS verification (for debug purpose) + */ +fun getAllVerificationEmojis(): List { + return (0..63).map { getEmojiForCode(it) } +} diff --git a/vector/src/debug/AndroidManifest.xml b/vector/src/debug/AndroidManifest.xml index 0d071e3465..8bb571902a 100644 --- a/vector/src/debug/AndroidManifest.xml +++ b/vector/src/debug/AndroidManifest.xml @@ -4,6 +4,7 @@ + diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt index bfb9f0654e..6624a05985 100644 --- a/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/riotx/features/debug/DebugMenuActivity.kt @@ -26,6 +26,7 @@ import androidx.core.app.Person import butterknife.OnClick import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.features.debug.sas.DebugSasEmojiActivity class DebugMenuActivity : VectorBaseActivity() { @@ -36,6 +37,11 @@ class DebugMenuActivity : VectorBaseActivity() { startActivity(Intent(this, TestLinkifyActivity::class.java)) } + @OnClick(R.id.debug_show_sas_emoji) + fun showSasEmoji() { + startActivity(Intent(this, DebugSasEmojiActivity::class.java)) + } + @OnClick(R.id.debug_test_notification) fun testNotification() { val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt b/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt new file mode 100644 index 0000000000..49756d0c1a --- /dev/null +++ b/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt @@ -0,0 +1,36 @@ +/* + * 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.debug.sas + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import im.vector.matrix.android.api.crypto.getAllVerificationEmojis +import im.vector.riotx.R +import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.* + +class DebugSasEmojiActivity : AppCompatActivity() { + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.fragment_generic_recycler_epoxy) + + val controller = SasEmojiController() + epoxyRecyclerView.setController(controller) + controller.setData(SasState(getAllVerificationEmojis())) + } +} diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt b/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt new file mode 100644 index 0000000000..e7f152673c --- /dev/null +++ b/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt @@ -0,0 +1,51 @@ +/* + * 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.debug.sas + +import android.annotation.SuppressLint +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.matrix.android.api.session.crypto.sas.EmojiRepresentation +import im.vector.riotx.core.epoxy.VectorEpoxyHolder +import im.vector.riotx.core.epoxy.VectorEpoxyModel + + +@EpoxyModelClass(layout = im.vector.riotx.R.layout.item_sas_emoji) +abstract class ItemSasEmoji : VectorEpoxyModel() { + + @EpoxyAttribute + var index: Int = 0 + @EpoxyAttribute + lateinit var emojiRepresentation: EmojiRepresentation + + @SuppressLint("SetTextI18n") + override fun bind(holder: Holder) { + super.bind(holder) + holder.indexView.text = "$index:" + holder.emojiView.text = emojiRepresentation.emoji + holder.textView.setText(emojiRepresentation.nameResId) + holder.idView.text = holder.idView.resources.getResourceEntryName(emojiRepresentation.nameResId) + } + + class Holder : VectorEpoxyHolder() { + val indexView by bind(im.vector.riotx.R.id.sas_emoji_index) + val emojiView by bind(im.vector.riotx.R.id.sas_emoji) + val textView by bind(im.vector.riotx.R.id.sas_emoji_text) + val idView by bind(im.vector.riotx.R.id.sas_emoji_text_id) + } +} diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/sas/SasEmojiController.kt b/vector/src/debug/java/im/vector/riotx/features/debug/sas/SasEmojiController.kt new file mode 100644 index 0000000000..daf432fb45 --- /dev/null +++ b/vector/src/debug/java/im/vector/riotx/features/debug/sas/SasEmojiController.kt @@ -0,0 +1,39 @@ +/* + * 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.debug.sas + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.matrix.android.api.session.crypto.sas.EmojiRepresentation + +data class SasState( + val emojiList: List +) + +class SasEmojiController : TypedEpoxyController() { + + override fun buildModels(data: SasState?) { + if (data == null) return + + data.emojiList.forEachIndexed { idx, emojiRepresentation -> + itemSasEmoji { + id(idx) + index(idx) + emojiRepresentation(emojiRepresentation) + } + } + } +} diff --git a/vector/src/debug/res/layout/activity_debug_menu.xml b/vector/src/debug/res/layout/activity_debug_menu.xml index a0acfe9937..01ab061f6a 100644 --- a/vector/src/debug/res/layout/activity_debug_menu.xml +++ b/vector/src/debug/res/layout/activity_debug_menu.xml @@ -47,6 +47,13 @@ android:layout_height="wrap_content" android:text="Test Material theme Dark" /> + + + + + + + + + + + + + + + + + From 96e610970a5c0f5bf8bb7a2eed98ba2c67582618 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Nov 2019 12:08:17 +0100 Subject: [PATCH 065/117] Finish the work --- .../restore/KeysBackupRestoreSuccessFragment.kt | 4 ---- .../keysbackup/setup/KeysBackupSetupStep1Fragment.kt | 8 ++------ .../CreateDirectRoomKnownUsersFragment.kt | 8 ++++---- .../riotx/features/reactions/EmojiChooserFragment.kt | 7 ++----- .../riotx/features/settings/VectorSettingsActivity.kt | 6 ++---- .../features/settings/VectorSettingsRootFragment.kt | 11 ++--------- vector/src/main/res/layout/fragment_home_detail.xml | 2 +- 7 files changed, 13 insertions(+), 33 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index 25be8ded47..813bb9ca72 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -58,8 +58,4 @@ class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragmen fun onDone() { sharedViewModel.importRoomKeysFinishWithResult.value = LiveEvent(sharedViewModel.importKeyResult!!) } - - companion object { - fun newInstance() = KeysBackupRestoreSuccessFragment() - } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index fd7a95bff1..d018cc1ce9 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -29,11 +29,7 @@ import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.utils.LiveEvent import javax.inject.Inject -class KeysBackupSetupStep1Fragment @Inject constructor(): VectorBaseFragment() { - - companion object { - fun newInstance() = KeysBackupSetupStep1Fragment() - } +class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step1 @@ -52,7 +48,7 @@ class KeysBackupSetupStep1Fragment @Inject constructor(): VectorBaseFragment() { ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) } ?: throw Exception("Invalid Activity") - viewModel.showManualExport.observe(this, Observer { + viewModel.showManualExport.observe(viewLifecycleOwner, Observer { val showOption = it ?: false // Can't use isVisible because the kotlin compiler will crash with Back-end (JVM) Internal error: wrong code generated advancedOptionText.visibility = if (showOption) View.VISIBLE else View.GONE diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index a05bbf1a21..3c38242c6b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -40,7 +40,7 @@ import kotlinx.android.synthetic.main.fragment_create_direct_room.* import javax.inject.Inject class CreateDirectRoomKnownUsersFragment @Inject constructor( - private val directRoomController: KnownUsersController, + private val knownUsersController: KnownUsersController, private val dimensionConverter: DimensionConverter ) : VectorBaseFragment(), KnownUsersController.Callback { @@ -97,8 +97,8 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( recyclerView.setHasFixedSize(true) // Don't activate animation as we might have way to much item animation when filtering recyclerView.itemAnimator = null - directRoomController.callback = this - recyclerView.setController(directRoomController) + knownUsersController.callback = this + recyclerView.setController(knownUsersController) } private fun setupFilterView() { @@ -127,7 +127,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( } override fun invalidate() = withState(viewModel) { - directRoomController.setData(it) + knownUsersController.setData(it) } private fun updateChipsView(data: SelectUserAction) { diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index 77cad5643f..589fa5dbff 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -20,12 +20,9 @@ import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.RecyclerView import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment +import javax.inject.Inject -class EmojiChooserFragment : VectorBaseFragment() { - - companion object { - fun newInstance() = EmojiChooserFragment() - } +class EmojiChooserFragment @Inject constructor() : VectorBaseFragment() { override fun getLayoutResId() = R.layout.emoji_chooser_fragment diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt index 36536994d5..16484224af 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsActivity.kt @@ -23,6 +23,7 @@ import androidx.preference.PreferenceFragmentCompat import im.vector.matrix.android.api.session.Session import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent +import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.VectorBaseActivity import kotlinx.android.synthetic.main.activity_vector_settings.* import timber.log.Timber @@ -52,11 +53,8 @@ class VectorSettingsActivity : VectorBaseActivity(), configureToolbar(settingsToolbar) if (isFirstCreation()) { - val vectorSettingsPreferencesFragment = VectorSettingsRootFragment.newInstance() // display the fragment - supportFragmentManager.beginTransaction() - .replace(R.id.vector_settings_page, vectorSettingsPreferencesFragment, FRAGMENT_TAG) - .commit() + replaceFragment(R.id.vector_settings_page, VectorSettingsRootFragment::class.java, null, FRAGMENT_TAG) } supportFragmentManager.addOnBackStackChangedListener(this) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsRootFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsRootFragment.kt index a70164485f..a50e0e9ad0 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsRootFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsRootFragment.kt @@ -17,9 +17,9 @@ package im.vector.riotx.features.settings import im.vector.riotx.R -import im.vector.riotx.core.extensions.withArgs +import javax.inject.Inject -class VectorSettingsRootFragment : VectorSettingsBaseFragment() { +class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragment() { override var titleRes: Int = R.string.title_activity_settings override val preferenceXmlRes = R.xml.vector_settings_root @@ -27,11 +27,4 @@ class VectorSettingsRootFragment : VectorSettingsBaseFragment() { override fun bindPref() { // Nothing to do } - - companion object { - fun newInstance() = VectorSettingsRootFragment() - .withArgs { - // putString(ARG_MATRIX_ID, matrixId) - } - } } diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index bda23973ee..7c0886efc5 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -63,7 +63,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/syncStateView" /> - Date: Thu, 7 Nov 2019 12:23:21 +0100 Subject: [PATCH 066/117] Fix regression when filtering emojis --- .../reactions/EmojiReactionPickerActivity.kt | 12 ++++++------ .../res/layout/activity_emoji_reaction_picker.xml | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) 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 a442f5f77e..4dc8cd643d 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 @@ -131,8 +131,8 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), } } - supportFragmentManager.findFragmentById(R.id.fragment)?.view?.isVisible = true - supportFragmentManager.findFragmentById(R.id.searchFragment)?.view?.isInvisible = true + emojiPickerWholeListFragmentContainer.isVisible = true + emojiPickerFilteredListFragmentContainer.isVisible = false tabLayout.isVisible = true } @@ -195,13 +195,13 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), private fun onQueryText(query: String) { if (query.isEmpty()) { - supportFragmentManager.findFragmentById(R.id.fragment)?.view?.isVisible = true - supportFragmentManager.findFragmentById(R.id.searchFragment)?.view?.isInvisible = true tabLayout.isVisible = true + emojiPickerWholeListFragmentContainer.isVisible = true + emojiPickerFilteredListFragmentContainer.isVisible = false } else { tabLayout.isVisible = false - supportFragmentManager.findFragmentById(R.id.fragment)?.view?.isInvisible = true - supportFragmentManager.findFragmentById(R.id.searchFragment)?.view?.isVisible = true + emojiPickerWholeListFragmentContainer.isVisible = false + emojiPickerFilteredListFragmentContainer.isVisible = true searchResultViewModel.updateQuery(query) } } diff --git a/vector/src/main/res/layout/activity_emoji_reaction_picker.xml b/vector/src/main/res/layout/activity_emoji_reaction_picker.xml index f46635d816..9d680e6221 100644 --- a/vector/src/main/res/layout/activity_emoji_reaction_picker.xml +++ b/vector/src/main/res/layout/activity_emoji_reaction_picker.xml @@ -7,7 +7,7 @@ tools:context="im.vector.riotx.features.reactions.EmojiReactionPickerActivity"> + android:visibility="gone" /> Date: Thu, 7 Nov 2019 13:59:21 +0100 Subject: [PATCH 067/117] remove unused import --- .../riotx/features/reactions/EmojiReactionPickerActivity.kt | 1 - 1 file changed, 1 deletion(-) 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 4dc8cd643d..cd5d5e3e74 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 @@ -25,7 +25,6 @@ import android.view.MenuInflater import android.view.MenuItem import android.widget.SearchView import androidx.appcompat.widget.Toolbar -import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders From 114101699d1c0373b0c5a3ea01ddf7fd7f1d9d5c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 4 Nov 2019 18:50:23 +0100 Subject: [PATCH 068/117] Fix potential ignoring of account data (return@foreach) --- .../internal/session/sync/UserAccountDataSyncHandler.kt | 8 +++----- .../session/sync/model/UserAccountDataFallback.kt | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt index 56b96b428d..10e9001cc2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt @@ -26,10 +26,7 @@ import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.session.pushers.SavePushRulesTask import im.vector.matrix.android.internal.session.room.membership.RoomMembers -import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync -import im.vector.matrix.android.internal.session.sync.model.UserAccountDataDirectMessages -import im.vector.matrix.android.internal.session.sync.model.UserAccountDataPushRules -import im.vector.matrix.android.internal.session.sync.model.UserAccountDataSync +import im.vector.matrix.android.internal.session.sync.model.* import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask import im.vector.matrix.android.internal.task.TaskExecutor @@ -51,7 +48,8 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc when (it) { is UserAccountDataDirectMessages -> handleDirectChatRooms(it) is UserAccountDataPushRules -> handlePushRules(it) - else -> return@forEach + is UserAccountDataFallback -> Timber.d("Receive account data of unhandled type ${it.type}") + else -> error("Missing code here!") } } monarchy.doWithRealm { realm -> diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt index 70d28c084f..99196bcaa2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt @@ -21,5 +21,6 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) internal data class UserAccountDataFallback( + @Json(name = "type") val type: String, @Json(name = "content") val content: Map ) : UserAccountData From 2f7d1f9f01da07d451b08003450f888eb6f8649f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 11:46:44 +0100 Subject: [PATCH 069/117] Ignored Users account data --- .../vector/matrix/android/api/util/Types.kt | 2 + .../android/internal/di/MoshiProvider.kt | 10 +++-- .../sync/UserAccountDataSyncHandler.kt | 4 ++ .../session/sync/model/SyncResponse.kt | 1 + .../model/accountdata/IgnoredUsersContent.kt | 29 +++++++++++++ .../{ => accountdata}/UserAccountData.kt | 8 +++- .../UserAccountDataDirectMessages.kt | 5 ++- .../UserAccountDataFallback.kt | 6 +-- .../UserAccountDataIgnoredUsers.kt | 41 +++++++++++++++++++ .../UserAccountDataPushRules.kt | 5 ++- .../{ => accountdata}/UserAccountDataSync.kt | 2 +- .../accountdata/UpdateUserAccountDataTask.kt | 2 +- 12 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/{ => accountdata}/UserAccountData.kt (81%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/{ => accountdata}/UserAccountDataDirectMessages.kt (82%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/{ => accountdata}/UserAccountDataFallback.kt (84%) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/{ => accountdata}/UserAccountDataPushRules.kt (83%) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/{ => accountdata}/UserAccountDataSync.kt (91%) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt index bfb9a59956..f83166512e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt @@ -21,4 +21,6 @@ import java.lang.reflect.ParameterizedType typealias JsonDict = Map +val emptyJsonDict = emptyMap() + internal val JSON_DICT_PARAMETERIZED_TYPE: ParameterizedType = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt index d8db462f7c..96cdf29226 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt @@ -20,10 +20,11 @@ import com.squareup.moshi.Moshi import im.vector.matrix.android.api.session.room.model.message.* import im.vector.matrix.android.internal.network.parsing.RuntimeJsonAdapterFactory import im.vector.matrix.android.internal.network.parsing.UriMoshiAdapter -import im.vector.matrix.android.internal.session.sync.model.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.UserAccountDataDirectMessages -import im.vector.matrix.android.internal.session.sync.model.UserAccountDataFallback -import im.vector.matrix.android.internal.session.sync.model.UserAccountDataPushRules +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataFallback +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules object MoshiProvider { @@ -31,6 +32,7 @@ object MoshiProvider { .add(UriMoshiAdapter()) .add(RuntimeJsonAdapterFactory.of(UserAccountData::class.java, "type", UserAccountDataFallback::class.java) .registerSubtype(UserAccountDataDirectMessages::class.java, UserAccountData.TYPE_DIRECT_MESSAGES) + .registerSubtype(UserAccountDataIgnoredUsers::class.java, UserAccountData.TYPE_IGNORED_USER_LIST) .registerSubtype(UserAccountDataPushRules::class.java, UserAccountData.TYPE_PUSH_RULES) ) .add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt index 10e9001cc2..97fa269b9f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt @@ -27,6 +27,10 @@ import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.session.pushers.SavePushRulesTask import im.vector.matrix.android.internal.session.room.membership.RoomMembers import im.vector.matrix.android.internal.session.sync.model.* +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataFallback +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask import im.vector.matrix.android.internal.task.TaskExecutor diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/SyncResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/SyncResponse.kt index d084dcdadd..9e5cc2cfa4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/SyncResponse.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/SyncResponse.kt @@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync // SyncResponse represents the request response for server sync v2. @JsonClass(generateAdapter = true) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt new file mode 100644 index 0000000000..c61c122ffe --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt @@ -0,0 +1,29 @@ +/* + * 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.matrix.android.internal.session.sync.model.accountdata + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import im.vector.matrix.android.api.util.JsonDict + +@JsonClass(generateAdapter = true) +internal data class IgnoredUsersContent( + /** + * Required. The map of users to ignore. UserId -> empty object for future enhancement + */ + @Json(name = "ignored_users") val ignoredUsers: Map +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt similarity index 81% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountData.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt index 2173d2f4df..55dbad6099 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountData.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt @@ -14,9 +14,13 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.session.sync.model +package im.vector.matrix.android.internal.session.sync.model.accountdata -internal interface UserAccountData { +import com.squareup.moshi.Json + +internal abstract class UserAccountData { + + @Json(name = "type") abstract val type: String companion object { const val TYPE_IGNORED_USER_LIST = "m.ignored_user_list" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataDirectMessages.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt similarity index 82% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataDirectMessages.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt index 825a16cb1e..e5c6135bd1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataDirectMessages.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataDirectMessages.kt @@ -14,12 +14,13 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.session.sync.model +package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) internal data class UserAccountDataDirectMessages( + @Json(name = "type") override val type: String = TYPE_DIRECT_MESSAGES, @Json(name = "content") val content: Map> -) : UserAccountData +) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataFallback.kt similarity index 84% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataFallback.kt index 99196bcaa2..a8b8235d37 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataFallback.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataFallback.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.session.sync.model +package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) internal data class UserAccountDataFallback( - @Json(name = "type") val type: String, + @Json(name = "type") override val type: String, @Json(name = "content") val content: Map -) : UserAccountData +) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt new file mode 100644 index 0000000000..f6d60b278b --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt @@ -0,0 +1,41 @@ +/* + * 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.matrix.android.internal.session.sync.model.accountdata + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import im.vector.matrix.android.api.util.emptyJsonDict + +@JsonClass(generateAdapter = true) +internal data class UserAccountDataIgnoredUsers( + @Json(name = "type") override val type: String = TYPE_IGNORED_USER_LIST, + @Json(name = "content") val content: IgnoredUsersContent +) : UserAccountData() { + + + companion object { + fun createWithUserIds(userIds: List): UserAccountDataIgnoredUsers { + return UserAccountDataIgnoredUsers( + content = IgnoredUsersContent( + ignoredUsers = userIds.associateWith { emptyJsonDict } + ) + ) + } + } +} + + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataPushRules.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt similarity index 83% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataPushRules.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt index 7f357c876b..0d549d1667 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataPushRules.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataPushRules.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.session.sync.model +package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,5 +22,6 @@ import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse @JsonClass(generateAdapter = true) internal data class UserAccountDataPushRules( + @Json(name = "type") override val type: String = TYPE_PUSH_RULES, @Json(name = "content") val content: GetPushRulesResponse -) : UserAccountData +) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataSync.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt similarity index 91% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataSync.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt index 4b9e9d652d..c7f8bfa4c2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/UserAccountDataSync.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataSync.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.session.sync.model +package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index 5c0dac1125..1327ca7410 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -18,7 +18,7 @@ package im.vector.matrix.android.internal.session.user.accountdata import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.network.executeRequest -import im.vector.matrix.android.internal.session.sync.model.UserAccountData +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData import im.vector.matrix.android.internal.task.Task import javax.inject.Inject From fbae3d27c23a61d8fc16560c7531206a24f89246 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 12:40:25 +0100 Subject: [PATCH 070/117] Ignore/Unignore userIds --- .../java/im/vector/matrix/rx/RxSession.kt | 4 ++ .../android/api/session/user/UserService.kt | 15 +++++ .../database/model/IgnoredUserEntity.kt | 24 +++++++ .../database/model/SessionRealmModule.kt | 1 + .../sync/UserAccountDataSyncHandler.kt | 22 +++++-- .../session/user/DefaultUserService.kt | 36 ++++++++++- .../internal/session/user/UserModule.kt | 10 +++ .../user/accountdata/SaveIgnoredUsersTask.kt | 45 +++++++++++++ .../accountdata/UpdateIgnoredUserIdsTask.kt | 64 +++++++++++++++++++ .../accountdata/UpdateUserAccountDataTask.kt | 1 + 10 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/IgnoredUserEntity.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index f19777b6f5..1ffb056f55 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -54,6 +54,10 @@ class RxSession(private val session: Session) { return session.liveUsers().asObservable() } + fun liveIgnoredUserIds(): Observable> { + return session.liveIgnoredUserIds().asObservable() + } + fun livePagedUsers(filter: String? = null): Observable> { return session.livePagedUsers(filter).asObservable() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt index d3de777e34..abc3c9330e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt @@ -64,4 +64,19 @@ interface UserService { * @return a Livedata of users */ fun livePagedUsers(filter: String? = null): LiveData> + + /** + * Get list of ignored users id + */ + fun liveIgnoredUserIds(): LiveData> + + /** + * Ignore users + */ + fun ignoreUserIds(userIds: List, callback: MatrixCallback): Cancelable + + /** + * Un-ignore some users + */ + fun unIgnoreUserIds(userIds: List, callback: MatrixCallback): Cancelable } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/IgnoredUserEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/IgnoredUserEntity.kt new file mode 100644 index 0000000000..bd31046f82 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/IgnoredUserEntity.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.matrix.android.internal.database.model + +import io.realm.RealmObject + +internal open class IgnoredUserEntity(var userId: String = "") : RealmObject() { + + companion object +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/SessionRealmModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/SessionRealmModule.kt index 21b2fdce5a..76b355b064 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/SessionRealmModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/SessionRealmModule.kt @@ -35,6 +35,7 @@ import io.realm.annotations.RealmModule RoomTagEntity::class, SyncEntity::class, UserEntity::class, + IgnoredUserEntity::class, EventAnnotationsSummaryEntity::class, ReactionAggregatedSummaryEntity::class, EditAggregatedSummaryEntity::class, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt index 97fa269b9f..07bf965ae1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt @@ -26,12 +26,10 @@ import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.session.pushers.SavePushRulesTask import im.vector.matrix.android.internal.session.room.membership.RoomMembers -import im.vector.matrix.android.internal.session.sync.model.* -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataFallback -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync +import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync +import im.vector.matrix.android.internal.session.sync.model.accountdata.* import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper +import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith @@ -45,6 +43,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc private val directChatsHelper: DirectChatsHelper, private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val savePushRulesTask: SavePushRulesTask, + private val saveIgnoredUsersTask: SaveIgnoredUsersTask, private val taskExecutor: TaskExecutor) { suspend fun handle(accountData: UserAccountDataSync?, invites: Map?) { @@ -52,10 +51,18 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc when (it) { is UserAccountDataDirectMessages -> handleDirectChatRooms(it) is UserAccountDataPushRules -> handlePushRules(it) + is UserAccountDataIgnoredUsers -> handleIgnoredUsers(it) is UserAccountDataFallback -> Timber.d("Receive account data of unhandled type ${it.type}") else -> error("Missing code here!") } } + + // TODO Store all account data, app can be interested of it + // accountData?.list?.forEach { + // it.toString() + // MoshiProvider.providesMoshi() + // } + monarchy.doWithRealm { realm -> synchronizeWithServerIfNeeded(realm, invites) } @@ -116,4 +123,9 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc updateUserAccountDataTask.configureWith(updateUserAccountParams).executeBy(taskExecutor) } } + + private fun handleIgnoredUsers(userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) { + saveIgnoredUsersTask.configureWith(userAccountDataIgnoredUsers).executeBy(taskExecutor) + // TODO If not initial sync, we should execute a init sync + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt index be330bfc36..5e21c58e09 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt @@ -29,9 +29,12 @@ import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.toOptional import im.vector.matrix.android.internal.database.mapper.asDomain +import im.vector.matrix.android.internal.database.model.IgnoredUserEntity +import im.vector.matrix.android.internal.database.model.IgnoredUserEntityFields import im.vector.matrix.android.internal.database.model.UserEntity import im.vector.matrix.android.internal.database.model.UserEntityFields import im.vector.matrix.android.internal.database.query.where +import im.vector.matrix.android.internal.session.user.accountdata.UpdateIgnoredUserIdsTask import im.vector.matrix.android.internal.session.user.model.SearchUserTask import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith @@ -40,8 +43,8 @@ import javax.inject.Inject internal class DefaultUserService @Inject constructor(private val monarchy: Monarchy, private val searchUserTask: SearchUserTask, + private val updateIgnoredUserIdsTask: UpdateIgnoredUserIdsTask, private val taskExecutor: TaskExecutor) : UserService { - private val realmDataSourceFactory: Monarchy.RealmDataSourceFactory by lazy { monarchy.createDataSourceFactory { realm -> realm.where(UserEntity::class.java) @@ -62,7 +65,7 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona override fun getUser(userId: String): User? { val userEntity = monarchy.fetchCopied { UserEntity.where(it, userId).findFirst() } - ?: return null + ?: return null return userEntity.asDomain() } @@ -117,4 +120,33 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona } .executeBy(taskExecutor) } + + override fun liveIgnoredUserIds(): LiveData> { + return monarchy.findAllMappedWithChanges( + { realm -> + realm.where(IgnoredUserEntity::class.java) + .isNotEmpty(IgnoredUserEntityFields.USER_ID) + .sort(IgnoredUserEntityFields.USER_ID) + }, + { it.userId } + ) + } + + override fun ignoreUserIds(userIds: List, callback: MatrixCallback): Cancelable { + val params = UpdateIgnoredUserIdsTask.Params(userIdsToIgnore = userIds.toList()) + return updateIgnoredUserIdsTask + .configureWith(params) { + this.callback = callback + } + .executeBy(taskExecutor) + } + + override fun unIgnoreUserIds(userIds: List, callback: MatrixCallback): Cancelable { + val params = UpdateIgnoredUserIdsTask.Params(userIdsToUnIgnore = userIds.toList()) + return updateIgnoredUserIdsTask + .configureWith(params) { + this.callback = callback + } + .executeBy(taskExecutor) + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/UserModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/UserModule.kt index a997c616f3..51c296ba6e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/UserModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/UserModule.kt @@ -21,6 +21,10 @@ import dagger.Module import dagger.Provides import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.internal.session.SessionScope +import im.vector.matrix.android.internal.session.user.accountdata.DefaultSaveIgnoredUsersTask +import im.vector.matrix.android.internal.session.user.accountdata.DefaultUpdateIgnoredUserIdsTask +import im.vector.matrix.android.internal.session.user.accountdata.SaveIgnoredUsersTask +import im.vector.matrix.android.internal.session.user.accountdata.UpdateIgnoredUserIdsTask import im.vector.matrix.android.internal.session.user.model.DefaultSearchUserTask import im.vector.matrix.android.internal.session.user.model.SearchUserTask import retrofit2.Retrofit @@ -43,4 +47,10 @@ internal abstract class UserModule { @Binds abstract fun bindSearchUserTask(searchUserTask: DefaultSearchUserTask): SearchUserTask + + @Binds + abstract fun bindSaveIgnoredUsersTask(task: DefaultSaveIgnoredUsersTask): SaveIgnoredUsersTask + + @Binds + abstract fun bindUpdateIgnoredUserIdsTask(task: DefaultUpdateIgnoredUserIdsTask): UpdateIgnoredUserIdsTask } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt new file mode 100644 index 0000000000..ef3a5d0e76 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt @@ -0,0 +1,45 @@ +/* + * 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.matrix.android.internal.session.user.accountdata + +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse +import im.vector.matrix.android.internal.database.model.IgnoredUserEntity +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers +import im.vector.matrix.android.internal.task.Task +import im.vector.matrix.android.internal.util.awaitTransaction +import javax.inject.Inject + +/** + * Save the ignored users list in DB + */ +internal interface SaveIgnoredUsersTask : Task { + data class Params(val pa: GetPushRulesResponse) +} + +internal class DefaultSaveIgnoredUsersTask @Inject constructor(private val monarchy: Monarchy) : SaveIgnoredUsersTask { + + override suspend fun execute(params: UserAccountDataIgnoredUsers) { + monarchy.awaitTransaction { realm -> + // clear current ignored users + realm.where(IgnoredUserEntity::class.java) + .findAll() + .deleteAllFromRealm() + + params.content.ignoredUsers.keys.forEach { realm.createObject(IgnoredUserEntity::class.java, it) } + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt new file mode 100644 index 0000000000..45dd4745d3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt @@ -0,0 +1,64 @@ +/* + * 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.matrix.android.internal.session.user.accountdata + +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.internal.database.model.IgnoredUserEntity +import im.vector.matrix.android.internal.di.UserId +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers +import im.vector.matrix.android.internal.task.Task +import javax.inject.Inject + +internal interface UpdateIgnoredUserIdsTask : Task { + + data class Params( + val userIdsToIgnore: List = emptyList(), + val userIdsToUnIgnore: List = emptyList() + ) + +} + +internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(private val accountDataApi: AccountDataAPI, + private val monarchy: Monarchy, + @UserId private val userId: String) : UpdateIgnoredUserIdsTask { + + override suspend fun execute(params: UpdateIgnoredUserIdsTask.Params) { + // Get current list + val ignoredUserIds = monarchy.fetchAllMappedSync( + { realm -> realm.where(IgnoredUserEntity::class.java) }, + { it.userId } + ) + + val original = ignoredUserIds.toList() + + ignoredUserIds -= params.userIdsToUnIgnore + ignoredUserIds += params.userIdsToIgnore + + if (original == ignoredUserIds) { + // No change + return + } + + val body = UserAccountDataIgnoredUsers.createWithUserIds(ignoredUserIds) + + return executeRequest { + apiCall = accountDataApi.setAccountData(userId, UserAccountData.TYPE_IGNORED_USER_LIST, body) + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index 1327ca7410..9fa71005ff 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -29,6 +29,7 @@ internal interface UpdateUserAccountDataTask : Task> ) : Params { From 9c952b6bc824b600ec916efd95be8b82ce52070b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 15:12:23 +0100 Subject: [PATCH 071/117] Display ignored users list --- .../sync/UserAccountDataSyncHandler.kt | 4 +- .../model/accountdata/IgnoredUsersContent.kt | 12 +- .../UserAccountDataIgnoredUsers.kt | 17 +-- .../user/accountdata/SaveIgnoredUsersTask.kt | 13 +- .../accountdata/UpdateIgnoredUserIdsTask.kt | 17 ++- .../riotx/core/platform/VectorViewModel.kt | 9 ++ .../features/settings/VectorPreferences.kt | 6 +- .../VectorSettingsIgnoredUsersFragment.kt | 121 ------------------ .../settings/ignored/IgnoredUserItem.kt | 47 +++++++ .../ignored/IgnoredUsersController.kt | 64 +++++++++ .../settings/ignored/IgnoredUsersViewModel.kt | 103 +++++++++++++++ .../VectorSettingsIgnoredUsersFragment.kt | 98 ++++++++++++++ .../fragment_generic_recycler_epoxy.xml | 18 ++- .../src/main/res/layout/item_ignored_user.xml | 21 +++ .../res/layout/merge_overlay_waiting_view.xml | 3 +- vector/src/main/res/values/strings_riotX.xml | 2 + .../res/xml/vector_settings_ignored_users.xml | 13 -- .../src/main/res/xml/vector_settings_root.xml | 3 +- 18 files changed, 394 insertions(+), 177 deletions(-) delete mode 100644 vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsIgnoredUsersFragment.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersViewModel.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt create mode 100644 vector/src/main/res/layout/item_ignored_user.xml delete mode 100644 vector/src/main/res/xml/vector_settings_ignored_users.xml diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt index 07bf965ae1..56bc005805 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/UserAccountDataSyncHandler.kt @@ -125,7 +125,9 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc } private fun handleIgnoredUsers(userAccountDataIgnoredUsers: UserAccountDataIgnoredUsers) { - saveIgnoredUsersTask.configureWith(userAccountDataIgnoredUsers).executeBy(taskExecutor) + saveIgnoredUsersTask + .configureWith(SaveIgnoredUsersTask.Params(userAccountDataIgnoredUsers.content.ignoredUsers.keys.toList())) + .executeBy(taskExecutor) // TODO If not initial sync, we should execute a init sync } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt index c61c122ffe..ea591d79b0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/IgnoredUsersContent.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.util.JsonDict +import im.vector.matrix.android.api.util.emptyJsonDict @JsonClass(generateAdapter = true) internal data class IgnoredUsersContent( @@ -26,4 +27,13 @@ internal data class IgnoredUsersContent( * Required. The map of users to ignore. UserId -> empty object for future enhancement */ @Json(name = "ignored_users") val ignoredUsers: Map -) +) { + + companion object { + fun createWithUserIds(userIds: List): IgnoredUsersContent { + return IgnoredUsersContent( + ignoredUsers = userIds.associateWith { emptyJsonDict } + ) + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt index f6d60b278b..63a7604305 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIgnoredUsers.kt @@ -18,24 +18,9 @@ package im.vector.matrix.android.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.util.emptyJsonDict @JsonClass(generateAdapter = true) internal data class UserAccountDataIgnoredUsers( @Json(name = "type") override val type: String = TYPE_IGNORED_USER_LIST, @Json(name = "content") val content: IgnoredUsersContent -) : UserAccountData() { - - - companion object { - fun createWithUserIds(userIds: List): UserAccountDataIgnoredUsers { - return UserAccountDataIgnoredUsers( - content = IgnoredUsersContent( - ignoredUsers = userIds.associateWith { emptyJsonDict } - ) - ) - } - } -} - - +) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt index ef3a5d0e76..c9a3eef440 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/SaveIgnoredUsersTask.kt @@ -16,9 +16,7 @@ package im.vector.matrix.android.internal.session.user.accountdata import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse import im.vector.matrix.android.internal.database.model.IgnoredUserEntity -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.util.awaitTransaction import javax.inject.Inject @@ -26,20 +24,23 @@ import javax.inject.Inject /** * Save the ignored users list in DB */ -internal interface SaveIgnoredUsersTask : Task { - data class Params(val pa: GetPushRulesResponse) +internal interface SaveIgnoredUsersTask : Task { + data class Params( + val userIds: List + ) } internal class DefaultSaveIgnoredUsersTask @Inject constructor(private val monarchy: Monarchy) : SaveIgnoredUsersTask { - override suspend fun execute(params: UserAccountDataIgnoredUsers) { + override suspend fun execute(params: SaveIgnoredUsersTask.Params) { monarchy.awaitTransaction { realm -> // clear current ignored users realm.where(IgnoredUserEntity::class.java) .findAll() .deleteAllFromRealm() - params.content.ignoredUsers.keys.forEach { realm.createObject(IgnoredUserEntity::class.java, it) } + // And save the new received list + params.userIds.forEach { realm.createObject(IgnoredUserEntity::class.java).apply { userId = it } } } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt index 45dd4745d3..d098f2620f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt @@ -20,8 +20,8 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.internal.database.model.IgnoredUserEntity import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.sync.model.accountdata.IgnoredUsersContent import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData -import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers import im.vector.matrix.android.internal.task.Task import javax.inject.Inject @@ -36,6 +36,7 @@ internal interface UpdateIgnoredUserIdsTask : Task realm.where(IgnoredUserEntity::class.java) }, { it.userId } - ) + ).toMutableSet() val original = ignoredUserIds.toList() - ignoredUserIds -= params.userIdsToUnIgnore - ignoredUserIds += params.userIdsToIgnore + ignoredUserIds.removeAll { it in params.userIdsToUnIgnore } + ignoredUserIds.addAll(params.userIdsToIgnore) if (original == ignoredUserIds) { // No change return } - val body = UserAccountDataIgnoredUsers.createWithUserIds(ignoredUserIds) + val list = ignoredUserIds.toList() + val body = IgnoredUsersContent.createWithUserIds(list) - return executeRequest { + executeRequest { apiCall = accountDataApi.setAccountData(userId, UserAccountData.TYPE_IGNORED_USER_LIST, body) } + + // Update the DB right now (do not wait for the sync to come back with updated data, for a faster UI update) + saveIgnoredUsersTask.execute(SaveIgnoredUsersTask.Params(list)) } } 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 9679c20efb..0e13ec12bd 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 @@ -16,13 +16,22 @@ package im.vector.riotx.core.platform +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import com.airbnb.mvrx.* +import im.vector.riotx.core.utils.LiveEvent import io.reactivex.Observable import io.reactivex.Single abstract class VectorViewModel(initialState: S) : BaseMvRxViewModel(initialState, false) { + // Generic handling of any request error + protected val _requestErrorLiveData = MutableLiveData>() + val requestErrorLiveData: LiveData> + get() = _requestErrorLiveData + + /** * This method does the same thing as the execute function, but it doesn't subscribe to the stream * so you can use this in a switchMap or a flatMap diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt index a593bb6e96..78f57dd548 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt @@ -55,8 +55,6 @@ class VectorPreferences @Inject constructor(private val context: Context) { const val SETTINGS_CONTACT_PREFERENCE_KEYS = "SETTINGS_CONTACT_PREFERENCE_KEYS" const val SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY = "SETTINGS_NOTIFICATIONS_TARGETS_PREFERENCE_KEY" const val SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY = "SETTINGS_NOTIFICATIONS_TARGET_DIVIDER_PREFERENCE_KEY" - const val SETTINGS_IGNORED_USERS_PREFERENCE_KEY = "SETTINGS_IGNORED_USERS_PREFERENCE_KEY" - const val SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY = "SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY" const val SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY = "SETTINGS_BACKGROUND_SYNC_PREFERENCE_KEY" const val SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY = "SETTINGS_BACKGROUND_SYNC_DIVIDER_PREFERENCE_KEY" const val SETTINGS_LABS_PREFERENCE_KEY = "SETTINGS_LABS_PREFERENCE_KEY" @@ -544,7 +542,7 @@ class VectorPreferences @Inject constructor(private val context: Context) { MEDIA_SAVING_1_WEEK -> System.currentTimeMillis() / 1000 - 7 * 24 * 60 * 60 MEDIA_SAVING_1_MONTH -> System.currentTimeMillis() / 1000 - 30 * 24 * 60 * 60 MEDIA_SAVING_FOREVER -> 0 - else -> 0 + else -> 0 } } @@ -559,7 +557,7 @@ class VectorPreferences @Inject constructor(private val context: Context) { MEDIA_SAVING_1_WEEK -> context.getString(R.string.media_saving_period_1_week) MEDIA_SAVING_1_MONTH -> context.getString(R.string.media_saving_period_1_month) MEDIA_SAVING_FOREVER -> context.getString(R.string.media_saving_period_forever) - else -> "?" + else -> "?" } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsIgnoredUsersFragment.kt deleted file mode 100644 index 32a6fe8f41..0000000000 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsIgnoredUsersFragment.kt +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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.settings - -import androidx.appcompat.app.AlertDialog -import androidx.preference.Preference -import androidx.preference.PreferenceCategory -import im.vector.riotx.R -import im.vector.riotx.core.preference.VectorPreference -import java.util.ArrayList -import kotlin.Comparator - -class VectorSettingsIgnoredUsersFragment : VectorSettingsBaseFragment() { - - override var titleRes = R.string.settings_ignored_users - override val preferenceXmlRes = R.xml.vector_settings_ignored_users - - // displayed the ignored users list - private val mIgnoredUserSettingsCategoryDivider by lazy { - findPreference(VectorPreferences.SETTINGS_IGNORE_USERS_DIVIDER_PREFERENCE_KEY)!! - } - private val mIgnoredUserSettingsCategory by lazy { - findPreference(VectorPreferences.SETTINGS_IGNORED_USERS_PREFERENCE_KEY)!! - } - - override fun bindPref() { - // Ignore users - refreshIgnoredUsersList() - } - - // ============================================================================================================== - // ignored users list management - // ============================================================================================================== - - /** - * Refresh the ignored users list - */ - private fun refreshIgnoredUsersList() { - val ignoredUsersList = mutableListOf() // TODO session.dataHandler.ignoredUserIds - - ignoredUsersList.sortWith(Comparator { u1, u2 -> - u1.toLowerCase(VectorLocale.applicationLocale).compareTo(u2.toLowerCase(VectorLocale.applicationLocale)) - }) - - val preferenceScreen = preferenceScreen - - preferenceScreen.removePreference(mIgnoredUserSettingsCategory) - preferenceScreen.removePreference(mIgnoredUserSettingsCategoryDivider) - mIgnoredUserSettingsCategory.removeAll() - - if (ignoredUsersList.size > 0) { - preferenceScreen.addPreference(mIgnoredUserSettingsCategoryDivider) - preferenceScreen.addPreference(mIgnoredUserSettingsCategory) - - for (userId in ignoredUsersList) { - val preference = Preference(activity) - - preference.title = userId - preference.key = IGNORED_USER_KEY_BASE + userId - - preference.onPreferenceClickListener = Preference.OnPreferenceClickListener { - activity?.let { - AlertDialog.Builder(it) - .setMessage(getString(R.string.settings_unignore_user, userId)) - .setPositiveButton(R.string.yes) { _, _ -> - displayLoadingView() - - val idsList = ArrayList() - idsList.add(userId) - - notImplemented() - /* TODO - session.unIgnoreUsers(idsList, object : MatrixCallback { - override fun onSuccess(info: Void?) { - onCommonDone(null) - } - - override fun onNetworkError(e: Exception) { - onCommonDone(e.localizedMessage) - } - - override fun onMatrixError(e: MatrixError) { - onCommonDone(e.localizedMessage) - } - - override fun onUnexpectedError(e: Exception) { - onCommonDone(e.localizedMessage) - } - }) - */ - } - .setNegativeButton(R.string.no, null) - .show() - } - - false - } - - mIgnoredUserSettingsCategory.addPreference(preference) - } - } - } - - companion object { - private const val IGNORED_USER_KEY_BASE = "IGNORED_USER_KEY_BASE" - } -} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt new file mode 100644 index 0000000000..2ce7df1dc4 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt @@ -0,0 +1,47 @@ +/* + * 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.settings.ignored + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.VectorEpoxyHolder +import im.vector.riotx.core.epoxy.VectorEpoxyModel +import im.vector.riotx.core.extensions.setTextOrHide + +/** + * A list item for ignored user. + */ +@EpoxyModelClass(layout = R.layout.item_ignored_user) +abstract class IgnoredUserItem : VectorEpoxyModel() { + + @EpoxyAttribute + var userId: String? = null + + @EpoxyAttribute + var itemClickAction: (() -> Unit)? = null + + override fun bind(holder: Holder) { + holder.userIdText.setTextOrHide(userId) + + holder.userIdText.setOnClickListener { itemClickAction?.invoke() } + } + + class Holder : VectorEpoxyHolder() { + val userIdText by bind(R.id.itemIgnoredUserId) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt new file mode 100644 index 0000000000..845f9bfb73 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt @@ -0,0 +1,64 @@ +/* + * 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.settings.ignored + +import com.airbnb.epoxy.EpoxyController +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.noResultItem +import im.vector.riotx.core.resources.StringProvider +import javax.inject.Inject + +class IgnoredUsersController @Inject constructor(private val stringProvider: StringProvider) : EpoxyController() { + + var callback: Callback? = null + private var viewState: IgnoredUsersViewState? = null + + init { + requestModelBuild() + } + + fun update(viewState: IgnoredUsersViewState) { + this.viewState = viewState + requestModelBuild() + } + + override fun buildModels() { + val nonNullViewState = viewState ?: return + buildIgnoredUserModels(nonNullViewState.ignoredUserIds) + } + + private fun buildIgnoredUserModels(userIds: List) { + if (userIds.isEmpty()) { + noResultItem { + id("empty") + text(stringProvider.getString(R.string.no_ignored_users)) + } + } else { + userIds.forEach { userId -> + ignoredUserItem { + id(userId) + userId(userId) + itemClickAction { callback?.onUserIdClicked(userId) } + } + } + } + } + + interface Callback { + fun onUserIdClicked(userId: String) + } +} 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 new file mode 100644 index 0000000000..fae596032e --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersViewModel.kt @@ -0,0 +1,103 @@ +/* + * 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.settings.ignored + +import com.airbnb.mvrx.* +import com.squareup.inject.assisted.Assisted +import com.squareup.inject.assisted.AssistedInject +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.Session +import im.vector.matrix.rx.rx +import im.vector.riotx.core.extensions.postLiveEvent +import im.vector.riotx.core.platform.VectorViewModel + +data class IgnoredUsersViewState( + val ignoredUserIds: List = emptyList(), + val unIgnoreRequest: Async = Uninitialized +) : MvRxState + + +sealed class IgnoredUsersAction { + data class UnIgnore(val userId: String) : IgnoredUsersAction() +} + +class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: IgnoredUsersViewState, + private val session: Session) : VectorViewModel(initialState) { + + @AssistedInject.Factory + interface Factory { + fun create(initialState: IgnoredUsersViewState): IgnoredUsersViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: IgnoredUsersViewState): IgnoredUsersViewModel? { + val ignoredUsersFragment: VectorSettingsIgnoredUsersFragment = (viewModelContext as FragmentViewModelContext).fragment() + return ignoredUsersFragment.ignoredUsersViewModelFactory.create(state) + } + } + + init { + observeIgnoredUsers() + } + + private fun observeIgnoredUsers() { + session.rx() + .liveIgnoredUserIds() + .execute { async -> + copy( + ignoredUserIds = async.invoke().orEmpty() + ) + } + } + + fun handle(action: IgnoredUsersAction) { + when (action) { + is IgnoredUsersAction.UnIgnore -> handleUnIgnore(action) + } + } + + private fun handleUnIgnore(action: IgnoredUsersAction.UnIgnore) { + setState { + copy( + unIgnoreRequest = Loading() + ) + } + + session.unIgnoreUserIds(listOf(action.userId), object : MatrixCallback { + override fun onFailure(failure: Throwable) { + setState { + copy( + unIgnoreRequest = Fail(failure) + ) + } + + _requestErrorLiveData.postLiveEvent(failure) + } + + override fun onSuccess(data: Unit) { + setState { + copy( + unIgnoreRequest = Success(data) + ) + } + } + }) + } + +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt new file mode 100644 index 0000000000..11e473ae24 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -0,0 +1,98 @@ +/* + * 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.settings.ignored + +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AlertDialog +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 im.vector.riotx.R +import im.vector.riotx.core.error.ErrorFormatter +import im.vector.riotx.core.extensions.observeEvent +import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.core.platform.VectorBaseFragment +import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.* +import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import javax.inject.Inject + +class VectorSettingsIgnoredUsersFragment @Inject constructor( + val ignoredUsersViewModelFactory: IgnoredUsersViewModel.Factory, + private val ignoredUsersController: IgnoredUsersController, + private val errorFormatter: ErrorFormatter +) : VectorBaseFragment(), IgnoredUsersController.Callback { + + override fun getLayoutResId() = R.layout.fragment_generic_recycler_epoxy + + private val ignoredUsersViewModel: IgnoredUsersViewModel by fragmentViewModel() + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + waiting_view_status_text.setText(R.string.please_wait) + waiting_view_status_text.isVisible = true + ignoredUsersController.callback = this + epoxyRecyclerView.setController(ignoredUsersController) + ignoredUsersViewModel.requestErrorLiveData.observeEvent(this) { + displayErrorDialog(it) + } + } + + override fun onResume() { + super.onResume() + + (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_ignored_users) + } + + override fun onUserIdClicked(userId: String) { + AlertDialog.Builder(requireActivity()) + .setMessage(getString(R.string.settings_unignore_user, userId)) + .setPositiveButton(R.string.yes) { _, _ -> + ignoredUsersViewModel.handle(IgnoredUsersAction.UnIgnore(userId)) + } + .setNegativeButton(R.string.no, null) + .show() + } + + private fun displayErrorDialog(throwable: Throwable) { + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.dialog_title_error) + .setMessage(errorFormatter.toHumanReadable(throwable)) + .setPositiveButton(R.string.ok, null) + .show() + } + + // ============================================================================================================== + // ignored users list management + // ============================================================================================================== + + override fun invalidate() = withState(ignoredUsersViewModel) { state -> + ignoredUsersController.update(state) + + handleUnIgnoreRequestStatus(state.unIgnoreRequest) + } + + private fun handleUnIgnoreRequestStatus(unIgnoreRequest: Async) { + when (unIgnoreRequest) { + is Loading -> waiting_view.isVisible = true + else -> waiting_view.isVisible = false + } + } +} diff --git a/vector/src/main/res/layout/fragment_generic_recycler_epoxy.xml b/vector/src/main/res/layout/fragment_generic_recycler_epoxy.xml index c794e8a5fa..3f02081b16 100644 --- a/vector/src/main/res/layout/fragment_generic_recycler_epoxy.xml +++ b/vector/src/main/res/layout/fragment_generic_recycler_epoxy.xml @@ -1,9 +1,17 @@ - + android:layout_height="match_parent"> + + + + + + diff --git a/vector/src/main/res/layout/item_ignored_user.xml b/vector/src/main/res/layout/item_ignored_user.xml new file mode 100644 index 0000000000..7003bb30ae --- /dev/null +++ b/vector/src/main/res/layout/item_ignored_user.xml @@ -0,0 +1,21 @@ + + + diff --git a/vector/src/main/res/layout/merge_overlay_waiting_view.xml b/vector/src/main/res/layout/merge_overlay_waiting_view.xml index 8f09ed0988..b7e7bf41c7 100644 --- a/vector/src/main/res/layout/merge_overlay_waiting_view.xml +++ b/vector/src/main/res/layout/merge_overlay_waiting_view.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> + android:layout_height="match_parent"> "%1$s made no changes" + You are not ignoring any users + diff --git a/vector/src/main/res/xml/vector_settings_ignored_users.xml b/vector/src/main/res/xml/vector_settings_ignored_users.xml deleted file mode 100644 index 4ad8aed5b6..0000000000 --- a/vector/src/main/res/xml/vector_settings_ignored_users.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_root.xml b/vector/src/main/res/xml/vector_settings_root.xml index e0cb4f778b..894784767a 100644 --- a/vector/src/main/res/xml/vector_settings_root.xml +++ b/vector/src/main/res/xml/vector_settings_root.xml @@ -37,10 +37,9 @@ + app:fragment="im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment" /> Date: Tue, 5 Nov 2019 16:13:46 +0100 Subject: [PATCH 072/117] Changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 093d2c0b86..f7b8847bbd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ Changes in RiotX 0.8.0 (2019-XX-XX) =================================================== Features ✨: - - + - Ignore/UnIgnore users, and display list of ignored users (#542, #617) Improvements 🙌: - Search reaction by name or keyword in emoji picker From d9f15c1d215fe42237c7aee3f988dfaed3f0a4cc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 16:32:43 +0100 Subject: [PATCH 073/117] Block user possibility after reporting event content --- .../home/room/detail/RoomDetailActions.kt | 9 ++++++++- .../home/room/detail/RoomDetailFragment.kt | 12 ++++++------ .../home/room/detail/RoomDetailViewModel.kt | 18 ++++++++++++++++++ .../action/MessageActionsEpoxyController.kt | 6 +++--- .../timeline/action/MessageActionsViewModel.kt | 2 +- .../detail/timeline/action/SimpleAction.kt | 8 ++++---- 6 files changed, 40 insertions(+), 15 deletions(-) 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 a219d25c09..9169183da1 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 @@ -50,7 +50,14 @@ sealed class RoomDetailActions { data class ResendMessage(val eventId: String) : RoomDetailActions() data class RemoveFailedEcho(val eventId: String) : RoomDetailActions() - data class ReportContent(val eventId: String, val reason: String, val spam: Boolean = false, val inappropriate: Boolean = false) : RoomDetailActions() + data class ReportContent( + val eventId: String, + val senderId: String?, + val reason: String, + val spam: Boolean = false, + val inappropriate: Boolean = false) : RoomDetailActions() + + data class IgnoreUser(val userId: String?) : RoomDetailActions() object ClearSendQueue : RoomDetailActions() object ResendAll : 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 667fa9784b..77fb382b9b 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 @@ -757,7 +757,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, reason)) + roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, reason)) } .setNegativeButton(R.string.cancel, null) .show() @@ -781,7 +781,7 @@ class RoomDetailFragment @Inject constructor( .setTitle(R.string.content_reported_as_spam_title) .setMessage(R.string.content_reported_as_spam_content) .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.block_user) { _, _ -> vectorBaseActivity.notImplemented("block user") } + .setNegativeButton(R.string.block_user) { _, _ -> roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) } @@ -790,7 +790,7 @@ class RoomDetailFragment @Inject constructor( .setTitle(R.string.content_reported_as_inappropriate_title) .setMessage(R.string.content_reported_as_inappropriate_content) .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.block_user) { _, _ -> vectorBaseActivity.notImplemented("block user") } + .setNegativeButton(R.string.block_user) { _, _ -> roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) } @@ -799,7 +799,7 @@ class RoomDetailFragment @Inject constructor( .setTitle(R.string.content_reported_title) .setMessage(R.string.content_reported_content) .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.block_user) { _, _ -> vectorBaseActivity.notImplemented("block user") } + .setNegativeButton(R.string.block_user) { _, _ -> roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) } @@ -1124,10 +1124,10 @@ class RoomDetailFragment @Inject constructor( roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId)) } is SimpleAction.ReportContentSpam -> { - roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, "This message is spam", spam = true)) + roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, "This message is spam", spam = true)) } is SimpleAction.ReportContentInappropriate -> { - roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, "This message is inappropriate", inappropriate = true)) + roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) } is SimpleAction.ReportContentCustom -> { promptReasonToReportContent(action) 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 2436b7a8b4..d180be5298 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 @@ -157,6 +157,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro is RoomDetailActions.SetReadMarkerAction -> handleSetReadMarkerAction(action) is RoomDetailActions.MarkAllAsRead -> handleMarkAllAsRead() is RoomDetailActions.ReportContent -> handleReportContent(action) + is RoomDetailActions.IgnoreUser -> handleIgnoreUser(action) } } @@ -710,6 +711,23 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro }) } + private fun handleIgnoreUser(action: RoomDetailActions.IgnoreUser) { + if (action.userId.isNullOrEmpty()) { + return + } + + session.ignoreUserIds(listOf(action.userId), object : MatrixCallback { + override fun onSuccess(data: Unit) { + _requestLiveData.postValue(LiveEvent(Success(action))) + } + + override fun onFailure(failure: Throwable) { + _requestLiveData.postValue(LiveEvent(Fail(failure))) + } + }) + } + + private fun observeSyncState() { session.rx() .liveSyncState() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index d9119f08b3..cea693c172 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -102,9 +102,9 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid if (action is SimpleAction.ReportContent && state.expendedReportContentMenu) { // Special case for report content menu: add the submenu listOf( - SimpleAction.ReportContentSpam(action.eventId), - SimpleAction.ReportContentInappropriate(action.eventId), - SimpleAction.ReportContentCustom(action.eventId) + SimpleAction.ReportContentSpam(action.eventId, action.senderId), + SimpleAction.ReportContentInappropriate(action.eventId, action.senderId), + SimpleAction.ReportContentCustom(action.eventId, action.senderId) ).forEachIndexed { indexReport, actionReport -> bottomSheetItemAction { id("actionReport_$indexReport") 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 63a4919763..63429e5def 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 @@ -263,7 +263,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted if (session.myUserId != event.root.senderId && event.root.getClearType() == EventType.MESSAGE) { // not sent by me - add(SimpleAction.ReportContent(eventId)) + add(SimpleAction.ReportContent(eventId, event.root.senderId)) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt index 5da589d862..fbb004c980 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt @@ -35,10 +35,10 @@ sealed class SimpleAction(@StringRes val titleRes: Int, @DrawableRes val iconRes data class ViewSource(val content: String) : SimpleAction(R.string.view_source, R.drawable.ic_view_source) data class ViewDecryptedSource(val content: String) : SimpleAction(R.string.view_decrypted_source, R.drawable.ic_view_source) data class CopyPermalink(val eventId: String) : SimpleAction(R.string.permalink, R.drawable.ic_permalink) - data class ReportContent(val eventId: String) : SimpleAction(R.string.report_content, R.drawable.ic_flag) - data class ReportContentSpam(val eventId: String) : SimpleAction(R.string.report_content_spam, R.drawable.ic_report_spam) - data class ReportContentInappropriate(val eventId: String) : SimpleAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) - data class ReportContentCustom(val eventId: String) : SimpleAction(R.string.report_content_custom, R.drawable.ic_report_custom) + data class ReportContent(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content, R.drawable.ic_flag) + data class ReportContentSpam(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content_spam, R.drawable.ic_report_spam) + data class ReportContentInappropriate(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) + data class ReportContentCustom(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content_custom, R.drawable.ic_report_custom) data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : SimpleAction(0, 0) data class ViewReactions(val messageInformationData: MessageInformationData) : SimpleAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) data class ViewEditHistory(val messageInformationData: MessageInformationData) : From 032e1b3d19c7769a214540a0e1e95be4245fd5ad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 16:33:40 +0100 Subject: [PATCH 074/117] ktlint --- .../session/user/accountdata/UpdateIgnoredUserIdsTask.kt | 1 - .../main/java/im/vector/riotx/core/platform/VectorViewModel.kt | 1 - .../riotx/features/home/room/detail/RoomDetailViewModel.kt | 1 - .../riotx/features/settings/ignored/IgnoredUsersViewModel.kt | 2 -- 4 files changed, 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt index d098f2620f..075eeb23d1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt @@ -31,7 +31,6 @@ internal interface UpdateIgnoredUserIdsTask : Task = emptyList(), val userIdsToUnIgnore: List = emptyList() ) - } internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor(private val accountDataApi: AccountDataAPI, 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 0e13ec12bd..ae601bb0f3 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 @@ -31,7 +31,6 @@ abstract class VectorViewModel(initialState: S) val requestErrorLiveData: LiveData> get() = _requestErrorLiveData - /** * This method does the same thing as the execute function, but it doesn't subscribe to the stream * so you can use this in a switchMap or a flatMap 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 d180be5298..4965de4438 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 @@ -727,7 +727,6 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro }) } - private fun observeSyncState() { session.rx() .liveSyncState() 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 fae596032e..ae8060dcd0 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 @@ -30,7 +30,6 @@ data class IgnoredUsersViewState( val unIgnoreRequest: Async = Uninitialized ) : MvRxState - sealed class IgnoredUsersAction { data class UnIgnore(val userId: String) : IgnoredUsersAction() } @@ -99,5 +98,4 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: } }) } - } From a87310ac1545a6233efba61a5897f6eb3c295201 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 17:58:50 +0100 Subject: [PATCH 075/117] update comment --- .../im/vector/matrix/android/api/session/cache/CacheService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt index f1e4ca6c7b..a84e5af48c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/cache/CacheService.kt @@ -19,7 +19,7 @@ package im.vector.matrix.android.api.session.cache import im.vector.matrix.android.api.MatrixCallback /** - * This interface defines a method to sign out. It's implemented at the session level. + * This interface defines a method to clear the cache. It's implemented at the session level. */ interface CacheService { From b6bb71426437ae087207c58d94cfb88669fb3937 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 18:36:40 +0100 Subject: [PATCH 076/117] Display name and avatar of the user --- .../java/im/vector/matrix/rx/RxSession.kt | 4 +- .../android/api/session/user/UserService.kt | 4 +- .../session/user/DefaultUserService.kt | 4 +- .../ignored/IgnoredUsersController.kt | 18 +++--- .../settings/ignored/IgnoredUsersViewModel.kt | 7 ++- .../{IgnoredUserItem.kt => UserItem.kt} | 26 ++++++--- .../src/main/res/layout/item_ignored_user.xml | 21 ------- vector/src/main/res/layout/item_user.xml | 58 +++++++++++++++++++ 8 files changed, 98 insertions(+), 44 deletions(-) rename vector/src/main/java/im/vector/riotx/features/settings/ignored/{IgnoredUserItem.kt => UserItem.kt} (56%) delete mode 100644 vector/src/main/res/layout/item_ignored_user.xml create mode 100644 vector/src/main/res/layout/item_user.xml diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index 1ffb056f55..1572851d3a 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -54,8 +54,8 @@ class RxSession(private val session: Session) { return session.liveUsers().asObservable() } - fun liveIgnoredUserIds(): Observable> { - return session.liveIgnoredUserIds().asObservable() + fun liveIgnoredUsers(): Observable> { + return session.liveIgnoredUsers().asObservable() } fun livePagedUsers(filter: String? = null): Observable> { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt index abc3c9330e..2a93a876f6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt @@ -66,9 +66,9 @@ interface UserService { fun livePagedUsers(filter: String? = null): LiveData> /** - * Get list of ignored users id + * Get list of ignored users */ - fun liveIgnoredUserIds(): LiveData> + fun liveIgnoredUsers(): LiveData> /** * Ignore users diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt index 5e21c58e09..d314c8d108 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt @@ -121,14 +121,14 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona .executeBy(taskExecutor) } - override fun liveIgnoredUserIds(): LiveData> { + override fun liveIgnoredUsers(): LiveData> { return monarchy.findAllMappedWithChanges( { realm -> realm.where(IgnoredUserEntity::class.java) .isNotEmpty(IgnoredUserEntityFields.USER_ID) .sort(IgnoredUserEntityFields.USER_ID) }, - { it.userId } + { getUser(it.userId) ?: User(userId = it.userId) } ) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt index 845f9bfb73..120781874d 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUsersController.kt @@ -17,12 +17,15 @@ package im.vector.riotx.features.settings.ignored import com.airbnb.epoxy.EpoxyController +import im.vector.matrix.android.api.session.user.model.User import im.vector.riotx.R import im.vector.riotx.core.epoxy.noResultItem import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.features.home.AvatarRenderer import javax.inject.Inject -class IgnoredUsersController @Inject constructor(private val stringProvider: StringProvider) : EpoxyController() { +class IgnoredUsersController @Inject constructor(private val stringProvider: StringProvider, + private val avatarRenderer: AvatarRenderer) : EpoxyController() { var callback: Callback? = null private var viewState: IgnoredUsersViewState? = null @@ -38,10 +41,10 @@ class IgnoredUsersController @Inject constructor(private val stringProvider: Str override fun buildModels() { val nonNullViewState = viewState ?: return - buildIgnoredUserModels(nonNullViewState.ignoredUserIds) + buildIgnoredUserModels(nonNullViewState.ignoredUsers) } - private fun buildIgnoredUserModels(userIds: List) { + private fun buildIgnoredUserModels(userIds: List) { if (userIds.isEmpty()) { noResultItem { id("empty") @@ -49,10 +52,11 @@ class IgnoredUsersController @Inject constructor(private val stringProvider: Str } } else { userIds.forEach { userId -> - ignoredUserItem { - id(userId) - userId(userId) - itemClickAction { callback?.onUserIdClicked(userId) } + userItem { + id(userId.userId) + avatarRenderer(avatarRenderer) + user(userId) + itemClickAction { callback?.onUserIdClicked(userId.userId) } } } } 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 ae8060dcd0..a9f142058d 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 @@ -21,12 +21,13 @@ import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.Session +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 data class IgnoredUsersViewState( - val ignoredUserIds: List = emptyList(), + val ignoredUsers: List = emptyList(), val unIgnoreRequest: Async = Uninitialized ) : MvRxState @@ -57,10 +58,10 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: private fun observeIgnoredUsers() { session.rx() - .liveIgnoredUserIds() + .liveIgnoredUsers() .execute { async -> copy( - ignoredUserIds = async.invoke().orEmpty() + ignoredUsers = async.invoke().orEmpty() ) } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/UserItem.kt similarity index 56% rename from vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt rename to vector/src/main/java/im/vector/riotx/features/settings/ignored/UserItem.kt index 2ce7df1dc4..a9c1b98915 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/ignored/IgnoredUserItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/UserItem.kt @@ -15,33 +15,45 @@ */ package im.vector.riotx.features.settings.ignored +import android.view.View +import android.widget.ImageView import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass +import im.vector.matrix.android.api.session.user.model.User import im.vector.riotx.R import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel import im.vector.riotx.core.extensions.setTextOrHide +import im.vector.riotx.features.home.AvatarRenderer /** - * A list item for ignored user. + * A list item for User. */ -@EpoxyModelClass(layout = R.layout.item_ignored_user) -abstract class IgnoredUserItem : VectorEpoxyModel() { +@EpoxyModelClass(layout = R.layout.item_user) +abstract class UserItem : VectorEpoxyModel() { @EpoxyAttribute - var userId: String? = null + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + lateinit var user: User @EpoxyAttribute var itemClickAction: (() -> Unit)? = null override fun bind(holder: Holder) { - holder.userIdText.setTextOrHide(userId) + holder.root.setOnClickListener { itemClickAction?.invoke() } - holder.userIdText.setOnClickListener { itemClickAction?.invoke() } + avatarRenderer.render(user, holder.avatarImage) + holder.userIdText.setTextOrHide(user.userId) + holder.displayNameText.setTextOrHide(user.displayName) } class Holder : VectorEpoxyHolder() { - val userIdText by bind(R.id.itemIgnoredUserId) + val root by bind(R.id.itemUserRoot) + val avatarImage by bind(R.id.itemUserAvatar) + val userIdText by bind(R.id.itemUserId) + val displayNameText by bind(R.id.itemUserName) } } diff --git a/vector/src/main/res/layout/item_ignored_user.xml b/vector/src/main/res/layout/item_ignored_user.xml deleted file mode 100644 index 7003bb30ae..0000000000 --- a/vector/src/main/res/layout/item_ignored_user.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/vector/src/main/res/layout/item_user.xml b/vector/src/main/res/layout/item_user.xml new file mode 100644 index 0000000000..20e339528a --- /dev/null +++ b/vector/src/main/res/layout/item_user.xml @@ -0,0 +1,58 @@ + + + + + + + + + + \ No newline at end of file From d3d7f7cc6143ddbd8b3d14aac535cfb7e32e28d6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Nov 2019 18:47:09 +0100 Subject: [PATCH 077/117] Split long lines --- .../home/room/detail/RoomDetailFragment.kt | 18 +++-- .../detail/timeline/action/SimpleAction.kt | 76 ++++++++++++++----- 2 files changed, 70 insertions(+), 24 deletions(-) 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 77fb382b9b..6d39a0b790 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 @@ -781,7 +781,9 @@ class RoomDetailFragment @Inject constructor( .setTitle(R.string.content_reported_as_spam_title) .setMessage(R.string.content_reported_as_spam_content) .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.block_user) { _, _ -> roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) } + .setNegativeButton(R.string.block_user) { _, _ -> + roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) + } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) } @@ -790,7 +792,9 @@ class RoomDetailFragment @Inject constructor( .setTitle(R.string.content_reported_as_inappropriate_title) .setMessage(R.string.content_reported_as_inappropriate_content) .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.block_user) { _, _ -> roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) } + .setNegativeButton(R.string.block_user) { _, _ -> + roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) + } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) } @@ -799,7 +803,9 @@ class RoomDetailFragment @Inject constructor( .setTitle(R.string.content_reported_title) .setMessage(R.string.content_reported_content) .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.block_user) { _, _ -> roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) } + .setNegativeButton(R.string.block_user) { _, _ -> + roomDetailViewModel.process(RoomDetailActions.IgnoreUser(data.senderId)) + } .show() .withColoredButton(DialogInterface.BUTTON_NEGATIVE) } @@ -1124,10 +1130,12 @@ class RoomDetailFragment @Inject constructor( roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId)) } is SimpleAction.ReportContentSpam -> { - roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, "This message is spam", spam = true)) + roomDetailViewModel.process(RoomDetailActions.ReportContent( + action.eventId, action.senderId, "This message is spam", spam = true)) } is SimpleAction.ReportContentInappropriate -> { - roomDetailViewModel.process(RoomDetailActions.ReportContent(action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) + roomDetailViewModel.process(RoomDetailActions.ReportContent( + action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) } is SimpleAction.ReportContentCustom -> { promptReasonToReportContent(action) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt index fbb004c980..ab2fb8e41e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt @@ -22,25 +22,63 @@ import im.vector.riotx.R import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData sealed class SimpleAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { - data class AddReaction(val eventId: String) : SimpleAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) - data class Copy(val content: String) : SimpleAction(R.string.copy, R.drawable.ic_copy) - data class Edit(val eventId: String) : SimpleAction(R.string.edit, R.drawable.ic_edit) - data class Quote(val eventId: String) : SimpleAction(R.string.quote, R.drawable.ic_quote) - data class Reply(val eventId: String) : SimpleAction(R.string.reply, R.drawable.ic_reply) - data class Share(val imageUrl: String) : SimpleAction(R.string.share, R.drawable.ic_share) - data class Resend(val eventId: String) : SimpleAction(R.string.global_retry, R.drawable.ic_refresh_cw) - data class Remove(val eventId: String) : SimpleAction(R.string.remove, R.drawable.ic_trash) - data class Delete(val eventId: String) : SimpleAction(R.string.delete, R.drawable.ic_delete) - data class Cancel(val eventId: String) : SimpleAction(R.string.cancel, R.drawable.ic_close_round) - data class ViewSource(val content: String) : SimpleAction(R.string.view_source, R.drawable.ic_view_source) - data class ViewDecryptedSource(val content: String) : SimpleAction(R.string.view_decrypted_source, R.drawable.ic_view_source) - data class CopyPermalink(val eventId: String) : SimpleAction(R.string.permalink, R.drawable.ic_permalink) - data class ReportContent(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content, R.drawable.ic_flag) - data class ReportContentSpam(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content_spam, R.drawable.ic_report_spam) - data class ReportContentInappropriate(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) - data class ReportContentCustom(val eventId: String, val senderId: String?) : SimpleAction(R.string.report_content_custom, R.drawable.ic_report_custom) - data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : SimpleAction(0, 0) - data class ViewReactions(val messageInformationData: MessageInformationData) : SimpleAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) + data class AddReaction(val eventId: String) : + SimpleAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) + + data class Copy(val content: String) : + SimpleAction(R.string.copy, R.drawable.ic_copy) + + data class Edit(val eventId: String) : + SimpleAction(R.string.edit, R.drawable.ic_edit) + + data class Quote(val eventId: String) : + SimpleAction(R.string.quote, R.drawable.ic_quote) + + data class Reply(val eventId: String) : + SimpleAction(R.string.reply, R.drawable.ic_reply) + + data class Share(val imageUrl: String) : + SimpleAction(R.string.share, R.drawable.ic_share) + + data class Resend(val eventId: String) : + SimpleAction(R.string.global_retry, R.drawable.ic_refresh_cw) + + data class Remove(val eventId: String) : + SimpleAction(R.string.remove, R.drawable.ic_trash) + + data class Delete(val eventId: String) : + SimpleAction(R.string.delete, R.drawable.ic_delete) + + data class Cancel(val eventId: String) : + SimpleAction(R.string.cancel, R.drawable.ic_close_round) + + data class ViewSource(val content: String) : + SimpleAction(R.string.view_source, R.drawable.ic_view_source) + + data class ViewDecryptedSource(val content: String) : + SimpleAction(R.string.view_decrypted_source, R.drawable.ic_view_source) + + data class CopyPermalink(val eventId: String) : + SimpleAction(R.string.permalink, R.drawable.ic_permalink) + + data class ReportContent(val eventId: String, val senderId: String?) : + SimpleAction(R.string.report_content, R.drawable.ic_flag) + + data class ReportContentSpam(val eventId: String, val senderId: String?) : + SimpleAction(R.string.report_content_spam, R.drawable.ic_report_spam) + + data class ReportContentInappropriate(val eventId: String, val senderId: String?) : + SimpleAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) + + data class ReportContentCustom(val eventId: String, val senderId: String?) : + SimpleAction(R.string.report_content_custom, R.drawable.ic_report_custom) + + data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : + SimpleAction(0, 0) + + data class ViewReactions(val messageInformationData: MessageInformationData) : + SimpleAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) + data class ViewEditHistory(val messageInformationData: MessageInformationData) : SimpleAction(R.string.message_view_edit_history, R.drawable.ic_view_edit_history) } From 10ca5d94ea3cc827f2f261a19bc813dcaab31ca0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 7 Nov 2019 14:25:09 +0100 Subject: [PATCH 078/117] Fix issue after rebase --- .../src/main/java/im/vector/riotx/core/di/FragmentModule.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt index df6d2abf88..6ae4619033 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt @@ -43,6 +43,7 @@ import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment import im.vector.riotx.features.settings.* +import im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment import im.vector.riotx.features.settings.push.PushGatewaysFragment @Module @@ -164,6 +165,11 @@ interface FragmentModule { @FragmentKey(VectorSettingsHelpAboutFragment::class) fun bindVectorSettingsHelpAboutFragment(fragment: VectorSettingsHelpAboutFragment): Fragment + @Binds + @IntoMap + @FragmentKey(VectorSettingsIgnoredUsersFragment::class) + fun bindVectorSettingsIgnoredUsersFragment(fragment: VectorSettingsIgnoredUsersFragment): Fragment + @Binds @IntoMap @FragmentKey(SASVerificationIncomingFragment::class) From 04f72dfcb82586e7c516a540b83b4306ede6fd46 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 7 Nov 2019 15:19:12 +0100 Subject: [PATCH 079/117] Clean code after Benoit's review --- ...bleStore.kt => ActiveSessionDataSource.kt} | 4 +- .../java/im/vector/riotx/AppStateHandler.kt | 16 +++--- .../riotx/core/di/ActiveSessionHolder.kt | 4 +- .../vector/riotx/core/di/VectorComponent.kt | 16 +++--- .../bottomsheet/BottomSheetItemAction.kt | 12 +++- .../core/utils/{RxStore.kt => DataSource.kt} | 16 +++--- .../features/home/HomeDetailViewModel.kt | 6 +- .../features/home/HomeNavigationViewModel.kt | 8 +-- ...ableStore.kt => HomeRoomListDataSource.kt} | 4 +- .../CreateDirectRoomNavigationViewModel.kt | 8 +-- .../features/home/group/GroupListViewModel.kt | 2 +- ...oupStore.kt => SelectedGroupDataSource.kt} | 4 +- .../home/room/detail/RoomDetailFragment.kt | 8 +-- .../action/MessageActionsBottomSheet.kt | 4 +- ...nsStore.kt => MessageActionsDispatcher.kt} | 10 ++-- .../home/room/list/RoomListFragment.kt | 55 +++++++++++++------ .../home/room/list/RoomListViewEvents.kt | 26 +++++++++ .../home/room/list/RoomListViewModel.kt | 46 +++++++--------- .../room/list/RoomListViewModelFactory.kt | 10 ++-- .../room/list/actions/RoomListQuickActions.kt | 18 +----- .../RoomListQuickActionsEpoxyController.kt | 25 ++++----- .../list/actions/RoomListQuickActionsStore.kt | 8 +-- .../RoomDirectoryNavigationViewModel.kt | 8 +-- .../features/share/IncomingShareViewModel.kt | 6 +- ...bleStore.kt => ShareRoomListDataSource.kt} | 4 +- 25 files changed, 180 insertions(+), 148 deletions(-) rename vector/src/main/java/im/vector/riotx/{ActiveSessionObservableStore.kt => ActiveSessionDataSource.kt} (84%) rename vector/src/main/java/im/vector/riotx/core/utils/{RxStore.kt => DataSource.kt} (78%) rename vector/src/main/java/im/vector/riotx/features/home/{HomeRoomListObservableStore.kt => HomeRoomListDataSource.kt} (84%) rename vector/src/main/java/im/vector/riotx/features/home/group/{SelectedGroupStore.kt => SelectedGroupDataSource.kt} (83%) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/{MessageActionsStore.kt => MessageActionsDispatcher.kt} (71%) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewEvents.kt rename vector/src/main/java/im/vector/riotx/features/share/{ShareRoomListObservableStore.kt => ShareRoomListDataSource.kt} (83%) diff --git a/vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt b/vector/src/main/java/im/vector/riotx/ActiveSessionDataSource.kt similarity index 84% rename from vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt rename to vector/src/main/java/im/vector/riotx/ActiveSessionDataSource.kt index cb89497577..4cafdb8d11 100644 --- a/vector/src/main/java/im/vector/riotx/ActiveSessionObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/ActiveSessionDataSource.kt @@ -19,9 +19,9 @@ package im.vector.riotx import arrow.core.Option import im.vector.matrix.android.api.session.Session -import im.vector.riotx.core.utils.BehaviorStore +import im.vector.riotx.core.utils.BehaviorDataSource import javax.inject.Inject import javax.inject.Singleton @Singleton -class ActiveSessionObservableStore @Inject constructor() : BehaviorStore>() +class ActiveSessionDataSource @Inject constructor() : BehaviorDataSource>() diff --git a/vector/src/main/java/im/vector/riotx/AppStateHandler.kt b/vector/src/main/java/im/vector/riotx/AppStateHandler.kt index 76cbb9ef94..7cb51b6373 100644 --- a/vector/src/main/java/im/vector/riotx/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/riotx/AppStateHandler.kt @@ -23,9 +23,9 @@ import arrow.core.Option import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.rx.rx -import im.vector.riotx.features.home.HomeRoomListObservableStore +import im.vector.riotx.features.home.HomeRoomListDataSource import im.vector.riotx.features.home.group.ALL_COMMUNITIES_GROUP_ID -import im.vector.riotx.features.home.group.SelectedGroupStore +import im.vector.riotx.features.home.group.SelectedGroupDataSource import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -41,9 +41,9 @@ import javax.inject.Singleton */ @Singleton class AppStateHandler @Inject constructor( - private val sessionObservableStore: ActiveSessionObservableStore, - private val homeRoomListObservableStore: HomeRoomListObservableStore, - private val selectedGroupStore: SelectedGroupStore) : LifecycleObserver { + private val sessionDataSource: ActiveSessionDataSource, + private val homeRoomListDataSource: HomeRoomListDataSource, + private val selectedGroupDataSource: SelectedGroupDataSource) : LifecycleObserver { private val compositeDisposable = CompositeDisposable() @@ -60,14 +60,14 @@ class AppStateHandler @Inject constructor( private fun observeRoomsAndGroup() { Observable .combineLatest, Option, List>( - sessionObservableStore.observe() + sessionDataSource.observe() .observeOn(AndroidSchedulers.mainThread()) .switchMap { it.orNull()?.rx()?.liveRoomSummaries() ?: Observable.just(emptyList()) } .throttleLast(300, TimeUnit.MILLISECONDS), - selectedGroupStore.observe(), + selectedGroupDataSource.observe(), BiFunction { rooms, selectedGroupOption -> val selectedGroup = selectedGroupOption.orNull() val filteredDirectRooms = rooms @@ -92,7 +92,7 @@ class AppStateHandler @Inject constructor( } ) .subscribe { - homeRoomListObservableStore.post(it) + homeRoomListDataSource.post(it) } .addTo(compositeDisposable) } diff --git a/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt b/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt index da3c041a1c..3eccb668ea 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ActiveSessionHolder.kt @@ -19,7 +19,7 @@ package im.vector.riotx.core.di import arrow.core.Option import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.api.session.Session -import im.vector.riotx.ActiveSessionObservableStore +import im.vector.riotx.ActiveSessionDataSource import im.vector.riotx.features.crypto.keysrequest.KeyRequestHandler import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler import java.util.concurrent.atomic.AtomicReference @@ -28,7 +28,7 @@ import javax.inject.Singleton @Singleton class ActiveSessionHolder @Inject constructor(private val authenticator: Authenticator, - private val sessionObservableStore: ActiveSessionObservableStore, + private val sessionObservableStore: ActiveSessionDataSource, private val keyRequestHandler: KeyRequestHandler, private val incomingVerificationRequestHandler: IncomingVerificationRequestHandler ) { diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt index 2dfbb5f799..d31955ce8e 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt @@ -23,7 +23,7 @@ import dagger.Component import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.api.session.Session -import im.vector.riotx.ActiveSessionObservableStore +import im.vector.riotx.ActiveSessionDataSource import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.EmojiCompatWrapper import im.vector.riotx.VectorApplication @@ -33,8 +33,8 @@ import im.vector.riotx.features.configuration.VectorConfiguration import im.vector.riotx.features.crypto.keysrequest.KeyRequestHandler import im.vector.riotx.features.crypto.verification.IncomingVerificationRequestHandler import im.vector.riotx.features.home.AvatarRenderer -import im.vector.riotx.features.home.HomeRoomListObservableStore -import im.vector.riotx.features.home.group.SelectedGroupStore +import im.vector.riotx.features.home.HomeRoomListDataSource +import im.vector.riotx.features.home.group.SelectedGroupDataSource import im.vector.riotx.features.html.EventHtmlRenderer import im.vector.riotx.features.navigation.Navigator import im.vector.riotx.features.notifications.* @@ -43,7 +43,7 @@ import im.vector.riotx.features.rageshake.VectorFileLogger import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotx.features.session.SessionListener import im.vector.riotx.features.settings.VectorPreferences -import im.vector.riotx.features.share.ShareRoomListObservableStore +import im.vector.riotx.features.share.ShareRoomListDataSource import im.vector.riotx.features.ui.UiStateRepository import javax.inject.Singleton @@ -85,13 +85,13 @@ interface VectorComponent { fun navigator(): Navigator - fun homeRoomListObservableStore(): HomeRoomListObservableStore + fun homeRoomListObservableStore(): HomeRoomListDataSource - fun shareRoomListObservableStore(): ShareRoomListObservableStore + fun shareRoomListObservableStore(): ShareRoomListDataSource - fun selectedGroupStore(): SelectedGroupStore + fun selectedGroupStore(): SelectedGroupDataSource - fun activeSessionObservableStore(): ActiveSessionObservableStore + fun activeSessionObservableStore(): ActiveSessionDataSource fun incomingVerificationRequestHandler(): IncomingVerificationRequestHandler diff --git a/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt index e0299f4e65..483650a434 100644 --- a/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/bottomsheet/BottomSheetItemAction.kt @@ -16,6 +16,7 @@ */ package im.vector.riotx.core.epoxy.bottomsheet +import android.content.res.ColorStateList import android.view.View import android.widget.ImageView import android.widget.TextView @@ -24,6 +25,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isInvisible import androidx.core.view.isVisible +import androidx.core.widget.ImageViewCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R @@ -51,6 +53,8 @@ abstract class BottomSheetItemAction : VectorEpoxyModel { +interface DataSource { fun observe(): Observable +} + +interface MutableDataSource : DataSource { fun post(value: T) } /** - * This store emits the most recent value it has observed and all subsequent observed values to each subscriber. + * This datasource emits the most recent value it has observed and all subsequent observed values to each subscriber. */ -open class BehaviorStore(private val defaultValue: T? = null) : RxStore { +open class BehaviorDataSource(private val defaultValue: T? = null) : MutableDataSource { private val storeRelay = createRelay() @@ -54,9 +54,9 @@ open class BehaviorStore(private val defaultValue: T? = null) : RxStore { } /** - * This store only emits all subsequent observed values to each subscriber. + * This datasource only emits all subsequent observed values to each subscriber. */ -open class PublishStore : RxStore { +open class PublishDataSource : MutableDataSource { private val storeRelay = PublishRelay.create() 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 c4dcd79ea0..585ecf126e 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 @@ -26,7 +26,7 @@ import im.vector.matrix.rx.rx 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.SelectedGroupStore +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 @@ -38,8 +38,8 @@ import io.reactivex.schedulers.Schedulers class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: HomeDetailViewState, private val session: Session, private val uiStateRepository: UiStateRepository, - private val selectedGroupStore: SelectedGroupStore, - private val homeRoomListStore: HomeRoomListObservableStore, + private val selectedGroupStore: SelectedGroupDataSource, + private val homeRoomListStore: HomeRoomListDataSource, private val stringProvider: StringProvider) : VectorViewModel(initialState) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt index 122eee1833..81c340e400 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt @@ -17,8 +17,8 @@ package im.vector.riotx.features.home import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishStore -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.core.utils.MutableDataSource -class HomeNavigationViewModel(private val store: RxStore = PublishStore()) - : ViewModel(), RxStore by store +class HomeNavigationViewModel(private val source: MutableDataSource = PublishDataSource()) + : ViewModel(), MutableDataSource by source diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListDataSource.kt similarity index 84% rename from vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt rename to vector/src/main/java/im/vector/riotx/features/home/HomeRoomListDataSource.kt index 6b43af4bfc..c27a58d177 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeRoomListDataSource.kt @@ -17,9 +17,9 @@ package im.vector.riotx.features.home import im.vector.matrix.android.api.session.room.model.RoomSummary -import im.vector.riotx.core.utils.BehaviorStore +import im.vector.riotx.core.utils.BehaviorDataSource import javax.inject.Inject import javax.inject.Singleton @Singleton -class HomeRoomListObservableStore @Inject constructor() : BehaviorStore>() +class HomeRoomListDataSource @Inject constructor() : BehaviorDataSource>() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt index d120c306fb..5a84cf4258 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt @@ -17,8 +17,8 @@ package im.vector.riotx.features.home.createdirect import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishStore -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.core.utils.MutableDataSource -class CreateDirectRoomNavigationViewModel(private val store: RxStore = PublishStore()) - : ViewModel(), RxStore by store +class CreateDirectRoomNavigationViewModel(private val dataSource: MutableDataSource = PublishDataSource()) + : ViewModel(), MutableDataSource by dataSource 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 ed547026ee..ac12113d66 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 @@ -39,7 +39,7 @@ import io.reactivex.functions.BiFunction const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID" class GroupListViewModel @AssistedInject constructor(@Assisted initialState: GroupListViewState, - private val selectedGroupStore: SelectedGroupStore, + private val selectedGroupStore: SelectedGroupDataSource, private val session: Session, private val stringProvider: StringProvider ) : VectorViewModel(initialState) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt b/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupDataSource.kt similarity index 83% rename from vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt rename to vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupDataSource.kt index a74f24c1d5..c7b36e1e7f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/group/SelectedGroupDataSource.kt @@ -18,9 +18,9 @@ package im.vector.riotx.features.home.group import arrow.core.Option import im.vector.matrix.android.api.session.group.model.GroupSummary -import im.vector.riotx.core.utils.BehaviorStore +import im.vector.riotx.core.utils.BehaviorDataSource import javax.inject.Inject import javax.inject.Singleton @Singleton -class SelectedGroupStore @Inject constructor() : BehaviorStore>(Option.empty()) +class SelectedGroupDataSource @Inject constructor() : BehaviorDataSource>(Option.empty()) 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 4875c87ec0..f2f65e5cf0 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 @@ -99,7 +99,7 @@ import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet -import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsStore +import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsDispatcher import im.vector.riotx.features.home.room.detail.timeline.action.SimpleAction import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.item.* @@ -200,7 +200,7 @@ class RoomDetailFragment : override fun getMenuRes() = R.menu.menu_timeline - private lateinit var messageActionsStore: MessageActionsStore + private lateinit var messageActionsDispatcher: MessageActionsDispatcher private lateinit var layoutManager: LinearLayoutManager private lateinit var attachmentsHelper: AttachmentsHelper private lateinit var keyboardStateUtils: KeyboardStateUtils @@ -217,7 +217,7 @@ class RoomDetailFragment : override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsStore::class.java) + messageActionsDispatcher = ViewModelProviders.of(requireActivity()).get(MessageActionsDispatcher::class.java) attachmentsHelper = AttachmentsHelper.create(this, this).register() keyboardStateUtils = KeyboardStateUtils(requireActivity()) setupToolbar(roomToolbar) @@ -236,7 +236,7 @@ class RoomDetailFragment : val message = requireContext().getString(pair.first, *pair.second.toTypedArray()) showSnackWithMessage(message, Snackbar.LENGTH_LONG) } - messageActionsStore + messageActionsDispatcher .observe() .subscribe { handleActions(it) 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 2f0e3fab65..d0dc3de8f3 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 @@ -47,7 +47,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override val showExpanded = true - private lateinit var messageActionsStore: MessageActionsStore + private lateinit var messageActionsStore: MessageActionsDispatcher override fun injectWith(screenComponent: ScreenComponent) { screenComponent.inject(this) @@ -61,7 +61,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsStore::class.java) + messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsDispatcher::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = messageActionsEpoxyController.adapter // Disable item animation diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt similarity index 71% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsStore.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt index 5c4c6fed80..a11e0c3689 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt @@ -16,12 +16,12 @@ package im.vector.riotx.features.home.room.detail.timeline.action import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishStore -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.core.utils.MutableDataSource /** * Activity shared view model to handle message actions */ -class MessageActionsStore constructor( - private val store: RxStore = PublishStore() -) : ViewModel(), RxStore by store +class MessageActionsDispatcher constructor( + private val dataSource: MutableDataSource = PublishDataSource() +) : ViewModel(), MutableDataSource by dataSource 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 bcd640589c..0ee34f0679 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 @@ -21,6 +21,7 @@ import android.os.Parcelable import android.view.Menu import android.view.MenuItem import androidx.annotation.StringRes +import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProviders @@ -36,8 +37,6 @@ import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer import im.vector.riotx.core.error.ErrorFormatter -import im.vector.riotx.core.extensions.observeEvent -import im.vector.riotx.core.extensions.observeEventFirstThrottle import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment @@ -47,6 +46,7 @@ import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsStore import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData +import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_room_list.* import javax.inject.Inject @@ -115,30 +115,42 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O setupCreateRoomButton() setupRecyclerView() roomListViewModel.subscribe { renderState(it) } - roomListViewModel.openRoomLiveData.observeEventFirstThrottle(this, 800L) { - if (roomListParams.displayMode == DisplayMode.SHARE) { - val sharedData = roomListParams.sharedData ?: return@observeEventFirstThrottle - navigator.openRoomForSharing(requireActivity(), it, sharedData) - } else { - navigator.openRoom(requireActivity(), it) - } - } + + roomListViewModel.viewEvents + .observe() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + when (it) { + is RoomListViewEvents.SelectRoom -> openSelectedRoom(it) + is RoomListViewEvents.Failure -> showError(it) + } + } + .disposeOnDestroy() createChatFabMenu.listener = this - roomListViewModel.invitationAnswerErrorLiveData.observeEvent(this) { throwable -> - vectorBaseActivity.coordinatorLayout?.let { - Snackbar.make(it, errorFormatter.toHumanReadable(throwable), Snackbar.LENGTH_SHORT) - .show() - } - } - quickActionsDispatcher .observe() .subscribe { handleQuickActions(it) } .disposeOnDestroy() } + private fun openSelectedRoom(event: RoomListViewEvents.SelectRoom) { + if (roomListParams.displayMode == DisplayMode.SHARE) { + val sharedData = roomListParams.sharedData ?: return + navigator.openRoomForSharing(requireActivity(), event.roomId, sharedData) + } else { + navigator.openRoom(requireActivity(), event.roomId) + } + } + + private fun showError(event: RoomListViewEvents.Failure) { + vectorBaseActivity.coordinatorLayout?.let { + Snackbar.make(it, errorFormatter.toHumanReadable(event.throwable), Snackbar.LENGTH_SHORT) + .show() + } + } + private fun setupCreateRoomButton() { when (roomListParams.displayMode) { DisplayMode.HOME -> createChatFabMenu.isVisible = true @@ -233,7 +245,14 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O vectorBaseActivity.notImplemented("Opening room settings") } is RoomListQuickActions.Leave -> { - roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) + AlertDialog.Builder(requireContext()) + .setTitle(R.string.room_participants_leave_prompt_title) + .setMessage(R.string.room_participants_leave_prompt_msg) + .setPositiveButton(R.string.leave) { _, _ -> + roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) + } + .setNegativeButton(R.string.cancel, null) + .show() } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewEvents.kt new file mode 100644 index 0000000000..1181236da2 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewEvents.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.home.room.list + +/** + * Transient events for RoomList + */ +sealed class RoomListViewEvents { + data class Failure(val throwable: Throwable) : RoomListViewEvents() + data class SelectRoom(val roomId: String) : RoomListViewEvents() +} 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 31fa9d0309..ae8654d561 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 @@ -16,8 +16,6 @@ package im.vector.riotx.features.home.room.list -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext @@ -26,17 +24,16 @@ 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.RoomSummary import im.vector.matrix.android.api.session.room.model.tag.RoomTag -import im.vector.riotx.core.extensions.postLiveEvent import im.vector.riotx.core.platform.VectorViewModel -import im.vector.riotx.core.utils.LiveEvent -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.DataSource +import im.vector.riotx.core.utils.PublishDataSource import io.reactivex.schedulers.Schedulers import timber.log.Timber import javax.inject.Inject class RoomListViewModel @Inject constructor(initialState: RoomListViewState, private val session: Session, - private val roomSummariesStore: RxStore>, + private val roomSummariesSource: DataSource>, private val alphabeticalRoomComparator: AlphabeticalRoomComparator, private val chronologicalRoomComparator: ChronologicalRoomComparator) : VectorViewModel(initialState) { @@ -57,13 +54,8 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, private val displayMode = initialState.displayMode private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode) - private val _openRoomLiveData = MutableLiveData>() - val openRoomLiveData: LiveData> - get() = _openRoomLiveData - - private val _invitationAnswerErrorLiveData = MutableLiveData>() - val invitationAnswerErrorLiveData: LiveData> - get() = _invitationAnswerErrorLiveData + private val _viewEvents = PublishDataSource() + val viewEvents: DataSource = _viewEvents init { observeRoomSummaries() @@ -85,7 +77,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, // PRIVATE METHODS ***************************************************************************** private fun handleSelectRoom(action: RoomListActions.SelectRoom) { - _openRoomLiveData.postLiveEvent(action.roomSummary.roomId) + _viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary.roomId)) } private fun handleToggleCategory(action: RoomListActions.ToggleCategory) = setState { @@ -101,7 +93,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } private fun observeRoomSummaries() { - roomSummariesStore + roomSummariesSource .observe() .observeOn(Schedulers.computation()) .map { @@ -111,7 +103,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, copy(asyncRooms = asyncRooms) } - roomSummariesStore + roomSummariesSource .observe() .observeOn(Schedulers.computation()) .map { buildRoomSummaries(it) } @@ -144,8 +136,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, override fun onFailure(failure: Throwable) { // Notify the user - _invitationAnswerErrorLiveData.postLiveEvent(failure) - + _viewEvents.post(RoomListViewEvents.Failure(failure)) setState { copy( joiningRoomsIds = joiningRoomsIds - roomId, @@ -182,8 +173,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, override fun onFailure(failure: Throwable) { // Notify the user - _invitationAnswerErrorLiveData.postLiveEvent(failure) - + _viewEvents.post(RoomListViewEvents.Failure(failure)) setState { copy( rejectingRoomsIds = rejectingRoomsIds - roomId, @@ -204,15 +194,19 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } private fun handleChangeNotificationMode(action: RoomListActions.ChangeRoomNotificationState) { - session.getRoom(action.roomId)?.also { - it.setRoomNotificationState(action.notificationState, object : MatrixCallback {}) - } + session.getRoom(action.roomId)?.setRoomNotificationState(action.notificationState, object : MatrixCallback { + override fun onFailure(failure: Throwable) { + _viewEvents.post(RoomListViewEvents.Failure(failure)) + } + }) } private fun handleLeaveRoom(action: RoomListActions.LeaveRoom) { - session.getRoom(action.roomId)?.also { - it.leave(object : MatrixCallback {}) - } + session.getRoom(action.roomId)?.leave(object : MatrixCallback { + override fun onFailure(failure: Throwable) { + _viewEvents.post(RoomListViewEvents.Failure(failure)) + } + }) } private fun buildRoomSummaries(rooms: List): RoomSummaries { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt index 5895aa4e52..897e72d811 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt @@ -17,14 +17,14 @@ package im.vector.riotx.features.home.room.list import im.vector.matrix.android.api.session.Session -import im.vector.riotx.features.home.HomeRoomListObservableStore -import im.vector.riotx.features.share.ShareRoomListObservableStore +import im.vector.riotx.features.home.HomeRoomListDataSource +import im.vector.riotx.features.share.ShareRoomListDataSource import javax.inject.Inject import javax.inject.Provider class RoomListViewModelFactory @Inject constructor(private val session: Provider, - private val homeRoomListObservableStore: Provider, - private val shareRoomListObservableStore: Provider, + private val homeRoomListDataSource: Provider, + private val shareRoomListDataSource: Provider, private val alphabeticalRoomComparator: Provider, private val chronologicalRoomComparator: Provider) : RoomListViewModel.Factory { @@ -32,7 +32,7 @@ class RoomListViewModelFactory @Inject constructor(private val session: Provider return RoomListViewModel( initialState, session.get(), - if (initialState.displayMode == RoomListFragment.DisplayMode.SHARE) shareRoomListObservableStore.get() else homeRoomListObservableStore.get(), + if (initialState.displayMode == RoomListFragment.DisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(), alphabeticalRoomComparator.get(), chronologicalRoomComparator.get()) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt index e89b4ebcd0..86cd9043f3 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt @@ -20,7 +20,7 @@ import androidx.annotation.DrawableRes import androidx.annotation.StringRes import im.vector.riotx.R -sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { +sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) { data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions( R.string.room_list_quick_actions_notifications_all_noisy, @@ -49,19 +49,7 @@ sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val data class Leave(val roomId: String) : RoomListQuickActions( R.string.room_list_quick_actions_leave, - R.drawable.ic_room_actions_leave + R.drawable.ic_room_actions_leave, + true ) - - companion object { - fun all(roomId: String): List { - return listOf( - NotificationsAllNoisy(roomId), - NotificationsAll(roomId), - NotificationsMentionsOnly(roomId), - NotificationsMute(roomId), - Settings(roomId), - Leave(roomId) - ) - } - } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index cc6abc42b1..70d0fc5f76 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -18,22 +18,16 @@ package im.vector.riotx.features.home.room.list.actions import android.view.View import com.airbnb.epoxy.TypedEpoxyController import im.vector.matrix.android.api.session.room.notification.RoomNotificationState -import im.vector.riotx.EmojiCompatFontProvider -import im.vector.riotx.core.date.VectorDateFormatter -import im.vector.riotx.core.epoxy.bottomsheet.BottomSheetItemAction_ +import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemAction import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemRoomPreview import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemSeparator -import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.AvatarRenderer import javax.inject.Inject /** * Epoxy controller for room list actions */ -class RoomListQuickActionsEpoxyController @Inject constructor(private val stringProvider: StringProvider, - private val avatarRenderer: AvatarRenderer, - private val dateFormatter: VectorDateFormatter, - private val fontProvider: EmojiCompatFontProvider) +class RoomListQuickActionsEpoxyController @Inject constructor(private val avatarRenderer: AvatarRenderer) : TypedEpoxyController() { var listener: Listener? = null @@ -78,13 +72,14 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val string is RoomListQuickActions.Settings, is RoomListQuickActions.Leave -> false } - return BottomSheetItemAction_() - .id("action_$index") - .selected(selected) - .iconRes(iconResId) - .textRes(titleRes) - .listener(View.OnClickListener { listener?.didSelectMenuAction(this) }) - .addTo(this@RoomListQuickActionsEpoxyController) + return bottomSheetItemAction { + id("action_$index") + selected(selected) + iconRes(iconResId) + textRes(titleRes) + destructive(this@toBottomSheetItem.destructive) + listener(View.OnClickListener { listener?.didSelectMenuAction(this@toBottomSheetItem) }) + } } interface Listener { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt index ce0479ac92..35fe09dff8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt @@ -17,12 +17,12 @@ package im.vector.riotx.features.home.room.list.actions import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishStore -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.core.utils.MutableDataSource /** * Activity shared view model to handle room list quick actions */ class RoomListQuickActionsStore constructor( - private val store: RxStore = PublishStore() -) : ViewModel(), RxStore by store + private val store: MutableDataSource = PublishDataSource() +) : ViewModel(), MutableDataSource by store diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt index cb26ff0c54..4e4230e07b 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt @@ -17,8 +17,8 @@ package im.vector.riotx.features.roomdirectory import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishStore -import im.vector.riotx.core.utils.RxStore +import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.core.utils.MutableDataSource -class RoomDirectoryNavigationViewModel(private val store: RxStore = PublishStore()) - : ViewModel(), RxStore by store +class RoomDirectoryNavigationViewModel(private val source: MutableDataSource = PublishDataSource()) + : ViewModel(), MutableDataSource by source diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt index 51485ecbf9..9fba8541e3 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt @@ -23,7 +23,7 @@ import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.rx.rx -import im.vector.riotx.ActiveSessionObservableStore +import im.vector.riotx.ActiveSessionDataSource import im.vector.riotx.core.platform.VectorViewModel import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers @@ -35,8 +35,8 @@ data class IncomingShareState(private val dummy: Boolean = false) : MvRxState * View model used to observe the room list and post update to the ShareRoomListObservableStore */ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState: IncomingShareState, - private val sessionObservableStore: ActiveSessionObservableStore, - private val shareRoomListObservableStore: ShareRoomListObservableStore) + private val sessionObservableStore: ActiveSessionDataSource, + private val shareRoomListObservableStore: ShareRoomListDataSource) : VectorViewModel(initialState) { @AssistedInject.Factory diff --git a/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt b/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListDataSource.kt similarity index 83% rename from vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt rename to vector/src/main/java/im/vector/riotx/features/share/ShareRoomListDataSource.kt index 32b0093b8f..b1b4d7b46e 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListObservableStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/ShareRoomListDataSource.kt @@ -17,9 +17,9 @@ package im.vector.riotx.features.share import im.vector.matrix.android.api.session.room.model.RoomSummary -import im.vector.riotx.core.utils.BehaviorStore +import im.vector.riotx.core.utils.BehaviorDataSource import javax.inject.Inject import javax.inject.Singleton @Singleton -class ShareRoomListObservableStore @Inject constructor() : BehaviorStore>() +class ShareRoomListDataSource @Inject constructor() : BehaviorDataSource>() From fa5d44af6515a26a107196e32bbf04b3c86426f6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 11:53:58 +0100 Subject: [PATCH 080/117] Create common parent for Action view model, to handle navigation, action, or other type of event --- .../platform/VectorEventViewModel.kt} | 14 ++++-- .../features/home/HomeActionViewModel.kt | 21 +++++++++ .../riotx/features/home/HomeActivity.kt | 17 +++---- .../riotx/features/home/HomeDetailFragment.kt | 6 +-- ....kt => CreateDirectRoomActionViewModel.kt} | 7 +-- .../createdirect/CreateDirectRoomActivity.kt | 21 ++++----- .../CreateDirectRoomDirectoryUsersFragment.kt | 8 ++-- .../CreateDirectRoomKnownUsersFragment.kt | 6 +-- .../features/home/group/GroupListFragment.kt | 8 ++-- .../home/room/detail/RoomDetailFragment.kt | 44 +++++++++---------- .../{SimpleAction.kt => EventAction.kt} | 43 +++++++++--------- .../action/MessageActionsBottomSheet.kt | 6 +-- .../action/MessageActionsDispatcher.kt | 8 +--- .../action/MessageActionsEpoxyController.kt | 14 +++--- .../action/MessageActionsViewModel.kt | 38 ++++++++-------- .../home/room/list/RoomListFragment.kt | 28 ++++++------ ...QuickActions.kt => RoomListQuickAction.kt} | 15 ++++--- .../RoomListQuickActionsBottomSheet.kt | 4 +- .../RoomListQuickActionsEpoxyController.kt | 28 ++++++------ .../list/actions/RoomListQuickActionsStore.kt | 8 +--- .../roomdirectory/PublicRoomsFragment.kt | 8 ++-- ...del.kt => RoomDirectoryActionViewModel.kt} | 7 +-- .../roomdirectory/RoomDirectoryActivity.kt | 25 ++++++----- .../createroom/CreateRoomActivity.kt | 12 ++--- .../createroom/CreateRoomFragment.kt | 10 ++--- .../picker/RoomDirectoryPickerFragment.kt | 8 ++-- 26 files changed, 216 insertions(+), 198 deletions(-) rename vector/src/main/java/im/vector/riotx/{features/home/HomeNavigationViewModel.kt => core/platform/VectorEventViewModel.kt} (70%) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt rename vector/src/main/java/im/vector/riotx/features/home/createdirect/{CreateDirectRoomNavigationViewModel.kt => CreateDirectRoomActionViewModel.kt} (63%) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/{SimpleAction.kt => EventAction.kt} (56%) rename vector/src/main/java/im/vector/riotx/features/home/room/list/actions/{RoomListQuickActions.kt => RoomListQuickAction.kt} (85%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/{RoomDirectoryNavigationViewModel.kt => RoomDirectoryActionViewModel.kt} (64%) diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt similarity index 70% rename from vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt rename to vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt index 81c340e400..977991cd4a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt @@ -14,11 +14,17 @@ * limitations under the License. */ -package im.vector.riotx.features.home +package im.vector.riotx.core.platform import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishDataSource import im.vector.riotx.core.utils.MutableDataSource +import im.vector.riotx.core.utils.PublishDataSource -class HomeNavigationViewModel(private val source: MutableDataSource = PublishDataSource()) - : ViewModel(), MutableDataSource by source + +interface VectorAction + +/** + * Parent class to handle navigation events, action events, or other any events + */ +open class VectorActionViewModel(private val store: MutableDataSource = PublishDataSource()) + : ViewModel(), MutableDataSource by store diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt new file mode 100644 index 0000000000..250ba8468c --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt @@ -0,0 +1,21 @@ +/* + * 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.VectorActionViewModel + +class HomeActionViewModel : VectorActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index c77e4f9373..459678863e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -33,6 +33,7 @@ import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.hideKeyboard import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.ToolbarConfigurable +import im.vector.riotx.core.platform.VectorAction import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.features.disclaimer.showDisclaimerDialog @@ -48,12 +49,12 @@ import javax.inject.Inject class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { // Supported navigation actions for this Activity - sealed class Navigation { - object OpenDrawer : Navigation() - object OpenGroup : Navigation() + sealed class HomeActivityAction : VectorAction { + object OpenDrawer : HomeActivityAction() + object OpenGroup : HomeActivityAction() } - private lateinit var navigationViewModel: HomeNavigationViewModel + private lateinit var actionViewModel: HomeActionViewModel @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler @@ -75,18 +76,18 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager) - navigationViewModel = ViewModelProviders.of(this).get(HomeNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(this).get(HomeActionViewModel::class.java) drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java) } - navigationViewModel.observe() + actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is Navigation.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) - is Navigation.OpenGroup -> { + is HomeActivityAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) + is HomeActivityAction.OpenGroup -> { drawerLayout.closeDrawer(GravityCompat.START) replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java) } 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 3c2eb1fe39..2daac15b3d 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 @@ -54,7 +54,7 @@ class HomeDetailFragment @Inject constructor( private val unreadCounterBadgeViews = arrayListOf() private val viewModel: HomeDetailViewModel by fragmentViewModel() - private lateinit var navigationViewModel: HomeNavigationViewModel + private lateinit var actionViewModel: HomeActionViewModel override fun getLayoutResId(): Int { return R.layout.fragment_home_detail @@ -63,7 +63,7 @@ class HomeDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - navigationViewModel = ViewModelProviders.of(requireActivity()).get(HomeNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeActionViewModel::class.java) setupBottomNavigationView() setupToolbar() @@ -129,7 +129,7 @@ class HomeDetailFragment @Inject constructor( } groupToolbar.title = "" groupToolbarAvatarImageView.setOnClickListener { - navigationViewModel.post(HomeActivity.Navigation.OpenDrawer) + actionViewModel.post(HomeActivity.HomeActivityAction.OpenDrawer) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt similarity index 63% rename from vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt rename to vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt index 5a84cf4258..beff263ea0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt @@ -16,9 +16,6 @@ package im.vector.riotx.features.home.createdirect -import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishDataSource -import im.vector.riotx.core.utils.MutableDataSource +import im.vector.riotx.core.platform.VectorActionViewModel -class CreateDirectRoomNavigationViewModel(private val dataSource: MutableDataSource = PublishDataSource()) - : ViewModel(), MutableDataSource by dataSource +class CreateDirectRoomActionViewModel : VectorActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index ab7ee0d160..6b5354b2b9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -32,20 +32,21 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.platform.SimpleFragmentActivity +import im.vector.riotx.core.platform.VectorAction import im.vector.riotx.core.platform.WaitingViewData import kotlinx.android.synthetic.main.activity.* import javax.inject.Inject class CreateDirectRoomActivity : SimpleFragmentActivity() { - sealed class Navigation { - object UsersDirectory : Navigation() - object Close : Navigation() - object Previous : Navigation() + sealed class CreateDirectRoomAction : VectorAction { + object OpenUsersDirectory : CreateDirectRoomAction() + object Close : CreateDirectRoomAction() + object GoBack : CreateDirectRoomAction() } private val viewModel: CreateDirectRoomViewModel by viewModel() - lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel + private lateinit var actionViewModel: CreateDirectRoomActionViewModel @Inject lateinit var createDirectRoomViewModelFactory: CreateDirectRoomViewModel.Factory @Inject lateinit var errorFormatter: ErrorFormatter @@ -57,13 +58,13 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) toolbar.visibility = View.GONE - navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) - navigationViewModel.observe() + actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomActionViewModel::class.java) + actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is Navigation.UsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) - Navigation.Close -> finish() - Navigation.Previous -> onBackPressed() + CreateDirectRoomAction.OpenUsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) + CreateDirectRoomAction.Close -> finish() + CreateDirectRoomAction.GoBack -> onBackPressed() } } .disposeOnDestroy() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 10c932342d..915280ae03 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -39,11 +39,11 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private val viewModel: CreateDirectRoomViewModel by activityViewModel() - private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel + private lateinit var actionViewModel: CreateDirectRoomActionViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - navigationViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomActionViewModel::class.java) setupRecyclerView() setupSearchByMatrixIdView() setupCloseView() @@ -70,7 +70,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private fun setupCloseView() { createDirectRoomClose.setOnClickListener { - navigationViewModel.post(CreateDirectRoomActivity.Navigation.Previous) + actionViewModel.post(CreateDirectRoomActivity.CreateDirectRoomAction.GoBack) } } @@ -81,7 +81,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( override fun onItemClick(user: User) { view?.hideKeyboard() viewModel.handle(CreateDirectRoomActions.SelectUser(user)) - navigationViewModel.post(CreateDirectRoomActivity.Navigation.Previous) + actionViewModel.post(CreateDirectRoomActivity.CreateDirectRoomAction.GoBack) } override fun retryDirectoryUsersRequest() { diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 02ca8ba55c..9cadbc230f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -49,11 +49,11 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( override fun getMenuRes() = R.menu.vector_create_direct_room private val viewModel: CreateDirectRoomViewModel by activityViewModel() - private lateinit var navigationViewModel: CreateDirectRoomNavigationViewModel + private lateinit var actionViewModel: CreateDirectRoomActionViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - navigationViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomActionViewModel::class.java) vectorBaseActivity.setSupportActionBar(createDirectRoomToolbar) setupRecyclerView() setupFilterView() @@ -89,7 +89,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( private fun setupAddByMatrixIdView() { addByMatrixId.setOnClickListener { - navigationViewModel.post(CreateDirectRoomActivity.Navigation.UsersDirectory) + actionViewModel.post(CreateDirectRoomActivity.CreateDirectRoomAction.OpenUsersDirectory) } } 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 a1e13e4acd..8666f57338 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 @@ -26,8 +26,8 @@ import im.vector.riotx.R import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.home.HomeActionViewModel import im.vector.riotx.features.home.HomeActivity -import im.vector.riotx.features.home.HomeNavigationViewModel import kotlinx.android.synthetic.main.fragment_group_list.* import javax.inject.Inject @@ -36,20 +36,20 @@ class GroupListFragment @Inject constructor( private val groupController: GroupSummaryController ) : VectorBaseFragment(), GroupSummaryController.Callback { - private lateinit var navigationViewModel: HomeNavigationViewModel + private lateinit var actionViewModel: HomeActionViewModel private val viewModel: GroupListViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_group_list override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - navigationViewModel = ViewModelProviders.of(requireActivity()).get(HomeNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeActionViewModel::class.java) groupController.callback = this stateView.contentView = groupListEpoxyRecyclerView groupListEpoxyRecyclerView.setController(groupController) viewModel.subscribe { renderState(it) } viewModel.openGroupLiveData.observeEvent(this) { - navigationViewModel.post(HomeActivity.Navigation.OpenGroup) + actionViewModel.post(HomeActivity.HomeActivityAction.OpenGroup) } } 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 465e085e3b..83004a35de 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 @@ -99,7 +99,7 @@ import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceipt import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsDispatcher -import im.vector.riotx.features.home.room.detail.timeline.action.SimpleAction +import im.vector.riotx.features.home.room.detail.timeline.action.EventAction import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.item.* import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet @@ -749,7 +749,7 @@ class RoomDetailFragment @Inject constructor( .show() } - private fun promptReasonToReportContent(action: SimpleAction.ReportContentCustom) { + private fun promptReasonToReportContent(action: EventAction.ReportContentCustom) { val inflater = requireActivity().layoutInflater val layout = inflater.inflate(R.layout.dialog_report_content, null) @@ -1037,25 +1037,25 @@ class RoomDetailFragment @Inject constructor( textComposerViewModel.process(TextComposerActions.QueryUsers(query)) } - private fun handleActions(action: SimpleAction) { + private fun handleActions(action: EventAction) { when (action) { - is SimpleAction.AddReaction -> { + is EventAction.AddReaction -> { startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), action.eventId), REACTION_SELECT_REQUEST_CODE) } - is SimpleAction.ViewReactions -> { + is EventAction.ViewReactions -> { ViewReactionsBottomSheet.newInstance(roomDetailArgs.roomId, action.messageInformationData) .show(requireActivity().supportFragmentManager, "DISPLAY_REACTIONS") } - is SimpleAction.Copy -> { + is EventAction.Copy -> { // I need info about the current selected message :/ copyToClipboard(requireContext(), action.content, false) val msg = requireContext().getString(R.string.copied_to_clipboard) showSnackWithMessage(msg, Snackbar.LENGTH_SHORT) } - is SimpleAction.Delete -> { + is EventAction.Delete -> { roomDetailViewModel.process(RoomDetailActions.RedactAction(action.eventId, context?.getString(R.string.event_redacted_by_user_reason))) } - is SimpleAction.Share -> { + is EventAction.Share -> { // TODO current data communication is too limited // Need to now the media type // TODO bad, just POC @@ -1083,10 +1083,10 @@ class RoomDetailFragment @Inject constructor( } ) } - is SimpleAction.ViewEditHistory -> { + is EventAction.ViewEditHistory -> { onEditedDecorationClicked(action.messageInformationData) } - is SimpleAction.ViewSource -> { + is EventAction.ViewSource -> { val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_event_content, null) view.findViewById(R.id.event_content_text_view)?.let { it.text = action.content @@ -1097,7 +1097,7 @@ class RoomDetailFragment @Inject constructor( .setPositiveButton(R.string.ok, null) .show() } - is SimpleAction.ViewDecryptedSource -> { + is EventAction.ViewDecryptedSource -> { val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_event_content, null) view.findViewById(R.id.event_content_text_view)?.let { it.text = action.content @@ -1108,42 +1108,42 @@ class RoomDetailFragment @Inject constructor( .setPositiveButton(R.string.ok, null) .show() } - is SimpleAction.QuickReact -> { + is EventAction.QuickReact -> { // eventId,ClickedOn,Add roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } - is SimpleAction.Edit -> { + is EventAction.Edit -> { roomDetailViewModel.process(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) } - is SimpleAction.Quote -> { + is EventAction.Quote -> { roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) } - is SimpleAction.Reply -> { + is EventAction.Reply -> { roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.composerEditText.text.toString())) } - is SimpleAction.CopyPermalink -> { + is EventAction.CopyPermalink -> { val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) copyToClipboard(requireContext(), permalink, false) showSnackWithMessage(requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) } - is SimpleAction.Resend -> { + is EventAction.Resend -> { roomDetailViewModel.process(RoomDetailActions.ResendMessage(action.eventId)) } - is SimpleAction.Remove -> { + is EventAction.Remove -> { roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId)) } - is SimpleAction.ReportContentSpam -> { + is EventAction.ReportContentSpam -> { roomDetailViewModel.process(RoomDetailActions.ReportContent( action.eventId, action.senderId, "This message is spam", spam = true)) } - is SimpleAction.ReportContentInappropriate -> { + is EventAction.ReportContentInappropriate -> { roomDetailViewModel.process(RoomDetailActions.ReportContent( action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) } - is SimpleAction.ReportContentCustom -> { + is EventAction.ReportContentCustom -> { promptReasonToReportContent(action) } - else -> { + else -> { Toast.makeText(context, "Action $action is not implemented yet", Toast.LENGTH_LONG).show() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventAction.kt similarity index 56% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventAction.kt index ab2fb8e41e..79d615112c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/SimpleAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventAction.kt @@ -19,66 +19,67 @@ package im.vector.riotx.features.home.room.detail.timeline.action import androidx.annotation.DrawableRes import androidx.annotation.StringRes import im.vector.riotx.R +import im.vector.riotx.core.platform.VectorAction import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData -sealed class SimpleAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) { +sealed class EventAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) : VectorAction { data class AddReaction(val eventId: String) : - SimpleAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) + EventAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) data class Copy(val content: String) : - SimpleAction(R.string.copy, R.drawable.ic_copy) + EventAction(R.string.copy, R.drawable.ic_copy) data class Edit(val eventId: String) : - SimpleAction(R.string.edit, R.drawable.ic_edit) + EventAction(R.string.edit, R.drawable.ic_edit) data class Quote(val eventId: String) : - SimpleAction(R.string.quote, R.drawable.ic_quote) + EventAction(R.string.quote, R.drawable.ic_quote) data class Reply(val eventId: String) : - SimpleAction(R.string.reply, R.drawable.ic_reply) + EventAction(R.string.reply, R.drawable.ic_reply) data class Share(val imageUrl: String) : - SimpleAction(R.string.share, R.drawable.ic_share) + EventAction(R.string.share, R.drawable.ic_share) data class Resend(val eventId: String) : - SimpleAction(R.string.global_retry, R.drawable.ic_refresh_cw) + EventAction(R.string.global_retry, R.drawable.ic_refresh_cw) data class Remove(val eventId: String) : - SimpleAction(R.string.remove, R.drawable.ic_trash) + EventAction(R.string.remove, R.drawable.ic_trash) data class Delete(val eventId: String) : - SimpleAction(R.string.delete, R.drawable.ic_delete) + EventAction(R.string.delete, R.drawable.ic_delete) data class Cancel(val eventId: String) : - SimpleAction(R.string.cancel, R.drawable.ic_close_round) + EventAction(R.string.cancel, R.drawable.ic_close_round) data class ViewSource(val content: String) : - SimpleAction(R.string.view_source, R.drawable.ic_view_source) + EventAction(R.string.view_source, R.drawable.ic_view_source) data class ViewDecryptedSource(val content: String) : - SimpleAction(R.string.view_decrypted_source, R.drawable.ic_view_source) + EventAction(R.string.view_decrypted_source, R.drawable.ic_view_source) data class CopyPermalink(val eventId: String) : - SimpleAction(R.string.permalink, R.drawable.ic_permalink) + EventAction(R.string.permalink, R.drawable.ic_permalink) data class ReportContent(val eventId: String, val senderId: String?) : - SimpleAction(R.string.report_content, R.drawable.ic_flag) + EventAction(R.string.report_content, R.drawable.ic_flag) data class ReportContentSpam(val eventId: String, val senderId: String?) : - SimpleAction(R.string.report_content_spam, R.drawable.ic_report_spam) + EventAction(R.string.report_content_spam, R.drawable.ic_report_spam) data class ReportContentInappropriate(val eventId: String, val senderId: String?) : - SimpleAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) + EventAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) data class ReportContentCustom(val eventId: String, val senderId: String?) : - SimpleAction(R.string.report_content_custom, R.drawable.ic_report_custom) + EventAction(R.string.report_content_custom, R.drawable.ic_report_custom) data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : - SimpleAction(0, 0) + EventAction(0, 0) data class ViewReactions(val messageInformationData: MessageInformationData) : - SimpleAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) + EventAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) data class ViewEditHistory(val messageInformationData: MessageInformationData) : - SimpleAction(R.string.message_view_edit_history, R.drawable.ic_view_edit_history) + EventAction(R.string.message_view_edit_history, R.drawable.ic_view_edit_history) } 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 d0dc3de8f3..fa738e5c42 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 @@ -69,12 +69,12 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message messageActionsEpoxyController.listener = this } - override fun didSelectMenuAction(simpleAction: SimpleAction) { - if (simpleAction is SimpleAction.ReportContent) { + override fun didSelectMenuAction(eventAction: EventAction) { + if (eventAction is EventAction.ReportContent) { // Toggle report menu viewModel.toggleReportMenu() } else { - messageActionsStore.post(simpleAction) + messageActionsStore.post(eventAction) dismiss() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt index a11e0c3689..54f9d0d583 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt @@ -15,13 +15,9 @@ */ package im.vector.riotx.features.home.room.detail.timeline.action -import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishDataSource -import im.vector.riotx.core.utils.MutableDataSource +import im.vector.riotx.core.platform.VectorActionViewModel /** * Activity shared view model to handle message actions */ -class MessageActionsDispatcher constructor( - private val dataSource: MutableDataSource = PublishDataSource() -) : ViewModel(), MutableDataSource by dataSource +class MessageActionsDispatcher : VectorActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index b7bf69b7a1..e30a383087 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -84,7 +84,7 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid selecteds(state.quickStates.invoke().map { it.isSelected }) listener(object : BottomSheetItemQuickReactions.Listener { override fun didSelect(emoji: String, selected: Boolean) { - listener?.didSelectMenuAction(SimpleAction.QuickReact(state.eventId, emoji, selected)) + listener?.didSelectMenuAction(EventAction.QuickReact(state.eventId, emoji, selected)) } }) } @@ -101,17 +101,17 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid id("action_$index") iconRes(action.iconResId) textRes(action.titleRes) - showExpand(action is SimpleAction.ReportContent) + showExpand(action is EventAction.ReportContent) expanded(state.expendedReportContentMenu) listener(View.OnClickListener { listener?.didSelectMenuAction(action) }) } - if (action is SimpleAction.ReportContent && state.expendedReportContentMenu) { + if (action is EventAction.ReportContent && state.expendedReportContentMenu) { // Special case for report content menu: add the submenu listOf( - SimpleAction.ReportContentSpam(action.eventId, action.senderId), - SimpleAction.ReportContentInappropriate(action.eventId, action.senderId), - SimpleAction.ReportContentCustom(action.eventId, action.senderId) + EventAction.ReportContentSpam(action.eventId, action.senderId), + EventAction.ReportContentInappropriate(action.eventId, action.senderId), + EventAction.ReportContentCustom(action.eventId, action.senderId) ).forEachIndexed { indexReport, actionReport -> bottomSheetItemAction { id("actionReport_$indexReport") @@ -126,6 +126,6 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid } interface MessageActionsEpoxyControllerListener { - fun didSelectMenuAction(simpleAction: SimpleAction) + fun didSelectMenuAction(eventAction: EventAction) } } 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 63429e5def..92be124940 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 @@ -62,7 +62,7 @@ data class MessageActionState( // For quick reactions val quickStates: Async> = Uninitialized, // For actions - val actions: Async> = Uninitialized, + val actions: Async> = Uninitialized, val expendedReportContentMenu: Boolean = false ) : MvRxState { @@ -184,63 +184,63 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } - private fun actionsForEvent(optionalEvent: Optional): List { + private fun actionsForEvent(optionalEvent: Optional): List { val event = optionalEvent.getOrNull() ?: return emptyList() val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent.toModel() ?: event.root.getClearContent().toModel() val type = messageContent?.type - return arrayListOf().apply { + return arrayListOf().apply { if (event.root.sendState.hasFailed()) { if (canRetry(event)) { - add(SimpleAction.Resend(eventId)) + add(EventAction.Resend(eventId)) } - add(SimpleAction.Remove(eventId)) + add(EventAction.Remove(eventId)) } else if (event.root.sendState.isSending()) { // TODO is uploading attachment? if (canCancel(event)) { - add(SimpleAction.Cancel(eventId)) + add(EventAction.Cancel(eventId)) } } else if (event.root.sendState == SendState.SYNCED) { if (!event.root.isRedacted()) { if (canReply(event, messageContent)) { - add(SimpleAction.Reply(eventId)) + add(EventAction.Reply(eventId)) } if (canEdit(event, session.myUserId)) { - add(SimpleAction.Edit(eventId)) + add(EventAction.Edit(eventId)) } if (canRedact(event, session.myUserId)) { - add(SimpleAction.Delete(eventId)) + add(EventAction.Delete(eventId)) } if (canCopy(type)) { // TODO copy images? html? see ClipBoard - add(SimpleAction.Copy(messageContent!!.body)) + add(EventAction.Copy(messageContent!!.body)) } if (event.canReact()) { - add(SimpleAction.AddReaction(eventId)) + add(EventAction.AddReaction(eventId)) } if (canQuote(event, messageContent)) { - add(SimpleAction.Quote(eventId)) + add(EventAction.Quote(eventId)) } if (canViewReactions(event)) { - add(SimpleAction.ViewReactions(informationData)) + add(EventAction.ViewReactions(informationData)) } if (event.hasBeenEdited()) { - add(SimpleAction.ViewEditHistory(informationData)) + add(EventAction.ViewEditHistory(informationData)) } if (canShare(type)) { if (messageContent is MessageImageContent) { session.contentUrlResolver().resolveFullSize(messageContent.url)?.let { url -> - add(SimpleAction.Share(url)) + add(EventAction.Share(url)) } } // TODO @@ -253,17 +253,17 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } - add(SimpleAction.ViewSource(event.root.toContentStringWithIndent())) + add(EventAction.ViewSource(event.root.toContentStringWithIndent())) if (event.isEncrypted()) { val decryptedContent = event.root.toClearContentStringWithIndent() ?: stringProvider.getString(R.string.encryption_information_decryption_error) - add(SimpleAction.ViewDecryptedSource(decryptedContent)) + add(EventAction.ViewDecryptedSource(decryptedContent)) } - add(SimpleAction.CopyPermalink(eventId)) + add(EventAction.CopyPermalink(eventId)) if (session.myUserId != event.root.senderId && event.root.getClearType() == EventType.MESSAGE) { // not sent by me - add(SimpleAction.ReportContent(eventId, event.root.senderId)) + add(EventAction.ReportContent(eventId, event.root.senderId)) } } } 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 13c6444400..64c8214236 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 @@ -39,7 +39,7 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.home.room.list.actions.RoomListQuickActions +import im.vector.riotx.features.home.room.list.actions.RoomListQuickAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsStore import im.vector.riotx.features.home.room.list.widget.FabMenuView @@ -216,29 +216,29 @@ class RoomListFragment @Inject constructor( } } - private fun handleQuickActions(quickActions: RoomListQuickActions) { - when (quickActions) { - is RoomListQuickActions.NotificationsAllNoisy -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) + private fun handleQuickActions(quickAction: RoomListQuickAction) { + when (quickAction) { + is RoomListQuickAction.NotificationsAllNoisy -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) } - is RoomListQuickActions.NotificationsAll -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.ALL_MESSAGES)) + is RoomListQuickAction.NotificationsAll -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) } - is RoomListQuickActions.NotificationsMentionsOnly -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MENTIONS_ONLY)) + is RoomListQuickAction.NotificationsMentionsOnly -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) } - is RoomListQuickActions.NotificationsMute -> { - roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickActions.roomId, RoomNotificationState.MUTE)) + is RoomListQuickAction.NotificationsMute -> { + roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) } - is RoomListQuickActions.Settings -> { + is RoomListQuickAction.Settings -> { vectorBaseActivity.notImplemented("Opening room settings") } - is RoomListQuickActions.Leave -> { + is RoomListQuickAction.Leave -> { AlertDialog.Builder(requireContext()) .setTitle(R.string.room_participants_leave_prompt_title) .setMessage(R.string.room_participants_leave_prompt_msg) .setPositiveButton(R.string.leave) { _, _ -> - roomListViewModel.accept(RoomListActions.LeaveRoom(quickActions.roomId)) + roomListViewModel.accept(RoomListActions.LeaveRoom(quickAction.roomId)) } .setNegativeButton(R.string.cancel, null) .show() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickAction.kt similarity index 85% rename from vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickAction.kt index 86cd9043f3..c0de0a9d7b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickAction.kt @@ -19,35 +19,36 @@ package im.vector.riotx.features.home.room.list.actions import androidx.annotation.DrawableRes import androidx.annotation.StringRes import im.vector.riotx.R +import im.vector.riotx.core.platform.VectorAction -sealed class RoomListQuickActions(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) { +sealed class RoomListQuickAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) : VectorAction { - data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActions( + data class NotificationsAllNoisy(val roomId: String) : RoomListQuickAction( R.string.room_list_quick_actions_notifications_all_noisy, R.drawable.ic_room_actions_notifications_all_noisy ) - data class NotificationsAll(val roomId: String) : RoomListQuickActions( + data class NotificationsAll(val roomId: String) : RoomListQuickAction( R.string.room_list_quick_actions_notifications_all, R.drawable.ic_room_actions_notifications_all ) - data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActions( + data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickAction( R.string.room_list_quick_actions_notifications_mentions, R.drawable.ic_room_actions_notifications_mentions ) - data class NotificationsMute(val roomId: String) : RoomListQuickActions( + data class NotificationsMute(val roomId: String) : RoomListQuickAction( R.string.room_list_quick_actions_notifications_mute, R.drawable.ic_room_actions_notifications_mutes ) - data class Settings(val roomId: String) : RoomListQuickActions( + data class Settings(val roomId: String) : RoomListQuickAction( R.string.room_list_quick_actions_settings, R.drawable.ic_room_actions_settings ) - data class Leave(val roomId: String) : RoomListQuickActions( + data class Leave(val roomId: String) : RoomListQuickAction( R.string.room_list_quick_actions_leave, R.drawable.ic_room_actions_leave, true diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 560c05771c..03fb5f5a00 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -82,8 +82,8 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R super.invalidate() } - override fun didSelectMenuAction(quickActions: RoomListQuickActions) { - actionsDispatcher.post(quickActions) + override fun didSelectMenuAction(quickAction: RoomListQuickAction) { + actionsDispatcher.post(quickAction) dismiss() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index 70d0fc5f76..16d96e8dba 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -42,7 +42,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar roomName(roomSummary.displayName) avatarUrl(roomSummary.avatarUrl) roomId(roomSummary.roomId) - settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickActions.Settings(roomSummary.roomId)) }) + settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickAction.Settings(roomSummary.roomId)) }) } // Notifications @@ -51,26 +51,26 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar } val selectedRoomState = state.roomNotificationState() - RoomListQuickActions.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) - RoomListQuickActions.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) - RoomListQuickActions.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) - RoomListQuickActions.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) + RoomListQuickAction.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) + RoomListQuickAction.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) + RoomListQuickAction.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) + RoomListQuickAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) // Leave bottomSheetItemSeparator { id("leave_separator") } - RoomListQuickActions.Leave(roomSummary.roomId).toBottomSheetItem(5) + RoomListQuickAction.Leave(roomSummary.roomId).toBottomSheetItem(5) } - private fun RoomListQuickActions.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { + private fun RoomListQuickAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { val selected = when (this) { - is RoomListQuickActions.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY - is RoomListQuickActions.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES - is RoomListQuickActions.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY - is RoomListQuickActions.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE - is RoomListQuickActions.Settings, - is RoomListQuickActions.Leave -> false + is RoomListQuickAction.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY + is RoomListQuickAction.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES + is RoomListQuickAction.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY + is RoomListQuickAction.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE + is RoomListQuickAction.Settings, + is RoomListQuickAction.Leave -> false } return bottomSheetItemAction { id("action_$index") @@ -83,6 +83,6 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar } interface Listener { - fun didSelectMenuAction(quickActions: RoomListQuickActions) + fun didSelectMenuAction(quickAction: RoomListQuickAction) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt index 35fe09dff8..503a3b0327 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt @@ -16,13 +16,9 @@ */ package im.vector.riotx.features.home.room.list.actions -import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishDataSource -import im.vector.riotx.core.utils.MutableDataSource +import im.vector.riotx.core.platform.VectorActionViewModel /** * Activity shared view model to handle room list quick actions */ -class RoomListQuickActionsStore constructor( - private val store: MutableDataSource = PublishDataSource() -) : ViewModel(), MutableDataSource by store +class RoomListQuickActionsStore : VectorActionViewModel() 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 303e931b5c..36c3c13cc3 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 @@ -47,7 +47,7 @@ class PublicRoomsFragment @Inject constructor( ) : VectorBaseFragment(), PublicRoomsController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() - private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel + private lateinit var actionViewModel: RoomDirectoryActionViewModel override fun getLayoutResId() = R.layout.fragment_public_rooms @@ -71,7 +71,7 @@ class PublicRoomsFragment @Inject constructor( .disposeOnDestroy() publicRoomsCreateNewRoom.setOnClickListener { - navigationViewModel.post(RoomDirectoryActivity.Navigation.CreateRoom) + actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.CreateRoom) } viewModel.joinRoomErrorLiveData.observeEvent(this) { throwable -> @@ -83,7 +83,7 @@ class PublicRoomsFragment @Inject constructor( override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_room_directory_change_protocol -> { - navigationViewModel.post(RoomDirectoryActivity.Navigation.ChangeProtocol) + actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.ChangeProtocol) true } else -> @@ -93,7 +93,7 @@ class PublicRoomsFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) setupRecyclerView() } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt similarity index 64% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt index 4e4230e07b..d9e1a4614b 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryNavigationViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt @@ -16,9 +16,6 @@ package im.vector.riotx.features.roomdirectory -import androidx.lifecycle.ViewModel -import im.vector.riotx.core.utils.PublishDataSource -import im.vector.riotx.core.utils.MutableDataSource +import im.vector.riotx.core.platform.VectorActionViewModel -class RoomDirectoryNavigationViewModel(private val source: MutableDataSource = PublishDataSource()) - : ViewModel(), MutableDataSource by source +class RoomDirectoryActionViewModel : VectorActionViewModel() 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 e98c180bc9..84d7b758ab 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 @@ -25,6 +25,7 @@ import im.vector.riotx.R 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.VectorAction import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.createroom.CreateRoomViewModel @@ -34,18 +35,18 @@ import javax.inject.Inject class RoomDirectoryActivity : VectorBaseActivity() { // Supported navigation actions for this Activity - sealed class Navigation { - object Back : Navigation() - object CreateRoom : Navigation() - object Close : Navigation() - object ChangeProtocol : Navigation() + sealed class RoomDirectoryAction : VectorAction { + object Back : RoomDirectoryAction() + object CreateRoom : RoomDirectoryAction() + object Close : RoomDirectoryAction() + object ChangeProtocol : RoomDirectoryAction() } @Inject lateinit var createRoomViewModelFactory: CreateRoomViewModel.Factory @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory private val roomDirectoryViewModel: RoomDirectoryViewModel by viewModel() private val createRoomViewModel: CreateRoomViewModel by viewModel() - private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel + private lateinit var actionViewModel: RoomDirectoryActionViewModel override fun getLayoutRes() = R.layout.activity_simple @@ -55,19 +56,19 @@ class RoomDirectoryActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryActionViewModel::class.java) if (isFirstCreation()) { roomDirectoryViewModel.filterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "") } - navigationViewModel.observe() + actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is Navigation.Back -> onBackPressed() - is Navigation.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) - is Navigation.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) - is Navigation.Close -> finish() + is RoomDirectoryAction.Back -> onBackPressed() + is RoomDirectoryAction.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) + is RoomDirectoryAction.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) + is RoomDirectoryAction.Close -> finish() } } .disposeOnDestroy() 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 6377f05d20..fb982babee 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 @@ -27,7 +27,7 @@ import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity -import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel import javax.inject.Inject /** @@ -38,7 +38,7 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { @Inject lateinit var createRoomViewModelFactory: CreateRoomViewModel.Factory private val createRoomViewModel: CreateRoomViewModel by viewModel() - private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel + private lateinit var actionViewModel: RoomDirectoryActionViewModel override fun getLayoutRes() = R.layout.activity_simple @@ -55,12 +55,12 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - navigationViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryNavigationViewModel::class.java) - navigationViewModel.observe() + actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryActionViewModel::class.java) + actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is RoomDirectoryActivity.Navigation.Back, - is RoomDirectoryActivity.Navigation.Close -> finish() + is RoomDirectoryActivity.RoomDirectoryAction.Back, + is RoomDirectoryActivity.RoomDirectoryAction.Close -> finish() } } .disposeOnDestroy() 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 88178eaad8..f33b3b003e 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 @@ -26,14 +26,14 @@ import com.airbnb.mvrx.withState import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity -import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel 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 { - private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel + private lateinit var actionViewModel: RoomDirectoryActionViewModel private val viewModel: CreateRoomViewModel by activityViewModel() override fun getLayoutResId() = R.layout.fragment_create_room @@ -43,10 +43,10 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) - navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { - navigationViewModel.post(RoomDirectoryActivity.Navigation.Back) + actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.Back) } } @@ -93,7 +93,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C // Navigate to freshly created room navigator.openRoom(requireActivity(), async()) - navigationViewModel.post(RoomDirectoryActivity.Navigation.Close) + actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.Close) } else { // Populate list with Epoxy createRoomController.setData(state) 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 e345322613..a6aa668d5c 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,8 +27,8 @@ 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.RoomDirectoryActionViewModel import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity -import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel import im.vector.riotx.features.roomdirectory.RoomDirectoryViewModel import kotlinx.android.synthetic.main.fragment_room_directory_picker.* import timber.log.Timber @@ -41,7 +41,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie ) : VectorBaseFragment(), RoomDirectoryPickerController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() - private lateinit var navigationViewModel: RoomDirectoryNavigationViewModel + private lateinit var actionViewModel: RoomDirectoryActionViewModel private val pickerViewModel: RoomDirectoryPickerViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_room_directory_picker @@ -71,7 +71,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - navigationViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryNavigationViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) setupRecyclerView() } @@ -88,7 +88,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie Timber.v("onRoomDirectoryClicked: $roomDirectoryData") viewModel.setRoomDirectoryData(roomDirectoryData) - navigationViewModel.post(RoomDirectoryActivity.Navigation.Back) + actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.Back) } override fun retry() { From c8bc553caa7ffe6d10908603b6c688f122df6bc7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 12:01:36 +0100 Subject: [PATCH 081/117] Move class to dedicated file --- .../features/home/HomeActionViewModel.kt | 2 +- .../riotx/features/home/HomeActivity.kt | 7 ----- .../riotx/features/home/HomeActivityAction.kt | 27 +++++++++++++++++ .../riotx/features/home/HomeDetailFragment.kt | 2 +- .../createdirect/CreateDirectRoomAction.kt | 25 ++++++++++++++++ .../CreateDirectRoomActionViewModel.kt | 2 +- .../createdirect/CreateDirectRoomActions.kt | 1 - .../createdirect/CreateDirectRoomActivity.kt | 7 ----- .../CreateDirectRoomDirectoryUsersFragment.kt | 4 +-- .../CreateDirectRoomKnownUsersFragment.kt | 2 +- .../features/home/group/GroupListFragment.kt | 4 +-- .../roomdirectory/PublicRoomsFragment.kt | 4 +-- .../roomdirectory/RoomDirectoryAction.kt | 29 +++++++++++++++++++ .../RoomDirectoryActionViewModel.kt | 2 +- .../roomdirectory/RoomDirectoryActivity.kt | 9 ------ .../createroom/CreateRoomActivity.kt | 6 ++-- .../createroom/CreateRoomFragment.kt | 6 ++-- .../picker/RoomDirectoryPickerFragment.kt | 4 +-- 18 files changed, 100 insertions(+), 43 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt index 250ba8468c..3d9f13e20a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt @@ -18,4 +18,4 @@ package im.vector.riotx.features.home import im.vector.riotx.core.platform.VectorActionViewModel -class HomeActionViewModel : VectorActionViewModel() +class HomeActionViewModel : VectorActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index 459678863e..7b86cfe67f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -33,7 +33,6 @@ import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.hideKeyboard import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.ToolbarConfigurable -import im.vector.riotx.core.platform.VectorAction import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.features.disclaimer.showDisclaimerDialog @@ -48,12 +47,6 @@ import javax.inject.Inject class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { - // Supported navigation actions for this Activity - sealed class HomeActivityAction : VectorAction { - object OpenDrawer : HomeActivityAction() - object OpenGroup : HomeActivityAction() - } - private lateinit var actionViewModel: HomeActionViewModel @Inject lateinit var activeSessionHolder: ActiveSessionHolder diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt new file mode 100644 index 0000000000..91612fa7b6 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt @@ -0,0 +1,27 @@ +/* + * 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.VectorAction + +/** + * Supported navigation actions for [HomeActivity] + */ +sealed class HomeActivityAction : VectorAction { + object OpenDrawer : HomeActivityAction() + object OpenGroup : HomeActivityAction() +} 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 2daac15b3d..6b642a31eb 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 @@ -129,7 +129,7 @@ class HomeDetailFragment @Inject constructor( } groupToolbar.title = "" groupToolbarAvatarImageView.setOnClickListener { - actionViewModel.post(HomeActivity.HomeActivityAction.OpenDrawer) + actionViewModel.post(HomeActivityAction.OpenDrawer) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt new file mode 100644 index 0000000000..3cd06aa63f --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.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.home.createdirect + +import im.vector.riotx.core.platform.VectorAction + +sealed class CreateDirectRoomAction : VectorAction { + object OpenUsersDirectory : CreateDirectRoomAction() + object Close : CreateDirectRoomAction() + object GoBack : CreateDirectRoomAction() +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt index beff263ea0..66f50829f8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt @@ -18,4 +18,4 @@ package im.vector.riotx.features.home.createdirect import im.vector.riotx.core.platform.VectorActionViewModel -class CreateDirectRoomActionViewModel : VectorActionViewModel() +class CreateDirectRoomActionViewModel : VectorActionViewModel() 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 8f30c9e559..3b0b36df34 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 @@ -19,7 +19,6 @@ package im.vector.riotx.features.home.createdirect import im.vector.matrix.android.api.session.user.model.User sealed class CreateDirectRoomActions { - 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/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index 6b5354b2b9..c1f71dfe08 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -32,19 +32,12 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.platform.SimpleFragmentActivity -import im.vector.riotx.core.platform.VectorAction import im.vector.riotx.core.platform.WaitingViewData import kotlinx.android.synthetic.main.activity.* import javax.inject.Inject class CreateDirectRoomActivity : SimpleFragmentActivity() { - sealed class CreateDirectRoomAction : VectorAction { - object OpenUsersDirectory : CreateDirectRoomAction() - object Close : CreateDirectRoomAction() - object GoBack : CreateDirectRoomAction() - } - private val viewModel: CreateDirectRoomViewModel by viewModel() private lateinit var actionViewModel: CreateDirectRoomActionViewModel @Inject lateinit var createDirectRoomViewModelFactory: CreateDirectRoomViewModel.Factory diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 915280ae03..2e8d7ea00d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -70,7 +70,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private fun setupCloseView() { createDirectRoomClose.setOnClickListener { - actionViewModel.post(CreateDirectRoomActivity.CreateDirectRoomAction.GoBack) + actionViewModel.post(CreateDirectRoomAction.GoBack) } } @@ -81,7 +81,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( override fun onItemClick(user: User) { view?.hideKeyboard() viewModel.handle(CreateDirectRoomActions.SelectUser(user)) - actionViewModel.post(CreateDirectRoomActivity.CreateDirectRoomAction.GoBack) + actionViewModel.post(CreateDirectRoomAction.GoBack) } override fun retryDirectoryUsersRequest() { diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 9cadbc230f..9b0a289a48 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -89,7 +89,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( private fun setupAddByMatrixIdView() { addByMatrixId.setOnClickListener { - actionViewModel.post(CreateDirectRoomActivity.CreateDirectRoomAction.OpenUsersDirectory) + actionViewModel.post(CreateDirectRoomAction.OpenUsersDirectory) } } 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 8666f57338..7f115ecc56 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 @@ -27,7 +27,7 @@ import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.home.HomeActionViewModel -import im.vector.riotx.features.home.HomeActivity +import im.vector.riotx.features.home.HomeActivityAction import kotlinx.android.synthetic.main.fragment_group_list.* import javax.inject.Inject @@ -49,7 +49,7 @@ class GroupListFragment @Inject constructor( groupListEpoxyRecyclerView.setController(groupController) viewModel.subscribe { renderState(it) } viewModel.openGroupLiveData.observeEvent(this) { - actionViewModel.post(HomeActivity.HomeActivityAction.OpenGroup) + actionViewModel.post(HomeActivityAction.OpenGroup) } } 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 36c3c13cc3..6e6a47cdc6 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 @@ -71,7 +71,7 @@ class PublicRoomsFragment @Inject constructor( .disposeOnDestroy() publicRoomsCreateNewRoom.setOnClickListener { - actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.CreateRoom) + actionViewModel.post(RoomDirectoryAction.CreateRoom) } viewModel.joinRoomErrorLiveData.observeEvent(this) { throwable -> @@ -83,7 +83,7 @@ class PublicRoomsFragment @Inject constructor( override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_room_directory_change_protocol -> { - actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.ChangeProtocol) + actionViewModel.post(RoomDirectoryAction.ChangeProtocol) true } else -> diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt new file mode 100644 index 0000000000..3c05dedb04 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt @@ -0,0 +1,29 @@ +/* + * 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.riotx.core.platform.VectorAction + +/** + * Supported navigation actions for [RoomDirectoryActivity] + */ +sealed class RoomDirectoryAction : VectorAction { + object Back : RoomDirectoryAction() + object CreateRoom : RoomDirectoryAction() + object Close : RoomDirectoryAction() + object ChangeProtocol : RoomDirectoryAction() +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt index d9e1a4614b..32b3ccf022 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt @@ -18,4 +18,4 @@ package im.vector.riotx.features.roomdirectory import im.vector.riotx.core.platform.VectorActionViewModel -class RoomDirectoryActionViewModel : VectorActionViewModel() +class RoomDirectoryActionViewModel : VectorActionViewModel() 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 84d7b758ab..c7d0d19c2c 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 @@ -25,7 +25,6 @@ import im.vector.riotx.R 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.VectorAction import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.createroom.CreateRoomViewModel @@ -34,14 +33,6 @@ import javax.inject.Inject class RoomDirectoryActivity : VectorBaseActivity() { - // Supported navigation actions for this Activity - sealed class RoomDirectoryAction : VectorAction { - object Back : RoomDirectoryAction() - object CreateRoom : RoomDirectoryAction() - object Close : RoomDirectoryAction() - object ChangeProtocol : RoomDirectoryAction() - } - @Inject lateinit var createRoomViewModelFactory: CreateRoomViewModel.Factory @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory private val roomDirectoryViewModel: RoomDirectoryViewModel by viewModel() 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 fb982babee..71b5d9527e 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 @@ -26,7 +26,7 @@ import im.vector.riotx.R import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity -import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity +import im.vector.riotx.features.roomdirectory.RoomDirectoryAction import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel import javax.inject.Inject @@ -59,8 +59,8 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is RoomDirectoryActivity.RoomDirectoryAction.Back, - is RoomDirectoryActivity.RoomDirectoryAction.Close -> finish() + is RoomDirectoryAction.Back, + is RoomDirectoryAction.Close -> finish() } } .disposeOnDestroy() 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 f33b3b003e..ff18b0f402 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 @@ -25,7 +25,7 @@ import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity +import im.vector.riotx.features.roomdirectory.RoomDirectoryAction import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel import kotlinx.android.synthetic.main.fragment_create_room.* import timber.log.Timber @@ -46,7 +46,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { - actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.Back) + actionViewModel.post(RoomDirectoryAction.Back) } } @@ -93,7 +93,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C // Navigate to freshly created room navigator.openRoom(requireActivity(), async()) - actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.Close) + actionViewModel.post(RoomDirectoryAction.Close) } else { // Populate list with Epoxy createRoomController.setData(state) 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 a6aa668d5c..ac86fe29bf 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,8 +27,8 @@ 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.RoomDirectoryAction import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel -import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity import im.vector.riotx.features.roomdirectory.RoomDirectoryViewModel import kotlinx.android.synthetic.main.fragment_room_directory_picker.* import timber.log.Timber @@ -88,7 +88,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie Timber.v("onRoomDirectoryClicked: $roomDirectoryData") viewModel.setRoomDirectoryData(roomDirectoryData) - actionViewModel.post(RoomDirectoryActivity.RoomDirectoryAction.Back) + actionViewModel.post(RoomDirectoryAction.Back) } override fun retry() { From 82f639b91fb3266c5e320db3aef358cc97f4a187 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 12:09:01 +0100 Subject: [PATCH 082/117] Rename to Shared --- .../core/platform/VectorEventViewModel.kt | 4 +- .../riotx/features/home/HomeActivity.kt | 8 ++-- ...yAction.kt => HomeActivitySharedAction.kt} | 8 ++-- .../riotx/features/home/HomeDetailFragment.kt | 6 +-- ...wModel.kt => HomeSharedActionViewModel.kt} | 4 +- .../createdirect/CreateDirectRoomActivity.kt | 10 ++--- .../CreateDirectRoomDirectoryUsersFragment.kt | 8 ++-- .../CreateDirectRoomKnownUsersFragment.kt | 6 +-- ...ion.kt => CreateDirectRoomSharedAction.kt} | 10 ++--- ... CreateDirectRoomSharedActionViewModel.kt} | 4 +- .../features/home/group/GroupListFragment.kt | 10 ++--- .../home/room/detail/RoomDetailFragment.kt | 44 +++++++++---------- .../{EventAction.kt => EventSharedAction.kt} | 44 +++++++++---------- .../action/MessageActionsBottomSheet.kt | 4 +- .../action/MessageActionsDispatcher.kt | 4 +- .../action/MessageActionsEpoxyController.kt | 14 +++--- .../action/MessageActionsViewModel.kt | 38 ++++++++-------- .../home/room/list/RoomListFragment.kt | 16 +++---- .../RoomListQuickActionsBottomSheet.kt | 2 +- .../RoomListQuickActionsEpoxyController.kt | 28 ++++++------ .../list/actions/RoomListQuickActionsStore.kt | 4 +- ...Action.kt => RoomListQuickSharedAction.kt} | 16 +++---- .../roomdirectory/PublicRoomsFragment.kt | 8 ++-- .../roomdirectory/RoomDirectoryActivity.kt | 12 ++--- ...Action.kt => RoomDirectorySharedAction.kt} | 12 ++--- ... => RoomDirectorySharedActionViewModel.kt} | 4 +- .../createroom/CreateRoomActivity.kt | 12 ++--- .../createroom/CreateRoomFragment.kt | 12 ++--- .../picker/RoomDirectoryPickerFragment.kt | 10 ++--- 29 files changed, 181 insertions(+), 181 deletions(-) rename vector/src/main/java/im/vector/riotx/features/home/{HomeActivityAction.kt => HomeActivitySharedAction.kt} (76%) rename vector/src/main/java/im/vector/riotx/features/home/{HomeActionViewModel.kt => HomeSharedActionViewModel.kt} (80%) rename vector/src/main/java/im/vector/riotx/features/home/createdirect/{CreateDirectRoomAction.kt => CreateDirectRoomSharedAction.kt} (69%) rename vector/src/main/java/im/vector/riotx/features/home/createdirect/{CreateDirectRoomActionViewModel.kt => CreateDirectRoomSharedActionViewModel.kt} (79%) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/{EventAction.kt => EventSharedAction.kt} (54%) rename vector/src/main/java/im/vector/riotx/features/home/room/list/actions/{RoomListQuickAction.kt => RoomListQuickSharedAction.kt} (80%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/{RoomDirectoryAction.kt => RoomDirectorySharedAction.kt} (69%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/{RoomDirectoryActionViewModel.kt => RoomDirectorySharedActionViewModel.kt} (79%) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt index 977991cd4a..4bf21c9aa9 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt @@ -21,10 +21,10 @@ import im.vector.riotx.core.utils.MutableDataSource import im.vector.riotx.core.utils.PublishDataSource -interface VectorAction +interface VectorSharedAction /** * Parent class to handle navigation events, action events, or other any events */ -open class VectorActionViewModel(private val store: MutableDataSource = PublishDataSource()) +open class VectorSharedActionViewModel(private val store: MutableDataSource = PublishDataSource()) : ViewModel(), MutableDataSource by store diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index 7b86cfe67f..f4694bff38 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -47,7 +47,7 @@ import javax.inject.Inject class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { - private lateinit var actionViewModel: HomeActionViewModel + private lateinit var actionViewModel: HomeSharedActionViewModel @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler @@ -69,7 +69,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager) - actionViewModel = ViewModelProviders.of(this).get(HomeActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(this).get(HomeSharedActionViewModel::class.java) drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) @@ -79,8 +79,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is HomeActivityAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) - is HomeActivityAction.OpenGroup -> { + is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) + is HomeActivitySharedAction.OpenGroup -> { drawerLayout.closeDrawer(GravityCompat.START) replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt similarity index 76% rename from vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt rename to vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt index 91612fa7b6..493a14512d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivityAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivitySharedAction.kt @@ -16,12 +16,12 @@ package im.vector.riotx.features.home -import im.vector.riotx.core.platform.VectorAction +import im.vector.riotx.core.platform.VectorSharedAction /** * Supported navigation actions for [HomeActivity] */ -sealed class HomeActivityAction : VectorAction { - object OpenDrawer : HomeActivityAction() - object OpenGroup : HomeActivityAction() +sealed class HomeActivitySharedAction : VectorSharedAction { + object OpenDrawer : HomeActivitySharedAction() + object OpenGroup : HomeActivitySharedAction() } 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 6b642a31eb..c6b7280f0c 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 @@ -54,7 +54,7 @@ class HomeDetailFragment @Inject constructor( private val unreadCounterBadgeViews = arrayListOf() private val viewModel: HomeDetailViewModel by fragmentViewModel() - private lateinit var actionViewModel: HomeActionViewModel + private lateinit var actionViewModel: HomeSharedActionViewModel override fun getLayoutResId(): Int { return R.layout.fragment_home_detail @@ -63,7 +63,7 @@ class HomeDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) setupBottomNavigationView() setupToolbar() @@ -129,7 +129,7 @@ class HomeDetailFragment @Inject constructor( } groupToolbar.title = "" groupToolbarAvatarImageView.setOnClickListener { - actionViewModel.post(HomeActivityAction.OpenDrawer) + actionViewModel.post(HomeActivitySharedAction.OpenDrawer) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt similarity index 80% rename from vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt rename to vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt index 3d9f13e20a..23baa53e3b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt @@ -16,6 +16,6 @@ package im.vector.riotx.features.home -import im.vector.riotx.core.platform.VectorActionViewModel +import im.vector.riotx.core.platform.VectorSharedActionViewModel -class HomeActionViewModel : VectorActionViewModel() +class HomeSharedActionViewModel : VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index c1f71dfe08..379611d970 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -39,7 +39,7 @@ import javax.inject.Inject class CreateDirectRoomActivity : SimpleFragmentActivity() { private val viewModel: CreateDirectRoomViewModel by viewModel() - private lateinit var actionViewModel: CreateDirectRoomActionViewModel + private lateinit var actionViewModel: CreateDirectRoomSharedActionViewModel @Inject lateinit var createDirectRoomViewModelFactory: CreateDirectRoomViewModel.Factory @Inject lateinit var errorFormatter: ErrorFormatter @@ -51,13 +51,13 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) toolbar.visibility = View.GONE - actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) actionViewModel.observe() .subscribe { navigation -> when (navigation) { - CreateDirectRoomAction.OpenUsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) - CreateDirectRoomAction.Close -> finish() - CreateDirectRoomAction.GoBack -> onBackPressed() + CreateDirectRoomSharedAction.OpenUsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) + CreateDirectRoomSharedAction.Close -> finish() + CreateDirectRoomSharedAction.GoBack -> onBackPressed() } } .disposeOnDestroy() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 2e8d7ea00d..7e8e5a16d4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -39,11 +39,11 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private val viewModel: CreateDirectRoomViewModel by activityViewModel() - private lateinit var actionViewModel: CreateDirectRoomActionViewModel + private lateinit var actionViewModel: CreateDirectRoomSharedActionViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) setupRecyclerView() setupSearchByMatrixIdView() setupCloseView() @@ -70,7 +70,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private fun setupCloseView() { createDirectRoomClose.setOnClickListener { - actionViewModel.post(CreateDirectRoomAction.GoBack) + actionViewModel.post(CreateDirectRoomSharedAction.GoBack) } } @@ -81,7 +81,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( override fun onItemClick(user: User) { view?.hideKeyboard() viewModel.handle(CreateDirectRoomActions.SelectUser(user)) - actionViewModel.post(CreateDirectRoomAction.GoBack) + actionViewModel.post(CreateDirectRoomSharedAction.GoBack) } override fun retryDirectoryUsersRequest() { diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 9b0a289a48..bbfab88528 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -49,11 +49,11 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( override fun getMenuRes() = R.menu.vector_create_direct_room private val viewModel: CreateDirectRoomViewModel by activityViewModel() - private lateinit var actionViewModel: CreateDirectRoomActionViewModel + private lateinit var actionViewModel: CreateDirectRoomSharedActionViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) vectorBaseActivity.setSupportActionBar(createDirectRoomToolbar) setupRecyclerView() setupFilterView() @@ -89,7 +89,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( private fun setupAddByMatrixIdView() { addByMatrixId.setOnClickListener { - actionViewModel.post(CreateDirectRoomAction.OpenUsersDirectory) + actionViewModel.post(CreateDirectRoomSharedAction.OpenUsersDirectory) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedAction.kt similarity index 69% rename from vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt rename to vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedAction.kt index 3cd06aa63f..0df6720734 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedAction.kt @@ -16,10 +16,10 @@ package im.vector.riotx.features.home.createdirect -import im.vector.riotx.core.platform.VectorAction +import im.vector.riotx.core.platform.VectorSharedAction -sealed class CreateDirectRoomAction : VectorAction { - object OpenUsersDirectory : CreateDirectRoomAction() - object Close : CreateDirectRoomAction() - object GoBack : CreateDirectRoomAction() +sealed class CreateDirectRoomSharedAction : VectorSharedAction { + object OpenUsersDirectory : CreateDirectRoomSharedAction() + object Close : CreateDirectRoomSharedAction() + object GoBack : CreateDirectRoomSharedAction() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt similarity index 79% rename from vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt rename to vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt index 66f50829f8..7e5a2bbe93 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt @@ -16,6 +16,6 @@ package im.vector.riotx.features.home.createdirect -import im.vector.riotx.core.platform.VectorActionViewModel +import im.vector.riotx.core.platform.VectorSharedActionViewModel -class CreateDirectRoomActionViewModel : VectorActionViewModel() +class CreateDirectRoomSharedActionViewModel : VectorSharedActionViewModel() 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 7f115ecc56..9972e7ac1c 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 @@ -26,8 +26,8 @@ import im.vector.riotx.R import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.home.HomeActionViewModel -import im.vector.riotx.features.home.HomeActivityAction +import im.vector.riotx.features.home.HomeSharedActionViewModel +import im.vector.riotx.features.home.HomeActivitySharedAction import kotlinx.android.synthetic.main.fragment_group_list.* import javax.inject.Inject @@ -36,20 +36,20 @@ class GroupListFragment @Inject constructor( private val groupController: GroupSummaryController ) : VectorBaseFragment(), GroupSummaryController.Callback { - private lateinit var actionViewModel: HomeActionViewModel + private lateinit var actionViewModel: HomeSharedActionViewModel private val viewModel: GroupListViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_group_list override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) groupController.callback = this stateView.contentView = groupListEpoxyRecyclerView groupListEpoxyRecyclerView.setController(groupController) viewModel.subscribe { renderState(it) } viewModel.openGroupLiveData.observeEvent(this) { - actionViewModel.post(HomeActivityAction.OpenGroup) + actionViewModel.post(HomeActivitySharedAction.OpenGroup) } } 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 83004a35de..473b131348 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 @@ -99,7 +99,7 @@ import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceipt import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsDispatcher -import im.vector.riotx.features.home.room.detail.timeline.action.EventAction +import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.item.* import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet @@ -749,7 +749,7 @@ class RoomDetailFragment @Inject constructor( .show() } - private fun promptReasonToReportContent(action: EventAction.ReportContentCustom) { + private fun promptReasonToReportContent(action: EventSharedAction.ReportContentCustom) { val inflater = requireActivity().layoutInflater val layout = inflater.inflate(R.layout.dialog_report_content, null) @@ -1037,25 +1037,25 @@ class RoomDetailFragment @Inject constructor( textComposerViewModel.process(TextComposerActions.QueryUsers(query)) } - private fun handleActions(action: EventAction) { + private fun handleActions(action: EventSharedAction) { when (action) { - is EventAction.AddReaction -> { + is EventSharedAction.AddReaction -> { startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), action.eventId), REACTION_SELECT_REQUEST_CODE) } - is EventAction.ViewReactions -> { + is EventSharedAction.ViewReactions -> { ViewReactionsBottomSheet.newInstance(roomDetailArgs.roomId, action.messageInformationData) .show(requireActivity().supportFragmentManager, "DISPLAY_REACTIONS") } - is EventAction.Copy -> { + is EventSharedAction.Copy -> { // I need info about the current selected message :/ copyToClipboard(requireContext(), action.content, false) val msg = requireContext().getString(R.string.copied_to_clipboard) showSnackWithMessage(msg, Snackbar.LENGTH_SHORT) } - is EventAction.Delete -> { + is EventSharedAction.Delete -> { roomDetailViewModel.process(RoomDetailActions.RedactAction(action.eventId, context?.getString(R.string.event_redacted_by_user_reason))) } - is EventAction.Share -> { + is EventSharedAction.Share -> { // TODO current data communication is too limited // Need to now the media type // TODO bad, just POC @@ -1083,10 +1083,10 @@ class RoomDetailFragment @Inject constructor( } ) } - is EventAction.ViewEditHistory -> { + is EventSharedAction.ViewEditHistory -> { onEditedDecorationClicked(action.messageInformationData) } - is EventAction.ViewSource -> { + is EventSharedAction.ViewSource -> { val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_event_content, null) view.findViewById(R.id.event_content_text_view)?.let { it.text = action.content @@ -1097,7 +1097,7 @@ class RoomDetailFragment @Inject constructor( .setPositiveButton(R.string.ok, null) .show() } - is EventAction.ViewDecryptedSource -> { + is EventSharedAction.ViewDecryptedSource -> { val view = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_event_content, null) view.findViewById(R.id.event_content_text_view)?.let { it.text = action.content @@ -1108,42 +1108,42 @@ class RoomDetailFragment @Inject constructor( .setPositiveButton(R.string.ok, null) .show() } - is EventAction.QuickReact -> { + is EventSharedAction.QuickReact -> { // eventId,ClickedOn,Add roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } - is EventAction.Edit -> { + is EventSharedAction.Edit -> { roomDetailViewModel.process(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) } - is EventAction.Quote -> { + is EventSharedAction.Quote -> { roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) } - is EventAction.Reply -> { + is EventSharedAction.Reply -> { roomDetailViewModel.process(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.composerEditText.text.toString())) } - is EventAction.CopyPermalink -> { + is EventSharedAction.CopyPermalink -> { val permalink = PermalinkFactory.createPermalink(roomDetailArgs.roomId, action.eventId) copyToClipboard(requireContext(), permalink, false) showSnackWithMessage(requireContext().getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) } - is EventAction.Resend -> { + is EventSharedAction.Resend -> { roomDetailViewModel.process(RoomDetailActions.ResendMessage(action.eventId)) } - is EventAction.Remove -> { + is EventSharedAction.Remove -> { roomDetailViewModel.process(RoomDetailActions.RemoveFailedEcho(action.eventId)) } - is EventAction.ReportContentSpam -> { + is EventSharedAction.ReportContentSpam -> { roomDetailViewModel.process(RoomDetailActions.ReportContent( action.eventId, action.senderId, "This message is spam", spam = true)) } - is EventAction.ReportContentInappropriate -> { + is EventSharedAction.ReportContentInappropriate -> { roomDetailViewModel.process(RoomDetailActions.ReportContent( action.eventId, action.senderId, "This message is inappropriate", inappropriate = true)) } - is EventAction.ReportContentCustom -> { + is EventSharedAction.ReportContentCustom -> { promptReasonToReportContent(action) } - else -> { + else -> { Toast.makeText(context, "Action $action is not implemented yet", Toast.LENGTH_LONG).show() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt similarity index 54% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventAction.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt index 79d615112c..73a4e245d0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt @@ -19,67 +19,67 @@ package im.vector.riotx.features.home.room.detail.timeline.action import androidx.annotation.DrawableRes import androidx.annotation.StringRes import im.vector.riotx.R -import im.vector.riotx.core.platform.VectorAction +import im.vector.riotx.core.platform.VectorSharedAction import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData -sealed class EventAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) : VectorAction { +sealed class EventSharedAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) : VectorSharedAction { data class AddReaction(val eventId: String) : - EventAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) + EventSharedAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) data class Copy(val content: String) : - EventAction(R.string.copy, R.drawable.ic_copy) + EventSharedAction(R.string.copy, R.drawable.ic_copy) data class Edit(val eventId: String) : - EventAction(R.string.edit, R.drawable.ic_edit) + EventSharedAction(R.string.edit, R.drawable.ic_edit) data class Quote(val eventId: String) : - EventAction(R.string.quote, R.drawable.ic_quote) + EventSharedAction(R.string.quote, R.drawable.ic_quote) data class Reply(val eventId: String) : - EventAction(R.string.reply, R.drawable.ic_reply) + EventSharedAction(R.string.reply, R.drawable.ic_reply) data class Share(val imageUrl: String) : - EventAction(R.string.share, R.drawable.ic_share) + EventSharedAction(R.string.share, R.drawable.ic_share) data class Resend(val eventId: String) : - EventAction(R.string.global_retry, R.drawable.ic_refresh_cw) + EventSharedAction(R.string.global_retry, R.drawable.ic_refresh_cw) data class Remove(val eventId: String) : - EventAction(R.string.remove, R.drawable.ic_trash) + EventSharedAction(R.string.remove, R.drawable.ic_trash) data class Delete(val eventId: String) : - EventAction(R.string.delete, R.drawable.ic_delete) + EventSharedAction(R.string.delete, R.drawable.ic_delete) data class Cancel(val eventId: String) : - EventAction(R.string.cancel, R.drawable.ic_close_round) + EventSharedAction(R.string.cancel, R.drawable.ic_close_round) data class ViewSource(val content: String) : - EventAction(R.string.view_source, R.drawable.ic_view_source) + EventSharedAction(R.string.view_source, R.drawable.ic_view_source) data class ViewDecryptedSource(val content: String) : - EventAction(R.string.view_decrypted_source, R.drawable.ic_view_source) + EventSharedAction(R.string.view_decrypted_source, R.drawable.ic_view_source) data class CopyPermalink(val eventId: String) : - EventAction(R.string.permalink, R.drawable.ic_permalink) + EventSharedAction(R.string.permalink, R.drawable.ic_permalink) data class ReportContent(val eventId: String, val senderId: String?) : - EventAction(R.string.report_content, R.drawable.ic_flag) + EventSharedAction(R.string.report_content, R.drawable.ic_flag) data class ReportContentSpam(val eventId: String, val senderId: String?) : - EventAction(R.string.report_content_spam, R.drawable.ic_report_spam) + EventSharedAction(R.string.report_content_spam, R.drawable.ic_report_spam) data class ReportContentInappropriate(val eventId: String, val senderId: String?) : - EventAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) + EventSharedAction(R.string.report_content_inappropriate, R.drawable.ic_report_inappropriate) data class ReportContentCustom(val eventId: String, val senderId: String?) : - EventAction(R.string.report_content_custom, R.drawable.ic_report_custom) + EventSharedAction(R.string.report_content_custom, R.drawable.ic_report_custom) data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : - EventAction(0, 0) + EventSharedAction(0, 0) data class ViewReactions(val messageInformationData: MessageInformationData) : - EventAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) + EventSharedAction(R.string.message_view_reaction, R.drawable.ic_view_reactions) data class ViewEditHistory(val messageInformationData: MessageInformationData) : - EventAction(R.string.message_view_edit_history, R.drawable.ic_view_edit_history) + EventSharedAction(R.string.message_view_edit_history, R.drawable.ic_view_edit_history) } 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 fa738e5c42..479a9dd05c 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 @@ -69,8 +69,8 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message messageActionsEpoxyController.listener = this } - override fun didSelectMenuAction(eventAction: EventAction) { - if (eventAction is EventAction.ReportContent) { + override fun didSelectMenuAction(eventAction: EventSharedAction) { + if (eventAction is EventSharedAction.ReportContent) { // Toggle report menu viewModel.toggleReportMenu() } else { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt index 54f9d0d583..0d4cd201d8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt @@ -15,9 +15,9 @@ */ package im.vector.riotx.features.home.room.detail.timeline.action -import im.vector.riotx.core.platform.VectorActionViewModel +import im.vector.riotx.core.platform.VectorSharedActionViewModel /** * Activity shared view model to handle message actions */ -class MessageActionsDispatcher : VectorActionViewModel() +class MessageActionsDispatcher : VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index e30a383087..0917f52779 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -84,7 +84,7 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid selecteds(state.quickStates.invoke().map { it.isSelected }) listener(object : BottomSheetItemQuickReactions.Listener { override fun didSelect(emoji: String, selected: Boolean) { - listener?.didSelectMenuAction(EventAction.QuickReact(state.eventId, emoji, selected)) + listener?.didSelectMenuAction(EventSharedAction.QuickReact(state.eventId, emoji, selected)) } }) } @@ -101,17 +101,17 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid id("action_$index") iconRes(action.iconResId) textRes(action.titleRes) - showExpand(action is EventAction.ReportContent) + showExpand(action is EventSharedAction.ReportContent) expanded(state.expendedReportContentMenu) listener(View.OnClickListener { listener?.didSelectMenuAction(action) }) } - if (action is EventAction.ReportContent && state.expendedReportContentMenu) { + if (action is EventSharedAction.ReportContent && state.expendedReportContentMenu) { // Special case for report content menu: add the submenu listOf( - EventAction.ReportContentSpam(action.eventId, action.senderId), - EventAction.ReportContentInappropriate(action.eventId, action.senderId), - EventAction.ReportContentCustom(action.eventId, action.senderId) + EventSharedAction.ReportContentSpam(action.eventId, action.senderId), + EventSharedAction.ReportContentInappropriate(action.eventId, action.senderId), + EventSharedAction.ReportContentCustom(action.eventId, action.senderId) ).forEachIndexed { indexReport, actionReport -> bottomSheetItemAction { id("actionReport_$indexReport") @@ -126,6 +126,6 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid } interface MessageActionsEpoxyControllerListener { - fun didSelectMenuAction(eventAction: EventAction) + fun didSelectMenuAction(eventAction: EventSharedAction) } } 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 92be124940..42d0c1d201 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 @@ -62,7 +62,7 @@ data class MessageActionState( // For quick reactions val quickStates: Async> = Uninitialized, // For actions - val actions: Async> = Uninitialized, + val actions: Async> = Uninitialized, val expendedReportContentMenu: Boolean = false ) : MvRxState { @@ -184,63 +184,63 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } - private fun actionsForEvent(optionalEvent: Optional): List { + private fun actionsForEvent(optionalEvent: Optional): List { val event = optionalEvent.getOrNull() ?: return emptyList() val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent.toModel() ?: event.root.getClearContent().toModel() val type = messageContent?.type - return arrayListOf().apply { + return arrayListOf().apply { if (event.root.sendState.hasFailed()) { if (canRetry(event)) { - add(EventAction.Resend(eventId)) + add(EventSharedAction.Resend(eventId)) } - add(EventAction.Remove(eventId)) + add(EventSharedAction.Remove(eventId)) } else if (event.root.sendState.isSending()) { // TODO is uploading attachment? if (canCancel(event)) { - add(EventAction.Cancel(eventId)) + add(EventSharedAction.Cancel(eventId)) } } else if (event.root.sendState == SendState.SYNCED) { if (!event.root.isRedacted()) { if (canReply(event, messageContent)) { - add(EventAction.Reply(eventId)) + add(EventSharedAction.Reply(eventId)) } if (canEdit(event, session.myUserId)) { - add(EventAction.Edit(eventId)) + add(EventSharedAction.Edit(eventId)) } if (canRedact(event, session.myUserId)) { - add(EventAction.Delete(eventId)) + add(EventSharedAction.Delete(eventId)) } if (canCopy(type)) { // TODO copy images? html? see ClipBoard - add(EventAction.Copy(messageContent!!.body)) + add(EventSharedAction.Copy(messageContent!!.body)) } if (event.canReact()) { - add(EventAction.AddReaction(eventId)) + add(EventSharedAction.AddReaction(eventId)) } if (canQuote(event, messageContent)) { - add(EventAction.Quote(eventId)) + add(EventSharedAction.Quote(eventId)) } if (canViewReactions(event)) { - add(EventAction.ViewReactions(informationData)) + add(EventSharedAction.ViewReactions(informationData)) } if (event.hasBeenEdited()) { - add(EventAction.ViewEditHistory(informationData)) + add(EventSharedAction.ViewEditHistory(informationData)) } if (canShare(type)) { if (messageContent is MessageImageContent) { session.contentUrlResolver().resolveFullSize(messageContent.url)?.let { url -> - add(EventAction.Share(url)) + add(EventSharedAction.Share(url)) } } // TODO @@ -253,17 +253,17 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } - add(EventAction.ViewSource(event.root.toContentStringWithIndent())) + add(EventSharedAction.ViewSource(event.root.toContentStringWithIndent())) if (event.isEncrypted()) { val decryptedContent = event.root.toClearContentStringWithIndent() ?: stringProvider.getString(R.string.encryption_information_decryption_error) - add(EventAction.ViewDecryptedSource(decryptedContent)) + add(EventSharedAction.ViewDecryptedSource(decryptedContent)) } - add(EventAction.CopyPermalink(eventId)) + add(EventSharedAction.CopyPermalink(eventId)) if (session.myUserId != event.root.senderId && event.root.getClearType() == EventType.MESSAGE) { // not sent by me - add(EventAction.ReportContent(eventId, event.root.senderId)) + add(EventSharedAction.ReportContent(eventId, event.root.senderId)) } } } 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 64c8214236..23fabe4b97 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 @@ -39,7 +39,7 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.home.room.list.actions.RoomListQuickAction +import im.vector.riotx.features.home.room.list.actions.RoomListQuickSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsStore import im.vector.riotx.features.home.room.list.widget.FabMenuView @@ -216,24 +216,24 @@ class RoomListFragment @Inject constructor( } } - private fun handleQuickActions(quickAction: RoomListQuickAction) { + private fun handleQuickActions(quickAction: RoomListQuickSharedAction) { when (quickAction) { - is RoomListQuickAction.NotificationsAllNoisy -> { + is RoomListQuickSharedAction.NotificationsAllNoisy -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) } - is RoomListQuickAction.NotificationsAll -> { + is RoomListQuickSharedAction.NotificationsAll -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) } - is RoomListQuickAction.NotificationsMentionsOnly -> { + is RoomListQuickSharedAction.NotificationsMentionsOnly -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) } - is RoomListQuickAction.NotificationsMute -> { + is RoomListQuickSharedAction.NotificationsMute -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) } - is RoomListQuickAction.Settings -> { + is RoomListQuickSharedAction.Settings -> { vectorBaseActivity.notImplemented("Opening room settings") } - is RoomListQuickAction.Leave -> { + is RoomListQuickSharedAction.Leave -> { AlertDialog.Builder(requireContext()) .setTitle(R.string.room_participants_leave_prompt_title) .setMessage(R.string.room_participants_leave_prompt_msg) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 03fb5f5a00..50d0503693 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -82,7 +82,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R super.invalidate() } - override fun didSelectMenuAction(quickAction: RoomListQuickAction) { + override fun didSelectMenuAction(quickAction: RoomListQuickSharedAction) { actionsDispatcher.post(quickAction) dismiss() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index 16d96e8dba..d54edce712 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -42,7 +42,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar roomName(roomSummary.displayName) avatarUrl(roomSummary.avatarUrl) roomId(roomSummary.roomId) - settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickAction.Settings(roomSummary.roomId)) }) + settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickSharedAction.Settings(roomSummary.roomId)) }) } // Notifications @@ -51,26 +51,26 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar } val selectedRoomState = state.roomNotificationState() - RoomListQuickAction.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) - RoomListQuickAction.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) - RoomListQuickAction.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) - RoomListQuickAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) + RoomListQuickSharedAction.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) + RoomListQuickSharedAction.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) + RoomListQuickSharedAction.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) + RoomListQuickSharedAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) // Leave bottomSheetItemSeparator { id("leave_separator") } - RoomListQuickAction.Leave(roomSummary.roomId).toBottomSheetItem(5) + RoomListQuickSharedAction.Leave(roomSummary.roomId).toBottomSheetItem(5) } - private fun RoomListQuickAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { + private fun RoomListQuickSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { val selected = when (this) { - is RoomListQuickAction.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY - is RoomListQuickAction.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES - is RoomListQuickAction.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY - is RoomListQuickAction.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE - is RoomListQuickAction.Settings, - is RoomListQuickAction.Leave -> false + is RoomListQuickSharedAction.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY + is RoomListQuickSharedAction.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES + is RoomListQuickSharedAction.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY + is RoomListQuickSharedAction.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE + is RoomListQuickSharedAction.Settings, + is RoomListQuickSharedAction.Leave -> false } return bottomSheetItemAction { id("action_$index") @@ -83,6 +83,6 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar } interface Listener { - fun didSelectMenuAction(quickAction: RoomListQuickAction) + fun didSelectMenuAction(quickAction: RoomListQuickSharedAction) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt index 503a3b0327..891ffc81f0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt @@ -16,9 +16,9 @@ */ package im.vector.riotx.features.home.room.list.actions -import im.vector.riotx.core.platform.VectorActionViewModel +import im.vector.riotx.core.platform.VectorSharedActionViewModel /** * Activity shared view model to handle room list quick actions */ -class RoomListQuickActionsStore : VectorActionViewModel() +class RoomListQuickActionsStore : VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickSharedAction.kt similarity index 80% rename from vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickAction.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickSharedAction.kt index c0de0a9d7b..4033434327 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickSharedAction.kt @@ -19,36 +19,36 @@ package im.vector.riotx.features.home.room.list.actions import androidx.annotation.DrawableRes import androidx.annotation.StringRes import im.vector.riotx.R -import im.vector.riotx.core.platform.VectorAction +import im.vector.riotx.core.platform.VectorSharedAction -sealed class RoomListQuickAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) : VectorAction { +sealed class RoomListQuickSharedAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) : VectorSharedAction { - data class NotificationsAllNoisy(val roomId: String) : RoomListQuickAction( + data class NotificationsAllNoisy(val roomId: String) : RoomListQuickSharedAction( R.string.room_list_quick_actions_notifications_all_noisy, R.drawable.ic_room_actions_notifications_all_noisy ) - data class NotificationsAll(val roomId: String) : RoomListQuickAction( + data class NotificationsAll(val roomId: String) : RoomListQuickSharedAction( R.string.room_list_quick_actions_notifications_all, R.drawable.ic_room_actions_notifications_all ) - data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickAction( + data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickSharedAction( R.string.room_list_quick_actions_notifications_mentions, R.drawable.ic_room_actions_notifications_mentions ) - data class NotificationsMute(val roomId: String) : RoomListQuickAction( + data class NotificationsMute(val roomId: String) : RoomListQuickSharedAction( R.string.room_list_quick_actions_notifications_mute, R.drawable.ic_room_actions_notifications_mutes ) - data class Settings(val roomId: String) : RoomListQuickAction( + data class Settings(val roomId: String) : RoomListQuickSharedAction( R.string.room_list_quick_actions_settings, R.drawable.ic_room_actions_settings ) - data class Leave(val roomId: String) : RoomListQuickAction( + data class Leave(val roomId: String) : RoomListQuickSharedAction( R.string.room_list_quick_actions_leave, R.drawable.ic_room_actions_leave, true 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 6e6a47cdc6..2840dc7e89 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 @@ -47,7 +47,7 @@ class PublicRoomsFragment @Inject constructor( ) : VectorBaseFragment(), PublicRoomsController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() - private lateinit var actionViewModel: RoomDirectoryActionViewModel + private lateinit var actionViewModel: RoomDirectorySharedActionViewModel override fun getLayoutResId() = R.layout.fragment_public_rooms @@ -71,7 +71,7 @@ class PublicRoomsFragment @Inject constructor( .disposeOnDestroy() publicRoomsCreateNewRoom.setOnClickListener { - actionViewModel.post(RoomDirectoryAction.CreateRoom) + actionViewModel.post(RoomDirectorySharedAction.CreateRoom) } viewModel.joinRoomErrorLiveData.observeEvent(this) { throwable -> @@ -83,7 +83,7 @@ class PublicRoomsFragment @Inject constructor( override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_room_directory_change_protocol -> { - actionViewModel.post(RoomDirectoryAction.ChangeProtocol) + actionViewModel.post(RoomDirectorySharedAction.ChangeProtocol) true } else -> @@ -93,7 +93,7 @@ class PublicRoomsFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } 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 c7d0d19c2c..b0b1a86275 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 @@ -37,7 +37,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory private val roomDirectoryViewModel: RoomDirectoryViewModel by viewModel() private val createRoomViewModel: CreateRoomViewModel by viewModel() - private lateinit var actionViewModel: RoomDirectoryActionViewModel + private lateinit var actionViewModel: RoomDirectorySharedActionViewModel override fun getLayoutRes() = R.layout.activity_simple @@ -47,7 +47,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) if (isFirstCreation()) { roomDirectoryViewModel.filterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "") @@ -56,10 +56,10 @@ class RoomDirectoryActivity : VectorBaseActivity() { actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is RoomDirectoryAction.Back -> onBackPressed() - is RoomDirectoryAction.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) - is RoomDirectoryAction.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) - is RoomDirectoryAction.Close -> finish() + is RoomDirectorySharedAction.Back -> onBackPressed() + is RoomDirectorySharedAction.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) + is RoomDirectorySharedAction.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) + is RoomDirectorySharedAction.Close -> finish() } } .disposeOnDestroy() diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedAction.kt similarity index 69% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedAction.kt index 3c05dedb04..b257f82595 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedAction.kt @@ -16,14 +16,14 @@ package im.vector.riotx.features.roomdirectory -import im.vector.riotx.core.platform.VectorAction +import im.vector.riotx.core.platform.VectorSharedAction /** * Supported navigation actions for [RoomDirectoryActivity] */ -sealed class RoomDirectoryAction : VectorAction { - object Back : RoomDirectoryAction() - object CreateRoom : RoomDirectoryAction() - object Close : RoomDirectoryAction() - object ChangeProtocol : RoomDirectoryAction() +sealed class RoomDirectorySharedAction : VectorSharedAction { + object Back : RoomDirectorySharedAction() + object CreateRoom : RoomDirectorySharedAction() + object Close : RoomDirectorySharedAction() + object ChangeProtocol : RoomDirectorySharedAction() } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt similarity index 79% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt index 32b3ccf022..257ad782fe 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt @@ -16,6 +16,6 @@ package im.vector.riotx.features.roomdirectory -import im.vector.riotx.core.platform.VectorActionViewModel +import im.vector.riotx.core.platform.VectorSharedActionViewModel -class RoomDirectoryActionViewModel : VectorActionViewModel() +class RoomDirectorySharedActionViewModel : VectorSharedActionViewModel() 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 71b5d9527e..4d0938814a 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 @@ -26,8 +26,8 @@ import im.vector.riotx.R import im.vector.riotx.core.extensions.addFragment import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity -import im.vector.riotx.features.roomdirectory.RoomDirectoryAction -import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedAction +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedActionViewModel import javax.inject.Inject /** @@ -38,7 +38,7 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { @Inject lateinit var createRoomViewModelFactory: CreateRoomViewModel.Factory private val createRoomViewModel: CreateRoomViewModel by viewModel() - private lateinit var actionViewModel: RoomDirectoryActionViewModel + private lateinit var actionViewModel: RoomDirectorySharedActionViewModel override fun getLayoutRes() = R.layout.activity_simple @@ -55,12 +55,12 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectoryActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) actionViewModel.observe() .subscribe { navigation -> when (navigation) { - is RoomDirectoryAction.Back, - is RoomDirectoryAction.Close -> finish() + is RoomDirectorySharedAction.Back, + is RoomDirectorySharedAction.Close -> finish() } } .disposeOnDestroy() 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 ff18b0f402..a421398322 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 @@ -25,15 +25,15 @@ import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.roomdirectory.RoomDirectoryAction -import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedAction +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedActionViewModel 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 { - private lateinit var actionViewModel: RoomDirectoryActionViewModel + private lateinit var actionViewModel: RoomDirectorySharedActionViewModel private val viewModel: CreateRoomViewModel by activityViewModel() override fun getLayoutResId() = R.layout.fragment_create_room @@ -43,10 +43,10 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) - actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { - actionViewModel.post(RoomDirectoryAction.Back) + actionViewModel.post(RoomDirectorySharedAction.Back) } } @@ -93,7 +93,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C // Navigate to freshly created room navigator.openRoom(requireActivity(), async()) - actionViewModel.post(RoomDirectoryAction.Close) + actionViewModel.post(RoomDirectorySharedAction.Close) } else { // Populate list with Epoxy createRoomController.setData(state) 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 ac86fe29bf..18be8498da 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,8 +27,8 @@ 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.RoomDirectoryAction -import im.vector.riotx.features.roomdirectory.RoomDirectoryActionViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedAction +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.riotx.features.roomdirectory.RoomDirectoryViewModel import kotlinx.android.synthetic.main.fragment_room_directory_picker.* import timber.log.Timber @@ -41,7 +41,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie ) : VectorBaseFragment(), RoomDirectoryPickerController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() - private lateinit var actionViewModel: RoomDirectoryActionViewModel + private lateinit var actionViewModel: RoomDirectorySharedActionViewModel private val pickerViewModel: RoomDirectoryPickerViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_room_directory_picker @@ -71,7 +71,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectoryActionViewModel::class.java) + actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } @@ -88,7 +88,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie Timber.v("onRoomDirectoryClicked: $roomDirectoryData") viewModel.setRoomDirectoryData(roomDirectoryData) - actionViewModel.post(RoomDirectoryAction.Back) + actionViewModel.post(RoomDirectorySharedAction.Back) } override fun retry() { From 238d1d87c61b9280a0a70499cd27b9bbb25421f1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 13:31:39 +0100 Subject: [PATCH 083/117] Rename class --- .../home/room/list/RoomListFragment.kt | 16 +++++------ .../RoomListQuickActionsBottomSheet.kt | 2 +- .../RoomListQuickActionsEpoxyController.kt | 28 +++++++++---------- ...kt => RoomListQuickActionsSharedAction.kt} | 14 +++++----- .../list/actions/RoomListQuickActionsStore.kt | 2 +- 5 files changed, 31 insertions(+), 31 deletions(-) rename vector/src/main/java/im/vector/riotx/features/home/room/list/actions/{RoomListQuickSharedAction.kt => RoomListQuickActionsSharedAction.kt} (80%) 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 23fabe4b97..f2bd02f9a3 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 @@ -39,7 +39,7 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.home.room.list.actions.RoomListQuickSharedAction +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsStore import im.vector.riotx.features.home.room.list.widget.FabMenuView @@ -216,24 +216,24 @@ class RoomListFragment @Inject constructor( } } - private fun handleQuickActions(quickAction: RoomListQuickSharedAction) { + private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) { when (quickAction) { - is RoomListQuickSharedAction.NotificationsAllNoisy -> { + is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) } - is RoomListQuickSharedAction.NotificationsAll -> { + is RoomListQuickActionsSharedAction.NotificationsAll -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) } - is RoomListQuickSharedAction.NotificationsMentionsOnly -> { + is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) } - is RoomListQuickSharedAction.NotificationsMute -> { + is RoomListQuickActionsSharedAction.NotificationsMute -> { roomListViewModel.accept(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) } - is RoomListQuickSharedAction.Settings -> { + is RoomListQuickActionsSharedAction.Settings -> { vectorBaseActivity.notImplemented("Opening room settings") } - is RoomListQuickSharedAction.Leave -> { + is RoomListQuickActionsSharedAction.Leave -> { AlertDialog.Builder(requireContext()) .setTitle(R.string.room_participants_leave_prompt_title) .setMessage(R.string.room_participants_leave_prompt_msg) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 50d0503693..d23183f077 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -82,7 +82,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R super.invalidate() } - override fun didSelectMenuAction(quickAction: RoomListQuickSharedAction) { + override fun didSelectMenuAction(quickAction: RoomListQuickActionsSharedAction) { actionsDispatcher.post(quickAction) dismiss() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index d54edce712..2e17464cc6 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -42,7 +42,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar roomName(roomSummary.displayName) avatarUrl(roomSummary.avatarUrl) roomId(roomSummary.roomId) - settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickSharedAction.Settings(roomSummary.roomId)) }) + settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Settings(roomSummary.roomId)) }) } // Notifications @@ -51,26 +51,26 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar } val selectedRoomState = state.roomNotificationState() - RoomListQuickSharedAction.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) - RoomListQuickSharedAction.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) - RoomListQuickSharedAction.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) - RoomListQuickSharedAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) + RoomListQuickActionsSharedAction.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState) + RoomListQuickActionsSharedAction.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState) + RoomListQuickActionsSharedAction.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState) + RoomListQuickActionsSharedAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) // Leave bottomSheetItemSeparator { id("leave_separator") } - RoomListQuickSharedAction.Leave(roomSummary.roomId).toBottomSheetItem(5) + RoomListQuickActionsSharedAction.Leave(roomSummary.roomId).toBottomSheetItem(5) } - private fun RoomListQuickSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { + private fun RoomListQuickActionsSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { val selected = when (this) { - is RoomListQuickSharedAction.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY - is RoomListQuickSharedAction.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES - is RoomListQuickSharedAction.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY - is RoomListQuickSharedAction.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE - is RoomListQuickSharedAction.Settings, - is RoomListQuickSharedAction.Leave -> false + is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY + is RoomListQuickActionsSharedAction.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES + is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY + is RoomListQuickActionsSharedAction.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE + is RoomListQuickActionsSharedAction.Settings, + is RoomListQuickActionsSharedAction.Leave -> false } return bottomSheetItemAction { id("action_$index") @@ -83,6 +83,6 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar } interface Listener { - fun didSelectMenuAction(quickAction: RoomListQuickSharedAction) + fun didSelectMenuAction(quickAction: RoomListQuickActionsSharedAction) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickSharedAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt similarity index 80% rename from vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickSharedAction.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt index 4033434327..5e0ca770dc 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickSharedAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt @@ -21,34 +21,34 @@ import androidx.annotation.StringRes import im.vector.riotx.R import im.vector.riotx.core.platform.VectorSharedAction -sealed class RoomListQuickSharedAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) : VectorSharedAction { +sealed class RoomListQuickActionsSharedAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) : VectorSharedAction { - data class NotificationsAllNoisy(val roomId: String) : RoomListQuickSharedAction( + data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_notifications_all_noisy, R.drawable.ic_room_actions_notifications_all_noisy ) - data class NotificationsAll(val roomId: String) : RoomListQuickSharedAction( + data class NotificationsAll(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_notifications_all, R.drawable.ic_room_actions_notifications_all ) - data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickSharedAction( + data class NotificationsMentionsOnly(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_notifications_mentions, R.drawable.ic_room_actions_notifications_mentions ) - data class NotificationsMute(val roomId: String) : RoomListQuickSharedAction( + data class NotificationsMute(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_notifications_mute, R.drawable.ic_room_actions_notifications_mutes ) - data class Settings(val roomId: String) : RoomListQuickSharedAction( + data class Settings(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_settings, R.drawable.ic_room_actions_settings ) - data class Leave(val roomId: String) : RoomListQuickSharedAction( + data class Leave(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_leave, R.drawable.ic_room_actions_leave, true diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt index 891ffc81f0..fb4b7c0455 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt @@ -21,4 +21,4 @@ import im.vector.riotx.core.platform.VectorSharedActionViewModel /** * Activity shared view model to handle room list quick actions */ -class RoomListQuickActionsStore : VectorSharedActionViewModel() +class RoomListQuickActionsStore : VectorSharedActionViewModel() From 17f361428865db04cb27cf4a7c716388d226284a Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 8 Nov 2019 13:48:35 +0100 Subject: [PATCH 084/117] Perf: try to optimize room summary updates --- .../internal/database/AsyncTransaction.kt | 7 ++++ .../session/room/RoomAvatarResolver.kt | 7 ++-- .../session/room/RoomSummaryUpdater.kt | 37 ++++++++++++------- .../room/membership/LoadRoomMembersTask.kt | 2 +- .../membership/RoomDisplayNameResolver.kt | 15 ++++---- .../internal/session/sync/RoomSyncHandler.kt | 19 +++++++--- 6 files changed, 57 insertions(+), 30 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt index 36e68e5cf3..af98f94146 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt @@ -20,14 +20,20 @@ import io.realm.RealmConfiguration import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext +import timber.log.Timber +import java.lang.RuntimeException suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> Unit) = withContext(Dispatchers.IO) { Realm.getInstance(config).use { bgRealm -> bgRealm.beginTransaction() try { + val start = System.currentTimeMillis() transaction(bgRealm) if (isActive) { bgRealm.commitTransaction() + val end = System.currentTimeMillis() + val time = end - start + Timber.v("Execute transaction in $time millis") } } finally { if (bgRealm.isInTransaction) { @@ -35,4 +41,5 @@ suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (r } } } + } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt index 0b18279aa8..070960fb91 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt @@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.RoomAvatarContent import im.vector.matrix.android.api.session.room.model.RoomMember +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields @@ -41,8 +42,8 @@ internal class RoomAvatarResolver @Inject constructor(private val monarchy: Mona fun resolve(roomId: String): String? { var res: String? = null monarchy.doWithRealm { realm -> - val roomName = EventEntity.where(realm, roomId, EventType.STATE_ROOM_AVATAR).prev()?.asDomain() - res = roomName?.content.toModel()?.avatarUrl + val roomName = EventEntity.where(realm, roomId, EventType.STATE_ROOM_AVATAR).prev() + res = ContentMapper.map(roomName?.content).toModel()?.avatarUrl if (!res.isNullOrEmpty()) { return@doWithRealm } @@ -60,6 +61,6 @@ internal class RoomAvatarResolver @Inject constructor(private val monarchy: Mona } private fun EventEntity?.toRoomMember(): RoomMember? { - return this?.asDomain()?.content?.toModel() + return ContentMapper.map(this?.content).toModel() } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt index 0d28720ec6..44794e307e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt @@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomTopicContent +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields @@ -65,8 +66,10 @@ internal class RoomSummaryUpdater @Inject constructor(@UserId private val userId roomId: String, membership: Membership? = null, roomSummary: RoomSyncSummary? = null, - unreadNotifications: RoomSyncUnreadNotifications? = null) { - val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) + unreadNotifications: RoomSyncUnreadNotifications? = null, + updateMembers: Boolean = false) { + val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() + ?: realm.createObject(roomId) if (roomSummary != null) { if (roomSummary.heroes.isNotEmpty()) { @@ -88,24 +91,30 @@ internal class RoomSummaryUpdater @Inject constructor(@UserId private val userId } val latestPreviewableEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true, filterTypes = PREVIEWABLE_TYPES) - val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain() + val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev() roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0 - // avoid this call if we are sure there are unread events - || !isEventRead(monarchy, userId, roomId, latestPreviewableEvent?.eventId) + // avoid this call if we are sure there are unread events + || !isEventRead(monarchy, userId, roomId, latestPreviewableEvent?.eventId) - val otherRoomMembers = RoomMembers(realm, roomId) - .queryRoomMembersEvent() - .notEqualTo(EventEntityFields.STATE_KEY, userId) - .findAll() - .asSequence() - .map { it.stateKey } roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString() roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId) - roomSummaryEntity.topic = lastTopicEvent?.content.toModel()?.topic + roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel()?.topic roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent - roomSummaryEntity.otherMemberIds.clear() - roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers) + + if (updateMembers) { + val otherRoomMembers = RoomMembers(realm, roomId) + .queryRoomMembersEvent() + .notEqualTo(EventEntityFields.STATE_KEY, userId) + .findAll() + .asSequence() + .map { it.stateKey } + + roomSummaryEntity.otherMemberIds.clear() + roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers) + } + + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/LoadRoomMembersTask.kt index d952915d2c..7d9332ee84 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/LoadRoomMembersTask.kt @@ -74,7 +74,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(private val roomAP it.updateSenderData() } roomEntity.areAllMembersLoaded = true - roomSummaryUpdater.update(realm, roomId) + roomSummaryUpdater.update(realm, roomId, updateMembers = true) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt index 965bd21cf4..365bde749a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt @@ -22,6 +22,7 @@ import im.vector.matrix.android.R import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.* +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields @@ -56,20 +57,20 @@ internal class RoomDisplayNameResolver @Inject constructor(private val context: var name: CharSequence? = null monarchy.doWithRealm { realm -> val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() - val roomName = EventEntity.where(realm, roomId, EventType.STATE_ROOM_NAME).prev()?.asDomain() - name = roomName?.content.toModel()?.name + val roomName = EventEntity.where(realm, roomId, EventType.STATE_ROOM_NAME).prev() + name = ContentMapper.map(roomName?.content).toModel()?.name if (!name.isNullOrEmpty()) { return@doWithRealm } - val canonicalAlias = EventEntity.where(realm, roomId, EventType.STATE_CANONICAL_ALIAS).prev()?.asDomain() - name = canonicalAlias?.content.toModel()?.canonicalAlias + val canonicalAlias = EventEntity.where(realm, roomId, EventType.STATE_CANONICAL_ALIAS).prev() + name = ContentMapper.map(canonicalAlias?.content).toModel()?.canonicalAlias if (!name.isNullOrEmpty()) { return@doWithRealm } - val aliases = EventEntity.where(realm, roomId, EventType.STATE_ROOM_ALIASES).prev()?.asDomain() - name = aliases?.content.toModel()?.aliases?.firstOrNull() + val aliases = EventEntity.where(realm, roomId, EventType.STATE_ROOM_ALIASES).prev() + name = ContentMapper.map(aliases?.content).toModel()?.aliases?.firstOrNull() if (!name.isNullOrEmpty()) { return@doWithRealm } @@ -132,6 +133,6 @@ internal class RoomDisplayNameResolver @Inject constructor(private val context: } private fun EventEntity?.toRoomMember(): RoomMember? { - return this?.asDomain()?.content?.toModel() + return ContentMapper.map(this?.content).toModel() } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 5fb25834c0..4a003eb7d9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -67,6 +67,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch } suspend fun handle(roomsSyncResponse: RoomsSyncResponse, isInitialSync: Boolean, reporter: DefaultInitialSyncProgressService? = null) { + Timber.v("Execute transaction from $this") monarchy.awaitTransaction { realm -> handleRoomSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), isInitialSync, reporter) handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), isInitialSync, reporter) @@ -133,6 +134,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch roomEntity.membership = Membership.JOIN // State event + if (roomSync.state != null && roomSync.state.events.isNotEmpty()) { val minStateIndex = roomEntity.untimelinedStateEvents.where().min(EventEntityFields.STATE_INDEX)?.toInt() ?: Int.MIN_VALUE @@ -146,7 +148,6 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch } } } - if (roomSync.timeline != null && roomSync.timeline.events.isNotEmpty()) { val chunkEntity = handleTimelineEvents( realm, @@ -157,14 +158,19 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch ) roomEntity.addOrUpdate(chunkEntity) } - roomSummaryUpdater.update(realm, roomId, Membership.JOIN, roomSync.summary, roomSync.unreadNotifications) + val hasRoomMember = roomSync.state?.events?.firstOrNull { + it.type == EventType.STATE_ROOM_MEMBER + } != null || roomSync.timeline?.events?.firstOrNull { + it.type == EventType.STATE_ROOM_MEMBER + } != null + + roomSummaryUpdater.update(realm, roomId, Membership.JOIN, roomSync.summary, roomSync.unreadNotifications, updateMembers = hasRoomMember) return roomEntity } private fun handleInvitedRoom(realm: Realm, roomId: String, - roomSync: - InvitedRoomSync): RoomEntity { + roomSync: InvitedRoomSync): RoomEntity { Timber.v("Handle invited sync for room $roomId") val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) roomEntity.membership = Membership.INVITE @@ -172,7 +178,10 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch val chunkEntity = handleTimelineEvents(realm, roomEntity, roomSync.inviteState.events) roomEntity.addOrUpdate(chunkEntity) } - roomSummaryUpdater.update(realm, roomId, Membership.INVITE) + val hasRoomMember = roomSync.inviteState?.events?.firstOrNull { + it.type == EventType.STATE_ROOM_MEMBER + } != null + roomSummaryUpdater.update(realm, roomId, Membership.INVITE, updateMembers = hasRoomMember) return roomEntity } From 70bce9e7dd1ec51faf5dc3239160360d36125acd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 15:05:11 +0100 Subject: [PATCH 085/117] Ensure ViewModel follow the same pattern to handle actions --- .../riotx/core/platform/VectorViewModel.kt | 8 +- .../settings/KeyBackupSettingsActions.kt | 25 ++++++ .../settings/KeysBackupManageActivity.kt | 2 +- .../settings/KeysBackupSettingsFragment.kt | 6 +- .../settings/KeysBackupSettingsViewModel.kt | 28 +++---- .../riotx/features/home/HomeDetailAction.kt | 24 ++++++ .../riotx/features/home/HomeDetailFragment.kt | 2 +- .../features/home/HomeDetailViewModel.kt | 17 ++-- .../createdirect/CreateDirectRoomActions.kt | 3 +- .../createdirect/CreateDirectRoomViewModel.kt | 4 +- .../features/home/group/GroupListActions.kt | 4 +- .../features/home/group/GroupListFragment.kt | 2 +- .../features/home/group/GroupListViewModel.kt | 4 +- .../home/room/detail/RoomDetailActions.kt | 4 +- .../home/room/detail/RoomDetailFragment.kt | 78 +++++++++---------- .../home/room/detail/RoomDetailViewModel.kt | 4 +- .../detail/composer/TextComposerActions.kt | 4 +- .../detail/composer/TextComposerViewModel.kt | 9 +-- .../action/MessageActionsBottomSheet.kt | 2 +- .../action/MessageActionsViewModel.kt | 20 +++-- .../edithistory/ViewEditHistoryViewModel.kt | 11 ++- .../reactions/ViewReactionsViewModel.kt | 22 +++--- .../home/room/list/RoomListActions.kt | 3 +- .../home/room/list/RoomListFragment.kt | 22 +++--- .../home/room/list/RoomListViewModel.kt | 4 +- .../actions/RoomListQuickActionsViewModel.kt | 11 ++- .../riotx/features/login/LoginActions.kt | 4 +- .../riotx/features/login/LoginViewModel.kt | 4 +- .../reactions/EmojiReactionPickerActivity.kt | 4 +- .../features/reactions/EmojiSearchActions.kt | 23 ++++++ .../reactions/EmojiSearchResultViewModel.kt | 16 ++-- .../roomdirectory/PublicRoomsFragment.kt | 8 +- .../roomdirectory/RoomDirectoryActions.kt | 28 +++++++ .../roomdirectory/RoomDirectoryActivity.kt | 5 +- .../roomdirectory/RoomDirectoryViewModel.kt | 43 ++++++---- .../createroom/CreateRoomActions.kt | 26 +++++++ .../createroom/CreateRoomActivity.kt | 2 +- .../createroom/CreateRoomFragment.kt | 12 +-- .../createroom/CreateRoomViewModel.kt | 19 +++-- .../picker/RoomDirectoryPickerActions.kt | 23 ++++++ .../picker/RoomDirectoryPickerFragment.kt | 5 +- .../picker/RoomDirectoryPickerViewModel.kt | 17 ++-- .../roompreview/RoomPreviewActions.kt | 23 ++++++ .../RoomPreviewNoPreviewFragment.kt | 2 +- .../roompreview/RoomPreviewViewModel.kt | 11 ++- .../settings/ignored/IgnoredUsersViewModel.kt | 8 +- .../settings/push/PushGatewaysViewModel.kt | 15 ++-- .../settings/push/PushRulesViewModel.kt | 8 +- .../features/share/IncomingShareViewModel.kt | 7 +- 49 files changed, 449 insertions(+), 187 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeyBackupSettingsActions.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchActions.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActions.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerActions.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActions.kt 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 + } } From a6fcc7dca6e38fbba7c7201dc3963cc0afcb75d6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 15:07:01 +0100 Subject: [PATCH 086/117] Move class to dedicated file --- .../timeline/action/MessageActionsActions.kt | 23 +++++++++++++++++++ .../action/MessageActionsBottomSheet.kt | 2 +- .../action/MessageActionsViewModel.kt | 11 +++------ 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.kt diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.kt new file mode 100644 index 0000000000..02c0eebe69 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.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.home.room.detail.timeline.action + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class MessageActionsActions : VectorViewModelAction { + object ToggleReportMenu : MessageActionsActions() +} 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 b98d74a8b4..84c8ed6886 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.handle(MessageActionActions.ToggleReportMenu) + viewModel.handle(MessageActionsActions.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 a65323f412..83045ce9bb 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,7 +37,6 @@ 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 @@ -77,10 +76,6 @@ 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 bottom sheet. */ @@ -90,7 +85,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 @@ -117,9 +112,9 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted observeEventAction() } - override fun handle(action: MessageActionActions) { + override fun handle(action: MessageActionsActions) { when (action) { - MessageActionActions.ToggleReportMenu -> toggleReportMenu() + MessageActionsActions.ToggleReportMenu -> toggleReportMenu() } } From f17564d743819e6c87b743dd92d9f23407ededa2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 15:08:50 +0100 Subject: [PATCH 087/117] Simple code --- .../features/roomdirectory/PublicRoomsFragment.kt | 2 +- .../features/roomdirectory/RoomDirectoryActions.kt | 3 +-- .../features/roomdirectory/RoomDirectoryViewModel.kt | 12 +++++------- 3 files changed, 7 insertions(+), 10 deletions(-) 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 b0198b39c4..ea46671e12 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 @@ -130,7 +130,7 @@ class PublicRoomsFragment @Inject constructor( override fun onPublicRoomJoin(publicRoom: PublicRoom) { Timber.v("PublicRoomJoinClicked: $publicRoom") - viewModel.handle(RoomDirectoryActions.JoinRoom(publicRoom)) + viewModel.handle(RoomDirectoryActions.JoinRoom(publicRoom.roomId)) } override fun loadMore() { 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 index 198426bc1d..0bb6658f2b 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt @@ -16,7 +16,6 @@ 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 @@ -24,5 +23,5 @@ 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() + data class JoinRoom(val roomId: String) : RoomDirectoryActions() } 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 d092453ba8..085d5dfe5f 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 @@ -202,9 +202,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: } private fun joinRoom(action: RoomDirectoryActions.JoinRoom) = withState { state -> - val roomId = action.publicRoom.roomId - - if (state.joiningRoomsIds.contains(roomId)) { + if (state.joiningRoomsIds.contains(action.roomId)) { // Request already sent, should not happen Timber.w("Try to join an already joining room. Should not happen") return@withState @@ -212,11 +210,11 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: setState { copy( - joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { add(roomId) } + joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { add(action.roomId) } ) } - session.joinRoom(roomId, emptyList(), object : MatrixCallback { + session.joinRoom(action.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 @@ -228,8 +226,8 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: setState { copy( - joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { remove(roomId) }, - joiningErrorRoomsIds = joiningErrorRoomsIds.toMutableSet().apply { add(roomId) } + joiningRoomsIds = joiningRoomsIds.toMutableSet().apply { remove(action.roomId) }, + joiningErrorRoomsIds = joiningErrorRoomsIds.toMutableSet().apply { add(action.roomId) } ) } } From 12376368c790e0272952d23a09e06fc57c1b5cef Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 15:20:46 +0100 Subject: [PATCH 088/117] Rename class --- .../riotx/core/platform/VectorViewModel.kt | 4 - .../core/platform/VectorViewModelAction.kt | 24 ++++ ...sActions.kt => KeyBackupSettingsAction.kt} | 8 +- .../settings/KeysBackupManageActivity.kt | 2 +- .../settings/KeysBackupSettingsFragment.kt | 6 +- .../settings/KeysBackupSettingsViewModel.kt | 10 +- ...omActions.kt => CreateDirectRoomAction.kt} | 14 +-- .../CreateDirectRoomDirectoryUsersFragment.kt | 6 +- .../CreateDirectRoomKnownUsersFragment.kt | 10 +- .../createdirect/CreateDirectRoomViewModel.kt | 20 +-- ...GroupListActions.kt => GroupListAction.kt} | 4 +- .../features/home/group/GroupListFragment.kt | 2 +- .../features/home/group/GroupListViewModel.kt | 8 +- ...omDetailActions.kt => RoomDetailAction.kt} | 56 ++++----- .../home/room/detail/RoomDetailFragment.kt | 82 ++++++------- .../home/room/detail/RoomDetailViewModel.kt | 114 +++++++++--------- ...mposerActions.kt => TextComposerAction.kt} | 4 +- .../detail/composer/TextComposerViewModel.kt | 8 +- ...ionsActions.kt => MessageActionsAction.kt} | 4 +- .../action/MessageActionsBottomSheet.kt | 2 +- .../action/MessageActionsViewModel.kt | 6 +- .../{RoomListActions.kt => RoomListAction.kt} | 18 +-- .../home/room/list/RoomListFragment.kt | 22 ++-- .../home/room/list/RoomListViewModel.kt | 34 +++--- .../login/{LoginActions.kt => LoginAction.kt} | 12 +- .../riotx/features/login/LoginActivity.kt | 2 +- .../riotx/features/login/LoginFragment.kt | 10 +- .../login/LoginSsoFallbackFragment.kt | 6 +- .../riotx/features/login/LoginViewModel.kt | 24 ++-- .../reactions/EmojiReactionPickerActivity.kt | 2 +- ...iSearchActions.kt => EmojiSearchAction.kt} | 4 +- .../reactions/EmojiSearchResultViewModel.kt | 8 +- .../roomdirectory/PublicRoomsFragment.kt | 6 +- ...ctoryActions.kt => RoomDirectoryAction.kt} | 10 +- .../roomdirectory/RoomDirectoryActivity.kt | 6 +- .../roomdirectory/RoomDirectoryViewModel.kt | 18 +-- ...eateRoomActions.kt => CreateRoomAction.kt} | 10 +- .../createroom/CreateRoomActivity.kt | 2 +- .../createroom/CreateRoomFragment.kt | 10 +- .../createroom/CreateRoomViewModel.kt | 18 +-- ...ctions.kt => RoomDirectoryPickerAction.kt} | 4 +- .../picker/RoomDirectoryPickerFragment.kt | 6 +- .../picker/RoomDirectoryPickerViewModel.kt | 6 +- ...PreviewActions.kt => RoomPreviewAction.kt} | 4 +- .../RoomPreviewNoPreviewFragment.kt | 2 +- .../roompreview/RoomPreviewViewModel.kt | 6 +- 46 files changed, 332 insertions(+), 312 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/core/platform/VectorViewModelAction.kt rename vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/{KeyBackupSettingsActions.kt => KeyBackupSettingsAction.kt} (76%) rename vector/src/main/java/im/vector/riotx/features/home/createdirect/{CreateDirectRoomActions.kt => CreateDirectRoomAction.kt} (85%) rename vector/src/main/java/im/vector/riotx/features/home/group/{GroupListActions.kt => GroupListAction.kt} (92%) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/{RoomDetailActions.kt => RoomDetailAction.kt} (75%) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/{TextComposerActions.kt => TextComposerAction.kt} (91%) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/{MessageActionsActions.kt => MessageActionsAction.kt} (86%) rename vector/src/main/java/im/vector/riotx/features/home/room/list/{RoomListActions.kt => RoomListAction.kt} (76%) rename vector/src/main/java/im/vector/riotx/features/login/{LoginActions.kt => LoginAction.kt} (90%) rename vector/src/main/java/im/vector/riotx/features/reactions/{EmojiSearchActions.kt => EmojiSearchAction.kt} (91%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/{RoomDirectoryActions.kt => RoomDirectoryAction.kt} (86%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/{CreateRoomActions.kt => CreateRoomAction.kt} (81%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/{RoomDirectoryPickerActions.kt => RoomDirectoryPickerAction.kt} (86%) rename vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/{RoomPreviewActions.kt => RoomPreviewAction.kt} (88%) 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 949ac4cdb9..74b18be3c2 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,10 +23,6 @@ import im.vector.riotx.core.utils.LiveEvent import io.reactivex.Observable import io.reactivex.Single -interface VectorViewModelAction - -object EmptyAction : VectorViewModelAction - abstract class VectorViewModel(initialState: S) : BaseMvRxViewModel(initialState, false) { diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModelAction.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModelAction.kt new file mode 100644 index 0000000000..81c1996497 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorViewModelAction.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.core.platform + +interface VectorViewModelAction + +/** + * To use when no action is associated to the ViewModel + */ +object EmptyAction : VectorViewModelAction 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/KeyBackupSettingsAction.kt similarity index 76% rename from vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeyBackupSettingsActions.kt rename to vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/settings/KeyBackupSettingsAction.kt index 5ced274b21..723be80dfd 100644 --- 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/KeyBackupSettingsAction.kt @@ -18,8 +18,8 @@ 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() +sealed class KeyBackupSettingsAction : VectorViewModelAction { + object Init : KeyBackupSettingsAction() + object GetKeyBackupTrust : KeyBackupSettingsAction() + object DeleteKeyBackup : KeyBackupSettingsAction() } 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 0d0ce551aa..98e954c5b5 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.handle(KeyBackupSettingsActions.Init) + viewModel.handle(KeyBackupSettingsAction.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 d281cd253f..9994ee5002 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.handle(KeyBackupSettingsActions.DeleteKeyBackup) + viewModel.handle(KeyBackupSettingsAction.DeleteKeyBackup) } .setNegativeButton(R.string.cancel, null) .setCancelable(true) @@ -75,10 +75,10 @@ class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSetti } override fun loadTrustData() { - viewModel.handle(KeyBackupSettingsActions.GetKeyBackupTrust) + viewModel.handle(KeyBackupSettingsAction.GetKeyBackupTrust) } override fun loadKeysBackupState() { - viewModel.handle(KeyBackupSettingsActions.Init) + viewModel.handle(KeyBackupSettingsAction.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 95b761291c..4acb318033 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 @@ -28,7 +28,7 @@ import im.vector.riotx.core.platform.VectorViewModel class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, session: Session -) : VectorViewModel(initialState), +) : VectorViewModel(initialState), KeysBackupStateListener { @AssistedInject.Factory @@ -58,11 +58,11 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS getKeysBackupTrust() } - override fun handle(action: KeyBackupSettingsActions) { + override fun handle(action: KeyBackupSettingsAction) { when (action) { - KeyBackupSettingsActions.Init -> init() - KeyBackupSettingsActions.GetKeyBackupTrust -> getKeysBackupTrust() - KeyBackupSettingsActions.DeleteKeyBackup -> deleteCurrentBackup() + KeyBackupSettingsAction.Init -> init() + KeyBackupSettingsAction.GetKeyBackupTrust -> getKeysBackupTrust() + KeyBackupSettingsAction.DeleteKeyBackup -> deleteCurrentBackup() } } 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/CreateDirectRoomAction.kt similarity index 85% rename from vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomAction.kt index 17aadcff35..8410a95707 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/CreateDirectRoomAction.kt @@ -19,11 +19,11 @@ 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 : VectorViewModelAction { - object CreateRoomAndInviteSelectedUsers : CreateDirectRoomActions() - data class FilterKnownUsers(val value: String) : CreateDirectRoomActions() - data class SearchDirectoryUsers(val value: String) : CreateDirectRoomActions() - object ClearFilterKnownUsers : CreateDirectRoomActions() - data class SelectUser(val user: User) : CreateDirectRoomActions() - data class RemoveSelectedUser(val user: User) : CreateDirectRoomActions() +sealed class CreateDirectRoomAction : VectorViewModelAction { + object CreateRoomAndInviteSelectedUsers : CreateDirectRoomAction() + data class FilterKnownUsers(val value: String) : CreateDirectRoomAction() + data class SearchDirectoryUsers(val value: String) : CreateDirectRoomAction() + object ClearFilterKnownUsers : CreateDirectRoomAction() + data class SelectUser(val user: User) : CreateDirectRoomAction() + data class RemoveSelectedUser(val user: User) : CreateDirectRoomAction() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 7e8e5a16d4..23bff0fced 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -60,7 +60,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( createDirectRoomSearchById .textChanges() .subscribe { - viewModel.handle(CreateDirectRoomActions.SearchDirectoryUsers(it.toString())) + viewModel.handle(CreateDirectRoomAction.SearchDirectoryUsers(it.toString())) } .disposeOnDestroy() createDirectRoomSearchById.requestFocus() @@ -80,12 +80,12 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( override fun onItemClick(user: User) { view?.hideKeyboard() - viewModel.handle(CreateDirectRoomActions.SelectUser(user)) + viewModel.handle(CreateDirectRoomAction.SelectUser(user)) actionViewModel.post(CreateDirectRoomSharedAction.GoBack) } override fun retryDirectoryUsersRequest() { val currentSearch = createDirectRoomSearchById.text.toString() - viewModel.handle(CreateDirectRoomActions.SearchDirectoryUsers(currentSearch)) + viewModel.handle(CreateDirectRoomAction.SearchDirectoryUsers(currentSearch)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index bbfab88528..24fea9e42c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -79,7 +79,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_create_direct_room -> { - viewModel.handle(CreateDirectRoomActions.CreateRoomAndInviteSelectedUsers) + viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers) true } else -> @@ -108,9 +108,9 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( .subscribe { text -> val filterValue = text.trim() val action = if (filterValue.isBlank()) { - CreateDirectRoomActions.ClearFilterKnownUsers + CreateDirectRoomAction.ClearFilterKnownUsers } else { - CreateDirectRoomActions.FilterKnownUsers(filterValue.toString()) + CreateDirectRoomAction.FilterKnownUsers(filterValue.toString()) } viewModel.handle(action) } @@ -157,7 +157,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( chip.isCloseIconVisible = true chipGroup.addView(chip) chip.setOnCloseIconClickListener { - viewModel.handle(CreateDirectRoomActions.RemoveSelectedUser(user)) + viewModel.handle(CreateDirectRoomAction.RemoveSelectedUser(user)) } chipGroupScrollView.post { chipGroupScrollView.fullScroll(ScrollView.FOCUS_DOWN) @@ -166,6 +166,6 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( override fun onItemClick(user: User) { view?.hideKeyboard() - viewModel.handle(CreateDirectRoomActions.SelectUser(user)) + viewModel.handle(CreateDirectRoomAction.SelectUser(user)) } } 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 776a044230..f4cd81436c 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,14 +79,14 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted observeDirectoryUsers() } - override fun handle(action: CreateDirectRoomActions) { + override fun handle(action: CreateDirectRoomAction) { when (action) { - is CreateDirectRoomActions.CreateRoomAndInviteSelectedUsers -> createRoomAndInviteSelectedUsers() - is CreateDirectRoomActions.FilterKnownUsers -> knownUsersFilter.accept(Option.just(action.value)) - is CreateDirectRoomActions.ClearFilterKnownUsers -> knownUsersFilter.accept(Option.empty()) - is CreateDirectRoomActions.SearchDirectoryUsers -> directoryUsersSearch.accept(action.value) - is CreateDirectRoomActions.SelectUser -> handleSelectUser(action) - is CreateDirectRoomActions.RemoveSelectedUser -> handleRemoveSelectedUser(action) + is CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers -> createRoomAndInviteSelectedUsers() + is CreateDirectRoomAction.FilterKnownUsers -> knownUsersFilter.accept(Option.just(action.value)) + is CreateDirectRoomAction.ClearFilterKnownUsers -> knownUsersFilter.accept(Option.empty()) + is CreateDirectRoomAction.SearchDirectoryUsers -> directoryUsersSearch.accept(action.value) + is CreateDirectRoomAction.SelectUser -> handleSelectUser(action) + is CreateDirectRoomAction.RemoveSelectedUser -> handleRemoveSelectedUser(action) } } @@ -105,14 +105,14 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted } } - private fun handleRemoveSelectedUser(action: CreateDirectRoomActions.RemoveSelectedUser) = withState { state -> + private fun handleRemoveSelectedUser(action: CreateDirectRoomAction.RemoveSelectedUser) = withState { state -> val index = state.selectedUsers.indexOfFirst { it.userId == action.user.userId } val selectedUsers = state.selectedUsers.minus(action.user) setState { copy(selectedUsers = selectedUsers) } _selectUserEvent.postLiveEvent(SelectUserAction(action.user, false, index)) } - private fun handleSelectUser(action: CreateDirectRoomActions.SelectUser) = withState { state -> + private fun handleSelectUser(action: CreateDirectRoomAction.SelectUser) = withState { state -> // Reset the filter asap directoryUsersSearch.accept("") val isAddOperation: Boolean 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/GroupListAction.kt similarity index 92% rename from vector/src/main/java/im/vector/riotx/features/home/group/GroupListActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/group/GroupListAction.kt index 74fc7ec76b..e81890e7f2 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/GroupListAction.kt @@ -19,6 +19,6 @@ 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 : VectorViewModelAction { - data class SelectGroup(val groupSummary: GroupSummary) : GroupListActions() +sealed class GroupListAction : VectorViewModelAction { + data class SelectGroup(val groupSummary: GroupSummary) : GroupListAction() } 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 d5951830b2..5875336d69 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.handle(GroupListActions.SelectGroup(groupSummary)) + viewModel.handle(GroupListAction.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 715bb857b4..d9a38d5d9b 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,15 +81,15 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro } } - override fun handle(action: GroupListActions) { + override fun handle(action: GroupListAction) { when (action) { - is GroupListActions.SelectGroup -> handleSelectGroup(action) + is GroupListAction.SelectGroup -> handleSelectGroup(action) } } // PRIVATE METHODS ***************************************************************************** - private fun handleSelectGroup(action: GroupListActions.SelectGroup) = withState { state -> + private fun handleSelectGroup(action: GroupListAction.SelectGroup) = withState { state -> if (state.selectedGroup?.groupId != action.groupSummary.groupId) { setState { copy(selectedGroup = action.groupSummary) } } 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/RoomDetailAction.kt similarity index 75% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt index 45d08820e4..b37d03097c 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/RoomDetailAction.kt @@ -23,42 +23,42 @@ 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 : 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() - data class TimelineEventTurnsVisible(val event: TimelineEvent) : RoomDetailActions() - data class TimelineEventTurnsInvisible(val event: TimelineEvent) : RoomDetailActions() - data class LoadMoreTimelineEvents(val direction: Timeline.Direction) : RoomDetailActions() - data class SendReaction(val targetEventId: String, val reaction: String) : RoomDetailActions() - data class UndoReaction(val targetEventId: String, val reaction: String, val reason: String? = "") : RoomDetailActions() - data class RedactAction(val targetEventId: String, val reason: String? = "") : RoomDetailActions() - data class UpdateQuickReactAction(val targetEventId: String, val selectedReaction: String, val add: Boolean) : RoomDetailActions() - data class NavigateToEvent(val eventId: String, val highlight: Boolean) : RoomDetailActions() - data class SetReadMarkerAction(val eventId: String) : RoomDetailActions() - object MarkAllAsRead : RoomDetailActions() - data class DownloadFile(val eventId: String, val messageFileContent: MessageFileContent) : RoomDetailActions() - data class HandleTombstoneEvent(val event: Event) : RoomDetailActions() - object AcceptInvite : RoomDetailActions() - object RejectInvite : RoomDetailActions() +sealed class RoomDetailAction : VectorViewModelAction { + data class SaveDraft(val draft: String) : RoomDetailAction() + data class SendMessage(val text: String, val autoMarkdown: Boolean) : RoomDetailAction() + data class SendMedia(val attachments: List) : RoomDetailAction() + data class TimelineEventTurnsVisible(val event: TimelineEvent) : RoomDetailAction() + data class TimelineEventTurnsInvisible(val event: TimelineEvent) : RoomDetailAction() + data class LoadMoreTimelineEvents(val direction: Timeline.Direction) : RoomDetailAction() + data class SendReaction(val targetEventId: String, val reaction: String) : RoomDetailAction() + data class UndoReaction(val targetEventId: String, val reaction: String, val reason: String? = "") : RoomDetailAction() + data class RedactAction(val targetEventId: String, val reason: String? = "") : RoomDetailAction() + data class UpdateQuickReactAction(val targetEventId: String, val selectedReaction: String, val add: Boolean) : RoomDetailAction() + data class NavigateToEvent(val eventId: String, val highlight: Boolean) : RoomDetailAction() + data class SetReadMarkerAction(val eventId: String) : RoomDetailAction() + object MarkAllAsRead : RoomDetailAction() + data class DownloadFile(val eventId: String, val messageFileContent: MessageFileContent) : RoomDetailAction() + data class HandleTombstoneEvent(val event: Event) : RoomDetailAction() + object AcceptInvite : RoomDetailAction() + object RejectInvite : RoomDetailAction() - data class EnterEditMode(val eventId: String, val draft: String) : RoomDetailActions() - data class EnterQuoteMode(val eventId: String, val draft: String) : RoomDetailActions() - data class EnterReplyMode(val eventId: String, val draft: String) : RoomDetailActions() - data class ExitSpecialMode(val draft: String) : RoomDetailActions() + data class EnterEditMode(val eventId: String, val draft: String) : RoomDetailAction() + data class EnterQuoteMode(val eventId: String, val draft: String) : RoomDetailAction() + data class EnterReplyMode(val eventId: String, val draft: String) : RoomDetailAction() + data class ExitSpecialMode(val draft: String) : RoomDetailAction() - data class ResendMessage(val eventId: String) : RoomDetailActions() - data class RemoveFailedEcho(val eventId: String) : RoomDetailActions() + data class ResendMessage(val eventId: String) : RoomDetailAction() + data class RemoveFailedEcho(val eventId: String) : RoomDetailAction() data class ReportContent( val eventId: String, val senderId: String?, val reason: String, val spam: Boolean = false, - val inappropriate: Boolean = false) : RoomDetailActions() + val inappropriate: Boolean = false) : RoomDetailAction() - data class IgnoreUser(val userId: String?) : RoomDetailActions() + data class IgnoreUser(val userId: String?) : RoomDetailAction() - object ClearSendQueue : RoomDetailActions() - object ResendAll : RoomDetailActions() + object ClearSendQueue : RoomDetailAction() + object ResendAll : RoomDetailAction() } 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 1090dedd8a..681952f4d4 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 @@ -91,7 +91,7 @@ import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.NavigateToRoomInterceptor import im.vector.riotx.features.home.PermalinkHandler import im.vector.riotx.features.home.getColorFromUserId -import im.vector.riotx.features.home.room.detail.composer.TextComposerActions +import im.vector.riotx.features.home.room.detail.composer.TextComposerAction import im.vector.riotx.features.home.room.detail.composer.TextComposerView import im.vector.riotx.features.home.room.detail.composer.TextComposerViewModel import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState @@ -278,8 +278,8 @@ class RoomDetailFragment @Inject constructor( if (savedInstanceState == null) { when (val sharedData = roomDetailArgs.sharedData) { - is SharedData.Text -> roomDetailViewModel.handle(RoomDetailActions.SendMessage(sharedData.text, false)) - is SharedData.Attachments -> roomDetailViewModel.handle(RoomDetailActions.SendMedia(sharedData.attachmentData)) + is SharedData.Text -> roomDetailViewModel.handle(RoomDetailAction.SendMessage(sharedData.text, false)) + is SharedData.Attachments -> roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.HandleTombstoneEvent(tombstoneEvent)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.ClearSendQueue) + roomDetailViewModel.handle(RoomDetailAction.ClearSendQueue) return true } if (item.itemId == R.id.resend_all) { - roomDetailViewModel.handle(RoomDetailActions.ResendAll) + roomDetailViewModel.handle(RoomDetailAction.ResendAll) return true } return super.onOptionsItemSelected(item) @@ -427,7 +427,7 @@ class RoomDetailFragment @Inject constructor( notificationDrawerManager.setCurrentRoom(null) - roomDetailViewModel.handle(RoomDetailActions.SaveDraft(composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.SendReaction(eventId, reaction)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.EnterReplyMode(eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.SendMessage(textMessage, vectorPreferences.isMarkdownEnabled())) + roomDetailViewModel.handle(RoomDetailAction.SendMessage(textMessage, vectorPreferences.isMarkdownEnabled())) } } composerLayout.composerRelatedMessageCloseButton.setOnClickListener { - roomDetailViewModel.handle(RoomDetailActions.ExitSpecialMode(composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailAction.ExitSpecialMode(composerLayout.composerEditText.text.toString())) } composerLayout.callback = object : TextComposerView.Callback { override fun onRichContentSelected(contentUri: Uri): Boolean { @@ -760,13 +760,13 @@ class RoomDetailFragment @Inject constructor( .setView(layout) .setPositiveButton(R.string.report_content_custom_submit) { _, _ -> val reason = input.text.toString() - roomDetailViewModel.handle(RoomDetailActions.ReportContent(action.eventId, action.senderId, reason)) + roomDetailViewModel.handle(RoomDetailAction.ReportContent(action.eventId, action.senderId, reason)) } .setNegativeButton(R.string.cancel, null) .show() } - private fun displayRoomDetailActionResult(result: Async) { + private fun displayRoomDetailActionResult(result: Async) { when (result) { is Fail -> { AlertDialog.Builder(requireActivity()) @@ -777,7 +777,7 @@ class RoomDetailFragment @Inject constructor( } is Success -> { when (val data = result.invoke()) { - is RoomDetailActions.ReportContent -> { + is RoomDetailAction.ReportContent -> { when { data.spam -> { AlertDialog.Builder(requireActivity()) @@ -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.handle(RoomDetailActions.IgnoreUser(data.senderId)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.IgnoreUser(data.senderId)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.IgnoreUser(data.senderId)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.NavigateToEvent(eventId, true)) + roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(eventId, true)) } return true } @@ -859,11 +859,11 @@ class RoomDetailFragment @Inject constructor( } override fun onEventVisible(event: TimelineEvent) { - roomDetailViewModel.handle(RoomDetailActions.TimelineEventTurnsVisible(event)) + roomDetailViewModel.handle(RoomDetailAction.TimelineEventTurnsVisible(event)) } override fun onEventInvisible(event: TimelineEvent) { - roomDetailViewModel.handle(RoomDetailActions.TimelineEventTurnsInvisible(event)) + roomDetailViewModel.handle(RoomDetailAction.TimelineEventTurnsInvisible(event)) } override fun onEncryptedMessageClicked(informationData: MessageInformationData, view: View) { @@ -899,7 +899,7 @@ class RoomDetailFragment @Inject constructor( } override fun onFileMessageClicked(eventId: String, messageFileContent: MessageFileContent) { - val action = RoomDetailActions.DownloadFile(eventId, messageFileContent) + val action = RoomDetailAction.DownloadFile(eventId, messageFileContent) // We need WRITE_EXTERNAL permission if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, PERMISSION_REQUEST_CODE_DOWNLOAD_FILE)) { roomDetailViewModel.handle(action) @@ -946,7 +946,7 @@ class RoomDetailFragment @Inject constructor( } override fun onLoadMore(direction: Timeline.Direction) { - roomDetailViewModel.handle(RoomDetailActions.LoadMoreTimelineEvents(direction)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.SendReaction(informationData.eventId, reaction)) + roomDetailViewModel.handle(RoomDetailAction.SendReaction(informationData.eventId, reaction)) } else { // I need to redact a reaction - roomDetailViewModel.handle(RoomDetailActions.UndoReaction(informationData.eventId, reaction)) + roomDetailViewModel.handle(RoomDetailAction.UndoReaction(informationData.eventId, reaction)) } } @@ -1027,14 +1027,14 @@ class RoomDetailFragment @Inject constructor( } } if (nextReadMarkerId != null) { - roomDetailViewModel.handle(RoomDetailActions.SetReadMarkerAction(nextReadMarkerId)) + roomDetailViewModel.handle(RoomDetailAction.SetReadMarkerAction(nextReadMarkerId)) } } // AutocompleteUserPresenter.Callback override fun onQueryUsers(query: CharSequence?) { - textComposerViewModel.handle(TextComposerActions.QueryUsers(query)) + textComposerViewModel.handle(TextComposerAction.QueryUsers(query)) } private fun handleActions(action: EventSharedAction) { @@ -1053,7 +1053,7 @@ class RoomDetailFragment @Inject constructor( showSnackWithMessage(msg, Snackbar.LENGTH_SHORT) } is EventSharedAction.Delete -> { - roomDetailViewModel.handle(RoomDetailActions.RedactAction(action.eventId, context?.getString(R.string.event_redacted_by_user_reason))) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) + roomDetailViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add)) } is EventSharedAction.Edit -> { - roomDetailViewModel.handle(RoomDetailActions.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailAction.EnterEditMode(action.eventId, composerLayout.composerEditText.text.toString())) } is EventSharedAction.Quote -> { - roomDetailViewModel.handle(RoomDetailActions.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailAction.EnterQuoteMode(action.eventId, composerLayout.composerEditText.text.toString())) } is EventSharedAction.Reply -> { - roomDetailViewModel.handle(RoomDetailActions.EnterReplyMode(action.eventId, composerLayout.composerEditText.text.toString())) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.ResendMessage(action.eventId)) + roomDetailViewModel.handle(RoomDetailAction.ResendMessage(action.eventId)) } is EventSharedAction.Remove -> { - roomDetailViewModel.handle(RoomDetailActions.RemoveFailedEcho(action.eventId)) + roomDetailViewModel.handle(RoomDetailAction.RemoveFailedEcho(action.eventId)) } is EventSharedAction.ReportContentSpam -> { - roomDetailViewModel.handle(RoomDetailActions.ReportContent( + roomDetailViewModel.handle(RoomDetailAction.ReportContent( action.eventId, action.senderId, "This message is spam", spam = true)) } is EventSharedAction.ReportContentInappropriate -> { - roomDetailViewModel.handle(RoomDetailActions.ReportContent( + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.AcceptInvite) + roomDetailViewModel.handle(RoomDetailAction.AcceptInvite) } override fun onRejectInvite() { notificationDrawerManager.clearMemberShipNotificationForRoom(roomDetailArgs.roomId) - roomDetailViewModel.handle(RoomDetailActions.RejectInvite) + roomDetailViewModel.handle(RoomDetailAction.RejectInvite) } // JumpToReadMarkerView.Callback override fun onJumpToReadMarkerClicked(readMarkerId: String) { - roomDetailViewModel.handle(RoomDetailActions.NavigateToEvent(readMarkerId, false)) + roomDetailViewModel.handle(RoomDetailAction.NavigateToEvent(readMarkerId, false)) } override fun onClearReadMarkerClicked() { - roomDetailViewModel.handle(RoomDetailActions.MarkAllAsRead) + roomDetailViewModel.handle(RoomDetailAction.MarkAllAsRead) } // AttachmentTypeSelectorView.Callback @@ -1252,7 +1252,7 @@ class RoomDetailFragment @Inject constructor( // AttachmentsHelper.Callback override fun onContentAttachmentsReady(attachments: List) { - roomDetailViewModel.handle(RoomDetailActions.SendMedia(attachments)) + roomDetailViewModel.handle(RoomDetailAction.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.handle(RoomDetailActions.SendMessage(formattedContact, false)) + roomDetailViewModel.handle(RoomDetailAction.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 c3b3edde65..dec77aa1c1 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,12 +69,12 @@ 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 - private val invisibleEventsObservable = BehaviorRelay.create() - private val visibleEventsObservable = BehaviorRelay.create() + private val invisibleEventsObservable = BehaviorRelay.create() + private val visibleEventsObservable = BehaviorRelay.create() private val timelineSettings = if (userPreferencesProvider.shouldShowHiddenEvents()) { TimelineSettings(30, filterEdits = false, @@ -92,12 +92,12 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private var timeline = room.createTimeline(eventId, timelineSettings) // Can be used for several actions, for a one shot result - private val _requestLiveData = MutableLiveData>>() - val requestLiveData: LiveData>> + private val _requestLiveData = MutableLiveData>>() + val requestLiveData: LiveData>> get() = _requestLiveData // Slot to keep a pending action during permission request - var pendingAction: RoomDetailActions? = null + var pendingAction: RoomDetailAction? = null // Slot to keep a pending uri during permission request var pendingUri: Uri? = null @@ -129,46 +129,46 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro setState { copy(timeline = this@RoomDetailViewModel.timeline) } } - override fun handle(action: RoomDetailActions) { + override fun handle(action: RoomDetailAction) { when (action) { - is RoomDetailActions.SaveDraft -> handleSaveDraft(action) - is RoomDetailActions.SendMessage -> handleSendMessage(action) - is RoomDetailActions.SendMedia -> handleSendMedia(action) - is RoomDetailActions.TimelineEventTurnsVisible -> handleEventVisible(action) - is RoomDetailActions.TimelineEventTurnsInvisible -> handleEventInvisible(action) - is RoomDetailActions.LoadMoreTimelineEvents -> handleLoadMore(action) - is RoomDetailActions.SendReaction -> handleSendReaction(action) - is RoomDetailActions.AcceptInvite -> handleAcceptInvite() - is RoomDetailActions.RejectInvite -> handleRejectInvite() - is RoomDetailActions.RedactAction -> handleRedactEvent(action) - is RoomDetailActions.UndoReaction -> handleUndoReact(action) - is RoomDetailActions.UpdateQuickReactAction -> handleUpdateQuickReaction(action) - is RoomDetailActions.ExitSpecialMode -> handleExitSpecialMode(action) - is RoomDetailActions.EnterEditMode -> handleEditAction(action) - is RoomDetailActions.EnterQuoteMode -> handleQuoteAction(action) - is RoomDetailActions.EnterReplyMode -> handleReplyAction(action) - is RoomDetailActions.DownloadFile -> handleDownloadFile(action) - is RoomDetailActions.NavigateToEvent -> handleNavigateToEvent(action) - is RoomDetailActions.HandleTombstoneEvent -> handleTombstoneEvent(action) - is RoomDetailActions.ResendMessage -> handleResendEvent(action) - is RoomDetailActions.RemoveFailedEcho -> handleRemove(action) - is RoomDetailActions.ClearSendQueue -> handleClearSendQueue() - is RoomDetailActions.ResendAll -> handleResendAll() - is RoomDetailActions.SetReadMarkerAction -> handleSetReadMarkerAction(action) - is RoomDetailActions.MarkAllAsRead -> handleMarkAllAsRead() - is RoomDetailActions.ReportContent -> handleReportContent(action) - is RoomDetailActions.IgnoreUser -> handleIgnoreUser(action) + is RoomDetailAction.SaveDraft -> handleSaveDraft(action) + is RoomDetailAction.SendMessage -> handleSendMessage(action) + is RoomDetailAction.SendMedia -> handleSendMedia(action) + is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action) + is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action) + is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action) + is RoomDetailAction.SendReaction -> handleSendReaction(action) + is RoomDetailAction.AcceptInvite -> handleAcceptInvite() + is RoomDetailAction.RejectInvite -> handleRejectInvite() + is RoomDetailAction.RedactAction -> handleRedactEvent(action) + is RoomDetailAction.UndoReaction -> handleUndoReact(action) + is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action) + is RoomDetailAction.ExitSpecialMode -> handleExitSpecialMode(action) + is RoomDetailAction.EnterEditMode -> handleEditAction(action) + is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action) + is RoomDetailAction.EnterReplyMode -> handleReplyAction(action) + is RoomDetailAction.DownloadFile -> handleDownloadFile(action) + is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action) + is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action) + is RoomDetailAction.ResendMessage -> handleResendEvent(action) + is RoomDetailAction.RemoveFailedEcho -> handleRemove(action) + is RoomDetailAction.ClearSendQueue -> handleClearSendQueue() + is RoomDetailAction.ResendAll -> handleResendAll() + is RoomDetailAction.SetReadMarkerAction -> handleSetReadMarkerAction(action) + is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead() + is RoomDetailAction.ReportContent -> handleReportContent(action) + is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action) } } - private fun handleEventInvisible(action: RoomDetailActions.TimelineEventTurnsInvisible) { + private fun handleEventInvisible(action: RoomDetailAction.TimelineEventTurnsInvisible) { invisibleEventsObservable.accept(action) } /** * Convert a send mode to a draft and save the draft */ - private fun handleSaveDraft(action: RoomDetailActions.SaveDraft) { + private fun handleSaveDraft(action: RoomDetailAction.SaveDraft) { withState { when (it.sendMode) { is SendMode.REGULAR -> room.saveDraft(UserDraft.REGULAR(action.draft)) @@ -211,7 +211,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro .disposeOnClear() } - private fun handleTombstoneEvent(action: RoomDetailActions.HandleTombstoneEvent) { + private fun handleTombstoneEvent(action: RoomDetailAction.HandleTombstoneEvent) { val tombstoneContent = action.event.getClearContent().toModel() ?: return @@ -267,7 +267,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro // PRIVATE METHODS ***************************************************************************** - private fun handleSendMessage(action: RoomDetailActions.SendMessage) { + private fun handleSendMessage(action: RoomDetailAction.SendMessage) { withState { state -> when (state.sendMode) { is SendMode.REGULAR -> { @@ -458,20 +458,20 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro }) } - private fun handleSendReaction(action: RoomDetailActions.SendReaction) { + private fun handleSendReaction(action: RoomDetailAction.SendReaction) { room.sendReaction(action.targetEventId, action.reaction) } - private fun handleRedactEvent(action: RoomDetailActions.RedactAction) { + private fun handleRedactEvent(action: RoomDetailAction.RedactAction) { val event = room.getTimeLineEvent(action.targetEventId) ?: return room.redactEvent(event.root, action.reason) } - private fun handleUndoReact(action: RoomDetailActions.UndoReaction) { + private fun handleUndoReact(action: RoomDetailAction.UndoReaction) { room.undoReaction(action.targetEventId, action.reaction) } - private fun handleUpdateQuickReaction(action: RoomDetailActions.UpdateQuickReactAction) { + private fun handleUpdateQuickReaction(action: RoomDetailAction.UpdateQuickReactAction) { if (action.add) { room.sendReaction(action.targetEventId, action.selectedReaction) } else { @@ -479,7 +479,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleSendMedia(action: RoomDetailActions.SendMedia) { + private fun handleSendMedia(action: RoomDetailAction.SendMedia) { val attachments = action.attachments val homeServerCapabilities = session.getHomeServerCapabilities() val maxUploadFileSize = homeServerCapabilities.maxUploadFileSize @@ -496,19 +496,19 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleEventVisible(action: RoomDetailActions.TimelineEventTurnsVisible) { + private fun handleEventVisible(action: RoomDetailAction.TimelineEventTurnsVisible) { if (action.event.root.sendState.isSent()) { // ignore pending/local events visibleEventsObservable.accept(action) } // We need to update this with the related m.replace also (to move read receipt) action.event.annotations?.editSummary?.sourceEvents?.forEach { room.getTimeLineEvent(it)?.let { event -> - visibleEventsObservable.accept(RoomDetailActions.TimelineEventTurnsVisible(event)) + visibleEventsObservable.accept(RoomDetailAction.TimelineEventTurnsVisible(event)) } } } - private fun handleLoadMore(action: RoomDetailActions.LoadMoreTimelineEvents) { + private fun handleLoadMore(action: RoomDetailAction.LoadMoreTimelineEvents) { timeline.paginate(action.direction, PAGINATION_COUNT) } @@ -520,7 +520,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro room.join(callback = object : MatrixCallback {}) } - private fun handleEditAction(action: RoomDetailActions.EnterEditMode) { + private fun handleEditAction(action: RoomDetailAction.EnterEditMode) { saveCurrentDraft(action.draft) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> @@ -530,7 +530,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleQuoteAction(action: RoomDetailActions.EnterQuoteMode) { + private fun handleQuoteAction(action: RoomDetailAction.EnterQuoteMode) { saveCurrentDraft(action.draft) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> @@ -547,7 +547,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleReplyAction(action: RoomDetailActions.EnterReplyMode) { + private fun handleReplyAction(action: RoomDetailAction.EnterReplyMode) { saveCurrentDraft(action.draft) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> @@ -578,7 +578,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleExitSpecialMode(action: RoomDetailActions.ExitSpecialMode) { + private fun handleExitSpecialMode(action: RoomDetailAction.ExitSpecialMode) { withState { state -> // For edit, just delete the current draft if (state.sendMode is SendMode.EDIT) { @@ -590,7 +590,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleDownloadFile(action: RoomDetailActions.DownloadFile) { + private fun handleDownloadFile(action: RoomDetailAction.DownloadFile) { session.downloadFile( FileService.DownloadMode.TO_EXPORT, action.eventId, @@ -616,7 +616,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro }) } - private fun handleNavigateToEvent(action: RoomDetailActions.NavigateToEvent) { + private fun handleNavigateToEvent(action: RoomDetailAction.NavigateToEvent) { val targetEventId: String = action.eventId val correctedEventId = timeline.getFirstDisplayableEventId(targetEventId) ?: targetEventId val indexOfEvent = timeline.getIndexOfEvent(correctedEventId) @@ -630,7 +630,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro _navigateToEvent.postLiveEvent(correctedEventId) } - private fun handleResendEvent(action: RoomDetailActions.ResendMessage) { + private fun handleResendEvent(action: RoomDetailAction.ResendMessage) { val targetEventId = action.eventId room.getTimeLineEvent(targetEventId)?.let { // State must be UNDELIVERED or Failed @@ -648,7 +648,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } } - private fun handleRemove(action: RoomDetailActions.RemoveFailedEcho) { + private fun handleRemove(action: RoomDetailAction.RemoveFailedEcho) { val targetEventId = action.eventId room.getTimeLineEvent(targetEventId)?.let { // State must be UNDELIVERED or Failed @@ -683,7 +683,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro .disposeOnClear() } - private fun handleSetReadMarkerAction(action: RoomDetailActions.SetReadMarkerAction) = withState { + private fun handleSetReadMarkerAction(action: RoomDetailAction.SetReadMarkerAction) = withState { var readMarkerId = action.eventId val indexOfEvent = timeline.getIndexOfEvent(readMarkerId) // force to set the read marker on the next event @@ -699,7 +699,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro room.markAllAsRead(object : MatrixCallback {}) } - private fun handleReportContent(action: RoomDetailActions.ReportContent) { + private fun handleReportContent(action: RoomDetailAction.ReportContent) { room.reportContent(action.eventId, -100, action.reason, object : MatrixCallback { override fun onSuccess(data: Unit) { _requestLiveData.postValue(LiveEvent(Success(action))) @@ -711,7 +711,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro }) } - private fun handleIgnoreUser(action: RoomDetailActions.IgnoreUser) { + private fun handleIgnoreUser(action: RoomDetailAction.IgnoreUser) { if (action.userId.isNullOrEmpty()) { return } 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/TextComposerAction.kt similarity index 91% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerAction.kt index 1e5fccfe49..5d60fa1cef 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/TextComposerAction.kt @@ -18,6 +18,6 @@ package im.vector.riotx.features.home.room.detail.composer import im.vector.riotx.core.platform.VectorViewModelAction -sealed class TextComposerActions : VectorViewModelAction { - data class QueryUsers(val query: CharSequence?) : TextComposerActions() +sealed class TextComposerAction : VectorViewModelAction { + data class QueryUsers(val query: CharSequence?) : TextComposerAction() } 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 5915ffa9db..88548e12b4 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 @@ -61,13 +61,13 @@ class TextComposerViewModel @AssistedInject constructor(@Assisted initialState: observeUsersQuery() } - override fun handle(action: TextComposerActions) { + override fun handle(action: TextComposerAction) { when (action) { - is TextComposerActions.QueryUsers -> handleQueryUsers(action) + is TextComposerAction.QueryUsers -> handleQueryUsers(action) } } - private fun handleQueryUsers(action: TextComposerActions.QueryUsers) { + private fun handleQueryUsers(action: TextComposerAction.QueryUsers) { val query = Option.fromNullable(action.query) usersQueryObservable.accept(query) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsAction.kt similarity index 86% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsAction.kt index 02c0eebe69..fe8a10d364 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsAction.kt @@ -18,6 +18,6 @@ package im.vector.riotx.features.home.room.detail.timeline.action import im.vector.riotx.core.platform.VectorViewModelAction -sealed class MessageActionsActions : VectorViewModelAction { - object ToggleReportMenu : MessageActionsActions() +sealed class MessageActionsAction : VectorViewModelAction { + object ToggleReportMenu : MessageActionsAction() } 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 84c8ed6886..1a8f31bb50 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.handle(MessageActionsActions.ToggleReportMenu) + viewModel.handle(MessageActionsAction.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 83045ce9bb..575f835bb4 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 @@ -85,7 +85,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 @@ -112,9 +112,9 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted observeEventAction() } - override fun handle(action: MessageActionsActions) { + override fun handle(action: MessageActionsAction) { when (action) { - MessageActionsActions.ToggleReportMenu -> toggleReportMenu() + MessageActionsAction.ToggleReportMenu -> toggleReportMenu() } } 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/RoomListAction.kt similarity index 76% rename from vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListActions.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListAction.kt index 25308dc3f9..9db7374169 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/RoomListAction.kt @@ -20,13 +20,13 @@ 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 : VectorViewModelAction { - data class SelectRoom(val roomSummary: RoomSummary) : RoomListActions() - data class ToggleCategory(val category: RoomCategory) : RoomListActions() - data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListActions() - data class RejectInvitation(val roomSummary: RoomSummary) : RoomListActions() - data class FilterWith(val filter: String) : RoomListActions() - data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : RoomListActions() - data class LeaveRoom(val roomId: String) : RoomListActions() - object MarkAllRoomsRead : RoomListActions() +sealed class RoomListAction : VectorViewModelAction { + data class SelectRoom(val roomSummary: RoomSummary) : RoomListAction() + data class ToggleCategory(val category: RoomCategory) : RoomListAction() + data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListAction() + data class RejectInvitation(val roomSummary: RoomSummary) : RoomListAction() + data class FilterWith(val filter: String) : RoomListAction() + data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : RoomListAction() + data class LeaveRoom(val roomId: String) : RoomListAction() + object MarkAllRoomsRead : RoomListAction() } 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 f177847448..47ef255fa8 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.handle(RoomListActions.MarkAllRoomsRead) + roomListViewModel.handle(RoomListAction.MarkAllRoomsRead) return true } } @@ -183,7 +183,7 @@ class RoomListFragment @Inject constructor( // Scroll the list to top roomListEpoxyRecyclerView.scrollToPosition(0) - roomListViewModel.handle(RoomListActions.FilterWith(filter)) + roomListViewModel.handle(RoomListAction.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.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) + roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) } is RoomListQuickActionsSharedAction.NotificationsAll -> { - roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) + roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) } is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> { - roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) + roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) } is RoomListQuickActionsSharedAction.NotificationsMute -> { - roomListViewModel.handle(RoomListActions.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) + roomListViewModel.handle(RoomListAction.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.handle(RoomListActions.LeaveRoom(quickAction.roomId)) + roomListViewModel.handle(RoomListAction.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.handle(RoomListActions.SelectRoom(room)) + roomListViewModel.handle(RoomListAction.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.handle(RoomListActions.AcceptInvitation(room)) + roomListViewModel.handle(RoomListAction.AcceptInvitation(room)) } override fun onRejectRoomInvitation(room: RoomSummary) { notificationDrawerManager.clearMemberShipNotificationForRoom(room.roomId) - roomListViewModel.handle(RoomListActions.RejectInvitation(room)) + roomListViewModel.handle(RoomListAction.RejectInvitation(room)) } override fun onToggleRoomCategory(roomCategory: RoomCategory) { - roomListViewModel.handle(RoomListActions.ToggleCategory(roomCategory)) + roomListViewModel.handle(RoomListAction.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 8094f42afb..6fd5d9763c 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,30 +61,30 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, observeRoomSummaries() } - override fun handle(action: RoomListActions) { + override fun handle(action: RoomListAction) { when (action) { - is RoomListActions.SelectRoom -> handleSelectRoom(action) - is RoomListActions.ToggleCategory -> handleToggleCategory(action) - is RoomListActions.AcceptInvitation -> handleAcceptInvitation(action) - is RoomListActions.RejectInvitation -> handleRejectInvitation(action) - is RoomListActions.FilterWith -> handleFilter(action) - is RoomListActions.MarkAllRoomsRead -> handleMarkAllRoomsRead() - is RoomListActions.LeaveRoom -> handleLeaveRoom(action) - is RoomListActions.ChangeRoomNotificationState -> handleChangeNotificationMode(action) + is RoomListAction.SelectRoom -> handleSelectRoom(action) + is RoomListAction.ToggleCategory -> handleToggleCategory(action) + is RoomListAction.AcceptInvitation -> handleAcceptInvitation(action) + is RoomListAction.RejectInvitation -> handleRejectInvitation(action) + is RoomListAction.FilterWith -> handleFilter(action) + is RoomListAction.MarkAllRoomsRead -> handleMarkAllRoomsRead() + is RoomListAction.LeaveRoom -> handleLeaveRoom(action) + is RoomListAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action) } } // PRIVATE METHODS ***************************************************************************** - private fun handleSelectRoom(action: RoomListActions.SelectRoom) { + private fun handleSelectRoom(action: RoomListAction.SelectRoom) { _viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary.roomId)) } - private fun handleToggleCategory(action: RoomListActions.ToggleCategory) = setState { + private fun handleToggleCategory(action: RoomListAction.ToggleCategory) = setState { this.toggle(action.category) } - private fun handleFilter(action: RoomListActions.FilterWith) { + private fun handleFilter(action: RoomListAction.FilterWith) { setState { copy( roomFilter = action.filter @@ -112,7 +112,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } } - private fun handleAcceptInvitation(action: RoomListActions.AcceptInvitation) = withState { state -> + private fun handleAcceptInvitation(action: RoomListAction.AcceptInvitation) = withState { state -> val roomId = action.roomSummary.roomId if (state.joiningRoomsIds.contains(roomId) || state.rejectingRoomsIds.contains(roomId)) { @@ -147,7 +147,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, }) } - private fun handleRejectInvitation(action: RoomListActions.RejectInvitation) = withState { state -> + private fun handleRejectInvitation(action: RoomListAction.RejectInvitation) = withState { state -> val roomId = action.roomSummary.roomId if (state.joiningRoomsIds.contains(roomId) || state.rejectingRoomsIds.contains(roomId)) { @@ -193,7 +193,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, ?.let { session.markAllAsRead(it, object : MatrixCallback {}) } } - private fun handleChangeNotificationMode(action: RoomListActions.ChangeRoomNotificationState) { + private fun handleChangeNotificationMode(action: RoomListAction.ChangeRoomNotificationState) { session.getRoom(action.roomId)?.setRoomNotificationState(action.notificationState, object : MatrixCallback { override fun onFailure(failure: Throwable) { _viewEvents.post(RoomListViewEvents.Failure(failure)) @@ -201,7 +201,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, }) } - private fun handleLeaveRoom(action: RoomListActions.LeaveRoom) { + private fun handleLeaveRoom(action: RoomListAction.LeaveRoom) { session.getRoom(action.roomId)?.leave(object : MatrixCallback { override fun onFailure(failure: Throwable) { _viewEvents.post(RoomListViewEvents.Failure(failure)) diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginAction.kt similarity index 90% rename from vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt rename to vector/src/main/java/im/vector/riotx/features/login/LoginAction.kt index 628c75e483..bb42bc8e0c 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginAction.kt @@ -19,10 +19,10 @@ 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 : 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() - data class NavigateTo(val target: LoginActivity.Navigation) : LoginActions() - data class InitWith(val loginConfig: LoginConfig) : LoginActions() +sealed class LoginAction : VectorViewModelAction { + data class UpdateHomeServer(val homeServerUrl: String) : LoginAction() + data class Login(val login: String, val password: String) : LoginAction() + data class SsoLoginSuccess(val credentials: Credentials) : LoginAction() + data class NavigateTo(val target: LoginActivity.Navigation) : LoginAction() + data class InitWith(val loginConfig: LoginConfig) : LoginAction() } diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt index 86156bc4d4..abed22cb5e 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginActivity.kt @@ -57,7 +57,7 @@ class LoginActivity : VectorBaseActivity() { // Get config extra val loginConfig = intent.getParcelableExtra(EXTRA_CONFIG) if (loginConfig != null && isFirstCreation()) { - loginViewModel.handle(LoginActions.InitWith(loginConfig)) + loginViewModel.handle(LoginAction.InitWith(loginConfig)) } loginViewModel.navigationLiveData.observeEvent(this) { diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt index 7da8a79ac8..f8295310f9 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt @@ -59,14 +59,14 @@ class LoginFragment @Inject constructor() : VectorBaseFragment() { homeServerField.focusChanges() .subscribe { if (!it) { - viewModel.handle(LoginActions.UpdateHomeServer(homeServerField.text.toString())) + viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString())) } } .disposeOnDestroy() homeServerField.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { - viewModel.handle(LoginActions.UpdateHomeServer(homeServerField.text.toString())) + viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString())) return@setOnEditorActionListener true } return@setOnEditorActionListener false @@ -78,7 +78,7 @@ class LoginFragment @Inject constructor() : VectorBaseFragment() { } else { homeServerField.setText(ServerUrlsRepository.getDefaultHomeServerUrl(requireContext())) } - viewModel.handle(LoginActions.UpdateHomeServer(homeServerField.text.toString())) + viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString())) } private fun setupNotice() { @@ -93,7 +93,7 @@ class LoginFragment @Inject constructor() : VectorBaseFragment() { val login = loginField.text?.trim().toString() val password = passwordField.text?.trim().toString() - viewModel.handle(LoginActions.Login(login, password)) + viewModel.handle(LoginAction.Login(login, password)) } private fun setupAuthButton() { @@ -114,7 +114,7 @@ class LoginFragment @Inject constructor() : VectorBaseFragment() { } private fun openSso() { - viewModel.handle(LoginActions.NavigateTo(LoginActivity.Navigation.OpenSsoLoginFallback)) + viewModel.handle(LoginAction.NavigateTo(LoginActivity.Navigation.OpenSsoLoginFallback)) } private fun setupPasswordReveal() { diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt index 9e0cd611d1..38deccccaf 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginSsoFallbackFragment.kt @@ -143,7 +143,7 @@ class LoginSsoFallbackFragment @Inject constructor() : VectorBaseFragment(), OnB super.onReceivedError(view, errorCode, description, failingUrl) // on error case, close this fragment - viewModel.handle(LoginActions.NavigateTo(LoginActivity.Navigation.GoBack)) + viewModel.handle(LoginAction.NavigateTo(LoginActivity.Navigation.GoBack)) } override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { @@ -253,7 +253,7 @@ class LoginSsoFallbackFragment @Inject constructor() : VectorBaseFragment(), OnB refreshToken = null ) - viewModel.handle(LoginActions.SsoLoginSuccess(safeCredentials)) + viewModel.handle(LoginAction.SsoLoginSuccess(safeCredentials)) } } } catch (e: Exception) { @@ -278,7 +278,7 @@ class LoginSsoFallbackFragment @Inject constructor() : VectorBaseFragment(), OnB refreshToken = null ) - viewModel.handle(LoginActions.SsoLoginSuccess(credentials)) + viewModel.handle(LoginAction.SsoLoginSuccess(credentials)) } } } 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 5890e71b32..5a9c682f61 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,21 +67,21 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi private var homeServerConnectionConfig: HomeServerConnectionConfig? = null private var currentTask: Cancelable? = null - override fun handle(action: LoginActions) { + override fun handle(action: LoginAction) { when (action) { - is LoginActions.InitWith -> handleInitWith(action) - is LoginActions.UpdateHomeServer -> handleUpdateHomeserver(action) - is LoginActions.Login -> handleLogin(action) - is LoginActions.SsoLoginSuccess -> handleSsoLoginSuccess(action) - is LoginActions.NavigateTo -> handleNavigation(action) + is LoginAction.InitWith -> handleInitWith(action) + is LoginAction.UpdateHomeServer -> handleUpdateHomeserver(action) + is LoginAction.Login -> handleLogin(action) + is LoginAction.SsoLoginSuccess -> handleSsoLoginSuccess(action) + is LoginAction.NavigateTo -> handleNavigation(action) } } - private fun handleInitWith(action: LoginActions.InitWith) { + private fun handleInitWith(action: LoginAction.InitWith) { loginConfig = action.loginConfig } - private fun handleLogin(action: LoginActions.Login) { + private fun handleLogin(action: LoginAction.Login) { val homeServerConnectionConfigFinal = homeServerConnectionConfig if (homeServerConnectionConfigFinal == null) { @@ -124,7 +124,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi } } - private fun handleSsoLoginSuccess(action: LoginActions.SsoLoginSuccess) { + private fun handleSsoLoginSuccess(action: LoginAction.SsoLoginSuccess) { val homeServerConnectionConfigFinal = homeServerConnectionConfig if (homeServerConnectionConfigFinal == null) { @@ -137,7 +137,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi } } - private fun handleUpdateHomeserver(action: LoginActions.UpdateHomeServer) = withState { state -> + private fun handleUpdateHomeserver(action: LoginAction.UpdateHomeServer) = withState { state -> var newConfig: HomeServerConnectionConfig? = null Try { @@ -197,7 +197,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi } } - private fun handleNavigation(action: LoginActions.NavigateTo) { + private fun handleNavigation(action: LoginAction.NavigateTo) { _navigationLiveData.postValue(LiveEvent(action.target)) } 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 83d3077708..8b739ce794 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 @@ -201,7 +201,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), tabLayout.isVisible = false emojiPickerWholeListFragmentContainer.isVisible = false emojiPickerFilteredListFragmentContainer.isVisible = true - searchResultViewModel.handle(EmojiSearchActions.UpdateQuery(query)) + searchResultViewModel.handle(EmojiSearchAction.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/EmojiSearchAction.kt similarity index 91% rename from vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchActions.kt rename to vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchAction.kt index 43fe45f2e3..badc6ea1e4 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchAction.kt @@ -18,6 +18,6 @@ package im.vector.riotx.features.reactions import im.vector.riotx.core.platform.VectorViewModelAction -sealed class EmojiSearchActions : VectorViewModelAction { - data class UpdateQuery(val queryString: String) : EmojiSearchActions() +sealed class EmojiSearchAction : VectorViewModelAction { + data class UpdateQuery(val queryString: String) : EmojiSearchAction() } 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 d89d1fa22e..8225fa7bd6 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,15 +26,15 @@ data class EmojiSearchResultViewState( ) : MvRxState class EmojiSearchResultViewModel(val dataSource: EmojiDataSource, initialState: EmojiSearchResultViewState) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { - override fun handle(action: EmojiSearchActions) { + override fun handle(action: EmojiSearchAction) { when (action) { - is EmojiSearchActions.UpdateQuery -> updateQuery(action) + is EmojiSearchAction.UpdateQuery -> updateQuery(action) } } - private fun updateQuery(action: EmojiSearchActions.UpdateQuery) { + private fun updateQuery(action: EmojiSearchAction.UpdateQuery) { setState { copy( query = action.queryString, 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 ea46671e12..80ee2ba014 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.handle(RoomDirectoryActions.FilterWith(it.toString())) + viewModel.handle(RoomDirectoryAction.FilterWith(it.toString())) } .disposeOnDestroy() @@ -130,11 +130,11 @@ class PublicRoomsFragment @Inject constructor( override fun onPublicRoomJoin(publicRoom: PublicRoom) { Timber.v("PublicRoomJoinClicked: $publicRoom") - viewModel.handle(RoomDirectoryActions.JoinRoom(publicRoom.roomId)) + viewModel.handle(RoomDirectoryAction.JoinRoom(publicRoom.roomId)) } override fun loadMore() { - viewModel.handle(RoomDirectoryActions.LoadMore) + viewModel.handle(RoomDirectoryAction.LoadMore) } private var initialValueSet = false diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt similarity index 86% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt index 0bb6658f2b..8b32726370 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryAction.kt @@ -19,9 +19,9 @@ package im.vector.riotx.features.roomdirectory 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 roomId: String) : RoomDirectoryActions() +sealed class RoomDirectoryAction : VectorViewModelAction { + data class SetRoomDirectoryData(val roomDirectoryData: RoomDirectoryData) : RoomDirectoryAction() + data class FilterWith(val filter: String) : RoomDirectoryAction() + object LoadMore : RoomDirectoryAction() + data class JoinRoom(val roomId: String) : RoomDirectoryAction() } 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 574b461b16..7252e7f271 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,7 +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.CreateRoomAction import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.createroom.CreateRoomViewModel import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment @@ -51,7 +51,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) if (isFirstCreation()) { - roomDirectoryViewModel.handle(RoomDirectoryActions.FilterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "")) + roomDirectoryViewModel.handle(RoomDirectoryAction.FilterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "")) } actionViewModel.observe() @@ -67,7 +67,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { roomDirectoryViewModel.selectSubscribe(this, PublicRoomsViewState::currentFilter) { currentFilter -> // Transmit the filter to the createRoomViewModel - createRoomViewModel.handle(CreateRoomActions.SetName(currentFilter)) + createRoomViewModel.handle(CreateRoomAction.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 085d5dfe5f..685e1aa282 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 @@ -40,7 +40,7 @@ private const val PUBLIC_ROOMS_LIMIT = 20 class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: PublicRoomsViewState, private val session: Session) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -103,16 +103,16 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: .disposeOnClear() } - override fun handle(action: RoomDirectoryActions) { + override fun handle(action: RoomDirectoryAction) { when (action) { - is RoomDirectoryActions.SetRoomDirectoryData -> setRoomDirectoryData(action) - is RoomDirectoryActions.FilterWith -> filterWith(action) - RoomDirectoryActions.LoadMore -> loadMore() - is RoomDirectoryActions.JoinRoom -> joinRoom(action) + is RoomDirectoryAction.SetRoomDirectoryData -> setRoomDirectoryData(action) + is RoomDirectoryAction.FilterWith -> filterWith(action) + RoomDirectoryAction.LoadMore -> loadMore() + is RoomDirectoryAction.JoinRoom -> joinRoom(action) } } - private fun setRoomDirectoryData(action: RoomDirectoryActions.SetRoomDirectoryData) { + private fun setRoomDirectoryData(action: RoomDirectoryAction.SetRoomDirectoryData) { if (this.roomDirectoryData == action.roomDirectoryData) { return } @@ -123,7 +123,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: load("") } - private fun filterWith(action: RoomDirectoryActions.FilterWith) = withState { state -> + private fun filterWith(action: RoomDirectoryAction.FilterWith) = withState { state -> if (state.currentFilter != action.filter) { currentTask?.cancel() @@ -201,7 +201,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState: }) } - private fun joinRoom(action: RoomDirectoryActions.JoinRoom) = withState { state -> + private fun joinRoom(action: RoomDirectoryAction.JoinRoom) = withState { state -> if (state.joiningRoomsIds.contains(action.roomId)) { // 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/roomdirectory/createroom/CreateRoomActions.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomAction.kt similarity index 81% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActions.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomAction.kt index 7c07143a53..333834ca3c 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/createroom/CreateRoomAction.kt @@ -18,9 +18,9 @@ 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() +sealed class CreateRoomAction : VectorViewModelAction { + data class SetName(val name: String) : CreateRoomAction() + data class SetIsPublic(val isPublic: Boolean) : CreateRoomAction() + data class SetIsInRoomDirectory(val isInRoomDirectory: Boolean) : CreateRoomAction() + object Create : CreateRoomAction() } 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 1e91a7224f..26c4f233f7 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.handle(CreateRoomActions.SetName(intent?.getStringExtra(INITIAL_NAME) ?: "")) + createRoomViewModel.handle(CreateRoomAction.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 285276ca7d..ee0a03ce7d 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 @@ -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.handle(CreateRoomActions.Create) + viewModel.handle(CreateRoomAction.Create) true } else -> @@ -71,20 +71,20 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C } override fun onNameChange(newName: String) { - viewModel.handle(CreateRoomActions.SetName(newName)) + viewModel.handle(CreateRoomAction.SetName(newName)) } override fun setIsPublic(isPublic: Boolean) { - viewModel.handle(CreateRoomActions.SetIsPublic(isPublic)) + viewModel.handle(CreateRoomAction.SetIsPublic(isPublic)) } override fun setIsInRoomDirectory(isInRoomDirectory: Boolean) { - viewModel.handle(CreateRoomActions.SetIsInRoomDirectory(isInRoomDirectory)) + viewModel.handle(CreateRoomAction.SetIsInRoomDirectory(isInRoomDirectory)) } override fun retry() { Timber.v("Retry") - viewModel.handle(CreateRoomActions.Create) + viewModel.handle(CreateRoomAction.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 3e794bceac..dcc124b568 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,20 +51,20 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr } } - override fun handle(action: CreateRoomActions) { + override fun handle(action: CreateRoomAction) { when (action) { - is CreateRoomActions.SetName -> setName(action) - is CreateRoomActions.SetIsPublic -> setIsPublic(action) - is CreateRoomActions.SetIsInRoomDirectory -> setIsInRoomDirectory(action) - is CreateRoomActions.Create -> doCreateRoom() + is CreateRoomAction.SetName -> setName(action) + is CreateRoomAction.SetIsPublic -> setIsPublic(action) + is CreateRoomAction.SetIsInRoomDirectory -> setIsInRoomDirectory(action) + is CreateRoomAction.Create -> doCreateRoom() } } - private fun setName(action: CreateRoomActions.SetName) = setState { copy(roomName = action.name) } + private fun setName(action: CreateRoomAction.SetName) = setState { copy(roomName = action.name) } - private fun setIsPublic(action: CreateRoomActions.SetIsPublic) = setState { copy(isPublic = action.isPublic) } + private fun setIsPublic(action: CreateRoomAction.SetIsPublic) = setState { copy(isPublic = action.isPublic) } - private fun setIsInRoomDirectory(action: CreateRoomActions.SetIsInRoomDirectory) = setState { copy(isInRoomDirectory = action.isInRoomDirectory) } + private fun setIsInRoomDirectory(action: CreateRoomAction.SetIsInRoomDirectory) = setState { copy(isInRoomDirectory = action.isInRoomDirectory) } private fun doCreateRoom() = withState { state -> if (state.asyncCreateRoomRequest is Loading || state.asyncCreateRoomRequest is Success) { 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/RoomDirectoryPickerAction.kt similarity index 86% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerActions.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerAction.kt index fe07ce4ac3..157025bb0c 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/picker/RoomDirectoryPickerAction.kt @@ -18,6 +18,6 @@ package im.vector.riotx.features.roomdirectory.picker import im.vector.riotx.core.platform.VectorViewModelAction -sealed class RoomDirectoryPickerActions : VectorViewModelAction { - object Retry : RoomDirectoryPickerActions() +sealed class RoomDirectoryPickerAction : VectorViewModelAction { + object Retry : RoomDirectoryPickerAction() } 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 f2daacb576..ce4a3b52b0 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,7 +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.RoomDirectoryAction import im.vector.riotx.features.roomdirectory.RoomDirectorySharedAction import im.vector.riotx.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.riotx.features.roomdirectory.RoomDirectoryViewModel @@ -87,14 +87,14 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onRoomDirectoryClicked(roomDirectoryData: RoomDirectoryData) { Timber.v("onRoomDirectoryClicked: $roomDirectoryData") - viewModel.handle(RoomDirectoryActions.SetRoomDirectoryData(roomDirectoryData)) + viewModel.handle(RoomDirectoryAction.SetRoomDirectoryData(roomDirectoryData)) actionViewModel.post(RoomDirectorySharedAction.Back) } override fun retry() { Timber.v("Retry") - pickerViewModel.handle(RoomDirectoryPickerActions.Retry) + pickerViewModel.handle(RoomDirectoryPickerAction.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 92abdb0b98..b7bdaea495 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 @@ -26,7 +26,7 @@ import im.vector.riotx.core.platform.VectorViewModel class RoomDirectoryPickerViewModel @AssistedInject constructor(@Assisted initialState: RoomDirectoryPickerViewState, private val session: Session) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -62,9 +62,9 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor(@Assisted initial }) } - override fun handle(action: RoomDirectoryPickerActions) { + override fun handle(action: RoomDirectoryPickerAction) { when (action) { - RoomDirectoryPickerActions.Retry -> load() + RoomDirectoryPickerAction.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/RoomPreviewAction.kt similarity index 88% rename from vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActions.kt rename to vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewAction.kt index ceedaba274..426078fa3d 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/roompreview/RoomPreviewAction.kt @@ -18,6 +18,6 @@ package im.vector.riotx.features.roomdirectory.roompreview import im.vector.riotx.core.platform.VectorViewModelAction -sealed class RoomPreviewActions : VectorViewModelAction { - object Join : RoomPreviewActions() +sealed class RoomPreviewAction : VectorViewModelAction { + object Join : RoomPreviewAction() } 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 7bb2655605..38e74c035a 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.handle(RoomPreviewActions.Join) + roomPreviewViewModel.handle(RoomPreviewAction.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 f1f3bc98ed..9ffb64556f 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 @@ -31,7 +31,7 @@ import timber.log.Timber class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: RoomPreviewViewState, private val session: Session) - : VectorViewModel(initialState) { + : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { @@ -77,9 +77,9 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R .disposeOnClear() } - override fun handle(action: RoomPreviewActions) { + override fun handle(action: RoomPreviewAction) { when (action) { - RoomPreviewActions.Join -> joinRoom() + RoomPreviewAction.Join -> joinRoom() } } From 631448335dfa8d4ada43e55a2e5c73feabcd23a5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 15:36:12 +0100 Subject: [PATCH 089/117] Rename stuff for code coherence --- .../java/im/vector/riotx/features/home/HomeActivity.kt | 10 +++++----- .../vector/riotx/features/home/HomeDetailFragment.kt | 6 +++--- .../home/createdirect/CreateDirectRoomActivity.kt | 10 +++++----- .../CreateDirectRoomDirectoryUsersFragment.kt | 8 ++++---- .../createdirect/CreateDirectRoomKnownUsersFragment.kt | 6 +++--- .../riotx/features/home/group/GroupListFragment.kt | 6 +++--- .../features/home/room/detail/RoomDetailFragment.kt | 8 ++++---- .../timeline/action/MessageActionsBottomSheet.kt | 6 +++--- ...nsDispatcher.kt => MessageSharedActionViewModel.kt} | 2 +- .../riotx/features/home/room/list/RoomListFragment.kt | 8 ++++---- .../list/actions/RoomListQuickActionsBottomSheet.kt | 6 +++--- ...kt => RoomListQuickActionsSharedActionViewModel.kt} | 2 +- .../features/roomdirectory/PublicRoomsFragment.kt | 8 ++++---- .../features/roomdirectory/RoomDirectoryActivity.kt | 10 +++++----- .../roomdirectory/createroom/CreateRoomActivity.kt | 10 +++++----- .../roomdirectory/createroom/CreateRoomFragment.kt | 8 ++++---- .../picker/RoomDirectoryPickerFragment.kt | 6 +++--- 17 files changed, 60 insertions(+), 60 deletions(-) rename vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/{MessageActionsDispatcher.kt => MessageSharedActionViewModel.kt} (90%) rename vector/src/main/java/im/vector/riotx/features/home/room/list/actions/{RoomListQuickActionsStore.kt => RoomListQuickActionsSharedActionViewModel.kt} (87%) diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index f4694bff38..18366a73cc 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -47,7 +47,7 @@ import javax.inject.Inject class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { - private lateinit var actionViewModel: HomeSharedActionViewModel + private lateinit var sharedActionViewModel: HomeSharedActionViewModel @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler @@ -69,16 +69,16 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager) - actionViewModel = ViewModelProviders.of(this).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(this).get(HomeSharedActionViewModel::class.java) drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java) } - actionViewModel.observe() - .subscribe { navigation -> - when (navigation) { + sharedActionViewModel.observe() + .subscribe { sharedAction -> + when (sharedAction) { is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) is HomeActivitySharedAction.OpenGroup -> { drawerLayout.closeDrawer(GravityCompat.START) 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 944d323306..03be7d881e 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 @@ -54,7 +54,7 @@ class HomeDetailFragment @Inject constructor( private val unreadCounterBadgeViews = arrayListOf() private val viewModel: HomeDetailViewModel by fragmentViewModel() - private lateinit var actionViewModel: HomeSharedActionViewModel + private lateinit var sharedActionViewModel: HomeSharedActionViewModel override fun getLayoutResId(): Int { return R.layout.fragment_home_detail @@ -63,7 +63,7 @@ class HomeDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) setupBottomNavigationView() setupToolbar() @@ -129,7 +129,7 @@ class HomeDetailFragment @Inject constructor( } groupToolbar.title = "" groupToolbarAvatarImageView.setOnClickListener { - actionViewModel.post(HomeActivitySharedAction.OpenDrawer) + sharedActionViewModel.post(HomeActivitySharedAction.OpenDrawer) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index 379611d970..311d88995c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -39,7 +39,7 @@ import javax.inject.Inject class CreateDirectRoomActivity : SimpleFragmentActivity() { private val viewModel: CreateDirectRoomViewModel by viewModel() - private lateinit var actionViewModel: CreateDirectRoomSharedActionViewModel + private lateinit var sharedActionViewModel: CreateDirectRoomSharedActionViewModel @Inject lateinit var createDirectRoomViewModelFactory: CreateDirectRoomViewModel.Factory @Inject lateinit var errorFormatter: ErrorFormatter @@ -51,10 +51,10 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) toolbar.visibility = View.GONE - actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) - actionViewModel.observe() - .subscribe { navigation -> - when (navigation) { + sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) + sharedActionViewModel.observe() + .subscribe { sharedAction -> + when (sharedAction) { CreateDirectRoomSharedAction.OpenUsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) CreateDirectRoomSharedAction.Close -> finish() CreateDirectRoomSharedAction.GoBack -> onBackPressed() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 23bff0fced..6d506e4af3 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -39,11 +39,11 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private val viewModel: CreateDirectRoomViewModel by activityViewModel() - private lateinit var actionViewModel: CreateDirectRoomSharedActionViewModel + private lateinit var sharedActionViewModel: CreateDirectRoomSharedActionViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) setupRecyclerView() setupSearchByMatrixIdView() setupCloseView() @@ -70,7 +70,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private fun setupCloseView() { createDirectRoomClose.setOnClickListener { - actionViewModel.post(CreateDirectRoomSharedAction.GoBack) + sharedActionViewModel.post(CreateDirectRoomSharedAction.GoBack) } } @@ -81,7 +81,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( override fun onItemClick(user: User) { view?.hideKeyboard() viewModel.handle(CreateDirectRoomAction.SelectUser(user)) - actionViewModel.post(CreateDirectRoomSharedAction.GoBack) + sharedActionViewModel.post(CreateDirectRoomSharedAction.GoBack) } override fun retryDirectoryUsersRequest() { diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 24fea9e42c..8d47b5224b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -49,11 +49,11 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( override fun getMenuRes() = R.menu.vector_create_direct_room private val viewModel: CreateDirectRoomViewModel by activityViewModel() - private lateinit var actionViewModel: CreateDirectRoomSharedActionViewModel + private lateinit var sharedActionViewModel: CreateDirectRoomSharedActionViewModel override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) vectorBaseActivity.setSupportActionBar(createDirectRoomToolbar) setupRecyclerView() setupFilterView() @@ -89,7 +89,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( private fun setupAddByMatrixIdView() { addByMatrixId.setOnClickListener { - actionViewModel.post(CreateDirectRoomSharedAction.OpenUsersDirectory) + sharedActionViewModel.post(CreateDirectRoomSharedAction.OpenUsersDirectory) } } 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 5875336d69..34258f6e00 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 @@ -36,20 +36,20 @@ class GroupListFragment @Inject constructor( private val groupController: GroupSummaryController ) : VectorBaseFragment(), GroupSummaryController.Callback { - private lateinit var actionViewModel: HomeSharedActionViewModel + private lateinit var sharedActionViewModel: HomeSharedActionViewModel private val viewModel: GroupListViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_group_list override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) groupController.callback = this stateView.contentView = groupListEpoxyRecyclerView groupListEpoxyRecyclerView.setController(groupController) viewModel.subscribe { renderState(it) } viewModel.openGroupLiveData.observeEvent(this) { - actionViewModel.post(HomeActivitySharedAction.OpenGroup) + sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup) } } 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 681952f4d4..8bfce87879 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 @@ -98,7 +98,7 @@ import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet -import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsDispatcher +import im.vector.riotx.features.home.room.detail.timeline.action.MessageSharedActionViewModel import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.item.* @@ -193,7 +193,7 @@ class RoomDetailFragment @Inject constructor( override fun getMenuRes() = R.menu.menu_timeline - private lateinit var messageActionsDispatcher: MessageActionsDispatcher + private lateinit var sharedActionViewModel: MessageSharedActionViewModel private lateinit var layoutManager: LinearLayoutManager private lateinit var attachmentsHelper: AttachmentsHelper private lateinit var keyboardStateUtils: KeyboardStateUtils @@ -206,7 +206,7 @@ class RoomDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - messageActionsDispatcher = ViewModelProviders.of(requireActivity()).get(MessageActionsDispatcher::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(MessageSharedActionViewModel::class.java) attachmentsHelper = AttachmentsHelper.create(this, this).register() keyboardStateUtils = KeyboardStateUtils(requireActivity()) setupToolbar(roomToolbar) @@ -225,7 +225,7 @@ class RoomDetailFragment @Inject constructor( val message = requireContext().getString(pair.first, *pair.second.toTypedArray()) showSnackWithMessage(message, Snackbar.LENGTH_LONG) } - messageActionsDispatcher + sharedActionViewModel .observe() .subscribe { handleActions(it) 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 1a8f31bb50..dfb84a0b4a 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 @@ -47,7 +47,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override val showExpanded = true - private lateinit var messageActionsStore: MessageActionsDispatcher + private lateinit var sharedActionViewModel: MessageSharedActionViewModel override fun injectWith(screenComponent: ScreenComponent) { screenComponent.inject(this) @@ -61,7 +61,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - messageActionsStore = ViewModelProviders.of(requireActivity()).get(MessageActionsDispatcher::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(MessageSharedActionViewModel::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = messageActionsEpoxyController.adapter // Disable item animation @@ -74,7 +74,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message // Toggle report menu viewModel.handle(MessageActionsAction.ToggleReportMenu) } else { - messageActionsStore.post(eventAction) + sharedActionViewModel.post(eventAction) dismiss() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt similarity index 90% rename from vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt index 0d4cd201d8..ff35c04044 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsDispatcher.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt @@ -20,4 +20,4 @@ import im.vector.riotx.core.platform.VectorSharedActionViewModel /** * Activity shared view model to handle message actions */ -class MessageActionsDispatcher : VectorSharedActionViewModel() +class MessageSharedActionViewModel : VectorSharedActionViewModel() 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 47ef255fa8..326a95ca7a 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 @@ -41,7 +41,7 @@ import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet -import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsStore +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData @@ -72,7 +72,7 @@ class RoomListFragment @Inject constructor( SHARE(/* Not used */ 0) } - private lateinit var quickActionsDispatcher: RoomListQuickActionsStore + private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel private val roomListParams: RoomListParams by args() private val roomListViewModel: RoomListViewModel by fragmentViewModel() @@ -100,7 +100,7 @@ class RoomListFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - quickActionsDispatcher = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsStore::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsSharedActionViewModel::class.java) setupCreateRoomButton() setupRecyclerView() roomListViewModel.subscribe { renderState(it) } @@ -118,7 +118,7 @@ class RoomListFragment @Inject constructor( createChatFabMenu.listener = this - quickActionsDispatcher + sharedActionViewModel .observe() .subscribe { handleQuickActions(it) } .disposeOnDestroy() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index d23183f077..06bed66135 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -45,7 +45,7 @@ data class RoomListActionsArgs( */ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { - private lateinit var actionsDispatcher: RoomListQuickActionsStore + private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel @Inject lateinit var roomListActionsViewModelFactory: RoomListQuickActionsViewModel.Factory @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController @Inject lateinit var navigator: Navigator @@ -69,7 +69,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionsDispatcher = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsStore::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsSharedActionViewModel::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = roomListActionsEpoxyController.adapter // Disable item animation @@ -83,7 +83,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R } override fun didSelectMenuAction(quickAction: RoomListQuickActionsSharedAction) { - actionsDispatcher.post(quickAction) + sharedActionViewModel.post(quickAction) dismiss() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt similarity index 87% rename from vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt rename to vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt index fb4b7c0455..9b9a7eb281 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsStore.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt @@ -21,4 +21,4 @@ import im.vector.riotx.core.platform.VectorSharedActionViewModel /** * Activity shared view model to handle room list quick actions */ -class RoomListQuickActionsStore : VectorSharedActionViewModel() +class RoomListQuickActionsSharedActionViewModel : VectorSharedActionViewModel() 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 80ee2ba014..3d8838a842 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 @@ -47,7 +47,7 @@ class PublicRoomsFragment @Inject constructor( ) : VectorBaseFragment(), PublicRoomsController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() - private lateinit var actionViewModel: RoomDirectorySharedActionViewModel + private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel override fun getLayoutResId() = R.layout.fragment_public_rooms @@ -71,7 +71,7 @@ class PublicRoomsFragment @Inject constructor( .disposeOnDestroy() publicRoomsCreateNewRoom.setOnClickListener { - actionViewModel.post(RoomDirectorySharedAction.CreateRoom) + sharedActionViewModel.post(RoomDirectorySharedAction.CreateRoom) } viewModel.joinRoomErrorLiveData.observeEvent(this) { throwable -> @@ -83,7 +83,7 @@ class PublicRoomsFragment @Inject constructor( override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_room_directory_change_protocol -> { - actionViewModel.post(RoomDirectorySharedAction.ChangeProtocol) + sharedActionViewModel.post(RoomDirectorySharedAction.ChangeProtocol) true } else -> @@ -93,7 +93,7 @@ class PublicRoomsFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } 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 7252e7f271..85405f00f6 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 @@ -38,7 +38,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory private val roomDirectoryViewModel: RoomDirectoryViewModel by viewModel() private val createRoomViewModel: CreateRoomViewModel by viewModel() - private lateinit var actionViewModel: RoomDirectorySharedActionViewModel + private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel override fun getLayoutRes() = R.layout.activity_simple @@ -48,15 +48,15 @@ class RoomDirectoryActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) if (isFirstCreation()) { roomDirectoryViewModel.handle(RoomDirectoryAction.FilterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "")) } - actionViewModel.observe() - .subscribe { navigation -> - when (navigation) { + sharedActionViewModel.observe() + .subscribe { sharedAction -> + when (sharedAction) { is RoomDirectorySharedAction.Back -> onBackPressed() is RoomDirectorySharedAction.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) is RoomDirectorySharedAction.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) 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 26c4f233f7..e5df1a55ca 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 @@ -38,7 +38,7 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { @Inject lateinit var createRoomViewModelFactory: CreateRoomViewModel.Factory private val createRoomViewModel: CreateRoomViewModel by viewModel() - private lateinit var actionViewModel: RoomDirectorySharedActionViewModel + private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel override fun getLayoutRes() = R.layout.activity_simple @@ -55,10 +55,10 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - actionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) - actionViewModel.observe() - .subscribe { navigation -> - when (navigation) { + sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel.observe() + .subscribe { sharedAction -> + when (sharedAction) { is RoomDirectorySharedAction.Back, is RoomDirectorySharedAction.Close -> finish() } 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 ee0a03ce7d..b1e451f893 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 @@ -33,7 +33,7 @@ import javax.inject.Inject class CreateRoomFragment @Inject constructor(private val createRoomController: CreateRoomController) : VectorBaseFragment(), CreateRoomController.Listener { - private lateinit var actionViewModel: RoomDirectorySharedActionViewModel + private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel private val viewModel: CreateRoomViewModel by activityViewModel() override fun getLayoutResId() = R.layout.fragment_create_room @@ -43,10 +43,10 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) - actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { - actionViewModel.post(RoomDirectorySharedAction.Back) + sharedActionViewModel.post(RoomDirectorySharedAction.Back) } } @@ -93,7 +93,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C // Navigate to freshly created room navigator.openRoom(requireActivity(), async()) - actionViewModel.post(RoomDirectorySharedAction.Close) + sharedActionViewModel.post(RoomDirectorySharedAction.Close) } else { // Populate list with Epoxy createRoomController.setData(state) 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 ce4a3b52b0..8d610823fb 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 @@ -42,7 +42,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie ) : VectorBaseFragment(), RoomDirectoryPickerController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() - private lateinit var actionViewModel: RoomDirectorySharedActionViewModel + private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel private val pickerViewModel: RoomDirectoryPickerViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_room_directory_picker @@ -72,7 +72,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - actionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } @@ -89,7 +89,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie Timber.v("onRoomDirectoryClicked: $roomDirectoryData") viewModel.handle(RoomDirectoryAction.SetRoomDirectoryData(roomDirectoryData)) - actionViewModel.post(RoomDirectorySharedAction.Back) + sharedActionViewModel.post(RoomDirectorySharedAction.Back) } override fun retry() { From 590a13334dfc9d818f1f44da90b0e3a31da43aab Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 16:04:41 +0100 Subject: [PATCH 090/117] ktlint --- .../java/im/vector/riotx/core/platform/VectorEventViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt index 4bf21c9aa9..e928be3343 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorEventViewModel.kt @@ -20,7 +20,6 @@ import androidx.lifecycle.ViewModel import im.vector.riotx.core.utils.MutableDataSource import im.vector.riotx.core.utils.PublishDataSource - interface VectorSharedAction /** From ea7213a5aec0154becc6dbd0225765b527554e3d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 16:16:42 +0100 Subject: [PATCH 091/117] Split long lines --- .../java/im/vector/riotx/features/home/HomeActivity.kt | 3 ++- .../home/createdirect/CreateDirectRoomActivity.kt | 6 ++++-- .../list/actions/RoomListQuickActionsSharedAction.kt | 6 +++++- .../features/roomdirectory/RoomDirectoryActivity.kt | 9 ++++++--- .../roomdirectory/createroom/CreateRoomActivity.kt | 3 ++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index 18366a73cc..5e8700e1eb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -76,7 +76,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java) } - sharedActionViewModel.observe() + sharedActionViewModel + .observe() .subscribe { sharedAction -> when (sharedAction) { is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index 311d88995c..6ec0a1e16c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -52,10 +52,12 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { super.onCreate(savedInstanceState) toolbar.visibility = View.GONE sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) - sharedActionViewModel.observe() + sharedActionViewModel + .observe() .subscribe { sharedAction -> when (sharedAction) { - CreateDirectRoomSharedAction.OpenUsersDirectory -> addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) + CreateDirectRoomSharedAction.OpenUsersDirectory -> + addFragmentToBackstack(R.id.container, CreateDirectRoomDirectoryUsersFragment::class.java) CreateDirectRoomSharedAction.Close -> finish() CreateDirectRoomSharedAction.GoBack -> onBackPressed() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt index 5e0ca770dc..ca006ddd7d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt @@ -21,7 +21,11 @@ import androidx.annotation.StringRes import im.vector.riotx.R import im.vector.riotx.core.platform.VectorSharedAction -sealed class RoomListQuickActionsSharedAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int, val destructive: Boolean = false) : VectorSharedAction { +sealed class RoomListQuickActionsSharedAction( + @StringRes val titleRes: Int, + @DrawableRes val iconResId: Int, + val destructive: Boolean = false) + : VectorSharedAction { data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_notifications_all_noisy, 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 85405f00f6..bea8e365b8 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 @@ -54,12 +54,15 @@ class RoomDirectoryActivity : VectorBaseActivity() { roomDirectoryViewModel.handle(RoomDirectoryAction.FilterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "")) } - sharedActionViewModel.observe() + sharedActionViewModel + .observe() .subscribe { sharedAction -> when (sharedAction) { is RoomDirectorySharedAction.Back -> onBackPressed() - is RoomDirectorySharedAction.CreateRoom -> addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) - is RoomDirectorySharedAction.ChangeProtocol -> addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) + is RoomDirectorySharedAction.CreateRoom -> + addFragmentToBackstack(R.id.simpleFragmentContainer, CreateRoomFragment::class.java) + is RoomDirectorySharedAction.ChangeProtocol -> + addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java) is RoomDirectorySharedAction.Close -> finish() } } 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 e5df1a55ca..feb23f46c0 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 @@ -56,7 +56,8 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) - sharedActionViewModel.observe() + sharedActionViewModel + .observe() .subscribe { sharedAction -> when (sharedAction) { is RoomDirectorySharedAction.Back, From a6df63f6d9ffb976755a5e52ec2309b5b6060533 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 16:56:45 +0100 Subject: [PATCH 092/117] Fix crash --- .../vector/riotx/core/di/ViewModelModule.kt | 24 +++++++++++++++++++ .../VectorBaseBottomSheetDialogFragment.kt | 5 +++- .../KeysBackupRestoreFromKeyFragment.kt | 5 +--- ...KeysBackupRestoreFromPassphraseFragment.kt | 4 +--- .../KeysBackupRestoreSuccessFragment.kt | 4 +--- .../setup/KeysBackupSetupStep1Fragment.kt | 4 +--- .../setup/KeysBackupSetupStep2Fragment.kt | 4 +--- .../setup/KeysBackupSetupStep3Fragment.kt | 4 +--- .../SASVerificationIncomingFragment.kt | 4 +--- .../SASVerificationShortCodeFragment.kt | 4 +--- .../SASVerificationVerifiedFragment.kt | 4 +--- .../riotx/features/home/HomeActivity.kt | 4 ++-- .../riotx/features/home/HomeDetailFragment.kt | 2 +- .../home/HomeSharedActionViewModel.kt | 3 ++- .../CreateDirectRoomSharedActionViewModel.kt | 3 ++- .../features/home/group/GroupListFragment.kt | 2 +- .../home/room/detail/RoomDetailFragment.kt | 2 +- .../action/MessageActionsBottomSheet.kt | 2 +- .../action/MessageSharedActionViewModel.kt | 3 ++- .../home/room/list/RoomListFragment.kt | 2 +- .../RoomListQuickActionsBottomSheet.kt | 2 +- ...omListQuickActionsSharedActionViewModel.kt | 3 ++- .../reactions/EmojiChooserFragment.kt | 4 +--- .../roomdirectory/PublicRoomsFragment.kt | 2 +- .../RoomDirectorySharedActionViewModel.kt | 3 ++- .../createroom/CreateRoomFragment.kt | 2 +- .../picker/RoomDirectoryPickerFragment.kt | 2 +- 27 files changed, 59 insertions(+), 48 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt index d2b8abb9c4..d4e55e6080 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt @@ -27,6 +27,10 @@ import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromP import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel import im.vector.riotx.features.crypto.verification.SasVerificationViewModel +import im.vector.riotx.features.home.HomeSharedActionViewModel +import im.vector.riotx.features.home.createdirect.CreateDirectRoomSharedActionViewModel +import im.vector.riotx.features.home.room.detail.timeline.action.MessageSharedActionViewModel +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.riotx.features.reactions.EmojiChooserViewModel import im.vector.riotx.features.workers.signout.SignOutViewModel @@ -82,4 +86,24 @@ interface ViewModelModule { @IntoMap @ViewModelKey(ConfigurationViewModel::class) fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(CreateDirectRoomSharedActionViewModel::class) + fun bindCreateDirectRoomSharedActionViewModel(viewModel: CreateDirectRoomSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(HomeSharedActionViewModel::class) + fun bindHomeSharedActionViewModel(viewModel: HomeSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(MessageSharedActionViewModel::class) + fun bindMessageSharedActionViewModel(viewModel: MessageSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomListQuickActionsSharedActionViewModel::class) + fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel } diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt index 1b07d739b5..6f8128e12a 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -21,6 +21,7 @@ import android.os.Bundle import android.os.Parcelable import android.widget.FrameLayout import androidx.annotation.CallSuper +import androidx.lifecycle.ViewModelProvider import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.MvRxView import com.airbnb.mvrx.MvRxViewModelStore @@ -30,7 +31,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import im.vector.riotx.core.di.DaggerScreenComponent import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.utils.DimensionConverter -import java.util.UUID +import java.util.* /** * Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment) @@ -40,6 +41,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) } private lateinit var mvrxPersistedViewId: String private lateinit var screenComponent: ScreenComponent + protected lateinit var viewModelFactory: ViewModelProvider.Factory final override val mvrxViewId: String by lazy { mvrxPersistedViewId } private var bottomSheetBehavior: BottomSheetBehavior? = null @@ -52,6 +54,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() override fun onAttach(context: Context) { screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity) + viewModelFactory = screenComponent.viewModelFactory() super.onAttach(context) injectWith(screenComponent) } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt index c30393dd5f..fbeeb273f0 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt @@ -54,10 +54,7 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromKeyViewModel::class.java) - sharedViewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) - } ?: throw Exception("Invalid Activity") - + sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) mKeyTextEdit.setText(viewModel.recoveryCode.value) mKeyTextEdit.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt index d4468081b8..ad4b9e885d 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt @@ -65,9 +65,7 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseF super.onActivityCreated(savedInstanceState) viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromPassphraseViewModel::class.java) - sharedViewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) - } ?: throw Exception("Invalid Activity") + sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) viewModel.passphraseErrorText.observe(viewLifecycleOwner, Observer { newValue -> mPassphraseInputLayout.error = newValue diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index 813bb9ca72..806a29b0e3 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -38,9 +38,7 @@ class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragmen override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedViewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) - } ?: throw Exception("Invalid Activity") + sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) sharedViewModel.importKeyResult?.let { val part1 = resources.getQuantityString(R.plurals.keys_backup_restore_success_description_part1, diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index d018cc1ce9..0b0be672bc 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -44,9 +44,7 @@ class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) viewModel.showManualExport.observe(viewLifecycleOwner, Observer { val showOption = it ?: false diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt index 21e4747a4e..fc9cff1b60 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt @@ -79,9 +79,7 @@ class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) viewModel.shouldPromptOnBack = true bindViewToViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index 008e1b8aef..cc84b7454e 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -58,9 +58,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) viewModel.shouldPromptOnBack = false diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt index 9bb3661bd7..d5b160b5a0 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt @@ -51,9 +51,7 @@ class SASVerificationIncomingFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(SasVerificationViewModel::class.java) otherUserDisplayNameTextView.text = viewModel.otherUser?.displayName ?: viewModel.otherUserId otherUserIdTextView.text = viewModel.otherUserId diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt index da19d48bfe..c4e3463bc4 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt @@ -62,9 +62,7 @@ class SASVerificationShortCodeFragment @Inject constructor(): VectorBaseFragment override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(SasVerificationViewModel::class.java) viewModel.transaction?.let { if (it.supportsEmoji()) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt index 59825c8282..915610567f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt @@ -31,9 +31,7 @@ class SASVerificationVerifiedFragment @Inject constructor() : VectorBaseFragment override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(SasVerificationViewModel::class.java) } @OnClick(R.id.sas_verification_verified_done_button) diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index 5e8700e1eb..a4bdf0a030 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -69,7 +69,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager) - sharedActionViewModel = ViewModelProviders.of(this).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(HomeSharedActionViewModel::class.java) drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) @@ -147,7 +147,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { } // Force remote backup state update to update the banner if needed - ViewModelProviders.of(this).get(SignOutViewModel::class.java).refreshRemoteStateIfNeeded() + ViewModelProviders.of(this, viewModelFactory).get(SignOutViewModel::class.java).refreshRemoteStateIfNeeded() } override fun configure(toolbar: Toolbar) { 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 03be7d881e..57325d1eda 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 @@ -63,7 +63,7 @@ class HomeDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(HomeSharedActionViewModel::class.java) setupBottomNavigationView() setupToolbar() diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt index 23baa53e3b..cd81448a0a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeSharedActionViewModel.kt @@ -17,5 +17,6 @@ package im.vector.riotx.features.home import im.vector.riotx.core.platform.VectorSharedActionViewModel +import javax.inject.Inject -class HomeSharedActionViewModel : VectorSharedActionViewModel() +class HomeSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt index 7e5a2bbe93..590a4855f5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomSharedActionViewModel.kt @@ -17,5 +17,6 @@ package im.vector.riotx.features.home.createdirect import im.vector.riotx.core.platform.VectorSharedActionViewModel +import javax.inject.Inject -class CreateDirectRoomSharedActionViewModel : VectorSharedActionViewModel() +class CreateDirectRoomSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel() 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 34258f6e00..95bb097d42 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 @@ -43,7 +43,7 @@ class GroupListFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(HomeSharedActionViewModel::class.java) groupController.callback = this stateView.contentView = groupListEpoxyRecyclerView groupListEpoxyRecyclerView.setController(groupController) 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 8bfce87879..e851ba58ce 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 @@ -206,7 +206,7 @@ class RoomDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(MessageSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(MessageSharedActionViewModel::class.java) attachmentsHelper = AttachmentsHelper.create(this, this).register() keyboardStateUtils = KeyboardStateUtils(requireActivity()) setupToolbar(roomToolbar) 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 dfb84a0b4a..2502f37b0e 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 @@ -61,7 +61,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(MessageSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(MessageSharedActionViewModel::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = messageActionsEpoxyController.adapter // Disable item animation diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt index ff35c04044..2e041fd2ea 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageSharedActionViewModel.kt @@ -16,8 +16,9 @@ package im.vector.riotx.features.home.room.detail.timeline.action import im.vector.riotx.core.platform.VectorSharedActionViewModel +import javax.inject.Inject /** * Activity shared view model to handle message actions */ -class MessageSharedActionViewModel : VectorSharedActionViewModel() +class MessageSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel() 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 326a95ca7a..08c646917c 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 @@ -100,7 +100,7 @@ class RoomListFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomListQuickActionsSharedActionViewModel::class.java) setupCreateRoomButton() setupRecyclerView() roomListViewModel.subscribe { renderState(it) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 06bed66135..77b60286ff 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -69,7 +69,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomListQuickActionsSharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomListQuickActionsSharedActionViewModel::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = roomListActionsEpoxyController.adapter // Disable item animation diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt index 9b9a7eb281..2f7e8354bf 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsSharedActionViewModel.kt @@ -17,8 +17,9 @@ package im.vector.riotx.features.home.room.list.actions import im.vector.riotx.core.platform.VectorSharedActionViewModel +import javax.inject.Inject /** * Activity shared view model to handle room list quick actions */ -class RoomListQuickActionsSharedActionViewModel : VectorSharedActionViewModel() +class RoomListQuickActionsSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index 589fa5dbff..418aea9417 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -30,9 +30,7 @@ class EmojiChooserFragment @Inject constructor() : VectorBaseFragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = activity?.run { - ViewModelProviders.of(this, viewModelFactory).get(EmojiChooserViewModel::class.java) - } ?: throw Exception("Invalid Activity") + viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(EmojiChooserViewModel::class.java) viewModel.initWithContext(context!!) (view as? RecyclerView)?.let { it.adapter = viewModel.adapter 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 3d8838a842..6220a34da5 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 @@ -93,7 +93,7 @@ class PublicRoomsFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt index 257ad782fe..12ae9c1cb5 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectorySharedActionViewModel.kt @@ -17,5 +17,6 @@ package im.vector.riotx.features.roomdirectory import im.vector.riotx.core.platform.VectorSharedActionViewModel +import javax.inject.Inject -class RoomDirectorySharedActionViewModel : VectorSharedActionViewModel() +class RoomDirectorySharedActionViewModel @Inject constructor() : VectorSharedActionViewModel() 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 b1e451f893..71f5669118 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 @@ -43,7 +43,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { sharedActionViewModel.post(RoomDirectorySharedAction.Back) 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 8d610823fb..750561ebf7 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 @@ -72,7 +72,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity()).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } From ec4d7e29ec0be6be1438c0d22ab55e2c54ab7392 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 17:08:29 +0100 Subject: [PATCH 093/117] Ensure we use the correct viewModelProvider --- .../riotx/core/platform/VectorBaseActivity.kt | 10 +++++++++- .../VectorBaseBottomSheetDialogFragment.kt | 18 +++++++++++++++++- .../riotx/core/platform/VectorBaseFragment.kt | 14 +++++++++++++- .../restore/KeysBackupRestoreActivity.kt | 2 +- .../KeysBackupRestoreFromKeyFragment.kt | 4 ++-- .../KeysBackupRestoreFromPassphraseFragment.kt | 4 ++-- .../KeysBackupRestoreSuccessFragment.kt | 2 +- .../setup/KeysBackupSetupActivity.kt | 2 +- .../setup/KeysBackupSetupStep1Fragment.kt | 2 +- .../setup/KeysBackupSetupStep2Fragment.kt | 2 +- .../setup/KeysBackupSetupStep3Fragment.kt | 2 +- .../verification/SASVerificationActivity.kt | 2 +- .../SASVerificationIncomingFragment.kt | 2 +- .../SASVerificationShortCodeFragment.kt | 2 +- .../SASVerificationStartFragment.kt | 2 +- .../SASVerificationVerifiedFragment.kt | 2 +- .../vector/riotx/features/home/HomeActivity.kt | 4 ++-- .../riotx/features/home/HomeDetailFragment.kt | 5 ++--- .../createdirect/CreateDirectRoomActivity.kt | 2 +- .../CreateDirectRoomDirectoryUsersFragment.kt | 2 +- .../CreateDirectRoomKnownUsersFragment.kt | 2 +- .../features/home/group/GroupListFragment.kt | 2 +- .../home/room/detail/RoomDetailFragment.kt | 2 +- .../action/MessageActionsBottomSheet.kt | 2 +- .../home/room/list/RoomListFragment.kt | 2 +- .../actions/RoomListQuickActionsBottomSheet.kt | 2 +- .../features/reactions/EmojiChooserFragment.kt | 2 +- .../reactions/EmojiReactionPickerActivity.kt | 2 +- .../reactions/EmojiSearchResultFragment.kt | 2 +- .../roomdirectory/PublicRoomsFragment.kt | 2 +- .../roomdirectory/RoomDirectoryActivity.kt | 2 +- .../createroom/CreateRoomActivity.kt | 2 +- .../createroom/CreateRoomFragment.kt | 2 +- .../createroom/CreateRoomViewModel.kt | 2 +- .../picker/RoomDirectoryPickerFragment.kt | 2 +- 35 files changed, 75 insertions(+), 40 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt index ede99e4f28..0cbc4e9b1d 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt @@ -69,11 +69,19 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector { @BindView(R.id.vector_coordinator_layout) var coordinatorLayout: CoordinatorLayout? = null + /* ========================================================================================== + * View model + * ========================================================================================== */ + + private lateinit var viewModelFactory: ViewModelProvider.Factory + + protected val viewModelProvider + get() = ViewModelProviders.of(this, viewModelFactory) + /* ========================================================================================== * DATA * ========================================================================================== */ - protected lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var configurationViewModel: ConfigurationViewModel private lateinit var sessionListener: SessionListener protected lateinit var bugReporter: BugReporter diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt index 6f8128e12a..2c8f840a41 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -22,6 +22,7 @@ import android.os.Parcelable import android.widget.FrameLayout import androidx.annotation.CallSuper import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.MvRxView import com.airbnb.mvrx.MvRxViewModelStore @@ -41,9 +42,24 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) } private lateinit var mvrxPersistedViewId: String private lateinit var screenComponent: ScreenComponent - protected lateinit var viewModelFactory: ViewModelProvider.Factory final override val mvrxViewId: String by lazy { mvrxPersistedViewId } + /* ========================================================================================== + * View model + * ========================================================================================== */ + + private lateinit var viewModelFactory: ViewModelProvider.Factory + + protected val activityViewModelProvider + get() = ViewModelProviders.of(requireActivity(), viewModelFactory) + + protected val fragmentViewModelProvider + get() = ViewModelProviders.of(this, viewModelFactory) + + /* ========================================================================================== + * BottomSheetBehavior + * ========================================================================================== */ + private var bottomSheetBehavior: BottomSheetBehavior? = null val vectorBaseActivity: VectorBaseActivity by lazy { diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt index 206a1bab06..255e18608a 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt @@ -25,6 +25,7 @@ import androidx.annotation.LayoutRes import androidx.annotation.MainThread import androidx.appcompat.widget.Toolbar import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelProviders import butterknife.ButterKnife import butterknife.Unbinder import com.airbnb.mvrx.BaseMvRxFragment @@ -51,10 +52,21 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { * Navigator * ========================================================================================== */ - protected lateinit var viewModelFactory: ViewModelProvider.Factory protected lateinit var navigator: Navigator private lateinit var screenComponent: ScreenComponent + /* ========================================================================================== + * View model + * ========================================================================================== */ + + private lateinit var viewModelFactory: ViewModelProvider.Factory + + protected val activityViewModelProvider + get() = ViewModelProviders.of(requireActivity(), viewModelFactory) + + protected val fragmentViewModelProvider + get() = ViewModelProviders.of(this, viewModelFactory) + /* ========================================================================================== * Life cycle * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt index cd5dc38c3d..7befd54ccd 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt @@ -43,7 +43,7 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() { override fun initUiAndData() { super.initUiAndData() - viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) + viewModel = viewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java) viewModel.initSession(session) viewModel.keyVersionResult.observe(this, Observer { keyVersion -> diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt index fbeeb273f0..38bb08688d 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt @@ -53,8 +53,8 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromKeyViewModel::class.java) - sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) + viewModel = fragmentViewModelProvider.get(KeysBackupRestoreFromKeyViewModel::class.java) + sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java) mKeyTextEdit.setText(viewModel.recoveryCode.value) mKeyTextEdit.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt index ad4b9e885d..e75163f45c 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt @@ -64,8 +64,8 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseF override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupRestoreFromPassphraseViewModel::class.java) - sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) + viewModel = fragmentViewModelProvider.get(KeysBackupRestoreFromPassphraseViewModel::class.java) + sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java) viewModel.passphraseErrorText.observe(viewLifecycleOwner, Observer { newValue -> mPassphraseInputLayout.error = newValue diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index 806a29b0e3..e938abf54f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -38,7 +38,7 @@ class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragmen override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupRestoreSharedViewModel::class.java) + sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java) sharedViewModel.importKeyResult?.let { val part1 = resources.getQuantityString(R.plurals.keys_backup_restore_success_description_part1, diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 8491435d3a..49149e5d98 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -43,7 +43,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() { replaceFragment(R.id.container, KeysBackupSetupStep1Fragment::class.java) } - viewModel = ViewModelProviders.of(this, viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) + viewModel = viewModelProvider.get(KeysBackupSetupSharedViewModel::class.java) viewModel.showManualExport.value = intent.getBooleanExtra(EXTRA_SHOW_MANUAL_EXPORT, false) viewModel.initSession(session) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index 0b0be672bc..efa10d8e84 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -44,7 +44,7 @@ class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) + viewModel = activityViewModelProvider.get(KeysBackupSetupSharedViewModel::class.java) viewModel.showManualExport.observe(viewLifecycleOwner, Observer { val showOption = it ?: false diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt index fc9cff1b60..8e27c57af6 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt @@ -79,7 +79,7 @@ class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) + viewModel = activityViewModelProvider.get(KeysBackupSetupSharedViewModel::class.java) viewModel.shouldPromptOnBack = true bindViewToViewModel() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index cc84b7454e..41de7c9a8a 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -58,7 +58,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(KeysBackupSetupSharedViewModel::class.java) + viewModel = activityViewModelProvider.get(KeysBackupSetupSharedViewModel::class.java) viewModel.shouldPromptOnBack = false diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt index 3890479d91..3e0ecbc39f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt @@ -83,7 +83,7 @@ class SASVerificationActivity : SimpleFragmentActivity() { override fun initUiAndData() { super.initUiAndData() - viewModel = ViewModelProviders.of(this, viewModelFactory).get(SasVerificationViewModel::class.java) + viewModel = viewModelProvider.get(SasVerificationViewModel::class.java) val transactionID: String? = intent.getStringExtra(EXTRA_TRANSACTION_ID) if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt index d5b160b5a0..c5c697277e 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt @@ -51,7 +51,7 @@ class SASVerificationIncomingFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(SasVerificationViewModel::class.java) + viewModel = activityViewModelProvider.get(SasVerificationViewModel::class.java) otherUserDisplayNameTextView.text = viewModel.otherUser?.displayName ?: viewModel.otherUserId otherUserIdTextView.text = viewModel.otherUserId diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt index c4e3463bc4..c4b9d39f39 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt @@ -62,7 +62,7 @@ class SASVerificationShortCodeFragment @Inject constructor(): VectorBaseFragment override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(SasVerificationViewModel::class.java) + viewModel = activityViewModelProvider.get(SasVerificationViewModel::class.java) viewModel.transaction?.let { if (it.supportsEmoji()) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt index 97a29d9b7b..94539e8c68 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt @@ -53,7 +53,7 @@ class SASVerificationStartFragment @Inject constructor(): VectorBaseFragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(vectorBaseActivity, viewModelFactory).get(SasVerificationViewModel::class.java) + viewModel = activityViewModelProvider.get(SasVerificationViewModel::class.java) viewModel.transactionState.observe(viewLifecycleOwner, Observer { val uxState = (viewModel.transaction as? OutgoingSasVerificationRequest)?.uxState when (uxState) { diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt index 915610567f..bc9bb71143 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt @@ -31,7 +31,7 @@ class SASVerificationVerifiedFragment @Inject constructor() : VectorBaseFragment override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(SasVerificationViewModel::class.java) + viewModel = activityViewModelProvider.get(SasVerificationViewModel::class.java) } @OnClick(R.id.sas_verification_verified_done_button) diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index a4bdf0a030..c12f6fc32f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -69,7 +69,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager) - sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java) drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) @@ -147,7 +147,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { } // Force remote backup state update to update the banner if needed - ViewModelProviders.of(this, viewModelFactory).get(SignOutViewModel::class.java).refreshRemoteStateIfNeeded() + viewModelProvider.get(SignOutViewModel::class.java).refreshRemoteStateIfNeeded() } override fun configure(toolbar: Toolbar) { 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 57325d1eda..77d606b14e 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 @@ -20,7 +20,6 @@ import android.os.Bundle import android.view.LayoutInflater import androidx.core.view.forEachIndexed import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.bottomnavigation.BottomNavigationItemView @@ -63,7 +62,7 @@ class HomeDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java) setupBottomNavigationView() setupToolbar() @@ -91,7 +90,7 @@ class HomeDetailFragment @Inject constructor( private fun setupKeysBackupBanner() { // Keys backup banner // Use the SignOutViewModel, it observe the keys backup state and this is what we need here - val model = ViewModelProviders.of(this, viewModelFactory).get(SignOutViewModel::class.java) + val model = fragmentViewModelProvider.get(SignOutViewModel::class.java) model.init(session) diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index 6ec0a1e16c..c32fe36bbc 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -51,7 +51,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) toolbar.visibility = View.GONE - sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) + sharedActionViewModel = viewModelProvider.get(CreateDirectRoomSharedActionViewModel::class.java) sharedActionViewModel .observe() .subscribe { sharedAction -> diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 6d506e4af3..07dccf1f80 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -43,7 +43,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(CreateDirectRoomSharedActionViewModel::class.java) setupRecyclerView() setupSearchByMatrixIdView() setupCloseView() diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 8d47b5224b..4e87d59f62 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -53,7 +53,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(CreateDirectRoomSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(CreateDirectRoomSharedActionViewModel::class.java) vectorBaseActivity.setSupportActionBar(createDirectRoomToolbar) setupRecyclerView() setupFilterView() 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 95bb097d42..fbc9f5ca4c 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 @@ -43,7 +43,7 @@ class GroupListFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(HomeSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java) groupController.callback = this stateView.contentView = groupListEpoxyRecyclerView groupListEpoxyRecyclerView.setController(groupController) 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 e851ba58ce..969bacaf6d 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 @@ -206,7 +206,7 @@ class RoomDetailFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(MessageSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java) attachmentsHelper = AttachmentsHelper.create(this, this).register() keyboardStateUtils = KeyboardStateUtils(requireActivity()) setupToolbar(roomToolbar) 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 2502f37b0e..a0bf43e6db 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 @@ -61,7 +61,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(MessageSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = messageActionsEpoxyController.adapter // Disable item animation 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 08c646917c..9c575c5dd2 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 @@ -100,7 +100,7 @@ class RoomListFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomListQuickActionsSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java) setupCreateRoomButton() setupRecyclerView() roomListViewModel.subscribe { renderState(it) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 77b60286ff..f1350a9b0b 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -69,7 +69,7 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomListQuickActionsSharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java) recyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false) recyclerView.adapter = roomListActionsEpoxyController.adapter // Disable item animation diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index 418aea9417..4bfde22774 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -30,7 +30,7 @@ class EmojiChooserFragment @Inject constructor() : VectorBaseFragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(EmojiChooserViewModel::class.java) + viewModel = activityViewModelProvider.get(EmojiChooserViewModel::class.java) viewModel.initWithContext(context!!) (view as? RecyclerView)?.let { it.adapter = viewModel.adapter 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 8b739ce794..966329e8d8 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 @@ -90,7 +90,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), tabLayout = findViewById(R.id.tabs) - viewModel = ViewModelProviders.of(this, viewModelFactory).get(EmojiChooserViewModel::class.java) + viewModel = viewModelProvider.get(EmojiChooserViewModel::class.java) viewModel.eventId = intent.getStringExtra(EXTRA_EVENT_ID) diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt index 04fc99bbaa..2c97d9fee5 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt @@ -41,7 +41,7 @@ class EmojiSearchResultFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(EmojiChooserViewModel::class.java) + sharedViewModel = activityViewModelProvider.get(EmojiChooserViewModel::class.java) epoxyController.listener = object : ReactionClickListener { override fun onReactionSelected(reaction: String) { 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 6220a34da5..cf60ba68a0 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 @@ -93,7 +93,7 @@ class PublicRoomsFragment @Inject constructor( override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } 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 bea8e365b8..5ba20e0e53 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 @@ -48,7 +48,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) if (isFirstCreation()) { roomDirectoryViewModel.handle(RoomDirectoryAction.FilterWith(intent?.getStringExtra(INITIAL_FILTER) ?: "")) 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 feb23f46c0..64f3563e20 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 @@ -55,7 +55,7 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(this, viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) sharedActionViewModel .observe() .subscribe { sharedAction -> 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 71f5669118..cdf006a4e7 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 @@ -43,7 +43,7 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() createRoomClose.setOnClickListener { sharedActionViewModel.post(RoomDirectorySharedAction.Back) 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 dcc124b568..ff4aa332f4 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 @@ -46,7 +46,7 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr return when (activity) { is CreateRoomActivity -> activity.createRoomViewModelFactory.create(state) is RoomDirectoryActivity -> activity.createRoomViewModelFactory.create(state) - else -> throw IllegalStateException("Wrong activity") + else -> error("Wrong activity") } } } 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 750561ebf7..11a08c6291 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 @@ -72,7 +72,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - sharedActionViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(RoomDirectorySharedActionViewModel::class.java) + sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() } From bcb811a7e83a56806a26e379f05bd8a5131085ff Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 8 Nov 2019 17:08:44 +0100 Subject: [PATCH 094/117] Realm perf: use Dispatchers.Default for write, as we don't want to create so many threads (and we can only have one write transaction at a time) --- .../vector/matrix/android/internal/database/AsyncTransaction.kt | 2 +- .../internal/database/query/TimelineEventEntityQueries.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt index af98f94146..6d2dccca41 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt @@ -23,7 +23,7 @@ import kotlinx.coroutines.withContext import timber.log.Timber import java.lang.RuntimeException -suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> Unit) = withContext(Dispatchers.IO) { +suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> Unit) = withContext(Dispatchers.Default) { Realm.getInstance(config).use { bgRealm -> bgRealm.beginTransaction() try { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt index 49474e8e6b..3bd035c0b1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt @@ -111,7 +111,7 @@ internal fun RealmQuery.prev(since: Int? = null, strict: Bo internal fun RealmList.find(eventId: String): TimelineEventEntity? { return this.where() - .equalTo(TimelineEventEntityFields.ROOT.EVENT_ID, eventId) + .equalTo(TimelineEventEntityFields.EVENT_ID, eventId) .findFirst() } From bb237e3bbb54c69a390ffe5ecfc2e799ff6371b0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 17:21:46 +0100 Subject: [PATCH 095/117] Fix ViewModel for Signout --- .../riotx/core/platform/VectorBaseActivity.kt | 2 +- .../riotx/features/home/HomeDetailFragment.kt | 2 - .../SignOutBottomSheetDialogFragment.kt | 29 +++--------- .../workers/signout/SignOutViewModel.kt | 44 +++++-------------- 4 files changed, 18 insertions(+), 59 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt index 0cbc4e9b1d..f0f6eea91d 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt @@ -138,7 +138,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector { supportFragmentManager.fragmentFactory = screenComponent.fragmentFactory() super.onCreate(savedInstanceState) viewModelFactory = screenComponent.viewModelFactory() - configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java) + configurationViewModel = viewModelProvider.get(ConfigurationViewModel::class.java) bugReporter = screenComponent.bugReporter() // Shake detector rageShake = screenComponent.rageShake() 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 77d606b14e..5b56a19648 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 @@ -92,8 +92,6 @@ class HomeDetailFragment @Inject constructor( // Use the SignOutViewModel, it observe the keys backup state and this is what we need here val model = fragmentViewModelProvider.get(SignOutViewModel::class.java) - model.init(session) - model.keysBackupState.observe(viewLifecycleOwner, Observer { keysBackupState -> when (keysBackupState) { null -> diff --git a/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutBottomSheetDialogFragment.kt index 32d67b87ca..94c718466f 100644 --- a/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutBottomSheetDialogFragment.kt @@ -18,7 +18,6 @@ package im.vector.riotx.features.workers.signout import android.app.Activity import android.app.Dialog -import android.content.Context import android.content.Intent import android.os.Bundle import android.view.LayoutInflater @@ -31,27 +30,19 @@ import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelProviders import androidx.transition.TransitionManager import butterknife.BindView import butterknife.ButterKnife import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.riotx.R -import im.vector.riotx.core.di.DaggerScreenComponent -import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.riotx.core.utils.toast import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupActivity -class SignOutBottomSheetDialogFragment : BottomSheetDialogFragment() { - - lateinit var session: Session - lateinit var viewModelFactory: ViewModelProvider.Factory +class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment() { @BindView(R.id.bottom_sheet_signout_warning_text) lateinit var sheetTitle: TextView @@ -97,20 +88,10 @@ class SignOutBottomSheetDialogFragment : BottomSheetDialogFragment() { private lateinit var viewModel: SignOutViewModel - override fun onAttach(context: Context) { - super.onAttach(context) - val vectorBaseActivity = activity as VectorBaseActivity - val screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity) - viewModelFactory = screenComponent.viewModelFactory() - session = screenComponent.activeSessionHolder().getActiveSession() - } - override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProviders.of(this, viewModelFactory).get(SignOutViewModel::class.java) - - viewModel.init(session) + viewModel = fragmentViewModelProvider.get(SignOutViewModel::class.java) setupClickableView.setOnClickListener { context?.let { context -> @@ -162,7 +143,7 @@ class SignOutBottomSheetDialogFragment : BottomSheetDialogFragment() { } } - viewModel.keysExportedToFile.observe(this, Observer { + viewModel.keysExportedToFile.observe(viewLifecycleOwner, Observer { val hasExportedToFile = it ?: false if (hasExportedToFile) { // We can allow to sign out @@ -177,7 +158,7 @@ class SignOutBottomSheetDialogFragment : BottomSheetDialogFragment() { } }) - viewModel.keysBackupState.observe(this, Observer { + viewModel.keysBackupState.observe(viewLifecycleOwner, Observer { if (viewModel.keysExportedToFile.value == true) { // ignore this return@Observer diff --git a/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutViewModel.kt b/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutViewModel.kt index c32d6f6631..8964b29952 100644 --- a/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/workers/signout/SignOutViewModel.kt @@ -23,59 +23,43 @@ import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener import javax.inject.Inject -class SignOutViewModel @Inject constructor() : ViewModel(), KeysBackupStateListener { +class SignOutViewModel @Inject constructor(private val session: Session) : ViewModel(), KeysBackupStateListener { // Keys exported manually var keysExportedToFile = MutableLiveData() var keysBackupState = MutableLiveData() - private var mxSession: Session? = null + init { + session.getKeysBackupService().addListener(this) - fun init(session: Session) { - if (mxSession == null) { - mxSession = session - - mxSession?.getKeysBackupService() - ?.addListener(this) - } - - keysBackupState.value = mxSession?.getKeysBackupService() - ?.state + keysBackupState.value = session.getKeysBackupService().state } /** * Safe way to get the current KeysBackup version */ fun getCurrentBackupVersion(): String { - return mxSession - ?.getKeysBackupService() - ?.currentBackupVersion - ?: "" + return session.getKeysBackupService().currentBackupVersion ?: "" } /** * Safe way to get the number of keys to backup */ fun getNumberOfKeysToBackup(): Int { - return mxSession - ?.inboundGroupSessionsCount(false) - ?: 0 + return session.inboundGroupSessionsCount(false) } /** * Safe way to tell if there are more keys on the server */ fun canRestoreKeys(): Boolean { - return mxSession - ?.getKeysBackupService() - ?.canRestoreKeys() == true + return session.getKeysBackupService().canRestoreKeys() } override fun onCleared() { super.onCleared() - mxSession?.getKeysBackupService() - ?.removeListener(this) + session.getKeysBackupService().removeListener(this) } override fun onStateChange(newState: KeysBackupState) { @@ -84,7 +68,7 @@ class SignOutViewModel @Inject constructor() : ViewModel(), KeysBackupStateListe fun refreshRemoteStateIfNeeded() { if (keysBackupState.value == KeysBackupState.Disabled) { - mxSession?.getKeysBackupService()?.checkAndStartKeysBackup() + session.getKeysBackupService().checkAndStartKeysBackup() } } @@ -92,13 +76,9 @@ class SignOutViewModel @Inject constructor() : ViewModel(), KeysBackupStateListe /** * The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready */ - fun doYouNeedToBeDisplayed(session: Session?): Boolean { - return session - ?.inboundGroupSessionsCount(false) - ?: 0 > 0 - && session - ?.getKeysBackupService() - ?.state != KeysBackupState.ReadyToBackUp + fun doYouNeedToBeDisplayed(session: Session): Boolean { + return session.inboundGroupSessionsCount(false) > 0 + && session.getKeysBackupService().state != KeysBackupState.ReadyToBackUp } } } From 50e2e6a82355055add1c3e363ae50eae8daef5a0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 17:23:21 +0100 Subject: [PATCH 096/117] Cleanup --- .../crypto/keysbackup/restore/KeysBackupRestoreActivity.kt | 1 - .../keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt | 1 - .../restore/KeysBackupRestoreFromPassphraseFragment.kt | 1 - .../keysbackup/restore/KeysBackupRestoreSuccessFragment.kt | 1 - .../features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt | 1 - .../crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt | 1 - .../crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt | 1 - .../crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt | 1 - .../features/crypto/verification/SASVerificationActivity.kt | 1 - .../crypto/verification/SASVerificationIncomingFragment.kt | 1 - .../crypto/verification/SASVerificationShortCodeFragment.kt | 1 - .../features/crypto/verification/SASVerificationStartFragment.kt | 1 - .../crypto/verification/SASVerificationVerifiedFragment.kt | 1 - .../src/main/java/im/vector/riotx/features/home/HomeActivity.kt | 1 - .../riotx/features/home/createdirect/CreateDirectRoomActivity.kt | 1 - .../home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt | 1 - .../home/createdirect/CreateDirectRoomKnownUsersFragment.kt | 1 - .../im/vector/riotx/features/home/group/GroupListFragment.kt | 1 - .../vector/riotx/features/home/room/detail/RoomDetailFragment.kt | 1 - .../room/detail/timeline/action/MessageActionsBottomSheet.kt | 1 - .../im/vector/riotx/features/home/room/list/RoomListFragment.kt | 1 - .../home/room/list/actions/RoomListQuickActionsBottomSheet.kt | 1 - .../im/vector/riotx/features/reactions/EmojiChooserFragment.kt | 1 - .../riotx/features/reactions/EmojiReactionPickerActivity.kt | 1 - .../vector/riotx/features/reactions/EmojiSearchResultFragment.kt | 1 - .../vector/riotx/features/roomdirectory/PublicRoomsFragment.kt | 1 - .../vector/riotx/features/roomdirectory/RoomDirectoryActivity.kt | 1 - .../features/roomdirectory/createroom/CreateRoomActivity.kt | 1 - .../features/roomdirectory/createroom/CreateRoomFragment.kt | 1 - .../features/roomdirectory/picker/RoomDirectoryPickerFragment.kt | 1 - 30 files changed, 30 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt index 7befd54ccd..a12a43d06f 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt @@ -21,7 +21,6 @@ import android.content.Intent import androidx.appcompat.app.AlertDialog import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import im.vector.riotx.R import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.extensions.observeEvent diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt index 38bb08688d..730c92a319 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt @@ -22,7 +22,6 @@ import android.text.Editable import android.view.inputmethod.EditorInfo import android.widget.EditText import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import butterknife.OnTextChanged diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt index e75163f45c..a9bdeee2d6 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt @@ -27,7 +27,6 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.text.set import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import butterknife.OnTextChanged diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index e938abf54f..0f681af737 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -17,7 +17,6 @@ package im.vector.riotx.features.crypto.keysbackup.restore import android.os.Bundle import android.widget.TextView -import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import im.vector.riotx.R diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 49149e5d98..b77620b15b 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -21,7 +21,6 @@ import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import im.vector.matrix.android.api.MatrixCallback import im.vector.riotx.R import im.vector.riotx.core.dialogs.ExportKeysDialog diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index efa10d8e84..a9bfbd83b0 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -21,7 +21,6 @@ import android.view.View import android.widget.Button import android.widget.TextView import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import im.vector.riotx.R diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt index 8e27c57af6..3522c5a752 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt @@ -22,7 +22,6 @@ import android.view.inputmethod.EditorInfo import android.widget.EditText import android.widget.ImageView import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import androidx.transition.TransitionManager import butterknife.BindView import butterknife.OnClick diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index 41de7c9a8a..52470a47b2 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -24,7 +24,6 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import arrow.core.Try import butterknife.BindView import butterknife.OnClick diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt index 3e0ecbc39f..cb5391be3c 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt @@ -21,7 +21,6 @@ import android.content.Intent import android.view.MenuItem import androidx.appcompat.app.AlertDialog import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import im.vector.matrix.android.api.session.crypto.sas.CancelCode import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt index c5c697277e..88df53d0f3 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationIncomingFragment.kt @@ -19,7 +19,6 @@ import android.os.Bundle import android.widget.ImageView import android.widget.TextView import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt index c4b9d39f39..ec9a943449 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationShortCodeFragment.kt @@ -21,7 +21,6 @@ import android.widget.TextView import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.OnClick import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt index 94539e8c68..d9c3b1d155 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationStartFragment.kt @@ -23,7 +23,6 @@ import android.widget.TextView import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import androidx.transition.TransitionManager import butterknife.BindView import butterknife.OnClick diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt index bc9bb71143..17beb21aff 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationVerifiedFragment.kt @@ -16,7 +16,6 @@ package im.vector.riotx.features.crypto.verification import android.os.Bundle -import androidx.lifecycle.ViewModelProviders import butterknife.OnClick import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index c12f6fc32f..104aa301cb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -26,7 +26,6 @@ import androidx.core.view.GravityCompat import androidx.core.view.isVisible import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.di.ScreenComponent diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt index c32fe36bbc..f7a68d4552 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomActivity.kt @@ -23,7 +23,6 @@ import android.content.Intent import android.os.Bundle import android.view.View import androidx.appcompat.app.AlertDialog -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.* import im.vector.matrix.android.api.session.room.failure.CreateRoomFailure import im.vector.riotx.R diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index 07dccf1f80..fe43b89a52 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -19,7 +19,6 @@ package im.vector.riotx.features.home.createdirect import android.content.Context import android.os.Bundle import android.view.inputmethod.InputMethodManager -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import com.jakewharton.rxbinding3.widget.textChanges diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 4e87d59f62..26265c8d56 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -23,7 +23,6 @@ import android.view.Menu import android.view.MenuItem import android.widget.ScrollView import androidx.core.view.size -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import com.google.android.material.chip.Chip 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 fbc9f5ca4c..bc39491773 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 @@ -17,7 +17,6 @@ package im.vector.riotx.features.home.group import android.os.Bundle -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.Incomplete import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel 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 969bacaf6d..f085eca233 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 @@ -40,7 +40,6 @@ import androidx.core.content.ContextCompat import androidx.core.util.Pair import androidx.core.view.ViewCompat import androidx.core.view.forEach -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView 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 a0bf43e6db..3f4171f733 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 @@ -19,7 +19,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import butterknife.BindView 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 9c575c5dd2..9c78b8688a 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 @@ -24,7 +24,6 @@ import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.view.isVisible -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.* diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index f1350a9b0b..3a85cf26fa 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -21,7 +21,6 @@ import android.os.Parcelable import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import butterknife.BindView diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index 4bfde22774..a32fa27bd5 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -16,7 +16,6 @@ package im.vector.riotx.features.reactions import android.os.Bundle -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.RecyclerView import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment 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 966329e8d8..85e4eecf21 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 @@ -27,7 +27,6 @@ import android.widget.SearchView import androidx.appcompat.widget.Toolbar import androidx.core.view.isVisible import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.viewModel import com.google.android.material.tabs.TabLayout import com.jakewharton.rxbinding3.widget.queryTextChanges diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt index 2c97d9fee5..ca4f18fe83 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt @@ -16,7 +16,6 @@ package im.vector.riotx.features.reactions import android.os.Bundle -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView 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 cf60ba68a0..21eedb4b24 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 @@ -19,7 +19,6 @@ package im.vector.riotx.features.roomdirectory import android.os.Bundle import android.view.MenuItem import android.view.View -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import com.airbnb.epoxy.EpoxyVisibilityTracker import com.airbnb.mvrx.activityViewModel 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 5ba20e0e53..e5ae0d4f54 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 @@ -19,7 +19,6 @@ package im.vector.riotx.features.roomdirectory import android.content.Context import android.content.Intent import android.os.Bundle -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.viewModel import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent 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 64f3563e20..a83208c98a 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 @@ -20,7 +20,6 @@ import android.content.Context import android.content.Intent import android.os.Bundle import androidx.appcompat.widget.Toolbar -import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.viewModel import im.vector.riotx.R import im.vector.riotx.core.extensions.addFragment 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 cdf006a4e7..0399ea0b57 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 @@ -18,7 +18,6 @@ package im.vector.riotx.features.roomdirectory.createroom import android.os.Bundle import android.view.MenuItem -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import com.airbnb.mvrx.Success import com.airbnb.mvrx.activityViewModel 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 11a08c6291..bad8486405 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 @@ -19,7 +19,6 @@ package im.vector.riotx.features.roomdirectory.picker import android.os.Bundle import android.view.MenuItem import android.view.View -import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.fragmentViewModel From 603b8fae45104bfd2733541b6083d6ed1adc6ba9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Nov 2019 17:30:04 +0100 Subject: [PATCH 097/117] Add missing binding --- .../main/java/im/vector/riotx/core/di/ViewModelModule.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt index d4e55e6080..cc1e4dabc7 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ViewModelModule.kt @@ -32,6 +32,7 @@ import im.vector.riotx.features.home.createdirect.CreateDirectRoomSharedActionVi import im.vector.riotx.features.home.room.detail.timeline.action.MessageSharedActionViewModel import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.riotx.features.reactions.EmojiChooserViewModel +import im.vector.riotx.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.riotx.features.workers.signout.SignOutViewModel @Module @@ -106,4 +107,9 @@ interface ViewModelModule { @IntoMap @ViewModelKey(RoomListQuickActionsSharedActionViewModel::class) fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomDirectorySharedActionViewModel::class) + fun bindRoomDirectorySharedActionViewModel(viewModel: RoomDirectorySharedActionViewModel): ViewModel } From b6199b1f27003a5ce66b09ae2d03995d8b8efb7c Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 8 Nov 2019 19:49:08 +0100 Subject: [PATCH 098/117] Fix some issues with fragments managers (Home fragments) and lifecycle --- .../vector/riotx/core/extensions/Fragment.kt | 10 ++++---- .../riotx/core/platform/VectorBaseFragment.kt | 5 ++-- .../im/vector/riotx/core/utils/DataSource.kt | 12 +++++----- .../riotx/features/home/HomeDetailFragment.kt | 24 +++++++++++-------- .../riotx/features/home/HomeDrawerFragment.kt | 6 +++-- .../CreateDirectRoomDirectoryUsersFragment.kt | 7 +++--- .../CreateDirectRoomKnownUsersFragment.kt | 7 +++--- .../features/home/group/GroupListFragment.kt | 5 ++-- .../home/room/detail/RoomDetailFragment.kt | 9 ++++--- .../home/room/list/RoomListFragment.kt | 15 +++++++----- .../riotx/features/login/LoginFragment.kt | 4 ++-- .../reactions/EmojiChooserFragment.kt | 6 +++-- .../reactions/EmojiSearchResultFragment.kt | 6 ++--- .../roomdirectory/PublicRoomsFragment.kt | 2 +- .../createroom/CreateRoomFragment.kt | 5 ++-- .../picker/RoomDirectoryPickerFragment.kt | 8 +++---- .../RoomPreviewNoPreviewFragment.kt | 7 +----- 17 files changed, 75 insertions(+), 63 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt index e6e83bfd67..f96b773990 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt @@ -41,7 +41,7 @@ fun VectorBaseFragment.replaceFragment(frameId: Int, fragmentClas } fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - parentFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } + parentFragmentManager.inTransaction { replace(frameId, fragment, tag).addToBackStack(tag) } } fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { @@ -50,8 +50,8 @@ fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragm } } -fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment) { - childFragmentManager.inTransaction { add(frameId, fragment) } +fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { + childFragmentManager.inTransaction { add(frameId, fragment, tag) } } fun VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { @@ -60,8 +60,8 @@ fun VectorBaseFragment.addChildFragment(frameId: Int, fragmentCla } } -fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment) { - childFragmentManager.inTransaction { replace(frameId, fragment) } +fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { + childFragmentManager.inTransaction { replace(frameId, fragment, tag) } } fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt index 255e18608a..9f94c15edd 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt @@ -114,11 +114,12 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { super.onDestroyView() mUnBinder?.unbind() mUnBinder = null + uiDisposables.clear() } override fun onDestroy() { - super.onDestroy() uiDisposables.dispose() + super.onDestroy() } override fun injector(): ScreenComponent { @@ -181,7 +182,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { private val uiDisposables = CompositeDisposable() - protected fun Disposable.disposeOnDestroy(): Disposable { + protected fun Disposable.disposeOnDestroyView(): Disposable { uiDisposables.add(this) return this } diff --git a/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt b/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt index 6c317eb977..726d2ea697 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/DataSource.kt @@ -34,14 +34,14 @@ interface MutableDataSource : DataSource { */ open class BehaviorDataSource(private val defaultValue: T? = null) : MutableDataSource { - private val storeRelay = createRelay() + private val behaviorRelay = createRelay() override fun observe(): Observable { - return storeRelay.hide().observeOn(Schedulers.computation()) + return behaviorRelay.hide().observeOn(Schedulers.computation()) } override fun post(value: T) { - storeRelay.accept(value) + behaviorRelay.accept(value) } private fun createRelay(): BehaviorRelay { @@ -58,13 +58,13 @@ open class BehaviorDataSource(private val defaultValue: T? = null) : MutableD */ open class PublishDataSource : MutableDataSource { - private val storeRelay = PublishRelay.create() + private val publishRelay = PublishRelay.create() override fun observe(): Observable { - return storeRelay.hide() + return publishRelay.hide() } override fun post(value: T) { - storeRelay.accept(value) + publishRelay.accept(value) } } 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 5b56a19648..7aa96d0b8d 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 @@ -18,6 +18,7 @@ package im.vector.riotx.features.home import android.os.Bundle import android.view.LayoutInflater +import android.view.View import androidx.core.view.forEachIndexed import androidx.lifecycle.Observer import com.airbnb.mvrx.fragmentViewModel @@ -28,7 +29,8 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R -import im.vector.riotx.core.extensions.addChildFragmentToBackstack +import im.vector.riotx.core.extensions.inTransaction +import im.vector.riotx.core.extensions.replaceChildFragment import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.KeysBackupBanner @@ -59,9 +61,8 @@ class HomeDetailFragment @Inject constructor( return R.layout.fragment_home_detail } - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java) setupBottomNavigationView() @@ -165,12 +166,15 @@ class HomeDetailFragment @Inject constructor( private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) { val fragmentTag = "FRAGMENT_TAG_${displayMode.name}" - val fragment = childFragmentManager.findFragmentByTag(fragmentTag) - if (fragment == null) { - val params = RoomListParams(displayMode) - addChildFragmentToBackstack(R.id.roomListContainer, RoomListFragment::class.java, params, fragmentTag) - } else { - addChildFragmentToBackstack(R.id.roomListContainer, fragment, fragmentTag) + val fragmentToShow = childFragmentManager.findFragmentByTag(fragmentTag) + childFragmentManager.inTransaction { + childFragmentManager.fragments.forEach { hide(it) } + if (fragmentToShow == null) { + val params = RoomListParams(displayMode) + add(R.id.roomListContainer, RoomListFragment::class.java, params.toMvRxBundle(), fragmentTag) + } else { + show(fragmentToShow) + } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt index 5b052f5ff5..f48c5650f5 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt @@ -17,6 +17,7 @@ package im.vector.riotx.features.home import android.os.Bundle +import android.view.View import im.vector.matrix.android.api.session.Session import im.vector.riotx.R import im.vector.riotx.core.extensions.observeK @@ -33,8 +34,8 @@ class HomeDrawerFragment @Inject constructor( override fun getLayoutResId() = R.layout.fragment_home_drawer - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) if (savedInstanceState == null) { replaceChildFragment(R.id.homeDrawerGroupListContainer, GroupListFragment::class.java) } @@ -55,4 +56,5 @@ class HomeDrawerFragment @Inject constructor( navigator.openDebug(requireActivity()) } } + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt index fe43b89a52..cf6abf12e9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomDirectoryUsersFragment.kt @@ -18,6 +18,7 @@ package im.vector.riotx.features.home.createdirect import android.content.Context import android.os.Bundle +import android.view.View import android.view.inputmethod.InputMethodManager import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState @@ -40,8 +41,8 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( private lateinit var sharedActionViewModel: CreateDirectRoomSharedActionViewModel - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(CreateDirectRoomSharedActionViewModel::class.java) setupRecyclerView() setupSearchByMatrixIdView() @@ -61,7 +62,7 @@ class CreateDirectRoomDirectoryUsersFragment @Inject constructor( .subscribe { viewModel.handle(CreateDirectRoomAction.SearchDirectoryUsers(it.toString())) } - .disposeOnDestroy() + .disposeOnDestroyView() createDirectRoomSearchById.requestFocus() val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager imm?.showSoftInput(createDirectRoomSearchById, InputMethodManager.SHOW_IMPLICIT) diff --git a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt index 26265c8d56..12019fa39e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/createdirect/CreateDirectRoomKnownUsersFragment.kt @@ -21,6 +21,7 @@ package im.vector.riotx.features.home.createdirect import android.os.Bundle import android.view.Menu import android.view.MenuItem +import android.view.View import android.widget.ScrollView import androidx.core.view.size import com.airbnb.mvrx.activityViewModel @@ -50,8 +51,8 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( private val viewModel: CreateDirectRoomViewModel by activityViewModel() private lateinit var sharedActionViewModel: CreateDirectRoomSharedActionViewModel - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(CreateDirectRoomSharedActionViewModel::class.java) vectorBaseActivity.setSupportActionBar(createDirectRoomToolbar) setupRecyclerView() @@ -113,7 +114,7 @@ class CreateDirectRoomKnownUsersFragment @Inject constructor( } viewModel.handle(action) } - .disposeOnDestroy() + .disposeOnDestroyView() createDirectRoomFilter.setupAsSearch() createDirectRoomFilter.requestFocus() 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 bc39491773..39f8c17f05 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 @@ -17,6 +17,7 @@ package im.vector.riotx.features.home.group import android.os.Bundle +import android.view.View import com.airbnb.mvrx.Incomplete import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel @@ -40,8 +41,8 @@ class GroupListFragment @Inject constructor( override fun getLayoutResId() = R.layout.fragment_group_list - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java) groupController.callback = this stateView.contentView = groupListEpoxyRecyclerView 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 c5cd46482e..062a4be2d2 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 @@ -203,8 +203,8 @@ class RoomDetailFragment @Inject constructor( private var lockSendButton = false - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java) attachmentsHelper = AttachmentsHelper.create(this, this).register() keyboardStateUtils = KeyboardStateUtils(requireActivity()) @@ -228,7 +228,7 @@ class RoomDetailFragment @Inject constructor( .subscribe { handleActions(it) } - .disposeOnDestroy() + .disposeOnDestroyView() roomDetailViewModel.navigateToEvent.observeEvent(this) { val scrollPosition = timelineEventController.searchPositionOfEvent(it) @@ -273,7 +273,10 @@ class RoomDetailFragment @Inject constructor( roomDetailViewModel.requestLiveData.observeEvent(this) { displayRoomDetailActionResult(it) } + } + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) if (savedInstanceState == null) { when (val sharedData = roomDetailArgs.sharedData) { is SharedData.Text -> roomDetailViewModel.handle(RoomDetailAction.SendMessage(sharedData.text, false)) 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 9c78b8688a..92080c1b1f 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 @@ -20,6 +20,7 @@ import android.os.Bundle import android.os.Parcelable import android.view.Menu import android.view.MenuItem +import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat @@ -45,8 +46,10 @@ import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.functions.Consumer import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_room_list.* +import timber.log.Timber import javax.inject.Inject @Parcelize @@ -97,13 +100,13 @@ class RoomListFragment @Inject constructor( super.onPrepareOptionsMenu(menu) } - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) setupCreateRoomButton() setupRecyclerView() - roomListViewModel.subscribe { renderState(it) } + sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java) + roomListViewModel.subscribe { renderState(it) } roomListViewModel.viewEvents .observe() .observeOn(AndroidSchedulers.mainThread()) @@ -113,14 +116,14 @@ class RoomListFragment @Inject constructor( is RoomListViewEvents.Failure -> showError(it) } } - .disposeOnDestroy() + .disposeOnDestroyView() createChatFabMenu.listener = this sharedActionViewModel .observe() .subscribe { handleQuickActions(it) } - .disposeOnDestroy() + .disposeOnDestroyView() } private fun openSelectedRoom(event: RoomListViewEvents.SelectRoom) { diff --git a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt index f8295310f9..456e4b2bb3 100644 --- a/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/login/LoginFragment.kt @@ -62,7 +62,7 @@ class LoginFragment @Inject constructor() : VectorBaseFragment() { viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString())) } } - .disposeOnDestroy() + .disposeOnDestroyView() homeServerField.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { @@ -107,7 +107,7 @@ class LoginFragment @Inject constructor() : VectorBaseFragment() { } ) .subscribeBy { authenticateButton.isEnabled = it } - .disposeOnDestroy() + .disposeOnDestroyView() authenticateButton.setOnClickListener { authenticate() } authenticateButtonSso.setOnClickListener { openSso() } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index a32fa27bd5..c66e322bae 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.reactions import android.os.Bundle +import android.view.View import androidx.recyclerview.widget.RecyclerView import im.vector.riotx.R import im.vector.riotx.core.platform.VectorBaseFragment @@ -27,8 +28,8 @@ class EmojiChooserFragment @Inject constructor() : VectorBaseFragment() { private lateinit var viewModel: EmojiChooserViewModel - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) viewModel = activityViewModelProvider.get(EmojiChooserViewModel::class.java) viewModel.initWithContext(context!!) (view as? RecyclerView)?.let { @@ -36,4 +37,5 @@ class EmojiChooserFragment @Inject constructor() : VectorBaseFragment() { it.adapter?.notifyDataSetChanged() } } + } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt index ca4f18fe83..029f468b70 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiSearchResultFragment.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.reactions import android.os.Bundle +import android.view.View import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -37,9 +38,8 @@ class EmojiSearchResultFragment @Inject constructor( var sharedViewModel: EmojiChooserViewModel? = null - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) sharedViewModel = activityViewModelProvider.get(EmojiChooserViewModel::class.java) epoxyController.listener = object : ReactionClickListener { 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 21eedb4b24..b41c563256 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 @@ -67,7 +67,7 @@ class PublicRoomsFragment @Inject constructor( .subscribeBy { viewModel.handle(RoomDirectoryAction.FilterWith(it.toString())) } - .disposeOnDestroy() + .disposeOnDestroyView() publicRoomsCreateNewRoom.setOnClickListener { sharedActionViewModel.post(RoomDirectorySharedAction.CreateRoom) 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 0399ea0b57..0dec14f50e 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 @@ -18,6 +18,7 @@ package im.vector.riotx.features.roomdirectory.createroom import android.os.Bundle import android.view.MenuItem +import android.view.View import androidx.recyclerview.widget.LinearLayoutManager import com.airbnb.mvrx.Success import com.airbnb.mvrx.activityViewModel @@ -39,8 +40,8 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C override fun getMenuRes() = R.menu.vector_room_creation - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) vectorBaseActivity.setSupportActionBar(createRoomToolbar) sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() 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 bad8486405..87cb8193bf 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 @@ -55,6 +55,9 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie it.setDisplayShowHomeEnabled(true) it.setDisplayHomeAsUpEnabled(true) } + + sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) + setupRecyclerView() } override fun getMenuRes() = R.menu.menu_directory_server_picker @@ -69,11 +72,6 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie return super.onOptionsItemSelected(item) } - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) - setupRecyclerView() - } private fun setupRecyclerView() { val layoutManager = LinearLayoutManager(context) 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 38e74c035a..9003421dc7 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 @@ -45,16 +45,11 @@ class RoomPreviewNoPreviewFragment @Inject constructor( private val roomPreviewViewModel: RoomPreviewViewModel by fragmentViewModel() private val roomPreviewData: RoomPreviewData by args() - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - setupToolbar(roomPreviewNoPreviewToolbar) - } - override fun getLayoutResId() = R.layout.fragment_room_preview_no_preview override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + setupToolbar(roomPreviewNoPreviewToolbar) // Toolbar avatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewToolbarAvatar) roomPreviewNoPreviewToolbarTitle.text = roomPreviewData.roomName From 9c5c65a243b009924042b78eb251877140b35192 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Nov 2019 10:13:12 +0100 Subject: [PATCH 099/117] Cleanup --- .../im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt | 1 - .../java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt | 1 - vector/src/main/res/values-de/strings.xml | 2 +- vector/src/main/res/values-zh-rTW/strings.xml | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt b/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt index 49756d0c1a..ba1c47c08c 100644 --- a/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt +++ b/vector/src/debug/java/im/vector/riotx/features/debug/sas/DebugSasEmojiActivity.kt @@ -24,7 +24,6 @@ import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.* class DebugSasEmojiActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.fragment_generic_recycler_epoxy) diff --git a/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt b/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt index e7f152673c..92d9bc0b11 100644 --- a/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt +++ b/vector/src/debug/java/im/vector/riotx/features/debug/sas/ItemSasEmoji.kt @@ -24,7 +24,6 @@ import im.vector.matrix.android.api.session.crypto.sas.EmojiRepresentation import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel - @EpoxyModelClass(layout = im.vector.riotx.R.layout.item_sas_emoji) abstract class ItemSasEmoji : VectorEpoxyModel() { diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 356e3fdaaa..251c42c00c 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1662,7 +1662,7 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A Kein Integrationsserver konfiguriert. Anruf aufgrund eines falsch konfigurierten Servers fehlgeschlagen - Versuchen Sie es mit %@ + Versuchen Sie es mit %s Nicht erneut fragen Richten Sie eine E-Mail für die Kontowiederherstellung ein, die später von Personen, die Sie kennen, optional gefunden werden kann. diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 837e75583a..a1d6ceb32b 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -1675,7 +1675,7 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 跳到底部 %1$s、%2$s 與 %3$d 個其他人已閱讀 - %1$s、%2$s 與 %3$d 已閱讀 + %1$s、%2$s 與 %3$s 已閱讀 %1$s 與 %2$s 已閱讀 %s 已閱讀 From 08c864bad7b0842ab51eb440cd2f6e6b3fb67807 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Nov 2019 11:39:47 +0100 Subject: [PATCH 100/117] Add help to reveal the long click on a room --- .../vector/riotx/core/epoxy/HelpFooterItem.kt | 37 +++++++++++++++++++ .../core/resources/UserPreferencesProvider.kt | 8 ++++ .../home/room/list/RoomListFragment.kt | 4 +- .../home/room/list/RoomSummaryController.kt | 23 +++++++++++- .../features/settings/VectorPreferences.kt | 21 +++++++++++ vector/src/main/res/drawable/ic_idea.xml | 10 +++++ .../src/main/res/layout/item_help_footer.xml | 23 ++++++++++++ vector/src/main/res/values/strings_riotX.xml | 2 + 8 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/core/epoxy/HelpFooterItem.kt create mode 100644 vector/src/main/res/drawable/ic_idea.xml create mode 100644 vector/src/main/res/layout/item_help_footer.xml diff --git a/vector/src/main/java/im/vector/riotx/core/epoxy/HelpFooterItem.kt b/vector/src/main/java/im/vector/riotx/core/epoxy/HelpFooterItem.kt new file mode 100644 index 0000000000..2784db5fce --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/core/epoxy/HelpFooterItem.kt @@ -0,0 +1,37 @@ +/* + * 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.core.epoxy + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.riotx.R + +@EpoxyModelClass(layout = R.layout.item_help_footer) +abstract class HelpFooterItem : VectorEpoxyModel() { + + @EpoxyAttribute + var text: String? = null + + override fun bind(holder: Holder) { + holder.textView.text = text + } + + class Holder : VectorEpoxyHolder() { + val textView by bind(R.id.itemHelpText) + } +} diff --git a/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt b/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt index bf3e360699..ac379a8f98 100644 --- a/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt +++ b/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt @@ -28,4 +28,12 @@ class UserPreferencesProvider @Inject constructor(private val vectorPreferences: fun shouldShowReadReceipts(): Boolean { return vectorPreferences.showReadReceipts() } + + fun shouldShowLongClickOnRoomHelp(): Boolean { + return vectorPreferences.shouldShowLongClickOnRoomHelp() + } + + fun neverShowLongClickOnRoomHelpAgain() { + vectorPreferences.neverShowLongClickOnRoomHelpAgain() + } } 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 9c78b8688a..df8bca7a2f 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 @@ -38,8 +38,8 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet +import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager @@ -345,6 +345,8 @@ class RoomListFragment @Inject constructor( } override fun onRoomLongClicked(room: RoomSummary): Boolean { + roomController.onRoomLongClicked() + RoomListQuickActionsBottomSheet .newInstance(room.roomId) .show(requireActivity().supportFragmentManager, "ROOM_LIST_QUICK_ACTIONS") diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt index 3401e041b1..5cd684b275 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt @@ -21,15 +21,18 @@ import com.airbnb.epoxy.EpoxyController import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.R +import im.vector.riotx.core.epoxy.helpFooterItem import im.vector.riotx.core.epoxy.noResultItem import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.core.resources.UserPreferencesProvider import im.vector.riotx.features.home.room.filtered.FilteredRoomFooterItem import im.vector.riotx.features.home.room.filtered.filteredRoomFooterItem import javax.inject.Inject class RoomSummaryController @Inject constructor(private val stringProvider: StringProvider, private val roomSummaryItemFactory: RoomSummaryItemFactory, - private val roomListNameFilter: RoomListNameFilter + private val roomListNameFilter: RoomListNameFilter, + private val userPreferencesProvider: UserPreferencesProvider ) : EpoxyController() { var listener: Listener? = null @@ -47,6 +50,11 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri requestModelBuild() } + fun onRoomLongClicked() { + userPreferencesProvider.neverShowLongClickOnRoomHelpAgain() + requestModelBuild() + } + override fun buildModels() { val nonNullViewState = viewState ?: return when (nonNullViewState.displayMode) { @@ -55,6 +63,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri buildFilteredRooms(nonNullViewState) } else -> { + var showHelp = false val roomSummaries = nonNullViewState.asyncFilteredRooms() roomSummaries?.forEach { (category, summaries) -> if (summaries.isEmpty()) { @@ -70,9 +79,14 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri nonNullViewState.joiningErrorRoomsIds, nonNullViewState.rejectingRoomsIds, nonNullViewState.rejectingErrorRoomsIds) + showHelp = userPreferencesProvider.shouldShowLongClickOnRoomHelp() } } } + + if (showHelp) { + buildLongClickHelp() + } } } } @@ -97,6 +111,13 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri } } + private fun buildLongClickHelp() { + helpFooterItem { + id("long_click_help") + text(stringProvider.getString(R.string.help_long_click_on_room_for_more_options)) + } + } + private fun addFilterFooter(viewState: RoomListViewState) { filteredRoomFooterItem { id("filter_footer") diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt index 78f57dd548..dd99488465 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt @@ -96,6 +96,9 @@ class VectorPreferences @Inject constructor(private val context: Context) { private const val SETTINGS_VIBRATE_ON_MENTION_KEY = "SETTINGS_VIBRATE_ON_MENTION_KEY" private const val SETTINGS_SEND_MESSAGE_WITH_ENTER = "SETTINGS_SEND_MESSAGE_WITH_ENTER" + // Help + private const val SETTINGS_SHOULD_SHOW_HELP_ON_ROOM_LIST_KEY = "SETTINGS_SHOULD_SHOW_HELP_ON_ROOM_LIST_KEY" + // home private const val SETTINGS_PIN_UNREAD_MESSAGES_PREFERENCE_KEY = "SETTINGS_PIN_UNREAD_MESSAGES_PREFERENCE_KEY" private const val SETTINGS_PIN_MISSED_NOTIFICATIONS_PREFERENCE_KEY = "SETTINGS_PIN_MISSED_NOTIFICATIONS_PREFERENCE_KEY" @@ -597,6 +600,24 @@ class VectorPreferences @Inject constructor(private val context: Context) { return defaultPrefs.getBoolean(SETTINGS_SHOW_READ_RECEIPTS_KEY, true) } + /** + * Tells if the help on room list should be shown + * + * @return true if the help on room list should be shown + */ + fun shouldShowLongClickOnRoomHelp(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_SHOULD_SHOW_HELP_ON_ROOM_LIST_KEY, true) + } + + /** + * Prevent help on room list to be shown again + */ + fun neverShowLongClickOnRoomHelpAgain() { + defaultPrefs.edit { + putBoolean(SETTINGS_SHOULD_SHOW_HELP_ON_ROOM_LIST_KEY, false) + } + } + /** * Tells if the message timestamps must be always shown * diff --git a/vector/src/main/res/drawable/ic_idea.xml b/vector/src/main/res/drawable/ic_idea.xml new file mode 100644 index 0000000000..4be057ec6c --- /dev/null +++ b/vector/src/main/res/drawable/ic_idea.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_help_footer.xml b/vector/src/main/res/layout/item_help_footer.xml new file mode 100644 index 0000000000..197c9e58ae --- /dev/null +++ b/vector/src/main/res/layout/item_help_footer.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index ad98fa2204..fcd9567de2 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -12,4 +12,6 @@ You are not ignoring any users + Long click on a room to see more options + From dbb41108ef4b7500eb041871ce3e6aff9ec56d4c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Nov 2019 11:50:16 +0100 Subject: [PATCH 101/117] Improve layout --- .../src/main/res/layout/item_help_footer.xml | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/layout/item_help_footer.xml b/vector/src/main/res/layout/item_help_footer.xml index 197c9e58ae..7a1db62872 100644 --- a/vector/src/main/res/layout/item_help_footer.xml +++ b/vector/src/main/res/layout/item_help_footer.xml @@ -1,23 +1,37 @@ - + + - \ No newline at end of file + \ No newline at end of file From 6463f3439f90c234047ff3536b5c2d864a6221fb Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 12 Nov 2019 15:11:52 +0100 Subject: [PATCH 102/117] Update Mvrx to 1.3 --- vector/build.gradle | 2 +- .../riotx/core/platform/VectorBaseActivity.kt | 4 ++-- .../VectorBaseBottomSheetDialogFragment.kt | 18 +++++------------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index d0a757d4e0..e425d53a62 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -268,7 +268,7 @@ dependencies { implementation("com.airbnb.android:epoxy:$epoxy_version") kapt "com.airbnb.android:epoxy-processor:$epoxy_version" implementation "com.airbnb.android:epoxy-paging:$epoxy_version" - implementation 'com.airbnb.android:mvrx:1.1.0' + implementation 'com.airbnb.android:mvrx:1.3.0' // Work implementation "androidx.work:work-runtime-ktx:2.3.0-alpha01" diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt index f0f6eea91d..4a3056657f 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt @@ -24,6 +24,7 @@ import android.view.Menu import android.view.MenuItem import android.view.View import androidx.annotation.* +import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible @@ -34,7 +35,6 @@ import androidx.lifecycle.ViewModelProviders import butterknife.BindView import butterknife.ButterKnife import butterknife.Unbinder -import com.airbnb.mvrx.BaseMvRxActivity import com.airbnb.mvrx.MvRx import com.bumptech.glide.util.Util import com.google.android.material.snackbar.Snackbar @@ -59,7 +59,7 @@ import io.reactivex.disposables.Disposable import timber.log.Timber import kotlin.system.measureTimeMillis -abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector { +abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { /* ========================================================================================== * UI * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt index 2c8f840a41..5727580653 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -25,24 +25,22 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.MvRxView -import com.airbnb.mvrx.MvRxViewModelStore +import com.airbnb.mvrx.MvRxViewId import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import im.vector.riotx.core.di.DaggerScreenComponent import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.utils.DimensionConverter -import java.util.* /** * Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment) */ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment(), MvRxView { - override val mvrxViewModelStore by lazy { MvRxViewModelStore(viewModelStore) } - private lateinit var mvrxPersistedViewId: String + private val mvrxViewIdProperty = MvRxViewId() + final override val mvrxViewId: String by mvrxViewIdProperty private lateinit var screenComponent: ScreenComponent - final override val mvrxViewId: String by lazy { mvrxPersistedViewId } /* ========================================================================================== * View model @@ -78,10 +76,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() protected open fun injectWith(screenComponent: ScreenComponent) = Unit override fun onCreate(savedInstanceState: Bundle?) { - mvrxViewModelStore.restoreViewModels(this, savedInstanceState) - mvrxPersistedViewId = savedInstanceState?.getString(PERSISTED_VIEW_ID_KEY) - ?: this::class.java.simpleName + "_" + UUID.randomUUID().toString() - + mvrxViewIdProperty.restoreFrom(savedInstanceState) super.onCreate(savedInstanceState) } @@ -98,8 +93,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - mvrxViewModelStore.saveViewModels(outState) - outState.putString(PERSISTED_VIEW_ID_KEY, mvrxViewId) + mvrxViewIdProperty.saveTo(outState) } override fun onStart() { @@ -121,5 +115,3 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() arguments = args?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } } } } - -private const val PERSISTED_VIEW_ID_KEY = "mvrx:bottomsheet_persisted_view_id" From 19b415871d3615124ec82e3d398289cd6bdfd441 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 12 Nov 2019 15:13:20 +0100 Subject: [PATCH 103/117] Extract displaymode, clear adapter on roomList/timeline and use commitNow when possible --- .../vector/riotx/core/extensions/Activity.kt | 12 ++-- .../vector/riotx/core/extensions/Fragment.kt | 24 +++---- .../riotx/core/extensions/FragmentManager.kt | 6 +- .../verification/SASVerificationActivity.kt | 18 +++--- .../riotx/features/home/HomeDetailAction.kt | 2 +- .../riotx/features/home/HomeDetailFragment.kt | 28 +++++---- .../features/home/HomeDetailViewModel.kt | 7 +++ .../features/home/HomeDetailViewState.kt | 7 ++- .../features/home/RoomListDisplayMode.kt | 28 +++++++++ .../home/room/detail/RoomDetailFragment.kt | 7 +++ .../room/filtered/FilteredRoomsActivity.kt | 3 +- .../room/list/RoomListDisplayModeFilter.kt | 13 ++-- .../home/room/list/RoomListFragment.kt | 62 +++++++++---------- .../home/room/list/RoomListViewModel.kt | 11 ++-- .../room/list/RoomListViewModelFactory.kt | 3 +- .../home/room/list/RoomListViewState.kt | 3 +- .../home/room/list/RoomSummaryController.kt | 7 ++- .../features/share/IncomingShareActivity.kt | 5 +- .../ui/SharedPreferencesUiStateRepository.kt | 18 +++--- .../riotx/features/ui/UiStateRepository.kt | 6 +- .../main/res/layout/fragment_room_list.xml | 8 +-- .../main/res/layout/motion_fab_menu_merge.xml | 2 +- 22 files changed, 169 insertions(+), 111 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.kt diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt index 6e4ecf4775..6d7c3d39e6 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt @@ -21,31 +21,31 @@ import androidx.fragment.app.Fragment import im.vector.riotx.core.platform.VectorBaseActivity fun VectorBaseActivity.addFragment(frameId: Int, fragment: Fragment) { - supportFragmentManager.inTransaction { add(frameId, fragment) } + supportFragmentManager.commitTransactionNow { add(frameId, fragment) } } fun VectorBaseActivity.addFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransactionNow { add(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseActivity.replaceFragment(frameId: Int, fragment: Fragment, tag: String? = null) { - supportFragmentManager.inTransaction { replace(frameId, fragment, tag) } + supportFragmentManager.commitTransactionNow { replace(frameId, fragment, tag) } } fun VectorBaseActivity.replaceFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransactionNow { replace(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - supportFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } + supportFragmentManager.commitTransaction { replace(frameId, fragment).addToBackStack(tag) } } fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt index f96b773990..7db27ececb 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt @@ -21,61 +21,61 @@ import androidx.fragment.app.Fragment import im.vector.riotx.core.platform.VectorBaseFragment fun VectorBaseFragment.addFragment(frameId: Int, fragment: Fragment) { - parentFragmentManager.inTransaction { add(frameId, fragment) } + parentFragmentManager.commitTransactionNow { add(frameId, fragment) } } fun VectorBaseFragment.addFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - parentFragmentManager.inTransaction { + parentFragmentManager.commitTransactionNow { add(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.replaceFragment(frameId: Int, fragment: Fragment) { - parentFragmentManager.inTransaction { replace(frameId, fragment) } + parentFragmentManager.commitTransactionNow { replace(frameId, fragment) } } fun VectorBaseFragment.replaceFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - parentFragmentManager.inTransaction { + parentFragmentManager.commitTransactionNow { replace(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - parentFragmentManager.inTransaction { replace(frameId, fragment, tag).addToBackStack(tag) } + parentFragmentManager.commitTransaction { replace(frameId, fragment, tag).addToBackStack(tag) } } fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - parentFragmentManager.inTransaction { + parentFragmentManager.commitTransaction { replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { - childFragmentManager.inTransaction { add(frameId, fragment, tag) } + childFragmentManager.commitTransactionNow { add(frameId, fragment, tag) } } fun VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - childFragmentManager.inTransaction { + childFragmentManager.commitTransactionNow { add(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { - childFragmentManager.inTransaction { replace(frameId, fragment, tag) } + childFragmentManager.commitTransactionNow { replace(frameId, fragment, tag) } } fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - childFragmentManager.inTransaction { + childFragmentManager.commitTransactionNow { replace(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - childFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } + childFragmentManager.commitTransaction { replace(frameId, fragment).addToBackStack(tag) } } fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - childFragmentManager.inTransaction { + childFragmentManager.commitTransaction { replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt b/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt index 1d7815b2b7..caf1bf90f8 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt @@ -18,6 +18,10 @@ package im.vector.riotx.core.extensions import androidx.fragment.app.FragmentTransaction -inline fun androidx.fragment.app.FragmentManager.inTransaction(func: FragmentTransaction.() -> FragmentTransaction) { +inline fun androidx.fragment.app.FragmentManager.commitTransactionNow(func: FragmentTransaction.() -> FragmentTransaction) { + beginTransaction().func().commitNow() +} + +inline fun androidx.fragment.app.FragmentManager.commitTransaction(func: FragmentTransaction.() -> FragmentTransaction) { beginTransaction().func().commit() } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt index cb5391be3c..cf80bf98fc 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt @@ -26,7 +26,7 @@ import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTr import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState import im.vector.riotx.R -import im.vector.riotx.core.extensions.inTransaction +import im.vector.riotx.core.extensions.commitTransaction import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.SimpleFragmentActivity import im.vector.riotx.core.platform.WaitingViewData @@ -102,20 +102,20 @@ class SASVerificationActivity : SimpleFragmentActivity() { IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT, IncomingSasVerificationTransaction.UxState.WAIT_FOR_KEY_AGREEMENT -> { supportActionBar?.setTitle(R.string.sas_incoming_request_title) - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationIncomingFragment::class.java, null) } } IncomingSasVerificationTransaction.UxState.WAIT_FOR_VERIFICATION, IncomingSasVerificationTransaction.UxState.SHOW_SAS -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) } } IncomingSasVerificationTransaction.UxState.VERIFIED -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) } @@ -133,20 +133,20 @@ class SASVerificationActivity : SimpleFragmentActivity() { OutgoingSasVerificationRequest.UxState.UNKNOWN, OutgoingSasVerificationRequest.UxState.WAIT_FOR_START, OutgoingSasVerificationRequest.UxState.WAIT_FOR_KEY_AGREEMENT -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationStartFragment::class.java, null) } } OutgoingSasVerificationRequest.UxState.SHOW_SAS, OutgoingSasVerificationRequest.UxState.WAIT_FOR_VERIFICATION -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) } } OutgoingSasVerificationRequest.UxState.VERIFIED -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) } @@ -172,13 +172,13 @@ class SASVerificationActivity : SimpleFragmentActivity() { finish() } SasVerificationViewModel.NAVIGATE_SAS_DISPLAY -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) } } SasVerificationViewModel.NAVIGATE_SUCCESS -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) } 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 index 189a1e8aeb..b4064f270e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt @@ -20,5 +20,5 @@ 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() + data class SwitchDisplayMode(val displayMode: RoomListDisplayMode) : 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 7aa96d0b8d..1c78acbcfe 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 @@ -29,8 +29,8 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R -import im.vector.riotx.core.extensions.inTransaction -import im.vector.riotx.core.extensions.replaceChildFragment +import im.vector.riotx.core.extensions.commitTransaction +import im.vector.riotx.core.extensions.commitTransactionNow import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.KeysBackupBanner @@ -134,10 +134,10 @@ class HomeDetailFragment @Inject constructor( private fun setupBottomNavigationView() { bottomNavigationView.setOnNavigationItemSelectedListener { val displayMode = when (it.itemId) { - R.id.bottom_action_home -> RoomListFragment.DisplayMode.HOME - R.id.bottom_action_people -> RoomListFragment.DisplayMode.PEOPLE - R.id.bottom_action_rooms -> RoomListFragment.DisplayMode.ROOMS - else -> RoomListFragment.DisplayMode.HOME + R.id.bottom_action_home -> RoomListDisplayMode.HOME + R.id.bottom_action_people -> RoomListDisplayMode.PEOPLE + R.id.bottom_action_rooms -> RoomListDisplayMode.ROOMS + else -> RoomListDisplayMode.HOME } viewModel.handle(HomeDetailAction.SwitchDisplayMode(displayMode)) true @@ -153,22 +153,26 @@ class HomeDetailFragment @Inject constructor( } } - private fun switchDisplayMode(displayMode: RoomListFragment.DisplayMode) { + private fun switchDisplayMode(displayMode: RoomListDisplayMode) { groupToolbarTitleView.setText(displayMode.titleRes) updateSelectedFragment(displayMode) // Update the navigation view (for when we restore the tabs) bottomNavigationView.selectedItemId = when (displayMode) { - RoomListFragment.DisplayMode.PEOPLE -> R.id.bottom_action_people - RoomListFragment.DisplayMode.ROOMS -> R.id.bottom_action_rooms + RoomListDisplayMode.PEOPLE -> R.id.bottom_action_people + RoomListDisplayMode.ROOMS -> R.id.bottom_action_rooms else -> R.id.bottom_action_home } } - private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) { + private fun updateSelectedFragment(displayMode: RoomListDisplayMode) { val fragmentTag = "FRAGMENT_TAG_${displayMode.name}" val fragmentToShow = childFragmentManager.findFragmentByTag(fragmentTag) - childFragmentManager.inTransaction { - childFragmentManager.fragments.forEach { hide(it) } + childFragmentManager.commitTransactionNow { + childFragmentManager.fragments + .filter { it != fragmentToShow } + .forEach { + hide(it) + } if (fragmentToShow == null) { val params = RoomListParams(displayMode) add(R.id.roomListContainer, RoomListFragment::class.java, params.toMvRxBundle(), fragmentTag) 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 ca552dc234..6b38fb34b1 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 @@ -22,11 +22,17 @@ 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.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.rx.rx 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.RoomCategory +import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.room.list.RoomSummaries import im.vector.riotx.features.ui.UiStateRepository import io.reactivex.schedulers.Schedulers @@ -144,4 +150,5 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho } .disposeOnClear() } + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt index b1c50b83cf..1fc3a1ef21 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt @@ -17,14 +17,19 @@ package im.vector.riotx.features.home import arrow.core.Option +import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized import im.vector.matrix.android.api.session.group.model.GroupSummary +import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.sync.SyncState import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.room.list.RoomSummaries data class HomeDetailViewState( val groupSummary: Option = Option.empty(), - val displayMode: RoomListFragment.DisplayMode = RoomListFragment.DisplayMode.HOME, + val asyncRooms: Async> = Uninitialized, + val displayMode: RoomListDisplayMode = RoomListDisplayMode.HOME, val notificationCountCatchup: Int = 0, val notificationHighlightCatchup: Boolean = false, val notificationCountPeople: Int = 0, diff --git a/vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.kt b/vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.kt new file mode 100644 index 0000000000..18b901a967 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.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.home + +import androidx.annotation.StringRes +import im.vector.riotx.R + +enum class RoomListDisplayMode(@StringRes val titleRes: Int) { + HOME(R.string.bottom_action_home), + PEOPLE(R.string.bottom_action_people_x), + ROOMS(R.string.bottom_action_rooms), + FILTERED(/* Not used */ 0), + SHARE(/* Not used */ 0) + } 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 062a4be2d2..3dcd185518 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 @@ -286,6 +286,11 @@ class RoomDetailFragment @Inject constructor( } } + override fun onDestroyView() { + super.onDestroyView() + recyclerView.adapter = null + } + override fun onDestroy() { debouncer.cancelAll() super.onDestroy() @@ -472,6 +477,7 @@ class RoomDetailFragment @Inject constructor( } } recyclerView.adapter = timelineEventController.adapter + recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { if (recyclerView.scrollState == RecyclerView.SCROLL_STATE_IDLE) { @@ -492,6 +498,7 @@ class RoomDetailFragment @Inject constructor( } } }) + timelineEventController.callback = this if (vectorPreferences.swipeToReplyIsEnabled()) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt index a3302d40c3..c4bb0d9b15 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt @@ -24,6 +24,7 @@ import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.home.room.list.RoomListParams import kotlinx.android.synthetic.main.activity_filtered_rooms.* @@ -47,7 +48,7 @@ class FilteredRoomsActivity : VectorBaseActivity() { super.onCreate(savedInstanceState) configureToolbar(filteredRoomsToolbar) if (isFirstCreation()) { - val params = RoomListParams(RoomListFragment.DisplayMode.FILTERED) + val params = RoomListParams(RoomListDisplayMode.FILTERED) replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG) } filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt index 3ea6745a94..8cae1fd4e8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt @@ -18,21 +18,22 @@ package im.vector.riotx.features.home.room.list import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.riotx.features.home.RoomListDisplayMode import io.reactivex.functions.Predicate -class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate { +class RoomListDisplayModeFilter(private val displayMode: RoomListDisplayMode) : Predicate { override fun test(roomSummary: RoomSummary): Boolean { if (roomSummary.membership.isLeft()) { return false } return when (displayMode) { - RoomListFragment.DisplayMode.HOME -> + RoomListDisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE || roomSummary.userDrafts.isNotEmpty() - RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN - RoomListFragment.DisplayMode.ROOMS -> !roomSummary.isDirect && roomSummary.membership == Membership.JOIN - RoomListFragment.DisplayMode.FILTERED -> roomSummary.membership == Membership.JOIN - RoomListFragment.DisplayMode.SHARE -> roomSummary.membership == Membership.JOIN + RoomListDisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN + RoomListDisplayMode.ROOMS -> !roomSummary.isDirect && roomSummary.membership == Membership.JOIN + RoomListDisplayMode.FILTERED -> roomSummary.membership == Membership.JOIN + RoomListDisplayMode.SHARE -> roomSummary.membership == Membership.JOIN } } } 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 92080c1b1f..73915493b9 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 @@ -39,6 +39,7 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel @@ -46,15 +47,13 @@ import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_room_list.* -import timber.log.Timber import javax.inject.Inject @Parcelize data class RoomListParams( - val displayMode: RoomListFragment.DisplayMode, + val displayMode: RoomListDisplayMode, val sharedData: SharedData? = null ) : Parcelable @@ -66,14 +65,6 @@ class RoomListFragment @Inject constructor( ) : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, FabMenuView.Listener { - enum class DisplayMode(@StringRes val titleRes: Int) { - HOME(R.string.bottom_action_home), - PEOPLE(R.string.bottom_action_people_x), - ROOMS(R.string.bottom_action_rooms), - FILTERED(/* Not used */ 0), - SHARE(/* Not used */ 0) - } - private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel private val roomListParams: RoomListParams by args() private val roomListViewModel: RoomListViewModel by fragmentViewModel() @@ -126,8 +117,13 @@ class RoomListFragment @Inject constructor( .disposeOnDestroyView() } + override fun onDestroyView() { + super.onDestroyView() + roomListView.adapter = null + } + private fun openSelectedRoom(event: RoomListViewEvents.SelectRoom) { - if (roomListParams.displayMode == DisplayMode.SHARE) { + if (roomListParams.displayMode == RoomListDisplayMode.SHARE) { val sharedData = roomListParams.sharedData ?: return navigator.openRoomForSharing(requireActivity(), event.roomId, sharedData) } else { @@ -144,9 +140,9 @@ class RoomListFragment @Inject constructor( private fun setupCreateRoomButton() { when (roomListParams.displayMode) { - DisplayMode.HOME -> createChatFabMenu.isVisible = true - DisplayMode.PEOPLE -> createChatRoomButton.isVisible = true - DisplayMode.ROOMS -> createGroupRoomButton.isVisible = true + RoomListDisplayMode.HOME -> createChatFabMenu.isVisible = true + RoomListDisplayMode.PEOPLE -> createChatRoomButton.isVisible = true + RoomListDisplayMode.ROOMS -> createGroupRoomButton.isVisible = true else -> Unit // No button in this mode } @@ -158,7 +154,7 @@ class RoomListFragment @Inject constructor( } // Hide FAB when list is scrolling - roomListEpoxyRecyclerView.addOnScrollListener( + roomListView.addOnScrollListener( object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { createChatFabMenu.removeCallbacks(showFabRunnable) @@ -170,9 +166,9 @@ class RoomListFragment @Inject constructor( RecyclerView.SCROLL_STATE_DRAGGING, RecyclerView.SCROLL_STATE_SETTLING -> { when (roomListParams.displayMode) { - DisplayMode.HOME -> createChatFabMenu.hide() - DisplayMode.PEOPLE -> createChatRoomButton.hide() - DisplayMode.ROOMS -> createGroupRoomButton.hide() + RoomListDisplayMode.HOME -> createChatFabMenu.hide() + RoomListDisplayMode.PEOPLE -> createChatRoomButton.hide() + RoomListDisplayMode.ROOMS -> createGroupRoomButton.hide() else -> Unit } } @@ -183,7 +179,7 @@ class RoomListFragment @Inject constructor( fun filterRoomsWith(filter: String) { // Scroll the list to top - roomListEpoxyRecyclerView.scrollToPosition(0) + roomListView.scrollToPosition(0) roomListViewModel.handle(RoomListAction.FilterWith(filter)) } @@ -199,20 +195,20 @@ class RoomListFragment @Inject constructor( private fun setupRecyclerView() { val layoutManager = LinearLayoutManager(context) val stateRestorer = LayoutManagerStateRestorer(layoutManager).register() - roomListEpoxyRecyclerView.layoutManager = layoutManager - roomListEpoxyRecyclerView.itemAnimator = RoomListAnimator() + roomListView.layoutManager = layoutManager + roomListView.itemAnimator = RoomListAnimator() roomController.listener = this roomController.addModelBuildListener { it.dispatchTo(stateRestorer) } - stateView.contentView = roomListEpoxyRecyclerView - roomListEpoxyRecyclerView.setController(roomController) + roomListView.adapter = roomController.adapter + stateView.contentView = roomListView } private val showFabRunnable = Runnable { if (isAdded) { when (roomListParams.displayMode) { - DisplayMode.HOME -> createChatFabMenu.show() - DisplayMode.PEOPLE -> createChatRoomButton.show() - DisplayMode.ROOMS -> createGroupRoomButton.show() + RoomListDisplayMode.HOME -> createChatFabMenu.show() + RoomListDisplayMode.PEOPLE -> createChatRoomButton.show() + RoomListDisplayMode.ROOMS -> createGroupRoomButton.show() else -> Unit } } @@ -258,9 +254,9 @@ class RoomListFragment @Inject constructor( // Mark all as read menu when (roomListParams.displayMode) { - DisplayMode.HOME, - DisplayMode.PEOPLE, - DisplayMode.ROOMS -> { + RoomListDisplayMode.HOME, + RoomListDisplayMode.PEOPLE, + RoomListDisplayMode.ROOMS -> { val newValue = state.hasUnread if (hasUnreadRooms != newValue) { hasUnreadRooms = newValue @@ -288,7 +284,7 @@ class RoomListFragment @Inject constructor( } .isNullOrEmpty() val emptyState = when (roomListParams.displayMode) { - DisplayMode.HOME -> { + RoomListDisplayMode.HOME -> { if (hasNoRoom) { StateView.State.Empty( getString(R.string.room_list_catchup_welcome_title), @@ -302,13 +298,13 @@ class RoomListFragment @Inject constructor( getString(R.string.room_list_catchup_empty_body)) } } - DisplayMode.PEOPLE -> + RoomListDisplayMode.PEOPLE -> StateView.State.Empty( getString(R.string.room_list_people_empty_title), ContextCompat.getDrawable(requireContext(), R.drawable.ic_home_bottom_chat), getString(R.string.room_list_people_empty_body) ) - DisplayMode.ROOMS -> + RoomListDisplayMode.ROOMS -> StateView.State.Empty( getString(R.string.room_list_rooms_empty_title), ContextCompat.getDrawable(requireContext(), R.drawable.ic_home_bottom_group), 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 6fd5d9763c..db4d634a05 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 @@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.utils.DataSource import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.features.home.RoomListDisplayMode import io.reactivex.schedulers.Schedulers import timber.log.Timber import javax.inject.Inject @@ -232,11 +233,11 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } val roomComparator = when (displayMode) { - RoomListFragment.DisplayMode.HOME -> chronologicalRoomComparator - RoomListFragment.DisplayMode.PEOPLE -> chronologicalRoomComparator - RoomListFragment.DisplayMode.ROOMS -> chronologicalRoomComparator - RoomListFragment.DisplayMode.FILTERED -> chronologicalRoomComparator - RoomListFragment.DisplayMode.SHARE -> chronologicalRoomComparator + RoomListDisplayMode.HOME -> chronologicalRoomComparator + RoomListDisplayMode.PEOPLE -> chronologicalRoomComparator + RoomListDisplayMode.ROOMS -> chronologicalRoomComparator + RoomListDisplayMode.FILTERED -> chronologicalRoomComparator + RoomListDisplayMode.SHARE -> chronologicalRoomComparator } return RoomSummaries().apply { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt index 897e72d811..836a1afb29 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt @@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.list import im.vector.matrix.android.api.session.Session import im.vector.riotx.features.home.HomeRoomListDataSource +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.share.ShareRoomListDataSource import javax.inject.Inject import javax.inject.Provider @@ -32,7 +33,7 @@ class RoomListViewModelFactory @Inject constructor(private val session: Provider return RoomListViewModel( initialState, session.get(), - if (initialState.displayMode == RoomListFragment.DisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(), + if (initialState.displayMode == RoomListDisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(), alphabeticalRoomComparator.get(), chronologicalRoomComparator.get()) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt index 505554a8fb..b41b4b9eeb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt @@ -23,9 +23,10 @@ import com.airbnb.mvrx.Uninitialized import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.R +import im.vector.riotx.features.home.RoomListDisplayMode data class RoomListViewState( - val displayMode: RoomListFragment.DisplayMode, + val displayMode: RoomListDisplayMode, val asyncRooms: Async> = Uninitialized, val roomFilter: String = "", val asyncFilteredRooms: Async = Uninitialized, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt index 3401e041b1..ca86191e8c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt @@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.R import im.vector.riotx.core.epoxy.noResultItem import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.filtered.FilteredRoomFooterItem import im.vector.riotx.features.home.room.filtered.filteredRoomFooterItem import javax.inject.Inject @@ -50,8 +51,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri override fun buildModels() { val nonNullViewState = viewState ?: return when (nonNullViewState.displayMode) { - RoomListFragment.DisplayMode.FILTERED, - RoomListFragment.DisplayMode.SHARE -> { + RoomListDisplayMode.FILTERED, + RoomListDisplayMode.SHARE -> { buildFilteredRooms(nonNullViewState) } else -> { @@ -92,7 +93,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri viewState.rejectingErrorRoomsIds) when { - viewState.displayMode == RoomListFragment.DisplayMode.FILTERED -> addFilterFooter(viewState) + viewState.displayMode == RoomListDisplayMode.FILTERED -> addFilterFooter(viewState) filteredSummaries.isEmpty() -> addEmptyFooter() } } diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt index 1ec020e1a0..33b0744d4f 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt @@ -31,6 +31,7 @@ import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.attachments.AttachmentsHelper import im.vector.riotx.features.home.LoadingFragment +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.home.room.list.RoomListParams import im.vector.riotx.features.login.LoginActivity @@ -97,7 +98,7 @@ class IncomingShareActivity : } override fun onContentAttachmentsReady(attachments: List) { - val roomListParams = RoomListParams(RoomListFragment.DisplayMode.SHARE, sharedData = SharedData.Attachments(attachments)) + val roomListParams = RoomListParams(RoomListDisplayMode.SHARE, sharedData = SharedData.Attachments(attachments)) replaceFragment(R.id.shareRoomListFragmentContainer, RoomListFragment::class.java, roomListParams) } @@ -116,7 +117,7 @@ class IncomingShareActivity : return if (sharedText.isNullOrEmpty()) { false } else { - val roomListParams = RoomListParams(RoomListFragment.DisplayMode.SHARE, sharedData = SharedData.Text(sharedText)) + val roomListParams = RoomListParams(RoomListDisplayMode.SHARE, sharedData = SharedData.Text(sharedText)) replaceFragment(R.id.shareRoomListFragmentContainer, RoomListFragment::class.java, roomListParams) true } diff --git a/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt index 85051a0137..f850d12422 100644 --- a/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt +++ b/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt @@ -18,7 +18,7 @@ package im.vector.riotx.features.ui import android.content.SharedPreferences import androidx.core.content.edit -import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.RoomListDisplayMode import javax.inject.Inject /** @@ -26,21 +26,21 @@ import javax.inject.Inject */ class SharedPreferencesUiStateRepository @Inject constructor(private val sharedPreferences: SharedPreferences) : UiStateRepository { - override fun getDisplayMode(): RoomListFragment.DisplayMode { + override fun getDisplayMode(): RoomListDisplayMode { return when (sharedPreferences.getInt(KEY_DISPLAY_MODE, VALUE_DISPLAY_MODE_CATCHUP)) { - VALUE_DISPLAY_MODE_PEOPLE -> RoomListFragment.DisplayMode.PEOPLE - VALUE_DISPLAY_MODE_ROOMS -> RoomListFragment.DisplayMode.ROOMS - else -> RoomListFragment.DisplayMode.HOME + VALUE_DISPLAY_MODE_PEOPLE -> RoomListDisplayMode.PEOPLE + VALUE_DISPLAY_MODE_ROOMS -> RoomListDisplayMode.ROOMS + else -> RoomListDisplayMode.HOME } } - override fun storeDisplayMode(displayMode: RoomListFragment.DisplayMode) { + override fun storeDisplayMode(displayMode: RoomListDisplayMode) { sharedPreferences.edit { putInt(KEY_DISPLAY_MODE, when (displayMode) { - RoomListFragment.DisplayMode.PEOPLE -> VALUE_DISPLAY_MODE_PEOPLE - RoomListFragment.DisplayMode.ROOMS -> VALUE_DISPLAY_MODE_ROOMS - else -> VALUE_DISPLAY_MODE_CATCHUP + RoomListDisplayMode.PEOPLE -> VALUE_DISPLAY_MODE_PEOPLE + RoomListDisplayMode.ROOMS -> VALUE_DISPLAY_MODE_ROOMS + else -> VALUE_DISPLAY_MODE_CATCHUP }) } } diff --git a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt index 1c59a22892..feac6a64ed 100644 --- a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt +++ b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt @@ -16,14 +16,14 @@ package im.vector.riotx.features.ui -import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.RoomListDisplayMode /** * This interface is used to persist UI state across application restart */ interface UiStateRepository { - fun getDisplayMode(): RoomListFragment.DisplayMode + fun getDisplayMode(): RoomListDisplayMode - fun storeDisplayMode(displayMode: RoomListFragment.DisplayMode) + fun storeDisplayMode(displayMode: RoomListDisplayMode) } diff --git a/vector/src/main/res/layout/fragment_room_list.xml b/vector/src/main/res/layout/fragment_room_list.xml index 30ab86d004..2c828c8397 100644 --- a/vector/src/main/res/layout/fragment_room_list.xml +++ b/vector/src/main/res/layout/fragment_room_list.xml @@ -7,8 +7,8 @@ android:layout_height="match_parent" android:background="?riotx_header_panel_background"> - @@ -30,7 +30,7 @@ android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:layout_marginBottom="16dp" - android:accessibilityTraversalBefore="@+id/roomListEpoxyRecyclerView" + android:accessibilityTraversalBefore="@+id/roomListView" android:contentDescription="@string/a11y_create_direct_message" android:scaleType="center" android:src="@drawable/ic_fab_add_chat" @@ -47,7 +47,7 @@ android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:layout_marginBottom="16dp" - android:accessibilityTraversalBefore="@+id/roomListEpoxyRecyclerView" + android:accessibilityTraversalBefore="@+id/roomListView" android:contentDescription="@string/a11y_create_room" android:src="@drawable/ic_fab_add_room" android:visibility="gone" diff --git a/vector/src/main/res/layout/motion_fab_menu_merge.xml b/vector/src/main/res/layout/motion_fab_menu_merge.xml index 02ba4341c6..104db206cd 100644 --- a/vector/src/main/res/layout/motion_fab_menu_merge.xml +++ b/vector/src/main/res/layout/motion_fab_menu_merge.xml @@ -24,7 +24,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" - android:accessibilityTraversalBefore="@+id/roomListEpoxyRecyclerView" + android:accessibilityTraversalBefore="@+id/roomListView" android:contentDescription="@string/a11y_create_room" android:src="@drawable/ic_fab_add_room" app:backgroundTint="#FFFFFF" From 54495924225e0f8cd016b5c174d6bbd14a577b19 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 12 Nov 2019 17:52:03 +0100 Subject: [PATCH 104/117] Add action to block user in the message action bottom sheet (following Nad's design) --- .../home/room/detail/RoomDetailFragment.kt | 5 +- .../timeline/action/EventSharedAction.kt | 6 ++ .../action/MessageActionsEpoxyController.kt | 56 ++++++++++--------- .../action/MessageActionsViewModel.kt | 9 ++- .../main/res/drawable/ic_alert_triangle.xml | 14 +++++ vector/src/main/res/values/strings_riotX.xml | 2 + 6 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 vector/src/main/res/drawable/ic_alert_triangle.xml 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 f085eca233..a5bdd674f0 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 @@ -96,9 +96,9 @@ import im.vector.riotx.features.home.room.detail.composer.TextComposerViewModel import im.vector.riotx.features.home.room.detail.composer.TextComposerViewState import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController +import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet import im.vector.riotx.features.home.room.detail.timeline.action.MessageSharedActionViewModel -import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet import im.vector.riotx.features.home.room.detail.timeline.item.* import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet @@ -1142,6 +1142,9 @@ class RoomDetailFragment @Inject constructor( is EventSharedAction.ReportContentCustom -> { promptReasonToReportContent(action) } + is EventSharedAction.IgnoreUser -> { + roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(action.senderId)) + } else -> { Toast.makeText(context, "Action $action is not implemented yet", Toast.LENGTH_LONG).show() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt index 73a4e245d0..37d96ad62c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/EventSharedAction.kt @@ -23,6 +23,9 @@ import im.vector.riotx.core.platform.VectorSharedAction import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData sealed class EventSharedAction(@StringRes val titleRes: Int, @DrawableRes val iconResId: Int) : VectorSharedAction { + object Separator : + EventSharedAction(0, 0) + data class AddReaction(val eventId: String) : EventSharedAction(R.string.message_add_reaction, R.drawable.ic_add_reaction) @@ -74,6 +77,9 @@ sealed class EventSharedAction(@StringRes val titleRes: Int, @DrawableRes val ic data class ReportContentCustom(val eventId: String, val senderId: String?) : EventSharedAction(R.string.report_content_custom, R.drawable.ic_report_custom) + data class IgnoreUser(val senderId: String?) : + EventSharedAction(R.string.message_ignore_user, R.drawable.ic_alert_triangle) + data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) : EventSharedAction(0, 0) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index 0917f52779..b561a6df3c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -20,12 +20,7 @@ import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Success import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.R -import im.vector.riotx.core.epoxy.bottomsheet.BottomSheetItemQuickReactions -import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemAction -import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemMessagePreview -import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemQuickReactions -import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemSendState -import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetItemSeparator +import im.vector.riotx.core.epoxy.bottomsheet.* import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.AvatarRenderer import javax.inject.Inject @@ -97,28 +92,35 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid // Action state.actions()?.forEachIndexed { index, action -> - bottomSheetItemAction { - id("action_$index") - iconRes(action.iconResId) - textRes(action.titleRes) - showExpand(action is EventSharedAction.ReportContent) - expanded(state.expendedReportContentMenu) - listener(View.OnClickListener { listener?.didSelectMenuAction(action) }) - } + if (action is EventSharedAction.Separator) { + bottomSheetItemSeparator { + id("separator_$index") + } + } else { + bottomSheetItemAction { + id("action_$index") + iconRes(action.iconResId) + textRes(action.titleRes) + showExpand(action is EventSharedAction.ReportContent) + expanded(state.expendedReportContentMenu) + listener(View.OnClickListener { listener?.didSelectMenuAction(action) }) + destructive(action is EventSharedAction.IgnoreUser) + } - if (action is EventSharedAction.ReportContent && state.expendedReportContentMenu) { - // Special case for report content menu: add the submenu - listOf( - EventSharedAction.ReportContentSpam(action.eventId, action.senderId), - EventSharedAction.ReportContentInappropriate(action.eventId, action.senderId), - EventSharedAction.ReportContentCustom(action.eventId, action.senderId) - ).forEachIndexed { indexReport, actionReport -> - bottomSheetItemAction { - id("actionReport_$indexReport") - subMenuItem(true) - iconRes(actionReport.iconResId) - textRes(actionReport.titleRes) - listener(View.OnClickListener { listener?.didSelectMenuAction(actionReport) }) + if (action is EventSharedAction.ReportContent && state.expendedReportContentMenu) { + // Special case for report content menu: add the submenu + listOf( + EventSharedAction.ReportContentSpam(action.eventId, action.senderId), + EventSharedAction.ReportContentInappropriate(action.eventId, action.senderId), + EventSharedAction.ReportContentCustom(action.eventId, action.senderId) + ).forEachIndexed { indexReport, actionReport -> + bottomSheetItemAction { + id("actionReport_$indexReport") + subMenuItem(true) + iconRes(actionReport.iconResId) + textRes(actionReport.titleRes) + listener(View.OnClickListener { listener?.didSelectMenuAction(actionReport) }) + } } } } 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 575f835bb4..102412948b 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 @@ -266,9 +266,14 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } add(EventSharedAction.CopyPermalink(eventId)) - if (session.myUserId != event.root.senderId && event.root.getClearType() == EventType.MESSAGE) { + if (session.myUserId != event.root.senderId) { // not sent by me - add(EventSharedAction.ReportContent(eventId, event.root.senderId)) + if (event.root.getClearType() == EventType.MESSAGE) { + add(EventSharedAction.ReportContent(eventId, event.root.senderId)) + } + + add(EventSharedAction.Separator) + add(EventSharedAction.IgnoreUser(event.root.senderId)) } } } diff --git a/vector/src/main/res/drawable/ic_alert_triangle.xml b/vector/src/main/res/drawable/ic_alert_triangle.xml new file mode 100644 index 0000000000..0daaca920a --- /dev/null +++ b/vector/src/main/res/drawable/ic_alert_triangle.xml @@ -0,0 +1,14 @@ + + + diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index aa0c31b26d..07b5b662e0 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,6 +2,8 @@ + Block user + "All messages (noisy)" "All messages" "Mentions only" From ec71b53c1e45e10f4fa4b48b435c1a4509f8eebe Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 12 Nov 2019 19:25:21 +0100 Subject: [PATCH 105/117] RoomSummary: don't map read receipts --- .../android/internal/database/mapper/RoomSummaryMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt index 0d0143d318..2577bec581 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt @@ -36,7 +36,7 @@ internal class RoomSummaryMapper @Inject constructor( } val latestEvent = roomSummaryEntity.latestPreviewableEvent?.let { - timelineEventMapper.map(it) + timelineEventMapper.map(it, buildReadReceipts = false) } if (latestEvent?.root?.isEncrypted() == true && latestEvent.root.mxDecryptionResult == null) { // TODO use a global event decryptor? attache to session and that listen to new sessionId? From d2acabddd973175cee93941f667d8422417b882c Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 12 Nov 2019 19:25:50 +0100 Subject: [PATCH 106/117] RoomDetail: fix enter/exit mode again after merge --- .../home/room/detail/RoomDetailAction.kt | 8 ++++---- .../home/room/detail/RoomDetailViewModel.kt | 16 ++++++++++------ .../constraint_set_composer_layout_expanded.xml | 6 ++---- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt index b37d03097c..2e59e70d08 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt @@ -42,10 +42,10 @@ sealed class RoomDetailAction : VectorViewModelAction { object AcceptInvite : RoomDetailAction() object RejectInvite : RoomDetailAction() - data class EnterEditMode(val eventId: String, val draft: String) : RoomDetailAction() - data class EnterQuoteMode(val eventId: String, val draft: String) : RoomDetailAction() - data class EnterReplyMode(val eventId: String, val draft: String) : RoomDetailAction() - data class ExitSpecialMode(val draft: String) : RoomDetailAction() + data class EnterEditMode(val eventId: String, val text: String) : RoomDetailAction() + data class EnterQuoteMode(val eventId: String, val text: String) : RoomDetailAction() + data class EnterReplyMode(val eventId: String, val text: String) : RoomDetailAction() + data class ExitSpecialMode(val text: String) : RoomDetailAction() data class ResendMessage(val eventId: String) : RoomDetailAction() data class RemoveFailedEcho(val eventId: String) : RoomDetailAction() 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 dec77aa1c1..d2c2c7fdde 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 @@ -521,9 +521,10 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleEditAction(action: RoomDetailAction.EnterEditMode) { - saveCurrentDraft(action.draft) + saveCurrentDraft(action.text) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> + setState { copy(sendMode = SendMode.EDIT(timelineEvent, action.text)) } timelineEvent.root.eventId?.let { room.saveDraft(UserDraft.EDIT(it, timelineEvent.getTextEditableContent() ?: "")) } @@ -531,16 +532,17 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleQuoteAction(action: RoomDetailAction.EnterQuoteMode) { - saveCurrentDraft(action.draft) + saveCurrentDraft(action.text) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> + setState { copy(sendMode = SendMode.QUOTE(timelineEvent, action.text)) } withState { state -> // Save a new draft and keep the previously entered text, if it was not an edit timelineEvent.root.eventId?.let { if (state.sendMode is SendMode.EDIT) { room.saveDraft(UserDraft.QUOTE(it, "")) } else { - room.saveDraft(UserDraft.QUOTE(it, action.draft)) + room.saveDraft(UserDraft.QUOTE(it, action.text)) } } } @@ -548,16 +550,17 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleReplyAction(action: RoomDetailAction.EnterReplyMode) { - saveCurrentDraft(action.draft) + saveCurrentDraft(action.text) room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> + setState { copy(sendMode = SendMode.REPLY(timelineEvent, action.text)) } withState { state -> // Save a new draft and keep the previously entered text, if it was not an edit timelineEvent.root.eventId?.let { if (state.sendMode is SendMode.EDIT) { room.saveDraft(UserDraft.REPLY(it, "")) } else { - room.saveDraft(UserDraft.REPLY(it, action.draft)) + room.saveDraft(UserDraft.REPLY(it, action.text)) } } } @@ -579,13 +582,14 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro } private fun handleExitSpecialMode(action: RoomDetailAction.ExitSpecialMode) { + setState { copy(sendMode = SendMode.REGULAR(action.text)) } withState { state -> // For edit, just delete the current draft if (state.sendMode is SendMode.EDIT) { room.deleteDraft() } else { // Save a new draft and keep the previously entered text - room.saveDraft(UserDraft.REGULAR(action.draft)) + room.saveDraft(UserDraft.REGULAR(action.text)) } } } diff --git a/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml b/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml index 3ce38c425d..4c9225dba7 100644 --- a/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml +++ b/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml @@ -90,10 +90,8 @@ Date: Tue, 12 Nov 2019 19:53:07 +0100 Subject: [PATCH 107/117] Optimize room list processing --- .../java/im/vector/riotx/AppStateHandler.kt | 38 +++++++++---------- .../home/room/list/RoomListViewModel.kt | 32 +++++----------- .../room/list/RoomListViewModelFactory.kt | 10 ++--- 3 files changed, 31 insertions(+), 49 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/AppStateHandler.kt b/vector/src/main/java/im/vector/riotx/AppStateHandler.kt index 7cb51b6373..187381d911 100644 --- a/vector/src/main/java/im/vector/riotx/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/riotx/AppStateHandler.kt @@ -26,11 +26,13 @@ import im.vector.matrix.rx.rx import im.vector.riotx.features.home.HomeRoomListDataSource import im.vector.riotx.features.home.group.ALL_COMMUNITIES_GROUP_ID import im.vector.riotx.features.home.group.SelectedGroupDataSource +import im.vector.riotx.features.home.room.list.ChronologicalRoomComparator import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.functions.BiFunction import io.reactivex.rxkotlin.addTo +import java.util.Comparator import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton @@ -43,7 +45,8 @@ import javax.inject.Singleton class AppStateHandler @Inject constructor( private val sessionDataSource: ActiveSessionDataSource, private val homeRoomListDataSource: HomeRoomListDataSource, - private val selectedGroupDataSource: SelectedGroupDataSource) : LifecycleObserver { + private val selectedGroupDataSource: SelectedGroupDataSource, + private val chronologicalRoomComparator: ChronologicalRoomComparator) : LifecycleObserver { private val compositeDisposable = CompositeDisposable() @@ -64,31 +67,24 @@ class AppStateHandler @Inject constructor( .observeOn(AndroidSchedulers.mainThread()) .switchMap { it.orNull()?.rx()?.liveRoomSummaries() - ?: Observable.just(emptyList()) + ?: Observable.just(emptyList()) } .throttleLast(300, TimeUnit.MILLISECONDS), selectedGroupDataSource.observe(), BiFunction { rooms, selectedGroupOption -> val selectedGroup = selectedGroupOption.orNull() - val filteredDirectRooms = rooms - .filter { it.isDirect } - .filter { - if (selectedGroup == null || selectedGroup.groupId == ALL_COMMUNITIES_GROUP_ID) { - true - } else { - it.otherMemberIds - .intersect(selectedGroup.userIds) - .isNotEmpty() - } - } - - val filteredGroupRooms = rooms - .filter { !it.isDirect } - .filter { - selectedGroup?.groupId == ALL_COMMUNITIES_GROUP_ID - || selectedGroup?.roomIds?.contains(it.roomId) ?: true - } - filteredDirectRooms + filteredGroupRooms + val filteredRooms = rooms.filter { + if (selectedGroup == null || selectedGroup.groupId == ALL_COMMUNITIES_GROUP_ID) { + true + } else if (it.isDirect) { + it.otherMemberIds + .intersect(selectedGroup.userIds) + .isNotEmpty() + } else { + selectedGroup.roomIds.contains(it.roomId) + } + } + filteredRooms.sortedWith(chronologicalRoomComparator) } ) .subscribe { 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 db4d634a05..9e94af577f 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 @@ -34,9 +34,7 @@ import javax.inject.Inject class RoomListViewModel @Inject constructor(initialState: RoomListViewState, private val session: Session, - private val roomSummariesSource: DataSource>, - private val alphabeticalRoomComparator: AlphabeticalRoomComparator, - private val chronologicalRoomComparator: ChronologicalRoomComparator) + private val roomSummariesSource: DataSource>) : VectorViewModel(initialState) { interface Factory { @@ -97,9 +95,6 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, roomSummariesSource .observe() .observeOn(Schedulers.computation()) - .map { - it.sortedWith(chronologicalRoomComparator) - } .execute { asyncRooms -> copy(asyncRooms = asyncRooms) } @@ -211,10 +206,11 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } private fun buildRoomSummaries(rooms: List): RoomSummaries { + // Set up init size on directChats and groupRooms as they are the biggest ones val invites = ArrayList() val favourites = ArrayList() - val directChats = ArrayList() - val groupRooms = ArrayList() + val directChats = ArrayList(rooms.size) + val groupRooms = ArrayList(rooms.size) val lowPriorities = ArrayList() val serverNotices = ArrayList() @@ -232,21 +228,13 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } } - val roomComparator = when (displayMode) { - RoomListDisplayMode.HOME -> chronologicalRoomComparator - RoomListDisplayMode.PEOPLE -> chronologicalRoomComparator - RoomListDisplayMode.ROOMS -> chronologicalRoomComparator - RoomListDisplayMode.FILTERED -> chronologicalRoomComparator - RoomListDisplayMode.SHARE -> chronologicalRoomComparator - } - return RoomSummaries().apply { - put(RoomCategory.INVITE, invites.sortedWith(roomComparator)) - put(RoomCategory.FAVOURITE, favourites.sortedWith(roomComparator)) - put(RoomCategory.DIRECT, directChats.sortedWith(roomComparator)) - put(RoomCategory.GROUP, groupRooms.sortedWith(roomComparator)) - put(RoomCategory.LOW_PRIORITY, lowPriorities.sortedWith(roomComparator)) - put(RoomCategory.SERVER_NOTICE, serverNotices.sortedWith(roomComparator)) + put(RoomCategory.INVITE, invites) + put(RoomCategory.FAVOURITE, favourites) + put(RoomCategory.DIRECT, directChats) + put(RoomCategory.GROUP, groupRooms) + put(RoomCategory.LOW_PRIORITY, lowPriorities) + put(RoomCategory.SERVER_NOTICE, serverNotices) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt index 836a1afb29..60ec92d8cf 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt @@ -25,16 +25,14 @@ import javax.inject.Provider class RoomListViewModelFactory @Inject constructor(private val session: Provider, private val homeRoomListDataSource: Provider, - private val shareRoomListDataSource: Provider, - private val alphabeticalRoomComparator: Provider, - private val chronologicalRoomComparator: Provider) : RoomListViewModel.Factory { + private val shareRoomListDataSource: Provider) + : RoomListViewModel.Factory { override fun create(initialState: RoomListViewState): RoomListViewModel { return RoomListViewModel( initialState, session.get(), - if (initialState.displayMode == RoomListDisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(), - alphabeticalRoomComparator.get(), - chronologicalRoomComparator.get()) + if (initialState.displayMode == RoomListDisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get() + ) } } From 0e0db67aef6dc5e5aa439142cb68af0d8cfb303f Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 12 Nov 2019 20:34:19 +0100 Subject: [PATCH 108/117] Timeline: clear some resources when unbind --- .../im/vector/riotx/core/ui/views/ReadReceiptsView.kt | 9 +++++++++ .../home/room/detail/timeline/item/AbsMessageItem.kt | 1 + .../room/detail/timeline/item/MessageImageVideoItem.kt | 2 ++ 3 files changed, 12 insertions(+) diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt index c74e9a4111..29b2863d02 100644 --- a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt +++ b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt @@ -23,6 +23,7 @@ import android.widget.ImageView import android.widget.LinearLayout import androidx.core.view.isVisible import im.vector.riotx.R +import im.vector.riotx.core.glide.GlideApp import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.item.ReadReceiptData import kotlinx.android.synthetic.main.view_read_receipts.view.* @@ -105,4 +106,12 @@ class ReadReceiptsView @JvmOverloads constructor( isVisible = false } } + + fun unbind() { + receiptAvatars.forEach { + GlideApp.with(context.applicationContext).clear(it) + } + isVisible = false + } + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt index bddee50861..2ca6bbfd37 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -139,6 +139,7 @@ abstract class AbsMessageItem : BaseEventItem() { override fun unbind(holder: H) { holder.readMarkerView.unbind() + holder.readReceiptsView.unbind() super.unbind(holder) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt index 928a18fe4d..457f30cbf4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageImageVideoItem.kt @@ -24,6 +24,7 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R +import im.vector.riotx.core.glide.GlideApp import im.vector.riotx.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.riotx.features.media.ImageContentRenderer @@ -60,6 +61,7 @@ abstract class MessageImageVideoItem : AbsMessageItem Date: Wed, 13 Nov 2019 11:37:59 +0100 Subject: [PATCH 109/117] Clean code for klint --- .../matrix/android/internal/auth/DefaultAuthenticator.kt | 2 -- .../matrix/android/internal/auth/SessionParamsStore.kt | 1 - .../matrix/android/internal/database/AsyncTransaction.kt | 2 -- .../android/internal/database/query/FilterEntityQueries.kt | 1 - .../internal/session/filter/DefaultFilterRepository.kt | 2 -- .../android/internal/session/room/RoomAvatarResolver.kt | 1 - .../android/internal/session/room/RoomSummaryUpdater.kt | 4 ---- .../session/room/membership/RoomDisplayNameResolver.kt | 1 - .../matrix/android/internal/session/sync/SyncTokenStore.kt | 2 -- vector/src/main/java/im/vector/riotx/AppStateHandler.kt | 1 - .../java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt | 1 - .../java/im/vector/riotx/features/home/HomeDetailAction.kt | 1 - .../im/vector/riotx/features/home/HomeDetailFragment.kt | 1 - .../im/vector/riotx/features/home/HomeDetailViewModel.kt | 7 ------- .../im/vector/riotx/features/home/HomeDetailViewState.kt | 2 -- .../im/vector/riotx/features/home/HomeDrawerFragment.kt | 1 - .../riotx/features/home/room/detail/RoomDetailFragment.kt | 3 --- .../features/home/room/detail/composer/TextComposerView.kt | 1 - .../riotx/features/home/room/list/RoomListViewModel.kt | 1 - .../riotx/features/reactions/EmojiChooserFragment.kt | 1 - .../roomdirectory/picker/RoomDirectoryPickerFragment.kt | 1 - 21 files changed, 37 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt index 1f7caa4fc3..ff49d4308b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt @@ -40,7 +40,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import javax.inject.Inject -import javax.inject.Provider internal class DefaultAuthenticator @Inject constructor(@Unauthenticated private val okHttpClient: Lazy, @@ -123,7 +122,6 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated sessionOrFailure.foldToCallback(callback) } return CancelableCoroutine(job) - } private suspend fun createSessionFromSso(credentials: Credentials, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt index 88beb92111..17bcb9dc81 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt @@ -16,7 +16,6 @@ package im.vector.matrix.android.internal.auth -import arrow.core.Try import im.vector.matrix.android.api.auth.data.SessionParams internal interface SessionParamsStore { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt index 6d2dccca41..0f8445d20f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/AsyncTransaction.kt @@ -21,7 +21,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext import timber.log.Timber -import java.lang.RuntimeException suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> Unit) = withContext(Dispatchers.Default) { Realm.getInstance(config).use { bgRealm -> @@ -41,5 +40,4 @@ suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (r } } } - } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt index bcc63dd0ba..4f64f2896f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterEntityQueries.kt @@ -20,7 +20,6 @@ import im.vector.matrix.android.internal.database.awaitTransaction import im.vector.matrix.android.internal.database.model.FilterEntity import im.vector.matrix.android.internal.session.filter.FilterFactory import io.realm.Realm -import io.realm.kotlin.createObject import io.realm.kotlin.where /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt index d7b742fd2d..53967784a1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/filter/DefaultFilterRepository.kt @@ -20,10 +20,8 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.internal.database.model.FilterEntity import im.vector.matrix.android.internal.database.model.FilterEntityFields import im.vector.matrix.android.internal.database.query.getFilter -import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.util.awaitTransaction import io.realm.Realm -import io.realm.RealmConfiguration import io.realm.kotlin.where import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt index 070960fb91..c9d5aeb6bb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAvatarResolver.kt @@ -22,7 +22,6 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.RoomAvatarContent import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.internal.database.mapper.ContentMapper -import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.query.prev diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt index 44794e307e..1158c08984 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt @@ -22,7 +22,6 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomTopicContent import im.vector.matrix.android.internal.database.mapper.ContentMapper -import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntity @@ -97,7 +96,6 @@ internal class RoomSummaryUpdater @Inject constructor(@UserId private val userId // avoid this call if we are sure there are unread events || !isEventRead(monarchy, userId, roomId, latestPreviewableEvent?.eventId) - roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString() roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId) roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel()?.topic @@ -114,7 +112,5 @@ internal class RoomSummaryUpdater @Inject constructor(@UserId private val userId roomSummaryEntity.otherMemberIds.clear() roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers) } - - } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt index 365bde749a..2271631932 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/RoomDisplayNameResolver.kt @@ -23,7 +23,6 @@ import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.* import im.vector.matrix.android.internal.database.mapper.ContentMapper -import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.RoomEntity diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt index 3d9052bee6..350f2a1d83 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTokenStore.kt @@ -18,10 +18,8 @@ package im.vector.matrix.android.internal.session.sync import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.internal.database.model.SyncEntity -import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.util.awaitTransaction import io.realm.Realm -import io.realm.RealmConfiguration import javax.inject.Inject internal class SyncTokenStore @Inject constructor(private val monarchy: Monarchy) { diff --git a/vector/src/main/java/im/vector/riotx/AppStateHandler.kt b/vector/src/main/java/im/vector/riotx/AppStateHandler.kt index 187381d911..cfbed0ee13 100644 --- a/vector/src/main/java/im/vector/riotx/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/riotx/AppStateHandler.kt @@ -32,7 +32,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.functions.BiFunction import io.reactivex.rxkotlin.addTo -import java.util.Comparator import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt index 29b2863d02..6e4229908f 100644 --- a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt +++ b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt @@ -113,5 +113,4 @@ class ReadReceiptsView @JvmOverloads constructor( } isVisible = false } - } 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 index b4064f270e..3309f987fd 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt @@ -17,7 +17,6 @@ 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: RoomListDisplayMode) : 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 1c78acbcfe..02ac9a26d2 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 @@ -29,7 +29,6 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R -import im.vector.riotx.core.extensions.commitTransaction import im.vector.riotx.core.extensions.commitTransactionNow import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseFragment 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 6b38fb34b1..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 @@ -22,17 +22,11 @@ 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.android.api.session.room.model.Membership -import im.vector.matrix.android.api.session.room.model.RoomSummary -import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.rx.rx 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.RoomCategory -import im.vector.riotx.features.home.room.list.RoomListFragment -import im.vector.riotx.features.home.room.list.RoomSummaries import im.vector.riotx.features.ui.UiStateRepository import io.reactivex.schedulers.Schedulers @@ -150,5 +144,4 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho } .disposeOnClear() } - } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt index 1fc3a1ef21..c7c5e4a233 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt @@ -23,8 +23,6 @@ import com.airbnb.mvrx.Uninitialized import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.sync.SyncState -import im.vector.riotx.features.home.room.list.RoomListFragment -import im.vector.riotx.features.home.room.list.RoomSummaries data class HomeDetailViewState( val groupSummary: Option = Option.empty(), diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt index f48c5650f5..422b59671e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt @@ -56,5 +56,4 @@ class HomeDrawerFragment @Inject constructor( navigator.openDebug(requireActivity()) } } - } 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 d995c9ffec..4643c30f4a 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 @@ -602,7 +602,6 @@ class RoomDetailFragment @Inject constructor( .build() composerLayout.callback = object : TextComposerView.Callback { - override fun onAddAttachment() { if (!::attachmentTypeSelector.isInitialized) { attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@RoomDetailFragment) @@ -610,7 +609,6 @@ class RoomDetailFragment @Inject constructor( attachmentTypeSelector.show(composerLayout.attachmentButton, keyboardStateUtils.isKeyboardShowing) } - override fun onSendMessage(text: String) { if (lockSendButton) { Timber.w("Send button is locked") @@ -626,7 +624,6 @@ class RoomDetailFragment @Inject constructor( roomDetailViewModel.handle(RoomDetailAction.ExitSpecialMode(composerLayout.text.toString())) } - override fun onRichContentSelected(contentUri: Uri): Boolean { // We need WRITE_EXTERNAL permission return if (checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this@RoomDetailFragment, PERMISSION_REQUEST_CODE_INCOMING_URI)) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt index 5de924dde0..32307dc3d4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/TextComposerView.kt @@ -93,7 +93,6 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib attachmentButton.setOnClickListener { callback?.onAddAttachment() } - } fun collapse(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) { 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 9e94af577f..e5924d9f2a 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 @@ -27,7 +27,6 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.utils.DataSource import im.vector.riotx.core.utils.PublishDataSource -import im.vector.riotx.features.home.RoomListDisplayMode import io.reactivex.schedulers.Schedulers import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt index c66e322bae..5e705a70c2 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/EmojiChooserFragment.kt @@ -37,5 +37,4 @@ class EmojiChooserFragment @Inject constructor() : VectorBaseFragment() { it.adapter?.notifyDataSetChanged() } } - } 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 87cb8193bf..ce7a57deba 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 @@ -72,7 +72,6 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie return super.onOptionsItemSelected(item) } - private fun setupRecyclerView() { val layoutManager = LinearLayoutManager(context) From f265724a3ccf5de77217cb98c759b48c621cbd8f Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 13 Nov 2019 19:20:03 +0100 Subject: [PATCH 110/117] Login sso: handle failure --- .../java/im/vector/riotx/features/login/LoginViewModel.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 4c72d041d6..a0a7258e2a 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 @@ -134,6 +134,10 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi override fun onSuccess(data: Session) { onSessionCreated(data) } + + override fun onFailure(failure: Throwable) = setState { + copy(asyncLoginAction = Fail(failure)) + } }) } } @@ -150,7 +154,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi // Do not retry if we already have flows for this config -> causes infinite focus loop if (newConfig?.homeServerUri?.toString() == homeServerConnectionConfig?.homeServerUri?.toString() - && state.asyncHomeServerLoginFlowRequest is Success) return@withState + && state.asyncHomeServerLoginFlowRequest is Success) return@withState currentTask?.cancel() homeServerConnectionConfig = newConfig From 79350899c5e7a69c882db7ec151c9e4f894dea2a Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 13 Nov 2019 19:21:14 +0100 Subject: [PATCH 111/117] Read receipts: use primary key to query --- .../internal/database/query/ReadReceiptEntityQueries.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt index e0a507f939..6b996d1285 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt @@ -24,8 +24,7 @@ import io.realm.kotlin.where internal fun ReadReceiptEntity.Companion.where(realm: Realm, roomId: String, userId: String): RealmQuery { return realm.where() - .equalTo(ReadReceiptEntityFields.ROOM_ID, roomId) - .equalTo(ReadReceiptEntityFields.USER_ID, userId) + .equalTo(ReadReceiptEntityFields.PRIMARY_KEY, buildPrimaryKey(roomId, userId)) } internal fun ReadReceiptEntity.Companion.whereUserId(realm: Realm, userId: String): RealmQuery { @@ -45,8 +44,10 @@ internal fun ReadReceiptEntity.Companion.createUnmanaged(roomId: String, eventId internal fun ReadReceiptEntity.Companion.getOrCreate(realm: Realm, roomId: String, userId: String): ReadReceiptEntity { return ReadReceiptEntity.where(realm, roomId, userId).findFirst() - ?: realm.createObject(ReadReceiptEntity::class.java, "${roomId}_$userId").apply { + ?: realm.createObject(ReadReceiptEntity::class.java, buildPrimaryKey(roomId, userId)).apply { this.roomId = roomId this.userId = userId } } + +private fun buildPrimaryKey(roomId: String, userId: String) = "${roomId}_$userId" From 4cefdfedce9f04b66597d421d3ac741d46ca4aa7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Nov 2019 11:18:45 +0100 Subject: [PATCH 112/117] Home: use detach/attach instead of hide/show --- .../vector/riotx/features/home/HomeDetailFragment.kt | 4 ++-- .../features/home/room/list/RoomListFragment.kt | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) 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 02ac9a26d2..fe98501e73 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 @@ -170,13 +170,13 @@ class HomeDetailFragment @Inject constructor( childFragmentManager.fragments .filter { it != fragmentToShow } .forEach { - hide(it) + detach(it) } if (fragmentToShow == null) { val params = RoomListParams(displayMode) add(R.id.roomListContainer, RoomListFragment::class.java, params.toMvRxBundle(), fragmentTag) } else { - show(fragmentToShow) + attach(fragmentToShow) } } } 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 f2c6725a47..a5e9a7b4bf 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 @@ -143,7 +143,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.HOME -> createChatFabMenu.isVisible = true RoomListDisplayMode.PEOPLE -> createChatRoomButton.isVisible = true RoomListDisplayMode.ROOMS -> createGroupRoomButton.isVisible = true - else -> Unit // No button in this mode + else -> Unit // No button in this mode } createChatRoomButton.setOnClickListener { @@ -169,7 +169,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.HOME -> createChatFabMenu.hide() RoomListDisplayMode.PEOPLE -> createChatRoomButton.hide() RoomListDisplayMode.ROOMS -> createGroupRoomButton.hide() - else -> Unit + else -> Unit } } } @@ -209,7 +209,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.HOME -> createChatFabMenu.show() RoomListDisplayMode.PEOPLE -> createChatRoomButton.show() RoomListDisplayMode.ROOMS -> createGroupRoomButton.show() - else -> Unit + else -> Unit } } } @@ -263,7 +263,7 @@ class RoomListFragment @Inject constructor( requireActivity().invalidateOptionsMenu() } } - else -> Unit + else -> Unit } } @@ -310,7 +310,7 @@ class RoomListFragment @Inject constructor( ContextCompat.getDrawable(requireContext(), R.drawable.ic_home_bottom_group), getString(R.string.room_list_rooms_empty_body) ) - else -> + else -> // Always display the content in this mode, because if the footer StateView.State.Content } @@ -348,7 +348,7 @@ class RoomListFragment @Inject constructor( RoomListQuickActionsBottomSheet .newInstance(room.roomId) - .show(requireActivity().supportFragmentManager, "ROOM_LIST_QUICK_ACTIONS") + .show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS") return true } From c7db695e67df70364e36e753c37a7368fc8d086a Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Nov 2019 12:21:55 +0100 Subject: [PATCH 113/117] Timeline: handle join rules event --- .../api/session/room/model/RoomJoinRules.kt | 39 +++++++++++++++++++ .../room/model/RoomJoinRulesContent.kt | 29 ++++++++++++++ .../timeline/factory/TimelineItemFactory.kt | 1 + .../timeline/format/NoticeEventFormatter.kt | 14 +++++++ .../helper/TimelineDisplayableEvents.kt | 3 +- vector/src/main/res/values/strings_riotX.xml | 5 +++ 6 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRulesContent.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt new file mode 100644 index 0000000000..fff93cbc6c --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt @@ -0,0 +1,39 @@ +/* + * 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.matrix.android.api.session.room.model + +import com.squareup.moshi.Json + +/** + * Enum for [RoomJoinRulesContent] : https://matrix.org/docs/spec/client_server/r0.4.0#m-room-join-rules + */ +enum class RoomJoinRules(val value: String) { + + @Json(name = "public") + PUBLIC("public"), + + @Json(name = "invite") + INVITE("invite"), + + @Json(name = "knock") + KNOCK("knock"), + + @Json(name = "private") + PRIVATE("private") +} + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRulesContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRulesContent.kt new file mode 100644 index 0000000000..cf6b182e2d --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRulesContent.kt @@ -0,0 +1,29 @@ +/* + * 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.matrix.android.api.session.room.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Class representing the EventType.STATE_ROOM_JOIN_RULES state event content + */ +@JsonClass(generateAdapter = true) +data class RoomJoinRulesContent( + @Json(name = "join_rule") val joinRules: RoomJoinRules? = null +) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index b396eb1f0e..547b739015 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -45,6 +45,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me EventType.STATE_ROOM_NAME, EventType.STATE_ROOM_TOPIC, EventType.STATE_ROOM_MEMBER, + EventType.STATE_ROOM_JOIN_RULES, EventType.STATE_HISTORY_VISIBILITY, EventType.CALL_INVITE, EventType.CALL_HANGUP, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 9a86420277..6a8f4a593d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -22,6 +22,8 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibilityContent +import im.vector.matrix.android.api.session.room.model.RoomJoinRules +import im.vector.matrix.android.api.session.room.model.RoomJoinRulesContent import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.RoomNameContent import im.vector.matrix.android.api.session.room.model.RoomTopicContent @@ -38,6 +40,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active fun format(timelineEvent: TimelineEvent): CharSequence? { return when (val type = timelineEvent.root.getClearType()) { + EventType.STATE_ROOM_JOIN_RULES -> formatJoinRulesEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) EventType.STATE_ROOM_NAME -> formatRoomNameEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) EventType.STATE_ROOM_TOPIC -> formatRoomTopicEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) EventType.STATE_ROOM_MEMBER -> formatRoomMemberEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName()) @@ -58,6 +61,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active fun format(event: Event, senderName: String?): CharSequence? { return when (val type = event.getClearType()) { + EventType.STATE_ROOM_JOIN_RULES -> formatJoinRulesEvent(event, senderName) EventType.STATE_ROOM_NAME -> formatRoomNameEvent(event, senderName) EventType.STATE_ROOM_TOPIC -> formatRoomTopicEvent(event, senderName) EventType.STATE_ROOM_MEMBER -> formatRoomMemberEvent(event, senderName) @@ -220,4 +224,14 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active else -> null } } + + private fun formatJoinRulesEvent(event: Event, senderName: String?): CharSequence? { + val content = event.getClearContent().toModel() ?: return null + return when (content.joinRules) { + RoomJoinRules.INVITE -> stringProvider.getString(R.string.room_join_rules_invite, senderName) + RoomJoinRules.PUBLIC -> stringProvider.getString(R.string.room_join_rules_public, senderName) + else -> null + } + } + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index f40b8e6f6d..1cd851f8c8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -36,7 +36,8 @@ object TimelineDisplayableEvents { EventType.STATE_ROOM_THIRD_PARTY_INVITE, EventType.STICKER, EventType.STATE_ROOM_CREATE, - EventType.STATE_ROOM_TOMBSTONE + EventType.STATE_ROOM_TOMBSTONE, + EventType.STATE_ROOM_JOIN_RULES ) val DEBUG_DISPLAYABLE_TYPES = DISPLAYABLE_TYPES + listOf( diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 6e5b5da92e..8d8be693e1 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -19,4 +19,9 @@ Long click on a room to see more options + + %1$s made the room public to whoever knows the link. + %1$s made the room invite only. + + From 6bd6ececb7b647ac7401f6620fa0787d18896dc6 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Nov 2019 13:23:12 +0100 Subject: [PATCH 114/117] Timeline: handle sticker events --- .../room/model/message/MessageImageContent.kt | 5 +- .../model/message/MessageImageInfoContent.kt | 25 ++++++++ .../model/message/MessageStickerContent.kt | 58 +++++++++++++++++++ .../session/room/timeline/TimelineEvent.kt | 12 +++- .../home/room/detail/RoomDetailFragment.kt | 2 +- .../timeline/TimelineEventController.kt | 2 +- .../timeline/factory/MessageItemFactory.kt | 28 ++++----- .../timeline/factory/TimelineItemFactory.kt | 14 ++--- .../home/room/list/RoomSummaryItemFactory.kt | 5 +- 9 files changed, 122 insertions(+), 29 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageInfoContent.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt index 107a8b276d..9980a36095 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt @@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo + @JsonClass(generateAdapter = true) data class MessageImageContent( /** @@ -38,7 +39,7 @@ data class MessageImageContent( /** * Metadata about the image referred to in url. */ - @Json(name = "info") val info: ImageInfo? = null, + @Json(name = "info") override val info: ImageInfo? = null, /** * Required. Required if the file is unencrypted. The URL (typically MXC URI) to the image. @@ -52,4 +53,4 @@ data class MessageImageContent( * Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption. */ @Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null -) : MessageEncryptedContent +) : MessageImageInfoContent diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageInfoContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageInfoContent.kt new file mode 100644 index 0000000000..9087a45b4c --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageInfoContent.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.matrix.android.api.session.room.model.message + +/** + * A content with image information + */ +interface MessageImageInfoContent : MessageEncryptedContent { + val info: ImageInfo? +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt new file mode 100644 index 0000000000..85d89383af --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt @@ -0,0 +1,58 @@ +/* + * 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.matrix.android.api.session.room.model.message + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import im.vector.matrix.android.api.session.events.model.Content +import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent +import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo + + +@JsonClass(generateAdapter = true) +data class MessageStickerContent( + /** + * Set in local, not from server + */ + override val type: String = MessageType.MSGTYPE_STICKER_LOCAL, + + /** + * Required. A textual representation of the image. This could be the alt text of the image, the filename of the image, + * or some kind of content description for accessibility e.g. 'image attachment'. + */ + @Json(name = "body") override val body: String, + + /** + * Metadata about the image referred to in url. + */ + @Json(name = "info") override val info: ImageInfo? = null, + + /** + * Required. Required if the file is unencrypted. The URL (typically MXC URI) to the image. + */ + @Json(name = "url") override val url: String? = null, + + @Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null, + @Json(name = "m.new_content") override val newContent: Content? = null, + + /** + * Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption. + */ + @Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null +) : MessageImageInfoContent + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt index c05383de4e..1c69dc37dd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt @@ -23,6 +23,8 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.model.message.MessageContent +import im.vector.matrix.android.api.session.room.model.message.MessageImageContent +import im.vector.matrix.android.api.session.room.model.message.MessageStickerContent import im.vector.matrix.android.api.session.room.model.message.isReply import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent @@ -99,8 +101,14 @@ fun TimelineEvent.getEditedEventId(): String? { /** * Get last MessageContent, after a possible edition */ -fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSummary?.aggregatedContent?.toModel() +fun TimelineEvent.getLastMessageContent(): MessageContent? { + return if (root.getClearType() == EventType.STICKER) { + root.getClearContent().toModel() + } else { + annotations?.editSummary?.aggregatedContent?.toModel() ?: root.getClearContent().toModel() + } +} /** * Get last Message body, after a possible edition @@ -110,7 +118,7 @@ fun TimelineEvent.getLastMessageBody(): String? { if (lastMessageContent != null) { return lastMessageContent.newContent?.toModel()?.body - ?: lastMessageContent.body + ?: lastMessageContent.body } return null 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 4643c30f4a..6fdbf94590 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 @@ -877,7 +877,7 @@ class RoomDetailFragment @Inject constructor( vectorBaseActivity.notImplemented("encrypted message click") } - override fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View) { + override fun onImageMessageClicked(messageImageContent: MessageImageInfoContent, mediaData: ImageContentRenderer.Data, view: View) { // TODO Use navigator val intent = ImageMediaViewerActivity.newIntent(vectorBaseActivity, mediaData, ViewCompat.getTransitionName(view)) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt index 8b1296482f..be2f1dd7e4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/TimelineEventController.kt @@ -62,7 +62,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec fun onEventVisible(event: TimelineEvent) fun onRoomCreateLinkClicked(url: String) fun onEncryptedMessageClicked(informationData: MessageInformationData, view: View) - fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View) + fun onImageMessageClicked(messageImageContent: MessageImageInfoContent, mediaData: ImageContentRenderer.Data, view: View) fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: VideoContentRenderer.Data, view: View) fun onFileMessageClicked(eventId: String, messageFileContent: MessageFileContent) fun onAudioMessageClicked(messageAudioContent: MessageAudioContent) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt index eacd702b7d..ac6c563099 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -89,7 +89,7 @@ class MessageItemFactory @Inject constructor( return defaultItemFactory.create(malformedText, informationData, highlight, callback) } if (messageContent.relatesTo?.type == RelationType.REPLACE - || event.isEncrypted() && event.root.content.toModel()?.relatesTo?.type == RelationType.REPLACE + || event.isEncrypted() && event.root.content.toModel()?.relatesTo?.type == RelationType.REPLACE ) { // This is an edit event, we should it when debugging as a notice event return noticeItemFactory.create(event, highlight, readMarkerVisible, callback) @@ -99,14 +99,14 @@ class MessageItemFactory @Inject constructor( // val all = event.root.toContent() // val ev = all.toModel() return when (messageContent) { - is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes) - is MessageImageContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageFileContent -> buildFileMessageItem(messageContent, informationData, highlight, callback, attributes) - is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, highlight, callback, attributes) - else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback) + is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageTextContent -> buildItemForTextContent(messageContent, informationData, highlight, callback, attributes) + is MessageImageInfoContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageFileContent -> buildFileMessageItem(messageContent, informationData, highlight, callback, attributes) + is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, highlight, callback, attributes) + else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback) } } @@ -157,7 +157,7 @@ class MessageItemFactory @Inject constructor( return defaultItemFactory.create(text, informationData, highlight, callback) } - private fun buildImageMessageItem(messageContent: MessageImageContent, + private fun buildImageMessageItem(messageContent: MessageImageInfoContent, @Suppress("UNUSED_PARAMETER") informationData: MessageInformationData, highlight: Boolean, @@ -196,7 +196,7 @@ class MessageItemFactory @Inject constructor( val thumbnailData = ImageContentRenderer.Data( filename = messageContent.body, url = messageContent.videoInfo?.thumbnailFile?.url - ?: messageContent.videoInfo?.thumbnailUrl, + ?: messageContent.videoInfo?.thumbnailUrl, elementToDecrypt = messageContent.videoInfo?.thumbnailFile?.toElementToDecrypt(), height = messageContent.videoInfo?.height, maxHeight = maxHeight, @@ -326,9 +326,9 @@ class MessageItemFactory @Inject constructor( // nop } }, - editStart, - editEnd, - Spanned.SPAN_INCLUSIVE_EXCLUSIVE) + editStart, + editEnd, + Spanned.SPAN_INCLUSIVE_EXCLUSIVE) return spannable } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index 547b739015..618ca121c2 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -39,7 +39,8 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me val computedModel = try { when (event.root.getClearType()) { - EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, highlight, readMarkerVisible, callback) + EventType.STICKER, + EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, highlight, readMarkerVisible, callback) // State and call EventType.STATE_ROOM_TOMBSTONE, EventType.STATE_ROOM_NAME, @@ -52,11 +53,11 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me EventType.CALL_ANSWER, EventType.REACTION, EventType.REDACTION, - EventType.ENCRYPTION -> noticeItemFactory.create(event, highlight, readMarkerVisible, callback) + EventType.ENCRYPTION -> noticeItemFactory.create(event, highlight, readMarkerVisible, callback) // State room create - EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(event, callback) + EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(event, callback) // Crypto - EventType.ENCRYPTED -> { + EventType.ENCRYPTED -> { if (event.root.isRedacted()) { // Redacted event, let the MessageItemFactory handle it messageItemFactory.create(event, nextEvent, highlight, readMarkerVisible, callback) @@ -66,9 +67,8 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me } // Unhandled event types (yet) - EventType.STATE_ROOM_THIRD_PARTY_INVITE, - EventType.STICKER -> defaultItemFactory.create(event, highlight, readMarkerVisible, callback) - else -> { + EventType.STATE_ROOM_THIRD_PARTY_INVITE -> defaultItemFactory.create(event, highlight, readMarkerVisible, callback) + else -> { Timber.v("Type ${event.root.getClearType()} not handled") null } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt index f977fe80fd..66caca26c7 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt @@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.message.MessageContent +import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent import im.vector.riotx.R import im.vector.riotx.core.date.VectorDateFormatter import im.vector.riotx.core.epoxy.VectorEpoxyModel @@ -97,9 +98,9 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte latestFormattedEvent = if (latestEvent.root.isEncrypted() && latestEvent.root.mxDecryptionResult == null) { stringProvider.getString(R.string.encrypted_message) - } else if (latestEvent.root.getClearType() == EventType.MESSAGE) { + } else if (latestEvent.root.getClearType() == EventType.MESSAGE || latestEvent.root.getClearType() == EventType.STICKER) { val senderName = latestEvent.getDisambiguatedDisplayName() - val content = latestEvent.root.getClearContent()?.toModel() + val content = latestEvent.getLastMessageContent() val message = content?.body ?: "" if (roomSummary.isDirect.not()) { span { From 6b1b3bec853885763de7bd142925834d16773d0c Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Nov 2019 13:25:04 +0100 Subject: [PATCH 115/117] Clean code for klint --- .../matrix/android/api/session/room/model/RoomJoinRules.kt | 1 - .../api/session/room/model/message/MessageImageContent.kt | 1 - .../api/session/room/model/message/MessageStickerContent.kt | 2 -- .../matrix/android/api/session/room/timeline/TimelineEvent.kt | 1 - .../home/room/detail/timeline/format/NoticeEventFormatter.kt | 1 - .../riotx/features/home/room/list/RoomSummaryItemFactory.kt | 2 -- 6 files changed, 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt index fff93cbc6c..d7cf8678c3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomJoinRules.kt @@ -36,4 +36,3 @@ enum class RoomJoinRules(val value: String) { @Json(name = "private") PRIVATE("private") } - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt index 9980a36095..fbac261802 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageImageContent.kt @@ -22,7 +22,6 @@ import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo - @JsonClass(generateAdapter = true) data class MessageImageContent( /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt index 85d89383af..d1b4a5c3cb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageStickerContent.kt @@ -23,7 +23,6 @@ import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo - @JsonClass(generateAdapter = true) data class MessageStickerContent( /** @@ -55,4 +54,3 @@ data class MessageStickerContent( */ @Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null ) : MessageImageInfoContent - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt index 1c69dc37dd..ad747efee9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt @@ -23,7 +23,6 @@ import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.model.message.MessageContent -import im.vector.matrix.android.api.session.room.model.message.MessageImageContent import im.vector.matrix.android.api.session.room.model.message.MessageStickerContent import im.vector.matrix.android.api.session.room.model.message.isReply import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 6a8f4a593d..a3910664a2 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -233,5 +233,4 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active else -> null } } - } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt index 66caca26c7..85652c4139 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryItemFactory.kt @@ -18,10 +18,8 @@ package im.vector.riotx.features.home.room.list import android.view.View import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary -import im.vector.matrix.android.api.session.room.model.message.MessageContent import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent import im.vector.riotx.R import im.vector.riotx.core.date.VectorDateFormatter From ec40a8c969171d8ebba81326547ae5802c24fc7b Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Nov 2019 13:26:25 +0100 Subject: [PATCH 116/117] Update CHANGES --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 4523eeaf5d..10e0b0dc01 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: - Search reaction by name or keyword in emoji picker - Handle code tags (#567) - Support spoiler messages + - Support m.sticker and m.room.join_rules events in timeline Other changes: - Markdown set to off by default (#412) From 57dcd569f35e6fb91e6670ce05c1d21529e3dd94 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Nov 2019 09:47:12 +0100 Subject: [PATCH 117/117] Prepare release 0.8.0 --- CHANGES.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 10e0b0dc01..33ba41e778 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,4 @@ -Changes in RiotX 0.8.0 (2019-XX-XX) +Changes in RiotX 0.8.0 (2019-11-19) =================================================== Features ✨: @@ -21,12 +21,6 @@ Bugfix 🐛: - Ask for permission to write external storage when uri comes from the keyboard (#658) - Fix issue with english US/GB translation (#671) -Translations 🗣: - - - -Build 🧱: - - - Changes in RiotX 0.7.0 (2019-10-24) ===================================================