mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-20 05:39:52 -07:00
Support displaying and editing room tags (#15)
This commit is contained in:
parent
4f2261e66f
commit
a6888bbc93
8 changed files with 443 additions and 109 deletions
|
@ -49,7 +49,7 @@ two other TUI clients and Element Web:
|
||||||
| --------------------------------------- | :---------- | :------: | :--------------: | :-----------------: |
|
| --------------------------------------- | :---------- | :------: | :--------------: | :-----------------: |
|
||||||
| Room directory | ❌ ([#14]) | ❌ | ✔️ | ✔️ |
|
| Room directory | ❌ ([#14]) | ❌ | ✔️ | ✔️ |
|
||||||
| Room tag showing | ❌ ([#15]) | ✔️ | ❌ | ✔️ |
|
| Room tag showing | ❌ ([#15]) | ✔️ | ❌ | ✔️ |
|
||||||
| Room tag editing | ❌ ([#15]) | ✔️ | ❌ | ✔️ |
|
| Room tag editing | ✔️ | ✔️ | ❌ | ✔️ |
|
||||||
| Search joined rooms | ❌ ([#16]) | ✔️ | ❌ | ✔️ |
|
| Search joined rooms | ❌ ([#16]) | ✔️ | ❌ | ✔️ |
|
||||||
| Room user list | ✔️ | ✔️ | ✔️ | ✔️ |
|
| Room user list | ✔️ | ✔️ | ✔️ | ✔️ |
|
||||||
| Display Room Description | ✔️ | ✔️ | ✔️ | ✔️ |
|
| Display Room Description | ✔️ | ✔️ | ✔️ | ✔️ |
|
||||||
|
|
29
src/base.rs
29
src/base.rs
|
@ -8,6 +8,7 @@ use tracing::warn;
|
||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
encryption::verification::SasVerification,
|
encryption::verification::SasVerification,
|
||||||
|
room::Joined,
|
||||||
ruma::{
|
ruma::{
|
||||||
events::room::message::{
|
events::room::message::{
|
||||||
OriginalRoomMessageEvent,
|
OriginalRoomMessageEvent,
|
||||||
|
@ -16,6 +17,7 @@ use matrix_sdk::{
|
||||||
RoomMessageEvent,
|
RoomMessageEvent,
|
||||||
RoomMessageEventContent,
|
RoomMessageEventContent,
|
||||||
},
|
},
|
||||||
|
events::tag::{TagName, Tags},
|
||||||
EventId,
|
EventId,
|
||||||
OwnedEventId,
|
OwnedEventId,
|
||||||
OwnedRoomId,
|
OwnedRoomId,
|
||||||
|
@ -94,9 +96,10 @@ pub enum MessageAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum SetRoomField {
|
pub enum RoomField {
|
||||||
Name(String),
|
Name,
|
||||||
Topic(String),
|
Tag(TagName),
|
||||||
|
Topic,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -105,13 +108,8 @@ pub enum RoomAction {
|
||||||
InviteReject,
|
InviteReject,
|
||||||
InviteSend(OwnedUserId),
|
InviteSend(OwnedUserId),
|
||||||
Members(Box<CommandContext<ProgramContext>>),
|
Members(Box<CommandContext<ProgramContext>>),
|
||||||
Set(SetRoomField),
|
Set(RoomField, String),
|
||||||
}
|
Unset(RoomField),
|
||||||
|
|
||||||
impl From<SetRoomField> for RoomAction {
|
|
||||||
fn from(act: SetRoomField) -> Self {
|
|
||||||
RoomAction::Set(act)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -194,6 +192,12 @@ impl ApplicationAction for IambAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RoomAction> for ProgramAction {
|
||||||
|
fn from(act: RoomAction) -> 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)
|
||||||
|
@ -277,6 +281,7 @@ pub enum RoomFetchStatus {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RoomInfo {
|
pub struct RoomInfo {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
pub tags: Option<Tags>,
|
||||||
|
|
||||||
pub keys: HashMap<OwnedEventId, MessageKey>,
|
pub keys: HashMap<OwnedEventId, MessageKey>,
|
||||||
pub messages: Messages,
|
pub messages: Messages,
|
||||||
|
@ -437,6 +442,10 @@ impl ChatStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_joined_room(&self, room_id: &RoomId) -> Option<Joined> {
|
||||||
|
self.worker.client.get_joined_room(room_id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_room_title(&self, room_id: &RoomId) -> String {
|
pub fn get_room_title(&self, room_id: &RoomId) -> String {
|
||||||
self.rooms
|
self.rooms
|
||||||
.get(room_id)
|
.get(room_id)
|
||||||
|
|
280
src/commands.rs
280
src/commands.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use matrix_sdk::ruma::OwnedUserId;
|
use matrix_sdk::ruma::{events::tag::TagName, OwnedUserId};
|
||||||
|
|
||||||
use modalkit::{
|
use modalkit::{
|
||||||
editing::base::OpenTarget,
|
editing::base::OpenTarget,
|
||||||
|
@ -17,14 +17,38 @@ use crate::base::{
|
||||||
ProgramCommands,
|
ProgramCommands,
|
||||||
ProgramContext,
|
ProgramContext,
|
||||||
RoomAction,
|
RoomAction,
|
||||||
|
RoomField,
|
||||||
SendAction,
|
SendAction,
|
||||||
SetRoomField,
|
|
||||||
VerifyAction,
|
VerifyAction,
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProgContext = CommandContext<ProgramContext>;
|
type ProgContext = CommandContext<ProgramContext>;
|
||||||
type ProgResult = CommandResult<ProgramCommand>;
|
type ProgResult = CommandResult<ProgramCommand>;
|
||||||
|
|
||||||
|
/// Convert strings the user types into a tag name.
|
||||||
|
fn tag_name(name: String) -> Result<TagName, CommandError> {
|
||||||
|
let tag = match name.as_str() {
|
||||||
|
"fav" | "favorite" | "favourite" | "m.favourite" => TagName::Favorite,
|
||||||
|
"low" | "lowpriority" | "low_priority" | "low-priority" | "m.lowpriority" => {
|
||||||
|
TagName::LowPriority
|
||||||
|
},
|
||||||
|
"servernotice" | "server_notice" | "server-notice" | "m.server_notice" => {
|
||||||
|
TagName::ServerNotice
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
if let Ok(tag) = name.parse() {
|
||||||
|
TagName::User(tag)
|
||||||
|
} else {
|
||||||
|
let msg = format!("Invalid user tag name: {}", name);
|
||||||
|
|
||||||
|
return Err(CommandError::Error(msg));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(tag)
|
||||||
|
}
|
||||||
|
|
||||||
fn iamb_invite(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
fn iamb_invite(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
let args = desc.arg.strings()?;
|
let args = desc.arg.strings()?;
|
||||||
|
|
||||||
|
@ -225,22 +249,46 @@ fn iamb_join(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
return Ok(step);
|
return Ok(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iamb_set(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
fn iamb_room(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
let mut args = desc.arg.strings()?;
|
let mut args = desc.arg.strings()?;
|
||||||
|
|
||||||
if args.len() != 2 {
|
if args.len() < 2 {
|
||||||
return Result::Err(CommandError::InvalidArgument);
|
return Result::Err(CommandError::InvalidArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
let field = args.remove(0);
|
let field = args.remove(0);
|
||||||
let value = args.remove(0);
|
let action = args.remove(0);
|
||||||
|
|
||||||
let act: IambAction = match field.as_str() {
|
if args.len() > 1 {
|
||||||
"room.name" => RoomAction::Set(SetRoomField::Name(value)).into(),
|
|
||||||
"room.topic" => RoomAction::Set(SetRoomField::Topic(value)).into(),
|
|
||||||
_ => {
|
|
||||||
return Result::Err(CommandError::InvalidArgument);
|
return Result::Err(CommandError::InvalidArgument);
|
||||||
},
|
}
|
||||||
|
|
||||||
|
let act: IambAction = match (field.as_str(), action.as_str(), args.pop()) {
|
||||||
|
// :room name set <room-name>
|
||||||
|
("name", "set", Some(s)) => RoomAction::Set(RoomField::Name, s).into(),
|
||||||
|
("name", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room name unset
|
||||||
|
("name", "unset", None) => RoomAction::Unset(RoomField::Name).into(),
|
||||||
|
("name", "unset", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room topic set <topic>
|
||||||
|
("topic", "set", Some(s)) => RoomAction::Set(RoomField::Topic, s).into(),
|
||||||
|
("topic", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room topic unset
|
||||||
|
("topic", "unset", None) => RoomAction::Unset(RoomField::Topic).into(),
|
||||||
|
("topic", "unset", Some(_)) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room tag set <tag-name>
|
||||||
|
("tag", "set", Some(s)) => RoomAction::Set(RoomField::Tag(tag_name(s)?), "".into()).into(),
|
||||||
|
("tag", "set", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
// :room tag unset <tag-name>
|
||||||
|
("tag", "unset", Some(s)) => RoomAction::Unset(RoomField::Tag(tag_name(s)?)).into(),
|
||||||
|
("tag", "unset", None) => return Result::Err(CommandError::InvalidArgument),
|
||||||
|
|
||||||
|
_ => return Result::Err(CommandError::InvalidArgument),
|
||||||
};
|
};
|
||||||
|
|
||||||
let step = CommandStep::Continue(act.into(), ctx.context.take());
|
let step = CommandStep::Continue(act.into(), ctx.context.take());
|
||||||
|
@ -287,7 +335,7 @@ fn add_iamb_commands(cmds: &mut ProgramCommands) {
|
||||||
cmds.add_command(ProgramCommand { names: vec!["redact".into()], f: iamb_redact });
|
cmds.add_command(ProgramCommand { names: vec!["redact".into()], f: iamb_redact });
|
||||||
cmds.add_command(ProgramCommand { names: vec!["reply".into()], f: iamb_reply });
|
cmds.add_command(ProgramCommand { names: vec!["reply".into()], f: iamb_reply });
|
||||||
cmds.add_command(ProgramCommand { names: vec!["rooms".into()], f: iamb_rooms });
|
cmds.add_command(ProgramCommand { names: vec!["rooms".into()], f: iamb_rooms });
|
||||||
cmds.add_command(ProgramCommand { names: vec!["set".into()], f: iamb_set });
|
cmds.add_command(ProgramCommand { names: vec!["room".into()], f: iamb_room });
|
||||||
cmds.add_command(ProgramCommand { names: vec!["spaces".into()], f: iamb_spaces });
|
cmds.add_command(ProgramCommand { names: vec!["spaces".into()], f: iamb_spaces });
|
||||||
cmds.add_command(ProgramCommand { names: vec!["upload".into()], f: iamb_upload });
|
cmds.add_command(ProgramCommand { names: vec!["upload".into()], f: iamb_upload });
|
||||||
cmds.add_command(ProgramCommand { names: vec!["verify".into()], f: iamb_verify });
|
cmds.add_command(ProgramCommand { names: vec!["verify".into()], f: iamb_verify });
|
||||||
|
@ -376,47 +424,227 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cmd_set() {
|
fn test_cmd_room_invalid() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room foo", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room set topic", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_topic_set() {
|
||||||
let mut cmds = setup_commands();
|
let mut cmds = setup_commands();
|
||||||
let ctx = ProgramContext::default();
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
let res = cmds
|
let res = cmds
|
||||||
.input_cmd("set room.topic \"Lots of fun discussion!\"", ctx.clone())
|
.input_cmd("room topic set \"Lots of fun discussion!\"", ctx.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let act = IambAction::Room(SetRoomField::Topic("Lots of fun discussion!".into()).into());
|
let act = RoomAction::Set(RoomField::Topic, "Lots of fun discussion!".into());
|
||||||
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
let res = cmds
|
let res = cmds
|
||||||
.input_cmd("set room.topic The\\ Discussion\\ Room", ctx.clone())
|
.input_cmd("room topic set The\\ Discussion\\ Room", ctx.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let act = IambAction::Room(SetRoomField::Topic("The Discussion Room".into()).into());
|
let act = RoomAction::Set(RoomField::Topic, "The Discussion Room".into());
|
||||||
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
let res = cmds.input_cmd("set room.topic Development", ctx.clone()).unwrap();
|
let res = cmds.input_cmd("room topic set Development", ctx.clone()).unwrap();
|
||||||
let act = IambAction::Room(SetRoomField::Topic("Development".into()).into());
|
let act = RoomAction::Set(RoomField::Topic, "Development".into());
|
||||||
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
let res = cmds.input_cmd("set room.name Development", ctx.clone()).unwrap();
|
let res = cmds.input_cmd("room topic", ctx.clone());
|
||||||
let act = IambAction::Room(SetRoomField::Name("Development".into()).into());
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room topic set", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room topic set A B C", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_name_invalid() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room name", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room name foo", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_name_set() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room name set Development", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Name, "Development".into());
|
||||||
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
let res = cmds
|
let res = cmds
|
||||||
.input_cmd("set room.name \"Application Development\"", ctx.clone())
|
.input_cmd("room name set \"Application Development\"", ctx.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let act = IambAction::Room(SetRoomField::Name("Application Development".into()).into());
|
let act = RoomAction::Set(RoomField::Name, "Application Development".into());
|
||||||
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
let res = cmds.input_cmd("set", ctx.clone());
|
let res = cmds.input_cmd("room name set", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_name_unset() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room name unset", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Name);
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room name unset foo", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_tag_set() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set favourite", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::Favorite), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set favorite", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::Favorite), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set fav", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::Favorite), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set low_priority", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::LowPriority), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set low-priority", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::LowPriority), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set low", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::LowPriority), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set servernotice", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::ServerNotice), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set server_notice", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::ServerNotice), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set server_notice", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(RoomField::Tag(TagName::ServerNotice), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set u.custom-tag", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Set(
|
||||||
|
RoomField::Tag(TagName::User("u.custom-tag".parse().unwrap())),
|
||||||
|
"".into(),
|
||||||
|
);
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set u.irc", ctx.clone()).unwrap();
|
||||||
|
let act =
|
||||||
|
RoomAction::Set(RoomField::Tag(TagName::User("u.irc".parse().unwrap())), "".into());
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag", ctx.clone());
|
||||||
assert_eq!(res, Err(CommandError::InvalidArgument));
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
let res = cmds.input_cmd("set room.name", ctx.clone());
|
let res = cmds.input_cmd("room tag set", ctx.clone());
|
||||||
assert_eq!(res, Err(CommandError::InvalidArgument));
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
let res = cmds.input_cmd("set room.topic", ctx.clone());
|
let res = cmds.input_cmd("room tag set unknown", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::Error("Invalid user tag name: unknown".into())));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag set needs-leading-u-dot", ctx.clone());
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
Err(CommandError::Error("Invalid user tag name: needs-leading-u-dot".into()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd_room_tag_unset() {
|
||||||
|
let mut cmds = setup_commands();
|
||||||
|
let ctx = ProgramContext::default();
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset favourite", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::Favorite));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset favorite", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::Favorite));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset fav", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::Favorite));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset low_priority", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::LowPriority));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset low-priority", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::LowPriority));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset low", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::LowPriority));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset servernotice", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::ServerNotice));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset server_notice", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::ServerNotice));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset server_notice", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::ServerNotice));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset u.custom-tag", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::User("u.custom-tag".parse().unwrap())));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset u.irc", ctx.clone()).unwrap();
|
||||||
|
let act = RoomAction::Unset(RoomField::Tag(TagName::User("u.irc".parse().unwrap())));
|
||||||
|
assert_eq!(res, vec![(act.into(), ctx.clone())]);
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag", ctx.clone());
|
||||||
assert_eq!(res, Err(CommandError::InvalidArgument));
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
let res = cmds.input_cmd("set room.topic A B C", ctx.clone());
|
let res = cmds.input_cmd("room tag set", ctx.clone());
|
||||||
assert_eq!(res, Err(CommandError::InvalidArgument));
|
assert_eq!(res, Err(CommandError::InvalidArgument));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset unknown", ctx.clone());
|
||||||
|
assert_eq!(res, Err(CommandError::Error("Invalid user tag name: unknown".into())));
|
||||||
|
|
||||||
|
let res = cmds.input_cmd("room tag unset needs-leading-u-dot", ctx.clone());
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
Err(CommandError::Error("Invalid user tag name: needs-leading-u-dot".into()))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -141,6 +141,7 @@ pub fn mock_room() -> RoomInfo {
|
||||||
|
|
||||||
keys: mock_keys(),
|
keys: mock_keys(),
|
||||||
messages: mock_messages(),
|
messages: mock_messages(),
|
||||||
|
tags: None,
|
||||||
|
|
||||||
fetch_id: RoomFetchStatus::NotStarted,
|
fetch_id: RoomFetchStatus::NotStarted,
|
||||||
fetch_last: None,
|
fetch_last: None,
|
||||||
|
|
|
@ -4,7 +4,12 @@ use std::collections::hash_map::Entry;
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
encryption::verification::{format_emojis, SasVerification},
|
encryption::verification::{format_emojis, SasVerification},
|
||||||
room::{Room as MatrixRoom, RoomMember},
|
room::{Room as MatrixRoom, RoomMember},
|
||||||
ruma::{events::room::member::MembershipState, OwnedRoomId, RoomId},
|
ruma::{
|
||||||
|
events::room::member::MembershipState,
|
||||||
|
events::tag::{TagName, Tags},
|
||||||
|
OwnedRoomId,
|
||||||
|
RoomId,
|
||||||
|
},
|
||||||
DisplayName,
|
DisplayName,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -346,7 +351,7 @@ impl WindowOps<IambInfo> for IambWindow {
|
||||||
let joined = store.application.worker.active_rooms();
|
let joined = store.application.worker.active_rooms();
|
||||||
let mut items = joined
|
let mut items = joined
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(room, name)| RoomItem::new(room, name, store))
|
.map(|(room, name, tags)| RoomItem::new(room, name, tags, store))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
items.sort();
|
items.sort();
|
||||||
|
|
||||||
|
@ -471,8 +476,8 @@ impl Window<IambInfo> for IambWindow {
|
||||||
fn open(id: IambId, store: &mut ProgramStore) -> IambResult<Self> {
|
fn open(id: IambId, store: &mut ProgramStore) -> IambResult<Self> {
|
||||||
match id {
|
match id {
|
||||||
IambId::Room(room_id) => {
|
IambId::Room(room_id) => {
|
||||||
let (room, name) = store.application.worker.get_room(room_id)?;
|
let (room, name, tags) = store.application.worker.get_room(room_id)?;
|
||||||
let room = RoomState::new(room, name, store);
|
let room = RoomState::new(room, name, tags, store);
|
||||||
|
|
||||||
return Ok(room.into());
|
return Ok(room.into());
|
||||||
},
|
},
|
||||||
|
@ -519,8 +524,8 @@ impl Window<IambInfo> for IambWindow {
|
||||||
let room_id = worker.join_room(v.key().to_string())?;
|
let room_id = worker.join_room(v.key().to_string())?;
|
||||||
v.insert(room_id.clone());
|
v.insert(room_id.clone());
|
||||||
|
|
||||||
let (room, name) = store.application.worker.get_room(room_id)?;
|
let (room, name, tags) = store.application.worker.get_room(room_id)?;
|
||||||
let room = RoomState::new(room, name, store);
|
let room = RoomState::new(room, name, tags, store);
|
||||||
|
|
||||||
Ok(room.into())
|
Ok(room.into())
|
||||||
},
|
},
|
||||||
|
@ -547,16 +552,24 @@ impl Window<IambInfo> for IambWindow {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RoomItem {
|
pub struct RoomItem {
|
||||||
room: MatrixRoom,
|
room: MatrixRoom,
|
||||||
|
tags: Option<Tags>,
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoomItem {
|
impl RoomItem {
|
||||||
fn new(room: MatrixRoom, name: DisplayName, store: &mut ProgramStore) -> Self {
|
fn new(
|
||||||
|
room: MatrixRoom,
|
||||||
|
name: DisplayName,
|
||||||
|
tags: Option<Tags>,
|
||||||
|
store: &mut ProgramStore,
|
||||||
|
) -> Self {
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
|
|
||||||
store.application.set_room_name(room.room_id(), name.as_str());
|
let info = store.application.get_room_info(room.room_id().to_owned());
|
||||||
|
info.name = name.clone().into();
|
||||||
|
info.tags = tags.clone();
|
||||||
|
|
||||||
RoomItem { room, name }
|
RoomItem { room, tags, name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +583,29 @@ impl Eq for RoomItem {}
|
||||||
|
|
||||||
impl Ord for RoomItem {
|
impl Ord for RoomItem {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
room_cmp(&self.room, &other.room)
|
let (fava, lowa) = self
|
||||||
|
.tags
|
||||||
|
.as_ref()
|
||||||
|
.map(|tags| {
|
||||||
|
(tags.contains_key(&TagName::Favorite), tags.contains_key(&TagName::LowPriority))
|
||||||
|
})
|
||||||
|
.unwrap_or((false, false));
|
||||||
|
|
||||||
|
let (favb, lowb) = other
|
||||||
|
.tags
|
||||||
|
.as_ref()
|
||||||
|
.map(|tags| {
|
||||||
|
(tags.contains_key(&TagName::Favorite), tags.contains_key(&TagName::LowPriority))
|
||||||
|
})
|
||||||
|
.unwrap_or((false, false));
|
||||||
|
|
||||||
|
// If self has Favorite and other doesn't, it should sort earlier in room list.
|
||||||
|
let cmpf = favb.cmp(&fava);
|
||||||
|
|
||||||
|
// If self has LowPriority and other doesn't, it should sort later in room list.
|
||||||
|
let cmpl = lowa.cmp(&lowb);
|
||||||
|
|
||||||
|
cmpl.then(cmpf).then_with(|| room_cmp(&self.room, &other.room))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,8 +623,40 @@ impl ToString for RoomItem {
|
||||||
|
|
||||||
impl ListItem<IambInfo> for RoomItem {
|
impl ListItem<IambInfo> for RoomItem {
|
||||||
fn show(&self, selected: bool, _: &ViewportContext<ListCursor>, _: &mut ProgramStore) -> Text {
|
fn show(&self, selected: bool, _: &ViewportContext<ListCursor>, _: &mut ProgramStore) -> Text {
|
||||||
|
if let Some(tags) = &self.tags {
|
||||||
|
let style = selected_style(selected);
|
||||||
|
let mut spans = vec![Span::styled(self.name.as_str(), style)];
|
||||||
|
|
||||||
|
if tags.is_empty() {
|
||||||
|
return Text::from(Spans(spans));
|
||||||
|
}
|
||||||
|
|
||||||
|
spans.push(Span::styled(" (", style));
|
||||||
|
|
||||||
|
for (i, tag) in tags.keys().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
spans.push(Span::styled(", ", style));
|
||||||
|
}
|
||||||
|
|
||||||
|
match tag {
|
||||||
|
TagName::Favorite => spans.push(Span::styled("Favorite", style)),
|
||||||
|
TagName::LowPriority => spans.push(Span::styled("Low Priority", style)),
|
||||||
|
TagName::ServerNotice => spans.push(Span::styled("Server Notice", style)),
|
||||||
|
TagName::User(tag) => {
|
||||||
|
spans.push(Span::styled("User Tag: ", style));
|
||||||
|
spans.push(Span::styled(tag.as_ref(), style));
|
||||||
|
},
|
||||||
|
tag => spans.push(Span::styled(format!("{:?}", tag), style)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spans.push(Span::styled(")", style));
|
||||||
|
|
||||||
|
Text::from(Spans(spans))
|
||||||
|
} else {
|
||||||
selected_text(self.name.as_str(), selected)
|
selected_text(self.name.as_str(), selected)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_word(&self) -> Option<String> {
|
fn get_word(&self) -> Option<String> {
|
||||||
self.room.room_id().to_string().into()
|
self.room.room_id().to_string().into()
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
room::{Invited, Room as MatrixRoom},
|
room::{Invited, Room as MatrixRoom},
|
||||||
ruma::RoomId,
|
ruma::{
|
||||||
|
events::{
|
||||||
|
room::{name::RoomNameEventContent, topic::RoomTopicEventContent},
|
||||||
|
tag::{TagInfo, Tags},
|
||||||
|
},
|
||||||
|
RoomId,
|
||||||
|
},
|
||||||
DisplayName,
|
DisplayName,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,6 +29,7 @@ use modalkit::{
|
||||||
PromptAction,
|
PromptAction,
|
||||||
Promptable,
|
Promptable,
|
||||||
Scrollable,
|
Scrollable,
|
||||||
|
UIError,
|
||||||
},
|
},
|
||||||
editing::base::{
|
editing::base::{
|
||||||
Axis,
|
Axis,
|
||||||
|
@ -48,6 +55,7 @@ use crate::base::{
|
||||||
ProgramContext,
|
ProgramContext,
|
||||||
ProgramStore,
|
ProgramStore,
|
||||||
RoomAction,
|
RoomAction,
|
||||||
|
RoomField,
|
||||||
SendAction,
|
SendAction,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,10 +93,16 @@ impl From<SpaceState> for RoomState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoomState {
|
impl RoomState {
|
||||||
pub fn new(room: MatrixRoom, name: DisplayName, store: &mut ProgramStore) -> Self {
|
pub fn new(
|
||||||
|
room: MatrixRoom,
|
||||||
|
name: DisplayName,
|
||||||
|
tags: Option<Tags>,
|
||||||
|
store: &mut ProgramStore,
|
||||||
|
) -> Self {
|
||||||
let room_id = room.room_id().to_owned();
|
let room_id = room.room_id().to_owned();
|
||||||
let info = store.application.get_room_info(room_id);
|
let info = store.application.get_room_info(room_id);
|
||||||
info.name = name.to_string().into();
|
info.name = name.to_string().into();
|
||||||
|
info.tags = tags;
|
||||||
|
|
||||||
if room.is_space() {
|
if room.is_space() {
|
||||||
SpaceState::new(room).into()
|
SpaceState::new(room).into()
|
||||||
|
@ -207,8 +221,50 @@ impl RoomState {
|
||||||
|
|
||||||
Ok(vec![(act, cmd.context.take())])
|
Ok(vec![(act, cmd.context.take())])
|
||||||
},
|
},
|
||||||
RoomAction::Set(field) => {
|
RoomAction::Set(field, value) => {
|
||||||
store.application.worker.set_room(self.id().to_owned(), field)?;
|
let room = store
|
||||||
|
.application
|
||||||
|
.get_joined_room(self.id())
|
||||||
|
.ok_or(UIError::Application(IambError::NotJoined))?;
|
||||||
|
|
||||||
|
match field {
|
||||||
|
RoomField::Name => {
|
||||||
|
let ev = RoomNameEventContent::new(value.into());
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
RoomField::Tag(tag) => {
|
||||||
|
let mut info = TagInfo::new();
|
||||||
|
info.order = Some(1.0);
|
||||||
|
|
||||||
|
let _ = room.set_tag(tag, info).await.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
RoomField::Topic => {
|
||||||
|
let ev = RoomTopicEventContent::new(value);
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(vec![])
|
||||||
|
},
|
||||||
|
RoomAction::Unset(field) => {
|
||||||
|
let room = store
|
||||||
|
.application
|
||||||
|
.get_joined_room(self.id())
|
||||||
|
.ok_or(UIError::Application(IambError::NotJoined))?;
|
||||||
|
|
||||||
|
match field {
|
||||||
|
RoomField::Name => {
|
||||||
|
let ev = RoomNameEventContent::new(None);
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
RoomField::Tag(tag) => {
|
||||||
|
let _ = room.remove_tag(tag).await.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
RoomField::Topic => {
|
||||||
|
let ev = RoomTopicEventContent::new("".into());
|
||||||
|
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
},
|
},
|
||||||
|
|
|
@ -104,10 +104,10 @@ impl<'a> StatefulWidget for Space<'a> {
|
||||||
let items = members
|
let items = members
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|id| {
|
.filter_map(|id| {
|
||||||
let (room, name) = self.store.application.worker.get_room(id.clone()).ok()?;
|
let (room, name, tags) = self.store.application.worker.get_room(id.clone()).ok()?;
|
||||||
|
|
||||||
if id != state.room_id {
|
if id != state.room_id {
|
||||||
Some(RoomItem::new(room, name, self.store))
|
Some(RoomItem::new(room, name, tags, self.store))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@ use matrix_sdk::{
|
||||||
message::{MessageType, RoomMessageEventContent},
|
message::{MessageType, RoomMessageEventContent},
|
||||||
name::RoomNameEventContent,
|
name::RoomNameEventContent,
|
||||||
redaction::{OriginalSyncRoomRedactionEvent, SyncRoomRedactionEvent},
|
redaction::{OriginalSyncRoomRedactionEvent, SyncRoomRedactionEvent},
|
||||||
topic::RoomTopicEventContent,
|
|
||||||
},
|
},
|
||||||
|
tag::Tags,
|
||||||
typing::SyncTypingEvent,
|
typing::SyncTypingEvent,
|
||||||
AnyMessageLikeEvent,
|
AnyMessageLikeEvent,
|
||||||
AnyTimelineEvent,
|
AnyTimelineEvent,
|
||||||
|
@ -57,7 +57,7 @@ use matrix_sdk::{
|
||||||
use modalkit::editing::action::{EditInfo, InfoMessage, UIError};
|
use modalkit::editing::action::{EditInfo, InfoMessage, UIError};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
base::{AsyncProgramStore, IambError, IambResult, SetRoomField, VerifyAction},
|
base::{AsyncProgramStore, IambError, IambResult, VerifyAction},
|
||||||
message::MessageFetchResult,
|
message::MessageFetchResult,
|
||||||
ApplicationSettings,
|
ApplicationSettings,
|
||||||
};
|
};
|
||||||
|
@ -100,18 +100,17 @@ fn oneshot<T>() -> (ClientReply<T>, ClientResponse<T>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum WorkerTask {
|
pub enum WorkerTask {
|
||||||
ActiveRooms(ClientReply<Vec<(MatrixRoom, DisplayName)>>),
|
ActiveRooms(ClientReply<Vec<(MatrixRoom, DisplayName, Option<Tags>)>>),
|
||||||
DirectMessages(ClientReply<Vec<(MatrixRoom, DisplayName)>>),
|
DirectMessages(ClientReply<Vec<(MatrixRoom, DisplayName)>>),
|
||||||
Init(AsyncProgramStore, ClientReply<()>),
|
Init(AsyncProgramStore, ClientReply<()>),
|
||||||
LoadOlder(OwnedRoomId, Option<String>, u32, ClientReply<MessageFetchResult>),
|
LoadOlder(OwnedRoomId, Option<String>, u32, ClientReply<MessageFetchResult>),
|
||||||
Login(LoginStyle, ClientReply<IambResult<EditInfo>>),
|
Login(LoginStyle, ClientReply<IambResult<EditInfo>>),
|
||||||
GetInviter(Invited, ClientReply<IambResult<Option<RoomMember>>>),
|
GetInviter(Invited, ClientReply<IambResult<Option<RoomMember>>>),
|
||||||
GetRoom(OwnedRoomId, ClientReply<IambResult<(MatrixRoom, DisplayName)>>),
|
GetRoom(OwnedRoomId, ClientReply<IambResult<(MatrixRoom, DisplayName, Option<Tags>)>>),
|
||||||
JoinRoom(String, ClientReply<IambResult<OwnedRoomId>>),
|
JoinRoom(String, ClientReply<IambResult<OwnedRoomId>>),
|
||||||
Members(OwnedRoomId, ClientReply<IambResult<Vec<RoomMember>>>),
|
Members(OwnedRoomId, ClientReply<IambResult<Vec<RoomMember>>>),
|
||||||
SpaceMembers(OwnedRoomId, ClientReply<IambResult<Vec<OwnedRoomId>>>),
|
SpaceMembers(OwnedRoomId, ClientReply<IambResult<Vec<OwnedRoomId>>>),
|
||||||
Spaces(ClientReply<Vec<(MatrixRoom, DisplayName)>>),
|
Spaces(ClientReply<Vec<(MatrixRoom, DisplayName)>>),
|
||||||
SetRoom(OwnedRoomId, SetRoomField, ClientReply<IambResult<()>>),
|
|
||||||
TypingNotice(OwnedRoomId),
|
TypingNotice(OwnedRoomId),
|
||||||
Verify(VerifyAction, SasVerification, ClientReply<IambResult<EditInfo>>),
|
Verify(VerifyAction, SasVerification, ClientReply<IambResult<EditInfo>>),
|
||||||
VerifyRequest(OwnedUserId, ClientReply<IambResult<EditInfo>>),
|
VerifyRequest(OwnedUserId, ClientReply<IambResult<EditInfo>>),
|
||||||
|
@ -178,13 +177,6 @@ impl Debug for WorkerTask {
|
||||||
WorkerTask::Spaces(_) => {
|
WorkerTask::Spaces(_) => {
|
||||||
f.debug_tuple("WorkerTask::Spaces").field(&format_args!("_")).finish()
|
f.debug_tuple("WorkerTask::Spaces").field(&format_args!("_")).finish()
|
||||||
},
|
},
|
||||||
WorkerTask::SetRoom(room_id, field, _) => {
|
|
||||||
f.debug_tuple("WorkerTask::SetRoom")
|
|
||||||
.field(room_id)
|
|
||||||
.field(field)
|
|
||||||
.field(&format_args!("_"))
|
|
||||||
.finish()
|
|
||||||
},
|
|
||||||
WorkerTask::TypingNotice(room_id) => {
|
WorkerTask::TypingNotice(room_id) => {
|
||||||
f.debug_tuple("WorkerTask::TypingNotice").field(room_id).finish()
|
f.debug_tuple("WorkerTask::TypingNotice").field(room_id).finish()
|
||||||
},
|
},
|
||||||
|
@ -259,7 +251,10 @@ impl Requester {
|
||||||
return response.recv();
|
return response.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_room(&self, room_id: OwnedRoomId) -> IambResult<(MatrixRoom, DisplayName)> {
|
pub fn get_room(
|
||||||
|
&self,
|
||||||
|
room_id: OwnedRoomId,
|
||||||
|
) -> IambResult<(MatrixRoom, DisplayName, Option<Tags>)> {
|
||||||
let (reply, response) = oneshot();
|
let (reply, response) = oneshot();
|
||||||
|
|
||||||
self.tx.send(WorkerTask::GetRoom(room_id, reply)).unwrap();
|
self.tx.send(WorkerTask::GetRoom(room_id, reply)).unwrap();
|
||||||
|
@ -275,7 +270,7 @@ impl Requester {
|
||||||
return response.recv();
|
return response.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_rooms(&self) -> Vec<(MatrixRoom, DisplayName)> {
|
pub fn active_rooms(&self) -> Vec<(MatrixRoom, DisplayName, Option<Tags>)> {
|
||||||
let (reply, response) = oneshot();
|
let (reply, response) = oneshot();
|
||||||
|
|
||||||
self.tx.send(WorkerTask::ActiveRooms(reply)).unwrap();
|
self.tx.send(WorkerTask::ActiveRooms(reply)).unwrap();
|
||||||
|
@ -299,14 +294,6 @@ impl Requester {
|
||||||
return response.recv();
|
return response.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_room(&self, room_id: OwnedRoomId, ev: SetRoomField) -> IambResult<()> {
|
|
||||||
let (reply, response) = oneshot();
|
|
||||||
|
|
||||||
self.tx.send(WorkerTask::SetRoom(room_id, ev, reply)).unwrap();
|
|
||||||
|
|
||||||
return response.recv();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spaces(&self) -> Vec<(MatrixRoom, DisplayName)> {
|
pub fn spaces(&self) -> Vec<(MatrixRoom, DisplayName)> {
|
||||||
let (reply, response) = oneshot();
|
let (reply, response) = oneshot();
|
||||||
|
|
||||||
|
@ -444,10 +431,6 @@ impl ClientWorker {
|
||||||
assert!(self.initialized);
|
assert!(self.initialized);
|
||||||
reply.send(self.members(room_id).await);
|
reply.send(self.members(room_id).await);
|
||||||
},
|
},
|
||||||
WorkerTask::SetRoom(room_id, field, reply) => {
|
|
||||||
assert!(self.initialized);
|
|
||||||
reply.send(self.set_room(room_id, field).await);
|
|
||||||
},
|
|
||||||
WorkerTask::SpaceMembers(space, reply) => {
|
WorkerTask::SpaceMembers(space, reply) => {
|
||||||
assert!(self.initialized);
|
assert!(self.initialized);
|
||||||
reply.send(self.space_members(space).await);
|
reply.send(self.space_members(space).await);
|
||||||
|
@ -721,10 +704,15 @@ impl ClientWorker {
|
||||||
Ok(Some(InfoMessage::from("Successfully logged in!")))
|
Ok(Some(InfoMessage::from("Successfully logged in!")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn direct_message(&mut self, user: OwnedUserId) -> IambResult<(MatrixRoom, DisplayName)> {
|
async fn direct_message(
|
||||||
|
&mut self,
|
||||||
|
user: OwnedUserId,
|
||||||
|
) -> IambResult<(MatrixRoom, DisplayName, Option<Tags>)> {
|
||||||
for (room, name) in self.direct_messages().await {
|
for (room, name) in self.direct_messages().await {
|
||||||
if room.get_member(user.as_ref()).await.map_err(IambError::from)?.is_some() {
|
if room.get_member(user.as_ref()).await.map_err(IambError::from)?.is_some() {
|
||||||
return Ok((room, name));
|
let tags = room.tags().await.map_err(IambError::from)?;
|
||||||
|
|
||||||
|
return Ok((room, name, tags));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,11 +746,15 @@ impl ClientWorker {
|
||||||
Ok(details.inviter)
|
Ok(details.inviter)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_room(&mut self, room_id: OwnedRoomId) -> IambResult<(MatrixRoom, DisplayName)> {
|
async fn get_room(
|
||||||
|
&mut self,
|
||||||
|
room_id: OwnedRoomId,
|
||||||
|
) -> IambResult<(MatrixRoom, DisplayName, Option<Tags>)> {
|
||||||
if let Some(room) = self.client.get_room(&room_id) {
|
if let Some(room) = self.client.get_room(&room_id) {
|
||||||
let name = room.display_name().await.map_err(IambError::from)?;
|
let name = room.display_name().await.map_err(IambError::from)?;
|
||||||
|
let tags = room.tags().await.map_err(IambError::from)?;
|
||||||
|
|
||||||
Ok((room, name))
|
Ok((room, name, tags))
|
||||||
} else {
|
} else {
|
||||||
Err(IambError::UnknownRoom(room_id).into())
|
Err(IambError::UnknownRoom(room_id).into())
|
||||||
}
|
}
|
||||||
|
@ -817,7 +809,7 @@ impl ClientWorker {
|
||||||
return rooms;
|
return rooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn active_rooms(&self) -> Vec<(MatrixRoom, DisplayName)> {
|
async fn active_rooms(&self) -> Vec<(MatrixRoom, DisplayName, Option<Tags>)> {
|
||||||
let mut rooms = vec![];
|
let mut rooms = vec![];
|
||||||
|
|
||||||
for room in self.client.invited_rooms().into_iter() {
|
for room in self.client.invited_rooms().into_iter() {
|
||||||
|
@ -826,8 +818,9 @@ impl ClientWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = room.display_name().await.unwrap_or(DisplayName::Empty);
|
let name = room.display_name().await.unwrap_or(DisplayName::Empty);
|
||||||
|
let tags = room.tags().await.unwrap_or_default();
|
||||||
|
|
||||||
rooms.push((room.into(), name));
|
rooms.push((room.into(), name, tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
for room in self.client.joined_rooms().into_iter() {
|
for room in self.client.joined_rooms().into_iter() {
|
||||||
|
@ -836,8 +829,9 @@ impl ClientWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = room.display_name().await.unwrap_or(DisplayName::Empty);
|
let name = room.display_name().await.unwrap_or(DisplayName::Empty);
|
||||||
|
let tags = room.tags().await.unwrap_or_default();
|
||||||
|
|
||||||
rooms.push((room.into(), name));
|
rooms.push((room.into(), name, tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rooms;
|
return rooms;
|
||||||
|
@ -886,27 +880,6 @@ impl ClientWorker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_room(&mut self, room_id: OwnedRoomId, field: SetRoomField) -> IambResult<()> {
|
|
||||||
let room = if let Some(r) = self.client.get_joined_room(&room_id) {
|
|
||||||
r
|
|
||||||
} else {
|
|
||||||
return Err(IambError::UnknownRoom(room_id).into());
|
|
||||||
};
|
|
||||||
|
|
||||||
match field {
|
|
||||||
SetRoomField::Name(name) => {
|
|
||||||
let ev = RoomNameEventContent::new(name.into());
|
|
||||||
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
|
||||||
},
|
|
||||||
SetRoomField::Topic(topic) => {
|
|
||||||
let ev = RoomTopicEventContent::new(topic);
|
|
||||||
let _ = room.send_state_event(ev).await.map_err(IambError::from)?;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn space_members(&mut self, space: OwnedRoomId) -> IambResult<Vec<OwnedRoomId>> {
|
async fn space_members(&mut self, space: OwnedRoomId) -> IambResult<Vec<OwnedRoomId>> {
|
||||||
let mut req = SpaceHierarchyRequest::new(&space);
|
let mut req = SpaceHierarchyRequest::new(&space);
|
||||||
req.limit = Some(1000u32.into());
|
req.limit = Some(1000u32.into());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue