diff --git a/CHANGES.md b/CHANGES.md index 657f553c36..91145eece4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ Changes in RiotX 0.14.0 (2020-XX-XX) =================================================== Features ✨: - - + - Enable encryption in unencrypted rooms, from the room settings (#212) Improvements 🙌: - diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt index b99268d6d4..4fdd2f1f73 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt @@ -22,32 +22,49 @@ import androidx.fragment.app.FragmentFactory import dagger.Binds import dagger.Module import dagger.multibindings.IntoMap +import im.vector.riotx.features.createdirect.CreateDirectRoomDirectoryUsersFragment +import im.vector.riotx.features.createdirect.CreateDirectRoomKnownUsersFragment import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupSettingsFragment import im.vector.riotx.features.crypto.verification.SASVerificationIncomingFragment import im.vector.riotx.features.crypto.verification.SASVerificationShortCodeFragment import im.vector.riotx.features.crypto.verification.SASVerificationStartFragment import im.vector.riotx.features.crypto.verification.SASVerificationVerifiedFragment +import im.vector.riotx.features.grouplist.GroupListFragment import im.vector.riotx.features.home.HomeDetailFragment import im.vector.riotx.features.home.HomeDrawerFragment import im.vector.riotx.features.home.LoadingFragment -import im.vector.riotx.features.createdirect.CreateDirectRoomDirectoryUsersFragment -import im.vector.riotx.features.createdirect.CreateDirectRoomKnownUsersFragment -import im.vector.riotx.features.grouplist.GroupListFragment import im.vector.riotx.features.home.room.breadcrumbs.BreadcrumbsFragment import im.vector.riotx.features.home.room.detail.RoomDetailFragment import im.vector.riotx.features.home.room.list.RoomListFragment -import im.vector.riotx.features.login.* +import im.vector.riotx.features.login.LoginCaptchaFragment +import im.vector.riotx.features.login.LoginFragment +import im.vector.riotx.features.login.LoginGenericTextInputFormFragment +import im.vector.riotx.features.login.LoginResetPasswordFragment +import im.vector.riotx.features.login.LoginResetPasswordMailConfirmationFragment +import im.vector.riotx.features.login.LoginResetPasswordSuccessFragment +import im.vector.riotx.features.login.LoginServerSelectionFragment +import im.vector.riotx.features.login.LoginServerUrlFormFragment +import im.vector.riotx.features.login.LoginSignUpSignInSelectionFragment +import im.vector.riotx.features.login.LoginSplashFragment +import im.vector.riotx.features.login.LoginWaitForEmailFragment +import im.vector.riotx.features.login.LoginWebFragment import im.vector.riotx.features.login.terms.LoginTermsFragment -import im.vector.riotx.features.roommemberprofile.RoomMemberProfileFragment import im.vector.riotx.features.reactions.EmojiChooserFragment import im.vector.riotx.features.reactions.EmojiSearchResultFragment import im.vector.riotx.features.roomdirectory.PublicRoomsFragment import im.vector.riotx.features.roomdirectory.createroom.CreateRoomFragment import im.vector.riotx.features.roomdirectory.picker.RoomDirectoryPickerFragment import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment +import im.vector.riotx.features.roommemberprofile.RoomMemberProfileFragment import im.vector.riotx.features.roomprofile.RoomProfileFragment import im.vector.riotx.features.roomprofile.members.RoomMemberListFragment -import im.vector.riotx.features.settings.* +import im.vector.riotx.features.roomprofile.settings.RoomSettingsFragment +import im.vector.riotx.features.settings.VectorSettingsAdvancedNotificationPreferenceFragment +import im.vector.riotx.features.settings.VectorSettingsHelpAboutFragment +import im.vector.riotx.features.settings.VectorSettingsNotificationPreferenceFragment +import im.vector.riotx.features.settings.VectorSettingsNotificationsTroubleshootFragment +import im.vector.riotx.features.settings.VectorSettingsPreferencesFragment +import im.vector.riotx.features.settings.VectorSettingsSecurityPrivacyFragment import im.vector.riotx.features.settings.devices.VectorSettingsDevicesFragment import im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment import im.vector.riotx.features.settings.push.PushGatewaysFragment @@ -272,6 +289,11 @@ interface FragmentModule { @FragmentKey(RoomMemberListFragment::class) fun bindRoomMemberListFragment(fragment: RoomMemberListFragment): Fragment + @Binds + @IntoMap + @FragmentKey(RoomSettingsFragment::class) + fun bindRoomSettingsFragment(fragment: RoomSettingsFragment): Fragment + @Binds @IntoMap @FragmentKey(RoomMemberProfileFragment::class) diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt index 91c166a96c..65b78a4eaa 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseFragment.kt @@ -22,10 +22,15 @@ import android.app.ProgressDialog import android.content.Context import android.os.Bundle import android.os.Parcelable -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.View +import android.view.ViewGroup import androidx.annotation.CallSuper import androidx.annotation.LayoutRes import androidx.annotation.MainThread +import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.Toolbar import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders @@ -35,6 +40,7 @@ import com.airbnb.mvrx.BaseMvRxFragment import com.airbnb.mvrx.MvRx import com.bumptech.glide.util.Util.assertMainThread import com.google.android.material.snackbar.Snackbar +import im.vector.riotx.R import im.vector.riotx.core.di.DaggerScreenComponent import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.di.ScreenComponent @@ -233,4 +239,16 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { inflater.inflate(menuRes, menu) } } + + /* ========================================================================================== + * Common Dialogs + * ========================================================================================== */ + + protected fun displayErrorDialog(throwable: Throwable) { + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.dialog_title_error) + .setMessage(errorFormatter.toHumanReadable(throwable)) + .setPositiveButton(R.string.ok, null) + .show() + } } diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/RoomProfileActivity.kt index 160d2341ed..1a9b268b90 100644 --- a/vector/src/main/java/im/vector/riotx/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/RoomProfileActivity.kt @@ -26,6 +26,7 @@ import im.vector.riotx.core.extensions.addFragmentToBackstack import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.roomprofile.members.RoomMemberListFragment +import im.vector.riotx.features.roomprofile.settings.RoomSettingsFragment class RoomProfileActivity : VectorBaseActivity(), ToolbarConfigurable { @@ -69,7 +70,7 @@ class RoomProfileActivity : VectorBaseActivity(), ToolbarConfigurable { } private fun openRoomSettings() { - notImplemented("Open room settings") + addFragmentToBackstack(R.id.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs) } private fun openRoomMembers() { diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsAction.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsAction.kt new file mode 100644 index 0000000000..3c1b10cf8e --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsAction.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.roomprofile.settings + +import im.vector.riotx.core.platform.VectorViewModelAction + +sealed class RoomSettingsAction : VectorViewModelAction { + data class SetRoomName(val newName: String) : RoomSettingsAction() + data class SetRoomTopic(val newTopic: String) : RoomSettingsAction() + data class SetRoomAvatar(val newAvatarUrl: String) : RoomSettingsAction() + object EnableEncryption : RoomSettingsAction() +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsController.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsController.kt new file mode 100644 index 0000000000..b9a20ef915 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsController.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.roomprofile.settings + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.profiles.buildProfileAction +import im.vector.riotx.core.epoxy.profiles.buildProfileSection +import im.vector.riotx.core.resources.ColorProvider +import im.vector.riotx.core.resources.StringProvider +import javax.inject.Inject + +// TODO Add other feature here (waiting for design) +class RoomSettingsController @Inject constructor( + private val stringProvider: StringProvider, + colorProvider: ColorProvider +) : TypedEpoxyController() { + + interface Callback { + fun onEnableEncryptionClicked() + } + + private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color) + + var callback: Callback? = null + + init { + setData(null) + } + + override fun buildModels(data: RoomSettingsViewState?) { + val roomSummary = data?.roomSummary?.invoke() ?: return + + buildProfileSection( + stringProvider.getString(R.string.settings) + ) + + // Only enable encryption for the moment + if (roomSummary.isEncrypted) { + buildProfileAction( + id = "encryption", + title = stringProvider.getString(R.string.room_settings_addresses_e2e_enabled), + dividerColor = dividerColor, + divider = false, + editable = false, + action = {} + ) + } else { + buildProfileAction( + id = "encryption", + title = stringProvider.getString(R.string.room_settings_enable_encryption), + subtitle = stringProvider.getString(R.string.room_settings_enable_encryption_warning), + dividerColor = dividerColor, + divider = false, + editable = true, + action = { callback?.onEnableEncryptionClicked() } + ) + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsFragment.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsFragment.kt new file mode 100644 index 0000000000..e7a221d40d --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsFragment.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.roomprofile.settings + +import android.os.Bundle +import android.view.View +import androidx.core.view.isVisible +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.args +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.matrix.android.api.util.toMatrixItem +import im.vector.riotx.R +import im.vector.riotx.core.extensions.cleanup +import im.vector.riotx.core.extensions.configureWith +import im.vector.riotx.core.extensions.observeEvent +import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.home.AvatarRenderer +import im.vector.riotx.features.roomprofile.RoomProfileArgs +import kotlinx.android.synthetic.main.fragment_room_member_list.* +import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import javax.inject.Inject + +class RoomSettingsFragment @Inject constructor( + val viewModelFactory: RoomSettingsViewModel.Factory, + private val controller: RoomSettingsController, + private val avatarRenderer: AvatarRenderer +) : VectorBaseFragment(), RoomSettingsController.Callback { + + private val viewModel: RoomSettingsViewModel by fragmentViewModel() + private val roomProfileArgs: RoomProfileArgs by args() + + override fun getLayoutResId() = R.layout.fragment_room_member_list + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + controller.callback = this + setupToolbar(roomMemberListToolbar) + recyclerView.configureWith(controller, hasFixedSize = true) + waiting_view_status_text.setText(R.string.please_wait) + waiting_view_status_text.isVisible = true + + viewModel.requestErrorLiveData.observeEvent(this) { + displayErrorDialog(it) + } + } + + override fun onDestroyView() { + recyclerView.cleanup() + super.onDestroyView() + } + + override fun invalidate() = withState(viewModel) { viewState -> + controller.setData(viewState) + renderRoomSummary(viewState) + } + + override fun onEnableEncryptionClicked() { + viewModel.handle(RoomSettingsAction.EnableEncryption) + } + + private fun renderRoomSummary(state: RoomSettingsViewState) { + waiting_view.isVisible = state.currentRequest is Loading + + state.roomSummary()?.let { + roomMemberListToolbarTitleView.text = it.displayName + avatarRenderer.render(it.toMatrixItem(), roomMemberListToolbarAvatarImageView) + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsViewModel.kt new file mode 100644 index 0000000000..fad8504e01 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsViewModel.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.roomprofile.settings + +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.Uninitialized +import com.airbnb.mvrx.ViewModelContext +import com.squareup.inject.assisted.Assisted +import com.squareup.inject.assisted.AssistedInject +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.Session +import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import im.vector.matrix.rx.rx +import im.vector.matrix.rx.unwrap +import im.vector.riotx.core.extensions.postLiveEvent +import im.vector.riotx.core.platform.VectorViewModel + +class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState, + private val session: Session) + : VectorViewModel(initialState) { + + @AssistedInject.Factory + interface Factory { + fun create(initialState: RoomSettingsViewState): RoomSettingsViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: RoomSettingsViewState): RoomSettingsViewModel? { + val fragment: RoomSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() + return fragment.viewModelFactory.create(state) + } + } + + private val room = session.getRoom(initialState.roomId)!! + + init { + observeRoomSummary() + } + + private fun observeRoomSummary() { + room.rx().liveRoomSummary() + .unwrap() + .execute { async -> + copy(roomSummary = async) + } + } + + override fun handle(action: RoomSettingsAction) { + when (action) { + is RoomSettingsAction.EnableEncryption -> handleEnableEncryption() + } + } + + private fun handleEnableEncryption() { + setState { + copy(currentRequest = Loading()) + } + + room.enableEncryption(MXCRYPTO_ALGORITHM_MEGOLM, object : MatrixCallback { + override fun onFailure(failure: Throwable) { + setState { + copy(currentRequest = Uninitialized) + } + + _requestErrorLiveData.postLiveEvent(failure) + } + + override fun onSuccess(data: Unit) { + setState { + copy(currentRequest = Uninitialized) + } + } + }) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsViewState.kt b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsViewState.kt new file mode 100644 index 0000000000..b3be2e308e --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/roomprofile/settings/RoomSettingsViewState.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.roomprofile.settings + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized +import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.riotx.features.roomprofile.RoomProfileArgs + +data class RoomSettingsViewState( + val roomId: String, + val roomSummary: Async = Uninitialized, + val currentRequest: Async = Uninitialized +) : MvRxState { + + constructor(args: RoomProfileArgs) : this(roomId = args.roomId) +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt index 465b3ba0fb..8de7c7a322 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -83,14 +83,6 @@ class VectorSettingsDevicesFragment @Inject constructor( (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_devices_list) } - private fun displayErrorDialog(throwable: Throwable) { - AlertDialog.Builder(requireActivity()) - .setTitle(R.string.dialog_title_error) - .setMessage(errorFormatter.toHumanReadable(throwable)) - .setPositiveButton(R.string.ok, null) - .show() - } - override fun onDeviceClicked(deviceInfo: DeviceInfo) { devicesViewModel.handle(DevicesAction.ToggleDevice(deviceInfo)) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index 6435f43d87..d7069ce9f9 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -77,14 +77,6 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( .show() } - private fun displayErrorDialog(throwable: Throwable) { - AlertDialog.Builder(requireActivity()) - .setTitle(R.string.dialog_title_error) - .setMessage(errorFormatter.toHumanReadable(throwable)) - .setPositiveButton(R.string.ok, null) - .show() - } - // ============================================================================================================== // ignored users list management // ============================================================================================================== diff --git a/vector/src/main/res/layout/fragment_room_member_list.xml b/vector/src/main/res/layout/fragment_room_member_list.xml index 5fe4fc3770..06b4293e78 100644 --- a/vector/src/main/res/layout/fragment_room_member_list.xml +++ b/vector/src/main/res/layout/fragment_room_member_list.xml @@ -4,14 +4,15 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/rootConstraintLayout" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:background="?riotx_header_panel_background"> @@ -42,9 +43,9 @@ android:maxLines="1" android:textColor="?vctr_toolbar_primary_text_color" android:textSize="18sp" - app:layout_constraintStart_toEndOf="@+id/roomMemberListToolbarAvatarImageView" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/roomMemberListToolbarAvatarImageView" app:layout_constraintTop_toTopOf="parent" tools:text="@sample/matrix.json/data/roomName" /> @@ -57,10 +58,12 @@ android:layout_width="0dp" android:layout_height="0dp" android:overScrollMode="always" - app:layout_constraintTop_toBottomOf="@+id/roomMemberListToolbar" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toBottomOf="@+id/roomMemberListToolbar" tools:listitem="@layout/item_autocomplete_matrix_item" /> + + diff --git a/vector/src/main/res/layout/merge_overlay_waiting_view.xml b/vector/src/main/res/layout/merge_overlay_waiting_view.xml index b7e7bf41c7..3ee572cd71 100644 --- a/vector/src/main/res/layout/merge_overlay_waiting_view.xml +++ b/vector/src/main/res/layout/merge_overlay_waiting_view.xml @@ -10,6 +10,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="?vctr_waiting_background_color" + android:clickable="true" + android:focusable="true" android:visibility="gone" tools:visibility="visible"> diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 7fff839e7e..453235e0ce 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -40,5 +40,7 @@ Message editor + Enable end-to-end encryption + Warning: once encryption is enabled in a room, it cannot be disabled