Skip to content

Commit 3b6fb20

Browse files
committed
feat: jsonrpc: add create_draft, draft_set_text, draft_set_subject, draft_set_quoted_message, draft_set_quoted_text
1 parent 187274d commit 3b6fb20

File tree

2 files changed

+139
-1
lines changed

2 files changed

+139
-1
lines changed

deltachat-jsonrpc/src/api.rs

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use types::chat::FullChat;
4949
use types::contact::{ContactObject, VcardContact};
5050
use types::events::Event;
5151
use types::http::HttpResponse;
52-
use types::message::{MessageData, MessageObject, MessageReadReceipt};
52+
use types::message::{MessageData, MessageObject, MessageReadReceipt, QuotedText};
5353
use types::provider_info::ProviderInfo;
5454
use types::reactions::JSONRPCReactions;
5555
use types::webxdc::WebxdcMessageInfo;
@@ -2022,6 +2022,133 @@ impl CommandApi {
20222022
}
20232023
}
20242024

2025+
/// Create a new draft (overwriting existing draft)
2026+
///
2027+
/// You can modify some fields of an existing draft while keeping it's message id (important to keep webxdc status updates) with the following methods:
2028+
/// - [Self::draft_set_text]
2029+
/// - [Self::draft_set_quoted_message]
2030+
/// - [Self::draft_set_quoted_text]
2031+
/// For other actions like changing the view type or file attachment you have to recreate the draft.
2032+
///
2033+
/// You can send the draft with [Self::send_draft]
2034+
async fn create_draft(&self, account_id: u32, chat_id: u32, data: MessageData) -> Result<u32> {
2035+
let ctx = self.get_context(account_id).await?;
2036+
let mut message = data
2037+
.create_message(&ctx)
2038+
.await
2039+
.context("Failed to create message")?;
2040+
2041+
ChatId::new(chat_id)
2042+
.set_draft(&ctx, Some(&mut message))
2043+
.await
2044+
.context("Failed to set draft message")?;
2045+
Ok(message.get_id().to_u32())
2046+
}
2047+
2048+
/// set text of draft
2049+
async fn draft_set_text(&self, account_id: u32, msg_id: u32, text: String) -> Result<()> {
2050+
let ctx = self.get_context(account_id).await?;
2051+
let mut message = message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await?;
2052+
2053+
if message.get_state() != deltachat::message::MessageState::OutDraft {
2054+
bail!("provided message is not a draft");
2055+
}
2056+
2057+
message.set_text(text);
2058+
message
2059+
.get_chat_id()
2060+
.set_draft(&ctx, Some(&mut message))
2061+
.await?;
2062+
2063+
Ok(())
2064+
}
2065+
2066+
/// set (email) subject of draft
2067+
async fn draft_set_subject(&self, account_id: u32, msg_id: u32, subject: String) -> Result<()> {
2068+
let ctx = self.get_context(account_id).await?;
2069+
let mut message = message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await?;
2070+
2071+
if message.get_state() != deltachat::message::MessageState::OutDraft {
2072+
bail!("provided message is not a draft");
2073+
}
2074+
2075+
message.set_subject(subject);
2076+
message
2077+
.get_chat_id()
2078+
.set_draft(&ctx, Some(&mut message))
2079+
.await?;
2080+
2081+
Ok(())
2082+
}
2083+
2084+
/// set quoted message id of draft
2085+
async fn draft_set_quoted_message(
2086+
&self,
2087+
account_id: u32,
2088+
msg_id: u32,
2089+
quoted_message_id: Option<u32>,
2090+
) -> Result<()> {
2091+
let ctx = self.get_context(account_id).await?;
2092+
let mut message = message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await?;
2093+
2094+
if message.get_state() != deltachat::message::MessageState::OutDraft {
2095+
bail!("provided message is not a draft");
2096+
}
2097+
2098+
let message_to_qoute = match quoted_message_id {
2099+
Some(msg_id) => Some(message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await?),
2100+
None => None,
2101+
};
2102+
2103+
message.set_quote(&ctx, message_to_qoute.as_ref()).await?;
2104+
message
2105+
.get_chat_id()
2106+
.set_draft(&ctx, Some(&mut message))
2107+
.await?;
2108+
2109+
Ok(())
2110+
}
2111+
2112+
/// set quoted text of draft
2113+
async fn draft_set_quoted_text(
2114+
&self,
2115+
account_id: u32,
2116+
msg_id: u32,
2117+
quoted_text: Option<QuotedText>,
2118+
) -> Result<()> {
2119+
let ctx = self.get_context(account_id).await?;
2120+
let mut message = message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await?;
2121+
2122+
if message.get_state() != deltachat::message::MessageState::OutDraft {
2123+
bail!("provided message is not a draft");
2124+
}
2125+
2126+
message.set_quote_text(quoted_text.map(|qt| (qt.text, qt.protect)));
2127+
2128+
message
2129+
.get_chat_id()
2130+
.set_draft(&ctx, Some(&mut message))
2131+
.await?;
2132+
2133+
Ok(())
2134+
}
2135+
2136+
/// send draft
2137+
async fn send_draft(&self, account_id: u32, msg_id: u32) -> Result<u32> {
2138+
// uses message id instead of chat id to force ui to have the right message id / know about the draft - reduce the chance of undefined behaviour
2139+
let ctx = self.get_context(account_id).await?;
2140+
let mut draft = message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await?;
2141+
2142+
if draft.get_state() != deltachat::message::MessageState::OutDraft {
2143+
bail!("provided message is not a draft");
2144+
}
2145+
2146+
let chat = draft.get_chat_id();
2147+
let msg_id = chat::send_msg(&ctx, chat, &mut draft).await?.to_u32();
2148+
Ok(msg_id)
2149+
}
2150+
2151+
20252152
async fn send_videochat_invitation(&self, account_id: u32, chat_id: u32) -> Result<u32> {
20262153
let ctx = self.get_context(account_id).await?;
20272154
chat::send_videochat_invitation(&ctx, ChatId::new(chat_id))

deltachat-jsonrpc/src/api/types/message.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,3 +708,14 @@ impl From<deltachat::ephemeral::Timer> for EphemeralTimer {
708708
}
709709
}
710710
}
711+
712+
713+
#[derive(Deserialize, Serialize, TypeDef, schemars::JsonSchema)]
714+
#[serde(rename_all = "camelCase")]
715+
pub struct QuotedText {
716+
/// Text shown in the Quote
717+
pub text: String,
718+
/// protect specifies whether text should only be sent encrypted.
719+
/// If it should, but the message is unencrypted, text is replaced with "...".
720+
pub protect: bool
721+
}

0 commit comments

Comments
 (0)