From e3b08fa92be93749523bb4135d10ca728347205c Mon Sep 17 00:00:00 2001 From: iequidoo Date: Sat, 21 Oct 2023 01:59:40 -0300 Subject: [PATCH] feat: Sync chat visibility across devices (#4817) --- src/chat.rs | 24 ++++++++++++++---------- src/sync.rs | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index f973b8bd3..374c7eb3a 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -10,6 +10,7 @@ use std::time::{Duration, SystemTime}; use anyhow::{bail, ensure, Context as _, Result}; use deltachat_derive::{FromSql, ToSql}; use serde::{Deserialize, Serialize}; +use strum_macros::EnumIter; use crate::aheader::EncryptPreference; use crate::blob::BlobObject; @@ -554,6 +555,7 @@ impl ChatId { "bad chat_id, can not be special chat: {}", self ); + let (context, nosync) = &context.unwrap_nosync(); context .sql @@ -574,6 +576,11 @@ impl ChatId { context.emit_msgs_changed_without_ids(); + if !nosync { + let chat = Chat::load_from_db(context, self).await?; + chat.add_sync_item(context, ChatAction::SetVisibility(visibility)) + .await?; + } Ok(()) } @@ -1882,26 +1889,22 @@ impl Chat { } /// Whether the chat is pinned or archived. -#[derive(Debug, Copy, Eq, PartialEq, Clone, Serialize, Deserialize)] +#[derive(Debug, Copy, Eq, PartialEq, Clone, Serialize, Deserialize, EnumIter)] +#[repr(i8)] pub enum ChatVisibility { /// Chat is neither archived nor pinned. - Normal, + Normal = 0, /// Chat is archived. - Archived, + Archived = 1, /// Chat is pinned to the top of the chatlist. - Pinned, + Pinned = 2, } impl rusqlite::types::ToSql for ChatVisibility { fn to_sql(&self) -> rusqlite::Result { - let visibility = match &self { - ChatVisibility::Normal => 0, - ChatVisibility::Archived => 1, - ChatVisibility::Pinned => 2, - }; - let val = rusqlite::types::Value::Integer(visibility); + let val = rusqlite::types::Value::Integer(*self as i64); let out = rusqlite::types::ToSqlOutput::Owned(val); Ok(out) } @@ -4044,6 +4047,7 @@ impl Context { ChatAction::Block => chat_id.block(self).await, ChatAction::Unblock => chat_id.unblock(self).await, ChatAction::Accept => chat_id.accept(self).await, + ChatAction::SetVisibility(v) => chat_id.set_visibility(self, *v).await, } .ok(); Ok(()) diff --git a/src/sync.rs b/src/sync.rs index 393a45902..c3c75459e 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -5,7 +5,7 @@ use lettre_email::mime::{self}; use lettre_email::PartBuilder; use serde::{Deserialize, Serialize}; -use crate::chat::{self, Chat}; +use crate::chat::{self, Chat, ChatVisibility}; use crate::config::Config; use crate::constants::Blocked; use crate::contact::ContactId; @@ -46,6 +46,7 @@ pub(crate) enum ChatAction { Unblock, Accept, + SetVisibility(ChatVisibility), } #[derive(Debug, Serialize, Deserialize)] @@ -288,6 +289,7 @@ impl Context { #[cfg(test)] mod tests { use anyhow::bail; + use strum::IntoEnumIterator; use super::*; use crate::chat::Chat; @@ -592,6 +594,19 @@ mod tests { sync(&alices).await?; assert_eq!(alices[1].get_chat(&bob).await.blocked, Blocked::Not); + assert_eq!( + alices[1].get_chat(&bob).await.get_visibility(), + ChatVisibility::Normal + ); + let mut visibilities = + ChatVisibility::iter().chain(std::iter::once(ChatVisibility::Normal)); + visibilities.next(); + for v in visibilities { + a0b_chat_id.set_visibility(&alices[0], v).await?; + sync(&alices).await?; + assert_eq!(alices[1].get_chat(&bob).await.get_visibility(), v); + } + Ok(()) } }