Allow incoming messages to be seen by Empathy

MDNs don't work because the sender is not in a "real chat" yet- it's
coming from an unknown user - but we mark them as seen anyway.
This commit is contained in:
2020-05-18 21:15:56 +01:00
parent b511dd873b
commit 72947bc99d
5 changed files with 115 additions and 56 deletions

View File

@@ -7,6 +7,9 @@ pub use self::connection::*;
mod connection_manager;
pub use self::connection_manager::*;
mod message;
pub use self::message::*;
mod protocol;
pub use self::protocol::*;

View File

@@ -1,4 +1,4 @@
use crate::padfoot::{var_i64, var_str, var_u32, VarArg};
use crate::padfoot::{convert_msg, VarArg};
use crate::telepathy;
use dbus::tree::MethodErr;
@@ -61,50 +61,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 => {
let mut parts = Vec::new();
let mut props = HashMap::new();
props.insert(
"message-token".to_string(),
var_str(format!("{}", msg_id.to_u32())),
);
props.insert("message-sent".to_string(), var_i64(msg.get_timestamp()));
props.insert(
"message-received".to_string(),
var_i64(msg.get_received_timestamp()),
);
props.insert("message-sender".to_string(), var_u32(msg.get_from_id()));
// props.insert("message-sender-id", var_str()); // This doesn't need to be sent
// props.insert("sender-nickname", var_str()); // Can we get away without this one?
props.insert("message-type".to_string(), var_u32(0)); // normal
// These relate to superseded messages
// props.insert("supersedes", var_str());
// props.insert("original-message-sent", var_i64());
// props.insert("original-message-received", var_i64());
props.insert("pending-message-id".to_string(), var_u32(msg_id.to_u32()));
parts.push(props);
// Don't need these
// props.insert("interface", var_str());
// props.insert("scrollback", var_vool());
// props.insert("silent", var_bool());
// props.insert("rescued", var_bool());
if let Some(text) = msg.get_text() {
let mut part = HashMap::new();
part.insert(
"content-type".to_string(),
var_str("text/plain".to_string()),
);
part.insert("content".to_string(), var_str(text));
parts.push(part);
}
out.push(parts);
}
MessageState::InFresh | MessageState::InNoticed => out.push(convert_msg(msg)),
_ => continue,
}
}

View File

@@ -1,6 +1,11 @@
use crate::padfoot::DbusAction;
use crate::telepathy;
use crate::telepathy::ChannelInterfaceMessages;
use dbus::message::SignalArgs;
use dbus::tree::MethodErr;
use dc::message::MsgId;
use deltachat as dc;
use super::{Channel, Result};
@@ -22,9 +27,32 @@ type PendingMessagesSpec = (
// Most of these methods are deprecated, so should be implemented in terms of
// the mandatory Messages interface.
impl telepathy::ChannelTypeText for Channel {
// ids is a list of deltachat msg_ids
fn acknowledge_pending_messages(&self, ids: Vec<u32>) -> Result<()> {
println!("Channel::acknowledge_pending_messages({:?})", ids);
Err(MethodErr::no_arg())
let ctx = self.ctx.read().unwrap();
let mut msg_ids = Vec::<MsgId>::new();
for msg_id in &ids {
msg_ids.push(MsgId::new(*msg_id));
}
print!(" Marking messages as seen...");
let result = dc::message::markseen_msgs(&ctx, &msg_ids);
if result {
println!("OK!");
// Emit a PendingMessagesRemoved signal only if all have been removed
let sig =
telepathy::ChannelInterfaceMessagesPendingMessagesRemoved { message_ids: ids }
.to_emit_message(&self.path());
self.actq.send(DbusAction::Signal(sig)).unwrap();
} else {
println!("FAILED!");
}
Ok(())
}
fn get_message_types(&self) -> Result<Vec<u32>> {
@@ -35,6 +63,7 @@ impl telepathy::ChannelTypeText for Channel {
fn list_pending_messages(&self, clear: bool) -> Result<Vec<PendingMessagesSpec>> {
println!("Channel::list_pending_messages({})", clear);
Err(MethodErr::no_arg())
}

View File

@@ -20,7 +20,7 @@ pub use self::requests::*;
mod simple_presence;
pub use self::simple_presence::*;
use crate::padfoot::{var_bool, var_str, var_str_vec, var_u32, Channel, VarArg};
use crate::padfoot::{convert_msg, var_bool, var_str, var_str_vec, var_u32, Channel, VarArg};
use crate::telepathy;
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
@@ -415,22 +415,37 @@ impl Connection {
// Autocreate channel if it doesn't already exist
// FIXME: unknown contacts need more care than this
if chans.contains_key(&chan_path) {
println!(
"Message {} received for {}, passing it on is TODO!",
msg_id, chan_path
);
print!("Message {} received for {}...", msg_id, chan_path);
// Emit new message signals for the channel
if let Ok(msg) = dc::message::Message::load_from_db(
&ctx.clone().read().unwrap(),
msg_id,
) {
let parts = convert_msg(msg);
let sig = telepathy::ChannelInterfaceMessagesMessageReceived {
message: parts,
}
.to_emit_message(&chan_path);
actq.send(DbusAction::Signal(sig)).unwrap();
println!("OK!");
} else {
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);
let contacts =
dc::chat::get_chat_contacts(&ctx.clone().read().unwrap(), chat_id);
if contacts.is_empty() {
println!("empty chat! ignoring");
if contacts.len() != 1 {
println!("...{} contacts in chat, ignoring!", contacts.len());
continue;
}
if contacts.len() > 1 {
println!("...{} contacts in chat, ignoring!", contacts.len())
}
let handle = contacts.first().unwrap();
let chan = Channel::new(

55
src/padfoot/message.rs Normal file
View File

@@ -0,0 +1,55 @@
use crate::padfoot::{var_i64, var_str, var_u32, VarArg};
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<HashMap<String, VarArg>> {
let mut parts = Vec::new();
let mut props = HashMap::new();
let msg_id = msg.get_id();
props.insert(
"message-token".to_string(),
var_str(format!("{}", msg_id.to_u32())),
);
props.insert("message-sent".to_string(), var_i64(msg.get_timestamp()));
props.insert(
"message-received".to_string(),
var_i64(msg.get_received_timestamp()),
);
props.insert("message-sender".to_string(), var_u32(msg.get_from_id()));
// props.insert("message-sender-id", var_str()); // This doesn't need to be sent
// props.insert("sender-nickname", var_str()); // Can we get away without this one?
props.insert("message-type".to_string(), var_u32(0)); // normal
// These relate to superseded messages
// props.insert("supersedes", var_str());
// props.insert("original-message-sent", var_i64());
// props.insert("original-message-received", var_i64());
props.insert("pending-message-id".to_string(), var_u32(msg_id.to_u32()));
parts.push(props);
// Don't need these
// props.insert("interface", var_str());
// props.insert("scrollback", var_vool());
// props.insert("silent", var_bool());
// props.insert("rescued", var_bool());
if let Some(text) = msg.get_text() {
let mut part = HashMap::new();
part.insert(
"content-type".to_string(),
var_str("text/plain".to_string()),
);
part.insert("content".to_string(), var_str(text));
parts.push(part);
}
// TODO: other parts. Can a deltachat message have multiple parts?
parts
}