Browse Source

room-details: Ask to confirm some changes in PermissionsMemberRow

When muting, promoting to the same level as our own user, or demoting
oneself like on the UserPage.
fractal-12
Kévin Commaille 8 months ago
parent
commit
0a92b9772a
No known key found for this signature in database
GPG Key ID: F26F4BE20A08255B
  1. 12
      src/components/dialogs/message_dialogs.rs
  2. 5
      src/session/model/room/permissions.rs
  3. 5
      src/session/view/content/room_details/permissions/member_power_level.rs
  4. 74
      src/session/view/content/room_details/permissions/member_row.rs

12
src/components/dialogs/message_dialogs.rs

@ -7,7 +7,7 @@ use crate::{
i18n::gettext_f,
ngettext_f,
prelude::*,
session::model::{Member, Membership, Room, RoomCategory},
session::model::{Member, Membership, Room, RoomCategory, User},
};
/// Show a dialog to confirm leaving a room.
@ -358,7 +358,7 @@ pub(crate) struct ConfirmRoomMemberDestructiveActionResponse {
/// Show a dialog to confirm muting one or several room members.
pub(crate) async fn confirm_mute_room_member_dialog(
members: &[Member],
members: &[impl IsA<User>],
parent: &impl IsA<gtk::Widget>,
) -> bool {
if members.is_empty() {
@ -367,7 +367,8 @@ pub(crate) async fn confirm_mute_room_member_dialog(
let first_member = members
.first()
.expect("there should be at least one member");
.expect("there should be at least one member")
.upcast_ref();
let count = members.len() as u32;
let heading = ngettext_f(
@ -406,7 +407,7 @@ pub(crate) async fn confirm_mute_room_member_dialog(
/// Show a dialog to confirm setting the power level of one or several room
/// members with the same value as our own.
pub(crate) async fn confirm_set_room_member_power_level_same_as_own_dialog(
members: &[Member],
members: &[impl IsA<User>],
parent: &impl IsA<gtk::Widget>,
) -> bool {
if members.is_empty() {
@ -415,7 +416,8 @@ pub(crate) async fn confirm_set_room_member_power_level_same_as_own_dialog(
let first_member = members
.first()
.expect("there should be at least one member");
.expect("there should be at least one member")
.upcast_ref();
let count = members.len() as u32;
let heading = ngettext_f(

5
src/session/model/room/permissions.rs

@ -500,6 +500,11 @@ impl Permissions {
self.imp().power_levels.borrow().clone()
}
/// The power level for the user with the given ID.
pub(crate) fn user_power_level(&self, user_id: &UserId) -> PowerLevel {
self.imp().power_levels.borrow().for_user(user_id).into()
}
/// The current [`MemberRole`] for the given power level.
pub(crate) fn role(&self, power_level: PowerLevel) -> MemberRole {
if power_level >= POWER_LEVEL_ADMIN {

5
src/session/view/content/room_details/permissions/member_power_level.rs

@ -77,10 +77,7 @@ mod imp {
return;
};
let power_levels = permissions.power_levels();
let power_level = power_levels.for_user(user.user_id());
self.set_power_level(power_level.into());
self.set_power_level(permissions.user_power_level(user.user_id()));
}
/// Set the wanted power level of the member.

74
src/session/view/content/room_details/permissions/member_row.rs

@ -1,8 +1,14 @@
use std::slice;
use gtk::{CompositeTemplate, glib, glib::clone, prelude::*, subclass::prelude::*};
use super::MemberPowerLevel;
use crate::{
components::{Avatar, PowerLevelSelectionPopover, RoleBadge},
components::{
Avatar, PowerLevelSelectionPopover, RoleBadge, confirm_mute_room_member_dialog,
confirm_own_demotion_dialog, confirm_set_room_member_power_level_same_as_own_dialog,
},
prelude::*,
session::model::Permissions,
utils::{BoundObject, key_bindings},
};
@ -82,7 +88,9 @@ mod imp {
impl PermissionsMemberRow {
/// Set the permissions of the room.
fn set_permissions(&self, permissions: Permissions) {
self.permissions.set(permissions.clone()).unwrap();
self.permissions
.set(permissions.clone())
.expect("permissions should be uninitialized");
self.popover.set_permissions(Some(permissions));
}
@ -174,13 +182,69 @@ mod imp {
/// The popover's selected power level changed.
#[template_callback]
fn power_level_changed(&self) {
async fn power_level_changed(&self) {
let Some(member) = self.member.obj() else {
return;
};
let pl = self.popover.selected_power_level();
member.set_power_level(pl);
let power_level = self.popover.selected_power_level();
let old_power_level = member.power_level();
if power_level == old_power_level {
// Nothing changed.
return;
}
let permissions = self
.permissions
.get()
.expect("permissions should be initialized");
let user = member.user();
let room_power_level = permissions.user_power_level(user.user_id());
if room_power_level == power_level {
// The power level was reset to the one in the room, nothing to check.
member.set_power_level(power_level);
return;
}
let obj = self.obj();
if user.is_own_user() {
// Warn that demoting oneself is irreversible.
if !confirm_own_demotion_dialog(&*obj).await {
// Reset the value in the popover.
self.popover.set_selected_power_level(old_power_level);
return;
}
} else {
// Warn if user is muted but was not before.
let mute_power_level = permissions.mute_power_level();
let is_muted =
power_level <= mute_power_level && old_power_level > mute_power_level;
if is_muted && !confirm_mute_room_member_dialog(slice::from_ref(&user), &*obj).await
{
// Reset the value in the popover.
self.popover.set_selected_power_level(old_power_level);
return;
}
// Warn if power level is set at same level as own power level.
let is_own_power_level = power_level == permissions.own_power_level();
if is_own_power_level
&& !confirm_set_room_member_power_level_same_as_own_dialog(
slice::from_ref(&user),
&*obj,
)
.await
{
// Reset the value in the popover.
self.popover.set_selected_power_level(old_power_level);
return;
}
}
member.set_power_level(power_level);
}
}
}

Loading…
Cancel
Save