new message: initial commit
This commit is contained in:
@@ -477,9 +477,8 @@ impl Daemon {
|
||||
.await;
|
||||
|
||||
// Convert DB messages to daemon model, substituting local_id when an alias exists.
|
||||
let mut result: Vec<Message> = Vec::with_capacity(
|
||||
db_messages.len() + outgoing_messages.len(),
|
||||
);
|
||||
let mut result: Vec<Message> =
|
||||
Vec::with_capacity(db_messages.len() + outgoing_messages.len());
|
||||
for m in db_messages.into_iter() {
|
||||
let server_id = m.id.clone();
|
||||
let mut dm: Message = m.into();
|
||||
|
||||
@@ -8,6 +8,7 @@ use tokio_condvar::Condvar;
|
||||
use crate::daemon::events::Event as DaemonEvent;
|
||||
use kordophone::api::APIInterface;
|
||||
use kordophone::model::outgoing_message::OutgoingMessage;
|
||||
use kordophone::model::OutgoingMessageTarget;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
@@ -102,10 +103,29 @@ impl<C: APIInterface, F: AsyncFnMut() -> Result<C>> PostOffice<C, F> {
|
||||
Ok(sent_message) => {
|
||||
log::info!(target: target::POST_OFFICE, "Message sent successfully: {}", message.guid);
|
||||
|
||||
let conversation_id = message.conversation_id.clone();
|
||||
let event =
|
||||
DaemonEvent::MessageSent(sent_message.into(), message, conversation_id);
|
||||
event_sink.send(event).await.unwrap();
|
||||
let conversation_id = sent_message.conversation_id.clone().or_else(|| {
|
||||
match &message.target {
|
||||
OutgoingMessageTarget::Conversation(conversation_id) => {
|
||||
Some(conversation_id.clone())
|
||||
}
|
||||
OutgoingMessageTarget::Handles(_) => None,
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(conversation_id) = conversation_id {
|
||||
let event = DaemonEvent::MessageSent(
|
||||
sent_message.message.into(),
|
||||
message,
|
||||
conversation_id,
|
||||
);
|
||||
event_sink.send(event).await.unwrap();
|
||||
} else {
|
||||
log::error!(
|
||||
target: target::POST_OFFICE,
|
||||
"Message sent but no conversation id was available for {}",
|
||||
message.guid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
|
||||
@@ -318,49 +318,49 @@ impl DbusRepository for DBusAgent {
|
||||
.attachments
|
||||
.into_iter()
|
||||
.map(|attachment| {
|
||||
attachment_count += 1;
|
||||
let mut attachment_map = arg::PropMap::new();
|
||||
attachment_map.insert(
|
||||
"guid".into(),
|
||||
arg::Variant(Box::new(attachment.guid.clone())),
|
||||
);
|
||||
attachment_map.insert(
|
||||
"downloaded".into(),
|
||||
arg::Variant(Box::new(attachment.is_downloaded(false))),
|
||||
);
|
||||
attachment_map.insert(
|
||||
"preview_downloaded".into(),
|
||||
arg::Variant(Box::new(attachment.is_downloaded(true))),
|
||||
);
|
||||
attachment_count += 1;
|
||||
let mut attachment_map = arg::PropMap::new();
|
||||
attachment_map.insert(
|
||||
"guid".into(),
|
||||
arg::Variant(Box::new(attachment.guid.clone())),
|
||||
);
|
||||
attachment_map.insert(
|
||||
"downloaded".into(),
|
||||
arg::Variant(Box::new(attachment.is_downloaded(false))),
|
||||
);
|
||||
attachment_map.insert(
|
||||
"preview_downloaded".into(),
|
||||
arg::Variant(Box::new(attachment.is_downloaded(true))),
|
||||
);
|
||||
|
||||
if let Some(ref metadata) = attachment.metadata {
|
||||
let mut metadata_map = arg::PropMap::new();
|
||||
if let Some(ref metadata) = attachment.metadata {
|
||||
let mut metadata_map = arg::PropMap::new();
|
||||
|
||||
if let Some(ref attribution_info) = metadata.attribution_info {
|
||||
let mut attribution_map = arg::PropMap::new();
|
||||
if let Some(width) = attribution_info.width {
|
||||
attribution_map.insert(
|
||||
"width".into(),
|
||||
arg::Variant(Box::new(width as i32)),
|
||||
if let Some(ref attribution_info) = metadata.attribution_info {
|
||||
let mut attribution_map = arg::PropMap::new();
|
||||
if let Some(width) = attribution_info.width {
|
||||
attribution_map.insert(
|
||||
"width".into(),
|
||||
arg::Variant(Box::new(width as i32)),
|
||||
);
|
||||
}
|
||||
if let Some(height) = attribution_info.height {
|
||||
attribution_map.insert(
|
||||
"height".into(),
|
||||
arg::Variant(Box::new(height as i32)),
|
||||
);
|
||||
}
|
||||
metadata_map.insert(
|
||||
"attribution_info".into(),
|
||||
arg::Variant(Box::new(attribution_map)),
|
||||
);
|
||||
}
|
||||
if let Some(height) = attribution_info.height {
|
||||
attribution_map.insert(
|
||||
"height".into(),
|
||||
arg::Variant(Box::new(height as i32)),
|
||||
);
|
||||
}
|
||||
metadata_map.insert(
|
||||
"attribution_info".into(),
|
||||
arg::Variant(Box::new(attribution_map)),
|
||||
|
||||
attachment_map.insert(
|
||||
"metadata".into(),
|
||||
arg::Variant(Box::new(metadata_map)),
|
||||
);
|
||||
}
|
||||
|
||||
attachment_map.insert(
|
||||
"metadata".into(),
|
||||
arg::Variant(Box::new(metadata_map)),
|
||||
);
|
||||
}
|
||||
attachment_map
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -15,10 +15,16 @@ pub struct DispatchResult {
|
||||
|
||||
impl DispatchResult {
|
||||
pub fn new(message: Message) -> Self {
|
||||
Self { message, cleanup: None }
|
||||
Self {
|
||||
message,
|
||||
cleanup: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_cleanup<T: Any + Send + 'static>(message: Message, cleanup: T) -> Self {
|
||||
Self { message, cleanup: Some(Box::new(cleanup)) }
|
||||
Self {
|
||||
message,
|
||||
cleanup: Some(Box::new(cleanup)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,12 @@ pub async fn dispatch(
|
||||
.and_then(|m| dict_get_str(m, "conversation_id"))
|
||||
{
|
||||
Some(id) => id,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing conversation_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing conversation_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
match agent
|
||||
.send_event(|r| Event::SyncConversation(conversation_id, r))
|
||||
@@ -122,7 +127,12 @@ pub async fn dispatch(
|
||||
.and_then(|m| dict_get_str(m, "conversation_id"))
|
||||
{
|
||||
Some(id) => id,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing conversation_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing conversation_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
match agent
|
||||
.send_event(|r| Event::MarkConversationAsRead(conversation_id, r))
|
||||
@@ -137,11 +147,21 @@ pub async fn dispatch(
|
||||
"GetMessages" => {
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let conversation_id = match dict_get_str(args, "conversation_id") {
|
||||
Some(id) => id,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing conversation_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing conversation_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
let last_message_id = dict_get_str(args, "last_message_id");
|
||||
match agent
|
||||
@@ -158,13 +178,10 @@ pub async fn dispatch(
|
||||
dict_put_str(&mut m, "sender", &msg.sender.display_name());
|
||||
|
||||
// Include attachment GUIDs for the client to resolve/download
|
||||
let attachment_guids: Vec<String> = msg
|
||||
.attachments
|
||||
.iter()
|
||||
.map(|a| a.guid.clone())
|
||||
.collect();
|
||||
let attachment_guids: Vec<String> =
|
||||
msg.attachments.iter().map(|a| a.guid.clone()).collect();
|
||||
m.insert(cstr("attachment_guids"), array_from_strs(attachment_guids));
|
||||
|
||||
|
||||
// Full attachments array with metadata (mirrors DBus fields)
|
||||
let mut attachments_items: Vec<Message> = Vec::new();
|
||||
for attachment in msg.attachments.iter() {
|
||||
@@ -193,12 +210,23 @@ pub async fn dispatch(
|
||||
if let Some(attribution_info) = &metadata.attribution_info {
|
||||
let mut attribution_map: XpcMap = HashMap::new();
|
||||
if let Some(width) = attribution_info.width {
|
||||
dict_put_i64_as_str(&mut attribution_map, "width", width as i64);
|
||||
dict_put_i64_as_str(
|
||||
&mut attribution_map,
|
||||
"width",
|
||||
width as i64,
|
||||
);
|
||||
}
|
||||
if let Some(height) = attribution_info.height {
|
||||
dict_put_i64_as_str(&mut attribution_map, "height", height as i64);
|
||||
dict_put_i64_as_str(
|
||||
&mut attribution_map,
|
||||
"height",
|
||||
height as i64,
|
||||
);
|
||||
}
|
||||
metadata_map.insert(cstr("attribution_info"), Message::Dictionary(attribution_map));
|
||||
metadata_map.insert(
|
||||
cstr("attribution_info"),
|
||||
Message::Dictionary(attribution_map),
|
||||
);
|
||||
}
|
||||
if !metadata_map.is_empty() {
|
||||
a.insert(cstr("metadata"), Message::Dictionary(metadata_map));
|
||||
@@ -208,7 +236,7 @@ pub async fn dispatch(
|
||||
attachments_items.push(Message::Dictionary(a));
|
||||
}
|
||||
m.insert(cstr("attachments"), Message::Array(attachments_items));
|
||||
|
||||
|
||||
items.push(Message::Dictionary(m));
|
||||
}
|
||||
let mut reply: XpcMap = HashMap::new();
|
||||
@@ -230,11 +258,21 @@ pub async fn dispatch(
|
||||
"SendMessage" => {
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let conversation_id = match dict_get_str(args, "conversation_id") {
|
||||
Some(v) => v,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing conversation_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing conversation_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
let text = dict_get_str(args, "text").unwrap_or_default();
|
||||
let attachment_guids: Vec<String> = match args.get(&cstr("attachment_guids")) {
|
||||
@@ -265,11 +303,21 @@ pub async fn dispatch(
|
||||
"GetAttachmentInfo" => {
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let attachment_id = match dict_get_str(args, "attachment_id") {
|
||||
Some(v) => v,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing attachment_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing attachment_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
match agent
|
||||
.send_event(|r| Event::GetAttachment(attachment_id, r))
|
||||
@@ -308,11 +356,21 @@ pub async fn dispatch(
|
||||
"OpenAttachmentFd" => {
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let attachment_id = match dict_get_str(args, "attachment_id") {
|
||||
Some(v) => v,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing attachment_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing attachment_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
let preview = dict_get_str(args, "preview")
|
||||
.map(|s| s == "true")
|
||||
@@ -324,7 +382,7 @@ pub async fn dispatch(
|
||||
{
|
||||
Ok(attachment) => {
|
||||
use std::os::fd::AsRawFd;
|
||||
|
||||
|
||||
let path = attachment.get_path_for_preview(preview);
|
||||
match std::fs::OpenOptions::new().read(true).open(&path) {
|
||||
Ok(file) => {
|
||||
@@ -335,9 +393,14 @@ pub async fn dispatch(
|
||||
dict_put_str(&mut reply, "type", "OpenAttachmentFdResponse");
|
||||
reply.insert(cstr("fd"), Message::Fd(fd));
|
||||
|
||||
DispatchResult { message: Message::Dictionary(reply), cleanup: Some(Box::new(file)) }
|
||||
DispatchResult {
|
||||
message: Message::Dictionary(reply),
|
||||
cleanup: Some(Box::new(file)),
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
DispatchResult::new(make_error_reply("OpenFailed", &format!("{}", e)))
|
||||
}
|
||||
Err(e) => DispatchResult::new(make_error_reply("OpenFailed", &format!("{}", e))),
|
||||
}
|
||||
}
|
||||
Err(e) => DispatchResult::new(make_error_reply("DaemonError", &format!("{}", e))),
|
||||
@@ -348,11 +411,21 @@ pub async fn dispatch(
|
||||
"DownloadAttachment" => {
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let attachment_id = match dict_get_str(args, "attachment_id") {
|
||||
Some(v) => v,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing attachment_id")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing attachment_id",
|
||||
))
|
||||
}
|
||||
};
|
||||
let preview = dict_get_str(args, "preview")
|
||||
.map(|s| s == "true")
|
||||
@@ -371,11 +444,18 @@ pub async fn dispatch(
|
||||
use std::path::PathBuf;
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let path = match dict_get_str(args, "path") {
|
||||
Some(v) => v,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing path")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply("InvalidRequest", "Missing path"))
|
||||
}
|
||||
};
|
||||
match agent
|
||||
.send_event(|r| Event::UploadAttachment(PathBuf::from(path), r))
|
||||
@@ -413,7 +493,12 @@ pub async fn dispatch(
|
||||
"UpdateSettings" => {
|
||||
let args = match get_dictionary_field(root, "arguments") {
|
||||
Some(a) => a,
|
||||
None => return DispatchResult::new(make_error_reply("InvalidRequest", "Missing arguments")),
|
||||
None => {
|
||||
return DispatchResult::new(make_error_reply(
|
||||
"InvalidRequest",
|
||||
"Missing arguments",
|
||||
))
|
||||
}
|
||||
};
|
||||
let server_url = dict_get_str(args, "server_url");
|
||||
let username = dict_get_str(args, "username");
|
||||
|
||||
Reference in New Issue
Block a user