From 3003f0a5286556bb0108ca3693d60f9b47ff078c Mon Sep 17 00:00:00 2001 From: Ulyssa Date: Sun, 18 Aug 2024 00:33:45 -0700 Subject: [PATCH] Add command for setting room history visibility (#328) --- src/base.rs | 7 +++++++ src/commands.rs | 12 ++++++++++++ src/windows/room/mod.rs | 29 +++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/base.rs b/src/base.rs index e5f6a62..420d4fe 100644 --- a/src/base.rs +++ b/src/base.rs @@ -369,6 +369,9 @@ impl<'de> Visitor<'de> for SortUserVisitor { /// A room property. #[derive(Clone, Debug, Eq, PartialEq)] pub enum RoomField { + /// The room's history visibility. + History, + /// The room name. Name, @@ -636,6 +639,10 @@ pub type MessageReactions = HashMap; /// Errors encountered during application use. #[derive(thiserror::Error, Debug)] pub enum IambError { + /// An invalid history visibility was specified. + #[error("Invalid history visibility setting: {0}")] + InvalidHistoryVisibility(String), + /// An invalid notification level was specified. #[error("Invalid notification level: {0}")] InvalidNotificationLevel(String), diff --git a/src/commands.rs b/src/commands.rs index 7c5aa5a..913e5f6 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -423,6 +423,18 @@ fn iamb_room(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult { RoomAction::MemberUpdate(MemberUpdateAction::Unban, u.into(), r, desc.bang).into() }, + // :room history set + ("history", "set", Some(s)) => RoomAction::Set(RoomField::History, s).into(), + ("history", "set", None) => return Result::Err(CommandError::InvalidArgument), + + // :room history unset + ("history", "unset", None) => RoomAction::Unset(RoomField::History).into(), + ("history", "unset", Some(_)) => return Result::Err(CommandError::InvalidArgument), + + // :room history show + ("history", "show", None) => RoomAction::Show(RoomField::History).into(), + ("history", "show", Some(_)) => return Result::Err(CommandError::InvalidArgument), + // :room name set ("name", "set", Some(s)) => RoomAction::Set(RoomField::Name, s).into(), ("name", "set", None) => return Result::Err(CommandError::InvalidArgument), diff --git a/src/windows/room/mod.rs b/src/windows/room/mod.rs index 0700746..f959172 100644 --- a/src/windows/room/mod.rs +++ b/src/windows/room/mod.rs @@ -15,6 +15,7 @@ use matrix_sdk::{ events::{ room::{ canonical_alias::RoomCanonicalAliasEventContent, + history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent}, name::RoomNameEventContent, topic::RoomTopicEventContent, }, @@ -98,6 +99,20 @@ fn notification_mode(name: impl Into) -> IambResult) -> IambResult { + let name = name.into(); + + let mode = match name.to_lowercase().as_str() { + "invited" => HistoryVisibility::Invited, + "joined" => HistoryVisibility::Joined, + "shared" => HistoryVisibility::Shared, + "world" | "world_readable" => HistoryVisibility::WorldReadable, + _ => return Err(IambError::InvalidHistoryVisibility(name).into()), + }; + + Ok(mode) +} + /// State for a Matrix room or space. /// /// Since spaces function as special rooms within Matrix, we wrap their window state together, so @@ -339,6 +354,11 @@ impl RoomState { .ok_or(UIError::Application(IambError::NotJoined))?; match field { + RoomField::History => { + let visibility = hist_visibility_mode(value)?; + let ev = RoomHistoryVisibilityEventContent::new(visibility); + let _ = room.send_state_event(ev).await.map_err(IambError::from)?; + }, RoomField::Name => { let ev = RoomNameEventContent::new(value); let _ = room.send_state_event(ev).await.map_err(IambError::from)?; @@ -455,6 +475,11 @@ impl RoomState { .ok_or(UIError::Application(IambError::NotJoined))?; match field { + RoomField::History => { + let visibility = HistoryVisibility::Joined; + let ev = RoomHistoryVisibilityEventContent::new(visibility); + let _ = room.send_state_event(ev).await.map_err(IambError::from)?; + }, RoomField::Name => { let ev = RoomNameEventContent::new("".into()); let _ = room.send_state_event(ev).await.map_err(IambError::from)?; @@ -545,6 +570,10 @@ impl RoomState { .ok_or(UIError::Application(IambError::NotJoined))?; let msg = match field { + RoomField::History => { + let visibility = room.history_visibility(); + format!("Room history visibility: {visibility}") + }, RoomField::Name => { match room.name() { None => "Room has no name".into(),