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:
@@ -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::*;
|
||||
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
||||
|
@@ -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())
|
||||
}
|
||||
|
||||
|
@@ -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
55
src/padfoot/message.rs
Normal 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
|
||||
}
|
Reference in New Issue
Block a user