From 3a9b80127f807e263e5143b03fe60ad0cd70d9bb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Jan 2021 11:46:59 +0100 Subject: [PATCH] Warn user when he is leaving a not public room (#1460) --- CHANGES.md | 3 +- .../room/state/StateServiceExtension.kt | 33 +++++++++++++++++ .../home/room/list/RoomListFragment.kt | 36 ++++++++++++++----- .../home/room/list/RoomListViewModel.kt | 5 +++ .../roomprofile/RoomProfileFragment.kt | 17 ++++++++- .../roomprofile/RoomProfileViewModel.kt | 5 +++ vector/src/main/res/values/strings.xml | 1 + 7 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt diff --git a/CHANGES.md b/CHANGES.md index 7d4678fe40..0ddd9572ea 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,8 @@ Features ✨: - Enable url previews for notices (#2562) Improvements 🙌: - - Add System theme option and set as default (#904) (#2387) + - Add System theme option and set as default (#904, #2387) + - Warn user when he is leaving a not public room (#1460) Bugfix 🐛: - Unspecced msgType field in m.sticker (#2580) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt new file mode 100644 index 0000000000..c625a7f088 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateServiceExtension.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.api.session.room.state + +import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.RoomJoinRules +import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent + +/** + * Return true if a room can be joined by anyone (RoomJoinRules.PUBLIC) + */ +fun StateService.isPublic(): Boolean { + return getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition) + ?.content + ?.toModel() + ?.joinRules == RoomJoinRules.PUBLIC +} 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 02a277f377..30cb360a9d 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 @@ -16,6 +16,7 @@ package im.vector.app.features.home.room.list +import android.content.DialogInterface import android.os.Bundle import android.os.Parcelable import android.view.LayoutInflater @@ -36,6 +37,7 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R +import im.vector.app.core.dialogs.withColoredButton import im.vector.app.core.epoxy.LayoutManagerStateRestorer import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.exhaustive @@ -246,19 +248,35 @@ class RoomListFragment @Inject constructor( roomListViewModel.handle(RoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_LOW_PRIORITY)) } is RoomListQuickActionsSharedAction.Leave -> { - AlertDialog.Builder(requireContext()) - .setTitle(R.string.room_participants_leave_prompt_title) - .setMessage(R.string.room_participants_leave_prompt_msg) - .setPositiveButton(R.string.leave) { _, _ -> - roomListViewModel.handle(RoomListAction.LeaveRoom(quickAction.roomId)) - } - .setNegativeButton(R.string.cancel, null) - .show() - Unit + promptLeaveRoom(quickAction.roomId) } }.exhaustive } + private fun promptLeaveRoom(roomId: String) { + val isPublicRoom = roomListViewModel.isPublicRoom(roomId) + val message = buildString { + append(getString(R.string.room_participants_leave_prompt_msg)) + if (!isPublicRoom) { + append("\n\n") + append(getString(R.string.room_participants_leave_private_warning)) + } + } + AlertDialog.Builder(requireContext()) + .setTitle(R.string.room_participants_leave_prompt_title) + .setMessage(message) + .setPositiveButton(R.string.leave) { _, _ -> + roomListViewModel.handle(RoomListAction.LeaveRoom(roomId)) + } + .setNegativeButton(R.string.cancel, null) + .show() + .apply { + if (!isPublicRoom) { + withColoredButton(DialogInterface.BUTTON_POSITIVE) + } + } + } + override fun invalidate() = withState(roomListViewModel) { state -> when (state.asyncFilteredRooms) { is Incomplete -> renderLoading() diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 84652506cd..6e5081a31c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.tag.RoomTag +import org.matrix.android.sdk.api.session.room.state.isPublic import org.matrix.android.sdk.rx.rx import timber.log.Timber import java.lang.Exception @@ -78,6 +79,10 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, }.exhaustive } + fun isPublicRoom(roomId: String): Boolean { + return session.getRoom(roomId)?.isPublic().orFalse() + } + // PRIVATE METHODS ***************************************************************************** private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState { 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 473c1d4324..53c5b25d6d 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 @@ -17,6 +17,7 @@ package im.vector.app.features.roomprofile +import android.content.DialogInterface import android.os.Bundle import android.os.Parcelable import android.view.LayoutInflater @@ -34,6 +35,7 @@ import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.animations.AppBarStateChangeListener import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener +import im.vector.app.core.dialogs.withColoredButton import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.copyOnLongClick @@ -247,14 +249,27 @@ class RoomProfileFragment @Inject constructor( } override fun onLeaveRoomClicked() { + val isPublicRoom = roomProfileViewModel.isPublicRoom() + val message = buildString { + append(getString(R.string.room_participants_leave_prompt_msg)) + if (!isPublicRoom) { + append("\n\n") + append(getString(R.string.room_participants_leave_private_warning)) + } + } AlertDialog.Builder(requireContext()) .setTitle(R.string.room_participants_leave_prompt_title) - .setMessage(R.string.room_participants_leave_prompt_msg) + .setMessage(message) .setPositiveButton(R.string.leave) { _, _ -> roomProfileViewModel.handle(RoomProfileAction.LeaveRoom) } .setNegativeButton(R.string.cancel, null) .show() + .apply { + if (!isPublicRoom) { + withColoredButton(DialogInterface.BUTTON_POSITIVE) + } + } } override fun onRoomIdClicked() { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index ec772ffcaa..cfdf1d9c0b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -37,6 +37,7 @@ 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.api.session.room.state.isPublic import org.matrix.android.sdk.rx.RxRoom import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.unwrap @@ -109,6 +110,10 @@ class RoomProfileViewModel @AssistedInject constructor( }.exhaustive } + fun isPublicRoom(): Boolean { + return room.isPublic() + } + private fun handleEnableEncryption() { postLoading(true) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 355ac4d6d6..4504febd1a 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -491,6 +491,7 @@ Leave room Are you sure you want to leave the room? + This room is not public. You will not be able to rejoin without an invite. Are you sure you want to remove %s from this chat? Create