mirror of
https://github.com/ulyssa/iamb.git
synced 2024-08-15 14:50:48 +03:00
Merge 069740419b
into 497be7f099
This commit is contained in:
commit
7eb6f93751
12
docs/iamb.1
12
docs/iamb.1
@ -130,6 +130,18 @@ Remove a tag from the currently focused room.
|
|||||||
Set the topic of the currently focused room.
|
Set the topic of the currently focused room.
|
||||||
.It Sy ":room topic unset"
|
.It Sy ":room topic unset"
|
||||||
Unset the topic of the currently focused room.
|
Unset the topic of the currently focused room.
|
||||||
|
.It Sy ":room alias set [alias]"
|
||||||
|
Create and point the given alias to the room.
|
||||||
|
.It Sy ":room alias unset [alias]"
|
||||||
|
Delete the provided alias from the room's alternative alias list.
|
||||||
|
.It Sy ":room alias show"
|
||||||
|
Show alternative aliases to the room, if any are set.
|
||||||
|
.It Sy ":room canonicalalias set [alias]"
|
||||||
|
Set the room's canonical alias to the one provided, deleting the previous one.
|
||||||
|
.It Sy ":room canonicalalias unset [alias]"
|
||||||
|
Delete the room's canonical alias.
|
||||||
|
.It Sy ":room canonicalalias show"
|
||||||
|
Show the room's canonical alias, if any is set.
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh "WINDOW COMMANDS"
|
.Sh "WINDOW COMMANDS"
|
||||||
|
16
src/base.rs
16
src/base.rs
@ -369,6 +369,15 @@ pub enum RoomField {
|
|||||||
|
|
||||||
/// The room topic.
|
/// The room topic.
|
||||||
Topic,
|
Topic,
|
||||||
|
|
||||||
|
/// The room's entire list of alternative aliases.
|
||||||
|
Aliases,
|
||||||
|
|
||||||
|
/// A specific alternative alias to the room.
|
||||||
|
Alias(String),
|
||||||
|
|
||||||
|
/// The room's canonical alias.
|
||||||
|
CanonicalAlias,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An action that operates on a focused room.
|
/// An action that operates on a focused room.
|
||||||
@ -397,6 +406,9 @@ pub enum RoomAction {
|
|||||||
|
|
||||||
/// Unset a room property.
|
/// Unset a room property.
|
||||||
Unset(RoomField),
|
Unset(RoomField),
|
||||||
|
|
||||||
|
/// List the values in a list room property.
|
||||||
|
Show(RoomField),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An action that sends a message to a room.
|
/// An action that sends a message to a room.
|
||||||
@ -659,6 +671,10 @@ pub enum IambError {
|
|||||||
#[error("Unknown room identifier: {0}")]
|
#[error("Unknown room identifier: {0}")]
|
||||||
UnknownRoom(OwnedRoomId),
|
UnknownRoom(OwnedRoomId),
|
||||||
|
|
||||||
|
/// An invalid room alias id was specified.
|
||||||
|
#[error("Invalid room alias id: {0}")]
|
||||||
|
InvalidRoomAliasId(#[from] matrix_sdk::ruma::IdParseError),
|
||||||
|
|
||||||
/// A failure occurred during verification.
|
/// A failure occurred during verification.
|
||||||
#[error("Verification request error: {0}")]
|
#[error("Verification request error: {0}")]
|
||||||
VerificationRequestError(#[from] matrix_sdk::encryption::identities::RequestVerificationError),
|
VerificationRequestError(#[from] matrix_sdk::encryption::identities::RequestVerificationError),
|
||||||
|
@ -454,6 +454,30 @@ fn iamb_room(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
|||||||
("tag", "unset", Some(s)) => RoomAction::Unset(RoomField::Tag(tag_name(s)?)).into(),
|
("tag", "unset", Some(s)) => RoomAction::Unset(RoomField::Tag(tag_name(s)?)).into(),
|
||||||
("tag", "unset", None) => return Result::Err(CommandError::InvalidArgument),
|
("tag", "unset", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room aliases show
|
||||||
|
("alias", "show", None) => RoomAction::Show(RoomField::Aliases).into(),
|
||||||
|
("alias", "show", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room aliases unset <alias>
|
||||||
|
("alias", "unset", Some(s)) => RoomAction::Unset(RoomField::Alias(s)).into(),
|
||||||
|
("alias", "unset", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room aliases set <alias>
|
||||||
|
("alias", "set", Some(s)) => RoomAction::Set(RoomField::Alias(s), "".into()).into(),
|
||||||
|
("alias", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room canonicalalias show
|
||||||
|
("canonicalalias", "show", None) => RoomAction::Show(RoomField::CanonicalAlias).into(),
|
||||||
|
("canonicalalias", "show", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room canonicalalias set
|
||||||
|
("canonicalalias", "set", Some(s)) => RoomAction::Set(RoomField::CanonicalAlias, s).into(),
|
||||||
|
("canonicalalias", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room canonicalalias unset
|
||||||
|
("canonicalalias", "unset", None) => RoomAction::Unset(RoomField::CanonicalAlias).into(),
|
||||||
|
("canonicalalias", "unset", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
_ => return Result::Err(CommandError::InvalidArgument),
|
_ => return Result::Err(CommandError::InvalidArgument),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,11 +2,25 @@
|
|||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
room::Room as MatrixRoom,
|
room::Room as MatrixRoom,
|
||||||
ruma::{
|
ruma::{
|
||||||
|
api::client::{
|
||||||
|
alias::{
|
||||||
|
create_alias::v3::Request as CreateAliasRequest,
|
||||||
|
delete_alias::v3::Request as DeleteAliasRequest,
|
||||||
|
get_alias::v3::Request as GetAliasRequest,
|
||||||
|
},
|
||||||
|
error::ErrorKind as ClientApiErrorKind,
|
||||||
|
},
|
||||||
events::{
|
events::{
|
||||||
room::{name::RoomNameEventContent, topic::RoomTopicEventContent},
|
room::{
|
||||||
|
canonical_alias::RoomCanonicalAliasEventContent,
|
||||||
|
name::RoomNameEventContent,
|
||||||
|
topic::RoomTopicEventContent,
|
||||||
|
},
|
||||||
tag::{TagInfo, Tags},
|
tag::{TagInfo, Tags},
|
||||||
},
|
},
|
||||||
OwnedEventId,
|
OwnedEventId,
|
||||||
|
OwnedRoomAliasId,
|
||||||
|
RoomAliasId,
|
||||||
RoomId,
|
RoomId,
|
||||||
},
|
},
|
||||||
DisplayName,
|
DisplayName,
|
||||||
@ -53,6 +67,8 @@ use crate::base::{
|
|||||||
use self::chat::ChatState;
|
use self::chat::ChatState;
|
||||||
use self::space::{Space, SpaceState};
|
use self::space::{Space, SpaceState};
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
mod chat;
|
mod chat;
|
||||||
mod scrollback;
|
mod scrollback;
|
||||||
mod space;
|
mod space;
|
||||||
@ -182,7 +198,7 @@ impl RoomState {
|
|||||||
pub async fn room_command(
|
pub async fn room_command(
|
||||||
&mut self,
|
&mut self,
|
||||||
act: RoomAction,
|
act: RoomAction,
|
||||||
_: ProgramContext,
|
ctx: ProgramContext,
|
||||||
store: &mut ProgramStore,
|
store: &mut ProgramStore,
|
||||||
) -> IambResult<Vec<(Action<IambInfo>, ProgramContext)>> {
|
) -> IambResult<Vec<(Action<IambInfo>, ProgramContext)>> {
|
||||||
match act {
|
match act {
|
||||||
@ -280,6 +296,85 @@ impl RoomState {
|
|||||||
let ev = RoomTopicEventContent::new(value);
|
let ev = RoomTopicEventContent::new(value);
|
||||||
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
},
|
},
|
||||||
|
RoomField::CanonicalAlias => {
|
||||||
|
let mut ev = RoomCanonicalAliasEventContent::new();
|
||||||
|
let rai: &RoomAliasId =
|
||||||
|
<&RoomAliasId>::try_from(value.as_str()).map_err(IambError::from)?;
|
||||||
|
let orai: OwnedRoomAliasId = rai.into();
|
||||||
|
let client = &mut store.application.worker.client;
|
||||||
|
|
||||||
|
// If the room's alias is already that, ignore it
|
||||||
|
if let Some(ex_orai) = room.canonical_alias() {
|
||||||
|
if ex_orai == orai {
|
||||||
|
return Ok(vec![]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the room alias does not exist on the server, create it
|
||||||
|
let alias_req = GetAliasRequest::new(orai.clone());
|
||||||
|
if let Err(alias_err) = client.send(alias_req, None).await {
|
||||||
|
let errkind = alias_err.client_api_error_kind();
|
||||||
|
if errkind.is_none() ||
|
||||||
|
matches!(errkind.unwrap(), ClientApiErrorKind::NotFound)
|
||||||
|
{
|
||||||
|
// Create it
|
||||||
|
let alias_create_req =
|
||||||
|
CreateAliasRequest::new(orai.clone(), room.room_id().into());
|
||||||
|
client
|
||||||
|
.send(alias_create_req, None)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// At this point the room alias definitely exists
|
||||||
|
// There is a previous one however
|
||||||
|
let alias_to_destroy = room.canonical_alias();
|
||||||
|
ev.alias = Some(orai);
|
||||||
|
ev.alt_aliases = room.alt_aliases();
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
if let Some(old_can) = alias_to_destroy {
|
||||||
|
let del_req = DeleteAliasRequest::new(old_can);
|
||||||
|
let _ = client.send(del_req, None).await.map_err(IambError::from)?;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RoomField::Alias(alias) => {
|
||||||
|
let rai: &RoomAliasId =
|
||||||
|
<&RoomAliasId>::try_from(alias.as_str()).map_err(IambError::from)?;
|
||||||
|
let orai: OwnedRoomAliasId = rai.into();
|
||||||
|
let alt_aliases = room.alt_aliases();
|
||||||
|
if !alt_aliases.contains(&orai) {
|
||||||
|
let client = &mut store.application.worker.client;
|
||||||
|
let mut ev = RoomCanonicalAliasEventContent::new();
|
||||||
|
ev.alias = room.canonical_alias();
|
||||||
|
ev.alt_aliases = alt_aliases;
|
||||||
|
ev.alt_aliases.push(orai.clone());
|
||||||
|
|
||||||
|
// If the room alias does not exist on the server, create it
|
||||||
|
let alias_req = GetAliasRequest::new(orai.clone());
|
||||||
|
if let Err(alias_err) = client.send(alias_req, None).await {
|
||||||
|
let errkind = alias_err.client_api_error_kind();
|
||||||
|
if errkind.is_none() ||
|
||||||
|
matches!(errkind.unwrap(), ClientApiErrorKind::NotFound)
|
||||||
|
{
|
||||||
|
// Create it
|
||||||
|
let alias_create_req = CreateAliasRequest::new(
|
||||||
|
orai.clone(),
|
||||||
|
room.room_id().into(),
|
||||||
|
);
|
||||||
|
client
|
||||||
|
.send(alias_create_req, None)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RoomField::Aliases => {
|
||||||
|
// This never happens, aliases is only used for showing
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
@ -302,10 +397,99 @@ impl RoomState {
|
|||||||
let ev = RoomTopicEventContent::new("".into());
|
let ev = RoomTopicEventContent::new("".into());
|
||||||
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
},
|
},
|
||||||
|
RoomField::CanonicalAlias => {
|
||||||
|
let mut ev = RoomCanonicalAliasEventContent::new();
|
||||||
|
ev.alias = None;
|
||||||
|
ev.alt_aliases = room.alt_aliases();
|
||||||
|
let alias_to_destroy = room.canonical_alias();
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
if let Some(old_can) = alias_to_destroy {
|
||||||
|
let del_req = DeleteAliasRequest::new(old_can);
|
||||||
|
let _ = store
|
||||||
|
.application
|
||||||
|
.worker
|
||||||
|
.client
|
||||||
|
.send(del_req, None)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RoomField::Alias(alias) => {
|
||||||
|
let rai: &RoomAliasId =
|
||||||
|
<&RoomAliasId>::try_from(alias.as_str()).map_err(IambError::from)?;
|
||||||
|
let orai: OwnedRoomAliasId = rai.into();
|
||||||
|
let alt_aliases = room.alt_aliases();
|
||||||
|
if alt_aliases.contains(&orai) {
|
||||||
|
let mut ev = RoomCanonicalAliasEventContent::new();
|
||||||
|
ev.alias = room.canonical_alias();
|
||||||
|
ev.alt_aliases = alt_aliases;
|
||||||
|
ev.alt_aliases.retain(|in_orai| *in_orai != orai);
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
let del_req = DeleteAliasRequest::new(orai);
|
||||||
|
let _ = store
|
||||||
|
.application
|
||||||
|
.worker
|
||||||
|
.client
|
||||||
|
.send(del_req, None)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RoomField::Aliases => {
|
||||||
|
// This will not happen, you cannot unset all aliases
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
},
|
},
|
||||||
|
RoomAction::Show(field) => {
|
||||||
|
let room = store
|
||||||
|
.application
|
||||||
|
.get_joined_room(self.id())
|
||||||
|
.ok_or(UIError::Application(IambError::NotJoined))?;
|
||||||
|
|
||||||
|
let action;
|
||||||
|
match field {
|
||||||
|
RoomField::Name => {
|
||||||
|
action = InfoMessage::Message(match room.name() {
|
||||||
|
None => "Room has no name".into(),
|
||||||
|
Some(name) => format!("Room name: \"{name}\"."),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
RoomField::Topic => {
|
||||||
|
action = InfoMessage::Message(match room.topic() {
|
||||||
|
None => "Room has no topic".into(),
|
||||||
|
Some(topic) => format!("Room topic: \"{topic}\"."),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
RoomField::Aliases => {
|
||||||
|
let aliases = room.alt_aliases();
|
||||||
|
action = InfoMessage::Message(match aliases.is_empty() {
|
||||||
|
true => "No alternative aliases in room.".into(),
|
||||||
|
false => {
|
||||||
|
format!(
|
||||||
|
"Alternative aliases: {}.",
|
||||||
|
aliases
|
||||||
|
.iter()
|
||||||
|
.map(OwnedRoomAliasId::to_string)
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
RoomField::CanonicalAlias => {
|
||||||
|
action = InfoMessage::Message(match room.canonical_alias() {
|
||||||
|
None => "No canonical alias for room.".into(),
|
||||||
|
Some(can) => format!("Canonical alias: {can}."),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
RoomField::Tag(_) | RoomField::Alias(_) => {
|
||||||
|
unreachable!("Nothing should ever enter this code path");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Ok(vec![(Action::ShowInfoMessage(action), ctx)])
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user