mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 10:56:29 +03:00
feat: Sync chat visibility across devices (#4817)
This commit is contained in:
24
src/chat.rs
24
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<rusqlite::types::ToSqlOutput> {
|
||||
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(())
|
||||
|
||||
17
src/sync.rs
17
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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user