mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 18:05:36 +03:00
Edit room permissions (#2471)
This commit is contained in:
parent
22c10f5ada
commit
c4a019f0d3
16 changed files with 654 additions and 9 deletions
|
@ -3,6 +3,7 @@ Changes in Element 1.0.14 (2020-XX-XX)
|
|||
|
||||
Features ✨:
|
||||
- Enable url previews for notices (#2562)
|
||||
- Edit room permissions (#2471)
|
||||
|
||||
Improvements 🙌:
|
||||
- Add System theme option and set as default (#904) (#2387)
|
||||
|
|
|
@ -84,6 +84,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.permissions.RoomPermissionsFragment
|
||||
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
|
||||
import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment
|
||||
import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment
|
||||
|
@ -364,6 +365,11 @@ interface FragmentModule {
|
|||
@FragmentKey(RoomAliasFragment::class)
|
||||
fun bindRoomAliasFragment(fragment: RoomAliasFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomPermissionsFragment::class)
|
||||
fun bindRoomPermissionsFragment(fragment: RoomPermissionsFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomMemberProfileFragment::class)
|
||||
|
|
|
@ -324,7 +324,7 @@ class RoomMemberProfileFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onEditPowerLevel(currentRole: Role) {
|
||||
EditPowerLevelDialogs.showChoice(requireActivity(), currentRole) { newPowerLevel ->
|
||||
EditPowerLevelDialogs.showChoice(requireActivity(), R.string.power_level_edit_title, currentRole) { newPowerLevel ->
|
||||
viewModel.handle(RoomMemberProfileAction.SetPowerLevel(currentRole.value, newPowerLevel, true))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.roommemberprofile.powerlevel
|
|||
import android.app.Activity
|
||||
import android.content.DialogInterface
|
||||
import android.view.KeyEvent
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
|
@ -29,7 +30,10 @@ import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
|||
|
||||
object EditPowerLevelDialogs {
|
||||
|
||||
fun showChoice(activity: Activity, currentRole: Role, listener: (Int) -> Unit) {
|
||||
fun showChoice(activity: Activity,
|
||||
@StringRes titleRes: Int,
|
||||
currentRole: Role,
|
||||
listener: (Int) -> Unit) {
|
||||
val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_edit_power_level, null)
|
||||
val views = DialogEditPowerLevelBinding.bind(dialogLayout)
|
||||
views.powerLevelRadioGroup.setOnCheckedChangeListener { _, checkedId ->
|
||||
|
@ -45,7 +49,7 @@ object EditPowerLevelDialogs {
|
|||
}
|
||||
|
||||
AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.power_level_edit_title)
|
||||
.setTitle(titleRes)
|
||||
.setView(dialogLayout)
|
||||
.setPositiveButton(R.string.edit) { _, _ ->
|
||||
val newValue = when (views.powerLevelRadioGroup.checkedRadioButtonId) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.extensions.addFragmentToBackstack
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
|
@ -38,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.permissions.RoomPermissionsFragment
|
||||
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -102,12 +104,13 @@ class RoomProfileActivity :
|
|||
.observe()
|
||||
.subscribe { sharedAction ->
|
||||
when (sharedAction) {
|
||||
is RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers()
|
||||
is RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings()
|
||||
is RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias()
|
||||
is RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
|
||||
is RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
|
||||
}
|
||||
RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers()
|
||||
RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings()
|
||||
RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias()
|
||||
RoomProfileSharedAction.OpenRoomPermissionsSettings -> openRoomPermissions()
|
||||
RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
|
||||
RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
|
||||
}.exhaustive
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
|
||||
|
@ -144,6 +147,10 @@ class RoomProfileActivity :
|
|||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomAliasFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomPermissions() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomPermissionsFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomMembers() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import im.vector.app.core.platform.VectorSharedAction
|
|||
sealed class RoomProfileSharedAction : VectorSharedAction {
|
||||
object OpenRoomSettings : RoomProfileSharedAction()
|
||||
object OpenRoomAliasesSettings : RoomProfileSharedAction()
|
||||
object OpenRoomPermissionsSettings : RoomProfileSharedAction()
|
||||
object OpenRoomUploads : RoomProfileSharedAction()
|
||||
object OpenRoomMembers : RoomProfileSharedAction()
|
||||
object OpenBannedRoomMembers : RoomProfileSharedAction()
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.permissions
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import im.vector.app.R
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
|
||||
/**
|
||||
* Change on each permission has an effect on the power level event. Try to sort the effect by category.
|
||||
*/
|
||||
sealed class EditablePermission(@StringRes val labelResId: Int) {
|
||||
// Updates `content.events.[eventType]`
|
||||
open class EventTypeEditablePermission(val eventType: String, @StringRes labelResId: Int) : EditablePermission(labelResId)
|
||||
|
||||
class ModifyWidgets : EventTypeEditablePermission(
|
||||
// Note: Element Web still use legacy value
|
||||
EventType.STATE_ROOM_WIDGET_LEGACY,
|
||||
R.string.room_permissions_modify_widgets
|
||||
)
|
||||
|
||||
class ChangeRoomAvatar : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_AVATAR,
|
||||
R.string.room_permissions_change_room_avatar
|
||||
)
|
||||
|
||||
class ChangeMainAddressForTheRoom : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_CANONICAL_ALIAS,
|
||||
R.string.room_permissions_change_main_address_for_the_room
|
||||
)
|
||||
|
||||
class EnableRoomEncryption : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_ENCRYPTION,
|
||||
R.string.room_permissions_enable_room_encryption
|
||||
)
|
||||
|
||||
class ChangeHistoryVisibility : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_HISTORY_VISIBILITY,
|
||||
R.string.room_permissions_change_history_visibility
|
||||
)
|
||||
|
||||
class ChangeRoomName : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_NAME,
|
||||
R.string.room_permissions_change_room_name
|
||||
)
|
||||
|
||||
class ChangePermissions : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_POWER_LEVELS,
|
||||
R.string.room_permissions_change_permissions
|
||||
)
|
||||
|
||||
class SendRoomServerAclEvents : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_SERVER_ACL,
|
||||
R.string.room_permissions_send_m_room_server_acl_events
|
||||
)
|
||||
|
||||
class UpgradeTheRoom : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_TOMBSTONE,
|
||||
R.string.room_permissions_upgrade_the_room
|
||||
)
|
||||
|
||||
class ChangeTopic : EventTypeEditablePermission(
|
||||
EventType.STATE_ROOM_TOPIC,
|
||||
R.string.room_permissions_change_topic
|
||||
)
|
||||
|
||||
// Updates `content.users_default`
|
||||
class DefaultRole : EditablePermission(R.string.room_permissions_default_role)
|
||||
|
||||
// Updates `content.events_default`
|
||||
class SendMessages : EditablePermission(R.string.room_permissions_send_messages)
|
||||
|
||||
// Updates `content.invites`
|
||||
class InviteUsers : EditablePermission(R.string.room_permissions_invite_users)
|
||||
|
||||
// Updates `content.state_default`
|
||||
class ChangeSettings : EditablePermission(R.string.room_permissions_change_settings)
|
||||
|
||||
// Updates `content.kick`
|
||||
class KickUsers : EditablePermission(R.string.room_permissions_kick_users)
|
||||
|
||||
// Updates `content.ban`
|
||||
class BanUsers : EditablePermission(R.string.room_permissions_ban_users)
|
||||
|
||||
// Updates `content.redact`
|
||||
class RemoveMessagesSentByOthers : EditablePermission(R.string.room_permissions_remove_messages_sent_by_others)
|
||||
|
||||
// Updates `content.notification.room`
|
||||
class NotifyEveryone : EditablePermission(R.string.room_permissions_notify_everyone)
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 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.permissions
|
||||
|
||||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
|
||||
sealed class RoomPermissionsAction : VectorViewModelAction {
|
||||
data class UpdatePermission(val editablePermission: EditablePermission, val powerLevel: Int) : RoomPermissionsAction()
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright 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.permissions
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import com.airbnb.mvrx.Success
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.epoxy.profiles.buildProfileAction
|
||||
import im.vector.app.core.epoxy.profiles.buildProfileSection
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.discovery.settingsInfoItem
|
||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomPermissionsController @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
colorProvider: ColorProvider
|
||||
) : TypedEpoxyController<RoomPermissionsViewState>() {
|
||||
|
||||
interface Callback {
|
||||
fun onEditPermission(editablePermission: EditablePermission, currentRole: Role)
|
||||
}
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
|
||||
|
||||
// Order is the order applied in the UI
|
||||
private val allEditablePermissions = listOf(
|
||||
EditablePermission.DefaultRole(),
|
||||
EditablePermission.SendMessages(),
|
||||
EditablePermission.InviteUsers(),
|
||||
EditablePermission.ChangeSettings(),
|
||||
EditablePermission.KickUsers(),
|
||||
EditablePermission.BanUsers(),
|
||||
EditablePermission.RemoveMessagesSentByOthers(),
|
||||
EditablePermission.NotifyEveryone(),
|
||||
EditablePermission.ModifyWidgets(),
|
||||
EditablePermission.ChangeRoomAvatar(),
|
||||
EditablePermission.ChangeMainAddressForTheRoom(),
|
||||
EditablePermission.EnableRoomEncryption(),
|
||||
EditablePermission.ChangeHistoryVisibility(),
|
||||
EditablePermission.ChangeRoomName(),
|
||||
EditablePermission.ChangePermissions(),
|
||||
EditablePermission.SendRoomServerAclEvents(),
|
||||
EditablePermission.UpgradeTheRoom(),
|
||||
EditablePermission.ChangeTopic()
|
||||
)
|
||||
|
||||
init {
|
||||
setData(null)
|
||||
}
|
||||
|
||||
override fun buildModels(data: RoomPermissionsViewState?) {
|
||||
buildProfileSection(
|
||||
stringProvider.getString(R.string.room_permissions_title)
|
||||
)
|
||||
|
||||
settingsInfoItem {
|
||||
id("notice")
|
||||
helperText(stringProvider.getString(R.string.room_permissions_notice))
|
||||
}
|
||||
|
||||
when (val content = data?.currentPowerLevelsContent) {
|
||||
is Success -> buildPermissions(data, content())
|
||||
else -> {
|
||||
loadingItem {
|
||||
id("loading")
|
||||
loadingText(stringProvider.getString(R.string.loading))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildPermissions(data: RoomPermissionsViewState, content: PowerLevelsContent) {
|
||||
allEditablePermissions.forEach { editablePermission ->
|
||||
val currentRole = getCurrentRole(editablePermission, content)
|
||||
buildProfileAction(
|
||||
id = editablePermission.labelResId.toString(),
|
||||
title = stringProvider.getString(editablePermission.labelResId),
|
||||
subtitle = getSubtitle(currentRole),
|
||||
dividerColor = dividerColor,
|
||||
divider = true,
|
||||
editable = data.actionPermissions.canChangePowerLevels,
|
||||
action = { callback?.onEditPermission(editablePermission, currentRole) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSubtitle(currentRole: Role): String {
|
||||
return when (currentRole) {
|
||||
Role.Admin,
|
||||
Role.Moderator,
|
||||
Role.Default -> stringProvider.getString(currentRole.res)
|
||||
is Role.Custom -> stringProvider.getString(currentRole.res, currentRole.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCurrentRole(editablePermission: EditablePermission, content: PowerLevelsContent): Role {
|
||||
val value = when (editablePermission) {
|
||||
is EditablePermission.EventTypeEditablePermission -> content.events[editablePermission.eventType] ?: content.stateDefault
|
||||
is EditablePermission.DefaultRole -> content.usersDefault
|
||||
is EditablePermission.SendMessages -> content.eventsDefault
|
||||
is EditablePermission.InviteUsers -> content.invite
|
||||
is EditablePermission.ChangeSettings -> content.stateDefault
|
||||
is EditablePermission.KickUsers -> content.kick
|
||||
is EditablePermission.BanUsers -> content.ban
|
||||
is EditablePermission.RemoveMessagesSentByOthers -> content.redact
|
||||
is EditablePermission.NotifyEveryone -> (content.notifications["room"] as? Int) ?: Role.Moderator.value
|
||||
}
|
||||
|
||||
return Role.fromValue(
|
||||
value,
|
||||
when (editablePermission) {
|
||||
is EditablePermission.EventTypeEditablePermission -> content.stateDefault
|
||||
is EditablePermission.DefaultRole -> Role.Default.value
|
||||
is EditablePermission.SendMessages -> Role.Default.value
|
||||
is EditablePermission.InviteUsers -> Role.Moderator.value
|
||||
is EditablePermission.ChangeSettings -> Role.Moderator.value
|
||||
is EditablePermission.KickUsers -> Role.Moderator.value
|
||||
is EditablePermission.BanUsers -> Role.Moderator.value
|
||||
is EditablePermission.RemoveMessagesSentByOthers -> Role.Moderator.value
|
||||
is EditablePermission.NotifyEveryone -> Role.Moderator.value
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright 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.permissions
|
||||
|
||||
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.args
|
||||
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.extensions.exhaustive
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.FragmentRoomSettingGenericBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.roommemberprofile.powerlevel.EditPowerLevelDialogs
|
||||
import im.vector.app.features.roomprofile.RoomProfileArgs
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.Role
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomPermissionsFragment @Inject constructor(
|
||||
val viewModelFactory: RoomPermissionsViewModel.Factory,
|
||||
private val controller: RoomPermissionsController,
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) :
|
||||
VectorBaseFragment<FragmentRoomSettingGenericBinding>(),
|
||||
RoomPermissionsController.Callback {
|
||||
|
||||
private val viewModel: RoomPermissionsViewModel by fragmentViewModel()
|
||||
|
||||
private val roomProfileArgs: RoomProfileArgs by args()
|
||||
|
||||
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)
|
||||
|
||||
controller.callback = this
|
||||
setupToolbar(views.roomSettingsToolbar)
|
||||
views.roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true)
|
||||
views.waitingView.waitingStatusText.setText(R.string.please_wait)
|
||||
views.waitingView.waitingStatusText.isVisible = true
|
||||
|
||||
viewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is RoomPermissionsViewEvents.Failure -> showFailure(it.throwable)
|
||||
RoomPermissionsViewEvents.Success -> showSuccess()
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSuccess() {
|
||||
activity?.toast(R.string.room_settings_save_success)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
controller.callback = null
|
||||
views.roomSettingsRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
views.waitingView.root.isVisible = state.isLoading
|
||||
controller.setData(state)
|
||||
renderRoomSummary(state)
|
||||
}
|
||||
|
||||
private fun renderRoomSummary(state: RoomPermissionsViewState) {
|
||||
state.roomSummary()?.let {
|
||||
views.roomSettingsToolbarTitleView.text = it.displayName
|
||||
avatarRenderer.render(it.toMatrixItem(), views.roomSettingsToolbarAvatarImageView)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEditPermission(editablePermission: EditablePermission, currentRole: Role) {
|
||||
EditPowerLevelDialogs.showChoice(requireActivity(), editablePermission.labelResId, currentRole) { newPowerLevel ->
|
||||
viewModel.handle(RoomPermissionsAction.UpdatePermission(editablePermission, newPowerLevel))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 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.permissions
|
||||
|
||||
import im.vector.app.core.platform.VectorViewEvents
|
||||
|
||||
/**
|
||||
* Transient events for room settings screen
|
||||
*/
|
||||
sealed class RoomPermissionsViewEvents : VectorViewEvents {
|
||||
data class Failure(val throwable: Throwable) : RoomPermissionsViewEvents()
|
||||
object Success : RoomPermissionsViewEvents()
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright 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.permissions
|
||||
|
||||
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 com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import kotlinx.coroutines.launch
|
||||
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.events.model.toContent
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import org.matrix.android.sdk.rx.unwrap
|
||||
|
||||
class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialState: RoomPermissionsViewState,
|
||||
private val session: Session)
|
||||
: VectorViewModel<RoomPermissionsViewState, RoomPermissionsAction, RoomPermissionsViewEvents>(initialState) {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: RoomPermissionsViewState): RoomPermissionsViewModel
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<RoomPermissionsViewModel, RoomPermissionsViewState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: RoomPermissionsViewState): RoomPermissionsViewModel? {
|
||||
val fragment: RoomPermissionsFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
return fragment.viewModelFactory.create(state)
|
||||
}
|
||||
}
|
||||
|
||||
private val room = session.getRoom(initialState.roomId)!!
|
||||
|
||||
init {
|
||||
observeRoomSummary()
|
||||
observePowerLevel()
|
||||
}
|
||||
|
||||
private fun observeRoomSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(
|
||||
roomSummary = async
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observePowerLevel() {
|
||||
PowerLevelsObservableFactory(room)
|
||||
.createObservable()
|
||||
.subscribe { powerLevelContent ->
|
||||
val powerLevelsHelper = PowerLevelsHelper(powerLevelContent)
|
||||
val permissions = RoomPermissionsViewState.ActionPermissions(
|
||||
canChangePowerLevels = powerLevelsHelper.isUserAllowedToSend(
|
||||
userId = session.myUserId,
|
||||
isState = true,
|
||||
eventType = EventType.STATE_ROOM_POWER_LEVELS
|
||||
)
|
||||
)
|
||||
setState {
|
||||
copy(
|
||||
actionPermissions = permissions,
|
||||
currentPowerLevelsContent = Success(powerLevelContent)
|
||||
)
|
||||
}
|
||||
}
|
||||
.disposeOnClear()
|
||||
}
|
||||
|
||||
override fun handle(action: RoomPermissionsAction) {
|
||||
when (action) {
|
||||
is RoomPermissionsAction.UpdatePermission -> updatePermission(action)
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun updatePermission(action: RoomPermissionsAction.UpdatePermission) {
|
||||
withState { state ->
|
||||
val currentPowerLevel = state.currentPowerLevelsContent.invoke() ?: return@withState
|
||||
postLoading(true)
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val newPowerLevelsContent = when(action.editablePermission) {
|
||||
is EditablePermission.EventTypeEditablePermission -> currentPowerLevel.copy(
|
||||
events = currentPowerLevel.events.toMutableMap().apply {
|
||||
put(action.editablePermission.eventType, action.powerLevel)
|
||||
}
|
||||
)
|
||||
is EditablePermission.DefaultRole -> currentPowerLevel.copy(usersDefault = action.powerLevel)
|
||||
is EditablePermission.SendMessages -> currentPowerLevel.copy(eventsDefault = action.powerLevel)
|
||||
is EditablePermission.InviteUsers -> currentPowerLevel.copy(invite = action.powerLevel)
|
||||
is EditablePermission.ChangeSettings -> currentPowerLevel.copy(stateDefault = action.powerLevel)
|
||||
is EditablePermission.KickUsers -> currentPowerLevel.copy(kick = action.powerLevel)
|
||||
is EditablePermission.BanUsers -> currentPowerLevel.copy(ban = action.powerLevel)
|
||||
is EditablePermission.RemoveMessagesSentByOthers -> currentPowerLevel.copy(redact = action.powerLevel)
|
||||
is EditablePermission.NotifyEveryone -> currentPowerLevel.copy(
|
||||
notifications = currentPowerLevel.notifications.toMutableMap().apply {
|
||||
put("room", action.powerLevel)
|
||||
}
|
||||
)
|
||||
}
|
||||
room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, newPowerLevelsContent.toContent())
|
||||
setState {
|
||||
copy(
|
||||
isLoading = false
|
||||
)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
postLoading(false)
|
||||
_viewEvents.post(RoomPermissionsViewEvents.Failure(failure))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun postLoading(isLoading: Boolean) {
|
||||
setState {
|
||||
copy(isLoading = isLoading)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 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.permissions
|
||||
|
||||
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.PowerLevelsContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
|
||||
data class RoomPermissionsViewState(
|
||||
val roomId: String,
|
||||
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val actionPermissions: ActionPermissions = ActionPermissions(),
|
||||
val currentPowerLevelsContent: Async<PowerLevelsContent> = Uninitialized,
|
||||
val newPowerLevelsContent: PowerLevelsContent? = null,
|
||||
val isLoading: Boolean = false
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||
|
||||
data class ActionPermissions(
|
||||
val canChangePowerLevels: Boolean = false
|
||||
)
|
||||
}
|
|
@ -46,6 +46,7 @@ class RoomSettingsController @Inject constructor(
|
|||
fun onTopicChanged(topic: String)
|
||||
fun onHistoryVisibilityClicked()
|
||||
fun onRoomAliasesClicked()
|
||||
fun onRoomPermissionsClicked()
|
||||
fun onJoinRuleClicked()
|
||||
}
|
||||
|
||||
|
@ -115,6 +116,16 @@ class RoomSettingsController @Inject constructor(
|
|||
action = { callback?.onRoomAliasesClicked() }
|
||||
)
|
||||
|
||||
buildProfileAction(
|
||||
id = "permissions",
|
||||
title = stringProvider.getString(R.string.room_settings_permissions_title),
|
||||
subtitle = stringProvider.getString(R.string.room_settings_permissions_subtitle),
|
||||
dividerColor = dividerColor,
|
||||
divider = true,
|
||||
editable = true,
|
||||
action = { callback?.onRoomPermissionsClicked() }
|
||||
)
|
||||
|
||||
buildProfileAction(
|
||||
id = "historyReadability",
|
||||
title = stringProvider.getString(R.string.room_settings_room_read_history_rules_pref_title),
|
||||
|
|
|
@ -178,6 +178,10 @@ class RoomSettingsFragment @Inject constructor(
|
|||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomAliasesSettings)
|
||||
}
|
||||
|
||||
override fun onRoomPermissionsClicked() {
|
||||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomPermissionsSettings)
|
||||
}
|
||||
|
||||
override fun onJoinRuleClicked() = withState(viewModel) { state ->
|
||||
val currentJoinRule = state.newRoomJoinRules.newJoinRules ?: state.currentRoomJoinRules
|
||||
val currentGuestAccess = state.newRoomJoinRules.newGuestAccess ?: state.currentGuestAccess
|
||||
|
|
|
@ -609,6 +609,32 @@
|
|||
<string name="ssl_expected_existing_expl">The certificate has changed from a previously trusted one to one that is not trusted. The server may have renewed its certificate. Contact the server administrator for the expected fingerprint.</string>
|
||||
<string name="ssl_only_accept">Only accept the certificate if the server administrator has published a fingerprint that matches the one above.</string>
|
||||
|
||||
<!-- Room Permissions -->
|
||||
<string name="room_settings_permissions_title">Room permissions</string>
|
||||
<string name="room_settings_permissions_subtitle">View and update the roles required to change various parts of the room.</string>
|
||||
|
||||
<string name="room_permissions_title">"Permissions"</string>
|
||||
<string name="room_permissions_notice">"Select the roles required to change various parts of the room"</string>
|
||||
|
||||
<string name="room_permissions_default_role">Default role</string>
|
||||
<string name="room_permissions_send_messages">Send messages</string>
|
||||
<string name="room_permissions_invite_users">Invite users</string>
|
||||
<string name="room_permissions_change_settings">Change settings</string>
|
||||
<string name="room_permissions_kick_users">Kick users</string>
|
||||
<string name="room_permissions_ban_users">Ban users</string>
|
||||
<string name="room_permissions_remove_messages_sent_by_others">Remove messages sent by others</string>
|
||||
<string name="room_permissions_notify_everyone">Notify everyone</string>
|
||||
<string name="room_permissions_modify_widgets">Modify widgets</string>
|
||||
<string name="room_permissions_change_room_avatar">Change room avatar</string>
|
||||
<string name="room_permissions_change_main_address_for_the_room">Change main address for the room</string>
|
||||
<string name="room_permissions_enable_room_encryption">Enable room encryption</string>
|
||||
<string name="room_permissions_change_history_visibility">Change history visibility</string>
|
||||
<string name="room_permissions_change_room_name">Change room name</string>
|
||||
<string name="room_permissions_change_permissions">Change permissions</string>
|
||||
<string name="room_permissions_send_m_room_server_acl_events">Send m.room.server_acl events</string>
|
||||
<string name="room_permissions_upgrade_the_room">Upgrade the room</string>
|
||||
<string name="room_permissions_change_topic">Change topic</string>
|
||||
|
||||
<!-- Room Details -->
|
||||
<string name="room_details_title">Room Details</string>
|
||||
<string name="room_details_people">People</string>
|
||||
|
|
Loading…
Reference in a new issue