Compare commits

...

1 Commits

Author SHA1 Message Date
Simon Laux
439d09ebb5 add chat.get_summary
(returns a lot like the original function chatlit.getsummary
 but it doesn't need a chatlist to work)
2020-07-15 22:51:21 +02:00
4 changed files with 125 additions and 2 deletions

View File

@@ -2439,6 +2439,32 @@ dc_lot_t* dc_chatlist_get_summary (const dc_chatlist_t* chatlist, siz
dc_context_t* dc_chatlist_get_context (dc_chatlist_t* chatlist);
/**
* Get a summary for a chat (same as dc_chatlist_get_summary only without the chatlist).
*
* The summary is returned by a dc_lot_t object with the following fields:
*
* - dc_lot_t::text1: contains the username or the strings "Me", "Draft" and so on.
* The string may be colored by having a look at text1_meaning.
* If there is no such name or it should not be displayed, the element is NULL.
*
* - dc_lot_t::text1_meaning: one of DC_TEXT1_USERNAME, DC_TEXT1_SELF or DC_TEXT1_DRAFT.
* Typically used to show dc_lot_t::text1 with different colors. 0 if not applicable.
*
* - dc_lot_t::text2: contains an excerpt of the message text or strings as
* "No messages". May be NULL of there is no such text (eg. for the archive link)
*
* - dc_lot_t::timestamp: the timestamp of the message. 0 if not applicable.
*
* - dc_lot_t::state: The state of the message as one of the DC_STATE_* constants (see #dc_msg_get_state()). 0 if not applicable.
*
* @memberof dc_chat_t
* @param context
* @param chat The chat object.
* @return The summary as an dc_lot_t object. Must be freed using dc_lot_unref(). NULL is never returned.
*/
dc_lot_t* dc_chat_get_summary (dc_context_t* context, dc_chat_t* chat);
/**
* Get info summary for a chat, in json format.
*

View File

@@ -2319,6 +2319,23 @@ pub unsafe extern "C" fn dc_chat_get_visibility(chat: *mut dc_chat_t) -> libc::c
}
}
#[no_mangle]
pub unsafe extern "C" fn dc_chat_get_summary(
context: *mut dc_context_t,
chat: *mut dc_chat_t,
) -> *mut dc_lot_t {
if chat.is_null() {
eprintln!("ignoring careless call to dc_chat_get_summary()");
return ptr::null_mut();
}
let ffi_chat = &*chat;
let ctx = &*context;
block_on(async move {
let lot = ffi_chat.chat.get_summary(&ctx).await;
Box::into_raw(Box::new(lot))
})
}
#[no_mangle]
pub unsafe extern "C" fn dc_chat_is_unpromoted(chat: *mut dc_chat_t) -> libc::c_int {
if chat.is_null() {

View File

@@ -5,7 +5,7 @@ import calendar
import json
from datetime import datetime
import os
from .cutil import as_dc_charpointer, from_dc_charpointer, iter_array
from .cutil import as_dc_charpointer, from_dc_charpointer, iter_array, DCLot
from .capi import lib, ffi
from . import const
from .message import Message
@@ -344,6 +344,11 @@ class Chat(object):
s = from_dc_charpointer(dc_res)
return json.loads(s)
def get_summary_lot(self):
""" return summary lot of chat (used for displaying last message in a chatlist)"""
lot = lib.dc_chat_get_summary(self.account._dc_context, self._dc_chat)
return DCLot(lot)
# ------ group management API ------------------------------
def add_contact(self, obj):

View File

@@ -23,7 +23,7 @@ use crate::message::{self, InvalidMsgId, Message, MessageState, MsgId};
use crate::mimeparser::SystemMessage;
use crate::param::*;
use crate::sql;
use crate::stock::StockMessage;
use crate::{lot::Lot, stock::StockMessage};
/// An chat item, such as a message or a marker.
#[derive(Debug, Copy, Clone)]
@@ -734,6 +734,65 @@ impl Chat {
})
}
/// Version of get_summary that just needs the chat no chatlist required
pub async fn get_summary(&self, context: &Context) -> Lot {
// The summary is created by the chat, not by the last message.
// 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 lastmsg_id = context
.sql
.query_row(
concat!(
"SELECT id, chat_id",
" FROM msgs",
" WHERE chat_id = ?",
" ORDER BY id DESC",
" LIMIT 1"
),
paramsv![self.id],
|row| {
let msg_id: MsgId = row.get("id")?;
Ok(msg_id)
},
)
.await
.unwrap_or_default();
let mut lastcontact = None;
let lastmsg = if let Ok(lastmsg) = Message::load_from_db(context, lastmsg_id).await {
if lastmsg.from_id != DC_CONTACT_ID_SELF
&& (self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup)
{
lastcontact = Contact::load_from_db(context, lastmsg.from_id).await.ok();
}
Some(lastmsg)
} else {
None
};
if self.id.is_archived_link() {
ret.text2 = None;
} else if lastmsg.is_none() || lastmsg.as_ref().unwrap().from_id == DC_CONTACT_ID_UNDEFINED
{
ret.text2 = Some(
context
.stock_str(StockMessage::NoMessages)
.await
.to_string(),
);
} else {
ret.fill(&mut lastmsg.unwrap(), self, lastcontact.as_ref(), context)
.await;
}
ret
}
pub fn get_visibility(&self) -> ChatVisibility {
self.visibility
}
@@ -3497,4 +3556,20 @@ mod tests {
chat_id.set_draft(&t.ctx, Some(&mut msg)).await;
assert!(!chat_id.parent_is_encrypted(&t.ctx).await.unwrap());
}
#[async_std::test]
async fn test_get_summary_unwrap() {
let t = TestContext::new().await;
let chat_id1 = create_group_chat(&t.ctx, VerifiedStatus::Unverified, "a chat")
.await
.unwrap();
let mut msg = Message::new(Viewtype::Text);
msg.set_text(Some("foo:\nbar \r\n test".to_string()));
chat_id1.set_draft(&t.ctx, Some(&mut msg)).await;
let chat = Chat::load_from_db(&t.ctx, chat_id1).await.unwrap();
let summary = chat.get_summary(&t.ctx).await;
assert_eq!(summary.get_text2().unwrap(), "foo: bar test"); // the linebreak should be removed from summary
}
}