Move "Enable Encryption" from room setting screen to room profile screen (#2394)
This commit is contained in:
parent
0022777a4f
commit
75c105a400
|
@ -8,6 +8,7 @@ Improvements 🙌:
|
|||
- Open an existing DM instead of creating a new one (#2319)
|
||||
- Ask for explicit user consent to send their contact details to the identity server (#2375)
|
||||
- Handle events of type "m.room.server_acl" (#890)
|
||||
- Move "Enable Encryption" from room setting screen to room profile screen (#2394)
|
||||
|
||||
Bugfix 🐛:
|
||||
- Fix issue when restoring draft after sharing (#2287)
|
||||
|
|
|
@ -21,6 +21,7 @@ import im.vector.app.core.platform.VectorViewModelAction
|
|||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||
|
||||
sealed class RoomProfileAction : VectorViewModelAction {
|
||||
object EnableEncryption : RoomProfileAction()
|
||||
object LeaveRoom : RoomProfileAction()
|
||||
data class ChangeRoomNotificationState(val notificationState: RoomNotificationState) : RoomProfileAction()
|
||||
object ShareRoomProfile : RoomProfileAction()
|
||||
|
|
|
@ -28,6 +28,7 @@ import im.vector.app.core.ui.list.genericFooterItem
|
|||
import im.vector.app.features.home.ShortcutCreator
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomProfileController @Inject constructor(
|
||||
|
@ -43,6 +44,7 @@ class RoomProfileController @Inject constructor(
|
|||
|
||||
interface Callback {
|
||||
fun onLearnMoreClicked()
|
||||
fun onEnableEncryptionClicked()
|
||||
fun onMemberListClicked()
|
||||
fun onBannedMemberListClicked()
|
||||
fun onNotificationsClicked()
|
||||
|
@ -84,6 +86,7 @@ class RoomProfileController @Inject constructor(
|
|||
centered(false)
|
||||
text(stringProvider.getString(learnMoreSubtitle))
|
||||
}
|
||||
buildEncryptionAction(data.actionPermissions, roomSummary)
|
||||
|
||||
// More
|
||||
buildProfileSection(stringProvider.getString(R.string.room_profile_section_more))
|
||||
|
@ -171,4 +174,29 @@ class RoomProfileController @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildEncryptionAction(actionPermissions: RoomProfileViewState.ActionPermissions, roomSummary: RoomSummary) {
|
||||
if (!roomSummary.isEncrypted) {
|
||||
if (actionPermissions.canEnableEncryption) {
|
||||
buildProfileAction(
|
||||
id = "enableEncryption",
|
||||
title = stringProvider.getString(R.string.room_settings_enable_encryption),
|
||||
dividerColor = dividerColor,
|
||||
icon = R.drawable.ic_shield_black,
|
||||
divider = false,
|
||||
editable = false,
|
||||
action = { callback?.onEnableEncryptionClicked() }
|
||||
)
|
||||
} else {
|
||||
buildProfileAction(
|
||||
id = "enableEncryption",
|
||||
title = stringProvider.getString(R.string.room_settings_enable_encryption_no_permission),
|
||||
dividerColor = dividerColor,
|
||||
icon = R.drawable.ic_shield_black,
|
||||
divider = false,
|
||||
editable = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
|
|||
import im.vector.app.features.media.BigImageViewerActivity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_matrix_profile.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import kotlinx.android.synthetic.main.view_stub_room_profile_header.*
|
||||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
|
@ -87,6 +88,7 @@ class RoomProfileFragment @Inject constructor(
|
|||
it.layoutResource = R.layout.view_stub_room_profile_header
|
||||
it.inflate()
|
||||
}
|
||||
setupWaitingView()
|
||||
setupToolbar(matrixProfileToolbar)
|
||||
setupRecyclerView()
|
||||
appBarStateChangeListener = MatrixItemAppBarStateChangeListener(
|
||||
|
@ -111,6 +113,11 @@ class RoomProfileFragment @Inject constructor(
|
|||
setupLongClicks()
|
||||
}
|
||||
|
||||
private fun setupWaitingView() {
|
||||
waiting_view_status_text.setText(R.string.please_wait)
|
||||
waiting_view_status_text.isVisible = true
|
||||
}
|
||||
|
||||
private fun setupLongClicks() {
|
||||
roomProfileNameView.copyOnLongClick()
|
||||
roomProfileAliasView.copyOnLongClick()
|
||||
|
@ -155,6 +162,8 @@ class RoomProfileFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun invalidate() = withState(roomProfileViewModel) { state ->
|
||||
waiting_view.isVisible = state.isLoading
|
||||
|
||||
state.roomSummary()?.also {
|
||||
if (it.membership.isLeft()) {
|
||||
Timber.w("The room has been left")
|
||||
|
@ -187,6 +196,17 @@ class RoomProfileFragment @Inject constructor(
|
|||
vectorBaseActivity.notImplemented()
|
||||
}
|
||||
|
||||
override fun onEnableEncryptionClicked() {
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setTitle(R.string.room_settings_enable_encryption_dialog_title)
|
||||
.setMessage(R.string.room_settings_enable_encryption_dialog_content)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.room_settings_enable_encryption_dialog_submit) { _, _ ->
|
||||
roomProfileViewModel.handle(RoomProfileAction.EnableEncryption)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onMemberListClicked() {
|
||||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomMembers)
|
||||
}
|
||||
|
|
|
@ -28,12 +28,15 @@ import im.vector.app.core.extensions.exhaustive
|
|||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.home.ShortcutCreator
|
||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.rx.RxRoom
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import org.matrix.android.sdk.rx.unwrap
|
||||
|
@ -65,6 +68,7 @@ class RoomProfileViewModel @AssistedInject constructor(
|
|||
val rxRoom = room.rx()
|
||||
observeRoomSummary(rxRoom)
|
||||
observeBannedRoomMembers(rxRoom)
|
||||
observePermissions()
|
||||
}
|
||||
|
||||
private fun observeRoomSummary(rxRoom: RxRoom) {
|
||||
|
@ -82,8 +86,22 @@ class RoomProfileViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun observePermissions() {
|
||||
PowerLevelsObservableFactory(room)
|
||||
.createObservable()
|
||||
.subscribe {
|
||||
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||
val permissions = RoomProfileViewState.ActionPermissions(
|
||||
canEnableEncryption = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
|
||||
)
|
||||
setState { copy(actionPermissions = permissions) }
|
||||
}
|
||||
.disposeOnClear()
|
||||
}
|
||||
|
||||
override fun handle(action: RoomProfileAction) {
|
||||
when (action) {
|
||||
is RoomProfileAction.EnableEncryption -> handleEnableEncryption()
|
||||
RoomProfileAction.LeaveRoom -> handleLeaveRoom()
|
||||
is RoomProfileAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
|
||||
is RoomProfileAction.ShareRoomProfile -> handleShareRoomProfile()
|
||||
|
@ -91,6 +109,24 @@ class RoomProfileViewModel @AssistedInject constructor(
|
|||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun handleEnableEncryption() {
|
||||
postLoading(true)
|
||||
|
||||
viewModelScope.launch {
|
||||
val result = runCatching { room.enableEncryption() }
|
||||
postLoading(false)
|
||||
result.onFailure { failure ->
|
||||
_viewEvents.post(RoomProfileViewEvents.Failure(failure))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun postLoading(isLoading: Boolean) {
|
||||
setState {
|
||||
copy(isLoading = isLoading)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleCreateShortcut() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
withState { state ->
|
||||
|
|
|
@ -26,8 +26,14 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
|||
data class RoomProfileViewState(
|
||||
val roomId: String,
|
||||
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val bannedMembership: Async<List<RoomMemberSummary>> = Uninitialized
|
||||
val bannedMembership: Async<List<RoomMemberSummary>> = Uninitialized,
|
||||
val actionPermissions: ActionPermissions = ActionPermissions(),
|
||||
val isLoading: Boolean = false
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||
|
||||
data class ActionPermissions(
|
||||
val canEnableEncryption: Boolean = false
|
||||
)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ sealed class RoomSettingsAction : VectorViewModelAction {
|
|||
data class SetRoomTopic(val newTopic: String) : RoomSettingsAction()
|
||||
data class SetRoomHistoryVisibility(val visibility: RoomHistoryVisibility) : RoomSettingsAction()
|
||||
data class SetRoomCanonicalAlias(val newCanonicalAlias: String) : RoomSettingsAction()
|
||||
object EnableEncryption : RoomSettingsAction()
|
||||
object Save : RoomSettingsAction()
|
||||
object Cancel : RoomSettingsAction()
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import im.vector.app.features.home.room.detail.timeline.format.RoomHistoryVisibi
|
|||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -44,7 +43,6 @@ class RoomSettingsController @Inject constructor(
|
|||
// Delete the avatar, or cancel an avatar change
|
||||
fun onAvatarDelete()
|
||||
fun onAvatarChange()
|
||||
fun onEnableEncryptionClicked()
|
||||
fun onNameChanged(name: String)
|
||||
fun onTopicChanged(topic: String)
|
||||
fun onHistoryVisibilityClicked()
|
||||
|
@ -130,33 +128,6 @@ class RoomSettingsController @Inject constructor(
|
|||
editable = data.actionPermissions.canChangeHistoryReadability,
|
||||
action = { if (data.actionPermissions.canChangeHistoryReadability) callback?.onHistoryVisibilityClicked() }
|
||||
)
|
||||
|
||||
buildEncryptionAction(data.actionPermissions, roomSummary)
|
||||
}
|
||||
|
||||
private fun buildEncryptionAction(actionPermissions: RoomSettingsViewState.ActionPermissions, roomSummary: RoomSummary) {
|
||||
if (!actionPermissions.canEnableEncryption) {
|
||||
return
|
||||
}
|
||||
if (roomSummary.isEncrypted) {
|
||||
buildProfileAction(
|
||||
id = "encryption",
|
||||
title = stringProvider.getString(R.string.room_settings_addresses_e2e_enabled),
|
||||
dividerColor = dividerColor,
|
||||
divider = false,
|
||||
editable = false
|
||||
)
|
||||
} 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() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatRoomHistoryVisibilityEvent(event: Event): String? {
|
||||
|
|
|
@ -127,17 +127,6 @@ class RoomSettingsFragment @Inject constructor(
|
|||
invalidateOptionsMenu()
|
||||
}
|
||||
|
||||
override fun onEnableEncryptionClicked() {
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setTitle(R.string.room_settings_enable_encryption_dialog_title)
|
||||
.setMessage(R.string.room_settings_enable_encryption_dialog_content)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.room_settings_enable_encryption_dialog_submit) { _, _ ->
|
||||
viewModel.handle(RoomSettingsAction.EnableEncryption)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onNameChanged(name: String) {
|
||||
viewModel.handle(RoomSettingsAction.SetRoomName(name))
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package im.vector.app.features.roomprofile.settings
|
||||
|
||||
import androidx.core.net.toFile
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
|
@ -28,7 +27,6 @@ import im.vector.app.core.platform.VectorViewModel
|
|||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Observable
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
|
@ -118,8 +116,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
|||
canChangeCanonicalAlias = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
|
||||
EventType.STATE_ROOM_CANONICAL_ALIAS),
|
||||
canChangeHistoryReadability = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true,
|
||||
EventType.STATE_ROOM_HISTORY_VISIBILITY),
|
||||
canEnableEncryption = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_ENCRYPTION)
|
||||
EventType.STATE_ROOM_HISTORY_VISIBILITY)
|
||||
)
|
||||
setState { copy(actionPermissions = permissions) }
|
||||
}
|
||||
|
@ -142,7 +139,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
|||
|
||||
override fun handle(action: RoomSettingsAction) {
|
||||
when (action) {
|
||||
is RoomSettingsAction.EnableEncryption -> handleEnableEncryption()
|
||||
is RoomSettingsAction.SetAvatarAction -> handleSetAvatarAction(action)
|
||||
is RoomSettingsAction.SetRoomName -> setState { copy(newName = action.newName) }
|
||||
is RoomSettingsAction.SetRoomTopic -> setState { copy(newTopic = action.newTopic) }
|
||||
|
@ -226,18 +222,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
|
|||
)
|
||||
}
|
||||
|
||||
private fun handleEnableEncryption() {
|
||||
postLoading(true)
|
||||
|
||||
viewModelScope.launch {
|
||||
val result = runCatching { room.enableEncryption() }
|
||||
postLoading(false)
|
||||
result.onFailure { failure ->
|
||||
_viewEvents.post(RoomSettingsViewEvents.Failure(failure))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun postLoading(isLoading: Boolean) {
|
||||
setState {
|
||||
copy(isLoading = isLoading)
|
||||
|
|
|
@ -47,8 +47,7 @@ data class RoomSettingsViewState(
|
|||
val canChangeName: Boolean = false,
|
||||
val canChangeTopic: Boolean = false,
|
||||
val canChangeCanonicalAlias: Boolean = false,
|
||||
val canChangeHistoryReadability: Boolean = false,
|
||||
val canEnableEncryption: Boolean = false
|
||||
val canChangeHistoryReadability: Boolean = false
|
||||
)
|
||||
|
||||
sealed class AvatarAction {
|
||||
|
|
|
@ -95,7 +95,6 @@
|
|||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -105,4 +104,6 @@
|
|||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:listitem="@layout/item_profile_action" />
|
||||
|
||||
<include layout="@layout/merge_overlay_waiting_view" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -2200,7 +2200,8 @@
|
|||
<!-- Title for category in the settings which affect the behavior of the message editor (ex: enable Markdown, send typing notification, etc.) -->
|
||||
<string name="settings_category_composer">Message editor</string>
|
||||
|
||||
<string name="room_settings_enable_encryption">Enable end-to-end encryption</string>
|
||||
<string name="room_settings_enable_encryption">Enable end-to-end encryption…</string>
|
||||
<string name="room_settings_enable_encryption_no_permission">You don\'t have permission to enable encryption in this room.</string>
|
||||
<string name="room_settings_enable_encryption_warning">Once enabled, encryption cannot be disabled.</string>
|
||||
|
||||
<string name="room_settings_enable_encryption_dialog_title">Enable encryption?</string>
|
||||
|
|
Loading…
Reference in New Issue