mirror of
https://github.com/chatmail/core.git
synced 2026-04-22 16:06:30 +03:00
jsonrpc: Remove message id from chatlist item (#3071)
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:
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- BREAKING: jsonrpc:
|
||||||
|
- `get_chatlist_items_by_entries` now takes only chatids instead of `ChatListEntries`
|
||||||
|
- `get_chatlist_entries` now returns `Vec<u32>` of chatids instead of `ChatListEntries`
|
||||||
|
|
||||||
|
|
||||||
## [1.114.0] - 2023-04-24
|
## [1.114.0] - 2023-04-24
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ pub mod types;
|
|||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use types::account::Account;
|
use types::account::Account;
|
||||||
use types::chat::FullChat;
|
use types::chat::FullChat;
|
||||||
use types::chat_list::ChatListEntry;
|
|
||||||
use types::contact::ContactObject;
|
use types::contact::ContactObject;
|
||||||
use types::http::HttpResponse;
|
use types::http::HttpResponse;
|
||||||
use types::message::MessageData;
|
use types::message::MessageData;
|
||||||
@@ -549,7 +548,7 @@ impl CommandApi {
|
|||||||
list_flags: Option<u32>,
|
list_flags: Option<u32>,
|
||||||
query_string: Option<String>,
|
query_string: Option<String>,
|
||||||
query_contact_id: Option<u32>,
|
query_contact_id: Option<u32>,
|
||||||
) -> Result<Vec<ChatListEntry>> {
|
) -> Result<Vec<u32>> {
|
||||||
let ctx = self.get_context(account_id).await?;
|
let ctx = self.get_context(account_id).await?;
|
||||||
let list = Chatlist::try_load(
|
let list = Chatlist::try_load(
|
||||||
&ctx,
|
&ctx,
|
||||||
@@ -558,12 +557,9 @@ impl CommandApi {
|
|||||||
query_contact_id.map(ContactId::new),
|
query_contact_id.map(ContactId::new),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let mut l: Vec<ChatListEntry> = Vec::with_capacity(list.len());
|
let mut l: Vec<u32> = Vec::with_capacity(list.len());
|
||||||
for i in 0..list.len() {
|
for i in 0..list.len() {
|
||||||
l.push(ChatListEntry(
|
l.push(list.get_chat_id(i)?.to_u32());
|
||||||
list.get_chat_id(i)?.to_u32(),
|
|
||||||
list.get_msg_id(i)?.unwrap_or_default().to_u32(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Ok(l)
|
Ok(l)
|
||||||
}
|
}
|
||||||
@@ -571,19 +567,18 @@ impl CommandApi {
|
|||||||
async fn get_chatlist_items_by_entries(
|
async fn get_chatlist_items_by_entries(
|
||||||
&self,
|
&self,
|
||||||
account_id: u32,
|
account_id: u32,
|
||||||
entries: Vec<ChatListEntry>,
|
entries: Vec<u32>,
|
||||||
) -> Result<HashMap<u32, ChatListItemFetchResult>> {
|
) -> Result<HashMap<u32, ChatListItemFetchResult>> {
|
||||||
// todo custom json deserializer for ChatListEntry?
|
|
||||||
let ctx = self.get_context(account_id).await?;
|
let ctx = self.get_context(account_id).await?;
|
||||||
let mut result: HashMap<u32, ChatListItemFetchResult> =
|
let mut result: HashMap<u32, ChatListItemFetchResult> =
|
||||||
HashMap::with_capacity(entries.len());
|
HashMap::with_capacity(entries.len());
|
||||||
for entry in entries.iter() {
|
for &entry in entries.iter() {
|
||||||
result.insert(
|
result.insert(
|
||||||
entry.0,
|
entry,
|
||||||
match get_chat_list_item_by_id(&ctx, entry).await {
|
match get_chat_list_item_by_id(&ctx, entry).await {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => ChatListItemFetchResult::Error {
|
Err(err) => ChatListItemFetchResult::Error {
|
||||||
id: entry.0,
|
id: entry,
|
||||||
error: format!("{err:#}"),
|
error: format!("{err:#}"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use deltachat::chat::{Chat, ChatId};
|
||||||
|
use deltachat::chatlist::get_last_message_for_chat;
|
||||||
use deltachat::constants::*;
|
use deltachat::constants::*;
|
||||||
use deltachat::contact::{Contact, ContactId};
|
use deltachat::contact::{Contact, ContactId};
|
||||||
use deltachat::{
|
use deltachat::{
|
||||||
chat::{get_chat_contacts, ChatVisibility},
|
chat::{get_chat_contacts, ChatVisibility},
|
||||||
chatlist::Chatlist,
|
chatlist::Chatlist,
|
||||||
};
|
};
|
||||||
use deltachat::{
|
|
||||||
chat::{Chat, ChatId},
|
|
||||||
message::MsgId,
|
|
||||||
};
|
|
||||||
use num_traits::cast::ToPrimitive;
|
use num_traits::cast::ToPrimitive;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::Serialize;
|
||||||
use typescript_type_def::TypeDef;
|
use typescript_type_def::TypeDef;
|
||||||
|
|
||||||
use super::color_int_to_hex_string;
|
use super::color_int_to_hex_string;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeDef)]
|
|
||||||
pub struct ChatListEntry(pub u32, pub u32);
|
|
||||||
|
|
||||||
#[derive(Serialize, TypeDef)]
|
#[derive(Serialize, TypeDef)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ChatListItemFetchResult {
|
pub enum ChatListItemFetchResult {
|
||||||
@@ -56,14 +51,9 @@ pub enum ChatListItemFetchResult {
|
|||||||
|
|
||||||
pub(crate) async fn get_chat_list_item_by_id(
|
pub(crate) async fn get_chat_list_item_by_id(
|
||||||
ctx: &deltachat::context::Context,
|
ctx: &deltachat::context::Context,
|
||||||
entry: &ChatListEntry,
|
entry: u32,
|
||||||
) -> Result<ChatListItemFetchResult> {
|
) -> Result<ChatListItemFetchResult> {
|
||||||
let chat_id = ChatId::new(entry.0);
|
let chat_id = ChatId::new(entry);
|
||||||
let last_msgid = match entry.1 {
|
|
||||||
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?;
|
||||||
|
|
||||||
if chat_id.is_archived_link() {
|
if chat_id.is_archived_link() {
|
||||||
@@ -72,6 +62,8 @@ pub(crate) async fn get_chat_list_item_by_id(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let last_msgid = get_last_message_for_chat(ctx, chat_id).await?;
|
||||||
|
|
||||||
let chat = Chat::load_from_db(ctx, chat_id).await?;
|
let chat = Chat::load_from_db(ctx, chat_id).await?;
|
||||||
let summary = Chatlist::get_summary2(ctx, chat_id, last_msgid, Some(&chat)).await?;
|
let summary = Chatlist::get_summary2(ctx, chat_id, last_msgid, Some(&chat)).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ async function run() {
|
|||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
for (const [chatId, _messageId] of chats) {
|
for (const chatId of chats) {
|
||||||
const chat = await client.rpc.getFullChatById(selectedAccount, chatId);
|
const chat = await client.rpc.getFullChatById(selectedAccount, chatId);
|
||||||
write($main, `<h3>${chat.name}</h3>`);
|
write($main, `<h3>${chat.name}</h3>`);
|
||||||
const messageIds = await client.rpc.getMessageIds(
|
const messageIds = await client.rpc.getMessageIds(
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ class Account:
|
|||||||
|
|
||||||
entries = await self._rpc.get_chatlist_entries(self.id, flags, query, contact and contact.id)
|
entries = await self._rpc.get_chatlist_entries(self.id, flags, query, contact and contact.id)
|
||||||
if not snapshot:
|
if not snapshot:
|
||||||
return [Chat(self, entry[0]) for entry in entries]
|
return [Chat(self, entry) for entry in entries]
|
||||||
|
|
||||||
items = await self._rpc.get_chatlist_items_by_entries(self.id, entries)
|
items = await self._rpc.get_chatlist_items_by_entries(self.id, entries)
|
||||||
chats = []
|
chats = []
|
||||||
|
|||||||
@@ -362,6 +362,25 @@ pub async fn get_archived_cnt(context: &Context) -> Result<usize> {
|
|||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the last message of a chat, the message that would also be displayed in the ChatList
|
||||||
|
/// Used for passing to `deltachat::chatlist::Chatlist::get_summary2`
|
||||||
|
pub async fn get_last_message_for_chat(
|
||||||
|
context: &Context,
|
||||||
|
chat_id: ChatId,
|
||||||
|
) -> Result<Option<MsgId>> {
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.query_get_value(
|
||||||
|
"SELECT id
|
||||||
|
FROM msgs
|
||||||
|
WHERE chat_id=?2
|
||||||
|
AND (hidden=0 OR state=?1)
|
||||||
|
ORDER BY timestamp DESC, id DESC LIMIT 1",
|
||||||
|
(MessageState::OutDraft, chat_id),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user