mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +03:00
add get_chat_list_item_by_id method
why? because desktop currently fetches the chatlist multiple times, even though it just needs the chatlistitem for one chat Note: @r10s was worried before that exposing the method to get a single updated chatlistitem could lead to race conditions where the chatlist item is newer than the chatlist order. But I don't think this will change anything for desktop besides making it a little faster. (because currently desktop fetches the whole chatlist instead of just the entry it needs when an entry updates)
This commit is contained in:
@@ -4,7 +4,7 @@ use deltachat::{
|
|||||||
self, add_contact_to_chat, forward_msgs, get_chat_media, get_chat_msgs, marknoticed_chat,
|
self, add_contact_to_chat, forward_msgs, get_chat_media, get_chat_msgs, marknoticed_chat,
|
||||||
remove_contact_from_chat, Chat, ChatId, ChatItem, ProtectionStatus,
|
remove_contact_from_chat, Chat, ChatId, ChatItem, ProtectionStatus,
|
||||||
},
|
},
|
||||||
chatlist::Chatlist,
|
chatlist::{get_chatlistitem_for_chat, Chatlist},
|
||||||
config::Config,
|
config::Config,
|
||||||
constants::DC_MSG_ID_DAYMARKER,
|
constants::DC_MSG_ID_DAYMARKER,
|
||||||
contact::{may_be_valid_addr, Contact, ContactId, Origin},
|
contact::{may_be_valid_addr, Contact, ContactId, Origin},
|
||||||
@@ -439,12 +439,27 @@ impl CommandApi {
|
|||||||
for i in 0..list.len() {
|
for i in 0..list.len() {
|
||||||
l.push(ChatListEntry(
|
l.push(ChatListEntry(
|
||||||
list.get_chat_id(i)?.to_u32(),
|
list.get_chat_id(i)?.to_u32(),
|
||||||
list.get_msg_id(i)?.unwrap_or_default().to_u32(),
|
list.get_msg_id(i)?.map(|msg_id| msg_id.to_u32()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Ok(l)
|
Ok(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a chat list entry for a specific chat,
|
||||||
|
/// you should prefer using `get_chatlist_entries` unless you need this function for your virtual list needs like desktop
|
||||||
|
async fn get_chatlist_entry_by_chat(
|
||||||
|
&self,
|
||||||
|
account_id: u32,
|
||||||
|
chat_id: u32,
|
||||||
|
) -> Result<ChatListEntry> {
|
||||||
|
let ctx = self.get_context(account_id).await?;
|
||||||
|
let (chat_id, message_id) = get_chatlistitem_for_chat(&ctx, ChatId::new(chat_id)).await?;
|
||||||
|
Ok(ChatListEntry(
|
||||||
|
chat_id.to_u32(),
|
||||||
|
message_id.map(|msg_id| msg_id.to_u32()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_chatlist_items_by_entries(
|
async fn get_chatlist_items_by_entries(
|
||||||
&self,
|
&self,
|
||||||
account_id: u32,
|
account_id: u32,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use typescript_type_def::TypeDef;
|
|||||||
use super::color_int_to_hex_string;
|
use super::color_int_to_hex_string;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeDef)]
|
#[derive(Deserialize, Serialize, TypeDef)]
|
||||||
pub struct ChatListEntry(pub u32, pub u32);
|
pub struct ChatListEntry(pub u32, pub Option<u32>);
|
||||||
|
|
||||||
#[derive(Serialize, TypeDef)]
|
#[derive(Serialize, TypeDef)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
@@ -59,10 +59,7 @@ pub(crate) async fn get_chat_list_item_by_id(
|
|||||||
entry: &ChatListEntry,
|
entry: &ChatListEntry,
|
||||||
) -> Result<ChatListItemFetchResult> {
|
) -> Result<ChatListItemFetchResult> {
|
||||||
let chat_id = ChatId::new(entry.0);
|
let chat_id = ChatId::new(entry.0);
|
||||||
let last_msgid = match entry.1 {
|
let last_msgid = entry.1.map(|msg_id| MsgId::new(msg_id));
|
||||||
0 => None,
|
|
||||||
_ => Some(MsgId::new(entry.1)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let fresh_message_counter = chat_id.get_fresh_msg_cnt(ctx).await?;
|
let fresh_message_counter = chat_id.get_fresh_msg_cnt(ctx).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -362,6 +362,38 @@ pub async fn get_archived_cnt(context: &Context) -> Result<usize> {
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a single chatlistitem (chatId and messageid), used by desktop to partially update the chatlist on specific events
|
||||||
|
pub async fn get_chatlistitem_for_chat(
|
||||||
|
context: &Context,
|
||||||
|
chat_id: ChatId,
|
||||||
|
) -> Result<(ChatId, Option<MsgId>)> {
|
||||||
|
// Similar result as normal chatlist, only one item though and:
|
||||||
|
// archived and blocked chats are included
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.query_row(
|
||||||
|
"SELECT c.id, m.id
|
||||||
|
FROM chats c
|
||||||
|
LEFT JOIN msgs m
|
||||||
|
ON c.id=m.chat_id
|
||||||
|
AND m.id=(
|
||||||
|
SELECT id
|
||||||
|
FROM msgs
|
||||||
|
WHERE chat_id=c.id
|
||||||
|
AND (hidden=0 OR state=?1)
|
||||||
|
ORDER BY timestamp DESC, id DESC LIMIT 1)
|
||||||
|
WHERE c.id=?2
|
||||||
|
GROUP BY c.id",
|
||||||
|
paramsv![MessageState::OutDraft, chat_id],
|
||||||
|
|row: &rusqlite::Row| {
|
||||||
|
let chat_id: ChatId = row.get(0)?;
|
||||||
|
let msg_id: Option<MsgId> = row.get(1)?;
|
||||||
|
Ok((chat_id, msg_id))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user