From a95be7ee4b0a556f1928465b208bf7c77b1956fc Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 18 May 2020 23:08:11 +0100 Subject: [PATCH] Implement sending text messages This works in a very simplistic way, but it's enough for two-way communication. Hurrah! --- README.md | 2 +- src/padfoot/channel/messages.rs | 61 +++++++++++++++++++++++++++++---- src/padfoot/connection.rs | 12 +++++-- src/padfoot/message.rs | 2 +- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f92c98e..e549ce8 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Here's where we're at right now: - [x] Disconnect! - [ ] Set up an account manually - [ ] Contacts handling -- [~] Text messages +- [x] Text messages - [ ] Multimedia messages - [ ] Setup messages - [ ] Import/Export diff --git a/src/padfoot/channel/messages.rs b/src/padfoot/channel/messages.rs index 0f65a7f..a4dafb8 100644 --- a/src/padfoot/channel/messages.rs +++ b/src/padfoot/channel/messages.rs @@ -1,8 +1,10 @@ -use crate::padfoot::{convert_msg, VarArg}; +use crate::padfoot::{convert_msg, DbusAction, VarArg}; use crate::telepathy; +use dbus::message::SignalArgs; use dbus::tree::MethodErr; -use dc::message::MessageState; +use dc::constants::Viewtype; +use dc::message::{Message, MessageState}; use deltachat as dc; use std::collections::HashMap; @@ -15,9 +17,56 @@ impl AsRef for std::sync::Arc } impl telepathy::ChannelInterfaceMessages for Channel { - fn send_message(&self, message: Vec>, flags: u32) -> Result { - println!("Channel::send_message({:?}, {})", message, flags); - Err(MethodErr::no_arg()) + fn send_message(&self, parts: Vec>, flags: u32) -> Result { + println!("Channel::send_message({:?}, {})", parts, flags); + + if parts.len() != 2 { + return Err(MethodErr::no_arg()); + } + let _meta = &parts[0]; + let content = &parts[1]; + + let content_type = content["content-type"].0.as_str().unwrap(); + + if content_type != "text/plain" { + println!("FIXME: can only send text/plain messages right now"); + return Err(MethodErr::no_arg()); + } + + let text_opt = content["content"].0.as_str().map(|s| s.to_string()); + let mut delta_msg = Message::new(Viewtype::Text); // FIXME: this won't always be plaintext + delta_msg.set_text(text_opt.clone()); + + let ctx = self.ctx.read().unwrap(); + let msg_id = match dc::chat::send_msg(&ctx, self.chat_id, &mut delta_msg) { + Ok(msg_id) => msg_id, + Err(e) => { + println!(" Failed to send message: {}", e); + return Err(MethodErr::no_arg()); + } + }; + + let token = format!("{}", msg_id.to_u32()); + let dbus_parts = convert_msg(&delta_msg); + + let messages_sig = telepathy::ChannelInterfaceMessagesMessageSent { + content: dbus_parts, + flags: 0, + message_token: token.clone(), + } + .to_emit_message(&self.path()); + + let text_sig = telepathy::ChannelTypeTextSent { + timestamp: delta_msg.get_timestamp() as u32, + type_: 0, + text: text_opt.or_else(|| Some("".to_string())).unwrap(), + } + .to_emit_message(&self.path()); + + self.actq.send(DbusAction::Signal(messages_sig)).unwrap(); + self.actq.send(DbusAction::Signal(text_sig)).unwrap(); + + Ok(token) } fn get_pending_message_content( @@ -61,7 +110,7 @@ impl telepathy::ChannelInterfaceMessages for Channel { if let Ok(msg) = dc::message::Message::load_from_db(&ctx, msg_id) { println!(" A message: {:?}", msg); match msg.get_state() { - MessageState::InFresh | MessageState::InNoticed => out.push(convert_msg(msg)), + MessageState::InFresh | MessageState::InNoticed => out.push(convert_msg(&msg)), _ => continue, } } diff --git a/src/padfoot/connection.rs b/src/padfoot/connection.rs index 1b7e9c3..584544e 100644 --- a/src/padfoot/connection.rs +++ b/src/padfoot/connection.rs @@ -422,7 +422,14 @@ impl Connection { &ctx.clone().read().unwrap(), msg_id, ) { - let parts = convert_msg(msg); + // Ignore messages that are self-originated. + // FIXME: special-case self-chats + if msg.get_from_id() == dc::constants::DC_CONTACT_ID_SELF { + println!("from ourselves, skipping"); + continue; + } + + let parts = convert_msg(&msg); let sig = telepathy::ChannelInterfaceMessagesMessageReceived { message: parts, @@ -433,9 +440,8 @@ impl Connection { println!("OK!"); } else { - println!(" couldn't find message not sending signal"); + println!(" couldn't find message, not sending signal"); } - // FIXME: We MUST also send a Text.Received signal } else { print!("Channel for {} doesn't exist yet, creating it...", chat_id); diff --git a/src/padfoot/message.rs b/src/padfoot/message.rs index e410094..f2aece5 100644 --- a/src/padfoot/message.rs +++ b/src/padfoot/message.rs @@ -5,7 +5,7 @@ use deltachat::message::Message; use std::collections::HashMap; // Turns a deltachat::message::Message into a Telepathy Message_Part_List -pub fn convert_msg(msg: Message) -> Vec> { +pub fn convert_msg(msg: &Message) -> Vec> { let mut parts = Vec::new(); let mut props = HashMap::new(); let msg_id = msg.get_id();