use crate::padfoot::{convert_msg, DbusAction, VarArg}; use crate::telepathy; use dbus::message::SignalArgs; use dbus::tree::MethodErr; use dc::constants::Viewtype; use dc::message::{Message, MessageState}; use deltachat as dc; use std::collections::HashMap; use super::{Channel, Result}; impl AsRef for std::sync::Arc { fn as_ref(&self) -> &(dyn telepathy::ChannelInterfaceMessages + 'static) { &**self } } impl telepathy::ChannelInterfaceMessages for Channel { 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( &self, message_id: u32, parts: Vec, ) -> Result> { println!( "Channel::get_pending_message_content({}, {:?})", message_id, parts ); Err(MethodErr::no_arg()) } fn supported_content_types(&self) -> Result> { println!("Channel::supported_content_types()"); Ok(vec!["text/plain".to_string()]) // TODO: image support } fn message_types(&self) -> Result> { println!("Channel::message_types()"); Ok(vec![0]) // Normal messages. FIXME: MDNs too } fn message_part_support_flags(&self) -> Result { println!("Channel::message_part_support_flags()"); Ok(0) // FIXME: support multipart messages } // Return value is an array of array of message parts fn pending_messages(&self) -> Result>>> { println!("Channel::pending_messages()"); let mut out = Vec::>>::new(); let ctx = self.ctx.read().unwrap(); for msg_id in dc::chat::get_chat_msgs(&ctx, self.chat_id, 0, None) { if let Ok(msg) = dc::message::Message::load_from_db(&ctx, msg_id) { match msg.get_state() { MessageState::InFresh | MessageState::InNoticed => { println!(" A message: {:?}", msg); out.push(convert_msg(&msg)) } _ => continue, } } } Ok(out) // FIXME: check for pending messages } fn delivery_reporting_support(&self) -> Result { println!("Channel::delivery_reporting_support()"); Ok(0) // FIXME: MDNs } }