aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-03-24 11:14:52 +0000
committerLibravatar cel 🌸 <cel@bunny.garden>2025-03-24 11:14:52 +0000
commit9f0a480bc4c6ee3ac8c707b05d40529afef0d78f (patch)
tree2e7fea9f07a12692f4b4d8dfd211918026acc8f0
parentb81f7f5bb418fb64211e5ec711cbcbecf8a681aa (diff)
downloadluz-9f0a480bc4c6ee3ac8c707b05d40529afef0d78f.tar.gz
luz-9f0a480bc4c6ee3ac8c707b05d40529afef0d78f.tar.bz2
luz-9f0a480bc4c6ee3ac8c707b05d40529afef0d78f.zip
feat(luz): get_chats_ordered_with_latest_messages and get_chats_ordered
-rw-r--r--luz/src/db/mod.rs26
-rw-r--r--luz/src/lib.rs52
2 files changed, 78 insertions, 0 deletions
diff --git a/luz/src/db/mod.rs b/luz/src/db/mod.rs
index d9fb3e3..aea40ac 100644
--- a/luz/src/db/mod.rs
+++ b/luz/src/db/mod.rs
@@ -333,6 +333,32 @@ impl Db {
Ok(chats)
}
+ /// chats ordered by date of last message
+ // greatest-n-per-group
+ pub(crate) async fn read_chats_ordered_with_latest_messages(
+ &self,
+ ) -> Result<Vec<(Chat, Message)>, Error> {
+ #[derive(sqlx::FromRow)]
+ pub struct ChatWithMessage {
+ #[sqlx(flatten)]
+ pub chat: Chat,
+ #[sqlx(flatten)]
+ pub message: Message,
+ }
+
+ // TODO: i don't know if this will assign the right uuid to the latest message or the chat's id. should probably check but i don't think it matters as nothing ever gets called with the id of the latest message in the chats list
+ let chats: Vec<ChatWithMessage> = sqlx::query_as("select c.*, m.* from chats c join (select chat_id, max(timestamp) max_timestamp from messages group by chat_id) max_timestamps on c.id = max_timestamps.chat_id join messages m on max_timestamps.chat_id = m.chat_id and max_timestamps.max_timestamp = m.timestamp order by m.timestamp desc")
+ .fetch_all(&self.db)
+ .await?;
+
+ let chats = chats
+ .into_iter()
+ .map(|chat_with_message| (chat_with_message.chat, chat_with_message.message))
+ .collect();
+
+ Ok(chats)
+ }
+
async fn read_chat_id(&self, chat: JID) -> Result<Uuid, Error> {
#[derive(sqlx::FromRow)]
struct Row {
diff --git a/luz/src/lib.rs b/luz/src/lib.rs
index f7d8a23..b87891d 100644
--- a/luz/src/lib.rs
+++ b/luz/src/lib.rs
@@ -323,9 +323,20 @@ impl CommandMessage {
}
}
CommandMessage::GetChats(sender) => {
+ let chats = db.read_chats().await.map_err(|e| e.into());
+ sender.send(chats);
+ }
+ CommandMessage::GetChatsOrdered(sender) => {
let chats = db.read_chats_ordered().await.map_err(|e| e.into());
sender.send(chats);
}
+ CommandMessage::GetChatsOrderedWithLatestMessages(sender) => {
+ let chats = db
+ .read_chats_ordered_with_latest_messages()
+ .await
+ .map_err(|e| e.into());
+ sender.send(chats);
+ }
CommandMessage::GetChat(jid, sender) => {
let chats = db.read_chat(jid).await.map_err(|e| e.into());
sender.send(chats);
@@ -509,9 +520,20 @@ impl CommandMessage {
}
}
CommandMessage::GetChats(sender) => {
+ let chats = db.read_chats().await.map_err(|e| e.into());
+ sender.send(chats);
+ }
+ CommandMessage::GetChatsOrdered(sender) => {
let chats = db.read_chats_ordered().await.map_err(|e| e.into());
sender.send(chats);
}
+ CommandMessage::GetChatsOrderedWithLatestMessages(sender) => {
+ let chats = db
+ .read_chats_ordered_with_latest_messages()
+ .await
+ .map_err(|e| e.into());
+ sender.send(chats);
+ }
CommandMessage::GetChat(jid, sender) => {
let chats = db.read_chat(jid).await.map_err(|e| e.into());
sender.send(chats);
@@ -1133,6 +1155,32 @@ impl LuzHandle {
Ok(chats)
}
+ pub async fn get_chats_ordered(&self) -> Result<Vec<Chat>, CommandError<DatabaseError>> {
+ let (send, recv) = oneshot::channel();
+ self.send(CommandMessage::GetChatsOrdered(send))
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
+ let chats = timeout(self.timeout, recv)
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
+ Ok(chats)
+ }
+
+ pub async fn get_chats_ordered_with_latest_messages(
+ &self,
+ ) -> Result<Vec<(Chat, Message)>, CommandError<DatabaseError>> {
+ let (send, recv) = oneshot::channel();
+ self.send(CommandMessage::GetChatsOrderedWithLatestMessages(send))
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
+ let chats = timeout(self.timeout, recv)
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
+ Ok(chats)
+ }
+
pub async fn get_chat(&self, jid: JID) -> Result<Chat, CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CommandMessage::GetChat(jid, send))
@@ -1360,6 +1408,10 @@ pub enum CommandMessage {
/// get all chats. chat will include 10 messages in their message Vec (enough for chat previews)
// TODO: paging and filtering
GetChats(oneshot::Sender<Result<Vec<Chat>, DatabaseError>>),
+ // TODO: paging and filtering
+ GetChatsOrdered(oneshot::Sender<Result<Vec<Chat>, DatabaseError>>),
+ // TODO: paging and filtering
+ GetChatsOrderedWithLatestMessages(oneshot::Sender<Result<Vec<(Chat, Message)>, DatabaseError>>),
/// get a specific chat by jid
GetChat(JID, oneshot::Sender<Result<Chat, DatabaseError>>),
/// get message history for chat (does appropriate mam things)