mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-19 21:29:52 -07:00
Support adding rooms to spaces (#407)
This commit is contained in:
parent
7dd09e32a8
commit
3e45ca3d2c
7 changed files with 366 additions and 5 deletions
10
docs/iamb.1
10
docs/iamb.1
|
@ -159,6 +159,8 @@ Create and point the given alias to the room.
|
||||||
Delete the provided alias from the room's alternative alias list.
|
Delete the provided alias from the room's alternative alias list.
|
||||||
.It Sy ":room alias show"
|
.It Sy ":room alias show"
|
||||||
Show alternative aliases to the room, if any are set.
|
Show alternative aliases to the room, if any are set.
|
||||||
|
.It Sy ":room id show"
|
||||||
|
Show the Matrix identifier for the room.
|
||||||
.It Sy ":room canon set [alias]"
|
.It Sy ":room canon set [alias]"
|
||||||
Set the room's canonical alias to the one provided, and make the previous one an alternative alias.
|
Set the room's canonical alias to the one provided, and make the previous one an alternative alias.
|
||||||
.It Sy ":room canon unset [alias]"
|
.It Sy ":room canon unset [alias]"
|
||||||
|
@ -173,6 +175,14 @@ Unban a user from this room with an optional reason.
|
||||||
Kick a user from this room with an optional reason.
|
Kick a user from this room with an optional reason.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
|
.Sh "SPACE COMMANDS"
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Sy ":space child set [room_id]"
|
||||||
|
Add a room to the currently focused space.
|
||||||
|
.It Sy ":space child remove"
|
||||||
|
Remove the selected room from the currently focused space.
|
||||||
|
.El
|
||||||
|
|
||||||
.Sh "WINDOW COMMANDS"
|
.Sh "WINDOW COMMANDS"
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Sy ":horizontal [cmd]"
|
.It Sy ":horizontal [cmd]"
|
||||||
|
|
47
src/base.rs
47
src/base.rs
|
@ -177,6 +177,19 @@ pub enum MessageAction {
|
||||||
Unreact(Option<String>, bool),
|
Unreact(Option<String>, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An action taken in the currently selected space.
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum SpaceAction {
|
||||||
|
/// Add a room or update metadata.
|
||||||
|
///
|
||||||
|
/// The [`Option<String>`] argument is the order parameter.
|
||||||
|
/// The [`bool`] argument indicates whether the room is suggested.
|
||||||
|
SetChild(OwnedRoomId, Option<String>, bool),
|
||||||
|
|
||||||
|
/// Remove the selected room.
|
||||||
|
RemoveChild,
|
||||||
|
}
|
||||||
|
|
||||||
/// The type of room being created.
|
/// The type of room being created.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum CreateRoomType {
|
pub enum CreateRoomType {
|
||||||
|
@ -379,6 +392,9 @@ pub enum RoomField {
|
||||||
/// The room name.
|
/// The room name.
|
||||||
Name,
|
Name,
|
||||||
|
|
||||||
|
/// The room id.
|
||||||
|
Id,
|
||||||
|
|
||||||
/// A room tag.
|
/// A room tag.
|
||||||
Tag(TagName),
|
Tag(TagName),
|
||||||
|
|
||||||
|
@ -497,6 +513,9 @@ pub enum IambAction {
|
||||||
/// Perform an action on the currently selected message.
|
/// Perform an action on the currently selected message.
|
||||||
Message(MessageAction),
|
Message(MessageAction),
|
||||||
|
|
||||||
|
/// Perform an action on the current space.
|
||||||
|
Space(SpaceAction),
|
||||||
|
|
||||||
/// Open a URL.
|
/// Open a URL.
|
||||||
OpenLink(String),
|
OpenLink(String),
|
||||||
|
|
||||||
|
@ -538,6 +557,12 @@ impl From<MessageAction> for IambAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<SpaceAction> for IambAction {
|
||||||
|
fn from(act: SpaceAction) -> Self {
|
||||||
|
IambAction::Space(act)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<RoomAction> for IambAction {
|
impl From<RoomAction> for IambAction {
|
||||||
fn from(act: RoomAction) -> Self {
|
fn from(act: RoomAction) -> Self {
|
||||||
IambAction::Room(act)
|
IambAction::Room(act)
|
||||||
|
@ -557,6 +582,7 @@ impl ApplicationAction for IambAction {
|
||||||
IambAction::Homeserver(..) => SequenceStatus::Break,
|
IambAction::Homeserver(..) => SequenceStatus::Break,
|
||||||
IambAction::Keys(..) => SequenceStatus::Break,
|
IambAction::Keys(..) => SequenceStatus::Break,
|
||||||
IambAction::Message(..) => SequenceStatus::Break,
|
IambAction::Message(..) => SequenceStatus::Break,
|
||||||
|
IambAction::Space(..) => SequenceStatus::Break,
|
||||||
IambAction::Room(..) => SequenceStatus::Break,
|
IambAction::Room(..) => SequenceStatus::Break,
|
||||||
IambAction::OpenLink(..) => SequenceStatus::Break,
|
IambAction::OpenLink(..) => SequenceStatus::Break,
|
||||||
IambAction::Send(..) => SequenceStatus::Break,
|
IambAction::Send(..) => SequenceStatus::Break,
|
||||||
|
@ -572,6 +598,7 @@ impl ApplicationAction for IambAction {
|
||||||
IambAction::Homeserver(..) => SequenceStatus::Atom,
|
IambAction::Homeserver(..) => SequenceStatus::Atom,
|
||||||
IambAction::Keys(..) => SequenceStatus::Atom,
|
IambAction::Keys(..) => SequenceStatus::Atom,
|
||||||
IambAction::Message(..) => SequenceStatus::Atom,
|
IambAction::Message(..) => SequenceStatus::Atom,
|
||||||
|
IambAction::Space(..) => SequenceStatus::Atom,
|
||||||
IambAction::OpenLink(..) => SequenceStatus::Atom,
|
IambAction::OpenLink(..) => SequenceStatus::Atom,
|
||||||
IambAction::Room(..) => SequenceStatus::Atom,
|
IambAction::Room(..) => SequenceStatus::Atom,
|
||||||
IambAction::Send(..) => SequenceStatus::Atom,
|
IambAction::Send(..) => SequenceStatus::Atom,
|
||||||
|
@ -587,6 +614,7 @@ impl ApplicationAction for IambAction {
|
||||||
IambAction::Homeserver(..) => SequenceStatus::Ignore,
|
IambAction::Homeserver(..) => SequenceStatus::Ignore,
|
||||||
IambAction::Keys(..) => SequenceStatus::Ignore,
|
IambAction::Keys(..) => SequenceStatus::Ignore,
|
||||||
IambAction::Message(..) => SequenceStatus::Ignore,
|
IambAction::Message(..) => SequenceStatus::Ignore,
|
||||||
|
IambAction::Space(..) => SequenceStatus::Ignore,
|
||||||
IambAction::Room(..) => SequenceStatus::Ignore,
|
IambAction::Room(..) => SequenceStatus::Ignore,
|
||||||
IambAction::OpenLink(..) => SequenceStatus::Ignore,
|
IambAction::OpenLink(..) => SequenceStatus::Ignore,
|
||||||
IambAction::Send(..) => SequenceStatus::Ignore,
|
IambAction::Send(..) => SequenceStatus::Ignore,
|
||||||
|
@ -601,6 +629,7 @@ impl ApplicationAction for IambAction {
|
||||||
IambAction::ClearUnreads => false,
|
IambAction::ClearUnreads => false,
|
||||||
IambAction::Homeserver(..) => false,
|
IambAction::Homeserver(..) => false,
|
||||||
IambAction::Message(..) => false,
|
IambAction::Message(..) => false,
|
||||||
|
IambAction::Space(..) => false,
|
||||||
IambAction::Room(..) => false,
|
IambAction::Room(..) => false,
|
||||||
IambAction::Keys(..) => false,
|
IambAction::Keys(..) => false,
|
||||||
IambAction::Send(..) => false,
|
IambAction::Send(..) => false,
|
||||||
|
@ -618,6 +647,12 @@ impl From<RoomAction> for ProgramAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<SpaceAction> for ProgramAction {
|
||||||
|
fn from(act: SpaceAction) -> Self {
|
||||||
|
IambAction::from(act).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<IambAction> for ProgramAction {
|
impl From<IambAction> for ProgramAction {
|
||||||
fn from(act: IambAction) -> Self {
|
fn from(act: IambAction) -> Self {
|
||||||
Action::Application(act)
|
Action::Application(act)
|
||||||
|
@ -713,10 +748,22 @@ pub enum IambError {
|
||||||
#[error("Current window is not a room or space")]
|
#[error("Current window is not a room or space")]
|
||||||
NoSelectedRoomOrSpace,
|
NoSelectedRoomOrSpace,
|
||||||
|
|
||||||
|
/// A failure due to not having a room or space item selected in a list.
|
||||||
|
#[error("No room or space currently selected in list")]
|
||||||
|
NoSelectedRoomOrSpaceItem,
|
||||||
|
|
||||||
/// A failure due to not having a room selected.
|
/// A failure due to not having a room selected.
|
||||||
#[error("Current window is not a room")]
|
#[error("Current window is not a room")]
|
||||||
NoSelectedRoom,
|
NoSelectedRoom,
|
||||||
|
|
||||||
|
/// A failure due to not having a space selected.
|
||||||
|
#[error("Current window is not a space")]
|
||||||
|
NoSelectedSpace,
|
||||||
|
|
||||||
|
/// A failure due to not having sufficient permission to perform an action in a room.
|
||||||
|
#[error("You do not have the permission to do that")]
|
||||||
|
InsufficientPermission,
|
||||||
|
|
||||||
/// A failure due to not having an outstanding room invitation.
|
/// A failure due to not having an outstanding room invitation.
|
||||||
#[error("You do not have a current invitation to this room")]
|
#[error("You do not have a current invitation to this room")]
|
||||||
NotInvited,
|
NotInvited,
|
||||||
|
|
193
src/commands.rs
193
src/commands.rs
|
@ -2,9 +2,9 @@
|
||||||
//!
|
//!
|
||||||
//! The command-bar commands are set up here, and iamb-specific commands are defined here. See
|
//! The command-bar commands are set up here, and iamb-specific commands are defined here. See
|
||||||
//! [modalkit::env::vim::command] for additional Vim commands we pull in.
|
//! [modalkit::env::vim::command] for additional Vim commands we pull in.
|
||||||
use std::convert::TryFrom;
|
use std::{convert::TryFrom, str::FromStr as _};
|
||||||
|
|
||||||
use matrix_sdk::ruma::{events::tag::TagName, OwnedUserId};
|
use matrix_sdk::ruma::{events::tag::TagName, OwnedRoomId, OwnedUserId};
|
||||||
|
|
||||||
use modalkit::{
|
use modalkit::{
|
||||||
commands::{CommandError, CommandResult, CommandStep},
|
commands::{CommandError, CommandResult, CommandStep},
|
||||||
|
@ -27,6 +27,7 @@ use crate::base::{
|
||||||
RoomAction,
|
RoomAction,
|
||||||
RoomField,
|
RoomField,
|
||||||
SendAction,
|
SendAction,
|
||||||
|
SpaceAction,
|
||||||
VerifyAction,
|
VerifyAction,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -535,6 +536,90 @@ fn iamb_room(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
return Result::Err(CommandError::InvalidArgument)
|
return Result::Err(CommandError::InvalidArgument)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// :room id show
|
||||||
|
("id", "show", None) => RoomAction::Show(RoomField::Id).into(),
|
||||||
|
("id", "show", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
_ => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
};
|
||||||
|
|
||||||
|
let step = CommandStep::Continue(act.into(), ctx.context.clone());
|
||||||
|
|
||||||
|
return Ok(step);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iamb_space(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
|
let mut args = desc.arg.options()?;
|
||||||
|
|
||||||
|
if args.len() < 2 {
|
||||||
|
return Err(CommandError::InvalidArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
let OptionType::Positional(field) = args.remove(0) else {
|
||||||
|
return Err(CommandError::InvalidArgument);
|
||||||
|
};
|
||||||
|
let OptionType::Positional(action) = args.remove(0) else {
|
||||||
|
return Err(CommandError::InvalidArgument);
|
||||||
|
};
|
||||||
|
|
||||||
|
let act: IambAction = match (field.as_str(), action.as_str()) {
|
||||||
|
("child", "remove") => {
|
||||||
|
if !(args.is_empty()) {
|
||||||
|
return Err(CommandError::InvalidArgument);
|
||||||
|
}
|
||||||
|
SpaceAction::RemoveChild.into()
|
||||||
|
},
|
||||||
|
// :space child set
|
||||||
|
("child", "set") => {
|
||||||
|
let mut order = None;
|
||||||
|
let mut suggested = false;
|
||||||
|
let mut raw_child = None;
|
||||||
|
|
||||||
|
for arg in args {
|
||||||
|
match arg {
|
||||||
|
OptionType::Flag(name, Some(arg)) => {
|
||||||
|
match name.as_str() {
|
||||||
|
"order" => {
|
||||||
|
if order.is_some() {
|
||||||
|
let msg = "Multiple ++order arguments are not allowed";
|
||||||
|
let err = CommandError::Error(msg.into());
|
||||||
|
|
||||||
|
return Err(err);
|
||||||
|
} else {
|
||||||
|
order = Some(arg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => return Err(CommandError::InvalidArgument),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OptionType::Flag(name, None) => {
|
||||||
|
match name.as_str() {
|
||||||
|
"suggested" => suggested = true,
|
||||||
|
_ => return Err(CommandError::InvalidArgument),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OptionType::Positional(arg) => {
|
||||||
|
if raw_child.is_some() {
|
||||||
|
let msg = "Multiple room arguments are not allowed";
|
||||||
|
let err = CommandError::Error(msg.into());
|
||||||
|
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
raw_child = Some(arg);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let child = if let Some(child) = raw_child {
|
||||||
|
OwnedRoomId::from_str(&child)
|
||||||
|
.map_err(|_| CommandError::Error("Invalid room id specified".into()))?
|
||||||
|
} else {
|
||||||
|
let msg = "Must specify a room to add";
|
||||||
|
return Err(CommandError::Error(msg.into()));
|
||||||
|
};
|
||||||
|
|
||||||
|
SpaceAction::SetChild(child, order, suggested).into()
|
||||||
|
},
|
||||||
_ => return Result::Err(CommandError::InvalidArgument),
|
_ => return Result::Err(CommandError::InvalidArgument),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -671,6 +756,11 @@ fn add_iamb_commands(cmds: &mut ProgramCommands) {
|
||||||
f: iamb_rooms,
|
f: iamb_rooms,
|
||||||
});
|
});
|
||||||
cmds.add_command(ProgramCommand { name: "room".into(), aliases: vec![], f: iamb_room });
|
cmds.add_command(ProgramCommand { name: "room".into(), aliases: vec![], f: iamb_room });
|
||||||
|
cmds.add_command(ProgramCommand {
|
||||||
|
name: "space".into(),
|
||||||
|
aliases: vec![],
|
||||||
|
f: iamb_space,
|
||||||
|
});
|
||||||
cmds.add_command(ProgramCommand {
|
cmds.add_command(ProgramCommand {
|
||||||
name: "spaces".into(),
|
name: "spaces".into(),
|
||||||
aliases: vec![],
|
aliases: vec![],
|
||||||
|
@ -725,7 +815,7 @@ pub fn setup_commands() -> ProgramCommands {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use matrix_sdk::ruma::user_id;
|
use matrix_sdk::ruma::{room_id, user_id};
|
||||||
use modalkit::actions::WindowAction;
|
use modalkit::actions::WindowAction;
|
||||||
use modalkit::editing::context::EditContext;
|
use modalkit::editing::context::EditContext;
|
||||||
|
|
||||||
|
@ -1067,6 +1157,103 @@ mod tests {
|
||||||
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_id_show() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = EditContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room id show", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Show(RoomField::Id);
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room id show foo", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_space_child() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = EditContext::default();
|
||||||
|
|
||||||
|
let cmd = "space";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let cmd = "space ++foo bar baz";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let cmd = "space child foo";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_space_child_set() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = EditContext::default();
|
||||||
|
|
||||||
|
let cmd = "space child set !roomid:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone()).unwrap();
|
||||||
|
let act = SpaceAction::SetChild(room_id!("!roomid:example.org").to_owned(), None, false);
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let cmd = "space child set ++order=abcd ++suggested !roomid:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone()).unwrap();
|
||||||
|
let act = SpaceAction::SetChild(
|
||||||
|
room_id!("!roomid:example.org").to_owned(),
|
||||||
|
Some("abcd".into()),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let cmd = "space child set ++order=abcd ++order=1234 !roomid:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
Err(CommandError::Error("Multiple ++order arguments are not allowed".into()))
|
||||||
|
);
|
||||||
|
|
||||||
|
let cmd = "space child set !roomid:example.org !otherroom:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::Error("Multiple room arguments are not allowed".into())));
|
||||||
|
|
||||||
|
let cmd = "space child set ++foo=abcd !roomid:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let cmd = "space child set ++foo !roomid:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let cmd = "space child ++order=abcd ++suggested set !roomid:example.org";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let cmd = "space child set foo";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::Error("Invalid room id specified".into())));
|
||||||
|
|
||||||
|
let cmd = "space child set";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::Error("Must specify a room to add".into())));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_space_child_remove() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = EditContext::default();
|
||||||
|
|
||||||
|
let cmd = "space child remove";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone()).unwrap();
|
||||||
|
let act = SpaceAction::RemoveChild;
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let cmd = "space child remove foo";
|
||||||
|
let res = cmds.input_cmd(cmd, ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cmd_invite() {
|
fn test_cmd_invite() {
|
||||||
let mut cmds = setup_commands();
|
let mut cmds = setup_commands();
|
||||||
|
|
|
@ -557,6 +557,9 @@ impl Application {
|
||||||
IambAction::Message(act) => {
|
IambAction::Message(act) => {
|
||||||
self.screen.current_window_mut()?.message_command(act, ctx, store).await?
|
self.screen.current_window_mut()?.message_command(act, ctx, store).await?
|
||||||
},
|
},
|
||||||
|
IambAction::Space(act) => {
|
||||||
|
self.screen.current_window_mut()?.space_command(act, ctx, store).await?
|
||||||
|
},
|
||||||
IambAction::Room(act) => {
|
IambAction::Room(act) => {
|
||||||
let acts = self.screen.current_window_mut()?.room_command(act, ctx, store).await?;
|
let acts = self.screen.current_window_mut()?.room_command(act, ctx, store).await?;
|
||||||
self.action_prepend(acts);
|
self.action_prepend(acts);
|
||||||
|
|
|
@ -76,6 +76,7 @@ use crate::base::{
|
||||||
SortFieldRoom,
|
SortFieldRoom,
|
||||||
SortFieldUser,
|
SortFieldUser,
|
||||||
SortOrder,
|
SortOrder,
|
||||||
|
SpaceAction,
|
||||||
UnreadInfo,
|
UnreadInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -360,6 +361,19 @@ impl IambWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn space_command(
|
||||||
|
&mut self,
|
||||||
|
act: SpaceAction,
|
||||||
|
ctx: ProgramContext,
|
||||||
|
store: &mut ProgramStore,
|
||||||
|
) -> IambResult<EditInfo> {
|
||||||
|
if let IambWindow::Room(w) = self {
|
||||||
|
w.space_command(act, ctx, store).await
|
||||||
|
} else {
|
||||||
|
return Err(IambError::NoSelectedRoom.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn room_command(
|
pub async fn room_command(
|
||||||
&mut self,
|
&mut self,
|
||||||
act: RoomAction,
|
act: RoomAction,
|
||||||
|
|
|
@ -66,6 +66,7 @@ use crate::base::{
|
||||||
RoomAction,
|
RoomAction,
|
||||||
RoomField,
|
RoomField,
|
||||||
SendAction,
|
SendAction,
|
||||||
|
SpaceAction,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::chat::ChatState;
|
use self::chat::ChatState;
|
||||||
|
@ -214,6 +215,18 @@ impl RoomState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn space_command(
|
||||||
|
&mut self,
|
||||||
|
act: SpaceAction,
|
||||||
|
ctx: ProgramContext,
|
||||||
|
store: &mut ProgramStore,
|
||||||
|
) -> IambResult<EditInfo> {
|
||||||
|
match self {
|
||||||
|
RoomState::Space(space) => space.space_command(act, ctx, store).await,
|
||||||
|
RoomState::Chat(_) => Err(IambError::NoSelectedSpace.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn send_command(
|
pub async fn send_command(
|
||||||
&mut self,
|
&mut self,
|
||||||
act: SendAction,
|
act: SendAction,
|
||||||
|
@ -464,6 +477,9 @@ impl RoomState {
|
||||||
RoomField::Aliases => {
|
RoomField::Aliases => {
|
||||||
// This never happens, aliases is only used for showing
|
// This never happens, aliases is only used for showing
|
||||||
},
|
},
|
||||||
|
RoomField::Id => {
|
||||||
|
// This never happens, id is only used for showing
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
|
@ -559,6 +575,9 @@ impl RoomState {
|
||||||
RoomField::Aliases => {
|
RoomField::Aliases => {
|
||||||
// This will not happen, you cannot unset all aliases
|
// This will not happen, you cannot unset all aliases
|
||||||
},
|
},
|
||||||
|
RoomField::Id => {
|
||||||
|
// This never happens, id is only used for showing
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
|
@ -574,6 +593,10 @@ impl RoomState {
|
||||||
let visibility = room.history_visibility();
|
let visibility = room.history_visibility();
|
||||||
format!("Room history visibility: {visibility}")
|
format!("Room history visibility: {visibility}")
|
||||||
},
|
},
|
||||||
|
RoomField::Id => {
|
||||||
|
let id = room.room_id();
|
||||||
|
format!("Room identifier: {id}")
|
||||||
|
},
|
||||||
RoomField::Name => {
|
RoomField::Name => {
|
||||||
match room.name() {
|
match room.name() {
|
||||||
None => "Room has no name".into(),
|
None => "Room has no name".into(),
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use matrix_sdk::ruma::events::space::child::SpaceChildEventContent;
|
||||||
|
use matrix_sdk::ruma::events::StateEventType;
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
room::Room as MatrixRoom,
|
room::Room as MatrixRoom,
|
||||||
ruma::{OwnedRoomId, RoomId},
|
ruma::{OwnedRoomId, RoomId},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use modalkit::prelude::{EditInfo, InfoMessage};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
layout::Rect,
|
layout::Rect,
|
||||||
|
@ -22,9 +25,18 @@ use modalkit_ratatui::{
|
||||||
WindowOps,
|
WindowOps,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::base::{IambBufferId, IambInfo, ProgramStore, RoomFocus};
|
use crate::base::{
|
||||||
|
IambBufferId,
|
||||||
|
IambError,
|
||||||
|
IambInfo,
|
||||||
|
IambResult,
|
||||||
|
ProgramContext,
|
||||||
|
ProgramStore,
|
||||||
|
RoomFocus,
|
||||||
|
SpaceAction,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::windows::{room_fields_cmp, RoomItem};
|
use crate::windows::{room_fields_cmp, RoomItem, RoomLikeItem};
|
||||||
|
|
||||||
const SPACE_HIERARCHY_DEBOUNCE: Duration = Duration::from_secs(5);
|
const SPACE_HIERARCHY_DEBOUNCE: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
|
@ -68,6 +80,71 @@ impl SpaceState {
|
||||||
last_fetch: self.last_fetch,
|
last_fetch: self.last_fetch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn space_command(
|
||||||
|
&mut self,
|
||||||
|
act: SpaceAction,
|
||||||
|
_: ProgramContext,
|
||||||
|
store: &mut ProgramStore,
|
||||||
|
) -> IambResult<EditInfo> {
|
||||||
|
match act {
|
||||||
|
SpaceAction::SetChild(child_id, order, suggested) => {
|
||||||
|
if !self
|
||||||
|
.room
|
||||||
|
.can_user_send_state(
|
||||||
|
&store.application.settings.profile.user_id,
|
||||||
|
StateEventType::SpaceChild,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?
|
||||||
|
{
|
||||||
|
return Err(IambError::InsufficientPermission.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let via = self.room.route().await.map_err(IambError::from)?;
|
||||||
|
let mut ev = SpaceChildEventContent::new(via);
|
||||||
|
ev.order = order;
|
||||||
|
ev.suggested = suggested;
|
||||||
|
let _ = self
|
||||||
|
.room
|
||||||
|
.send_state_event_for_key(&child_id, ev)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
|
||||||
|
Ok(InfoMessage::from("Space updated").into())
|
||||||
|
},
|
||||||
|
SpaceAction::RemoveChild => {
|
||||||
|
let space = self.list.get().ok_or(IambError::NoSelectedRoomOrSpaceItem)?;
|
||||||
|
if !self
|
||||||
|
.room
|
||||||
|
.can_user_send_state(
|
||||||
|
&store.application.settings.profile.user_id,
|
||||||
|
StateEventType::SpaceChild,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?
|
||||||
|
{
|
||||||
|
return Err(IambError::InsufficientPermission.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let ev = SpaceChildEventContent::new(vec![]);
|
||||||
|
let event_id = self
|
||||||
|
.room
|
||||||
|
.send_state_event_for_key(&space.room_id().to_owned(), ev)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
|
||||||
|
// Fix for element (see https://github.com/element-hq/element-web/issues/29606)
|
||||||
|
let _ = self
|
||||||
|
.room
|
||||||
|
.redact(&event_id.event_id, Some("workaround for element bug"), None)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
|
||||||
|
Ok(InfoMessage::from("Room removed").into())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalCursor for SpaceState {
|
impl TerminalCursor for SpaceState {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue