|
|
|
|
@@ -18,7 +18,12 @@ pub async fn dispatch(
|
|
|
|
|
|
|
|
|
|
let method = match dict_get_str(root, "method").or_else(|| dict_get_str(root, "type")) {
|
|
|
|
|
Some(m) => m,
|
|
|
|
|
None => return attach_request_id(make_error_reply("InvalidRequest", "Missing method/type"), request_id),
|
|
|
|
|
None => {
|
|
|
|
|
return attach_request_id(
|
|
|
|
|
make_error_reply("InvalidRequest", "Missing method/type"),
|
|
|
|
|
request_id,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let _arguments = get_dictionary_field(root, "arguments");
|
|
|
|
|
@@ -40,19 +45,38 @@ pub async fn dispatch(
|
|
|
|
|
let mut limit: i32 = 100;
|
|
|
|
|
let mut offset: i32 = 0;
|
|
|
|
|
if let Some(args) = get_dictionary_field(root, "arguments") {
|
|
|
|
|
if let Some(v) = dict_get_i64_from_str(args, "limit") { limit = v as i32; }
|
|
|
|
|
if let Some(v) = dict_get_i64_from_str(args, "offset") { offset = v as i32; }
|
|
|
|
|
if let Some(v) = dict_get_i64_from_str(args, "limit") {
|
|
|
|
|
limit = v as i32;
|
|
|
|
|
}
|
|
|
|
|
match agent.send_event(|r| Event::GetAllConversations(limit, offset, r)).await {
|
|
|
|
|
if let Some(v) = dict_get_i64_from_str(args, "offset") {
|
|
|
|
|
offset = v as i32;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::GetAllConversations(limit, offset, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(conversations) => {
|
|
|
|
|
let mut items: Vec<Message> = Vec::with_capacity(conversations.len());
|
|
|
|
|
for conv in conversations {
|
|
|
|
|
let mut m: XpcMap = HashMap::new();
|
|
|
|
|
dict_put_str(&mut m, "guid", &conv.guid);
|
|
|
|
|
dict_put_str(&mut m, "display_name", &conv.display_name.unwrap_or_default());
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut m,
|
|
|
|
|
"display_name",
|
|
|
|
|
&conv.display_name.unwrap_or_default(),
|
|
|
|
|
);
|
|
|
|
|
dict_put_i64_as_str(&mut m, "unread_count", conv.unread_count as i64);
|
|
|
|
|
dict_put_str(&mut m, "last_message_preview", &conv.last_message_preview.unwrap_or_default());
|
|
|
|
|
let participant_names: Vec<String> = conv.participants.into_iter().map(|p| p.display_name()).collect();
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut m,
|
|
|
|
|
"last_message_preview",
|
|
|
|
|
&conv.last_message_preview.unwrap_or_default(),
|
|
|
|
|
);
|
|
|
|
|
let participant_names: Vec<String> = conv
|
|
|
|
|
.participants
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|p| p.display_name())
|
|
|
|
|
.collect();
|
|
|
|
|
m.insert(cstr("participants"), array_from_strs(participant_names));
|
|
|
|
|
dict_put_i64_as_str(&mut m, "date", conv.date.and_utc().timestamp());
|
|
|
|
|
items.push(Message::Dictionary(m));
|
|
|
|
|
@@ -76,11 +100,16 @@ pub async fn dispatch(
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
},
|
|
|
|
|
"SyncConversation" => {
|
|
|
|
|
let conversation_id = match get_dictionary_field(root, "arguments").and_then(|m| dict_get_str(m, "conversation_id")) {
|
|
|
|
|
let conversation_id = match get_dictionary_field(root, "arguments")
|
|
|
|
|
.and_then(|m| dict_get_str(m, "conversation_id"))
|
|
|
|
|
{
|
|
|
|
|
Some(id) => id,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing conversation_id"),
|
|
|
|
|
};
|
|
|
|
|
match agent.send_event(|r| Event::SyncConversation(conversation_id, r)).await {
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::SyncConversation(conversation_id, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(()) => make_ok_reply(),
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
}
|
|
|
|
|
@@ -88,11 +117,16 @@ pub async fn dispatch(
|
|
|
|
|
|
|
|
|
|
// Mark as read
|
|
|
|
|
"MarkConversationAsRead" => {
|
|
|
|
|
let conversation_id = match get_dictionary_field(root, "arguments").and_then(|m| dict_get_str(m, "conversation_id")) {
|
|
|
|
|
let conversation_id = match get_dictionary_field(root, "arguments")
|
|
|
|
|
.and_then(|m| dict_get_str(m, "conversation_id"))
|
|
|
|
|
{
|
|
|
|
|
Some(id) => id,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing conversation_id"),
|
|
|
|
|
};
|
|
|
|
|
match agent.send_event(|r| Event::MarkConversationAsRead(conversation_id, r)).await {
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::MarkConversationAsRead(conversation_id, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(()) => make_ok_reply(),
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
}
|
|
|
|
|
@@ -100,10 +134,19 @@ pub async fn dispatch(
|
|
|
|
|
|
|
|
|
|
// GetMessages
|
|
|
|
|
"GetMessages" => {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") { Some(a) => a, None => return make_error_reply("InvalidRequest", "Missing arguments") };
|
|
|
|
|
let conversation_id = match dict_get_str(args, "conversation_id") { Some(id) => id, None => return make_error_reply("InvalidRequest", "Missing conversation_id") };
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") {
|
|
|
|
|
Some(a) => a,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing arguments"),
|
|
|
|
|
};
|
|
|
|
|
let conversation_id = match dict_get_str(args, "conversation_id") {
|
|
|
|
|
Some(id) => id,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing conversation_id"),
|
|
|
|
|
};
|
|
|
|
|
let last_message_id = dict_get_str(args, "last_message_id");
|
|
|
|
|
match agent.send_event(|r| Event::GetMessages(conversation_id, last_message_id, r)).await {
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::GetMessages(conversation_id, last_message_id, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(messages) => {
|
|
|
|
|
let mut items: Vec<Message> = Vec::with_capacity(messages.len());
|
|
|
|
|
for msg in messages {
|
|
|
|
|
@@ -131,14 +174,29 @@ pub async fn dispatch(
|
|
|
|
|
|
|
|
|
|
// SendMessage
|
|
|
|
|
"SendMessage" => {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") { Some(a) => a, None => return make_error_reply("InvalidRequest", "Missing arguments") };
|
|
|
|
|
let conversation_id = match dict_get_str(args, "conversation_id") { Some(v) => v, None => return make_error_reply("InvalidRequest", "Missing conversation_id") };
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") {
|
|
|
|
|
Some(a) => a,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing arguments"),
|
|
|
|
|
};
|
|
|
|
|
let conversation_id = match dict_get_str(args, "conversation_id") {
|
|
|
|
|
Some(v) => v,
|
|
|
|
|
None => return 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")) {
|
|
|
|
|
Some(Message::Array(arr)) => arr.iter().filter_map(|m| match m { Message::String(s) => Some(s.to_string_lossy().into_owned()), _ => None }).collect(),
|
|
|
|
|
Some(Message::Array(arr)) => arr
|
|
|
|
|
.iter()
|
|
|
|
|
.filter_map(|m| match m {
|
|
|
|
|
Message::String(s) => Some(s.to_string_lossy().into_owned()),
|
|
|
|
|
_ => None,
|
|
|
|
|
})
|
|
|
|
|
.collect(),
|
|
|
|
|
_ => Vec::new(),
|
|
|
|
|
};
|
|
|
|
|
match agent.send_event(|r| Event::SendMessage(conversation_id, text, attachment_guids, r)).await {
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::SendMessage(conversation_id, text, attachment_guids, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(uuid) => {
|
|
|
|
|
let mut reply: XpcMap = HashMap::new();
|
|
|
|
|
dict_put_str(&mut reply, "type", "SendMessageResponse");
|
|
|
|
|
@@ -151,16 +209,41 @@ pub async fn dispatch(
|
|
|
|
|
|
|
|
|
|
// GetAttachmentInfo
|
|
|
|
|
"GetAttachmentInfo" => {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") { Some(a) => a, None => return make_error_reply("InvalidRequest", "Missing arguments") };
|
|
|
|
|
let attachment_id = match dict_get_str(args, "attachment_id") { Some(v) => v, None => return make_error_reply("InvalidRequest", "Missing attachment_id") };
|
|
|
|
|
match agent.send_event(|r| Event::GetAttachment(attachment_id, r)).await {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") {
|
|
|
|
|
Some(a) => a,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing arguments"),
|
|
|
|
|
};
|
|
|
|
|
let attachment_id = match dict_get_str(args, "attachment_id") {
|
|
|
|
|
Some(v) => v,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing attachment_id"),
|
|
|
|
|
};
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::GetAttachment(attachment_id, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(attachment) => {
|
|
|
|
|
let mut reply: XpcMap = HashMap::new();
|
|
|
|
|
dict_put_str(&mut reply, "type", "GetAttachmentInfoResponse");
|
|
|
|
|
dict_put_str(&mut reply, "path", &attachment.get_path_for_preview(false).to_string_lossy());
|
|
|
|
|
dict_put_str(&mut reply, "preview_path", &attachment.get_path_for_preview(true).to_string_lossy());
|
|
|
|
|
dict_put_str(&mut reply, "downloaded", &attachment.is_downloaded(false).to_string());
|
|
|
|
|
dict_put_str(&mut reply, "preview_downloaded", &attachment.is_downloaded(true).to_string());
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut reply,
|
|
|
|
|
"path",
|
|
|
|
|
&attachment.get_path_for_preview(false).to_string_lossy(),
|
|
|
|
|
);
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut reply,
|
|
|
|
|
"preview_path",
|
|
|
|
|
&attachment.get_path_for_preview(true).to_string_lossy(),
|
|
|
|
|
);
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut reply,
|
|
|
|
|
"downloaded",
|
|
|
|
|
&attachment.is_downloaded(false).to_string(),
|
|
|
|
|
);
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut reply,
|
|
|
|
|
"preview_downloaded",
|
|
|
|
|
&attachment.is_downloaded(true).to_string(),
|
|
|
|
|
);
|
|
|
|
|
Message::Dictionary(reply)
|
|
|
|
|
}
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
@@ -169,10 +252,21 @@ pub async fn dispatch(
|
|
|
|
|
|
|
|
|
|
// DownloadAttachment
|
|
|
|
|
"DownloadAttachment" => {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") { Some(a) => a, None => return make_error_reply("InvalidRequest", "Missing arguments") };
|
|
|
|
|
let attachment_id = match dict_get_str(args, "attachment_id") { Some(v) => v, None => return make_error_reply("InvalidRequest", "Missing attachment_id") };
|
|
|
|
|
let preview = dict_get_str(args, "preview").map(|s| s == "true").unwrap_or(false);
|
|
|
|
|
match agent.send_event(|r| Event::DownloadAttachment(attachment_id, preview, r)).await {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") {
|
|
|
|
|
Some(a) => a,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing arguments"),
|
|
|
|
|
};
|
|
|
|
|
let attachment_id = match dict_get_str(args, "attachment_id") {
|
|
|
|
|
Some(v) => v,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing attachment_id"),
|
|
|
|
|
};
|
|
|
|
|
let preview = dict_get_str(args, "preview")
|
|
|
|
|
.map(|s| s == "true")
|
|
|
|
|
.unwrap_or(false);
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::DownloadAttachment(attachment_id, preview, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(()) => make_ok_reply(),
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
}
|
|
|
|
|
@@ -181,9 +275,18 @@ pub async fn dispatch(
|
|
|
|
|
// UploadAttachment
|
|
|
|
|
"UploadAttachment" => {
|
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") { Some(a) => a, None => return make_error_reply("InvalidRequest", "Missing arguments") };
|
|
|
|
|
let path = match dict_get_str(args, "path") { Some(v) => v, None => return make_error_reply("InvalidRequest", "Missing path") };
|
|
|
|
|
match agent.send_event(|r| Event::UploadAttachment(PathBuf::from(path), r)).await {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") {
|
|
|
|
|
Some(a) => a,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing arguments"),
|
|
|
|
|
};
|
|
|
|
|
let path = match dict_get_str(args, "path") {
|
|
|
|
|
Some(v) => v,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing path"),
|
|
|
|
|
};
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::UploadAttachment(PathBuf::from(path), r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(upload_guid) => {
|
|
|
|
|
let mut reply: XpcMap = HashMap::new();
|
|
|
|
|
dict_put_str(&mut reply, "type", "UploadAttachmentResponse");
|
|
|
|
|
@@ -199,18 +302,36 @@ pub async fn dispatch(
|
|
|
|
|
Ok(settings) => {
|
|
|
|
|
let mut reply: XpcMap = HashMap::new();
|
|
|
|
|
dict_put_str(&mut reply, "type", "GetAllSettingsResponse");
|
|
|
|
|
dict_put_str(&mut reply, "server_url", &settings.server_url.unwrap_or_default());
|
|
|
|
|
dict_put_str(&mut reply, "username", &settings.username.unwrap_or_default());
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut reply,
|
|
|
|
|
"server_url",
|
|
|
|
|
&settings.server_url.unwrap_or_default(),
|
|
|
|
|
);
|
|
|
|
|
dict_put_str(
|
|
|
|
|
&mut reply,
|
|
|
|
|
"username",
|
|
|
|
|
&settings.username.unwrap_or_default(),
|
|
|
|
|
);
|
|
|
|
|
Message::Dictionary(reply)
|
|
|
|
|
}
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
},
|
|
|
|
|
"UpdateSettings" => {
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") { Some(a) => a, None => return make_error_reply("InvalidRequest", "Missing arguments") };
|
|
|
|
|
let args = match get_dictionary_field(root, "arguments") {
|
|
|
|
|
Some(a) => a,
|
|
|
|
|
None => return make_error_reply("InvalidRequest", "Missing arguments"),
|
|
|
|
|
};
|
|
|
|
|
let server_url = dict_get_str(args, "server_url");
|
|
|
|
|
let username = dict_get_str(args, "username");
|
|
|
|
|
let settings = Settings { server_url, username, token: None };
|
|
|
|
|
match agent.send_event(|r| Event::UpdateSettings(settings, r)).await {
|
|
|
|
|
let settings = Settings {
|
|
|
|
|
server_url,
|
|
|
|
|
username,
|
|
|
|
|
token: None,
|
|
|
|
|
};
|
|
|
|
|
match agent
|
|
|
|
|
.send_event(|r| Event::UpdateSettings(settings, r))
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(()) => make_ok_reply(),
|
|
|
|
|
Err(e) => make_error_reply("DaemonError", &format!("{}", e)),
|
|
|
|
|
}
|
|
|
|
|
@@ -224,7 +345,7 @@ pub async fn dispatch(
|
|
|
|
|
log::trace!(target: LOG_TARGET, "Client subscribed to signals (total subscribers: {})", list.len());
|
|
|
|
|
}
|
|
|
|
|
make_ok_reply()
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unknown method fallback
|
|
|
|
|
other => make_error_reply("UnknownMethod", other),
|
|
|
|
|
|