mirror of
https://github.com/chatmail/core.git
synced 2026-04-26 09:56:35 +03:00
Move module functions to type methods
This moves the module-level lookup and creation functions to the types, which make the naming more consistent. Now the lookup_* get_* and create_* functions all behave similarly. Peraps even more important the API of the lookup now allows distinguishing failure from not found. This in turn is important to be able to remove reliance on a ChatId with a 0 or "unset" value. The locations where this ChatId(0) is still used is in database queries which should be solved in an independed commit.
This commit is contained in:
@@ -639,7 +639,7 @@ pub unsafe extern "C" fn dc_create_chat_by_contact_id(
|
||||
let ctx = &*context;
|
||||
|
||||
block_on(async move {
|
||||
chat::create_by_contact_id(&ctx, contact_id)
|
||||
ChatId::create_for_contact(&ctx, contact_id)
|
||||
.await
|
||||
.log_err(ctx, "Failed to create chat from contact_id")
|
||||
.map(|id| id.to_u32())
|
||||
@@ -659,11 +659,12 @@ pub unsafe extern "C" fn dc_get_chat_id_by_contact_id(
|
||||
let ctx = &*context;
|
||||
|
||||
block_on(async move {
|
||||
chat::get_by_contact_id(&ctx, contact_id)
|
||||
ChatId::lookup_by_contact(&ctx, contact_id)
|
||||
.await
|
||||
.log_err(ctx, "Failed to get chat for contact_id")
|
||||
.unwrap_or_default() // unwraps the Result
|
||||
.map(|id| id.to_u32())
|
||||
.unwrap_or(0)
|
||||
.unwrap_or(0) // unwraps the Option
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -675,7 +675,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
||||
"createchat" => {
|
||||
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
|
||||
let contact_id: u32 = arg1.parse()?;
|
||||
let chat_id = chat::create_by_contact_id(&context, contact_id).await?;
|
||||
let chat_id = ChatId::create_for_contact(&context, contact_id).await?;
|
||||
|
||||
println!("Single#{} created successfully.", chat_id,);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use tempfile::tempdir;
|
||||
|
||||
use deltachat::chat;
|
||||
use deltachat::chat::{self, ChatId};
|
||||
use deltachat::chatlist::*;
|
||||
use deltachat::config;
|
||||
use deltachat::contact::*;
|
||||
@@ -70,7 +70,7 @@ async fn main() {
|
||||
let contact_id = Contact::create(&ctx, "dignifiedquire", "dignifiedquire@gmail.com")
|
||||
.await
|
||||
.unwrap();
|
||||
let chat_id = chat::create_by_contact_id(&ctx, contact_id).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(&ctx, contact_id).await.unwrap();
|
||||
|
||||
for i in 0..1 {
|
||||
log::info!("sending message {}", i);
|
||||
|
||||
201
src/chat.rs
201
src/chat.rs
@@ -155,15 +155,66 @@ impl ChatId {
|
||||
self == DC_CHAT_ID_ALLDONE_HINT
|
||||
}
|
||||
|
||||
/// Returns the [`ChatId`] for the 1:1 chat with `contact_id` if it exists.
|
||||
///
|
||||
/// If it does not exist, `None` is returned.
|
||||
pub async fn lookup_by_contact(context: &Context, contact_id: u32) -> Result<Option<Self>> {
|
||||
ChatIdBlocked::lookup_by_contact(context, contact_id)
|
||||
.await
|
||||
.map(|lookup| lookup.map(|chat| chat.id))
|
||||
}
|
||||
|
||||
/// Returns the [`ChatId`] for the 1:1 chat with `contact_id`.
|
||||
///
|
||||
/// If the chat does not yet exist an unblocked chat ([`Blocked::Not`]) is created.
|
||||
///
|
||||
/// This is an internal API, if **a user action** needs to get a chat
|
||||
/// [`ChatId::create_for_contact`] should be used as this also scales up the
|
||||
/// [`Contact`]'s origin.
|
||||
pub async fn get_for_contact(context: &Context, contact_id: u32) -> Result<Self> {
|
||||
ChatIdBlocked::get_for_contact(context, contact_id, Blocked::Not)
|
||||
.await
|
||||
.map(|chat| chat.id)
|
||||
}
|
||||
|
||||
/// Returns the unblocked 1:1 chat with `contact_id`.
|
||||
///
|
||||
/// This should be used when **a user action** creates a chat 1:1, it ensures the chat
|
||||
/// exists and is unblocked and scales the [`Contact`]'s origin.
|
||||
///
|
||||
/// If a chat was in the deaddrop unblocking is how it becomes a normal chat and it will
|
||||
/// look to the user like the chat was newly created.
|
||||
pub async fn create_for_contact(context: &Context, contact_id: u32) -> Result<Self> {
|
||||
let chat_id = match ChatIdBlocked::lookup_by_contact(context, contact_id).await? {
|
||||
Some(chat) => {
|
||||
if chat.blocked != Blocked::Not {
|
||||
chat.id.unblock(context).await;
|
||||
}
|
||||
chat.id
|
||||
}
|
||||
None => {
|
||||
if Contact::real_exists_by_id(context, contact_id).await
|
||||
|| contact_id == DC_CONTACT_ID_SELF
|
||||
{
|
||||
let chat_id = ChatId::get_for_contact(context, contact_id).await?;
|
||||
Contact::scaleup_origin_by_id(context, contact_id, Origin::CreateChat).await;
|
||||
chat_id
|
||||
} else {
|
||||
warn!(
|
||||
context,
|
||||
"Cannot create chat, contact {} does not exist.", contact_id,
|
||||
);
|
||||
bail!("Can not create chat for non-existing contact");
|
||||
}
|
||||
}
|
||||
};
|
||||
context.emit_event(EventType::MsgsChanged {
|
||||
chat_id: ChatId::new(0),
|
||||
msg_id: MsgId::new(0),
|
||||
});
|
||||
Ok(chat_id)
|
||||
}
|
||||
|
||||
pub async fn set_selfavatar_timestamp(self, context: &Context, timestamp: i64) -> Result<()> {
|
||||
context
|
||||
.sql
|
||||
@@ -1312,50 +1363,9 @@ pub async fn create_by_msg_id(context: &Context, msg_id: MsgId) -> Result<ChatId
|
||||
Ok(chat.id)
|
||||
}
|
||||
|
||||
/// Create a normal chat with a single user.
|
||||
///
|
||||
/// To create group chats, see [`create_group_chat`].
|
||||
///
|
||||
/// If a chat already exists, this ID is returned, otherwise a new chat is created;
|
||||
/// this new chat may already contain messages, eg. from the deaddrop, to get the
|
||||
/// chat messages, use dc_get_chat_msgs().
|
||||
pub async fn create_by_contact_id(context: &Context, contact_id: u32) -> Result<ChatId> {
|
||||
let chat_id = match lookup_by_contact_id(context, contact_id).await {
|
||||
Ok((chat_id, chat_blocked)) => {
|
||||
if chat_blocked != Blocked::Not {
|
||||
// unblock chat (typically move it from the deaddrop to view)
|
||||
chat_id.unblock(context).await;
|
||||
}
|
||||
chat_id
|
||||
}
|
||||
Err(err) => {
|
||||
if !Contact::real_exists_by_id(context, contact_id).await
|
||||
&& contact_id != DC_CONTACT_ID_SELF
|
||||
{
|
||||
warn!(
|
||||
context,
|
||||
"Cannot create chat, contact {} does not exist.", contact_id,
|
||||
);
|
||||
return Err(err);
|
||||
} else {
|
||||
let chat_id = ChatId::get_for_contact(context, contact_id).await?;
|
||||
Contact::scaleup_origin_by_id(context, contact_id, Origin::CreateChat).await;
|
||||
chat_id
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
context.emit_event(EventType::MsgsChanged {
|
||||
chat_id: ChatId::new(0),
|
||||
msg_id: MsgId::new(0),
|
||||
});
|
||||
|
||||
Ok(chat_id)
|
||||
}
|
||||
|
||||
pub(crate) async fn update_saved_messages_icon(context: &Context) -> Result<()> {
|
||||
// if there is no saved-messages chat, there is nothing to update. this is no error.
|
||||
if let Ok((chat_id, _)) = lookup_by_contact_id(context, DC_CONTACT_ID_SELF).await {
|
||||
if let Some(chat_id) = ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF).await? {
|
||||
let icon = include_bytes!("../assets/icon-saved-messages.png");
|
||||
let blob = BlobObject::create(context, "icon-saved-messages.png".to_string(), icon).await?;
|
||||
let icon = blob.as_name().to_string();
|
||||
@@ -1369,7 +1379,7 @@ pub(crate) async fn update_saved_messages_icon(context: &Context) -> Result<()>
|
||||
|
||||
pub(crate) async fn update_device_icon(context: &Context) -> Result<()> {
|
||||
// if there is no device-chat, there is nothing to update. this is no error.
|
||||
if let Ok((chat_id, _)) = lookup_by_contact_id(context, DC_CONTACT_ID_DEVICE).await {
|
||||
if let Some(chat_id) = ChatId::lookup_by_contact(context, DC_CONTACT_ID_DEVICE).await? {
|
||||
let icon = include_bytes!("../assets/icon-device.png");
|
||||
let blob = BlobObject::create(context, "icon-device.png".to_string(), icon).await?;
|
||||
let icon = blob.as_name().to_string();
|
||||
@@ -1386,7 +1396,7 @@ pub(crate) async fn update_device_icon(context: &Context) -> Result<()> {
|
||||
}
|
||||
|
||||
async fn update_special_chat_name(context: &Context, contact_id: u32, name: String) -> Result<()> {
|
||||
if let Ok((chat_id, _)) = lookup_by_contact_id(context, contact_id).await {
|
||||
if let Some(chat_id) = ChatId::lookup_by_contact(context, contact_id).await? {
|
||||
// the `!= name` condition avoids unneeded writes
|
||||
context
|
||||
.sql
|
||||
@@ -1432,7 +1442,7 @@ impl ChatIdBlocked {
|
||||
/// Searches the database for the 1:1 chat with this contact.
|
||||
///
|
||||
/// If no chat is found `None` is returned.
|
||||
async fn lookup_by_contact(context: &Context, contact_id: u32) -> Result<Option<Self>, Error> {
|
||||
pub async fn lookup_by_contact(context: &Context, contact_id: u32) -> Result<Option<Self>> {
|
||||
ensure!(context.sql.is_open().await, "Database not available");
|
||||
ensure!(contact_id > 0, "Invalid contact id requested");
|
||||
|
||||
@@ -1465,7 +1475,7 @@ impl ChatIdBlocked {
|
||||
context: &Context,
|
||||
contact_id: u32,
|
||||
create_blocked: Blocked,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self> {
|
||||
ensure!(context.sql.is_open().await, "Database not available");
|
||||
ensure!(contact_id > 0, "Invalid contact id requested");
|
||||
|
||||
@@ -1533,41 +1543,6 @@ impl ChatIdBlocked {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn lookup_by_contact_id(
|
||||
context: &Context,
|
||||
contact_id: u32,
|
||||
) -> Result<(ChatId, Blocked)> {
|
||||
ensure!(context.sql.is_open().await, "Database not available");
|
||||
|
||||
let row = context
|
||||
.sql
|
||||
.query_row(
|
||||
"SELECT c.id, c.blocked
|
||||
FROM chats c
|
||||
INNER JOIN chats_contacts j
|
||||
ON c.id=j.chat_id
|
||||
WHERE c.type=100
|
||||
AND c.id>9
|
||||
AND j.contact_id=?;",
|
||||
paramsv![contact_id as i32],
|
||||
|row| {
|
||||
Ok((
|
||||
row.get::<_, ChatId>(0)?,
|
||||
row.get::<_, Option<_>>(1)?.unwrap_or_default(),
|
||||
))
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
pub async fn get_by_contact_id(context: &Context, contact_id: u32) -> Result<ChatId> {
|
||||
let (chat_id, blocked) = lookup_by_contact_id(context, contact_id).await?;
|
||||
ensure_eq!(blocked, Blocked::Not, "Requested contact is blocked");
|
||||
|
||||
Ok(chat_id)
|
||||
}
|
||||
|
||||
pub async fn prepare_msg(context: &Context, chat_id: ChatId, msg: &mut Message) -> Result<MsgId> {
|
||||
ensure!(
|
||||
!chat_id.is_special(),
|
||||
@@ -3182,7 +3157,7 @@ mod tests {
|
||||
async fn test_add_remove_contact_for_single() {
|
||||
let ctx = TestContext::new_alice().await;
|
||||
let bob = Contact::create(&ctx, "", "bob@f.br").await.unwrap();
|
||||
let chat_id = create_by_contact_id(&ctx, bob).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(&ctx, bob).await.unwrap();
|
||||
let chat = Chat::load_from_db(&ctx, chat_id).await.unwrap();
|
||||
assert_eq!(chat.typ, Chattype::Single);
|
||||
assert_eq!(get_chat_contacts(&ctx, chat.id).await.unwrap().len(), 1);
|
||||
@@ -3623,11 +3598,15 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_ne!(contact1, 0);
|
||||
|
||||
let chat_id = create_by_contact_id(&context.ctx, contact1).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(&context.ctx, contact1)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!chat_id.is_special(), "chat_id too small {}", chat_id);
|
||||
let chat = Chat::load_from_db(&context.ctx, chat_id).await.unwrap();
|
||||
|
||||
let chat2_id = create_by_contact_id(&context.ctx, contact1).await.unwrap();
|
||||
let chat2_id = ChatId::create_for_contact(&context.ctx, contact1)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(chat2_id, chat_id);
|
||||
let chat2 = Chat::load_from_db(&context.ctx, chat2_id).await.unwrap();
|
||||
|
||||
@@ -3823,13 +3802,16 @@ mod tests {
|
||||
// create contact, then unblocked chat
|
||||
let contact_id = Contact::create(&ctx, "", "bob@foo.de").await.unwrap();
|
||||
assert_ne!(contact_id, 0);
|
||||
let res = lookup_by_contact_id(&ctx, contact_id).await;
|
||||
assert!(res.is_err());
|
||||
let found = ChatId::lookup_by_contact(&ctx, contact_id).await.unwrap();
|
||||
assert!(found.is_none());
|
||||
|
||||
let chat_id = create_by_contact_id(&ctx, contact_id).await.unwrap();
|
||||
let (chat_id2, blocked) = lookup_by_contact_id(&ctx, contact_id).await.unwrap();
|
||||
assert_eq!(chat_id, chat_id2);
|
||||
assert_eq!(blocked, Blocked::Not);
|
||||
let chat_id = ChatId::create_for_contact(&ctx, contact_id).await.unwrap();
|
||||
let chat2 = ChatIdBlocked::lookup_by_contact(&ctx, contact_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(chat_id, chat2.id);
|
||||
assert_eq!(chat2.blocked, Blocked::Not);
|
||||
|
||||
// create contact, then blocked chat
|
||||
let contact_id = Contact::create(&ctx, "", "claire@foo.de").await.unwrap();
|
||||
@@ -3837,33 +3819,38 @@ mod tests {
|
||||
.await
|
||||
.unwrap()
|
||||
.id;
|
||||
let (chat_id2, blocked) = lookup_by_contact_id(&ctx, contact_id).await.unwrap();
|
||||
assert_eq!(chat_id, chat_id2);
|
||||
assert_eq!(blocked, Blocked::Manually);
|
||||
let chat2 = ChatIdBlocked::lookup_by_contact(&ctx, contact_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(chat_id, chat2.id);
|
||||
assert_eq!(chat2.blocked, Blocked::Manually);
|
||||
|
||||
// test nonexistent contact, and also check if reasonable defaults are used
|
||||
let res = lookup_by_contact_id(&ctx, 1234).await;
|
||||
assert!(res.is_err());
|
||||
// test nonexistent contact
|
||||
let found = ChatId::lookup_by_contact(&ctx, 1234).await.unwrap();
|
||||
assert!(found.is_none());
|
||||
|
||||
let (chat_id, blocked) = lookup_by_contact_id(&ctx, 1234).await.unwrap_or_default();
|
||||
assert_eq!(chat_id, ChatId::new(0));
|
||||
assert_eq!(blocked, Blocked::Not);
|
||||
let found = ChatIdBlocked::lookup_by_contact(&ctx, 1234).await.unwrap();
|
||||
assert!(found.is_none());
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_lookup_self_by_contact_id() {
|
||||
let ctx = TestContext::new_alice().await;
|
||||
|
||||
let res = lookup_by_contact_id(&ctx, DC_CONTACT_ID_SELF).await;
|
||||
assert!(res.is_err());
|
||||
|
||||
ctx.update_device_chats().await.unwrap();
|
||||
let (chat_id, blocked) = lookup_by_contact_id(&ctx, DC_CONTACT_ID_SELF)
|
||||
let chat = ChatId::lookup_by_contact(&ctx, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!chat_id.is_special());
|
||||
assert!(chat_id.is_self_talk(&ctx).await.unwrap());
|
||||
assert_eq!(blocked, Blocked::Not);
|
||||
assert!(chat.is_none());
|
||||
|
||||
ctx.update_device_chats().await.unwrap();
|
||||
let chat = ChatIdBlocked::lookup_by_contact(&ctx, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert!(!chat.id.is_special());
|
||||
assert!(chat.id.is_self_talk(&ctx).await.unwrap());
|
||||
assert_eq!(chat.blocked, Blocked::Not);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use anyhow::{bail, ensure, Result};
|
||||
|
||||
use crate::chat;
|
||||
use crate::chat::{update_special_chat_names, Chat, ChatId, ChatVisibility};
|
||||
use crate::constants::{
|
||||
Chattype, DC_CHAT_ID_ALLDONE_HINT, DC_CHAT_ID_ARCHIVED_LINK, DC_CHAT_ID_DEADDROP,
|
||||
@@ -110,15 +109,6 @@ impl Chatlist {
|
||||
|
||||
let mut add_archived_link_item = false;
|
||||
|
||||
let skip_id = if flag_for_forwarding {
|
||||
chat::lookup_by_contact_id(context, DC_CONTACT_ID_DEVICE)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.0
|
||||
} else {
|
||||
ChatId::new(0)
|
||||
};
|
||||
|
||||
let process_row = |row: &rusqlite::Row| {
|
||||
let chat_id: ChatId = row.get(0)?;
|
||||
let msg_id: MsgId = row.get(1).unwrap_or_default();
|
||||
@@ -130,6 +120,14 @@ impl Chatlist {
|
||||
.map_err(Into::into)
|
||||
};
|
||||
|
||||
let skip_id = if flag_for_forwarding {
|
||||
ChatId::lookup_by_contact(context, DC_CONTACT_ID_DEVICE)
|
||||
.await?
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
ChatId::new(0)
|
||||
};
|
||||
|
||||
// select with left join and minimum:
|
||||
//
|
||||
// - the inner select must use `hidden` and _not_ `m.hidden`
|
||||
@@ -232,10 +230,9 @@ impl Chatlist {
|
||||
} else {
|
||||
// show normal chatlist
|
||||
let sort_id_up = if flag_for_forwarding {
|
||||
chat::lookup_by_contact_id(context, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF)
|
||||
.await?
|
||||
.unwrap_or_default()
|
||||
.0
|
||||
} else {
|
||||
ChatId::new(0)
|
||||
};
|
||||
|
||||
@@ -609,8 +609,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::chat::{
|
||||
create_by_contact_id, get_chat_contacts, get_chat_msgs, send_msg, set_muted, Chat,
|
||||
MuteDuration,
|
||||
get_chat_contacts, get_chat_msgs, send_msg, set_muted, Chat, ChatId, MuteDuration,
|
||||
};
|
||||
use crate::constants::{Viewtype, DC_CONTACT_ID_SELF};
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
@@ -893,7 +892,7 @@ mod tests {
|
||||
#[async_std::test]
|
||||
async fn test_search_msgs() -> Result<()> {
|
||||
let alice = TestContext::new_alice().await;
|
||||
let self_talk = create_by_contact_id(&alice, DC_CONTACT_ID_SELF).await?;
|
||||
let self_talk = ChatId::create_for_contact(&alice, DC_CONTACT_ID_SELF).await?;
|
||||
let chat = alice
|
||||
.create_chat_with_contact("Bob", "bob@example.org")
|
||||
.await;
|
||||
|
||||
@@ -474,10 +474,9 @@ async fn add_parts(
|
||||
}
|
||||
}
|
||||
|
||||
let (test_normal_chat_id, test_normal_chat_id_blocked) =
|
||||
chat::lookup_by_contact_id(context, from_id)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
let test_normal_chat = ChatIdBlocked::lookup_by_contact(context, from_id)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
// get the chat_id - a chat_id here is no indicator that the chat is displayed in the normal list,
|
||||
// it might also be blocked and displayed in the deaddrop as a result
|
||||
@@ -498,17 +497,18 @@ async fn add_parts(
|
||||
if chat_id.is_unset() {
|
||||
// try to create a group
|
||||
|
||||
let create_blocked =
|
||||
if !test_normal_chat_id.is_unset() && test_normal_chat_id_blocked == Blocked::Not {
|
||||
Blocked::Not
|
||||
} else {
|
||||
Blocked::Deaddrop
|
||||
};
|
||||
let create_blocked = match test_normal_chat {
|
||||
Some(ChatIdBlocked {
|
||||
id: _,
|
||||
blocked: Blocked::Not,
|
||||
}) => Blocked::Not,
|
||||
_ => Blocked::Deaddrop,
|
||||
};
|
||||
|
||||
let (new_chat_id, new_chat_id_blocked) = create_or_lookup_group(
|
||||
context,
|
||||
&mut mime_parser,
|
||||
if test_normal_chat_id.is_unset() {
|
||||
if test_normal_chat.is_none() {
|
||||
allow_creation
|
||||
} else {
|
||||
true
|
||||
@@ -600,9 +600,9 @@ async fn add_parts(
|
||||
Blocked::Deaddrop
|
||||
};
|
||||
|
||||
if !test_normal_chat_id.is_unset() {
|
||||
*chat_id = test_normal_chat_id;
|
||||
chat_id_blocked = test_normal_chat_id_blocked;
|
||||
if let Some(chat) = test_normal_chat {
|
||||
*chat_id = chat.id;
|
||||
chat_id_blocked = chat.blocked;
|
||||
} else if allow_creation {
|
||||
if let Ok(chat) = ChatIdBlocked::get_for_contact(context, from_id, create_blocked)
|
||||
.await
|
||||
@@ -2358,7 +2358,7 @@ mod tests {
|
||||
let t = TestContext::new_alice().await;
|
||||
|
||||
let bob_id = Contact::create(&t, "bob", "bob@example.com").await.unwrap();
|
||||
let one2one_id = chat::create_by_contact_id(&t, bob_id).await.unwrap();
|
||||
let one2one_id = ChatId::create_for_contact(&t, bob_id).await.unwrap();
|
||||
one2one_id
|
||||
.set_visibility(&t, ChatVisibility::Archived)
|
||||
.await
|
||||
@@ -2527,7 +2527,7 @@ mod tests {
|
||||
let contact_id = Contact::create(&t, "foobar", "foobar@example.com")
|
||||
.await
|
||||
.unwrap();
|
||||
let chat_id = chat::create_by_contact_id(&t, contact_id).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(&t, contact_id).await.unwrap();
|
||||
dc_receive_imf(
|
||||
&t,
|
||||
b"From: =?UTF-8?B?0JjQvNGPLCDQpNCw0LzQuNC70LjRjw==?= <foobar@example.com>\n\
|
||||
|
||||
@@ -65,19 +65,17 @@ use anyhow::{ensure, Context as _, Result};
|
||||
use async_std::task;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::chat::{send_msg, ChatId};
|
||||
use crate::constants::{
|
||||
Viewtype, DC_CHAT_ID_LAST_SPECIAL, DC_CHAT_ID_TRASH, DC_CONTACT_ID_DEVICE, DC_CONTACT_ID_SELF,
|
||||
};
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::time;
|
||||
use crate::events::EventType;
|
||||
use crate::job;
|
||||
use crate::message::{Message, MessageState, MsgId};
|
||||
use crate::mimeparser::SystemMessage;
|
||||
use crate::stock_str;
|
||||
use crate::{
|
||||
chat::{lookup_by_contact_id, send_msg, ChatId},
|
||||
job,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
|
||||
pub enum Timer {
|
||||
@@ -329,14 +327,12 @@ WHERE
|
||||
> 0;
|
||||
|
||||
if let Some(delete_device_after) = context.get_config_delete_device_after().await? {
|
||||
let self_chat_id = lookup_by_contact_id(context, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.0;
|
||||
let device_chat_id = lookup_by_contact_id(context, DC_CONTACT_ID_DEVICE)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.0;
|
||||
let self_chat_id = ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
let device_chat_id = ChatId::lookup_by_contact(context, DC_CONTACT_ID_DEVICE)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
|
||||
let threshold_timestamp = time() - delete_device_after;
|
||||
|
||||
|
||||
@@ -213,6 +213,8 @@ pub enum EventType {
|
||||
/// - Messages sent, received or removed
|
||||
/// - Chats created, deleted or archived
|
||||
/// - A draft has been set
|
||||
///
|
||||
/// The `chat_id` and `msg_id` values will be 0 if more than one message is changed.
|
||||
#[strum(props(id = "2000"))]
|
||||
MsgsChanged { chat_id: ChatId, msg_id: MsgId },
|
||||
|
||||
|
||||
14
src/imex.rs
14
src/imex.rs
@@ -3,16 +3,18 @@
|
||||
use std::any::Any;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
use ::pgp::types::KeyTrait;
|
||||
use anyhow::{bail, ensure, format_err, Context as _, Result};
|
||||
use async_std::path::{Path, PathBuf};
|
||||
use async_std::{
|
||||
fs::{self, File},
|
||||
path::{Path, PathBuf},
|
||||
prelude::*,
|
||||
};
|
||||
use async_tar::Archive;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::chat;
|
||||
use crate::chat::delete_and_reset_all_device_msgs;
|
||||
use crate::blob::BlobObject;
|
||||
use crate::chat::{self, delete_and_reset_all_device_msgs, ChatId};
|
||||
use crate::config::Config;
|
||||
use crate::constants::{Viewtype, DC_CONTACT_ID_SELF};
|
||||
use crate::context::Context;
|
||||
@@ -23,15 +25,13 @@ use crate::dc_tools::{
|
||||
use crate::e2ee;
|
||||
use crate::events::EventType;
|
||||
use crate::key::{self, DcKey, DcSecretKey, SignedPublicKey, SignedSecretKey};
|
||||
use crate::log::LogExt;
|
||||
use crate::message::{Message, MsgId};
|
||||
use crate::mimeparser::SystemMessage;
|
||||
use crate::param::Param;
|
||||
use crate::pgp;
|
||||
use crate::sql::{self, Sql};
|
||||
use crate::stock_str;
|
||||
use crate::{blob::BlobObject, log::LogExt};
|
||||
use ::pgp::types::KeyTrait;
|
||||
use async_tar::Archive;
|
||||
|
||||
// Name of the database file in the backup.
|
||||
const DBFILE_BACKUP_NAME: &str = "dc_database_backup.sqlite";
|
||||
@@ -231,7 +231,7 @@ async fn do_initiate_key_transfer(context: &Context) -> Result<String> {
|
||||
)
|
||||
.await?;
|
||||
|
||||
let chat_id = chat::create_by_contact_id(context, DC_CONTACT_ID_SELF).await?;
|
||||
let chat_id = ChatId::create_for_contact(context, DC_CONTACT_ID_SELF).await?;
|
||||
msg = Message::default();
|
||||
msg.viewtype = Viewtype::File;
|
||||
msg.param.set(Param::File, setup_file_blob.as_name());
|
||||
|
||||
29
src/job.rs
29
src/job.rs
@@ -12,25 +12,24 @@ use deltachat_derive::{FromSql, ToSql};
|
||||
use itertools::Itertools;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::blob::BlobObject;
|
||||
use crate::chat::{self, Chat, ChatId, ChatIdBlocked, ChatItem};
|
||||
use crate::config::Config;
|
||||
use crate::constants::{Blocked, Chattype, DC_CHAT_ID_DEADDROP};
|
||||
use crate::contact::{normalize_name, Contact, Modifier, Origin};
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::{dc_delete_file, dc_read_file, time};
|
||||
use crate::ephemeral::load_imap_deletion_msgid;
|
||||
use crate::events::EventType;
|
||||
use crate::imap::{Imap, ImapActionResult};
|
||||
use crate::location;
|
||||
use crate::message::MsgId;
|
||||
use crate::message::{self, Message, MessageState};
|
||||
use crate::log::LogExt;
|
||||
use crate::message::{self, Message, MessageState, MsgId};
|
||||
use crate::mimefactory::MimeFactory;
|
||||
use crate::param::{Param, Params};
|
||||
use crate::scheduler::InterruptInfo;
|
||||
use crate::smtp::Smtp;
|
||||
use crate::{blob::BlobObject, contact::normalize_name, contact::Modifier, contact::Origin};
|
||||
use crate::{
|
||||
chat::{self, Chat, ChatId, ChatItem},
|
||||
constants::DC_CHAT_ID_DEADDROP,
|
||||
};
|
||||
use crate::{config::Config, constants::Blocked};
|
||||
use crate::{constants::Chattype, contact::Contact};
|
||||
use crate::{context::Context, log::LogExt};
|
||||
use crate::{scheduler::InterruptInfo, sql};
|
||||
use crate::sql;
|
||||
|
||||
// results in ~3 weeks for the last backoff timespan
|
||||
const JOB_RETRIES: u32 = 17;
|
||||
@@ -729,10 +728,12 @@ impl Job {
|
||||
};
|
||||
match chat.typ {
|
||||
Chattype::Group | Chattype::Mailinglist => {
|
||||
if let Ok((_1to1_chat, Blocked::Not)) =
|
||||
chat::lookup_by_contact_id(context, msg.from_id).await
|
||||
if let Ok(Some(one_to_one_chat)) =
|
||||
ChatIdBlocked::lookup_by_contact(context, msg.from_id).await
|
||||
{
|
||||
chat.id.unblock(context).await;
|
||||
if one_to_one_chat.blocked == Blocked::Not {
|
||||
chat.id.unblock(context).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
Chattype::Single | Chattype::Undefined => {}
|
||||
|
||||
@@ -1941,10 +1941,9 @@ pub async fn estimate_deletion_cnt(
|
||||
from_server: bool,
|
||||
seconds: i64,
|
||||
) -> Result<usize> {
|
||||
let self_chat_id = chat::lookup_by_contact_id(context, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.0;
|
||||
let self_chat_id = ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
let threshold_timestamp = time() - seconds;
|
||||
|
||||
let cnt = if from_server {
|
||||
@@ -2226,7 +2225,7 @@ mod tests {
|
||||
let contact_id = Contact::create(&t.ctx, "", "bob@example.net")
|
||||
.await
|
||||
.unwrap();
|
||||
chat::create_by_contact_id(&t.ctx, contact_id)
|
||||
ChatId::create_for_contact(&t.ctx, contact_id)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -1348,11 +1348,11 @@ mod tests {
|
||||
use async_std::prelude::*;
|
||||
|
||||
use crate::chat::ChatId;
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::contact::Origin;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::mimeparser::MimeMessage;
|
||||
use crate::test_utils::TestContext;
|
||||
use crate::{chatlist::Chatlist, test_utils::get_chat_msg};
|
||||
use crate::test_utils::{get_chat_msg, TestContext};
|
||||
|
||||
use async_std::fs::File;
|
||||
use pretty_assertions::assert_eq;
|
||||
@@ -1687,7 +1687,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.0;
|
||||
|
||||
let chat_id = chat::create_by_contact_id(&t, contact_id).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(&t, contact_id).await.unwrap();
|
||||
|
||||
let mut new_msg = Message::new(Viewtype::Text);
|
||||
new_msg.set_text(Some("Hi".to_string()));
|
||||
|
||||
@@ -304,7 +304,7 @@ async fn securejoin(context: &Context, qr: &str) -> Result<ChatId, JoinError> {
|
||||
StartedProtocolVariant::SetupContact => {
|
||||
// for a one-to-one-chat, the chat is already known, return the chat-id,
|
||||
// the verification runs in background
|
||||
let chat_id = chat::create_by_contact_id(context, invite.contact_id())
|
||||
let chat_id = ChatId::create_for_contact(context, invite.contact_id())
|
||||
.await
|
||||
.map_err(JoinError::UnknownContact)?;
|
||||
Ok(chat_id)
|
||||
|
||||
@@ -185,7 +185,7 @@ impl BobState {
|
||||
context: &Context,
|
||||
invite: QrInvite,
|
||||
) -> Result<(Self, BobHandshakeStage), JoinError> {
|
||||
let chat_id = chat::create_by_contact_id(context, invite.contact_id())
|
||||
let chat_id = ChatId::create_for_contact(context, invite.contact_id())
|
||||
.await
|
||||
.map_err(JoinError::UnknownContact)?;
|
||||
if fingerprint_equals_sender(context, invite.fingerprint(), chat_id).await? {
|
||||
|
||||
@@ -8,8 +8,7 @@ use strum::EnumProperty;
|
||||
use strum_macros::EnumProperty;
|
||||
|
||||
use crate::blob::BlobObject;
|
||||
use crate::chat;
|
||||
use crate::chat::ProtectionStatus;
|
||||
use crate::chat::{self, ChatId, ProtectionStatus};
|
||||
use crate::config::Config;
|
||||
use crate::constants::{Viewtype, DC_CONTACT_ID_SELF};
|
||||
use crate::contact::{Contact, Origin};
|
||||
@@ -916,7 +915,7 @@ impl Context {
|
||||
self.sql
|
||||
.set_raw_config_bool("self-chat-added", true)
|
||||
.await?;
|
||||
chat::create_by_contact_id(self, DC_CONTACT_ID_SELF).await?;
|
||||
ChatId::create_for_contact(self, DC_CONTACT_ID_SELF).await?;
|
||||
}
|
||||
|
||||
// add welcome-messages. by the label, this is done only once,
|
||||
|
||||
@@ -355,7 +355,7 @@ impl TestContext {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let chat_id = chat::create_by_contact_id(self, contact_id).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(self, contact_id).await.unwrap();
|
||||
Chat::load_from_db(self, chat_id).await.unwrap()
|
||||
}
|
||||
|
||||
@@ -367,13 +367,13 @@ impl TestContext {
|
||||
let contact = Contact::create(self, name, addr)
|
||||
.await
|
||||
.expect("failed to create contact");
|
||||
let chat_id = chat::create_by_contact_id(self, contact).await.unwrap();
|
||||
let chat_id = ChatId::create_for_contact(self, contact).await.unwrap();
|
||||
Chat::load_from_db(self, chat_id).await.unwrap()
|
||||
}
|
||||
|
||||
/// Retrieves the "self" chat.
|
||||
pub async fn get_self_chat(&self) -> Chat {
|
||||
let chat_id = chat::create_by_contact_id(self, DC_CONTACT_ID_SELF)
|
||||
let chat_id = ChatId::create_for_contact(self, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap();
|
||||
Chat::load_from_db(self, chat_id).await.unwrap()
|
||||
|
||||
Reference in New Issue
Block a user