From 9811d6fefc0a038ab7073929db14f513d2fb0b2a Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 20 Jul 2021 01:31:13 +0100 Subject: [PATCH 01/14] add viewmodel, business logic, events, state, fragment and layout --- .../RoomNotificationSettingsAction.kt | 25 +++++ .../RoomNotificationSettingsFragment.kt | 59 ++++++++++++ .../RoomNotificationSettingsViewEvents.kt | 24 +++++ .../RoomNotificationSettingsViewModel.kt | 91 +++++++++++++++++++ .../RoomNotificationSettingsViewState.kt | 40 ++++++++ .../view_edit_room_notification_settings.xml | 14 +++ 6 files changed, 253 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt create mode 100644 vector/src/main/res/layout/view_edit_room_notification_settings.xml diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt new file mode 100644 index 0000000000..9eca3ac5ea --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.notifications + +import im.vector.app.core.platform.VectorViewModelAction +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState + +sealed class RoomNotificationSettingsAction : VectorViewModelAction { + data class SelectNotificationState(val notificationState: RoomNotificationState): RoomNotificationSettingsAction() + object Save: RoomNotificationSettingsAction() +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt new file mode 100644 index 0000000000..4ee9b60dc2 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.notifications + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.fragmentViewModel +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.ViewEditRoomNotificationSettingsBinding +import im.vector.app.features.home.AvatarRenderer +import javax.inject.Inject + +/** + * In this screen: + * - the account has been created and we propose the user to set an avatar and a display name + */ +class RoomNotificationSettingsFragment @Inject constructor( + val roomNotificationSettingsViewModel: RoomNotificationSettingsViewModel.Factory, + private val avatarRenderer: AvatarRenderer, +) : VectorBaseFragment() { + + private val viewModel: RoomNotificationSettingsViewModel by fragmentViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): ViewEditRoomNotificationSettingsBinding { + return ViewEditRoomNotificationSettingsBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + observeViewEvents() + } + + private fun observeViewEvents() { + viewModel.observeViewEvents { + when (it) { + is RoomNotificationSettingsViewEvents.Failure -> displayErrorDialog(it.throwable) + RoomNotificationSettingsViewEvents.SaveComplete -> TODO() + } + } + } + +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt new file mode 100644 index 0000000000..1fe1a98340 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.notifications + +import im.vector.app.core.platform.VectorViewEvents + +sealed class RoomNotificationSettingsViewEvents : VectorViewEvents { + data class Failure(val throwable: Throwable) : RoomNotificationSettingsViewEvents() + object SaveComplete : RoomNotificationSettingsViewEvents() +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt new file mode 100644 index 0000000000..d8fcc102d3 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.notifications + +import androidx.lifecycle.viewModelScope +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.ViewModelContext +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.session.room.Room +import org.matrix.android.sdk.rx.rx + +class RoomNotificationSettingsViewModel @AssistedInject constructor( + @Assisted initialState: RoomNotificationSettingsViewState, + private val room: Room +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory { + fun create(initialState: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel? { + val fragment: RoomNotificationSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() + return fragment.roomNotificationSettingsViewModel.create(state) + } + } + + init { + observeNotificationState() + } + + private fun observeNotificationState() { + room.rx() + .liveNotificationState() + .subscribe{ + setState { + copy(notificationState = it ) + } + } + .disposeOnClear() + } + + override fun handle(action: RoomNotificationSettingsAction) { + when (action) { + is RoomNotificationSettingsAction.SelectNotificationState -> handleSelectNotificationState(action) + is RoomNotificationSettingsAction.Save -> handleSaveNotificationSelection(action) + } + } + + private fun handleSelectNotificationState(action: RoomNotificationSettingsAction.SelectNotificationState) { + setState { + copy(notificationState = action.notificationState) + } + } + + private fun handleSaveNotificationSelection(action: RoomNotificationSettingsAction.Save) { + setState { copy(isLoading = true) } + withState { state -> + viewModelScope.launch { + runCatching { room.setRoomNotificationState(state.notificationState) } + .onFailure { _viewEvents.post(RoomNotificationSettingsViewEvents.Failure(it)) } + setState { + copy(isLoading = false) + } + _viewEvents.post(RoomNotificationSettingsViewEvents.SaveComplete) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt new file mode 100644 index 0000000000..4844521ca3 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.notifications + +import com.airbnb.mvrx.MvRxState +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState + +data class RoomNotificationSettingsViewState( + val isLoading: Boolean, + val roomEncrypted: Boolean, + val notificationState: RoomNotificationState, + val avatarData: AvatarData? +) : MvRxState + +data class AvatarData ( + val displayName: String, + val avatarUrl: String +) + +val RoomNotificationSettingsViewState.notificationOptions: List + get() { + return if (roomEncrypted) { + listOf(RoomNotificationState.ALL_MESSAGES, RoomNotificationState.MUTE) + } else + RoomNotificationState.values().asList() + } diff --git a/vector/src/main/res/layout/view_edit_room_notification_settings.xml b/vector/src/main/res/layout/view_edit_room_notification_settings.xml new file mode 100644 index 0000000000..ecb5c742f7 --- /dev/null +++ b/vector/src/main/res/layout/view_edit_room_notification_settings.xml @@ -0,0 +1,14 @@ + + + + + + + From df7e6bd00dc8acb9290743fabbe643ca753b761b Mon Sep 17 00:00:00 2001 From: David Langley Date: Fri, 23 Jul 2021 14:16:32 +0100 Subject: [PATCH 02/14] add radioItem, RoomNotificationSettingsController and render it in fragment --- .../im/vector/app/core/di/FragmentModule.kt | 7 ++ .../vector/app/core/epoxy/RadioButtonItem.kt | 68 +++++++++++++++++++ .../roomprofile/RoomProfileActivity.kt | 18 +++-- .../roomprofile/RoomProfileFragment.kt | 12 +++- .../roomprofile/RoomProfileSharedAction.kt | 1 + .../RoomNotificationSettingsAction.kt | 1 - .../RoomNotificationSettingsController.kt | 62 +++++++++++++++++ .../RoomNotificationSettingsFragment.kt | 40 +++++++---- .../RoomNotificationSettingsViewEvents.kt | 1 - .../RoomNotificationSettingsViewModel.kt | 43 ++++++------ .../RoomNotificationSettingsViewState.kt | 19 ++++-- vector/src/main/res/layout/item_radio.xml | 40 +++++++++++ .../view_edit_room_notification_settings.xml | 21 ++++++ 13 files changed, 281 insertions(+), 52 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt create mode 100644 vector/src/main/res/layout/item_radio.xml diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 8580543022..8020abd43b 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -106,6 +106,7 @@ import im.vector.app.features.roomprofile.RoomProfileFragment import im.vector.app.features.roomprofile.alias.RoomAliasFragment import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment import im.vector.app.features.roomprofile.members.RoomMemberListFragment +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment @@ -715,6 +716,12 @@ interface FragmentModule { @FragmentKey(RoomBannedMemberListFragment::class) fun bindRoomBannedMemberListFragment(fragment: RoomBannedMemberListFragment): Fragment + @Binds + @IntoMap + @FragmentKey(RoomNotificationSettingsFragment::class) + fun bindRoomNotificationSettingsFragment(fragment: RoomNotificationSettingsFragment): Fragment + + @Binds @IntoMap @FragmentKey(SearchFragment::class) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt new file mode 100644 index 0000000000..e0c7028711 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.epoxy + +import android.widget.ImageView +import android.widget.TextView +import androidx.annotation.StringRes +import androidx.core.content.ContextCompat +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R + +/** + * A action for bottom sheet. + */ +@EpoxyModelClass(layout = R.layout.item_radio) +abstract class RadioButtonItem : VectorEpoxyModel() { + + @EpoxyAttribute + var title: CharSequence? = null + + @StringRes + @EpoxyAttribute + var titleRes: Int? = null + + @EpoxyAttribute + var selected = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + lateinit var listener: ClickListener + + override fun bind(holder: Holder) { + super.bind(holder) + holder.view.onClick(listener) + if (titleRes != null) { + holder.titleText.setText(titleRes!!) + } else { + holder.titleText.text = title + } + + if (selected) { + holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_on)) + holder.radioImage.contentDescription = holder.view.context.getString(R.string.a11y_checked) + } else { + holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_off)) + holder.radioImage.contentDescription = holder.view.context.getString(R.string.a11y_unchecked) + } + } + + class Holder : VectorEpoxyHolder() { + val titleText by bind(R.id.actionTitle) + val radioImage by bind(R.id.radioIcon) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index 07ba442621..d8e080f6a4 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -39,6 +39,7 @@ import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment import im.vector.app.features.roomprofile.members.RoomMemberListFragment import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.alias.RoomAliasFragment +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import javax.inject.Inject @@ -107,12 +108,13 @@ class RoomProfileActivity : .observe() .subscribe { sharedAction -> when (sharedAction) { - RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers() - RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings() - RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias() - RoomProfileSharedAction.OpenRoomPermissionsSettings -> openRoomPermissions() - RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads() - RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() + RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers() + RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings() + RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias() + RoomProfileSharedAction.OpenRoomPermissionsSettings -> openRoomPermissions() + RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads() + RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() + RoomProfileSharedAction.OpenRoomNotificaitonSettings -> openRoomNotificationSettings() }.exhaustive } .disposeOnDestroy() @@ -162,6 +164,10 @@ class RoomProfileActivity : addFragmentToBackstack(R.id.simpleFragmentContainer, RoomBannedMemberListFragment::class.java, roomProfileArgs) } + private fun openRoomNotificationSettings() { + addFragmentToBackstack(R.id.simpleFragmentContainer, RoomNotificationSettingsFragment::class.java, roomProfileArgs) + } + override fun configure(toolbar: MaterialToolbar) { configureToolbar(toolbar) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 14ddf896ca..69e05f372d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -30,6 +30,7 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.animations.AppBarStateChangeListener import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener @@ -253,9 +254,14 @@ class RoomProfileFragment @Inject constructor( } override fun onNotificationsClicked() { - RoomListQuickActionsBottomSheet - .newInstance(roomProfileArgs.roomId, RoomListActionsArgs.Mode.NOTIFICATIONS) - .show(childFragmentManager, "ROOM_PROFILE_NOTIFICATIONS") + // TODO: Use BuildConfig here when merged in + if (false) { + RoomListQuickActionsBottomSheet + .newInstance(roomProfileArgs.roomId, RoomListActionsArgs.Mode.NOTIFICATIONS) + .show(childFragmentManager, "ROOM_PROFILE_NOTIFICATIONS") + } else { + roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificaitonSettings) + } } override fun onUploadsClicked() { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt index 2a5775d1af..6a9533a2eb 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt @@ -28,4 +28,5 @@ sealed class RoomProfileSharedAction : VectorSharedAction { object OpenRoomUploads : RoomProfileSharedAction() object OpenRoomMembers : RoomProfileSharedAction() object OpenBannedRoomMembers : RoomProfileSharedAction() + object OpenRoomNotificaitonSettings : RoomProfileSharedAction() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt index 9eca3ac5ea..10c8861183 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsAction.kt @@ -21,5 +21,4 @@ import org.matrix.android.sdk.api.session.room.notification.RoomNotificationStat sealed class RoomNotificationSettingsAction : VectorViewModelAction { data class SelectNotificationState(val notificationState: RoomNotificationState): RoomNotificationSettingsAction() - object Save: RoomNotificationSettingsAction() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt new file mode 100644 index 0000000000..0e8d7cb2c1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.notifications + +import androidx.annotation.StringRes +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R +import im.vector.app.core.epoxy.radioButtonItem +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState +import javax.inject.Inject + +class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyController() { + + interface Callback { + fun didSelectRoomNotificationState(roomNotificationState: RoomNotificationState) + } + + var callback: Callback? = null + + init { + setData(null) + } + + @StringRes + private fun titleForNotificationState(notificationState: RoomNotificationState) = when(notificationState) { + RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages_noisy + RoomNotificationState.ALL_MESSAGES -> R.string.room_settings_all_messages + RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_only + RoomNotificationState.MUTE -> R.string.room_settings_mute + } + + override fun buildModels(data: RoomNotificationSettingsViewState?) { + val host = this + data ?: return + + data.notificationOptions.forEach { notificationState -> + val title = titleForNotificationState(notificationState) + radioButtonItem { + id(notificationState.name) + titleRes(title) + selected(data.notificationState() == notificationState) + listener { + host.callback?.didSelectRoomNotificationState(notificationState) + } + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt index 4ee9b60dc2..44ae9a3395 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt @@ -20,40 +20,56 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.app.R +import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.databinding.ViewEditRoomNotificationSettingsBinding -import im.vector.app.features.home.AvatarRenderer +import im.vector.app.databinding.FragmentRoomSettingGenericBinding +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import javax.inject.Inject -/** - * In this screen: - * - the account has been created and we propose the user to set an avatar and a display name - */ class RoomNotificationSettingsFragment @Inject constructor( val roomNotificationSettingsViewModel: RoomNotificationSettingsViewModel.Factory, - private val avatarRenderer: AvatarRenderer, -) : VectorBaseFragment() { + val roomNotificationSettingsController: RoomNotificationSettingsController +) : VectorBaseFragment(), + RoomNotificationSettingsController.Callback { private val viewModel: RoomNotificationSettingsViewModel by fragmentViewModel() - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): ViewEditRoomNotificationSettingsBinding { - return ViewEditRoomNotificationSettingsBinding.inflate(inflater, container, false) + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomSettingGenericBinding { + return FragmentRoomSettingGenericBinding.inflate(inflater, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + setupToolbar(views.roomSettingsToolbar) + views.roomSettingsToolbarTitleView.setText(R.string.settings_notifications) + roomNotificationSettingsController.callback = this + views.roomSettingsRecyclerView.configureWith(roomNotificationSettingsController, hasFixedSize = true) + setupWaitingView() observeViewEvents() } + private fun setupWaitingView() { + views.waitingView.waitingStatusText.setText(R.string.please_wait) + views.waitingView.waitingStatusText.isVisible = true + } private fun observeViewEvents() { viewModel.observeViewEvents { when (it) { is RoomNotificationSettingsViewEvents.Failure -> displayErrorDialog(it.throwable) - RoomNotificationSettingsViewEvents.SaveComplete -> TODO() } } } + override fun invalidate() = withState(viewModel) { viewState -> + roomNotificationSettingsController.setData(viewState) + views.waitingView.root.isVisible = viewState.isLoading + } + + override fun didSelectRoomNotificationState(roomNotificationState: RoomNotificationState) { + viewModel.handle(RoomNotificationSettingsAction.SelectNotificationState(roomNotificationState)) + } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt index 1fe1a98340..dda858283b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewEvents.kt @@ -20,5 +20,4 @@ import im.vector.app.core.platform.VectorViewEvents sealed class RoomNotificationSettingsViewEvents : VectorViewEvents { data class Failure(val throwable: Throwable) : RoomNotificationSettingsViewEvents() - object SaveComplete : RoomNotificationSettingsViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index d8fcc102d3..c92d4dd422 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -19,18 +19,19 @@ package im.vector.app.features.roomprofile.notifications import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.session.room.Room +import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.rx.rx class RoomNotificationSettingsViewModel @AssistedInject constructor( @Assisted initialState: RoomNotificationSettingsViewState, - private val room: Room + session: Session ) : VectorViewModel(initialState) { @AssistedFactory @@ -41,50 +42,46 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( companion object : MvRxViewModelFactory { @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel? { + override fun create(viewModelContext: ViewModelContext, state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel { val fragment: RoomNotificationSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() return fragment.roomNotificationSettingsViewModel.create(state) } } + private val room = session.getRoom(initialState.roomId)!! + init { + initEncrypted() observeNotificationState() } + private fun initEncrypted() { + setState { + copy(roomEncrypted = room.isEncrypted()) + } + } + private fun observeNotificationState() { room.rx() .liveNotificationState() - .subscribe{ - setState { - copy(notificationState = it ) - } + .execute { + copy(notificationState = it) } - .disposeOnClear() } override fun handle(action: RoomNotificationSettingsAction) { when (action) { is RoomNotificationSettingsAction.SelectNotificationState -> handleSelectNotificationState(action) - is RoomNotificationSettingsAction.Save -> handleSaveNotificationSelection(action) } } private fun handleSelectNotificationState(action: RoomNotificationSettingsAction.SelectNotificationState) { - setState { - copy(notificationState = action.notificationState) - } - } - - private fun handleSaveNotificationSelection(action: RoomNotificationSettingsAction.Save) { setState { copy(isLoading = true) } - withState { state -> - viewModelScope.launch { - runCatching { room.setRoomNotificationState(state.notificationState) } - .onFailure { _viewEvents.post(RoomNotificationSettingsViewEvents.Failure(it)) } - setState { - copy(isLoading = false) - } - _viewEvents.post(RoomNotificationSettingsViewEvents.SaveComplete) + viewModelScope.launch { + runCatching { room.setRoomNotificationState(action.notificationState) } + .onFailure { _viewEvents.post(RoomNotificationSettingsViewEvents.Failure(it)) } + setState { + copy(isLoading = false, notificationState = Success(action.notificationState)) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index 4844521ca3..f67947ca9f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -16,15 +16,22 @@ package im.vector.app.features.roomprofile.notifications +import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized +import im.vector.app.features.roomprofile.RoomProfileArgs import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState data class RoomNotificationSettingsViewState( - val isLoading: Boolean, - val roomEncrypted: Boolean, - val notificationState: RoomNotificationState, - val avatarData: AvatarData? -) : MvRxState + val roomId: String, + val isLoading: Boolean = false, + val roomEncrypted: Boolean = false, + val notificationState: Async = Uninitialized, + val avatarData: AvatarData? = null +) : MvRxState { + + constructor(args: RoomProfileArgs) : this(roomId = args.roomId) +} data class AvatarData ( val displayName: String, @@ -34,7 +41,7 @@ data class AvatarData ( val RoomNotificationSettingsViewState.notificationOptions: List get() { return if (roomEncrypted) { - listOf(RoomNotificationState.ALL_MESSAGES, RoomNotificationState.MUTE) + listOf(RoomNotificationState.ALL_MESSAGES_NOISY, RoomNotificationState.ALL_MESSAGES, RoomNotificationState.MUTE) } else RoomNotificationState.values().asList() } diff --git a/vector/src/main/res/layout/item_radio.xml b/vector/src/main/res/layout/item_radio.xml new file mode 100644 index 0000000000..4cd5312dc0 --- /dev/null +++ b/vector/src/main/res/layout/item_radio.xml @@ -0,0 +1,40 @@ + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/view_edit_room_notification_settings.xml b/vector/src/main/res/layout/view_edit_room_notification_settings.xml index ecb5c742f7..3d4cafc40f 100644 --- a/vector/src/main/res/layout/view_edit_room_notification_settings.xml +++ b/vector/src/main/res/layout/view_edit_room_notification_settings.xml @@ -10,5 +10,26 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + + + From 90e04d4358e733eab1530c0ec6f2fbf2552980cf Mon Sep 17 00:00:00 2001 From: David Langley Date: Fri, 23 Jul 2021 22:37:36 +0100 Subject: [PATCH 03/14] add header footer and fix toolbar --- .../NotificationSettingsFooterItem.kt | 60 +++++++++++++++++++ .../notifications}/RadioButtonItem.kt | 10 ++-- .../profiles/notifications/TextHeaderItem.kt | 49 +++++++++++++++ .../im/vector/app/core/extensions/TextView.kt | 17 ++++++ .../RoomNotificationSettingsController.kt | 18 +++++- .../RoomNotificationSettingsFragment.kt | 21 ++++++- .../RoomNotificationSettingsViewModel.kt | 12 +++- .../RoomNotificationSettingsViewState.kt | 3 +- .../res/layout/item_notifications_footer.xml | 25 ++++++++ .../src/main/res/layout/item_text_header.xml | 25 ++++++++ vector/src/main/res/values/strings.xml | 4 ++ 11 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt rename vector/src/main/java/im/vector/app/core/epoxy/{ => profiles/notifications}/RadioButtonItem.kt (89%) create mode 100644 vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt create mode 100644 vector/src/main/res/layout/item_notifications_footer.xml create mode 100644 vector/src/main/res/layout/item_text_header.xml diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt new file mode 100644 index 0000000000..540d1ff5bd --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.epoxy.profiles.notifications + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.extensions.setTextWithColoredPart + +@EpoxyModelClass(layout = R.layout.item_notifications_footer) +abstract class NotificationSettingsFooterItem : VectorEpoxyModel() { + + @EpoxyAttribute + var encrypted: Boolean = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var clickListener: ClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + + + val accountSettingsString = holder.view.context.getString(R.string.room_settings_room_notifications_account_settings) + val manageNotificationsString = StringBuilder(holder.view.context.getString(R.string.room_settings_room_notifications_manage_notifications, accountSettingsString)) + if (encrypted) { + val encryptionNotice = holder.view.context.getString(R.string.room_settings_room_notifications_encryption_notice) + manageNotificationsString.appendLine().append(encryptionNotice) + } + + holder.textView.setTextWithColoredPart( + manageNotificationsString.toString(), + accountSettingsString, + underline = true + ) { + clickListener?.invoke(holder.textView) + } + } + + class Holder : VectorEpoxyHolder() { + val textView by bind(R.id.footerText) + } +} diff --git a/vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/RadioButtonItem.kt similarity index 89% rename from vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt rename to vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/RadioButtonItem.kt index e0c7028711..3afec2c5ce 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/RadioButtonItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/RadioButtonItem.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.core.epoxy +package im.vector.app.core.epoxy.profiles.notifications import android.widget.ImageView import android.widget.TextView @@ -23,10 +23,12 @@ import androidx.core.content.ContextCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick + -/** - * A action for bottom sheet. - */ @EpoxyModelClass(layout = R.layout.item_radio) abstract class RadioButtonItem : VectorEpoxyModel() { diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt new file mode 100644 index 0000000000..1f6cea0fd5 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.epoxy.profiles.notifications + +import android.widget.TextView +import androidx.annotation.StringRes +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel + +@EpoxyModelClass(layout = R.layout.item_text_header) +abstract class TextHeaderItem : VectorEpoxyModel() { + + @EpoxyAttribute + var text: String? = null + + @StringRes + @EpoxyAttribute + var textRes: Int? = null + + override fun bind(holder: Holder) { + super.bind(holder) + if (textRes != null) { + holder.textView.setText(textRes!!) + } else { + holder.textView.text = text + } + } + + class Holder : VectorEpoxyHolder() { + val textView by bind(R.id.headerText) + } +} diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt index bb991ac32c..1c424f7071 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt @@ -65,6 +65,23 @@ fun TextView.setTextWithColoredPart(@StringRes fullTextRes: Int, val coloredPart = resources.getString(coloredTextRes) // Insert colored part into the full text val fullText = resources.getString(fullTextRes, coloredPart) + + setTextWithColoredPart(fullText, coloredPart, colorAttribute, underline, onClick) +} + +/** + * Set text with a colored part + * @param fullText The full text. + * @param coloredPart The colored part of the text + * @param colorAttribute attribute of the color. Default to colorPrimary + * @param underline true to also underline the text. Default to false + * @param onClick attributes to handle click on the colored part if needed + */ +fun TextView.setTextWithColoredPart(fullText: String, + coloredPart: String, + @AttrRes colorAttribute: Int = R.attr.colorPrimary, + underline: Boolean = false, + onClick: (() -> Unit)? = null) { val color = ThemeUtils.getColor(context, colorAttribute) val foregroundSpan = ForegroundColorSpan(color) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt index 0e8d7cb2c1..6de4b586c0 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt @@ -19,7 +19,11 @@ package im.vector.app.features.roomprofile.notifications import androidx.annotation.StringRes import com.airbnb.epoxy.TypedEpoxyController import im.vector.app.R -import im.vector.app.core.epoxy.radioButtonItem +import im.vector.app.core.epoxy.profiles.notifications.notificationSettingsFooterItem +import im.vector.app.core.epoxy.profiles.notifications.radioButtonItem +import im.vector.app.core.epoxy.profiles.notifications.textHeaderItem +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.ui.list.genericHeaderItem import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import javax.inject.Inject @@ -27,6 +31,7 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr interface Callback { fun didSelectRoomNotificationState(roomNotificationState: RoomNotificationState) + fun didSelectAccountSettingsLink() } var callback: Callback? = null @@ -47,6 +52,10 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr val host = this data ?: return + textHeaderItem { + id("roomNotificationSettingsHeader") + textRes(R.string.room_settings_room_notifications_notify_me) + } data.notificationOptions.forEach { notificationState -> val title = titleForNotificationState(notificationState) radioButtonItem { @@ -58,5 +67,12 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr } } } + notificationSettingsFooterItem { + id("roomNotificationSettingsFooter") + encrypted(data.roomEncrypted) + clickListener { + host.callback?.didSelectAccountSettingsLink() + } + } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt index 44ae9a3395..8baef5d10c 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt @@ -27,12 +27,15 @@ import im.vector.app.R import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomSettingGenericBinding +import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState +import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject class RoomNotificationSettingsFragment @Inject constructor( - val roomNotificationSettingsViewModel: RoomNotificationSettingsViewModel.Factory, - val roomNotificationSettingsController: RoomNotificationSettingsController + val viewModelFactory: RoomNotificationSettingsViewModel.Factory, + private val roomNotificationSettingsController: RoomNotificationSettingsController, + private val avatarRenderer: AvatarRenderer ) : VectorBaseFragment(), RoomNotificationSettingsController.Callback { @@ -45,7 +48,6 @@ class RoomNotificationSettingsFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupToolbar(views.roomSettingsToolbar) - views.roomSettingsToolbarTitleView.setText(R.string.settings_notifications) roomNotificationSettingsController.callback = this views.roomSettingsRecyclerView.configureWith(roomNotificationSettingsController, hasFixedSize = true) setupWaitingView() @@ -67,9 +69,22 @@ class RoomNotificationSettingsFragment @Inject constructor( override fun invalidate() = withState(viewModel) { viewState -> roomNotificationSettingsController.setData(viewState) views.waitingView.root.isVisible = viewState.isLoading + renderRoomSummary(viewState) } override fun didSelectRoomNotificationState(roomNotificationState: RoomNotificationState) { viewModel.handle(RoomNotificationSettingsAction.SelectNotificationState(roomNotificationState)) } + + override fun didSelectAccountSettingsLink() { + navigator.openSettings(requireContext()) + } + + private fun renderRoomSummary(state: RoomNotificationSettingsViewState) { + state.roomSummary()?.let { + views.roomSettingsToolbarTitleView.text = it.displayName + avatarRenderer.render(it.toMatrixItem(), views.roomSettingsToolbarAvatarImageView) + views.roomSettingsDecorationToolbarAvatarImageView.render(it.roomEncryptionTrustLevel) + } + } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index c92d4dd422..ad71343c1f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -28,6 +28,7 @@ import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.rx.rx +import org.matrix.android.sdk.rx.unwrap class RoomNotificationSettingsViewModel @AssistedInject constructor( @Assisted initialState: RoomNotificationSettingsViewState, @@ -44,7 +45,7 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( @JvmStatic override fun create(viewModelContext: ViewModelContext, state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel { val fragment: RoomNotificationSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomNotificationSettingsViewModel.create(state) + return fragment.viewModelFactory.create(state) } } @@ -52,6 +53,7 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( init { initEncrypted() + observeSummary() observeNotificationState() } @@ -61,6 +63,14 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( } } + private fun observeSummary() { + room.rx().liveRoomSummary() + .unwrap() + .execute { async -> + copy(roomSummary = async) + } + } + private fun observeNotificationState() { room.rx() .liveNotificationState() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index f67947ca9f..2f1916751f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -20,14 +20,15 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.Uninitialized import im.vector.app.features.roomprofile.RoomProfileArgs +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState data class RoomNotificationSettingsViewState( val roomId: String, + val roomSummary: Async = Uninitialized, val isLoading: Boolean = false, val roomEncrypted: Boolean = false, val notificationState: Async = Uninitialized, - val avatarData: AvatarData? = null ) : MvRxState { constructor(args: RoomProfileArgs) : this(roomId = args.roomId) diff --git a/vector/src/main/res/layout/item_notifications_footer.xml b/vector/src/main/res/layout/item_notifications_footer.xml new file mode 100644 index 0000000000..8338358048 --- /dev/null +++ b/vector/src/main/res/layout/item_notifications_footer.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_text_header.xml b/vector/src/main/res/layout/item_text_header.xml new file mode 100644 index 0000000000..15848f585e --- /dev/null +++ b/vector/src/main/res/layout/item_text_header.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index ef25329eed..5cf121b388 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1408,6 +1408,10 @@ Access and visibility List this room in room directory Notifications + Notify me for + Please note that mentions & keyword notifications are not available in encrypted rooms on mobile. + You can manage notifications in %1$s. + Account settings Room Access Room History Readability Who can read history? From 57c32502e55c8463dad7a73f226257e24a757114 Mon Sep 17 00:00:00 2001 From: David Langley Date: Fri, 23 Jul 2021 23:18:39 +0100 Subject: [PATCH 04/14] change notification state options as outlined in v2 --- .../RoomNotificationSettingsController.kt | 12 +++++----- .../RoomNotificationSettingsViewState.kt | 22 ++++++++++++++++--- vector/src/main/res/values/strings.xml | 2 ++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt index 6de4b586c0..cad8ef8287 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt @@ -41,11 +41,11 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr } @StringRes - private fun titleForNotificationState(notificationState: RoomNotificationState) = when(notificationState) { - RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages_noisy - RoomNotificationState.ALL_MESSAGES -> R.string.room_settings_all_messages - RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_only - RoomNotificationState.MUTE -> R.string.room_settings_mute + private fun titleForNotificationState(notificationState: RoomNotificationState): Int? = when(notificationState) { + RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages + RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_and_keyword_only + RoomNotificationState.MUTE -> R.string.room_settings_none + else -> null } override fun buildModels(data: RoomNotificationSettingsViewState?) { @@ -61,7 +61,7 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr radioButtonItem { id(notificationState.name) titleRes(title) - selected(data.notificationState() == notificationState) + selected(data.notificationStateMapped() == notificationState) listener { host.callback?.didSelectRoomNotificationState(notificationState) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index 2f1916751f..bff1a26595 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -18,6 +18,7 @@ package im.vector.app.features.roomprofile.notifications import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import im.vector.app.features.roomprofile.RoomProfileArgs import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -30,7 +31,6 @@ data class RoomNotificationSettingsViewState( val roomEncrypted: Boolean = false, val notificationState: Async = Uninitialized, ) : MvRxState { - constructor(args: RoomProfileArgs) : this(roomId = args.roomId) } @@ -39,10 +39,26 @@ data class AvatarData ( val avatarUrl: String ) +/** + * Used to map this old room notification settings to the new options in v2. + */ +val RoomNotificationSettingsViewState.notificationStateMapped: Async + get() { + if ((roomEncrypted && notificationState() == RoomNotificationState.MENTIONS_ONLY) || notificationState() == RoomNotificationState.ALL_MESSAGES) { + /** if in an encrypted room, mentions notifications are not supported so show "All Messages" as selected. + * Also in the new settings there is no notion of notifications without sound so it maps to noisy also + */ + return Success(RoomNotificationState.ALL_MESSAGES_NOISY) + } + return notificationState + } +/** + * Used to enumerate the new settings in notification settings v2. Notifications without sound and mentions in encrypted rooms not supported. + */ val RoomNotificationSettingsViewState.notificationOptions: List get() { return if (roomEncrypted) { - listOf(RoomNotificationState.ALL_MESSAGES_NOISY, RoomNotificationState.ALL_MESSAGES, RoomNotificationState.MUTE) + listOf(RoomNotificationState.ALL_MESSAGES_NOISY, RoomNotificationState.MUTE) } else - RoomNotificationState.values().asList() + listOf(RoomNotificationState.ALL_MESSAGES_NOISY, RoomNotificationState.MENTIONS_ONLY, RoomNotificationState.MUTE) } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 5cf121b388..05980c8914 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1037,6 +1037,8 @@ All messages Mentions only Mute + Mentions & Keywords only + None Favourite De-prioritize Direct Chat From 42a1ed2abe05b04dd7730126a8eef7ff2b213e99 Mon Sep 17 00:00:00 2001 From: David Langley Date: Fri, 23 Jul 2021 23:22:06 +0100 Subject: [PATCH 05/14] remove unneeded layout file --- .../RoomNotificationSettingsController.kt | 2 -- .../view_edit_room_notification_settings.xml | 35 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 vector/src/main/res/layout/view_edit_room_notification_settings.xml diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt index cad8ef8287..e6c57523e5 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt @@ -22,8 +22,6 @@ import im.vector.app.R import im.vector.app.core.epoxy.profiles.notifications.notificationSettingsFooterItem import im.vector.app.core.epoxy.profiles.notifications.radioButtonItem import im.vector.app.core.epoxy.profiles.notifications.textHeaderItem -import im.vector.app.core.resources.StringProvider -import im.vector.app.core.ui.list.genericHeaderItem import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import javax.inject.Inject diff --git a/vector/src/main/res/layout/view_edit_room_notification_settings.xml b/vector/src/main/res/layout/view_edit_room_notification_settings.xml deleted file mode 100644 index 3d4cafc40f..0000000000 --- a/vector/src/main/res/layout/view_edit_room_notification_settings.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - From a76a936e21db572737101d9fb5edd927bdc70476 Mon Sep 17 00:00:00 2001 From: David Langley Date: Mon, 26 Jul 2021 22:54:32 +0100 Subject: [PATCH 06/14] implement bottom sheet and error handling --- .../home/room/list/RoomListFragment.kt | 12 ++- .../RoomListQuickActionsBottomSheet.kt | 36 ++++++++- .../RoomListQuickActionsEpoxyController.kt | 65 ++++++++++++---- .../RoomListQuickActionsSharedAction.kt | 7 +- .../list/actions/RoomListQuickActionsState.kt | 33 -------- .../actions/RoomListQuickActionsViewModel.kt | 78 ------------------- .../roomprofile/RoomProfileFragment.kt | 1 - .../RoomNotificationSettingsViewModel.kt | 11 ++- .../RoomNotificationSettingsViewState.kt | 2 + 9 files changed, 108 insertions(+), 137 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsState.kt delete mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsViewModel.kt diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index fdfe171439..b053b5b825 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -473,9 +473,17 @@ class RoomListFragment @Inject constructor( // refresh footer footerController.setData(it) } - RoomListQuickActionsBottomSheet + val bottomSheet = RoomListQuickActionsBottomSheet .newInstance(room.roomId, RoomListActionsArgs.Mode.FULL) - .show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS") + bottomSheet.listener = object : RoomListQuickActionsBottomSheet.Listener { + override fun handleFailure(throwable: Throwable) { + showFailure(throwable) + } + } + + bottomSheet.show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS") + + return true } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 94f9aaf496..463e5ad94a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -22,6 +22,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.core.di.ScreenComponent @@ -30,7 +31,12 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.features.navigation.Navigator +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsAction +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewEvents +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewModel +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewState import kotlinx.parcelize.Parcelize +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import javax.inject.Inject @Parcelize @@ -45,6 +51,11 @@ data class RoomListActionsArgs( } } +data class RoomListQuickActionViewState( + val roomListActionsArgs: RoomListActionsArgs, + val notificationSettingsViewState: RoomNotificationSettingsViewState +) + /** * Bottom sheet fragment that shows room information with list of contextual actions */ @@ -52,15 +63,20 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { + interface Listener { + fun handleFailure(throwable: Throwable) + } private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool - @Inject lateinit var roomListActionsViewModelFactory: RoomListQuickActionsViewModel.Factory + @Inject lateinit var roomNotificationSettingsViewModelFactory: RoomNotificationSettingsViewModel.Factory @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController @Inject lateinit var navigator: Navigator - private val viewModel: RoomListQuickActionsViewModel by fragmentViewModel(RoomListQuickActionsViewModel::class) + private val roomListActionsArgs: RoomListActionsArgs by args() + private val viewModel: RoomNotificationSettingsViewModel by fragmentViewModel(RoomNotificationSettingsViewModel::class) override val showExpanded = true + var listener: Listener? = null override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -80,6 +96,12 @@ class RoomListQuickActionsBottomSheet : disableItemAnimation = true ) roomListActionsEpoxyController.listener = this + + viewModel.observeViewEvents { + when(it){ + is RoomNotificationSettingsViewEvents.Failure -> listener?.handleFailure(it.throwable) + } + } } override fun onDestroyView() { @@ -89,7 +111,11 @@ class RoomListQuickActionsBottomSheet : } override fun invalidate() = withState(viewModel) { - roomListActionsEpoxyController.setData(it) + val roomListViewState = RoomListQuickActionViewState( + roomListActionsArgs, + it + ) + roomListActionsEpoxyController.setData(roomListViewState) super.invalidate() } @@ -103,6 +129,10 @@ class RoomListQuickActionsBottomSheet : } } + override fun didSelectRoomNotificationState(roomNotificationState: RoomNotificationState) { + viewModel.handle(RoomNotificationSettingsAction.SelectNotificationState(roomNotificationState)) + } + companion object { fun newInstance(roomId: String, mode: RoomListActionsArgs.Mode): RoomListQuickActionsBottomSheet { return RoomListQuickActionsBottomSheet().apply { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index 4604159338..0bca6639a0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -15,13 +15,18 @@ */ package im.vector.app.features.home.room.list.actions +import androidx.annotation.StringRes import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R import im.vector.app.core.epoxy.bottomSheetDividerItem import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem import im.vector.app.core.epoxy.bottomsheet.bottomSheetRoomPreviewItem +import im.vector.app.core.epoxy.profiles.notifications.radioButtonItem import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.roomprofile.notifications.notificationOptions +import im.vector.app.features.roomprofile.notifications.notificationStateMapped import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject @@ -33,16 +38,26 @@ class RoomListQuickActionsEpoxyController @Inject constructor( private val avatarRenderer: AvatarRenderer, private val colorProvider: ColorProvider, private val stringProvider: StringProvider -) : TypedEpoxyController() { +) : TypedEpoxyController() { var listener: Listener? = null - override fun buildModels(state: RoomListQuickActionsState) { - val roomSummary = state.roomSummary() ?: return - val host = this - val showAll = state.mode == RoomListActionsArgs.Mode.FULL + @StringRes + private fun titleForNotificationState(notificationState: RoomNotificationState): Int? = when(notificationState) { + RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages + RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_and_keyword_only + RoomNotificationState.MUTE -> R.string.room_settings_none + else -> null + } - if (showAll) { + override fun buildModels(state: RoomListQuickActionViewState) { + val notificationViewState = state.notificationSettingsViewState + val roomSummary = notificationViewState.roomSummary() ?: return + val host = this + val showFull = state.roomListActionsArgs.mode == RoomListActionsArgs.Mode.FULL + var isV2 = true + + if (showFull || isV2) { // Preview, favorite, settings bottomSheetRoomPreviewItem { id("room_preview") @@ -63,15 +78,30 @@ class RoomListQuickActionsEpoxyController @Inject constructor( } } - val selectedRoomState = state.roomNotificationState() - 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) - - if (showAll) { - RoomListQuickActionsSharedAction.Leave(roomSummary.roomId).toBottomSheetItem(5) + if (isV2) { + notificationViewState.notificationOptions.forEach { notificationState -> + val title = titleForNotificationState(notificationState) + radioButtonItem { + id(notificationState.name) + titleRes(title) + selected(notificationViewState.notificationStateMapped() == notificationState) + listener { + host.listener?.didSelectRoomNotificationState(notificationState) + } + } + } + } else { + val selectedRoomState = notificationViewState.notificationState() + 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) } + + if (showFull || isV2) { + RoomListQuickActionsSharedAction.Leave(roomSummary.roomId, showIcon = !isV2).toBottomSheetItem(5) + } + } private fun RoomListQuickActionsSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { @@ -86,7 +116,11 @@ class RoomListQuickActionsEpoxyController @Inject constructor( return bottomSheetActionItem { id("action_$index") selected(selected) - iconRes(iconResId) + if(iconResId != null){ + iconRes(iconResId) + } else{ + showIcon(false) + } textRes(titleRes) destructive(this@toBottomSheetItem.destructive) listener { host.listener?.didSelectMenuAction(this@toBottomSheetItem) } @@ -95,5 +129,6 @@ class RoomListQuickActionsEpoxyController @Inject constructor( interface Listener { fun didSelectMenuAction(quickAction: RoomListQuickActionsSharedAction) + fun didSelectRoomNotificationState(roomNotificationState: RoomNotificationState) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt index 075dca0c52..20c3087f54 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt @@ -21,9 +21,10 @@ import androidx.annotation.StringRes import im.vector.app.R import im.vector.app.core.platform.VectorSharedAction + sealed class RoomListQuickActionsSharedAction( @StringRes val titleRes: Int, - @DrawableRes val iconResId: Int, + @DrawableRes val iconResId: Int?, val destructive: Boolean = false) : VectorSharedAction { @@ -60,9 +61,9 @@ sealed class RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_favorite_add, R.drawable.ic_star_24dp) - data class Leave(val roomId: String) : RoomListQuickActionsSharedAction( + data class Leave(val roomId: String, val showIcon: Boolean=true) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_leave, - R.drawable.ic_room_actions_leave, + if (showIcon) R.drawable.ic_room_actions_leave else null, true ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsState.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsState.kt deleted file mode 100644 index 2731620cec..0000000000 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsState.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.app.features.home.room.list.actions - -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.MvRxState -import com.airbnb.mvrx.Uninitialized -import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState - -data class RoomListQuickActionsState( - val roomId: String, - val mode: RoomListActionsArgs.Mode, - val roomSummary: Async = Uninitialized, - val roomNotificationState: Async = Uninitialized -) : MvRxState { - - constructor(args: RoomListActionsArgs) : this(roomId = args.roomId, mode = args.mode) -} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsViewModel.kt deleted file mode 100644 index 75e9459d2c..0000000000 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsViewModel.kt +++ /dev/null @@ -1,78 +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.app.features.home.room.list.actions - -import com.airbnb.mvrx.FragmentViewModelContext -import com.airbnb.mvrx.MvRxViewModelFactory -import com.airbnb.mvrx.ViewModelContext -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import dagger.assisted.AssistedFactory -import im.vector.app.core.platform.EmptyAction -import im.vector.app.core.platform.EmptyViewEvents -import im.vector.app.core.platform.VectorViewModel -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.rx.rx -import org.matrix.android.sdk.rx.unwrap - -class RoomListQuickActionsViewModel @AssistedInject constructor(@Assisted initialState: RoomListQuickActionsState, - session: Session -) : VectorViewModel(initialState) { - - @AssistedFactory - interface Factory { - fun create(initialState: RoomListQuickActionsState): RoomListQuickActionsViewModel - } - - companion object : MvRxViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomListQuickActionsState): RoomListQuickActionsViewModel? { - val fragment: RoomListQuickActionsBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomListActionsViewModelFactory.create(state) - } - } - - private val room = session.getRoom(initialState.roomId)!! - - init { - observeRoomSummary() - observeNotificationState() - } - - private fun observeNotificationState() { - room - .rx() - .liveNotificationState() - .execute { - copy(roomNotificationState = it) - } - } - - private fun observeRoomSummary() { - room - .rx() - .liveRoomSummary() - .unwrap() - .execute { - copy(roomSummary = it) - } - } - - override fun handle(action: EmptyAction) { - // No op - } -} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 69e05f372d..7030e96c6f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -30,7 +30,6 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder -import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.animations.AppBarStateChangeListener import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index ad71343c1f..5d23931d88 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -25,6 +25,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.rx.rx @@ -44,8 +45,14 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( @JvmStatic override fun create(viewModelContext: ViewModelContext, state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel { - val fragment: RoomNotificationSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) + val fragmentModelContext = (viewModelContext as FragmentViewModelContext) + return if (fragmentModelContext.fragment is RoomNotificationSettingsFragment) { + val fragment: RoomNotificationSettingsFragment = fragmentModelContext.fragment() + fragment.viewModelFactory.create(state) + } else { + val fragment: RoomListQuickActionsBottomSheet = fragmentModelContext.fragment() + fragment.roomNotificationSettingsViewModelFactory.create(state) + } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index bff1a26595..a88dc84078 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -20,6 +20,7 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized +import im.vector.app.features.home.room.list.actions.RoomListActionsArgs import im.vector.app.features.roomprofile.RoomProfileArgs import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState @@ -32,6 +33,7 @@ data class RoomNotificationSettingsViewState( val notificationState: Async = Uninitialized, ) : MvRxState { constructor(args: RoomProfileArgs) : this(roomId = args.roomId) + constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) } data class AvatarData ( From 92a44cd9d61c369ce79d34091b816ca543fbc566 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 11 Aug 2021 13:13:38 +0100 Subject: [PATCH 07/14] add build config, use single variable in grandle file and update source to use feature flag --- vector/build.gradle | 9 +++++++-- .../list/actions/RoomListQuickActionsEpoxyController.kt | 3 ++- .../app/features/roomprofile/RoomProfileFragment.kt | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index 5b5f65e9dd..311f7ed172 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -142,9 +142,14 @@ android { resValue "bool", "useLoginV1", "true" resValue "bool", "useLoginV2", "false" + + // NotificationSettingsV2 is disabled. To be released in conjunction with iOS/Web - resValue "bool", "useNotificationSettingsV1", "true" - resValue "bool", "useNotificationSettingsV2", "false" + def useNotificationSettingsV2 = false + buildConfigField "Boolean", "USE_NOTIFICATION_SETTINGS_V2", "${useNotificationSettingsV2}" + resValue "bool", "useNotificationSettingsV1", "${!useNotificationSettingsV2}" + resValue "bool", "useNotificationSettingsV2", "${useNotificationSettingsV2}" + buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping" diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index 0bca6639a0..ccfe0fdf71 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.list.actions import androidx.annotation.StringRes import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.epoxy.bottomSheetDividerItem import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem @@ -55,7 +56,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor( val roomSummary = notificationViewState.roomSummary() ?: return val host = this val showFull = state.roomListActionsArgs.mode == RoomListActionsArgs.Mode.FULL - var isV2 = true + var isV2 = BuildConfig.USE_NOTIFICATION_SETTINGS_V2 if (showFull || isV2) { // Preview, favorite, settings diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 7030e96c6f..ea5bbd2e84 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -30,6 +30,7 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.animations.AppBarStateChangeListener import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener @@ -253,13 +254,12 @@ class RoomProfileFragment @Inject constructor( } override fun onNotificationsClicked() { - // TODO: Use BuildConfig here when merged in - if (false) { + if (BuildConfig.USE_NOTIFICATION_SETTINGS_V2) { + roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificaitonSettings) + } else { RoomListQuickActionsBottomSheet .newInstance(roomProfileArgs.roomId, RoomListActionsArgs.Mode.NOTIFICATIONS) .show(childFragmentManager, "ROOM_PROFILE_NOTIFICATIONS") - } else { - roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificaitonSettings) } } From 00275d936763b6d09ab78e0fd29278af6b301195 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 11 Aug 2021 14:31:00 +0100 Subject: [PATCH 08/14] Cleanup and link --- .../im/vector/app/core/di/FragmentModule.kt | 1 - .../NotificationSettingsFooterItem.kt | 2 -- .../profiles/notifications/RadioButtonItem.kt | 1 - .../profiles/notifications/TextHeaderItem.kt | 5 ++-- .../home/room/list/RoomListFragment.kt | 1 - .../actions/RoomListQuickActionViewState.kt | 24 +++++++++++++++++++ .../RoomListQuickActionsBottomSheet.kt | 8 +------ .../RoomListQuickActionsEpoxyController.kt | 22 ++++++++--------- .../RoomListQuickActionsSharedAction.kt | 3 +-- .../RoomNotificationSettingsController.kt | 16 ++++++------- .../RoomNotificationSettingsViewState.kt | 7 +++--- 11 files changed, 51 insertions(+), 39 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionViewState.kt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 991807bbef..6b42f1e428 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -723,7 +723,6 @@ interface FragmentModule { @FragmentKey(RoomNotificationSettingsFragment::class) fun bindRoomNotificationSettingsFragment(fragment: RoomNotificationSettingsFragment): Fragment - @Binds @IntoMap @FragmentKey(SearchFragment::class) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt index 540d1ff5bd..c882cf8615 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt @@ -36,8 +36,6 @@ abstract class NotificationSettingsFooterItem : VectorEpoxyModel() { diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt index 1f6cea0fd5..2dfe7be2e6 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/TextHeaderItem.kt @@ -36,8 +36,9 @@ abstract class TextHeaderItem : VectorEpoxyModel() { override fun bind(holder: Holder) { super.bind(holder) - if (textRes != null) { - holder.textView.setText(textRes!!) + val textResource = textRes + if (textResource != null) { + holder.textView.setText(textResource) } else { holder.textView.text = text } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index b053b5b825..344a4abbac 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -483,7 +483,6 @@ class RoomListFragment @Inject constructor( bottomSheet.show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS") - return true } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionViewState.kt new file mode 100644 index 0000000000..d063e07ed7 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionViewState.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.actions + +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewState + +data class RoomListQuickActionViewState( + val roomListActionsArgs: RoomListActionsArgs, + val notificationSettingsViewState: RoomNotificationSettingsViewState +) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 463e5ad94a..ccbed264e3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -34,7 +34,6 @@ import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsAction import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewEvents import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewModel -import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewState import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import javax.inject.Inject @@ -51,11 +50,6 @@ data class RoomListActionsArgs( } } -data class RoomListQuickActionViewState( - val roomListActionsArgs: RoomListActionsArgs, - val notificationSettingsViewState: RoomNotificationSettingsViewState -) - /** * Bottom sheet fragment that shows room information with list of contextual actions */ @@ -98,7 +92,7 @@ class RoomListQuickActionsBottomSheet : roomListActionsEpoxyController.listener = this viewModel.observeViewEvents { - when(it){ + when (it) { is RoomNotificationSettingsViewEvents.Failure -> listener?.handleFailure(it.throwable) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index ccfe0fdf71..b109f0466d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -43,20 +43,12 @@ class RoomListQuickActionsEpoxyController @Inject constructor( var listener: Listener? = null - @StringRes - private fun titleForNotificationState(notificationState: RoomNotificationState): Int? = when(notificationState) { - RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages - RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_and_keyword_only - RoomNotificationState.MUTE -> R.string.room_settings_none - else -> null - } - override fun buildModels(state: RoomListQuickActionViewState) { val notificationViewState = state.notificationSettingsViewState val roomSummary = notificationViewState.roomSummary() ?: return val host = this val showFull = state.roomListActionsArgs.mode == RoomListActionsArgs.Mode.FULL - var isV2 = BuildConfig.USE_NOTIFICATION_SETTINGS_V2 + val isV2 = BuildConfig.USE_NOTIFICATION_SETTINGS_V2 if (showFull || isV2) { // Preview, favorite, settings @@ -102,9 +94,15 @@ class RoomListQuickActionsEpoxyController @Inject constructor( if (showFull || isV2) { RoomListQuickActionsSharedAction.Leave(roomSummary.roomId, showIcon = !isV2).toBottomSheetItem(5) } - } + @StringRes + private fun titleForNotificationState(notificationState: RoomNotificationState): Int? = when (notificationState) { + RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages + RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_and_keyword_only + RoomNotificationState.MUTE -> R.string.room_settings_none + else -> null + } private fun RoomListQuickActionsSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) { val host = this@RoomListQuickActionsEpoxyController val selected = when (this) { @@ -117,9 +115,9 @@ class RoomListQuickActionsEpoxyController @Inject constructor( return bottomSheetActionItem { id("action_$index") selected(selected) - if(iconResId != null){ + if (iconResId != null) { iconRes(iconResId) - } else{ + } else { showIcon(false) } textRes(titleRes) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt index 20c3087f54..6f93599d02 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt @@ -21,7 +21,6 @@ import androidx.annotation.StringRes import im.vector.app.R import im.vector.app.core.platform.VectorSharedAction - sealed class RoomListQuickActionsSharedAction( @StringRes val titleRes: Int, @DrawableRes val iconResId: Int?, @@ -61,7 +60,7 @@ sealed class RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_favorite_add, R.drawable.ic_star_24dp) - data class Leave(val roomId: String, val showIcon: Boolean=true) : RoomListQuickActionsSharedAction( + data class Leave(val roomId: String, val showIcon: Boolean = true) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_leave, if (showIcon) R.drawable.ic_room_actions_leave else null, true diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt index e6c57523e5..654400e790 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt @@ -38,14 +38,6 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr setData(null) } - @StringRes - private fun titleForNotificationState(notificationState: RoomNotificationState): Int? = when(notificationState) { - RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages - RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_and_keyword_only - RoomNotificationState.MUTE -> R.string.room_settings_none - else -> null - } - override fun buildModels(data: RoomNotificationSettingsViewState?) { val host = this data ?: return @@ -73,4 +65,12 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr } } } + + @StringRes + private fun titleForNotificationState(notificationState: RoomNotificationState): Int? = when (notificationState) { + RoomNotificationState.ALL_MESSAGES_NOISY -> R.string.room_settings_all_messages + RoomNotificationState.MENTIONS_ONLY -> R.string.room_settings_mention_and_keyword_only + RoomNotificationState.MUTE -> R.string.room_settings_none + else -> null + } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index a88dc84078..30fde5ddea 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -30,13 +30,13 @@ data class RoomNotificationSettingsViewState( val roomSummary: Async = Uninitialized, val isLoading: Boolean = false, val roomEncrypted: Boolean = false, - val notificationState: Async = Uninitialized, + val notificationState: Async = Uninitialized ) : MvRxState { constructor(args: RoomProfileArgs) : this(roomId = args.roomId) constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) } -data class AvatarData ( +data class AvatarData( val displayName: String, val avatarUrl: String ) @@ -61,6 +61,7 @@ val RoomNotificationSettingsViewState.notificationOptions: List Date: Wed, 11 Aug 2021 14:36:32 +0100 Subject: [PATCH 09/14] fix line length --- .../notifications/NotificationSettingsFooterItem.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt index c882cf8615..4608f2b1ce 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/notifications/NotificationSettingsFooterItem.kt @@ -37,14 +37,18 @@ abstract class NotificationSettingsFooterItem : VectorEpoxyModel Date: Wed, 11 Aug 2021 15:00:27 +0100 Subject: [PATCH 10/14] simplify logic in bottom sheet and add comment --- vector/build.gradle | 3 --- .../list/actions/RoomListQuickActionsEpoxyController.kt | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index 311f7ed172..7c1119f9c1 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -142,15 +142,12 @@ android { resValue "bool", "useLoginV1", "true" resValue "bool", "useLoginV2", "false" - - // NotificationSettingsV2 is disabled. To be released in conjunction with iOS/Web def useNotificationSettingsV2 = false buildConfigField "Boolean", "USE_NOTIFICATION_SETTINGS_V2", "${useNotificationSettingsV2}" resValue "bool", "useNotificationSettingsV1", "${!useNotificationSettingsV2}" resValue "bool", "useNotificationSettingsV2", "${useNotificationSettingsV2}" - buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping" buildConfigField "Long", "VOICE_MESSAGE_DURATION_LIMIT_MS", "120_000L" diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt index b109f0466d..7e39156b18 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt @@ -47,10 +47,11 @@ class RoomListQuickActionsEpoxyController @Inject constructor( val notificationViewState = state.notificationSettingsViewState val roomSummary = notificationViewState.roomSummary() ?: return val host = this - val showFull = state.roomListActionsArgs.mode == RoomListActionsArgs.Mode.FULL val isV2 = BuildConfig.USE_NOTIFICATION_SETTINGS_V2 + // V2 always shows full details as we no longer display the sheet from RoomProfile > Notifications + val showFull = state.roomListActionsArgs.mode == RoomListActionsArgs.Mode.FULL || isV2 - if (showFull || isV2) { + if (showFull) { // Preview, favorite, settings bottomSheetRoomPreviewItem { id("room_preview") @@ -91,7 +92,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor( RoomListQuickActionsSharedAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState) } - if (showFull || isV2) { + if (showFull) { RoomListQuickActionsSharedAction.Leave(roomSummary.roomId, showIcon = !isV2).toBottomSheetItem(5) } } From fe800a56e21ba7330af86ada7669188fae239957 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 24 Aug 2021 12:12:39 +0100 Subject: [PATCH 11/14] Address comments. --- .../roomprofile/RoomProfileActivity.kt | 4 +-- .../roomprofile/RoomProfileFragment.kt | 2 +- .../roomprofile/RoomProfileSharedAction.kt | 2 +- .../RoomNotificationSettingsController.kt | 2 +- .../RoomNotificationSettingsFragment.kt | 11 ++++++- .../RoomNotificationSettingsViewModel.kt | 24 +++++++------- .../RoomNotificationSettingsViewState.kt | 10 ++---- .../res/layout/item_notifications_footer.xml | 30 ++++++------------ .../src/main/res/layout/item_text_header.xml | 31 ++++++------------- 9 files changed, 49 insertions(+), 67 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index d8e080f6a4..d28878283f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -113,8 +113,8 @@ class RoomProfileActivity : RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias() RoomProfileSharedAction.OpenRoomPermissionsSettings -> openRoomPermissions() RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads() - RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() - RoomProfileSharedAction.OpenRoomNotificaitonSettings -> openRoomNotificationSettings() + RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() + RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings() }.exhaustive } .disposeOnDestroy() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index ea5bbd2e84..4b37d038b5 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -255,7 +255,7 @@ class RoomProfileFragment @Inject constructor( override fun onNotificationsClicked() { if (BuildConfig.USE_NOTIFICATION_SETTINGS_V2) { - roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificaitonSettings) + roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificationSettings) } else { RoomListQuickActionsBottomSheet .newInstance(roomProfileArgs.roomId, RoomListActionsArgs.Mode.NOTIFICATIONS) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt index 6a9533a2eb..eb4ab56634 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt @@ -28,5 +28,5 @@ sealed class RoomProfileSharedAction : VectorSharedAction { object OpenRoomUploads : RoomProfileSharedAction() object OpenRoomMembers : RoomProfileSharedAction() object OpenBannedRoomMembers : RoomProfileSharedAction() - object OpenRoomNotificaitonSettings : RoomProfileSharedAction() + object OpenRoomNotificationSettings : RoomProfileSharedAction() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt index 654400e790..9a2085a7e8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsController.kt @@ -59,7 +59,7 @@ class RoomNotificationSettingsController @Inject constructor() : TypedEpoxyContr } notificationSettingsFooterItem { id("roomNotificationSettingsFooter") - encrypted(data.roomEncrypted) + encrypted(data.roomSummary()?.isEncrypted == true) clickListener { host.callback?.didSelectAccountSettingsLink() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt index 8baef5d10c..ce0fde32c6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsFragment.kt @@ -24,10 +24,12 @@ import androidx.core.view.isVisible import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R +import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.settings.VectorSettingsActivity import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject @@ -53,6 +55,13 @@ class RoomNotificationSettingsFragment @Inject constructor( setupWaitingView() observeViewEvents() } + + override fun onDestroyView() { + views.roomSettingsRecyclerView.cleanup() + roomNotificationSettingsController.callback = null + super.onDestroyView() + } + private fun setupWaitingView() { views.waitingView.waitingStatusText.setText(R.string.please_wait) views.waitingView.waitingStatusText.isVisible = true @@ -77,7 +86,7 @@ class RoomNotificationSettingsFragment @Inject constructor( } override fun didSelectAccountSettingsLink() { - navigator.openSettings(requireContext()) + navigator.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_NOTIFICATIONS) } private fun renderRoomSummary(state: RoomNotificationSettingsViewState) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index 5d23931d88..dd0535f51b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -59,17 +59,10 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( private val room = session.getRoom(initialState.roomId)!! init { - initEncrypted() observeSummary() observeNotificationState() } - private fun initEncrypted() { - setState { - copy(roomEncrypted = room.isEncrypted()) - } - } - private fun observeSummary() { room.rx().liveRoomSummary() .unwrap() @@ -96,10 +89,19 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( setState { copy(isLoading = true) } viewModelScope.launch { runCatching { room.setRoomNotificationState(action.notificationState) } - .onFailure { _viewEvents.post(RoomNotificationSettingsViewEvents.Failure(it)) } - setState { - copy(isLoading = false, notificationState = Success(action.notificationState)) - } + .fold( + { + setState { + copy(isLoading = false, notificationState = Success(action.notificationState)) + } + }, + { + setState { + copy(isLoading = false) + } + _viewEvents.post(RoomNotificationSettingsViewEvents.Failure(it)) + } + ) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index 30fde5ddea..54e2ef9550 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -29,24 +29,18 @@ data class RoomNotificationSettingsViewState( val roomId: String, val roomSummary: Async = Uninitialized, val isLoading: Boolean = false, - val roomEncrypted: Boolean = false, val notificationState: Async = Uninitialized ) : MvRxState { constructor(args: RoomProfileArgs) : this(roomId = args.roomId) constructor(args: RoomListActionsArgs) : this(roomId = args.roomId) } -data class AvatarData( - val displayName: String, - val avatarUrl: String -) - /** * Used to map this old room notification settings to the new options in v2. */ val RoomNotificationSettingsViewState.notificationStateMapped: Async get() { - if ((roomEncrypted && notificationState() == RoomNotificationState.MENTIONS_ONLY) || notificationState() == RoomNotificationState.ALL_MESSAGES) { + if ((roomSummary()?.isEncrypted == true && notificationState() == RoomNotificationState.MENTIONS_ONLY) || notificationState() == RoomNotificationState.ALL_MESSAGES) { /** if in an encrypted room, mentions notifications are not supported so show "All Messages" as selected. * Also in the new settings there is no notion of notifications without sound so it maps to noisy also */ @@ -59,7 +53,7 @@ val RoomNotificationSettingsViewState.notificationStateMapped: Async get() { - return if (roomEncrypted) { + return if (roomSummary()?.isEncrypted == true) { listOf(RoomNotificationState.ALL_MESSAGES_NOISY, RoomNotificationState.MUTE) } else { listOf(RoomNotificationState.ALL_MESSAGES_NOISY, RoomNotificationState.MENTIONS_ONLY, RoomNotificationState.MUTE) diff --git a/vector/src/main/res/layout/item_notifications_footer.xml b/vector/src/main/res/layout/item_notifications_footer.xml index 8338358048..36db166e8f 100644 --- a/vector/src/main/res/layout/item_notifications_footer.xml +++ b/vector/src/main/res/layout/item_notifications_footer.xml @@ -1,25 +1,13 @@ - - - - - \ No newline at end of file + android:paddingStart="@dimen/layout_horizontal_margin" + android:paddingTop="@dimen/layout_vertical_margin" + android:paddingEnd="@dimen/layout_horizontal_margin" + android:paddingBottom="@dimen/layout_vertical_margin" + android:textColor="?vctr_content_secondary" + tools:text="@string/room_settings_room_notifications_encryption_notice" /> diff --git a/vector/src/main/res/layout/item_text_header.xml b/vector/src/main/res/layout/item_text_header.xml index 15848f585e..3f876e5ece 100644 --- a/vector/src/main/res/layout/item_text_header.xml +++ b/vector/src/main/res/layout/item_text_header.xml @@ -1,25 +1,14 @@ - - - - - \ No newline at end of file + android:paddingStart="@dimen/layout_horizontal_margin" + android:paddingTop="@dimen/layout_vertical_margin" + android:paddingEnd="@dimen/layout_horizontal_margin" + android:paddingBottom="@dimen/layout_vertical_margin" + android:textColor="?vctr_content_secondary" + android:textStyle="bold" + tools:text="@string/room_settings_room_notifications_notify_me" /> \ No newline at end of file From cd424b0766c52eeb4b88ef64dbc61004b3f3b1a2 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 24 Aug 2021 12:17:39 +0100 Subject: [PATCH 12/14] fix checks --- .../notifications/RoomNotificationSettingsViewState.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt index 54e2ef9550..72e61fba70 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewState.kt @@ -40,7 +40,8 @@ data class RoomNotificationSettingsViewState( */ val RoomNotificationSettingsViewState.notificationStateMapped: Async get() { - if ((roomSummary()?.isEncrypted == true && notificationState() == RoomNotificationState.MENTIONS_ONLY) || notificationState() == RoomNotificationState.ALL_MESSAGES) { + if ((roomSummary()?.isEncrypted == true && notificationState() == RoomNotificationState.MENTIONS_ONLY) + || notificationState() == RoomNotificationState.ALL_MESSAGES) { /** if in an encrypted room, mentions notifications are not supported so show "All Messages" as selected. * Also in the new settings there is no notion of notifications without sound so it maps to noisy also */ From f8114dd7a1cf281f323d7c00812c6a9c680fbe80 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 24 Aug 2021 22:28:31 +0100 Subject: [PATCH 13/14] Fix HomeList error snackbar and add dialog for bottom sheet errors --- vector/build.gradle | 2 +- .../vector/app/features/home/HomeActivity.kt | 2 ++ .../home/room/list/RoomListFragment.kt | 11 ++--------- .../RoomListQuickActionsBottomSheet.kt | 19 ++++++++++++++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index 7c1119f9c1..f5731c819f 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -143,7 +143,7 @@ android { resValue "bool", "useLoginV2", "false" // NotificationSettingsV2 is disabled. To be released in conjunction with iOS/Web - def useNotificationSettingsV2 = false + def useNotificationSettingsV2 = true buildConfigField "Boolean", "USE_NOTIFICATION_SETTINGS_V2", "${useNotificationSettingsV2}" resValue "bool", "useNotificationSettingsV1", "${!useNotificationSettingsV2}" resValue "bool", "useNotificationSettingsV2", "${useNotificationSettingsV2}" diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 4a563b563a..9ae6d4c39f 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -143,6 +143,8 @@ class HomeActivity : } } + override fun getCoordinatorLayout() = views.coordinatorLayout + override fun getBinding() = ActivityHomeBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index 344a4abbac..fdfe171439 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -473,16 +473,9 @@ class RoomListFragment @Inject constructor( // refresh footer footerController.setData(it) } - val bottomSheet = RoomListQuickActionsBottomSheet + RoomListQuickActionsBottomSheet .newInstance(room.roomId, RoomListActionsArgs.Mode.FULL) - bottomSheet.listener = object : RoomListQuickActionsBottomSheet.Listener { - override fun handleFailure(throwable: Throwable) { - showFailure(throwable) - } - } - - bottomSheet.show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS") - + .show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS") return true } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index ccbed264e3..fcc9960414 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -25,10 +25,14 @@ import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import im.vector.app.R import im.vector.app.core.di.ScreenComponent +import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsAction @@ -57,20 +61,17 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { - interface Listener { - fun handleFailure(throwable: Throwable) - } private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool @Inject lateinit var roomNotificationSettingsViewModelFactory: RoomNotificationSettingsViewModel.Factory @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController @Inject lateinit var navigator: Navigator + @Inject lateinit var errorFormatter: ErrorFormatter private val roomListActionsArgs: RoomListActionsArgs by args() private val viewModel: RoomNotificationSettingsViewModel by fragmentViewModel(RoomNotificationSettingsViewModel::class) override val showExpanded = true - var listener: Listener? = null override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -93,7 +94,7 @@ class RoomListQuickActionsBottomSheet : viewModel.observeViewEvents { when (it) { - is RoomNotificationSettingsViewEvents.Failure -> listener?.handleFailure(it.throwable) + is RoomNotificationSettingsViewEvents.Failure -> displayErrorDialog(it.throwable) } } } @@ -134,4 +135,12 @@ class RoomListQuickActionsBottomSheet : } } } + + private fun displayErrorDialog(throwable: Throwable) { + MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.dialog_title_error) + .setMessage(errorFormatter.toHumanReadable(throwable)) + .setPositiveButton(R.string.ok, null) + .show() + } } From 4d4d370b8fca5333ef945cb0e15632a29e8d5528 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 24 Aug 2021 22:33:32 +0100 Subject: [PATCH 14/14] checks and remove build settings --- vector/build.gradle | 2 +- .../home/room/list/actions/RoomListQuickActionsBottomSheet.kt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index f5731c819f..7c1119f9c1 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -143,7 +143,7 @@ android { resValue "bool", "useLoginV2", "false" // NotificationSettingsV2 is disabled. To be released in conjunction with iOS/Web - def useNotificationSettingsV2 = true + def useNotificationSettingsV2 = false buildConfigField "Boolean", "USE_NOTIFICATION_SETTINGS_V2", "${useNotificationSettingsV2}" resValue "bool", "useNotificationSettingsV1", "${!useNotificationSettingsV2}" resValue "bool", "useNotificationSettingsV2", "${useNotificationSettingsV2}" diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index fcc9960414..8c1bdc086f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -32,7 +32,6 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment -import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsAction