mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +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 anyhow::{bail, ensure, Context as _, Result};
|
||||||
use deltachat_derive::{FromSql, ToSql};
|
use deltachat_derive::{FromSql, ToSql};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
use crate::aheader::EncryptPreference;
|
use crate::aheader::EncryptPreference;
|
||||||
use crate::blob::BlobObject;
|
use crate::blob::BlobObject;
|
||||||
@@ -554,6 +555,7 @@ impl ChatId {
|
|||||||
"bad chat_id, can not be special chat: {}",
|
"bad chat_id, can not be special chat: {}",
|
||||||
self
|
self
|
||||||
);
|
);
|
||||||
|
let (context, nosync) = &context.unwrap_nosync();
|
||||||
|
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
@@ -574,6 +576,11 @@ impl ChatId {
|
|||||||
|
|
||||||
context.emit_msgs_changed_without_ids();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1882,26 +1889,22 @@ impl Chat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the chat is pinned or archived.
|
/// 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 {
|
pub enum ChatVisibility {
|
||||||
/// Chat is neither archived nor pinned.
|
/// Chat is neither archived nor pinned.
|
||||||
Normal,
|
Normal = 0,
|
||||||
|
|
||||||
/// Chat is archived.
|
/// Chat is archived.
|
||||||
Archived,
|
Archived = 1,
|
||||||
|
|
||||||
/// Chat is pinned to the top of the chatlist.
|
/// Chat is pinned to the top of the chatlist.
|
||||||
Pinned,
|
Pinned = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rusqlite::types::ToSql for ChatVisibility {
|
impl rusqlite::types::ToSql for ChatVisibility {
|
||||||
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
|
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
|
||||||
let visibility = match &self {
|
let val = rusqlite::types::Value::Integer(*self as i64);
|
||||||
ChatVisibility::Normal => 0,
|
|
||||||
ChatVisibility::Archived => 1,
|
|
||||||
ChatVisibility::Pinned => 2,
|
|
||||||
};
|
|
||||||
let val = rusqlite::types::Value::Integer(visibility);
|
|
||||||
let out = rusqlite::types::ToSqlOutput::Owned(val);
|
let out = rusqlite::types::ToSqlOutput::Owned(val);
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
@@ -4044,6 +4047,7 @@ impl Context {
|
|||||||
ChatAction::Block => chat_id.block(self).await,
|
ChatAction::Block => chat_id.block(self).await,
|
||||||
ChatAction::Unblock => chat_id.unblock(self).await,
|
ChatAction::Unblock => chat_id.unblock(self).await,
|
||||||
ChatAction::Accept => chat_id.accept(self).await,
|
ChatAction::Accept => chat_id.accept(self).await,
|
||||||
|
ChatAction::SetVisibility(v) => chat_id.set_visibility(self, *v).await,
|
||||||
}
|
}
|
||||||
.ok();
|
.ok();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
17
src/sync.rs
17
src/sync.rs
@@ -5,7 +5,7 @@ use lettre_email::mime::{self};
|
|||||||
use lettre_email::PartBuilder;
|
use lettre_email::PartBuilder;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::chat::{self, Chat};
|
use crate::chat::{self, Chat, ChatVisibility};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::constants::Blocked;
|
use crate::constants::Blocked;
|
||||||
use crate::contact::ContactId;
|
use crate::contact::ContactId;
|
||||||
@@ -46,6 +46,7 @@ pub(crate) enum ChatAction {
|
|||||||
Unblock,
|
Unblock,
|
||||||
|
|
||||||
Accept,
|
Accept,
|
||||||
|
SetVisibility(ChatVisibility),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@@ -288,6 +289,7 @@ impl Context {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::chat::Chat;
|
use crate::chat::Chat;
|
||||||
@@ -592,6 +594,19 @@ mod tests {
|
|||||||
sync(&alices).await?;
|
sync(&alices).await?;
|
||||||
assert_eq!(alices[1].get_chat(&bob).await.blocked, Blocked::Not);
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user