mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-19 21:29:52 -07:00
Add ban/unban/kick room commands (#327)
This commit is contained in:
parent
2a66496913
commit
df3896df9c
4 changed files with 145 additions and 0 deletions
|
@ -161,6 +161,12 @@ Set the room's canonical alias to the one provided, and make the previous one an
|
||||||
Delete the room's canonical alias.
|
Delete the room's canonical alias.
|
||||||
.It Sy ":room canon show"
|
.It Sy ":room canon show"
|
||||||
Show the room's canonical alias, if any is set.
|
Show the room's canonical alias, if any is set.
|
||||||
|
.It Sy ":room ban [user] [reason]"
|
||||||
|
Ban a user from this room with an optional reason.
|
||||||
|
.It Sy ":room unban [user] [reason]"
|
||||||
|
Unban a user from this room with an optional reason.
|
||||||
|
.It Sy ":room kick [user] [reason]"
|
||||||
|
Kick a user from this room with an optional reason.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh "WINDOW COMMANDS"
|
.Sh "WINDOW COMMANDS"
|
||||||
|
|
21
src/base.rs
21
src/base.rs
|
@ -391,6 +391,24 @@ pub enum RoomField {
|
||||||
CanonicalAlias,
|
CanonicalAlias,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An action that operates on a room member.
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum MemberUpdateAction {
|
||||||
|
Ban,
|
||||||
|
Kick,
|
||||||
|
Unban,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for MemberUpdateAction {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
MemberUpdateAction::Ban => write!(f, "ban"),
|
||||||
|
MemberUpdateAction::Kick => write!(f, "kick"),
|
||||||
|
MemberUpdateAction::Unban => write!(f, "unban"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An action that operates on a focused room.
|
/// An action that operates on a focused room.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum RoomAction {
|
pub enum RoomAction {
|
||||||
|
@ -406,6 +424,9 @@ pub enum RoomAction {
|
||||||
/// Leave this room.
|
/// Leave this room.
|
||||||
Leave(bool),
|
Leave(bool),
|
||||||
|
|
||||||
|
/// Update a user's membership in this room.
|
||||||
|
MemberUpdate(MemberUpdateAction, String, Option<String>, bool),
|
||||||
|
|
||||||
/// Open the members window.
|
/// Open the members window.
|
||||||
Members(Box<CommandContext>),
|
Members(Box<CommandContext>),
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ use crate::base::{
|
||||||
IambAction,
|
IambAction,
|
||||||
IambId,
|
IambId,
|
||||||
KeysAction,
|
KeysAction,
|
||||||
|
MemberUpdateAction,
|
||||||
MessageAction,
|
MessageAction,
|
||||||
ProgramCommand,
|
ProgramCommand,
|
||||||
ProgramCommands,
|
ProgramCommands,
|
||||||
|
@ -411,6 +412,17 @@ fn iamb_room(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
("dm", "unset", None) => RoomAction::SetDirect(false).into(),
|
("dm", "unset", None) => RoomAction::SetDirect(false).into(),
|
||||||
("dm", "unset", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
("dm", "unset", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room [kick|ban|unban] <user>
|
||||||
|
("kick", u, r) => {
|
||||||
|
RoomAction::MemberUpdate(MemberUpdateAction::Kick, u.into(), r, desc.bang).into()
|
||||||
|
},
|
||||||
|
("ban", u, r) => {
|
||||||
|
RoomAction::MemberUpdate(MemberUpdateAction::Ban, u.into(), r, desc.bang).into()
|
||||||
|
},
|
||||||
|
("unban", u, r) => {
|
||||||
|
RoomAction::MemberUpdate(MemberUpdateAction::Unban, u.into(), r, desc.bang).into()
|
||||||
|
},
|
||||||
|
|
||||||
// :room name set <room-name>
|
// :room name set <room-name>
|
||||||
("name", "set", Some(s)) => RoomAction::Set(RoomField::Name, s).into(),
|
("name", "set", Some(s)) => RoomAction::Set(RoomField::Name, s).into(),
|
||||||
("name", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
("name", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
@ -1047,6 +1059,69 @@ mod tests {
|
||||||
assert_eq!(res, Err(CommandError::InvalidArgument));
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_kick() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = EditContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room kick @user:example.com", ctx.clone()).unwrap();
|
||||||
|
let act = IambAction::Room(RoomAction::MemberUpdate(
|
||||||
|
MemberUpdateAction::Kick,
|
||||||
|
"@user:example.com".into(),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room! kick @user:example.com", ctx.clone()).unwrap();
|
||||||
|
let act = IambAction::Room(RoomAction::MemberUpdate(
|
||||||
|
MemberUpdateAction::Kick,
|
||||||
|
"@user:example.com".into(),
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds
|
||||||
|
.input_cmd("room! kick @user:example.com \"reason here\"", ctx.clone())
|
||||||
|
.unwrap();
|
||||||
|
let act = IambAction::Room(RoomAction::MemberUpdate(
|
||||||
|
MemberUpdateAction::Kick,
|
||||||
|
"@user:example.com".into(),
|
||||||
|
Some("reason here".into()),
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_ban_unban() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = EditContext::default();
|
||||||
|
|
||||||
|
let res = cmds
|
||||||
|
.input_cmd("room! ban @user:example.com \"spam\"", ctx.clone())
|
||||||
|
.unwrap();
|
||||||
|
let act = IambAction::Room(RoomAction::MemberUpdate(
|
||||||
|
MemberUpdateAction::Ban,
|
||||||
|
"@user:example.com".into(),
|
||||||
|
Some("spam".into()),
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds
|
||||||
|
.input_cmd("room unban @user:example.com \"reconciled\"", ctx.clone())
|
||||||
|
.unwrap();
|
||||||
|
let act = IambAction::Room(RoomAction::MemberUpdate(
|
||||||
|
MemberUpdateAction::Unban,
|
||||||
|
"@user:example.com".into(),
|
||||||
|
Some("reconciled".into()),
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cmd_redact() {
|
fn test_cmd_redact() {
|
||||||
let mut cmds = setup_commands();
|
let mut cmds = setup_commands();
|
||||||
|
|
|
@ -22,6 +22,7 @@ use matrix_sdk::{
|
||||||
},
|
},
|
||||||
OwnedEventId,
|
OwnedEventId,
|
||||||
OwnedRoomAliasId,
|
OwnedRoomAliasId,
|
||||||
|
OwnedUserId,
|
||||||
RoomId,
|
RoomId,
|
||||||
},
|
},
|
||||||
DisplayName,
|
DisplayName,
|
||||||
|
@ -56,6 +57,7 @@ use crate::base::{
|
||||||
IambId,
|
IambId,
|
||||||
IambInfo,
|
IambInfo,
|
||||||
IambResult,
|
IambResult,
|
||||||
|
MemberUpdateAction,
|
||||||
MessageAction,
|
MessageAction,
|
||||||
ProgramAction,
|
ProgramAction,
|
||||||
ProgramContext,
|
ProgramContext,
|
||||||
|
@ -269,6 +271,47 @@ impl RoomState {
|
||||||
Err(IambError::NotJoined.into())
|
Err(IambError::NotJoined.into())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
RoomAction::MemberUpdate(mua, user, reason, skip_confirm) => {
|
||||||
|
let Some(room) = store.application.worker.client.get_room(self.id()) else {
|
||||||
|
return Err(IambError::NotJoined.into());
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(user_id) = OwnedUserId::try_from(user.as_str()) else {
|
||||||
|
let err = IambError::InvalidUserId(user);
|
||||||
|
|
||||||
|
return Err(err.into());
|
||||||
|
};
|
||||||
|
|
||||||
|
if !skip_confirm {
|
||||||
|
let msg = format!("Do you really want to {mua} {user} from this room?");
|
||||||
|
let act = RoomAction::MemberUpdate(mua, user, reason, true);
|
||||||
|
let act = IambAction::from(act);
|
||||||
|
let prompt = PromptYesNo::new(msg, vec![Action::from(act)]);
|
||||||
|
let prompt = Box::new(prompt);
|
||||||
|
|
||||||
|
return Err(UIError::NeedConfirm(prompt));
|
||||||
|
}
|
||||||
|
|
||||||
|
match mua {
|
||||||
|
MemberUpdateAction::Ban => {
|
||||||
|
room.ban_user(&user_id, reason.as_deref())
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
MemberUpdateAction::Unban => {
|
||||||
|
room.unban_user(&user_id, reason.as_deref())
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
MemberUpdateAction::Kick => {
|
||||||
|
room.kick_user(&user_id, reason.as_deref())
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(vec![])
|
||||||
|
},
|
||||||
RoomAction::Members(mut cmd) => {
|
RoomAction::Members(mut cmd) => {
|
||||||
let width = Count::Exact(30);
|
let width = Count::Exact(30);
|
||||||
let act =
|
let act =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue