Support creating new rooms and spaces (#40)

This commit is contained in:
Ulyssa 2023-03-04 12:23:17 -08:00
parent 11625262f1
commit 93eff79f79
No known key found for this signature in database
GPG Key ID: 1B3965A3D18B9B64
6 changed files with 122 additions and 10 deletions

4
Cargo.lock generated
View File

@ -1882,9 +1882,9 @@ dependencies = [
[[package]]
name = "modalkit"
version = "0.0.12"
version = "0.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a4e5226a5d33a7bdf5b4fc067baa211c94f21aa6667af5eec8b357a8af5e4ba"
checksum = "038bb42efcd659fb123708bf8e4ea12ca9023f07d44514f9358b9334ea7ba80f"
dependencies = [
"anymap2",
"arboard",

View File

@ -39,7 +39,7 @@ unicode-width = "0.1.10"
url = {version = "^2.2.2", features = ["serde"]}
[dependencies.modalkit]
version = "0.0.12"
version = "0.0.13"
[dependencies.matrix-sdk]
version = "0.6"

View File

@ -135,6 +135,12 @@ pub enum MessageAction {
pub enum CreateRoomType {
/// A direct message room.
Direct(OwnedUserId),
/// A standard chat room.
Room,
/// A Matrix space.
Space,
}
bitflags::bitflags! {
@ -184,8 +190,14 @@ pub enum SendAction {
Upload(String),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum HomeserverAction {
CreateRoom(Option<String>, CreateRoomType, CreateRoomFlags),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum IambAction {
Homeserver(HomeserverAction),
Message(MessageAction),
Room(RoomAction),
Send(SendAction),
@ -194,6 +206,12 @@ pub enum IambAction {
ToggleScrollbackFocus,
}
impl From<HomeserverAction> for IambAction {
fn from(act: HomeserverAction) -> Self {
IambAction::Homeserver(act)
}
}
impl From<MessageAction> for IambAction {
fn from(act: MessageAction) -> Self {
IambAction::Message(act)
@ -215,6 +233,7 @@ impl From<SendAction> for IambAction {
impl ApplicationAction for IambAction {
fn is_edit_sequence<C: EditContext>(&self, _: &C) -> SequenceStatus {
match self {
IambAction::Homeserver(..) => SequenceStatus::Break,
IambAction::Message(..) => SequenceStatus::Break,
IambAction::Room(..) => SequenceStatus::Break,
IambAction::Send(..) => SequenceStatus::Break,
@ -226,6 +245,7 @@ impl ApplicationAction for IambAction {
fn is_last_action<C: EditContext>(&self, _: &C) -> SequenceStatus {
match self {
IambAction::Homeserver(..) => SequenceStatus::Atom,
IambAction::Message(..) => SequenceStatus::Atom,
IambAction::Room(..) => SequenceStatus::Atom,
IambAction::Send(..) => SequenceStatus::Atom,
@ -237,6 +257,7 @@ impl ApplicationAction for IambAction {
fn is_last_selection<C: EditContext>(&self, _: &C) -> SequenceStatus {
match self {
IambAction::Homeserver(..) => SequenceStatus::Ignore,
IambAction::Message(..) => SequenceStatus::Ignore,
IambAction::Room(..) => SequenceStatus::Ignore,
IambAction::Send(..) => SequenceStatus::Ignore,
@ -248,6 +269,7 @@ impl ApplicationAction for IambAction {
fn is_switchable<C: EditContext>(&self, _: &C) -> bool {
match self {
IambAction::Homeserver(..) => false,
IambAction::Message(..) => false,
IambAction::Room(..) => false,
IambAction::Send(..) => false,

View File

@ -4,13 +4,16 @@ use matrix_sdk::ruma::{events::tag::TagName, OwnedUserId};
use modalkit::{
editing::base::OpenTarget,
env::vim::command::{CommandContext, CommandDescription},
env::vim::command::{CommandContext, CommandDescription, OptionType},
input::commands::{CommandError, CommandResult, CommandStep},
input::InputContext,
};
use crate::base::{
CreateRoomFlags,
CreateRoomType,
DownloadFlags,
HomeserverAction,
IambAction,
IambId,
MessageAction,
@ -297,6 +300,53 @@ fn iamb_join(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
return Ok(step);
}
fn iamb_create(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
let args = desc.arg.options()?;
let mut flags = CreateRoomFlags::NONE;
let mut alias = None;
let mut ct = CreateRoomType::Room;
for arg in args {
match arg {
OptionType::Flag(name, Some(arg)) => {
match name.as_str() {
"alias" => {
if alias.is_some() {
let msg = "Multiple ++alias arguments are not allowed";
let err = CommandError::Error(msg.into());
return Err(err);
} else {
alias = Some(arg);
}
},
_ => return Err(CommandError::InvalidArgument),
}
},
OptionType::Flag(name, None) => {
match name.as_str() {
"public" => flags |= CreateRoomFlags::PUBLIC,
"space" => ct = CreateRoomType::Space,
"enc" | "encrypted" => flags |= CreateRoomFlags::ENCRYPTED,
_ => return Err(CommandError::InvalidArgument),
}
},
OptionType::Positional(_) => {
let msg = ":create doesn't take any positional arguments";
let err = CommandError::Error(msg.into());
return Err(err);
},
}
}
let hact = HomeserverAction::CreateRoom(alias, ct, flags);
let iact = IambAction::from(hact);
let step = CommandStep::Continue(iact.into(), ctx.context.take());
return Ok(step);
}
fn iamb_room(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
let mut args = desc.arg.strings()?;
@ -400,6 +450,11 @@ fn add_iamb_commands(cmds: &mut ProgramCommands) {
aliases: vec![],
f: iamb_cancel,
});
cmds.add_command(ProgramCommand {
name: "create".into(),
aliases: vec![],
f: iamb_create,
});
cmds.add_command(ProgramCommand { name: "dms".into(), aliases: vec![], f: iamb_dms });
cmds.add_command(ProgramCommand {
name: "download".into(),

View File

@ -53,6 +53,7 @@ use crate::{
base::{
AsyncProgramStore,
ChatStore,
HomeserverAction,
IambAction,
IambError,
IambId,
@ -64,7 +65,7 @@ use crate::{
},
config::{ApplicationSettings, Iamb},
windows::IambWindow,
worker::{ClientWorker, LoginStyle, Requester},
worker::{create_room, ClientWorker, LoginStyle, Requester},
};
use modalkit::{
@ -355,6 +356,12 @@ impl Application {
None
},
IambAction::Homeserver(act) => {
let acts = self.homeserver_command(act, ctx, store).await?;
self.action_prepend(acts);
None
},
IambAction::Message(act) => {
self.screen.current_window_mut()?.message_command(act, ctx, store).await?
},
@ -387,6 +394,25 @@ impl Application {
Ok(info)
}
async fn homeserver_command(
&mut self,
action: HomeserverAction,
ctx: ProgramContext,
store: &mut ProgramStore,
) -> IambResult<Vec<(Action<IambInfo>, ProgramContext)>> {
match action {
HomeserverAction::CreateRoom(alias, vis, flags) => {
let client = &store.application.worker.client;
let room_id = create_room(client, alias.as_deref(), vis, flags).await?;
let room = IambId::Room(room_id);
let target = OpenTarget::Application(room);
let action = WindowAction::Switch(target);
Ok(vec![(action.into(), ctx)])
},
}
}
pub async fn run(&mut self) -> Result<(), std::io::Error> {
self.terminal.clear()?;
@ -518,7 +544,7 @@ fn main() -> IambResult<()> {
let subscriber = FmtSubscriber::builder()
.with_writer(appender)
.with_max_level(Level::TRACE)
.with_max_level(Level::INFO)
.finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");

View File

@ -20,7 +20,7 @@ use matrix_sdk::{
room::{Invited, Messages, MessagesOptions, Room as MatrixRoom, RoomMember},
ruma::{
api::client::{
room::create_room::v3::{Request as CreateRoomRequest, RoomPreset},
room::create_room::v3::{CreationContent, Request as CreateRoomRequest, RoomPreset},
room::Visibility,
space::get_hierarchy::v1::Request as SpaceHierarchyRequest,
},
@ -50,6 +50,7 @@ use matrix_sdk::{
SyncMessageLikeEvent,
SyncStateEvent,
},
room::RoomType,
serde::Raw,
EventEncryptionAlgorithm,
OwnedRoomId,
@ -93,10 +94,10 @@ pub async fn create_room(
rt: CreateRoomType,
flags: CreateRoomFlags,
) -> IambResult<OwnedRoomId> {
let creation_content = None;
let mut creation_content = None;
let mut initial_state = vec![];
let is_direct;
let preset;
let mut is_direct = false;
let mut preset = None;
let mut invite = vec![];
let visibility = if flags.contains(CreateRoomFlags::PUBLIC) {
@ -111,6 +112,14 @@ pub async fn create_room(
is_direct = true;
preset = Some(RoomPreset::TrustedPrivateChat);
},
CreateRoomType::Space => {
let mut cc = CreationContent::new();
cc.room_type = Some(RoomType::Space);
let raw_cc = Raw::new(&cc).map_err(IambError::from)?;
creation_content = Some(raw_cc);
},
CreateRoomType::Room => {},
}
// Set up encryption.