mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 11:26:29 +03:00
Implement chatlist.to_json() method and chat.get_lastmsg_id()
This commit is contained in:
18
src/chat.rs
18
src/chat.rs
@@ -415,6 +415,24 @@ impl Chat {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_lastmsg_id(&self, context: &Context) -> Option<MsgId> {
|
||||||
|
context.sql.query_row(
|
||||||
|
"SELECT m.id
|
||||||
|
FROM chats c
|
||||||
|
LEFT JOIN msgs m
|
||||||
|
ON c.id=m.chat_id
|
||||||
|
AND m.timestamp=(
|
||||||
|
SELECT MAX(timestamp)
|
||||||
|
FROM msgs
|
||||||
|
WHERE chat_id=c.id
|
||||||
|
AND (hidden=0 OR state=?))
|
||||||
|
WHERE c.id=?
|
||||||
|
",
|
||||||
|
params![self.id],
|
||||||
|
|row: &rusqlite::Row| Ok(row.get(0)?)
|
||||||
|
).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the chat is archived.
|
/// Returns true if the chat is archived.
|
||||||
pub fn is_archived(&self) -> bool {
|
pub fn is_archived(&self) -> bool {
|
||||||
self.archived
|
self.archived
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use crate::error::Result;
|
|||||||
use crate::lot::Lot;
|
use crate::lot::Lot;
|
||||||
use crate::message::{Message, MessageState, MsgId};
|
use crate::message::{Message, MessageState, MsgId};
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// An object representing a single chatlist in memory.
|
/// An object representing a single chatlist in memory.
|
||||||
///
|
///
|
||||||
@@ -33,7 +34,7 @@ use crate::stock::StockMessage;
|
|||||||
/// first entry and only present on new messages, there is the rough idea that it can be optionally always
|
/// first entry and only present on new messages, there is the rough idea that it can be optionally always
|
||||||
/// present and sorted into the list by date. Rendering the deaddrop in the described way
|
/// present and sorted into the list by date. Rendering the deaddrop in the described way
|
||||||
/// would not add extra work in the UI then.
|
/// would not add extra work in the UI then.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Chatlist {
|
pub struct Chatlist {
|
||||||
/// Stores pairs of `chat_id, message_id`
|
/// Stores pairs of `chat_id, message_id`
|
||||||
ids: Vec<(ChatId, MsgId)>,
|
ids: Vec<(ChatId, MsgId)>,
|
||||||
@@ -231,6 +232,10 @@ impl Chatlist {
|
|||||||
Ok(Chatlist { ids })
|
Ok(Chatlist { ids })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_json(&self) -> String {
|
||||||
|
serde_json::to_string(&self.ids).unwrap_or_else(|_| "".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
/// Find out the number of chats.
|
/// Find out the number of chats.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.ids.len()
|
self.ids.len()
|
||||||
@@ -375,6 +380,11 @@ mod tests {
|
|||||||
assert_eq!(chats.get_chat_id(1), chat_id2);
|
assert_eq!(chats.get_chat_id(1), chat_id2);
|
||||||
assert_eq!(chats.get_chat_id(2), chat_id1);
|
assert_eq!(chats.get_chat_id(2), chat_id1);
|
||||||
|
|
||||||
|
assert_eq!(chats.to_json(), format!("[[{},{}],[{},{}],[{},{}]]",
|
||||||
|
chats.get_chat_id(0), chats.get_msg_id(0).map(|msg_id| msg_id.to_u32()).unwrap_or(0),
|
||||||
|
chats.get_chat_id(1), chats.get_msg_id(1).map(|msg_id| msg_id.to_u32()).unwrap_or(0),
|
||||||
|
chats.get_chat_id(2), chats.get_msg_id(2).map(|msg_id| msg_id.to_u32()).unwrap_or(0)));
|
||||||
|
|
||||||
// drafts are sorted to the top
|
// drafts are sorted to the top
|
||||||
let mut msg = Message::new(Viewtype::Text);
|
let mut msg = Message::new(Viewtype::Text);
|
||||||
msg.set_text(Some("hello".to_string()));
|
msg.set_text(Some("hello".to_string()));
|
||||||
@@ -382,16 +392,30 @@ mod tests {
|
|||||||
let chats = Chatlist::try_load(&t.ctx, 0, None, None).unwrap();
|
let chats = Chatlist::try_load(&t.ctx, 0, None, None).unwrap();
|
||||||
assert_eq!(chats.get_chat_id(0), chat_id2);
|
assert_eq!(chats.get_chat_id(0), chat_id2);
|
||||||
|
|
||||||
|
assert_eq!(chats.to_json(), format!("[[{},{}],[{},{}],[{},{}]]",
|
||||||
|
chats.get_chat_id(0), chats.get_msg_id(0).map(|msg_id| msg_id.to_u32()).unwrap_or(0),
|
||||||
|
chats.get_chat_id(1), chats.get_msg_id(1).map(|msg_id| msg_id.to_u32()).unwrap_or(0),
|
||||||
|
chats.get_chat_id(2), chats.get_msg_id(2).map(|msg_id| msg_id.to_u32()).unwrap_or(0)));
|
||||||
|
|
||||||
// check chatlist query and archive functionality
|
// check chatlist query and archive functionality
|
||||||
let chats = Chatlist::try_load(&t.ctx, 0, Some("b"), None).unwrap();
|
let chats = Chatlist::try_load(&t.ctx, 0, Some("b"), None).unwrap();
|
||||||
assert_eq!(chats.len(), 1);
|
assert_eq!(chats.len(), 1);
|
||||||
|
|
||||||
|
assert_eq!(chats.to_json(), format!("[[{},{}]]",
|
||||||
|
chats.get_chat_id(0), chats.get_msg_id(0).map(|msg_id| msg_id.to_u32()).unwrap_or(0)));
|
||||||
|
|
||||||
let chats = Chatlist::try_load(&t.ctx, DC_GCL_ARCHIVED_ONLY, None, None).unwrap();
|
let chats = Chatlist::try_load(&t.ctx, DC_GCL_ARCHIVED_ONLY, None, None).unwrap();
|
||||||
assert_eq!(chats.len(), 0);
|
assert_eq!(chats.len(), 0);
|
||||||
|
|
||||||
|
assert_eq!(chats.to_json(), "[]".to_string());
|
||||||
|
|
||||||
chat::archive(&t.ctx, chat_id1, true).ok();
|
chat::archive(&t.ctx, chat_id1, true).ok();
|
||||||
let chats = Chatlist::try_load(&t.ctx, DC_GCL_ARCHIVED_ONLY, None, None).unwrap();
|
let chats = Chatlist::try_load(&t.ctx, DC_GCL_ARCHIVED_ONLY, None, None).unwrap();
|
||||||
assert_eq!(chats.len(), 1);
|
assert_eq!(chats.len(), 1);
|
||||||
|
|
||||||
|
assert_eq!(chats.to_json(), format!("[[{},{}]]",
|
||||||
|
chats.get_chat_id(0), chats.get_msg_id(0).map(|msg_id| msg_id.to_u32()).unwrap_or(0)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use crate::param::*;
|
|||||||
use crate::pgp::*;
|
use crate::pgp::*;
|
||||||
use crate::sql;
|
use crate::sql;
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
// In practice, the user additionally cuts the string themselves
|
// In practice, the user additionally cuts the string themselves
|
||||||
// pixel-accurate.
|
// pixel-accurate.
|
||||||
@@ -29,7 +30,7 @@ const SUMMARY_CHARACTERS: usize = 160;
|
|||||||
/// Some message IDs are reserved to identify special message types.
|
/// Some message IDs are reserved to identify special message types.
|
||||||
/// This type can represent both the special as well as normal
|
/// This type can represent both the special as well as normal
|
||||||
/// messages.
|
/// messages.
|
||||||
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct MsgId(u32);
|
pub struct MsgId(u32);
|
||||||
|
|
||||||
impl MsgId {
|
impl MsgId {
|
||||||
|
|||||||
Reference in New Issue
Block a user