diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 1d26a802a..ff38042ba 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -2470,6 +2470,28 @@ uint32_t dc_chatlist_get_msg_id (const dc_chatlist_t* chatlist, siz dc_lot_t* dc_chatlist_get_summary (const dc_chatlist_t* chatlist, size_t index, dc_chat_t* chat); +/** + * Create a chatlist summary item when the chatlist object is already unref()'d. + * + * This function is similar to dc_chatlist_get_summary(), however, + * takes the chat-id and message-id as returned by dc_chatlist_get_chat_id() and dc_chatlist_get_msg_id() + * as arguments. The chatlist object itself is not needed directly. + * + * This maybe useful if you convert the complete object into a different represenation + * as done eg. in the node-bindings. + * If you have access to the chatlist object in some way, using this function is not recommended, + * use dc_chatlist_get_summary() in this case instead. + * + * @memberof dc_context_t + * @param context The context as created by dc_context_new() + * @param chat_id Chat to get a summary for. + * @param msg_id Messasge to get a summary for. + * @return The summary as an dc_lot_t object, see dc_chatlist_get_summary() for details. + * Must be freed using dc_lot_unref(). NULL is never returned. + */ +dc_lot_t* dc_chatlist_get_summary2 (dc_context_t* context, uint32_t chat_id, uint32_t msg_id); + + /** * Helper function to get the associated context object. * diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index aa0442318..fce9ac8b4 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -38,6 +38,7 @@ mod dc_array; mod string; use self::string::*; +use deltachat::chatlist::Chatlist; // as C lacks a good and portable error handling, // in general, the C Interface is forgiving wrt to bad parameters. @@ -2227,6 +2228,24 @@ pub unsafe extern "C" fn dc_chatlist_get_summary( }) } +#[no_mangle] +pub unsafe extern "C" fn dc_chatlist_get_summary2( + context: *mut dc_context_t, + chat_id: u32, + msg_id: u32, +) -> *mut dc_lot_t { + if context.is_null() { + eprintln!("ignoring careless call to dc_chatlist_get_summary2()"); + return ptr::null_mut(); + } + let ctx = &*context; + block_on(async move { + let lot = + Chatlist::get_summary2(&ctx, ChatId::new(chat_id), MsgId::new(msg_id), None).await; + Box::into_raw(Box::new(lot)) + }) +} + #[no_mangle] pub unsafe extern "C" fn dc_chatlist_get_context( chatlist: *mut dc_chatlist_t, diff --git a/src/chatlist.rs b/src/chatlist.rs index e4b332f5b..fbee5e1ed 100644 --- a/src/chatlist.rs +++ b/src/chatlist.rs @@ -329,20 +329,30 @@ impl Chatlist { // This is because we may want to display drafts here or stuff as // "is typing". // Also, sth. as "No messages" would not work if the summary comes from a message. - let mut ret = Lot::new(); - let (chat_id, lastmsg_id) = match self.ids.get(index) { Some(ids) => ids, None => { + let mut ret = Lot::new(); ret.text2 = Some("ErrBadChatlistIndex".to_string()); - return ret; + return Lot::new(); } }; + Chatlist::get_summary2(context, *chat_id, *lastmsg_id, chat).await + } + + pub async fn get_summary2( + context: &Context, + chat_id: ChatId, + lastmsg_id: MsgId, + chat: Option<&Chat>, + ) -> Lot { + let mut ret = Lot::new(); + let chat_loaded: Chat; let chat = if let Some(chat) = chat { chat - } else if let Ok(chat) = Chat::load_from_db(context, *chat_id).await { + } else if let Ok(chat) = Chat::load_from_db(context, chat_id).await { chat_loaded = chat; &chat_loaded } else { @@ -351,7 +361,7 @@ impl Chatlist { let mut lastcontact = None; - let lastmsg = if let Ok(lastmsg) = Message::load_from_db(context, *lastmsg_id).await { + let lastmsg = if let Ok(lastmsg) = Message::load_from_db(context, lastmsg_id).await { if lastmsg.from_id != DC_CONTACT_ID_SELF && (chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup) {