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;
|
mod connection_manager;
|
||||||
pub use self::connection_manager::*;
|
pub use self::connection_manager::*;
|
||||||
|
|
||||||
|
mod message;
|
||||||
|
pub use self::message::*;
|
||||||
|
|
||||||
mod protocol;
|
mod protocol;
|
||||||
pub use self::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 crate::telepathy;
|
||||||
|
|
||||||
use dbus::tree::MethodErr;
|
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) {
|
if let Ok(msg) = dc::message::Message::load_from_db(&ctx, msg_id) {
|
||||||
println!(" A message: {:?}", msg);
|
println!(" A message: {:?}", msg);
|
||||||
match msg.get_state() {
|
match msg.get_state() {
|
||||||
MessageState::InFresh | MessageState::InNoticed => {
|
MessageState::InFresh | MessageState::InNoticed => out.push(convert_msg(msg)),
|
||||||
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);
|
|
||||||
}
|
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,11 @@
|
|||||||
|
use crate::padfoot::DbusAction;
|
||||||
use crate::telepathy;
|
use crate::telepathy;
|
||||||
use crate::telepathy::ChannelInterfaceMessages;
|
use crate::telepathy::ChannelInterfaceMessages;
|
||||||
|
|
||||||
|
use dbus::message::SignalArgs;
|
||||||
use dbus::tree::MethodErr;
|
use dbus::tree::MethodErr;
|
||||||
|
use dc::message::MsgId;
|
||||||
|
use deltachat as dc;
|
||||||
|
|
||||||
use super::{Channel, Result};
|
use super::{Channel, Result};
|
||||||
|
|
||||||
@@ -22,9 +27,32 @@ type PendingMessagesSpec = (
|
|||||||
// Most of these methods are deprecated, so should be implemented in terms of
|
// Most of these methods are deprecated, so should be implemented in terms of
|
||||||
// the mandatory Messages interface.
|
// the mandatory Messages interface.
|
||||||
impl telepathy::ChannelTypeText for Channel {
|
impl telepathy::ChannelTypeText for Channel {
|
||||||
|
// ids is a list of deltachat msg_ids
|
||||||
fn acknowledge_pending_messages(&self, ids: Vec<u32>) -> Result<()> {
|
fn acknowledge_pending_messages(&self, ids: Vec<u32>) -> Result<()> {
|
||||||
println!("Channel::acknowledge_pending_messages({:?})", ids);
|
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>> {
|
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>> {
|
fn list_pending_messages(&self, clear: bool) -> Result<Vec<PendingMessagesSpec>> {
|
||||||
println!("Channel::list_pending_messages({})", clear);
|
println!("Channel::list_pending_messages({})", clear);
|
||||||
|
|
||||||
Err(MethodErr::no_arg())
|
Err(MethodErr::no_arg())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ pub use self::requests::*;
|
|||||||
mod simple_presence;
|
mod simple_presence;
|
||||||
pub use self::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 crate::telepathy;
|
||||||
|
|
||||||
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
|
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
|
||||||
@@ -415,22 +415,37 @@ impl Connection {
|
|||||||
// Autocreate channel if it doesn't already exist
|
// Autocreate channel if it doesn't already exist
|
||||||
// FIXME: unknown contacts need more care than this
|
// FIXME: unknown contacts need more care than this
|
||||||
if chans.contains_key(&chan_path) {
|
if chans.contains_key(&chan_path) {
|
||||||
println!(
|
print!("Message {} received for {}...", msg_id, chan_path);
|
||||||
"Message {} received for {}, passing it on is TODO!",
|
|
||||||
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 {
|
} else {
|
||||||
print!("Channel for {} doesn't exist yet, creating it...", chat_id);
|
print!("Channel for {} doesn't exist yet, creating it...", chat_id);
|
||||||
|
|
||||||
let contacts =
|
let contacts =
|
||||||
dc::chat::get_chat_contacts(&ctx.clone().read().unwrap(), chat_id);
|
dc::chat::get_chat_contacts(&ctx.clone().read().unwrap(), chat_id);
|
||||||
if contacts.is_empty() {
|
if contacts.len() != 1 {
|
||||||
println!("empty chat! ignoring");
|
println!("...{} contacts in chat, ignoring!", contacts.len());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if contacts.len() > 1 {
|
|
||||||
println!("...{} contacts in chat, ignoring!", contacts.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
let handle = contacts.first().unwrap();
|
let handle = contacts.first().unwrap();
|
||||||
let chan = Channel::new(
|
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