mirror of
https://github.com/chatmail/core.git
synced 2026-04-06 15:42:10 +03:00
Compare commits
1 Commits
hoc/housek
...
flub/cbind
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeaf320595 |
@@ -17,7 +17,6 @@
|
||||
- speed up loading of chat messages #3171
|
||||
- clear more columns when message expires due to `delete_device_after` setting #3181
|
||||
- do not try to use stale SMTP connections #3180
|
||||
- retry message sending automatically if loop is not interrupted #3183
|
||||
|
||||
### Changes
|
||||
- add more SMTP logging #3093
|
||||
@@ -29,7 +28,6 @@
|
||||
- automatically accept chats with outgoing messages #3143
|
||||
- `dc_receive_imf` refactorings #3154 #3156
|
||||
- add index to speedup deletion of expired ephemeral messages #3155
|
||||
- muted chats stay archived on new messages #3184
|
||||
|
||||
|
||||
### Fixes
|
||||
|
||||
68
Cargo.lock
generated
68
Cargo.lock
generated
@@ -636,6 +636,25 @@ dependencies = [
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cbindgen"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "485ede05a56152367a6ec586a7425b475d6c3d3838581ff651d2a6e3730a62ef"
|
||||
dependencies = [
|
||||
"clap 3.1.8",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"tempfile",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
@@ -712,6 +731,21 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"indexmap",
|
||||
"os_str_bytes",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
"textwrap 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clear_on_drop"
|
||||
version = "0.2.4"
|
||||
@@ -836,7 +870,7 @@ dependencies = [
|
||||
"async-std",
|
||||
"atty",
|
||||
"cast",
|
||||
"clap",
|
||||
"clap 2.34.0",
|
||||
"criterion-plot",
|
||||
"csv",
|
||||
"futures",
|
||||
@@ -1014,7 +1048,7 @@ dependencies = [
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"strsim 0.9.3",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@@ -1154,6 +1188,7 @@ version = "1.76.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
"cbindgen",
|
||||
"deltachat",
|
||||
"human-panic",
|
||||
"libc",
|
||||
@@ -1973,6 +2008,16 @@ dependencies = [
|
||||
"nom 6.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.2.3"
|
||||
@@ -2509,6 +2554,15 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_type"
|
||||
version = "2.4.0"
|
||||
@@ -3636,6 +3690,12 @@ version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.24.0"
|
||||
@@ -4361,9 +4421,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.2"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d"
|
||||
checksum = "db2a3b9c90b21734aaf4449cee7735305f559f28894123b57e0f700be8459418"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc32fast",
|
||||
|
||||
@@ -75,7 +75,7 @@ humansize = "1"
|
||||
qrcodegen = "1.7.0"
|
||||
tagger = "4.3.3"
|
||||
textwrap = "0.15.0"
|
||||
zip = { version = "0.6.2", default-features = false, features = ["deflate"] }
|
||||
zip = { version = "0.6.1", default-features = false, features = ["deflate"] }
|
||||
|
||||
[dev-dependencies]
|
||||
ansi_term = "0.12.0"
|
||||
|
||||
@@ -25,6 +25,9 @@ anyhow = "1"
|
||||
thiserror = "1"
|
||||
rand = "0.7"
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.21.0"
|
||||
|
||||
[features]
|
||||
default = ["vendored"]
|
||||
vendored = ["deltachat/vendored"]
|
||||
|
||||
600
deltachat-ffi/bindings.h
Normal file
600
deltachat-ffi/bindings.h
Normal file
@@ -0,0 +1,600 @@
|
||||
#ifndef __DELTACHAT_H__
|
||||
#define __DELTACHAT_H__
|
||||
|
||||
/* Generated with cbindgen:0.21.0 */
|
||||
|
||||
/* WARNING: this file is autogenerated by cbindgen. Do not modify manually. */
|
||||
|
||||
#ifndef PY_CFFI
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define DC_CONNECTIVITY_CONNECTING 2000
|
||||
|
||||
#define DC_CONNECTIVITY_WORKING 3000
|
||||
|
||||
#define DC_CONNECTIVITY_CONNECTED 4000
|
||||
|
||||
typedef struct dc_provider_t dc_provider_t;
|
||||
|
||||
typedef struct dc_accounts_event_emitter_t dc_accounts_event_emitter_t;
|
||||
|
||||
/**
|
||||
* Struct representing a list of deltachat accounts.
|
||||
*/
|
||||
typedef struct dc_accounts_t dc_accounts_t;
|
||||
|
||||
typedef struct dc_array_t dc_array_t;
|
||||
|
||||
typedef struct dc_chat_t dc_chat_t;
|
||||
|
||||
typedef struct dc_chatlist_t dc_chatlist_t;
|
||||
|
||||
typedef struct dc_contact_t dc_contact_t;
|
||||
|
||||
/**
|
||||
* Struct representing the deltachat context.
|
||||
*/
|
||||
typedef struct dc_context_t dc_context_t;
|
||||
|
||||
typedef struct dc_event_emitter_t dc_event_emitter_t;
|
||||
|
||||
typedef struct dc_event_t dc_event_t;
|
||||
|
||||
/**
|
||||
* An object containing a set of values.
|
||||
* The meaning of the values is defined by the function returning the object.
|
||||
* Lot objects are created
|
||||
* eg. by chatlist.get_summary() or dc_msg_get_summary().
|
||||
*
|
||||
* *Lot* is used in the meaning *heap* here.
|
||||
*/
|
||||
typedef struct dc_lot_t dc_lot_t;
|
||||
|
||||
typedef struct dc_msg_t dc_msg_t;
|
||||
|
||||
typedef struct dc_provider_t dc_provider_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct dc_context_t *dc_context_new(const char *_os_name, const char *dbfile, const char *blobdir);
|
||||
|
||||
struct dc_context_t *dc_context_new_closed(const char *dbfile);
|
||||
|
||||
int dc_context_open(struct dc_context_t *context, const char *passphrase);
|
||||
|
||||
int dc_context_is_open(struct dc_context_t *context);
|
||||
|
||||
/**
|
||||
* Release the context structure.
|
||||
*
|
||||
* This function releases the memory of the `dc_context_t` structure.
|
||||
*/
|
||||
void dc_context_unref(struct dc_context_t *context);
|
||||
|
||||
char *dc_get_blobdir(struct dc_context_t *context);
|
||||
|
||||
int dc_set_config(struct dc_context_t *context, const char *key, const char *value);
|
||||
|
||||
char *dc_get_config(struct dc_context_t *context, const char *key);
|
||||
|
||||
int dc_set_stock_translation(struct dc_context_t *context, uint32_t stock_id, char *stock_msg);
|
||||
|
||||
int dc_set_config_from_qr(struct dc_context_t *context, char *qr);
|
||||
|
||||
char *dc_get_info(const struct dc_context_t *context);
|
||||
|
||||
int dc_get_connectivity(const struct dc_context_t *context);
|
||||
|
||||
char *dc_get_connectivity_html(const struct dc_context_t *context);
|
||||
|
||||
int dc_all_work_done(struct dc_context_t *context);
|
||||
|
||||
char *dc_get_oauth2_url(struct dc_context_t *context, const char *addr, const char *redirect);
|
||||
|
||||
void dc_configure(struct dc_context_t *context);
|
||||
|
||||
int dc_is_configured(struct dc_context_t *context);
|
||||
|
||||
void dc_start_io(struct dc_context_t *context);
|
||||
|
||||
int dc_get_id(struct dc_context_t *context);
|
||||
|
||||
void dc_event_unref(struct dc_event_t *a);
|
||||
|
||||
int dc_event_get_id(struct dc_event_t *event);
|
||||
|
||||
int dc_event_get_data1_int(struct dc_event_t *event);
|
||||
|
||||
int dc_event_get_data2_int(struct dc_event_t *event);
|
||||
|
||||
char *dc_event_get_data2_str(struct dc_event_t *event);
|
||||
|
||||
uint32_t dc_event_get_account_id(struct dc_event_t *event);
|
||||
|
||||
struct dc_event_emitter_t *dc_get_event_emitter(struct dc_context_t *context);
|
||||
|
||||
void dc_event_emitter_unref(struct dc_event_emitter_t *emitter);
|
||||
|
||||
struct dc_event_t *dc_get_next_event(struct dc_event_emitter_t *events);
|
||||
|
||||
void dc_stop_io(struct dc_context_t *context);
|
||||
|
||||
void dc_maybe_network(struct dc_context_t *context);
|
||||
|
||||
int32_t dc_preconfigure_keypair(struct dc_context_t *context,
|
||||
const char *addr,
|
||||
const char *public_data,
|
||||
const char *secret_data);
|
||||
|
||||
struct dc_chatlist_t *dc_get_chatlist(struct dc_context_t *context,
|
||||
int flags,
|
||||
const char *query_str,
|
||||
uint32_t query_id);
|
||||
|
||||
uint32_t dc_create_chat_by_contact_id(struct dc_context_t *context, uint32_t contact_id);
|
||||
|
||||
uint32_t dc_get_chat_id_by_contact_id(struct dc_context_t *context, uint32_t contact_id);
|
||||
|
||||
uint32_t dc_prepare_msg(struct dc_context_t *context, uint32_t chat_id, struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_send_msg(struct dc_context_t *context, uint32_t chat_id, struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_send_msg_sync(struct dc_context_t *context, uint32_t chat_id, struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_send_text_msg(struct dc_context_t *context, uint32_t chat_id, const char *text_to_send);
|
||||
|
||||
uint32_t dc_send_videochat_invitation(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
int dc_send_webxdc_status_update(struct dc_context_t *context,
|
||||
uint32_t msg_id,
|
||||
const char *json,
|
||||
const char *descr);
|
||||
|
||||
char *dc_get_webxdc_status_updates(struct dc_context_t *context,
|
||||
uint32_t msg_id,
|
||||
uint32_t last_known_serial);
|
||||
|
||||
void dc_set_draft(struct dc_context_t *context, uint32_t chat_id, struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_add_device_msg(struct dc_context_t *context, const char *label, struct dc_msg_t *msg);
|
||||
|
||||
int dc_was_device_msg_ever_added(struct dc_context_t *context, const char *label);
|
||||
|
||||
struct dc_msg_t *dc_get_draft(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
dc_array_t *dc_get_chat_msgs(struct dc_context_t *context,
|
||||
uint32_t chat_id,
|
||||
uint32_t flags,
|
||||
uint32_t marker1before);
|
||||
|
||||
int dc_get_msg_cnt(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
int dc_get_fresh_msg_cnt(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
int dc_estimate_deletion_cnt(struct dc_context_t *context, int from_server, int64_t seconds);
|
||||
|
||||
dc_array_t *dc_get_fresh_msgs(struct dc_context_t *context);
|
||||
|
||||
void dc_marknoticed_chat(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
dc_array_t *dc_get_chat_media(struct dc_context_t *context,
|
||||
uint32_t chat_id,
|
||||
int msg_type,
|
||||
int or_msg_type2,
|
||||
int or_msg_type3);
|
||||
|
||||
uint32_t dc_get_next_media(struct dc_context_t *context,
|
||||
uint32_t msg_id,
|
||||
int dir,
|
||||
int msg_type,
|
||||
int or_msg_type2,
|
||||
int or_msg_type3);
|
||||
|
||||
int dc_set_chat_protection(struct dc_context_t *context, uint32_t chat_id, int protect);
|
||||
|
||||
void dc_set_chat_visibility(struct dc_context_t *context, uint32_t chat_id, int archive);
|
||||
|
||||
void dc_delete_chat(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
void dc_block_chat(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
void dc_accept_chat(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
dc_array_t *dc_get_chat_contacts(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
dc_array_t *dc_search_msgs(struct dc_context_t *context, uint32_t chat_id, const char *query);
|
||||
|
||||
struct dc_chat_t *dc_get_chat(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
uint32_t dc_create_group_chat(struct dc_context_t *context, int protect, const char *name);
|
||||
|
||||
uint32_t dc_create_broadcast_list(struct dc_context_t *context);
|
||||
|
||||
int dc_is_contact_in_chat(struct dc_context_t *context, uint32_t chat_id, uint32_t contact_id);
|
||||
|
||||
int dc_add_contact_to_chat(struct dc_context_t *context, uint32_t chat_id, uint32_t contact_id);
|
||||
|
||||
int dc_remove_contact_from_chat(struct dc_context_t *context,
|
||||
uint32_t chat_id,
|
||||
uint32_t contact_id);
|
||||
|
||||
int dc_set_chat_name(struct dc_context_t *context, uint32_t chat_id, const char *name);
|
||||
|
||||
int dc_set_chat_profile_image(struct dc_context_t *context, uint32_t chat_id, const char *image);
|
||||
|
||||
int dc_set_chat_mute_duration(struct dc_context_t *context, uint32_t chat_id, int64_t duration);
|
||||
|
||||
char *dc_get_chat_encrinfo(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
uint32_t dc_get_chat_ephemeral_timer(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
int dc_set_chat_ephemeral_timer(struct dc_context_t *context, uint32_t chat_id, uint32_t timer);
|
||||
|
||||
char *dc_get_msg_info(struct dc_context_t *context, uint32_t msg_id);
|
||||
|
||||
char *dc_get_msg_html(struct dc_context_t *context, uint32_t msg_id);
|
||||
|
||||
char *dc_get_mime_headers(struct dc_context_t *context, uint32_t msg_id);
|
||||
|
||||
void dc_delete_msgs(struct dc_context_t *context, const uint32_t *msg_ids, int msg_cnt);
|
||||
|
||||
void dc_forward_msgs(struct dc_context_t *context,
|
||||
const uint32_t *msg_ids,
|
||||
int msg_cnt,
|
||||
uint32_t chat_id);
|
||||
|
||||
void dc_markseen_msgs(struct dc_context_t *context, const uint32_t *msg_ids, int msg_cnt);
|
||||
|
||||
struct dc_msg_t *dc_get_msg(struct dc_context_t *context, uint32_t msg_id);
|
||||
|
||||
void dc_download_full_msg(struct dc_context_t *context, uint32_t msg_id);
|
||||
|
||||
int dc_may_be_valid_addr(const char *addr);
|
||||
|
||||
uint32_t dc_lookup_contact_id_by_addr(struct dc_context_t *context, const char *addr);
|
||||
|
||||
uint32_t dc_create_contact(struct dc_context_t *context, const char *name, const char *addr);
|
||||
|
||||
int dc_add_address_book(struct dc_context_t *context, const char *addr_book);
|
||||
|
||||
dc_array_t *dc_get_contacts(struct dc_context_t *context, uint32_t flags, const char *query);
|
||||
|
||||
int dc_get_blocked_cnt(struct dc_context_t *context);
|
||||
|
||||
dc_array_t *dc_get_blocked_contacts(struct dc_context_t *context);
|
||||
|
||||
void dc_block_contact(struct dc_context_t *context, uint32_t contact_id, int block);
|
||||
|
||||
char *dc_get_contact_encrinfo(struct dc_context_t *context, uint32_t contact_id);
|
||||
|
||||
int dc_delete_contact(struct dc_context_t *context, uint32_t contact_id);
|
||||
|
||||
struct dc_contact_t *dc_get_contact(struct dc_context_t *context, uint32_t contact_id);
|
||||
|
||||
void dc_imex(struct dc_context_t *context, int what_raw, const char *param1, const char *param2);
|
||||
|
||||
char *dc_imex_has_backup(struct dc_context_t *context, const char *dir);
|
||||
|
||||
char *dc_initiate_key_transfer(struct dc_context_t *context);
|
||||
|
||||
int dc_continue_key_transfer(struct dc_context_t *context, uint32_t msg_id, const char *setup_code);
|
||||
|
||||
void dc_stop_ongoing_process(struct dc_context_t *context);
|
||||
|
||||
struct dc_lot_t *dc_check_qr(struct dc_context_t *context, const char *qr);
|
||||
|
||||
char *dc_get_securejoin_qr(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
char *dc_get_securejoin_qr_svg(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
uint32_t dc_join_securejoin(struct dc_context_t *context, const char *qr);
|
||||
|
||||
void dc_send_locations_to_chat(struct dc_context_t *context, uint32_t chat_id, int seconds);
|
||||
|
||||
int dc_is_sending_locations_to_chat(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
int dc_set_location(struct dc_context_t *context,
|
||||
double latitude,
|
||||
double longitude,
|
||||
double accuracy);
|
||||
|
||||
dc_array_t *dc_get_locations(struct dc_context_t *context,
|
||||
uint32_t chat_id,
|
||||
uint32_t contact_id,
|
||||
int64_t timestamp_begin,
|
||||
int64_t timestamp_end);
|
||||
|
||||
void dc_delete_all_locations(struct dc_context_t *context);
|
||||
|
||||
char *dc_get_last_error(struct dc_context_t *context);
|
||||
|
||||
void dc_array_unref(dc_array_t *a);
|
||||
|
||||
size_t dc_array_get_cnt(const dc_array_t *array);
|
||||
|
||||
uint32_t dc_array_get_id(const dc_array_t *array, size_t index);
|
||||
|
||||
double dc_array_get_latitude(const dc_array_t *array, size_t index);
|
||||
|
||||
double dc_array_get_longitude(const dc_array_t *array, size_t index);
|
||||
|
||||
double dc_array_get_accuracy(const dc_array_t *array, size_t index);
|
||||
|
||||
int64_t dc_array_get_timestamp(const dc_array_t *array, size_t index);
|
||||
|
||||
unsigned int dc_array_get_chat_id(const dc_array_t *array, size_t index);
|
||||
|
||||
unsigned int dc_array_get_contact_id(const dc_array_t *array, size_t index);
|
||||
|
||||
unsigned int dc_array_get_msg_id(const dc_array_t *array, size_t index);
|
||||
|
||||
char *dc_array_get_marker(const dc_array_t *array, size_t index);
|
||||
|
||||
int dc_array_search_id(const dc_array_t *array, unsigned int needle, size_t *ret_index);
|
||||
|
||||
void dc_chatlist_unref(struct dc_chatlist_t *chatlist);
|
||||
|
||||
size_t dc_chatlist_get_cnt(struct dc_chatlist_t *chatlist);
|
||||
|
||||
uint32_t dc_chatlist_get_chat_id(struct dc_chatlist_t *chatlist, size_t index);
|
||||
|
||||
uint32_t dc_chatlist_get_msg_id(struct dc_chatlist_t *chatlist, size_t index);
|
||||
|
||||
struct dc_lot_t *dc_chatlist_get_summary(struct dc_chatlist_t *chatlist,
|
||||
size_t index,
|
||||
struct dc_chat_t *chat);
|
||||
|
||||
struct dc_lot_t *dc_chatlist_get_summary2(struct dc_context_t *context,
|
||||
uint32_t chat_id,
|
||||
uint32_t msg_id);
|
||||
|
||||
const struct dc_context_t *dc_chatlist_get_context(struct dc_chatlist_t *chatlist);
|
||||
|
||||
void dc_chat_unref(struct dc_chat_t *chat);
|
||||
|
||||
uint32_t dc_chat_get_id(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_get_type(struct dc_chat_t *chat);
|
||||
|
||||
char *dc_chat_get_name(struct dc_chat_t *chat);
|
||||
|
||||
char *dc_chat_get_profile_image(struct dc_chat_t *chat);
|
||||
|
||||
uint32_t dc_chat_get_color(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_get_visibility(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_contact_request(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_unpromoted(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_self_talk(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_device_talk(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_can_send(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_protected(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_sending_locations(struct dc_chat_t *chat);
|
||||
|
||||
int dc_chat_is_muted(struct dc_chat_t *chat);
|
||||
|
||||
int64_t dc_chat_get_remaining_mute_duration(struct dc_chat_t *chat);
|
||||
|
||||
char *dc_chat_get_info_json(struct dc_context_t *context, uint32_t chat_id);
|
||||
|
||||
struct dc_msg_t *dc_msg_new(struct dc_context_t *context, int viewtype);
|
||||
|
||||
void dc_msg_unref(struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_msg_get_id(struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_msg_get_from_id(struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_msg_get_chat_id(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_viewtype(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_state(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_download_state(struct dc_msg_t *msg);
|
||||
|
||||
int64_t dc_msg_get_timestamp(struct dc_msg_t *msg);
|
||||
|
||||
int64_t dc_msg_get_received_timestamp(struct dc_msg_t *msg);
|
||||
|
||||
int64_t dc_msg_get_sort_timestamp(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_text(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_subject(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_file(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_filename(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_webxdc_blob(struct dc_msg_t *msg, const char *filename, size_t *ret_bytes);
|
||||
|
||||
char *dc_msg_get_webxdc_info(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_filemime(struct dc_msg_t *msg);
|
||||
|
||||
uint64_t dc_msg_get_filebytes(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_width(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_height(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_duration(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_showpadlock(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_is_bot(struct dc_msg_t *msg);
|
||||
|
||||
uint32_t dc_msg_get_ephemeral_timer(struct dc_msg_t *msg);
|
||||
|
||||
int64_t dc_msg_get_ephemeral_timestamp(struct dc_msg_t *msg);
|
||||
|
||||
struct dc_lot_t *dc_msg_get_summary(struct dc_msg_t *msg, struct dc_chat_t *chat);
|
||||
|
||||
char *dc_msg_get_summarytext(struct dc_msg_t *msg, int approx_characters);
|
||||
|
||||
char *dc_msg_get_override_sender_name(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_has_deviating_timestamp(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_has_location(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_is_sent(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_is_forwarded(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_is_info(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_info_type(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_is_increation(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_is_setupmessage(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_has_html(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_videochat_url(struct dc_msg_t *msg);
|
||||
|
||||
int dc_msg_get_videochat_type(struct dc_msg_t *msg);
|
||||
|
||||
char *dc_msg_get_setupcodebegin(struct dc_msg_t *msg);
|
||||
|
||||
void dc_msg_set_text(struct dc_msg_t *msg, const char *text);
|
||||
|
||||
void dc_msg_set_html(struct dc_msg_t *msg, const char *html);
|
||||
|
||||
void dc_msg_set_override_sender_name(struct dc_msg_t *msg, const char *name);
|
||||
|
||||
void dc_msg_set_file(struct dc_msg_t *msg, const char *file, const char *filemime);
|
||||
|
||||
void dc_msg_set_dimension(struct dc_msg_t *msg, int width, int height);
|
||||
|
||||
void dc_msg_set_duration(struct dc_msg_t *msg, int duration);
|
||||
|
||||
void dc_msg_set_location(struct dc_msg_t *msg, double latitude, double longitude);
|
||||
|
||||
void dc_msg_latefiling_mediasize(struct dc_msg_t *msg, int width, int height, int duration);
|
||||
|
||||
char *dc_msg_get_error(struct dc_msg_t *msg);
|
||||
|
||||
void dc_msg_set_quote(struct dc_msg_t *msg, const struct dc_msg_t *quote);
|
||||
|
||||
char *dc_msg_get_quoted_text(const struct dc_msg_t *msg);
|
||||
|
||||
struct dc_msg_t *dc_msg_get_quoted_msg(const struct dc_msg_t *msg);
|
||||
|
||||
struct dc_msg_t *dc_msg_get_parent(const struct dc_msg_t *msg);
|
||||
|
||||
void dc_msg_force_plaintext(struct dc_msg_t *msg);
|
||||
|
||||
void dc_contact_unref(struct dc_contact_t *contact);
|
||||
|
||||
uint32_t dc_contact_get_id(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_addr(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_name(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_auth_name(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_display_name(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_name_n_addr(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_profile_image(struct dc_contact_t *contact);
|
||||
|
||||
uint32_t dc_contact_get_color(struct dc_contact_t *contact);
|
||||
|
||||
char *dc_contact_get_status(struct dc_contact_t *contact);
|
||||
|
||||
int64_t dc_contact_get_last_seen(struct dc_contact_t *contact);
|
||||
|
||||
int dc_contact_is_blocked(struct dc_contact_t *contact);
|
||||
|
||||
int dc_contact_is_verified(struct dc_contact_t *contact);
|
||||
|
||||
void dc_lot_unref(struct dc_lot_t *lot);
|
||||
|
||||
char *dc_lot_get_text1(struct dc_lot_t *lot);
|
||||
|
||||
char *dc_lot_get_text2(struct dc_lot_t *lot);
|
||||
|
||||
int dc_lot_get_text1_meaning(struct dc_lot_t *lot);
|
||||
|
||||
int dc_lot_get_state(struct dc_lot_t *lot);
|
||||
|
||||
uint32_t dc_lot_get_id(struct dc_lot_t *lot);
|
||||
|
||||
int64_t dc_lot_get_timestamp(struct dc_lot_t *lot);
|
||||
|
||||
void dc_str_unref(char *s);
|
||||
|
||||
const dc_provider_t *dc_provider_new_from_email(const struct dc_context_t *context,
|
||||
const char *addr);
|
||||
|
||||
char *dc_provider_get_overview_page(const dc_provider_t *provider);
|
||||
|
||||
char *dc_provider_get_before_login_hint(const dc_provider_t *provider);
|
||||
|
||||
int dc_provider_get_status(const dc_provider_t *provider);
|
||||
|
||||
void dc_provider_unref(dc_provider_t *provider);
|
||||
|
||||
struct dc_accounts_t *dc_accounts_new(const char *_os_name, const char *dbfile);
|
||||
|
||||
/**
|
||||
* Release the accounts structure.
|
||||
*
|
||||
* This function releases the memory of the `dc_accounts_t` structure.
|
||||
*/
|
||||
void dc_accounts_unref(struct dc_accounts_t *accounts);
|
||||
|
||||
struct dc_context_t *dc_accounts_get_account(struct dc_accounts_t *accounts, uint32_t id);
|
||||
|
||||
struct dc_context_t *dc_accounts_get_selected_account(struct dc_accounts_t *accounts);
|
||||
|
||||
int dc_accounts_select_account(struct dc_accounts_t *accounts, uint32_t id);
|
||||
|
||||
uint32_t dc_accounts_add_account(struct dc_accounts_t *accounts);
|
||||
|
||||
uint32_t dc_accounts_add_closed_account(struct dc_accounts_t *accounts);
|
||||
|
||||
int dc_accounts_remove_account(struct dc_accounts_t *accounts, uint32_t id);
|
||||
|
||||
uint32_t dc_accounts_migrate_account(struct dc_accounts_t *accounts, const char *dbfile);
|
||||
|
||||
dc_array_t *dc_accounts_get_all(struct dc_accounts_t *accounts);
|
||||
|
||||
int dc_accounts_all_work_done(struct dc_accounts_t *accounts);
|
||||
|
||||
void dc_accounts_start_io(struct dc_accounts_t *accounts);
|
||||
|
||||
void dc_accounts_stop_io(struct dc_accounts_t *accounts);
|
||||
|
||||
void dc_accounts_maybe_network(struct dc_accounts_t *accounts);
|
||||
|
||||
void dc_accounts_maybe_network_lost(struct dc_accounts_t *accounts);
|
||||
|
||||
struct dc_accounts_event_emitter_t *dc_accounts_get_event_emitter(struct dc_accounts_t *accounts);
|
||||
|
||||
void dc_accounts_event_emitter_unref(struct dc_accounts_event_emitter_t *emitter);
|
||||
|
||||
struct dc_event_t *dc_accounts_get_next_event(struct dc_accounts_event_emitter_t *emitter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* __DELTACHAT_H__ */
|
||||
@@ -32,4 +32,9 @@ fn main() {
|
||||
.unwrap()
|
||||
.write_all(pkg_config.as_bytes())
|
||||
.unwrap();
|
||||
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
cbindgen::generate(crate_dir)
|
||||
.expect("Unable to generate header file")
|
||||
.write_to_file("bindings.h");
|
||||
}
|
||||
|
||||
43
deltachat-ffi/cbindgen.toml
Normal file
43
deltachat-ffi/cbindgen.toml
Normal file
@@ -0,0 +1,43 @@
|
||||
language = "C"
|
||||
include_guard = "__DELTACHAT_H__"
|
||||
include_version = true
|
||||
autogen_warning = "/* WARNING: this file is autogenerated by cbindgen. Do not modify manually. */"
|
||||
# header = """
|
||||
# /* We start with a bunch of opaque `_dc_something_t` structs. */
|
||||
# """
|
||||
no_includes = true
|
||||
after_includes = """
|
||||
#ifndef PY_CFFI
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
"""
|
||||
cpp_compat = true
|
||||
# style = "tag"
|
||||
style = "both"
|
||||
documentation = true
|
||||
documentation_style = "doxy"
|
||||
documentation_length = "full"
|
||||
|
||||
[export]
|
||||
# exclude = ["AccountsWrapper"]
|
||||
|
||||
[export.rename]
|
||||
# The opaque wrapper structs are usually prefixed with an underscore
|
||||
# in C headers. To keep the Rust source clean we rename them here,
|
||||
# though at the end of the day this doesn't really matter.
|
||||
# "AccountsWrapper" = "_dc_accounts_t"
|
||||
# "ChatWrapper" = "_dc_chat_t"
|
||||
# "ChatlistWrapper" = "_dc_chatlist_t"
|
||||
# "ContactWrapper" = "_dc_contact_t"
|
||||
# "MessageWrapper" = "_dc_message_t"
|
||||
# "Context" = "_dc_context_t"
|
||||
# "Event" = "_dc_event_t"
|
||||
# "EventEmitter" = "_dc_event_emitter_t"
|
||||
# "AccountsEventEmitter" = "_dc_accounts_event_emitter_t"
|
||||
# "Lot" = "_dc_lot_t"
|
||||
"Provider" = "dc_provider_t"
|
||||
|
||||
[parse]
|
||||
parse_deps = true
|
||||
include = ["deltachat"]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ use std::borrow::Cow;
|
||||
///
|
||||
/// *Lot* is used in the meaning *heap* here.
|
||||
#[derive(Debug)]
|
||||
pub enum Lot {
|
||||
pub enum dc_lot_t {
|
||||
Summary(Summary),
|
||||
Qr(Qr),
|
||||
Error(String),
|
||||
@@ -34,7 +34,7 @@ impl Default for Meaning {
|
||||
}
|
||||
}
|
||||
|
||||
impl Lot {
|
||||
impl dc_lot_t {
|
||||
pub fn get_text1(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Summary(summary) => match &summary.prefix {
|
||||
@@ -225,21 +225,21 @@ impl From<MessageState> for LotState {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Summary> for Lot {
|
||||
impl From<Summary> for dc_lot_t {
|
||||
fn from(summary: Summary) -> Self {
|
||||
Lot::Summary(summary)
|
||||
dc_lot_t::Summary(summary)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Qr> for Lot {
|
||||
impl From<Qr> for dc_lot_t {
|
||||
fn from(qr: Qr) -> Self {
|
||||
Lot::Qr(qr)
|
||||
dc_lot_t::Qr(qr)
|
||||
}
|
||||
}
|
||||
|
||||
// Make it easy to convert errors into the final `Lot`.
|
||||
impl From<Error> for Lot {
|
||||
impl From<Error> for dc_lot_t {
|
||||
fn from(error: Error) -> Self {
|
||||
Lot::Error(error.to_string())
|
||||
dc_lot_t::Error(error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ async fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: &Message) {
|
||||
contact_id,
|
||||
msgtext.unwrap_or_default(),
|
||||
if msg.has_html() { "[HAS-HTML]️" } else { "" },
|
||||
if msg.get_from_id() == ContactId::SELF {
|
||||
if msg.get_from_id() == DC_CONTACT_ID_SELF {
|
||||
""
|
||||
} else if msg.get_state() == MessageState::InSeen {
|
||||
"[SEEN]"
|
||||
@@ -297,7 +297,7 @@ async fn log_contactlist(context: &Context, contacts: &[ContactId]) -> Result<()
|
||||
let peerstate = Peerstate::from_addr(context, addr)
|
||||
.await
|
||||
.expect("peerstate error");
|
||||
if peerstate.is_some() && *contact_id != ContactId::SELF {
|
||||
if peerstate.is_some() && *contact_id != DC_CONTACT_ID_SELF {
|
||||
line2 = format!(
|
||||
", prefer-encrypt={}",
|
||||
peerstate.as_ref().unwrap().prefer_encrypt
|
||||
|
||||
258
src/chat.rs
258
src/chat.rs
@@ -16,7 +16,8 @@ use crate::color::str_to_color;
|
||||
use crate::config::Config;
|
||||
use crate::constants::{
|
||||
Blocked, Chattype, DC_CHAT_ID_ALLDONE_HINT, DC_CHAT_ID_ARCHIVED_LINK, DC_CHAT_ID_LAST_SPECIAL,
|
||||
DC_CHAT_ID_TRASH, DC_GCM_ADDDAYMARKER, DC_GCM_INFO_ONLY, DC_RESEND_USER_AVATAR_DAYS,
|
||||
DC_CHAT_ID_TRASH, DC_CONTACT_ID_DEVICE, DC_CONTACT_ID_INFO, DC_CONTACT_ID_LAST_SPECIAL,
|
||||
DC_CONTACT_ID_SELF, DC_GCM_ADDDAYMARKER, DC_GCM_INFO_ONLY, DC_RESEND_USER_AVATAR_DAYS,
|
||||
};
|
||||
use crate::contact::{addr_cmp, Contact, ContactId, Origin, VerifiedStatus};
|
||||
use crate::context::Context;
|
||||
@@ -198,7 +199,7 @@ impl ChatId {
|
||||
}
|
||||
None => {
|
||||
if Contact::real_exists_by_id(context, contact_id).await?
|
||||
|| contact_id == ContactId::SELF
|
||||
|| contact_id == DC_CONTACT_ID_SELF
|
||||
{
|
||||
let chat_id =
|
||||
ChatIdBlocked::get_for_contact(context, contact_id, create_blocked)
|
||||
@@ -296,7 +297,7 @@ impl ChatId {
|
||||
}
|
||||
Chattype::Single => {
|
||||
for contact_id in get_chat_contacts(context, self).await? {
|
||||
if contact_id != ContactId::SELF {
|
||||
if contact_id != DC_CONTACT_ID_SELF {
|
||||
info!(
|
||||
context,
|
||||
"Blocking the contact {} to block 1:1 chat", contact_id
|
||||
@@ -339,7 +340,7 @@ impl ChatId {
|
||||
// Previously accepting a chat literally created a chat because unaccepted chats
|
||||
// went to "contact requests" list rather than normal chatlist.
|
||||
for contact_id in get_chat_contacts(context, self).await? {
|
||||
if contact_id != ContactId::SELF {
|
||||
if contact_id != DC_CONTACT_ID_SELF {
|
||||
Contact::scaleup_origin_by_id(context, contact_id, Origin::CreateChat)
|
||||
.await?;
|
||||
}
|
||||
@@ -463,7 +464,7 @@ impl ChatId {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
self.add_protection_msg(context, protect, chat.is_promoted(), ContactId::SELF)
|
||||
self.add_protection_msg(context, protect, chat.is_promoted(), DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -500,15 +501,14 @@ impl ChatId {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Unarchives a chat that is archived and not muted.
|
||||
// Needed when a message is added to a chat so that the chat gets a normal visibility again.
|
||||
// Sending an appropriate event is up to the caller.
|
||||
pub async fn unarchive_if_not_muted(self, context: &Context) -> Result<()> {
|
||||
// note that unarchive() is not the same as set_visibility(Normal) -
|
||||
// eg. unarchive() does not modify pinned chats and does not send events.
|
||||
pub async fn unarchive(self, context: &Context) -> Result<()> {
|
||||
context
|
||||
.sql
|
||||
.execute(
|
||||
"UPDATE chats SET archived=0 WHERE id=? AND archived=1 AND NOT(muted_until=-1 OR muted_until>?)",
|
||||
paramsv![self, time()],
|
||||
"UPDATE chats SET archived=0 WHERE id=? and archived=1",
|
||||
paramsv![self],
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
@@ -714,7 +714,7 @@ impl ChatId {
|
||||
VALUES (?,?,?, ?,?,?,?,?,?);",
|
||||
paramsv![
|
||||
self,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
time(),
|
||||
msg.viewtype,
|
||||
MessageState::OutDraft,
|
||||
@@ -861,7 +861,7 @@ impl ChatId {
|
||||
for contact_id in get_chat_contacts(context, self)
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|&contact_id| !contact_id.is_special())
|
||||
.filter(|&contact_id| *contact_id > DC_CONTACT_ID_LAST_SPECIAL)
|
||||
{
|
||||
let contact = Contact::load_from_db(context, *contact_id).await?;
|
||||
let addr = contact.get_addr();
|
||||
@@ -1087,7 +1087,7 @@ impl Chat {
|
||||
pub(crate) async fn is_self_in_chat(&self, context: &Context) -> Result<bool> {
|
||||
match self.typ {
|
||||
Chattype::Single | Chattype::Broadcast | Chattype::Mailinglist => Ok(true),
|
||||
Chattype::Group => is_contact_in_chat(context, self.id, ContactId::SELF).await,
|
||||
Chattype::Group => is_contact_in_chat(context, self.id, DC_CONTACT_ID_SELF).await,
|
||||
Chattype::Undefined => Ok(false),
|
||||
}
|
||||
}
|
||||
@@ -1241,7 +1241,7 @@ impl Chat {
|
||||
|
||||
if !self.can_send(context).await? {
|
||||
if self.typ == Chattype::Group
|
||||
&& !is_contact_in_chat(context, self.id, ContactId::SELF).await?
|
||||
&& !is_contact_in_chat(context, self.id, DC_CONTACT_ID_SELF).await?
|
||||
{
|
||||
context.emit_event(EventType::ErrorSelfNotInGroup(
|
||||
"Cannot send message; self not in group.".into(),
|
||||
@@ -1355,7 +1355,7 @@ impl Chat {
|
||||
VALUES (?,?,?, ?,?,1);",
|
||||
paramsv![
|
||||
timestamp,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
self.id,
|
||||
msg.param.get_float(Param::SetLatitude).unwrap_or_default(),
|
||||
msg.param.get_float(Param::SetLongitude).unwrap_or_default(),
|
||||
@@ -1407,7 +1407,7 @@ impl Chat {
|
||||
paramsv![
|
||||
new_rfc724_mid,
|
||||
self.id,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
to_id as i32,
|
||||
timestamp,
|
||||
msg.viewtype,
|
||||
@@ -1427,6 +1427,7 @@ impl Chat {
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
schedule_ephemeral_task(context).await;
|
||||
msg.id = update_msg_id;
|
||||
} else {
|
||||
let raw_id = context
|
||||
@@ -1455,7 +1456,7 @@ impl Chat {
|
||||
paramsv![
|
||||
new_rfc724_mid,
|
||||
self.id,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
to_id as i32,
|
||||
timestamp,
|
||||
msg.viewtype,
|
||||
@@ -1584,7 +1585,7 @@ pub struct ChatInfo {
|
||||
|
||||
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 Some(chat_id) = ChatId::lookup_by_contact(context, ContactId::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", icon).await?;
|
||||
let icon = blob.as_name().to_string();
|
||||
@@ -1598,7 +1599,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 Some(chat_id) = ChatId::lookup_by_contact(context, ContactId::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", icon).await?;
|
||||
let icon = blob.as_name().to_string();
|
||||
@@ -1607,7 +1608,7 @@ pub(crate) async fn update_device_icon(context: &Context) -> Result<()> {
|
||||
chat.param.set(Param::ProfileImage, &icon);
|
||||
chat.update_param(context).await?;
|
||||
|
||||
let mut contact = Contact::load_from_db(context, ContactId::DEVICE).await?;
|
||||
let mut contact = Contact::load_from_db(context, DC_CONTACT_ID_DEVICE).await?;
|
||||
contact.param.set(Param::ProfileImage, icon);
|
||||
contact.update_param(context).await?;
|
||||
}
|
||||
@@ -1650,13 +1651,13 @@ async fn update_special_chat_name(
|
||||
pub(crate) async fn update_special_chat_names(context: &Context) -> Result<()> {
|
||||
update_special_chat_name(
|
||||
context,
|
||||
ContactId::DEVICE,
|
||||
DC_CONTACT_ID_DEVICE,
|
||||
stock_str::device_messages(context).await,
|
||||
)
|
||||
.await?;
|
||||
update_special_chat_name(
|
||||
context,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
stock_str::saved_messages(context).await,
|
||||
)
|
||||
.await?;
|
||||
@@ -1686,7 +1687,7 @@ impl ChatIdBlocked {
|
||||
) -> Result<Option<Self>> {
|
||||
ensure!(context.sql.is_open().await, "Database not available");
|
||||
ensure!(
|
||||
contact_id != ContactId::UNDEFINED,
|
||||
contact_id > ContactId::new(0),
|
||||
"Invalid contact id requested"
|
||||
);
|
||||
|
||||
@@ -1722,7 +1723,7 @@ impl ChatIdBlocked {
|
||||
) -> Result<Self> {
|
||||
ensure!(context.sql.is_open().await, "Database not available");
|
||||
ensure!(
|
||||
contact_id != ContactId::UNDEFINED,
|
||||
contact_id > ContactId::new(0),
|
||||
"Invalid contact id requested"
|
||||
);
|
||||
|
||||
@@ -1735,10 +1736,10 @@ impl ChatIdBlocked {
|
||||
let chat_name = contact.get_display_name().to_string();
|
||||
let mut params = Params::new();
|
||||
match contact_id {
|
||||
ContactId::SELF => {
|
||||
DC_CONTACT_ID_SELF => {
|
||||
params.set_int(Param::Selftalk, 1);
|
||||
}
|
||||
ContactId::DEVICE => {
|
||||
DC_CONTACT_ID_DEVICE => {
|
||||
params.set_int(Param::Devicetalk, 1);
|
||||
}
|
||||
_ => (),
|
||||
@@ -1779,8 +1780,8 @@ impl ChatIdBlocked {
|
||||
.await?;
|
||||
|
||||
match contact_id {
|
||||
ContactId::SELF => update_saved_messages_icon(context).await?,
|
||||
ContactId::DEVICE => update_device_icon(context).await?,
|
||||
DC_CONTACT_ID_SELF => update_saved_messages_icon(context).await?,
|
||||
DC_CONTACT_ID_DEVICE => update_device_icon(context).await?,
|
||||
_ => (),
|
||||
}
|
||||
|
||||
@@ -1894,7 +1895,7 @@ async fn prepare_msg_common(
|
||||
msg.state = change_state_to;
|
||||
|
||||
prepare_msg_blob(context, msg).await?;
|
||||
chat_id.unarchive_if_not_muted(context).await?;
|
||||
chat_id.unarchive(context).await?;
|
||||
msg.id = chat
|
||||
.prepare_msg_raw(
|
||||
context,
|
||||
@@ -1916,8 +1917,8 @@ pub async fn is_contact_in_chat(
|
||||
) -> Result<bool> {
|
||||
// this function works for group and for normal chats, however, it is more useful
|
||||
// for group chats.
|
||||
// ContactId::SELF may be used to check, if the user itself is in a group
|
||||
// chat (ContactId::SELF is not added to normal chats)
|
||||
// DC_CONTACT_ID_SELF may be used to check, if the user itself is in a group
|
||||
// chat (DC_CONTACT_ID_SELF is not added to normal chats)
|
||||
|
||||
let exists = context
|
||||
.sql
|
||||
@@ -1985,7 +1986,7 @@ async fn send_msg_inner(context: &Context, chat_id: ChatId, msg: &mut Message) -
|
||||
});
|
||||
|
||||
if msg.param.exists(Param::SetLatitude) {
|
||||
context.emit_event(EventType::LocationChanged(Some(ContactId::SELF)));
|
||||
context.emit_event(EventType::LocationChanged(Some(DC_CONTACT_ID_SELF)));
|
||||
}
|
||||
|
||||
context.interrupt_smtp(InterruptInfo::new(false)).await;
|
||||
@@ -2204,6 +2205,23 @@ pub async fn get_chat_msgs(
|
||||
flags: u32,
|
||||
marker1before: Option<MsgId>,
|
||||
) -> Result<Vec<ChatItem>> {
|
||||
match delete_expired_messages(context).await {
|
||||
Err(err) => warn!(context, "Failed to delete expired messages: {}", err),
|
||||
Ok(messages_deleted) => {
|
||||
if messages_deleted {
|
||||
// Trigger reload of chatlist.
|
||||
//
|
||||
// On desktop chatlist is always shown on the side,
|
||||
// and it is important to update the last message shown
|
||||
// there.
|
||||
context.emit_event(EventType::MsgsChanged {
|
||||
msg_id: MsgId::new(0),
|
||||
chat_id: ChatId::new(0),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let process_row = if (flags & DC_GCM_INFO_ONLY) != 0 {
|
||||
|row: &rusqlite::Row| {
|
||||
// is_info logic taken from Message.is_info()
|
||||
@@ -2212,8 +2230,8 @@ pub async fn get_chat_msgs(
|
||||
row.get::<_, ContactId>("from_id")?,
|
||||
row.get::<_, ContactId>("to_id")?,
|
||||
);
|
||||
let is_info_msg: bool = from_id == ContactId::INFO
|
||||
|| to_id == ContactId::INFO
|
||||
let is_info_msg: bool = from_id == DC_CONTACT_ID_INFO
|
||||
|| to_id == DC_CONTACT_ID_INFO
|
||||
|| match Params::from_str(¶ms) {
|
||||
Ok(p) => {
|
||||
let cmd = p.get_cmd();
|
||||
@@ -2287,7 +2305,7 @@ pub async fn get_chat_msgs(
|
||||
OR m.from_id == ?
|
||||
OR m.to_id == ?
|
||||
);",
|
||||
paramsv![chat_id, ContactId::INFO, ContactId::INFO],
|
||||
paramsv![chat_id, DC_CONTACT_ID_INFO, DC_CONTACT_ID_INFO],
|
||||
process_row,
|
||||
process_rows,
|
||||
)
|
||||
@@ -2569,8 +2587,8 @@ pub async fn create_group_chat(
|
||||
.await?;
|
||||
|
||||
let chat_id = ChatId::new(u32::try_from(row_id)?);
|
||||
if !is_contact_in_chat(context, chat_id, ContactId::SELF).await? {
|
||||
add_to_chat_contacts_table(context, chat_id, ContactId::SELF).await?;
|
||||
if !is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF).await? {
|
||||
add_to_chat_contacts_table(context, chat_id, DC_CONTACT_ID_SELF).await?;
|
||||
}
|
||||
|
||||
context.emit_event(EventType::MsgsChanged {
|
||||
@@ -2699,13 +2717,13 @@ pub(crate) async fn add_contact_to_chat_ex(
|
||||
chat_id
|
||||
);
|
||||
ensure!(
|
||||
Contact::real_exists_by_id(context, contact_id).await? || contact_id == ContactId::SELF,
|
||||
Contact::real_exists_by_id(context, contact_id).await? || contact_id == DC_CONTACT_ID_SELF,
|
||||
"invalid contact_id {} for adding to group",
|
||||
contact_id
|
||||
);
|
||||
ensure!(!chat.is_mailing_list(), "Mailing lists can't be changed");
|
||||
ensure!(
|
||||
chat.typ != Chattype::Broadcast || contact_id != ContactId::SELF,
|
||||
chat.typ != Chattype::Broadcast || contact_id != DC_CONTACT_ID_SELF,
|
||||
"Cannot add SELF to broadcast."
|
||||
);
|
||||
|
||||
@@ -2727,7 +2745,7 @@ pub(crate) async fn add_contact_to_chat_ex(
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
if addr_cmp(contact.get_addr(), &self_addr) {
|
||||
// ourself is added using ContactId::SELF, do not add this address explicitly.
|
||||
// ourself is added using DC_CONTACT_ID_SELF, do not add this address explicitly.
|
||||
// if SELF is not in the group, members cannot be added at all.
|
||||
warn!(
|
||||
context,
|
||||
@@ -2760,7 +2778,7 @@ pub(crate) async fn add_contact_to_chat_ex(
|
||||
msg.viewtype = Viewtype::Text;
|
||||
|
||||
msg.text =
|
||||
Some(stock_str::msg_add_member(context, contact.get_addr(), ContactId::SELF).await);
|
||||
Some(stock_str::msg_add_member(context, contact.get_addr(), DC_CONTACT_ID_SELF).await);
|
||||
msg.param.set_cmd(SystemMessage::MemberAddedToGroup);
|
||||
msg.param.set(Param::Arg, contact.get_addr());
|
||||
msg.param.set_int(Param::Arg2, from_handshake.into());
|
||||
@@ -2786,7 +2804,7 @@ pub(crate) async fn shall_attach_selfavatar(context: &Context, chat_id: ChatId)
|
||||
FROM chats_contacts cc
|
||||
LEFT JOIN contacts c ON c.id=cc.contact_id
|
||||
WHERE cc.chat_id=? AND cc.contact_id!=?;",
|
||||
paramsv![chat_id, ContactId::SELF],
|
||||
paramsv![chat_id, DC_CONTACT_ID_SELF],
|
||||
|row| Ok(row.get::<_, i64>(0)),
|
||||
|rows| {
|
||||
let mut needs_attach = false;
|
||||
@@ -2871,7 +2889,7 @@ pub async fn remove_contact_from_chat(
|
||||
chat_id
|
||||
);
|
||||
ensure!(
|
||||
!contact_id.is_special() || contact_id == ContactId::SELF,
|
||||
contact_id > DC_CONTACT_ID_LAST_SPECIAL || contact_id == DC_CONTACT_ID_SELF,
|
||||
"Cannot remove special contact"
|
||||
);
|
||||
|
||||
@@ -2890,16 +2908,16 @@ pub async fn remove_contact_from_chat(
|
||||
if let Ok(contact) = Contact::get_by_id(context, contact_id).await {
|
||||
if chat.typ == Chattype::Group && chat.is_promoted() {
|
||||
msg.viewtype = Viewtype::Text;
|
||||
if contact.id == ContactId::SELF {
|
||||
if contact.id == DC_CONTACT_ID_SELF {
|
||||
set_group_explicitly_left(context, &chat.grpid).await?;
|
||||
msg.text =
|
||||
Some(stock_str::msg_group_left(context, ContactId::SELF).await);
|
||||
Some(stock_str::msg_group_left(context, DC_CONTACT_ID_SELF).await);
|
||||
} else {
|
||||
msg.text = Some(
|
||||
stock_str::msg_del_member(
|
||||
context,
|
||||
contact.get_addr(),
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
@@ -2992,7 +3010,8 @@ pub async fn set_chat_name(context: &Context, chat_id: ChatId, new_name: &str) -
|
||||
if chat.is_promoted() && !chat.is_mailing_list() && chat.typ != Chattype::Broadcast {
|
||||
msg.viewtype = Viewtype::Text;
|
||||
msg.text = Some(
|
||||
stock_str::msg_grp_name(context, &chat.name, &new_name, ContactId::SELF).await,
|
||||
stock_str::msg_grp_name(context, &chat.name, &new_name, DC_CONTACT_ID_SELF)
|
||||
.await,
|
||||
);
|
||||
msg.param.set_cmd(SystemMessage::GroupNameChanged);
|
||||
if !chat.name.is_empty() {
|
||||
@@ -3033,7 +3052,7 @@ pub async fn set_chat_profile_image(
|
||||
"Failed to set profile image; group does not exist"
|
||||
);
|
||||
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
|
||||
if !is_contact_in_chat(context, chat_id, ContactId::SELF).await? {
|
||||
if !is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF).await? {
|
||||
context.emit_event(EventType::ErrorSelfNotInGroup(
|
||||
"Cannot set chat profile image; self not in group.".into(),
|
||||
));
|
||||
@@ -3045,7 +3064,7 @@ pub async fn set_chat_profile_image(
|
||||
if new_image.as_ref().is_empty() {
|
||||
chat.param.remove(Param::ProfileImage);
|
||||
msg.param.remove(Param::Arg);
|
||||
msg.text = Some(stock_str::msg_grp_img_deleted(context, ContactId::SELF).await);
|
||||
msg.text = Some(stock_str::msg_grp_img_deleted(context, DC_CONTACT_ID_SELF).await);
|
||||
} else {
|
||||
let mut image_blob = match BlobObject::from_path(context, Path::new(new_image.as_ref())) {
|
||||
Ok(blob) => Ok(blob),
|
||||
@@ -3059,7 +3078,7 @@ pub async fn set_chat_profile_image(
|
||||
image_blob.recode_to_avatar_size(context).await?;
|
||||
chat.param.set(Param::ProfileImage, image_blob.as_name());
|
||||
msg.param.set(Param::Arg, image_blob.as_name());
|
||||
msg.text = Some(stock_str::msg_grp_img_changed(context, ContactId::SELF).await);
|
||||
msg.text = Some(stock_str::msg_grp_img_changed(context, DC_CONTACT_ID_SELF).await);
|
||||
}
|
||||
chat.update_param(context).await?;
|
||||
if chat.is_promoted() && !chat.is_mailing_list() {
|
||||
@@ -3081,7 +3100,7 @@ pub async fn forward_msgs(context: &Context, msg_ids: &[MsgId], chat_id: ChatId)
|
||||
let mut created_msgs: Vec<MsgId> = Vec::new();
|
||||
let mut curr_timestamp: i64;
|
||||
|
||||
chat_id.unarchive_if_not_muted(context).await?;
|
||||
chat_id.unarchive(context).await?;
|
||||
if let Ok(mut chat) = Chat::load_from_db(context, chat_id).await {
|
||||
ensure!(chat.can_send(context).await?, "cannot send to {}", chat_id);
|
||||
curr_timestamp = dc_create_smeared_timestamps(context, msg_ids.len()).await;
|
||||
@@ -3234,12 +3253,12 @@ pub async fn add_device_msg_with_importance(
|
||||
}
|
||||
|
||||
if let Some(msg) = msg {
|
||||
chat_id = ChatId::get_for_contact(context, ContactId::DEVICE).await?;
|
||||
chat_id = ChatId::get_for_contact(context, DC_CONTACT_ID_DEVICE).await?;
|
||||
|
||||
let rfc724_mid = dc_create_outgoing_rfc724_mid(None, "@device");
|
||||
msg.try_calc_and_set_dimensions(context).await.ok();
|
||||
prepare_msg_blob(context, msg).await?;
|
||||
chat_id.unarchive_if_not_muted(context).await?;
|
||||
chat_id.unarchive(context).await?;
|
||||
|
||||
let timestamp_sent = dc_create_smeared_timestamp(context).await;
|
||||
|
||||
@@ -3276,8 +3295,8 @@ pub async fn add_device_msg_with_importance(
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?);",
|
||||
paramsv![
|
||||
chat_id,
|
||||
ContactId::DEVICE,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_DEVICE,
|
||||
DC_CONTACT_ID_SELF,
|
||||
timestamp_sort,
|
||||
timestamp_sent,
|
||||
timestamp_sent, // timestamp_sent equals timestamp_rcvd
|
||||
@@ -3337,7 +3356,7 @@ pub async fn was_device_msg_ever_added(context: &Context, label: &str) -> Result
|
||||
}
|
||||
|
||||
// needed on device-switches during export/import;
|
||||
// - deletion in `msgs` with `ContactId::DEVICE` makes sure,
|
||||
// - deletion in `msgs` with `DC_CONTACT_ID_DEVICE` makes sure,
|
||||
// no wrong information are shown in the device chat
|
||||
// - deletion in `devmsglabels` makes sure,
|
||||
// deleted messages are resetted and useful messages can be added again
|
||||
@@ -3348,7 +3367,7 @@ pub(crate) async fn delete_and_reset_all_device_msgs(context: &Context) -> Resul
|
||||
.sql
|
||||
.execute(
|
||||
"DELETE FROM msgs WHERE from_id=?;",
|
||||
paramsv![ContactId::DEVICE],
|
||||
paramsv![DC_CONTACT_ID_DEVICE],
|
||||
)
|
||||
.await?;
|
||||
context
|
||||
@@ -3383,8 +3402,8 @@ pub(crate) async fn add_info_msg_with_cmd(
|
||||
"INSERT INTO msgs (chat_id,from_id,to_id,timestamp,type,state,txt,rfc724_mid,ephemeral_timer, param,mime_in_reply_to) VALUES (?,?,?, ?,?,?, ?,?,?, ?,?);",
|
||||
paramsv![
|
||||
chat_id,
|
||||
ContactId::INFO,
|
||||
ContactId::INFO,
|
||||
DC_CONTACT_ID_INFO,
|
||||
DC_CONTACT_ID_INFO,
|
||||
timestamp,
|
||||
Viewtype::Text,
|
||||
MessageState::InNoticed,
|
||||
@@ -3639,7 +3658,7 @@ mod tests {
|
||||
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo")
|
||||
.await
|
||||
.unwrap();
|
||||
let added = add_contact_to_chat_ex(&t, chat_id, ContactId::SELF, false)
|
||||
let added = add_contact_to_chat_ex(&t, chat_id, DC_CONTACT_ID_SELF, false)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(added, false);
|
||||
@@ -3849,7 +3868,7 @@ mod tests {
|
||||
let bob_msg = bob.get_last_msg().await;
|
||||
let bob_chat_id = bob_msg.chat_id;
|
||||
bob_chat_id.accept(&bob).await?;
|
||||
remove_contact_from_chat(&bob, bob_chat_id, ContactId::SELF).await?;
|
||||
remove_contact_from_chat(&bob, bob_chat_id, DC_CONTACT_ID_SELF).await?;
|
||||
|
||||
let leave_msg = bob.pop_sent_msg().await;
|
||||
alice.recv_msg(&leave_msg).await;
|
||||
@@ -3878,7 +3897,7 @@ mod tests {
|
||||
assert!(removed.is_err());
|
||||
assert_eq!(get_chat_contacts(&ctx, chat.id).await.unwrap().len(), 1);
|
||||
|
||||
let removed = remove_contact_from_chat(&ctx, chat.id, ContactId::SELF).await;
|
||||
let removed = remove_contact_from_chat(&ctx, chat.id, DC_CONTACT_ID_SELF).await;
|
||||
assert!(removed.is_err());
|
||||
assert_eq!(get_chat_contacts(&ctx, chat.id).await.unwrap().len(), 1);
|
||||
}
|
||||
@@ -3887,6 +3906,7 @@ mod tests {
|
||||
async fn test_self_talk() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
let chat = &t.get_self_chat().await;
|
||||
assert_eq!(DC_CONTACT_ID_SELF, ContactId::new(1));
|
||||
assert!(!chat.id.is_special());
|
||||
assert!(chat.is_self_talk());
|
||||
assert!(chat.visibility == ChatVisibility::Normal);
|
||||
@@ -3897,8 +3917,8 @@ mod tests {
|
||||
|
||||
let msg_id = send_text_msg(&t, chat.id, "foo self".to_string()).await?;
|
||||
let msg = Message::load_from_db(&t, msg_id).await?;
|
||||
assert_eq!(msg.from_id, ContactId::SELF);
|
||||
assert_eq!(msg.to_id, ContactId::SELF);
|
||||
assert_eq!(msg.from_id, DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg.to_id, DC_CONTACT_ID_SELF);
|
||||
assert!(msg.get_showpadlock());
|
||||
|
||||
let sent_msg = t.pop_sent_msg().await;
|
||||
@@ -3907,8 +3927,8 @@ mod tests {
|
||||
let chat = &t2.get_self_chat().await;
|
||||
let msg = t2.get_last_msg_in(chat.id).await;
|
||||
assert_eq!(msg.text, Some("foo self".to_string()));
|
||||
assert_eq!(msg.from_id, ContactId::SELF);
|
||||
assert_eq!(msg.to_id, ContactId::SELF);
|
||||
assert_eq!(msg.from_id, DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg.to_id, DC_CONTACT_ID_SELF);
|
||||
assert!(msg.get_showpadlock());
|
||||
|
||||
Ok(())
|
||||
@@ -3935,8 +3955,8 @@ mod tests {
|
||||
assert!(msg1.is_ok());
|
||||
let msg1 = msg1.unwrap();
|
||||
assert_eq!(msg1.text.as_ref().unwrap(), "first message");
|
||||
assert_eq!(msg1.from_id, ContactId::DEVICE);
|
||||
assert_eq!(msg1.to_id, ContactId::SELF);
|
||||
assert_eq!(msg1.from_id, DC_CONTACT_ID_DEVICE);
|
||||
assert_eq!(msg1.to_id, DC_CONTACT_ID_SELF);
|
||||
assert!(!msg1.is_info());
|
||||
assert!(!msg1.is_setupmessage());
|
||||
|
||||
@@ -3970,8 +3990,8 @@ mod tests {
|
||||
let msg1 = message::Message::load_from_db(&t, *msg1_id.as_ref().unwrap()).await?;
|
||||
assert_eq!(msg1_id.as_ref().unwrap(), &msg1.id);
|
||||
assert_eq!(msg1.text.as_ref().unwrap(), "first message");
|
||||
assert_eq!(msg1.from_id, ContactId::DEVICE);
|
||||
assert_eq!(msg1.to_id, ContactId::SELF);
|
||||
assert_eq!(msg1.from_id, DC_CONTACT_ID_DEVICE);
|
||||
assert_eq!(msg1.to_id, DC_CONTACT_ID_SELF);
|
||||
assert!(!msg1.is_info());
|
||||
assert!(!msg1.is_setupmessage());
|
||||
|
||||
@@ -4063,7 +4083,7 @@ mod tests {
|
||||
async fn test_device_chat_cannot_sent() {
|
||||
let t = TestContext::new().await;
|
||||
t.update_device_chats().await.unwrap();
|
||||
let device_chat_id = ChatId::get_for_contact(&t, ContactId::DEVICE)
|
||||
let device_chat_id = ChatId::get_for_contact(&t, DC_CONTACT_ID_DEVICE)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -4211,90 +4231,6 @@ mod tests {
|
||||
assert_eq!(chatlist_len(&t, DC_GCL_ARCHIVED_ONLY).await, 1);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_unarchive_if_muted() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
|
||||
async fn msg_from_bob(t: &TestContext, num: u32) -> Result<()> {
|
||||
dc_receive_imf(
|
||||
t,
|
||||
format!(
|
||||
"From: bob@example.net\n\
|
||||
To: alice@example.org\n\
|
||||
Message-ID: <{}@example.org>\n\
|
||||
Chat-Version: 1.0\n\
|
||||
Date: Sun, 22 Mar 2022 19:37:57 +0000\n\
|
||||
\n\
|
||||
hello\n",
|
||||
num
|
||||
)
|
||||
.as_bytes(),
|
||||
"INBOX",
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
msg_from_bob(&t, 1).await?;
|
||||
let chat_id = t.get_last_msg().await.get_chat_id();
|
||||
chat_id.accept(&t).await?;
|
||||
chat_id.set_visibility(&t, ChatVisibility::Archived).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 1);
|
||||
|
||||
// not muted chat is unarchived on receiving a message
|
||||
msg_from_bob(&t, 2).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 0);
|
||||
|
||||
// forever muted chat is not unarchived on receiving a message
|
||||
chat_id.set_visibility(&t, ChatVisibility::Archived).await?;
|
||||
set_muted(&t, chat_id, MuteDuration::Forever).await?;
|
||||
msg_from_bob(&t, 3).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 1);
|
||||
|
||||
// otherwise muted chat is not unarchived on receiving a message
|
||||
set_muted(
|
||||
&t,
|
||||
chat_id,
|
||||
MuteDuration::Until(
|
||||
SystemTime::now()
|
||||
.checked_add(Duration::from_secs(1000))
|
||||
.unwrap(),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
msg_from_bob(&t, 4).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 1);
|
||||
|
||||
// expired mute will unarchive the chat
|
||||
set_muted(
|
||||
&t,
|
||||
chat_id,
|
||||
MuteDuration::Until(
|
||||
SystemTime::now()
|
||||
.checked_sub(Duration::from_secs(1000))
|
||||
.unwrap(),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
msg_from_bob(&t, 5).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 0);
|
||||
|
||||
// no unarchiving on sending to muted chat or on adding info messages to muted chat
|
||||
chat_id.set_visibility(&t, ChatVisibility::Archived).await?;
|
||||
set_muted(&t, chat_id, MuteDuration::Forever).await?;
|
||||
send_text_msg(&t, chat_id, "out".to_string()).await?;
|
||||
add_info_msg(&t, chat_id, "info", time()).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 1);
|
||||
|
||||
// finally, unarchive on sending to not muted chat
|
||||
set_muted(&t, chat_id, MuteDuration::NotMuted).await?;
|
||||
send_text_msg(&t, chat_id, "out2".to_string()).await?;
|
||||
assert_eq!(dc_get_archived_cnt(&t).await?, 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_chats_from_chat_list(ctx: &Context, listflags: usize) -> Vec<ChatId> {
|
||||
let chatlist = Chatlist::try_load(ctx, listflags, None, None)
|
||||
.await
|
||||
@@ -4387,7 +4323,7 @@ mod tests {
|
||||
let contact1 = Contact::create(&context.ctx, "bob", "bob@mail.de")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_ne!(contact1, ContactId::UNDEFINED);
|
||||
assert_ne!(contact1, ContactId::new(0));
|
||||
|
||||
let chat_id = ChatId::create_for_contact(&context.ctx, contact1)
|
||||
.await
|
||||
@@ -4592,7 +4528,7 @@ mod tests {
|
||||
|
||||
// create contact, then unblocked chat
|
||||
let contact_id = Contact::create(&ctx, "", "bob@foo.de").await.unwrap();
|
||||
assert_ne!(contact_id, ContactId::UNDEFINED);
|
||||
assert_ne!(contact_id, ContactId::new(0));
|
||||
let found = ChatId::lookup_by_contact(&ctx, contact_id).await.unwrap();
|
||||
assert!(found.is_none());
|
||||
|
||||
@@ -4633,13 +4569,13 @@ mod tests {
|
||||
async fn test_lookup_self_by_contact_id() {
|
||||
let ctx = TestContext::new_alice().await;
|
||||
|
||||
let chat = ChatId::lookup_by_contact(&ctx, ContactId::SELF)
|
||||
let chat = ChatId::lookup_by_contact(&ctx, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(chat.is_none());
|
||||
|
||||
ctx.update_device_chats().await.unwrap();
|
||||
let chat = ChatIdBlocked::lookup_by_contact(&ctx, ContactId::SELF)
|
||||
let chat = ChatIdBlocked::lookup_by_contact(&ctx, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
@@ -5164,7 +5100,7 @@ mod tests {
|
||||
.await?,
|
||||
true
|
||||
);
|
||||
remove_contact_from_chat(&alice, chat_id, ContactId::SELF).await?;
|
||||
remove_contact_from_chat(&alice, chat_id, DC_CONTACT_ID_SELF).await?;
|
||||
assert_eq!(
|
||||
Chat::load_from_db(&alice, chat_id)
|
||||
.await?
|
||||
|
||||
@@ -4,8 +4,9 @@ use anyhow::{ensure, Context as _, Result};
|
||||
|
||||
use crate::chat::{update_special_chat_names, Chat, ChatId, ChatVisibility};
|
||||
use crate::constants::{
|
||||
Blocked, Chattype, DC_CHAT_ID_ALLDONE_HINT, DC_CHAT_ID_ARCHIVED_LINK, DC_GCL_ADD_ALLDONE_HINT,
|
||||
DC_GCL_ARCHIVED_ONLY, DC_GCL_FOR_FORWARDING, DC_GCL_NO_SPECIALS,
|
||||
Blocked, Chattype, DC_CHAT_ID_ALLDONE_HINT, DC_CHAT_ID_ARCHIVED_LINK, DC_CONTACT_ID_DEVICE,
|
||||
DC_CONTACT_ID_SELF, DC_CONTACT_ID_UNDEFINED, DC_GCL_ADD_ALLDONE_HINT, DC_GCL_ARCHIVED_ONLY,
|
||||
DC_GCL_FOR_FORWARDING, DC_GCL_NO_SPECIALS,
|
||||
};
|
||||
use crate::contact::{Contact, ContactId};
|
||||
use crate::context::Context;
|
||||
@@ -91,6 +92,12 @@ impl Chatlist {
|
||||
let flag_no_specials = 0 != listflags & DC_GCL_NO_SPECIALS;
|
||||
let flag_add_alldone_hint = 0 != listflags & DC_GCL_ADD_ALLDONE_HINT;
|
||||
|
||||
// Note that we do not emit DC_EVENT_MSGS_MODIFIED here even if some
|
||||
// messages get deleted to avoid reloading the same chatlist.
|
||||
if let Err(err) = delete_expired_messages(context).await {
|
||||
warn!(context, "Failed to hide expired messages: {}", err);
|
||||
}
|
||||
|
||||
let mut add_archived_link_item = false;
|
||||
|
||||
let process_row = |row: &rusqlite::Row| {
|
||||
@@ -105,7 +112,7 @@ impl Chatlist {
|
||||
};
|
||||
|
||||
let skip_id = if flag_for_forwarding {
|
||||
ChatId::lookup_by_contact(context, ContactId::DEVICE)
|
||||
ChatId::lookup_by_contact(context, DC_CONTACT_ID_DEVICE)
|
||||
.await?
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
@@ -209,7 +216,7 @@ impl Chatlist {
|
||||
} else {
|
||||
// show normal chatlist
|
||||
let sort_id_up = if flag_for_forwarding {
|
||||
ChatId::lookup_by_contact(context, ContactId::SELF)
|
||||
ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF)
|
||||
.await?
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
@@ -319,7 +326,7 @@ impl Chatlist {
|
||||
|
||||
let (lastmsg, lastcontact) = if let Some(lastmsg_id) = lastmsg_id {
|
||||
let lastmsg = Message::load_from_db(context, lastmsg_id).await?;
|
||||
if lastmsg.from_id == ContactId::SELF {
|
||||
if lastmsg.from_id == DC_CONTACT_ID_SELF {
|
||||
(Some(lastmsg), None)
|
||||
} else {
|
||||
match chat.typ {
|
||||
@@ -336,7 +343,7 @@ impl Chatlist {
|
||||
|
||||
if chat.id.is_archived_link() {
|
||||
Ok(Default::default())
|
||||
} else if let Some(lastmsg) = lastmsg.filter(|msg| msg.from_id != ContactId::UNDEFINED) {
|
||||
} else if let Some(lastmsg) = lastmsg.filter(|msg| msg.from_id != DC_CONTACT_ID_UNDEFINED) {
|
||||
Ok(Summary::new(context, &lastmsg, chat, lastcontact.as_ref()).await)
|
||||
} else {
|
||||
Ok(Summary {
|
||||
|
||||
@@ -4,6 +4,7 @@ use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::chat::ChatId;
|
||||
use crate::contact::ContactId;
|
||||
|
||||
pub static DC_VERSION_STR: Lazy<String> = Lazy::new(|| env!("CARGO_PKG_VERSION").to_string());
|
||||
|
||||
@@ -179,6 +180,16 @@ pub const DC_ELLIPSIS: &str = "[...]";
|
||||
/// `char`s), not Unicode Grapheme Clusters.
|
||||
pub const DC_DESIRED_TEXT_LEN: usize = 5000;
|
||||
|
||||
pub const DC_CONTACT_ID_UNDEFINED: ContactId = ContactId::new(0);
|
||||
pub const DC_CONTACT_ID_SELF: ContactId = ContactId::new(1);
|
||||
pub const DC_CONTACT_ID_INFO: ContactId = ContactId::new(2);
|
||||
pub const DC_CONTACT_ID_DEVICE: ContactId = ContactId::new(5);
|
||||
pub const DC_CONTACT_ID_LAST_SPECIAL: ContactId = ContactId::new(9);
|
||||
|
||||
// decorative address that is used for DC_CONTACT_ID_DEVICE
|
||||
// when an api that returns an email is called.
|
||||
pub const DC_CONTACT_ID_DEVICE_ADDR: &str = "device@localhost";
|
||||
|
||||
// Flags for empty server job
|
||||
|
||||
pub const DC_EMPTY_MVBOX: u32 = 0x01;
|
||||
|
||||
153
src/contact.rs
153
src/contact.rs
@@ -14,7 +14,11 @@ use crate::aheader::EncryptPreference;
|
||||
use crate::chat::ChatId;
|
||||
use crate::color::str_to_color;
|
||||
use crate::config::Config;
|
||||
use crate::constants::{Blocked, Chattype, DC_GCL_ADD_SELF, DC_GCL_VERIFIED_ONLY};
|
||||
use crate::constants::{
|
||||
Blocked, Chattype, DC_CONTACT_ID_DEVICE, DC_CONTACT_ID_DEVICE_ADDR, DC_CONTACT_ID_INFO,
|
||||
DC_CONTACT_ID_LAST_SPECIAL, DC_CONTACT_ID_SELF, DC_CONTACT_ID_UNDEFINED, DC_GCL_ADD_SELF,
|
||||
DC_GCL_VERIFIED_ONLY,
|
||||
};
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::{dc_get_abs_path, improve_single_line_input, EmailAddress};
|
||||
use crate::events::EventType;
|
||||
@@ -30,44 +34,18 @@ use crate::{chat, stock_str};
|
||||
///
|
||||
/// Some contact IDs are reserved to identify special contacts. This
|
||||
/// type can represent both the special as well as normal contacts.
|
||||
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Copy, Clone, Default, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct ContactId(u32);
|
||||
|
||||
impl ContactId {
|
||||
pub const UNDEFINED: ContactId = ContactId::new(0);
|
||||
/// The owner of the account.
|
||||
///
|
||||
/// The email-address is set by `dc_set_config` using "addr".
|
||||
pub const SELF: ContactId = ContactId::new(1);
|
||||
pub const INFO: ContactId = ContactId::new(2);
|
||||
pub const DEVICE: ContactId = ContactId::new(5);
|
||||
const LAST_SPECIAL: ContactId = ContactId::new(9);
|
||||
|
||||
/// Address to go with [`ContactId::DEVICE`].
|
||||
///
|
||||
/// This is used by APIs which need to return an email address for this contact.
|
||||
pub const DEVICE_ADDR: &'static str = "device@localhost";
|
||||
|
||||
/// Creates a new [`ContactId`].
|
||||
pub const fn new(id: u32) -> ContactId {
|
||||
ContactId(id)
|
||||
}
|
||||
|
||||
/// Whether this is a special [`ContactId`].
|
||||
///
|
||||
/// Some [`ContactId`]s are reserved for special contacts like [`ContactId::SELF`],
|
||||
/// [`ContactId::INFO`] and [`ContactId::DEVICE`]. This function indicates whether this
|
||||
/// [`ContactId`] is any of the reserved special [`ContactId`]s (`true`) or whether it
|
||||
/// is the [`ContactId`] of a real contact (`false`).
|
||||
pub fn is_special(&self) -> bool {
|
||||
self.0 <= Self::LAST_SPECIAL.0
|
||||
}
|
||||
|
||||
/// Numerical representation of the [`ContactId`].
|
||||
///
|
||||
/// Each contact ID has a unique numerical representation which is used in the database
|
||||
/// (via [`rusqlite::ToSql`]) and also for FFI purposes. In Rust code you should never
|
||||
/// need to use this directly.
|
||||
/// Bad evil escape hatch, do not use.
|
||||
pub const fn to_u32(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
@@ -75,15 +53,15 @@ impl ContactId {
|
||||
|
||||
impl fmt::Display for ContactId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if *self == ContactId::UNDEFINED {
|
||||
if *self == DC_CONTACT_ID_UNDEFINED {
|
||||
write!(f, "Contact#Undefined")
|
||||
} else if *self == ContactId::SELF {
|
||||
} else if *self == DC_CONTACT_ID_SELF {
|
||||
write!(f, "Contact#Self")
|
||||
} else if *self == ContactId::INFO {
|
||||
} else if *self == DC_CONTACT_ID_INFO {
|
||||
write!(f, "Contact#Info")
|
||||
} else if *self == ContactId::DEVICE {
|
||||
} else if *self == DC_CONTACT_ID_DEVICE {
|
||||
write!(f, "Contact#Device")
|
||||
} else if self.is_special() {
|
||||
} else if *self <= DC_CONTACT_ID_LAST_SPECIAL {
|
||||
write!(f, "Contact#Special{}", self.0)
|
||||
} else {
|
||||
write!(f, "Contact#{}", self.0)
|
||||
@@ -126,6 +104,12 @@ impl rusqlite::types::FromSql for ContactId {
|
||||
#[derive(Debug)]
|
||||
pub struct Contact {
|
||||
/// The contact ID.
|
||||
///
|
||||
/// Special message IDs:
|
||||
/// - DC_CONTACT_ID_SELF (1) - this is the owner of the account with the email-address set by
|
||||
/// `dc_set_config` using "addr".
|
||||
///
|
||||
/// Normal contact IDs are larger than these special ones (larger than DC_CONTACT_ID_LAST_SPECIAL).
|
||||
pub id: ContactId,
|
||||
|
||||
/// Contact name. It is recommended to use `Contact::get_name`,
|
||||
@@ -294,7 +278,7 @@ impl Contact {
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
if contact_id == ContactId::SELF {
|
||||
if contact_id == DC_CONTACT_ID_SELF {
|
||||
contact.name = stock_str::self_msg(context).await;
|
||||
contact.addr = context
|
||||
.get_config(Config::ConfiguredAddr)
|
||||
@@ -304,9 +288,9 @@ impl Contact {
|
||||
.get_config(Config::Selfstatus)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
} else if contact_id == ContactId::DEVICE {
|
||||
} else if contact_id == DC_CONTACT_ID_DEVICE {
|
||||
contact.name = stock_str::device_messages(context).await;
|
||||
contact.addr = ContactId::DEVICE_ADDR.to_string();
|
||||
contact.addr = DC_CONTACT_ID_DEVICE_ADDR.to_string();
|
||||
contact.status = stock_str::device_messages_hint(context).await;
|
||||
}
|
||||
Ok(contact)
|
||||
@@ -400,7 +384,7 @@ impl Contact {
|
||||
|
||||
if let Some(addr_self) = context.get_config(Config::ConfiguredAddr).await? {
|
||||
if addr_cmp(addr_normalized, &addr_self) {
|
||||
return Ok(Some(ContactId::SELF));
|
||||
return Ok(Some(DC_CONTACT_ID_SELF));
|
||||
}
|
||||
}
|
||||
let id = context
|
||||
@@ -409,7 +393,11 @@ impl Contact {
|
||||
"SELECT id FROM contacts \
|
||||
WHERE addr=?1 COLLATE NOCASE \
|
||||
AND id>?2 AND origin>=?3 AND blocked=0;",
|
||||
paramsv![addr_normalized, ContactId::LAST_SPECIAL, min_origin as u32,],
|
||||
paramsv![
|
||||
addr_normalized,
|
||||
DC_CONTACT_ID_LAST_SPECIAL,
|
||||
min_origin as u32,
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
Ok(id)
|
||||
@@ -458,7 +446,7 @@ impl Contact {
|
||||
.unwrap_or_default();
|
||||
|
||||
if addr_cmp(&addr, &addr_self) {
|
||||
return Ok((ContactId::SELF, sth_modified));
|
||||
return Ok((DC_CONTACT_ID_SELF, sth_modified));
|
||||
}
|
||||
|
||||
if !may_be_valid_addr(&addr) {
|
||||
@@ -718,7 +706,7 @@ impl Contact {
|
||||
ORDER BY LOWER(iif(c.name='',c.authname,c.name)||c.addr),c.id;",
|
||||
paramsv![
|
||||
self_addr,
|
||||
ContactId::LAST_SPECIAL,
|
||||
DC_CONTACT_ID_LAST_SPECIAL,
|
||||
Origin::IncomingReplyTo,
|
||||
s3str_like_cmd,
|
||||
s3str_like_cmd,
|
||||
@@ -762,7 +750,11 @@ impl Contact {
|
||||
AND origin>=?3
|
||||
AND blocked=0
|
||||
ORDER BY LOWER(iif(name='',authname,name)||addr),id;",
|
||||
paramsv![self_addr, ContactId::LAST_SPECIAL, Origin::IncomingReplyTo],
|
||||
paramsv![
|
||||
self_addr,
|
||||
DC_CONTACT_ID_LAST_SPECIAL,
|
||||
Origin::IncomingReplyTo
|
||||
],
|
||||
|row| row.get::<_, ContactId>(0),
|
||||
|ids| {
|
||||
for id in ids {
|
||||
@@ -775,7 +767,7 @@ impl Contact {
|
||||
}
|
||||
|
||||
if flag_add_self && add_self {
|
||||
ret.push(ContactId::SELF);
|
||||
ret.push(DC_CONTACT_ID_SELF);
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
@@ -830,7 +822,7 @@ impl Contact {
|
||||
.sql
|
||||
.count(
|
||||
"SELECT COUNT(*) FROM contacts WHERE id>? AND blocked!=0",
|
||||
paramsv![ContactId::LAST_SPECIAL],
|
||||
paramsv![DC_CONTACT_ID_LAST_SPECIAL],
|
||||
)
|
||||
.await?;
|
||||
Ok(count as usize)
|
||||
@@ -846,7 +838,7 @@ impl Contact {
|
||||
.sql
|
||||
.query_map(
|
||||
"SELECT id FROM contacts WHERE id>? AND blocked!=0 ORDER BY LOWER(iif(name='',authname,name)||addr),id;",
|
||||
paramsv![ContactId::LAST_SPECIAL],
|
||||
paramsv![DC_CONTACT_ID_LAST_SPECIAL],
|
||||
|row| row.get::<_, ContactId>(0),
|
||||
|ids| {
|
||||
ids.collect::<std::result::Result<Vec<_>, _>>()
|
||||
@@ -864,7 +856,7 @@ impl Contact {
|
||||
/// fingerprints of the keys involved.
|
||||
pub async fn get_encrinfo(context: &Context, contact_id: ContactId) -> Result<String> {
|
||||
ensure!(
|
||||
!contact_id.is_special(),
|
||||
contact_id > DC_CONTACT_ID_LAST_SPECIAL,
|
||||
"Can not provide encryption info for special contact"
|
||||
);
|
||||
|
||||
@@ -932,7 +924,10 @@ impl Contact {
|
||||
///
|
||||
/// May result in a `#DC_EVENT_CONTACTS_CHANGED` event.
|
||||
pub async fn delete(context: &Context, contact_id: ContactId) -> Result<()> {
|
||||
ensure!(!contact_id.is_special(), "Can not delete special contact");
|
||||
ensure!(
|
||||
contact_id > DC_CONTACT_ID_LAST_SPECIAL,
|
||||
"Can not delete special contact"
|
||||
);
|
||||
|
||||
let count_chats = context
|
||||
.sql
|
||||
@@ -968,7 +963,7 @@ impl Contact {
|
||||
|
||||
/// Get a single contact object. For a list, see eg. dc_get_contacts().
|
||||
///
|
||||
/// For contact ContactId::SELF (1), the function returns sth.
|
||||
/// For contact DC_CONTACT_ID_SELF (1), the function returns sth.
|
||||
/// like "Me" in the selected language and the email address
|
||||
/// defined by dc_set_config().
|
||||
pub async fn get_by_id(context: &Context, contact_id: ContactId) -> Result<Contact> {
|
||||
@@ -1061,7 +1056,7 @@ impl Contact {
|
||||
/// This is the image set by each remote user on their own
|
||||
/// using dc_set_config(context, "selfavatar", image).
|
||||
pub async fn get_profile_image(&self, context: &Context) -> Result<Option<PathBuf>> {
|
||||
if self.id == ContactId::SELF {
|
||||
if self.id == DC_CONTACT_ID_SELF {
|
||||
if let Some(p) = context.get_config(Config::Selfavatar).await? {
|
||||
return Ok(Some(PathBuf::from(p)));
|
||||
}
|
||||
@@ -1107,7 +1102,7 @@ impl Contact {
|
||||
) -> Result<VerifiedStatus> {
|
||||
// We're always sort of secured-verified as we could verify the key on this device any time with the key
|
||||
// on this device
|
||||
if self.id == ContactId::SELF {
|
||||
if self.id == DC_CONTACT_ID_SELF {
|
||||
return Ok(VerifiedStatus::BidirectVerified);
|
||||
}
|
||||
|
||||
@@ -1155,14 +1150,14 @@ impl Contact {
|
||||
.sql
|
||||
.count(
|
||||
"SELECT COUNT(*) FROM contacts WHERE id>?;",
|
||||
paramsv![ContactId::LAST_SPECIAL],
|
||||
paramsv![DC_CONTACT_ID_LAST_SPECIAL],
|
||||
)
|
||||
.await?;
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
pub async fn real_exists_by_id(context: &Context, contact_id: ContactId) -> Result<bool> {
|
||||
if contact_id.is_special() {
|
||||
if contact_id <= DC_CONTACT_ID_LAST_SPECIAL {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
@@ -1235,7 +1230,7 @@ async fn set_block_contact(
|
||||
new_blocking: bool,
|
||||
) -> Result<()> {
|
||||
ensure!(
|
||||
!contact_id.is_special(),
|
||||
contact_id > DC_CONTACT_ID_LAST_SPECIAL,
|
||||
"Can't block special contact {}",
|
||||
contact_id
|
||||
);
|
||||
@@ -1305,7 +1300,7 @@ pub(crate) async fn set_profile_image(
|
||||
let mut contact = Contact::load_from_db(context, contact_id).await?;
|
||||
let changed = match profile_image {
|
||||
AvatarAction::Change(profile_image) => {
|
||||
if contact_id == ContactId::SELF {
|
||||
if contact_id == DC_CONTACT_ID_SELF {
|
||||
if was_encrypted {
|
||||
context
|
||||
.set_config(Config::Selfavatar, Some(profile_image))
|
||||
@@ -1319,7 +1314,7 @@ pub(crate) async fn set_profile_image(
|
||||
true
|
||||
}
|
||||
AvatarAction::Delete => {
|
||||
if contact_id == ContactId::SELF {
|
||||
if contact_id == DC_CONTACT_ID_SELF {
|
||||
if was_encrypted {
|
||||
context.set_config(Config::Selfavatar, None).await?;
|
||||
} else {
|
||||
@@ -1350,7 +1345,7 @@ pub(crate) async fn set_status(
|
||||
encrypted: bool,
|
||||
has_chat_version: bool,
|
||||
) -> Result<()> {
|
||||
if contact_id == ContactId::SELF {
|
||||
if contact_id == DC_CONTACT_ID_SELF {
|
||||
if encrypted && has_chat_version {
|
||||
context
|
||||
.set_config(Config::Selfstatus, Some(&status))
|
||||
@@ -1375,7 +1370,7 @@ pub(crate) async fn update_last_seen(
|
||||
timestamp: i64,
|
||||
) -> Result<()> {
|
||||
ensure!(
|
||||
!contact_id.is_special(),
|
||||
contact_id > DC_CONTACT_ID_LAST_SPECIAL,
|
||||
"Can not update special contact last seen timestamp"
|
||||
);
|
||||
|
||||
@@ -1479,17 +1474,6 @@ mod tests {
|
||||
use crate::message::Message;
|
||||
use crate::test_utils::{self, TestContext};
|
||||
|
||||
#[test]
|
||||
fn test_contact_id_values() {
|
||||
// Some FFI users need to have the values of these fixed, how naughty. But let's
|
||||
// make sure we don't modify them anyway.
|
||||
assert_eq!(ContactId::UNDEFINED.to_u32(), 0);
|
||||
assert_eq!(ContactId::SELF.to_u32(), 1);
|
||||
assert_eq!(ContactId::INFO.to_u32(), 2);
|
||||
assert_eq!(ContactId::DEVICE.to_u32(), 5);
|
||||
assert_eq!(ContactId::LAST_SPECIAL.to_u32(), 9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_may_be_valid_addr() {
|
||||
assert_eq!(may_be_valid_addr(""), false);
|
||||
@@ -1553,7 +1537,7 @@ mod tests {
|
||||
Origin::IncomingReplyTo,
|
||||
)
|
||||
.await?;
|
||||
assert_ne!(id, ContactId::UNDEFINED);
|
||||
assert_ne!(id, ContactId::new(0));
|
||||
|
||||
let contact = Contact::load_from_db(&context.ctx, id).await.unwrap();
|
||||
assert_eq!(contact.get_name(), "");
|
||||
@@ -1631,7 +1615,7 @@ mod tests {
|
||||
Contact::add_or_lookup(&t, "bla foo", "one@eins.org", Origin::IncomingUnknownTo)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
assert_eq!(sth_modified, Modifier::Modified);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_id(), contact_id);
|
||||
@@ -1658,7 +1642,7 @@ mod tests {
|
||||
Contact::add_or_lookup(&t, "", "three@drei.sam", Origin::IncomingUnknownTo)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
assert_eq!(sth_modified, Modifier::None);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_name(), "");
|
||||
@@ -1698,7 +1682,7 @@ mod tests {
|
||||
Contact::add_or_lookup(&t, "", "alice@w.de", Origin::IncomingUnknownTo)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
assert_eq!(sth_modified, Modifier::None);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_name(), "Wonderland, Alice");
|
||||
@@ -1707,7 +1691,8 @@ mod tests {
|
||||
assert_eq!(contact.get_name_n_addr(), "Wonderland, Alice (alice@w.de)");
|
||||
|
||||
// check SELF
|
||||
let contact = Contact::load_from_db(&t, ContactId::SELF).await.unwrap();
|
||||
let contact = Contact::load_from_db(&t, DC_CONTACT_ID_SELF).await.unwrap();
|
||||
assert_eq!(DC_CONTACT_ID_SELF, ContactId::new(1));
|
||||
assert_eq!(contact.get_name(), stock_str::self_msg(&t).await);
|
||||
assert_eq!(contact.get_addr(), ""); // we're not configured
|
||||
assert!(!contact.is_blocked());
|
||||
@@ -1717,7 +1702,7 @@ mod tests {
|
||||
async fn test_delete() -> Result<()> {
|
||||
let alice = TestContext::new_alice().await;
|
||||
|
||||
assert!(Contact::delete(&alice, ContactId::SELF).await.is_err());
|
||||
assert!(Contact::delete(&alice, DC_CONTACT_ID_SELF).await.is_err());
|
||||
|
||||
// Create Bob contact
|
||||
let (contact_id, _) =
|
||||
@@ -1750,7 +1735,7 @@ mod tests {
|
||||
Contact::add_or_lookup(&t, "bob1", "bob@example.org", Origin::IncomingUnknownFrom)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
assert_eq!(sth_modified, Modifier::Created);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_authname(), "bob1");
|
||||
@@ -1762,7 +1747,7 @@ mod tests {
|
||||
Contact::add_or_lookup(&t, "bob2", "bob@example.org", Origin::IncomingUnknownFrom)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
assert_eq!(sth_modified, Modifier::Modified);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_authname(), "bob2");
|
||||
@@ -1773,7 +1758,7 @@ mod tests {
|
||||
let contact_id = Contact::create(&t, "bob3", "bob@example.org")
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_authname(), "bob2");
|
||||
assert_eq!(contact.get_name(), "bob3");
|
||||
@@ -1784,7 +1769,7 @@ mod tests {
|
||||
Contact::add_or_lookup(&t, "bob4", "bob@example.org", Origin::IncomingUnknownFrom)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
assert_eq!(sth_modified, Modifier::Modified);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_authname(), "bob4");
|
||||
@@ -1798,7 +1783,7 @@ mod tests {
|
||||
|
||||
// manually create "claire@example.org" without a given name
|
||||
let contact_id = Contact::create(&t, "", "claire@example.org").await.unwrap();
|
||||
assert!(!contact_id.is_special());
|
||||
assert!(contact_id > DC_CONTACT_ID_LAST_SPECIAL);
|
||||
let contact = Contact::load_from_db(&t, contact_id).await.unwrap();
|
||||
assert_eq!(contact.get_authname(), "");
|
||||
assert_eq!(contact.get_name(), "");
|
||||
@@ -1972,7 +1957,7 @@ mod tests {
|
||||
let id = Contact::lookup_id_by_addr(&alice.ctx, "alice@example.org", Origin::Unknown)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(id, Some(ContactId::SELF));
|
||||
assert_eq!(id, Some(DC_CONTACT_ID_SELF));
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
@@ -1980,9 +1965,9 @@ mod tests {
|
||||
let alice = TestContext::new_alice().await;
|
||||
|
||||
// Return error for special IDs
|
||||
let encrinfo = Contact::get_encrinfo(&alice, ContactId::SELF).await;
|
||||
let encrinfo = Contact::get_encrinfo(&alice, DC_CONTACT_ID_SELF).await;
|
||||
assert!(encrinfo.is_err());
|
||||
let encrinfo = Contact::get_encrinfo(&alice, ContactId::DEVICE).await;
|
||||
let encrinfo = Contact::get_encrinfo(&alice, DC_CONTACT_ID_DEVICE).await;
|
||||
assert!(encrinfo.is_err());
|
||||
|
||||
let (contact_bob_id, _modified) =
|
||||
|
||||
@@ -56,7 +56,7 @@ pub struct InnerContext {
|
||||
pub(crate) events: Events,
|
||||
|
||||
pub(crate) scheduler: RwLock<Scheduler>,
|
||||
pub(crate) ephemeral_task: RwLock<Option<(task::JoinHandle<()>, Sender<()>)>>,
|
||||
pub(crate) ephemeral_task: RwLock<Option<task::JoinHandle<()>>>,
|
||||
|
||||
/// Recently loaded quota information, if any.
|
||||
/// Set to `None` if quota was never tried to load.
|
||||
@@ -670,7 +670,7 @@ mod tests {
|
||||
use crate::chat::{
|
||||
get_chat_contacts, get_chat_msgs, send_msg, set_muted, Chat, ChatId, MuteDuration,
|
||||
};
|
||||
use crate::contact::ContactId;
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::dc_tools::dc_create_outgoing_rfc724_mid;
|
||||
use crate::message::{Message, Viewtype};
|
||||
@@ -956,7 +956,7 @@ mod tests {
|
||||
#[async_std::test]
|
||||
async fn test_search_msgs() -> Result<()> {
|
||||
let alice = TestContext::new_alice().await;
|
||||
let self_talk = ChatId::create_for_contact(&alice, ContactId::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;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Internet Message Format reception pipeline.
|
||||
|
||||
use std::cmp::min;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::BTreeSet;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use anyhow::{bail, ensure, Context as _, Result};
|
||||
@@ -13,7 +13,9 @@ use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::chat::{self, Chat, ChatId, ChatIdBlocked, ProtectionStatus};
|
||||
use crate::config::Config;
|
||||
use crate::constants::{Blocked, Chattype, ShowEmails, DC_CHAT_ID_TRASH};
|
||||
use crate::constants::{
|
||||
Blocked, Chattype, ShowEmails, DC_CHAT_ID_TRASH, DC_CONTACT_ID_LAST_SPECIAL, DC_CONTACT_ID_SELF,
|
||||
};
|
||||
use crate::contact;
|
||||
use crate::contact::{
|
||||
addr_cmp, may_be_valid_addr, normalize_name, Contact, ContactId, Origin, VerifiedStatus,
|
||||
@@ -178,7 +180,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
||||
let (from_id, _from_id_blocked, incoming_origin) =
|
||||
from_field_to_contact_id(context, &mime_parser.from, prevent_rename).await?;
|
||||
|
||||
let incoming = from_id != ContactId::SELF;
|
||||
let incoming = from_id != DC_CONTACT_ID_SELF;
|
||||
|
||||
let to_ids = dc_add_or_lookup_contacts_by_address_list(
|
||||
context,
|
||||
@@ -220,7 +222,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
||||
.await
|
||||
.context("add_parts error")?;
|
||||
|
||||
if !from_id.is_special() {
|
||||
if from_id > DC_CONTACT_ID_LAST_SPECIAL {
|
||||
contact::update_last_seen(context, from_id, sent_timestamp).await?;
|
||||
}
|
||||
|
||||
@@ -254,7 +256,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
||||
save_locations(context, &mime_parser, chat_id, from_id, insert_msg_id).await?;
|
||||
|
||||
if let Some(ref sync_items) = mime_parser.sync_items {
|
||||
if from_id == ContactId::SELF {
|
||||
if from_id == DC_CONTACT_ID_SELF {
|
||||
if mime_parser.was_encrypted() {
|
||||
if let Err(err) = context.execute_sync_items(sync_items).await {
|
||||
warn!(context, "receive_imf cannot execute sync items: {}", err);
|
||||
@@ -277,7 +279,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
||||
}
|
||||
|
||||
if let Some(avatar_action) = &mime_parser.user_avatar {
|
||||
if from_id != ContactId::UNDEFINED
|
||||
if from_id != ContactId::new(0)
|
||||
&& context
|
||||
.update_contacts_timestamp(from_id, Param::AvatarTimestamp, sent_timestamp)
|
||||
.await?
|
||||
@@ -305,7 +307,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
||||
// Ignore MDNs though, as they never contain the signature even if user has set it.
|
||||
if mime_parser.mdn_reports.is_empty()
|
||||
&& is_partial_download.is_none()
|
||||
&& from_id != ContactId::UNDEFINED
|
||||
&& from_id != ContactId::new(0)
|
||||
&& context
|
||||
.update_contacts_timestamp(from_id, Param::StatusTimestamp, sent_timestamp)
|
||||
.await?
|
||||
@@ -393,8 +395,8 @@ pub async fn from_field_to_contact_id(
|
||||
)
|
||||
.await?;
|
||||
|
||||
if from_ids.contains(&ContactId::SELF) {
|
||||
Ok((ContactId::SELF, false, Origin::OutgoingBcc))
|
||||
if from_ids.contains(&DC_CONTACT_ID_SELF) {
|
||||
Ok((DC_CONTACT_ID_SELF, false, Origin::OutgoingBcc))
|
||||
} else if !from_ids.is_empty() {
|
||||
if from_ids.len() > 1 {
|
||||
warn!(
|
||||
@@ -417,7 +419,7 @@ pub async fn from_field_to_contact_id(
|
||||
"mail has an empty From header: {:?}", from_address_list
|
||||
);
|
||||
|
||||
Ok((ContactId::UNDEFINED, false, Origin::Unknown))
|
||||
Ok((ContactId::new(0), false, Origin::Unknown))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,7 +494,7 @@ async fn add_parts(
|
||||
let state: MessageState;
|
||||
let mut needs_delete_job = false;
|
||||
if incoming {
|
||||
to_id = ContactId::SELF;
|
||||
to_id = DC_CONTACT_ID_SELF;
|
||||
|
||||
// Whether the message is a part of securejoin handshake that should be marked as seen
|
||||
// automatically.
|
||||
@@ -524,7 +526,7 @@ async fn add_parts(
|
||||
securejoin_seen = false;
|
||||
}
|
||||
|
||||
let test_normal_chat = if from_id == ContactId::UNDEFINED {
|
||||
let test_normal_chat = if from_id == ContactId::new(0) {
|
||||
Default::default()
|
||||
} else {
|
||||
ChatIdBlocked::lookup_by_contact(context, from_id).await?
|
||||
@@ -666,7 +668,7 @@ async fn add_parts(
|
||||
|
||||
if chat_id.is_none() {
|
||||
// try to create a normal chat
|
||||
let create_blocked = if from_id == ContactId::SELF {
|
||||
let create_blocked = if from_id == DC_CONTACT_ID_SELF {
|
||||
Blocked::Not
|
||||
} else {
|
||||
Blocked::Request
|
||||
@@ -718,8 +720,9 @@ async fn add_parts(
|
||||
state = MessageState::OutDelivered;
|
||||
to_id = to_ids.get(0).cloned().unwrap_or_default();
|
||||
|
||||
let self_sent =
|
||||
from_id == ContactId::SELF && to_ids.len() == 1 && to_ids.contains(&ContactId::SELF);
|
||||
let self_sent = from_id == DC_CONTACT_ID_SELF
|
||||
&& to_ids.len() == 1
|
||||
&& to_ids.contains(&DC_CONTACT_ID_SELF);
|
||||
|
||||
// handshake may mark contacts as verified and must be processed before chats are created
|
||||
if mime_parser.get_header(HeaderDef::SecureJoin).is_some() {
|
||||
@@ -833,11 +836,12 @@ async fn add_parts(
|
||||
}
|
||||
|
||||
if chat_id.is_none() && self_sent {
|
||||
// from_id==to_id==ContactId::SELF - this is a self-sent messages,
|
||||
// from_id==to_id==DC_CONTACT_ID_SELF - this is a self-sent messages,
|
||||
// maybe an Autocrypt Setup Message
|
||||
if let Ok(chat) = ChatIdBlocked::get_for_contact(context, ContactId::SELF, Blocked::Not)
|
||||
.await
|
||||
.log_err(context, "Failed to get (new) chat for contact")
|
||||
if let Ok(chat) =
|
||||
ChatIdBlocked::get_for_contact(context, DC_CONTACT_ID_SELF, Blocked::Not)
|
||||
.await
|
||||
.log_err(context, "Failed to get (new) chat for contact")
|
||||
{
|
||||
chat_id = Some(chat.id);
|
||||
chat_id_blocked = chat.blocked;
|
||||
@@ -1144,8 +1148,8 @@ INSERT INTO msgs
|
||||
stmt.execute(paramsv![
|
||||
rfc724_mid,
|
||||
chat_id,
|
||||
if trash { ContactId::UNDEFINED } else { from_id },
|
||||
if trash { ContactId::UNDEFINED } else { to_id },
|
||||
if trash { ContactId::new(0) } else { from_id },
|
||||
if trash { ContactId::new(0) } else { to_id },
|
||||
sort_timestamp,
|
||||
sent_timestamp,
|
||||
rcvd_timestamp,
|
||||
@@ -1187,7 +1191,7 @@ INSERT INTO msgs
|
||||
}
|
||||
drop(conn);
|
||||
|
||||
chat_id.unarchive_if_not_muted(context).await?;
|
||||
chat_id.unarchive(context).await?;
|
||||
|
||||
info!(
|
||||
context,
|
||||
@@ -1371,14 +1375,14 @@ async fn is_probably_private_reply(
|
||||
// contain a Chat-Group-Id header and can be sorted into the correct chat this way.
|
||||
|
||||
let private_message =
|
||||
(to_ids == [ContactId::SELF]) || (from_id == ContactId::SELF && to_ids.len() == 1);
|
||||
(to_ids == [DC_CONTACT_ID_SELF]) || (from_id == DC_CONTACT_ID_SELF && to_ids.len() == 1);
|
||||
if !private_message {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if !mime_parser.has_chat_version() {
|
||||
let chat_contacts = chat::get_chat_contacts(context, parent_chat_id).await?;
|
||||
if chat_contacts.len() == 2 && chat_contacts.contains(&ContactId::SELF) {
|
||||
if chat_contacts.len() == 2 && chat_contacts.contains(&DC_CONTACT_ID_SELF) {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
@@ -1406,8 +1410,8 @@ async fn create_or_lookup_group(
|
||||
if !member_ids.contains(&(from_id)) {
|
||||
member_ids.push(from_id);
|
||||
}
|
||||
if !member_ids.contains(&(ContactId::SELF)) {
|
||||
member_ids.push(ContactId::SELF);
|
||||
if !member_ids.contains(&(DC_CONTACT_ID_SELF)) {
|
||||
member_ids.push(DC_CONTACT_ID_SELF);
|
||||
}
|
||||
|
||||
let res = create_adhoc_group(context, mime_parser, create_blocked, &member_ids)
|
||||
@@ -1488,8 +1492,9 @@ async fn create_or_lookup_group(
|
||||
chat_id_blocked = create_blocked;
|
||||
|
||||
// Create initial member list.
|
||||
chat::add_to_chat_contacts_table(context, new_chat_id, ContactId::SELF).await?;
|
||||
if !from_id.is_special() && !chat::is_contact_in_chat(context, new_chat_id, from_id).await?
|
||||
chat::add_to_chat_contacts_table(context, new_chat_id, DC_CONTACT_ID_SELF).await?;
|
||||
if from_id > DC_CONTACT_ID_LAST_SPECIAL
|
||||
&& !chat::is_contact_in_chat(context, new_chat_id, from_id).await?
|
||||
{
|
||||
chat::add_to_chat_contacts_table(context, new_chat_id, from_id).await?;
|
||||
}
|
||||
@@ -1642,7 +1647,7 @@ async fn apply_group_changes(
|
||||
|
||||
// add members to group/check members
|
||||
if recreate_member_list {
|
||||
if chat::is_contact_in_chat(context, chat_id, ContactId::SELF).await?
|
||||
if chat::is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF).await?
|
||||
&& !chat::is_contact_in_chat(context, chat_id, from_id).await?
|
||||
{
|
||||
warn!(
|
||||
@@ -1656,7 +1661,7 @@ async fn apply_group_changes(
|
||||
.await?
|
||||
{
|
||||
if removed_id.is_some()
|
||||
|| !chat::is_contact_in_chat(context, chat_id, ContactId::SELF).await?
|
||||
|| !chat::is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF).await?
|
||||
{
|
||||
// Members could have been removed while we were
|
||||
// absent. We can't use existing member list and need to
|
||||
@@ -1669,11 +1674,11 @@ async fn apply_group_changes(
|
||||
)
|
||||
.await?;
|
||||
|
||||
if removed_id != Some(ContactId::SELF) {
|
||||
chat::add_to_chat_contacts_table(context, chat_id, ContactId::SELF).await?;
|
||||
if removed_id != Some(DC_CONTACT_ID_SELF) {
|
||||
chat::add_to_chat_contacts_table(context, chat_id, DC_CONTACT_ID_SELF).await?;
|
||||
}
|
||||
}
|
||||
if !from_id.is_special()
|
||||
if from_id > DC_CONTACT_ID_LAST_SPECIAL
|
||||
&& !Contact::addr_equals_contact(context, &self_addr, from_id).await?
|
||||
&& !chat::is_contact_in_chat(context, chat_id, from_id).await?
|
||||
&& removed_id != Some(from_id)
|
||||
@@ -1694,7 +1699,7 @@ async fn apply_group_changes(
|
||||
}
|
||||
|
||||
if let Some(avatar_action) = &mime_parser.group_avatar {
|
||||
if !chat::is_contact_in_chat(context, chat_id, ContactId::SELF).await? {
|
||||
if !chat::is_contact_in_chat(context, chat_id, DC_CONTACT_ID_SELF).await? {
|
||||
warn!(
|
||||
context,
|
||||
"Received group avatar update for group chat {} we are not a member of.", chat_id
|
||||
@@ -1844,7 +1849,7 @@ async fn create_or_lookup_mailinglist(
|
||||
)
|
||||
})?;
|
||||
|
||||
chat::add_to_chat_contacts_table(context, chat_id, ContactId::SELF).await?;
|
||||
chat::add_to_chat_contacts_table(context, chat_id, DC_CONTACT_ID_SELF).await?;
|
||||
Ok(Some((chat_id, Blocked::Request)))
|
||||
} else {
|
||||
info!(context, "creating list forbidden by caller");
|
||||
@@ -2010,7 +2015,7 @@ async fn create_adhoc_grp_id(context: &Context, member_ids: &[ContactId]) -> Res
|
||||
);
|
||||
let mut params = Vec::new();
|
||||
params.extend_from_slice(member_ids);
|
||||
params.push(ContactId::SELF);
|
||||
params.push(DC_CONTACT_ID_SELF);
|
||||
|
||||
let members = context
|
||||
.sql
|
||||
@@ -2066,7 +2071,7 @@ async fn check_verified_properties(
|
||||
// and the message is signed with a verified key of the sender.
|
||||
// this check is skipped for SELF as there is no proper SELF-peerstate
|
||||
// and results in group-splits otherwise.
|
||||
if from_id != ContactId::SELF {
|
||||
if from_id != DC_CONTACT_ID_SELF {
|
||||
let peerstate = Peerstate::from_addr(context, contact.get_addr()).await?;
|
||||
|
||||
if peerstate.is_none()
|
||||
@@ -2091,7 +2096,7 @@ async fn check_verified_properties(
|
||||
let to_ids = to_ids
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|id| *id != ContactId::SELF)
|
||||
.filter(|id| *id != DC_CONTACT_ID_SELF)
|
||||
.collect::<Vec<ContactId>>();
|
||||
|
||||
if to_ids.is_empty() {
|
||||
@@ -2260,7 +2265,7 @@ async fn dc_add_or_lookup_contacts_by_address_list(
|
||||
origin: Origin,
|
||||
prevent_rename: bool,
|
||||
) -> Result<Vec<ContactId>> {
|
||||
let mut contact_ids = HashSet::new();
|
||||
let mut contact_ids = BTreeSet::new();
|
||||
for info in address_list.iter() {
|
||||
let addr = &info.addr;
|
||||
if !may_be_valid_addr(addr) {
|
||||
@@ -2286,7 +2291,7 @@ async fn add_or_lookup_contact_by_addr(
|
||||
origin: Origin,
|
||||
) -> Result<ContactId> {
|
||||
if context.is_self_addr(addr).await? {
|
||||
return Ok(ContactId::SELF);
|
||||
return Ok(DC_CONTACT_ID_SELF);
|
||||
}
|
||||
let display_name_normalized = display_name.map(normalize_name).unwrap_or_default();
|
||||
|
||||
@@ -2306,7 +2311,7 @@ mod tests {
|
||||
use crate::chat::get_chat_contacts;
|
||||
use crate::chat::{get_chat_msgs, ChatItem, ChatVisibility};
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::constants::DC_GCL_NO_SPECIALS;
|
||||
use crate::constants::{DC_CONTACT_ID_INFO, DC_GCL_NO_SPECIALS};
|
||||
use crate::message::Message;
|
||||
use crate::test_utils::{get_chat_msg, TestContext, TestContextManager};
|
||||
|
||||
@@ -2954,7 +2959,7 @@ mod tests {
|
||||
last_msg.text,
|
||||
Some(stock_str::failed_sending_to(&t, "assidhfaaspocwaeofi@gmail.com").await,)
|
||||
);
|
||||
assert_eq!(last_msg.from_id, ContactId::INFO);
|
||||
assert_eq!(last_msg.from_id, DC_CONTACT_ID_INFO);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -4896,7 +4901,7 @@ Hi, I created a group"#,
|
||||
)
|
||||
.await?;
|
||||
let msg_out = t.get_last_msg().await;
|
||||
assert_eq!(msg_out.from_id, ContactId::SELF);
|
||||
assert_eq!(msg_out.from_id, DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg_out.text.unwrap(), "Hi, I created a group");
|
||||
assert_eq!(msg_out.in_reply_to, None);
|
||||
|
||||
@@ -4921,7 +4926,7 @@ Reply from different address
|
||||
)
|
||||
.await?;
|
||||
let msg_in = t.get_last_msg().await;
|
||||
assert_eq!(msg_in.to_id, ContactId::SELF);
|
||||
assert_eq!(msg_in.to_id, DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg_in.text.unwrap(), "Reply from different address");
|
||||
assert_eq!(
|
||||
msg_in.in_reply_to.unwrap(),
|
||||
@@ -5072,7 +5077,7 @@ Reply from different address
|
||||
let received = alice1.get_last_msg().await;
|
||||
let alice1_bob_contact = alice1.add_or_lookup_contact(&bob).await;
|
||||
assert_eq!(received.from_id, alice1_bob_contact.id);
|
||||
assert_eq!(received.to_id, ContactId::SELF);
|
||||
assert_eq!(received.to_id, DC_CONTACT_ID_SELF);
|
||||
assert!(!received.hidden);
|
||||
assert_eq!(received.text, Some("Hello all!".to_string()));
|
||||
assert_eq!(received.in_reply_to, None);
|
||||
@@ -5099,7 +5104,7 @@ Reply from different address
|
||||
assert_eq!(received.chat_id, alice2.get_chat(&bob).await.unwrap().id);
|
||||
|
||||
let alice2_bob_contact = alice2.add_or_lookup_contact(&bob).await;
|
||||
assert_eq!(received.from_id, ContactId::SELF);
|
||||
assert_eq!(received.from_id, DC_CONTACT_ID_SELF);
|
||||
assert_eq!(received.to_id, alice2_bob_contact.id);
|
||||
assert!(!received.hidden);
|
||||
assert_eq!(received.text, Some("Private reply".to_string()));
|
||||
|
||||
@@ -62,18 +62,18 @@ use std::str::FromStr;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use anyhow::{ensure, Context as _, Result};
|
||||
use async_std::future::timeout;
|
||||
use async_std::{channel, task};
|
||||
use async_std::task;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::chat::{send_msg, ChatId};
|
||||
use crate::constants::{DC_CHAT_ID_LAST_SPECIAL, DC_CHAT_ID_TRASH};
|
||||
use crate::constants::{
|
||||
DC_CHAT_ID_LAST_SPECIAL, DC_CHAT_ID_TRASH, DC_CONTACT_ID_DEVICE, DC_CONTACT_ID_SELF,
|
||||
};
|
||||
use crate::contact::ContactId;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::time;
|
||||
use crate::download::MIN_DELETE_SERVER_AFTER;
|
||||
use crate::events::EventType;
|
||||
use crate::log::LogExt;
|
||||
use crate::message::{Message, MessageState, MsgId, Viewtype};
|
||||
use crate::mimeparser::SystemMessage;
|
||||
use crate::sql;
|
||||
@@ -198,7 +198,7 @@ impl ChatId {
|
||||
}
|
||||
self.inner_set_ephemeral_timer(context, timer).await?;
|
||||
let mut msg = Message::new(Viewtype::Text);
|
||||
msg.text = Some(stock_ephemeral_timer_changed(context, timer, ContactId::SELF).await);
|
||||
msg.text = Some(stock_ephemeral_timer_changed(context, timer, DC_CONTACT_ID_SELF).await);
|
||||
msg.param.set_cmd(SystemMessage::EphemeralTimerChanged);
|
||||
if let Err(err) = send_msg(context, self, &mut msg).await {
|
||||
error!(
|
||||
@@ -346,8 +346,8 @@ pub(crate) async fn delete_expired_messages(context: &Context) -> Result<bool> {
|
||||
// which information dc_receive_imf::add_parts() still adds to the db if the chat_id is TRASH
|
||||
r#"
|
||||
UPDATE msgs
|
||||
SET
|
||||
chat_id=?, txt='', subject='', txt_raw='',
|
||||
SET
|
||||
chat_id=?, txt='', subject='', txt_raw='',
|
||||
mime_headers='', from_id=0, to_id=0, param=''
|
||||
WHERE
|
||||
ephemeral_timestamp != 0
|
||||
@@ -361,10 +361,10 @@ WHERE
|
||||
> 0;
|
||||
|
||||
if let Some(delete_device_after) = context.get_config_delete_device_after().await? {
|
||||
let self_chat_id = ChatId::lookup_by_contact(context, ContactId::SELF)
|
||||
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, ContactId::DEVICE)
|
||||
let device_chat_id = ChatId::lookup_by_contact(context, DC_CONTACT_ID_DEVICE)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -399,14 +399,6 @@ WHERE
|
||||
}
|
||||
|
||||
schedule_ephemeral_task(context).await;
|
||||
|
||||
if updated {
|
||||
context.emit_event(EventType::MsgsChanged {
|
||||
msg_id: MsgId::new(0),
|
||||
chat_id: ChatId::new(0),
|
||||
})
|
||||
}
|
||||
|
||||
Ok(updated)
|
||||
}
|
||||
|
||||
@@ -444,9 +436,8 @@ pub async fn schedule_ephemeral_task(context: &Context) {
|
||||
};
|
||||
|
||||
// Cancel existing task, if any
|
||||
let old_task = context.ephemeral_task.write().await.take();
|
||||
if let Some((_, stop_sender)) = old_task {
|
||||
stop_sender.try_send(()).ok();
|
||||
if let Some(ephemeral_task) = context.ephemeral_task.write().await.take() {
|
||||
ephemeral_task.cancel().await;
|
||||
}
|
||||
|
||||
if let Some(ephemeral_timestamp) = ephemeral_timestamp {
|
||||
@@ -455,27 +446,27 @@ pub async fn schedule_ephemeral_task(context: &Context) {
|
||||
+ Duration::from_secs(ephemeral_timestamp.try_into().unwrap_or(u64::MAX))
|
||||
+ Duration::from_secs(1);
|
||||
|
||||
let (stop_sender, stop_receiver) = channel::bounded(1);
|
||||
|
||||
let context1 = context.clone();
|
||||
let ephemeral_task = task::spawn(async move {
|
||||
if let Some((join_handle, _)) = old_task {
|
||||
join_handle.await; // First of all, join the old task.
|
||||
}
|
||||
if let Ok(duration) = until.duration_since(now) {
|
||||
timeout(duration, stop_receiver.recv()).await;
|
||||
} else {
|
||||
stop_receiver.try_recv();
|
||||
}
|
||||
delete_expired_messages(&context).await.ok_or_log(&context);
|
||||
});
|
||||
// Schedule a task, ephemeral_timestamp is in the future
|
||||
*context.ephemeral_task.write().await = Some((ephemeral_task, stop_sender));
|
||||
if let Ok(duration) = until.duration_since(now) {
|
||||
// Schedule a task, ephemeral_timestamp is in the future
|
||||
let context1 = context.clone();
|
||||
let ephemeral_task = task::spawn(async move {
|
||||
async_std::task::sleep(duration).await;
|
||||
context1.emit_event(EventType::MsgsChanged {
|
||||
chat_id: ChatId::new(0),
|
||||
msg_id: MsgId::new(0),
|
||||
});
|
||||
});
|
||||
*context.ephemeral_task.write().await = Some(ephemeral_task);
|
||||
} else {
|
||||
// Emit event immediately
|
||||
context.emit_event(EventType::MsgsChanged {
|
||||
chat_id: ChatId::new(0),
|
||||
msg_id: MsgId::new(0),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn ephemeral_deletion_loop(context: &Context) -> Result {}
|
||||
|
||||
/// Schedules expired IMAP messages for deletion.
|
||||
pub(crate) async fn delete_expired_imap_messages(context: &Context) -> Result<()> {
|
||||
let now = time();
|
||||
@@ -554,7 +545,7 @@ mod tests {
|
||||
let context = TestContext::new().await;
|
||||
|
||||
assert_eq!(
|
||||
stock_ephemeral_timer_changed(&context, Timer::Disabled, ContactId::SELF).await,
|
||||
stock_ephemeral_timer_changed(&context, Timer::Disabled, DC_CONTACT_ID_SELF).await,
|
||||
"Message deletion timer is disabled by me."
|
||||
);
|
||||
|
||||
@@ -562,7 +553,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 1 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1 s by me."
|
||||
@@ -571,7 +562,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 30 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 30 s by me."
|
||||
@@ -580,7 +571,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 60 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1 minute by me."
|
||||
@@ -589,7 +580,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 90 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1.5 minutes by me."
|
||||
@@ -598,7 +589,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 30 * 60 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 30 minutes by me."
|
||||
@@ -607,7 +598,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 60 * 60 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1 hour by me."
|
||||
@@ -616,7 +607,7 @@ mod tests {
|
||||
stock_ephemeral_timer_changed(
|
||||
&context,
|
||||
Timer::Enabled { duration: 5400 },
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1.5 hours by me."
|
||||
@@ -627,7 +618,7 @@ mod tests {
|
||||
Timer::Enabled {
|
||||
duration: 2 * 60 * 60
|
||||
},
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 2 hours by me."
|
||||
@@ -638,7 +629,7 @@ mod tests {
|
||||
Timer::Enabled {
|
||||
duration: 24 * 60 * 60
|
||||
},
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1 day by me."
|
||||
@@ -649,7 +640,7 @@ mod tests {
|
||||
Timer::Enabled {
|
||||
duration: 2 * 24 * 60 * 60
|
||||
},
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 2 days by me."
|
||||
@@ -660,7 +651,7 @@ mod tests {
|
||||
Timer::Enabled {
|
||||
duration: 7 * 24 * 60 * 60
|
||||
},
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 1 week by me."
|
||||
@@ -671,7 +662,7 @@ mod tests {
|
||||
Timer::Enabled {
|
||||
duration: 4 * 7 * 24 * 60 * 60
|
||||
},
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
)
|
||||
.await,
|
||||
"Message deletion timer is set to 4 weeks by me."
|
||||
@@ -855,7 +846,6 @@ mod tests {
|
||||
}
|
||||
|
||||
async fn check_msg_was_deleted(t: &TestContext, chat: &Chat, msg_id: MsgId) {
|
||||
// trigger deletion?
|
||||
let chat_items = chat::get_chat_msgs(t, chat.id, 0, None).await.unwrap();
|
||||
// Check that the chat is empty except for possibly info messages:
|
||||
for item in &chat_items {
|
||||
@@ -867,8 +857,8 @@ mod tests {
|
||||
|
||||
// Check that if there is a message left, the text and metadata are gone
|
||||
if let Ok(msg) = Message::load_from_db(t, msg_id).await {
|
||||
assert_eq!(msg.from_id, ContactId::UNDEFINED);
|
||||
assert_eq!(msg.to_id, ContactId::UNDEFINED);
|
||||
assert_eq!(msg.from_id, ContactId::new(0));
|
||||
assert_eq!(msg.to_id, ContactId::new(0));
|
||||
assert!(msg.text.is_none_or_empty(), "{:?}", msg.text);
|
||||
let rawtxt: Option<String> = t
|
||||
.sql
|
||||
|
||||
10
src/html.rs
10
src/html.rs
@@ -279,7 +279,7 @@ mod tests {
|
||||
use crate::chat;
|
||||
use crate::chat::forward_msgs;
|
||||
use crate::config::Config;
|
||||
use crate::contact::ContactId;
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::message::{MessengerMessage, Viewtype};
|
||||
use crate::test_utils::TestContext;
|
||||
@@ -442,7 +442,7 @@ test some special html-characters as < > and & but also " and &#x
|
||||
let raw = include_bytes!("../test-data/message/text_alt_plain_html.eml");
|
||||
dc_receive_imf(&alice, raw, "INBOX", false).await.unwrap();
|
||||
let msg = alice.get_last_msg_in(chat.get_id()).await;
|
||||
assert_ne!(msg.get_from_id(), ContactId::SELF);
|
||||
assert_ne!(msg.get_from_id(), DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg.is_dc_message, MessengerMessage::No);
|
||||
assert!(!msg.is_forwarded());
|
||||
assert!(msg.get_text().unwrap().contains("this is plain"));
|
||||
@@ -456,7 +456,7 @@ test some special html-characters as < > and & but also " and &#x
|
||||
.await
|
||||
.unwrap();
|
||||
let msg = alice.get_last_msg_in(chat.get_id()).await;
|
||||
assert_eq!(msg.get_from_id(), ContactId::SELF);
|
||||
assert_eq!(msg.get_from_id(), DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg.is_dc_message, MessengerMessage::Yes);
|
||||
assert!(msg.is_forwarded());
|
||||
assert!(msg.get_text().unwrap().contains("this is plain"));
|
||||
@@ -469,7 +469,7 @@ test some special html-characters as < > and & but also " and &#x
|
||||
let chat = bob.create_chat_with_contact("", "alice@example.org").await;
|
||||
bob.recv_msg(&alice.pop_sent_msg().await).await;
|
||||
let msg = bob.get_last_msg_in(chat.get_id()).await;
|
||||
assert_ne!(msg.get_from_id(), ContactId::SELF);
|
||||
assert_ne!(msg.get_from_id(), DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg.is_dc_message, MessengerMessage::Yes);
|
||||
assert!(msg.is_forwarded());
|
||||
assert!(msg.get_text().unwrap().contains("this is plain"));
|
||||
@@ -506,7 +506,7 @@ test some special html-characters as < > and & but also " and &#x
|
||||
alice.recv_msg(&msg).await;
|
||||
let chat = alice.get_self_chat().await;
|
||||
let msg = alice.get_last_msg_in(chat.get_id()).await;
|
||||
assert_eq!(msg.get_from_id(), ContactId::SELF);
|
||||
assert_eq!(msg.get_from_id(), DC_CONTACT_ID_SELF);
|
||||
assert_eq!(msg.is_dc_message, MessengerMessage::Yes);
|
||||
assert!(msg.get_showpadlock());
|
||||
assert!(msg.is_forwarded());
|
||||
|
||||
@@ -20,10 +20,9 @@ use num_traits::FromPrimitive;
|
||||
use crate::chat::{self, ChatId, ChatIdBlocked};
|
||||
use crate::config::Config;
|
||||
use crate::constants::{
|
||||
Blocked, Chattype, ShowEmails, DC_FETCH_EXISTING_MSGS_COUNT, DC_FOLDERS_CONFIGURED_VERSION,
|
||||
DC_LP_AUTH_OAUTH2,
|
||||
Blocked, Chattype, ShowEmails, DC_CONTACT_ID_SELF, DC_FETCH_EXISTING_MSGS_COUNT,
|
||||
DC_FOLDERS_CONFIGURED_VERSION, DC_LP_AUTH_OAUTH2,
|
||||
};
|
||||
use crate::contact::ContactId;
|
||||
use crate::context::Context;
|
||||
use crate::dc_receive_imf::{
|
||||
dc_receive_imf_inner, from_field_to_contact_id, get_prefetch_parent_message, ReceivedMsg,
|
||||
@@ -1640,7 +1639,7 @@ async fn should_move_out_of_spam(
|
||||
if chat_id_blocked.blocked != Blocked::Not {
|
||||
return Ok(false);
|
||||
}
|
||||
} else if from_id != ContactId::SELF {
|
||||
} else if from_id != DC_CONTACT_ID_SELF {
|
||||
// No chat with this contact found.
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use rand::{thread_rng, Rng};
|
||||
use crate::blob::BlobObject;
|
||||
use crate::chat::{self, delete_and_reset_all_device_msgs, ChatId};
|
||||
use crate::config::Config;
|
||||
use crate::contact::ContactId;
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::{
|
||||
dc_create_folder, dc_delete_file, dc_delete_files_in_dir, dc_get_filesuffix_lc,
|
||||
@@ -176,7 +176,7 @@ async fn do_initiate_key_transfer(context: &Context) -> Result<String> {
|
||||
)
|
||||
.await?;
|
||||
|
||||
let chat_id = ChatId::create_for_contact(context, ContactId::SELF).await?;
|
||||
let chat_id = ChatId::create_for_contact(context, DC_CONTACT_ID_SELF).await?;
|
||||
let mut msg = Message {
|
||||
viewtype: Viewtype::File,
|
||||
..Default::default()
|
||||
|
||||
@@ -62,7 +62,7 @@ mod e2ee;
|
||||
pub mod ephemeral;
|
||||
mod imap;
|
||||
pub mod imex;
|
||||
mod scheduler;
|
||||
pub mod scheduler;
|
||||
#[macro_use]
|
||||
mod job;
|
||||
mod format_flowed;
|
||||
|
||||
@@ -7,6 +7,7 @@ use quick_xml::events::{BytesEnd, BytesStart, BytesText};
|
||||
|
||||
use crate::chat::{self, ChatId};
|
||||
use crate::config::Config;
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
use crate::contact::ContactId;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::time;
|
||||
@@ -314,7 +315,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
|
||||
accuracy,
|
||||
time(),
|
||||
chat_id,
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
]
|
||||
).await {
|
||||
warn!(context, "failed to store location {:?}", err);
|
||||
@@ -323,7 +324,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
|
||||
}
|
||||
}
|
||||
if continue_streaming {
|
||||
context.emit_event(EventType::LocationChanged(Some(ContactId::SELF)));
|
||||
context.emit_event(EventType::LocationChanged(Some(DC_CONTACT_ID_SELF)));
|
||||
};
|
||||
schedule_maybe_send_locations(context, false).await.ok();
|
||||
}
|
||||
@@ -462,10 +463,10 @@ pub async fn get_kml(context: &Context, chat_id: ChatId) -> Result<(String, u32)
|
||||
GROUP BY timestamp \
|
||||
ORDER BY timestamp;",
|
||||
paramsv![
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
locations_send_begin,
|
||||
locations_last_sent,
|
||||
ContactId::SELF
|
||||
DC_CONTACT_ID_SELF
|
||||
],
|
||||
|row| {
|
||||
let location_id: i32 = row.get(0)?;
|
||||
@@ -666,7 +667,7 @@ pub(crate) async fn job_maybe_send_locations(context: &Context, _job: &Job) -> j
|
||||
for (chat_id, locations_send_begin, locations_last_sent) in &rows {
|
||||
if !stmt_locations
|
||||
.exists(paramsv![
|
||||
ContactId::SELF,
|
||||
DC_CONTACT_ID_SELF,
|
||||
*locations_send_begin,
|
||||
*locations_last_sent,
|
||||
])
|
||||
|
||||
@@ -10,7 +10,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::chat::{self, Chat, ChatId};
|
||||
use crate::constants::{
|
||||
Blocked, Chattype, VideochatType, DC_CHAT_ID_TRASH, DC_DESIRED_TEXT_LEN, DC_MSG_ID_LAST_SPECIAL,
|
||||
Blocked, Chattype, VideochatType, DC_CHAT_ID_TRASH, DC_CONTACT_ID_INFO, DC_CONTACT_ID_SELF,
|
||||
DC_DESIRED_TEXT_LEN, DC_MSG_ID_LAST_SPECIAL,
|
||||
};
|
||||
use crate::contact::{Contact, ContactId, Origin};
|
||||
use crate::context::Context;
|
||||
@@ -430,7 +431,7 @@ impl Message {
|
||||
/// this is done by dc_set_location() and dc_send_locations_to_chat().
|
||||
///
|
||||
/// Typically results in the event #DC_EVENT_LOCATION_CHANGED with
|
||||
/// contact_id set to ContactId::SELF.
|
||||
/// contact_id set to DC_CONTACT_ID_SELF.
|
||||
///
|
||||
/// @param latitude North-south position of the location.
|
||||
/// @param longitude East-west position of the location.
|
||||
@@ -543,7 +544,7 @@ impl Message {
|
||||
&chat_loaded
|
||||
};
|
||||
|
||||
let contact = if self.from_id != ContactId::SELF {
|
||||
let contact = if self.from_id != DC_CONTACT_ID_SELF {
|
||||
match chat.typ {
|
||||
Chattype::Group | Chattype::Broadcast | Chattype::Mailinglist => {
|
||||
Some(Contact::get_by_id(context, self.from_id).await?)
|
||||
@@ -596,8 +597,8 @@ impl Message {
|
||||
|
||||
pub fn is_info(&self) -> bool {
|
||||
let cmd = self.param.get_cmd();
|
||||
self.from_id == ContactId::INFO
|
||||
|| self.to_id == ContactId::INFO
|
||||
self.from_id == DC_CONTACT_ID_INFO
|
||||
|| self.to_id == DC_CONTACT_ID_INFO
|
||||
|| cmd != SystemMessage::Unknown && cmd != SystemMessage::AutocryptSetupMessage
|
||||
}
|
||||
|
||||
@@ -1016,7 +1017,7 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> Result<String> {
|
||||
ret += &format!(" by {}", name);
|
||||
ret += "\n";
|
||||
|
||||
if msg.from_id != ContactId::SELF {
|
||||
if msg.from_id != DC_CONTACT_ID_SELF {
|
||||
let s = dc_timestamp_to_str(if 0 != msg.timestamp_rcvd {
|
||||
msg.timestamp_rcvd
|
||||
} else {
|
||||
@@ -1037,7 +1038,7 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> Result<String> {
|
||||
);
|
||||
}
|
||||
|
||||
if msg.from_id == ContactId::INFO || msg.to_id == ContactId::INFO {
|
||||
if msg.from_id == DC_CONTACT_ID_INFO || msg.to_id == DC_CONTACT_ID_INFO {
|
||||
// device-internal message, no further details needed
|
||||
return Ok(ret);
|
||||
}
|
||||
@@ -1431,7 +1432,7 @@ pub async fn handle_mdn(
|
||||
rfc724_mid: &str,
|
||||
timestamp_sent: i64,
|
||||
) -> Result<Option<(ChatId, MsgId)>> {
|
||||
if from_id == ContactId::SELF {
|
||||
if from_id == DC_CONTACT_ID_SELF {
|
||||
warn!(
|
||||
context,
|
||||
"ignoring MDN sent to self, this is a bug on the sender device"
|
||||
@@ -1636,7 +1637,7 @@ pub async fn estimate_deletion_cnt(
|
||||
from_server: bool,
|
||||
seconds: i64,
|
||||
) -> Result<usize> {
|
||||
let self_chat_id = ChatId::lookup_by_contact(context, ContactId::SELF)
|
||||
let self_chat_id = ChatId::lookup_by_contact(context, DC_CONTACT_ID_SELF)
|
||||
.await?
|
||||
.unwrap_or_default();
|
||||
let threshold_timestamp = time() - seconds;
|
||||
@@ -1804,6 +1805,7 @@ mod tests {
|
||||
|
||||
use crate::chat::{marknoticed_chat, ChatItem};
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::constants::DC_CONTACT_ID_DEVICE;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::test_utils as test;
|
||||
use crate::test_utils::TestContext;
|
||||
@@ -1943,7 +1945,7 @@ mod tests {
|
||||
// test that get_width() and get_height() are returning some dimensions for images;
|
||||
// (as the device-chat contains a welcome-images, we check that)
|
||||
t.update_device_chats().await.ok();
|
||||
let device_chat_id = ChatId::get_for_contact(&t, ContactId::DEVICE)
|
||||
let device_chat_id = ChatId::get_for_contact(&t, DC_CONTACT_ID_DEVICE)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -711,7 +711,7 @@ mod tests {
|
||||
..
|
||||
} = qr
|
||||
{
|
||||
assert_ne!(contact_id, ContactId::UNDEFINED);
|
||||
assert_ne!(contact_id, ContactId::new(0));
|
||||
assert_eq!(grpname, "test ? test !");
|
||||
} else {
|
||||
bail!("Wrong QR code type");
|
||||
@@ -729,7 +729,7 @@ mod tests {
|
||||
..
|
||||
} = qr
|
||||
{
|
||||
assert_ne!(contact_id, ContactId::UNDEFINED);
|
||||
assert_ne!(contact_id, ContactId::new(0));
|
||||
assert_eq!(grpname, "test ? test !");
|
||||
|
||||
let contact = Contact::get_by_id(&ctx.ctx, contact_id).await?;
|
||||
@@ -751,7 +751,7 @@ mod tests {
|
||||
).await?;
|
||||
|
||||
if let Qr::AskVerifyContact { contact_id, .. } = qr {
|
||||
assert_ne!(contact_id, ContactId::UNDEFINED);
|
||||
assert_ne!(contact_id, ContactId::new(0));
|
||||
} else {
|
||||
bail!("Wrong QR code type");
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ use crate::{
|
||||
chat::{Chat, ChatId},
|
||||
color::color_int_to_hex_string,
|
||||
config::Config,
|
||||
contact::{Contact, ContactId},
|
||||
constants::DC_CONTACT_ID_SELF,
|
||||
contact::Contact,
|
||||
context::Context,
|
||||
securejoin, stock_str,
|
||||
};
|
||||
@@ -40,7 +41,7 @@ async fn generate_join_group_qr_code(context: &Context, chat_id: ChatId) -> Resu
|
||||
}
|
||||
|
||||
async fn generate_verification_qr(context: &Context) -> Result<String> {
|
||||
let contact = Contact::get_by_id(context, ContactId::SELF).await?;
|
||||
let contact = Contact::get_by_id(context, DC_CONTACT_ID_SELF).await?;
|
||||
|
||||
let avatar = match contact.get_profile_image(context).await? {
|
||||
Some(path) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::smtp::{send_smtp_messages, Smtp};
|
||||
|
||||
use self::connectivity::ConnectivityStore;
|
||||
|
||||
pub(crate) mod connectivity;
|
||||
pub mod connectivity;
|
||||
|
||||
pub(crate) struct StopToken;
|
||||
|
||||
@@ -305,7 +305,6 @@ async fn smtp_loop(ctx: Context, started: Sender<()>, smtp_handlers: SmtpConnect
|
||||
.expect("smtp loop, missing started receiver");
|
||||
let ctx = ctx1;
|
||||
|
||||
let mut timeout = None;
|
||||
let mut interrupt_info = Default::default();
|
||||
loop {
|
||||
let job = match job::load_next(&ctx, Thread::Smtp, &interrupt_info).await {
|
||||
@@ -323,16 +322,9 @@ async fn smtp_loop(ctx: Context, started: Sender<()>, smtp_handlers: SmtpConnect
|
||||
interrupt_info = Default::default();
|
||||
}
|
||||
None => {
|
||||
let res = send_smtp_messages(&ctx, &mut connection).await;
|
||||
if let Err(err) = &res {
|
||||
if let Err(err) = send_smtp_messages(&ctx, &mut connection).await {
|
||||
warn!(ctx, "send_smtp_messages failed: {:#}", err);
|
||||
}
|
||||
let success = res.unwrap_or(false);
|
||||
timeout = if success {
|
||||
None
|
||||
} else {
|
||||
Some(timeout.map_or(30, |timeout: u64| timeout.saturating_mul(3)))
|
||||
};
|
||||
|
||||
// Fake Idle
|
||||
info!(ctx, "smtp fake idle - started");
|
||||
@@ -341,27 +333,7 @@ async fn smtp_loop(ctx: Context, started: Sender<()>, smtp_handlers: SmtpConnect
|
||||
Some(err) => connection.connectivity.set_err(&ctx, err).await,
|
||||
}
|
||||
|
||||
// If send_smtp_messages() failed, we set a timeout for the fake-idle so that
|
||||
// sending is retried (at the latest) after the timeout. If sending fails
|
||||
// again, we increase the timeout exponentially, in order not to do lots of
|
||||
// unnecessary retries.
|
||||
if let Some(timeout) = timeout {
|
||||
info!(
|
||||
ctx,
|
||||
"smtp has messages to retry, planning to retry {} seconds later",
|
||||
timeout
|
||||
);
|
||||
let duration = std::time::Duration::from_secs(timeout);
|
||||
interrupt_info = async_std::future::timeout(duration, async {
|
||||
idle_interrupt_receiver.recv().await.unwrap_or_default()
|
||||
})
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
} else {
|
||||
info!(ctx, "smtp has no messages to retry, waiting for interrupt");
|
||||
interrupt_info = idle_interrupt_receiver.recv().await.unwrap_or_default();
|
||||
};
|
||||
|
||||
interrupt_info = idle_interrupt_receiver.recv().await.unwrap_or_default();
|
||||
info!(ctx, "smtp fake idle - interrupted")
|
||||
}
|
||||
}
|
||||
@@ -398,10 +370,9 @@ impl Scheduler {
|
||||
|
||||
let inbox_handle = {
|
||||
let ctx = ctx.clone();
|
||||
Some(
|
||||
task::spawn(async move { inbox_loop(ctx, inbox_start_send, inbox_handlers).await })
|
||||
.cancel(),
|
||||
)
|
||||
Some(task::spawn(async move {
|
||||
inbox_loop(ctx, inbox_start_send, inbox_handlers).await
|
||||
}))
|
||||
};
|
||||
|
||||
if ctx.should_watch_mvbox().await? {
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::{context::Context, log::LogExt};
|
||||
use anyhow::{anyhow, Result};
|
||||
use humansize::{file_size_opts, FileSize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumProperty, PartialOrd, Ord)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Connectivity {
|
||||
NotConnected = 1000,
|
||||
Connecting = 2000,
|
||||
@@ -27,7 +27,7 @@ pub enum Connectivity {
|
||||
// the top) take priority. This means that e.g. if any folder has an error - usually
|
||||
// because there is no internet connection - the connectivity for the whole
|
||||
// account will be `Notconnected`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, EnumProperty, PartialOrd)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
|
||||
enum DetailedConnectivity {
|
||||
Error(String),
|
||||
Uninitialized,
|
||||
|
||||
@@ -8,7 +8,7 @@ use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
|
||||
use crate::aheader::EncryptPreference;
|
||||
use crate::chat::{self, Chat, ChatId, ChatIdBlocked};
|
||||
use crate::config::Config;
|
||||
use crate::constants::Blocked;
|
||||
use crate::constants::{Blocked, DC_CONTACT_ID_LAST_SPECIAL};
|
||||
use crate::contact::{Contact, ContactId, Origin, VerifiedStatus};
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::time;
|
||||
@@ -310,7 +310,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
||||
mime_message: &MimeMessage,
|
||||
contact_id: ContactId,
|
||||
) -> Result<HandshakeMessage> {
|
||||
if contact_id.is_special() {
|
||||
if contact_id <= DC_CONTACT_ID_LAST_SPECIAL {
|
||||
return Err(Error::msg("Can not be called with special contact ID"));
|
||||
}
|
||||
let step = mime_message
|
||||
@@ -573,7 +573,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
||||
mime_message: &MimeMessage,
|
||||
contact_id: ContactId,
|
||||
) -> Result<HandshakeMessage> {
|
||||
if contact_id.is_special() {
|
||||
if contact_id <= DC_CONTACT_ID_LAST_SPECIAL {
|
||||
return Err(Error::msg("Can not be called with special contact ID"));
|
||||
}
|
||||
let step = mime_message
|
||||
|
||||
11
src/smtp.rs
11
src/smtp.rs
@@ -483,9 +483,10 @@ pub(crate) async fn send_msg_to_smtp(
|
||||
///
|
||||
/// Logs and ignores SMTP errors to ensure that a single SMTP message constantly failing to be sent
|
||||
/// does not block other messages in the queue from being sent.
|
||||
///
|
||||
/// Returns true if all messages were sent successfully, false otherwise.
|
||||
pub(crate) async fn send_smtp_messages(context: &Context, connection: &mut Smtp) -> Result<bool> {
|
||||
pub(crate) async fn send_smtp_messages(
|
||||
context: &Context,
|
||||
connection: &mut Smtp,
|
||||
) -> anyhow::Result<()> {
|
||||
context.send_sync_msg().await?; // Add sync message to the end of the queue if needed.
|
||||
let rowids = context
|
||||
.sql
|
||||
@@ -503,12 +504,10 @@ pub(crate) async fn send_smtp_messages(context: &Context, connection: &mut Smtp)
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
let mut success = true;
|
||||
for rowid in rowids {
|
||||
if let Err(err) = send_msg_to_smtp(context, connection, rowid).await {
|
||||
info!(context, "Failed to send message over SMTP: {:#}.", err);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
Ok(success)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use strum_macros::EnumProperty;
|
||||
use crate::blob::BlobObject;
|
||||
use crate::chat::{self, Chat, ChatId, ProtectionStatus};
|
||||
use crate::config::Config;
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
use crate::contact::{Contact, ContactId, Origin};
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::dc_timestamp_to_str;
|
||||
@@ -396,7 +397,7 @@ trait StockStringMods: AsRef<str> + Sized {
|
||||
Box::pin(async move {
|
||||
let message = self.as_ref().trim_end_matches('.');
|
||||
match contact_id {
|
||||
ContactId::SELF => msg_action_by_me(context, message).await,
|
||||
DC_CONTACT_ID_SELF => msg_action_by_me(context, message).await,
|
||||
_ => {
|
||||
let displayname = Contact::get_by_id(context, contact_id)
|
||||
.await
|
||||
@@ -1128,7 +1129,7 @@ impl Context {
|
||||
self.sql
|
||||
.set_raw_config_bool("self-chat-added", true)
|
||||
.await?;
|
||||
ChatId::create_for_contact(self, ContactId::SELF).await?;
|
||||
ChatId::create_for_contact(self, DC_CONTACT_ID_SELF).await?;
|
||||
}
|
||||
|
||||
// add welcome-messages. by the label, this is done only once,
|
||||
@@ -1148,13 +1149,14 @@ impl Context {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use num_traits::ToPrimitive;
|
||||
use super::*;
|
||||
use crate::test_utils::TestContext;
|
||||
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
|
||||
use crate::chat::Chat;
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::test_utils::TestContext;
|
||||
|
||||
use super::*;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
#[test]
|
||||
fn test_enum_mapping() {
|
||||
@@ -1231,7 +1233,7 @@ mod tests {
|
||||
async fn test_stock_system_msg_add_member_by_me() {
|
||||
let t = TestContext::new().await;
|
||||
assert_eq!(
|
||||
msg_add_member(&t, "alice@example.org", ContactId::SELF).await,
|
||||
msg_add_member(&t, "alice@example.org", DC_CONTACT_ID_SELF).await,
|
||||
"Member alice@example.org added by me."
|
||||
)
|
||||
}
|
||||
@@ -1243,7 +1245,7 @@ mod tests {
|
||||
.await
|
||||
.expect("failed to create contact");
|
||||
assert_eq!(
|
||||
msg_add_member(&t, "alice@example.org", ContactId::SELF).await,
|
||||
msg_add_member(&t, "alice@example.org", DC_CONTACT_ID_SELF).await,
|
||||
"Member Alice (alice@example.org) added by me."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! # Message summary for chatlist.
|
||||
|
||||
use crate::chat::Chat;
|
||||
use crate::constants::Chattype;
|
||||
use crate::contact::{Contact, ContactId};
|
||||
use crate::constants::{Chattype, DC_CONTACT_ID_SELF};
|
||||
use crate::contact::Contact;
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::dc_truncate;
|
||||
use crate::message::{Message, MessageState, Viewtype};
|
||||
@@ -60,7 +60,7 @@ impl Summary {
|
||||
) -> Self {
|
||||
let prefix = if msg.state == MessageState::OutDraft {
|
||||
Some(SummaryPrefix::Draft(stock_str::draft(context).await))
|
||||
} else if msg.from_id == ContactId::SELF {
|
||||
} else if msg.from_id == DC_CONTACT_ID_SELF {
|
||||
if msg.is_info() || chat.is_self_talk() {
|
||||
None
|
||||
} else {
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
use crate::chat::{Chat, ChatId};
|
||||
use crate::config::Config;
|
||||
use crate::constants::Blocked;
|
||||
use crate::contact::ContactId;
|
||||
use crate::constants::{Blocked, DC_CONTACT_ID_SELF};
|
||||
use crate::context::Context;
|
||||
use crate::dc_tools::time;
|
||||
use crate::message::{Message, MsgId, Viewtype};
|
||||
@@ -127,7 +126,7 @@ impl Context {
|
||||
pub async fn send_sync_msg(&self) -> Result<Option<MsgId>> {
|
||||
if let Some((json, ids)) = self.build_sync_json().await? {
|
||||
let chat_id =
|
||||
ChatId::create_for_contact_with_blocked(self, ContactId::SELF, Blocked::Yes)
|
||||
ChatId::create_for_contact_with_blocked(self, DC_CONTACT_ID_SELF, Blocked::Yes)
|
||||
.await?;
|
||||
let mut msg = Message {
|
||||
chat_id,
|
||||
@@ -484,7 +483,7 @@ mod tests {
|
||||
// check that the used self-talk is not visible to the user
|
||||
// but that creation will still work (in this case, the chat is empty)
|
||||
assert_eq!(Chatlist::try_load(&alice, 0, None, None).await?.len(), 0);
|
||||
let chat_id = ChatId::create_for_contact(&alice, ContactId::SELF).await?;
|
||||
let chat_id = ChatId::create_for_contact(&alice, DC_CONTACT_ID_SELF).await?;
|
||||
let chat = Chat::load_from_db(&alice, chat_id).await?;
|
||||
assert!(chat.is_self_talk());
|
||||
assert_eq!(Chatlist::try_load(&alice, 0, None, None).await?.len(), 1);
|
||||
|
||||
@@ -22,8 +22,8 @@ use crate::chat::{self, Chat, ChatId};
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::config::Config;
|
||||
use crate::constants::Chattype;
|
||||
use crate::constants::{DC_MSG_ID_DAYMARKER, DC_MSG_ID_MARKER1};
|
||||
use crate::contact::{Contact, ContactId, Modifier, Origin};
|
||||
use crate::constants::{DC_CONTACT_ID_SELF, DC_MSG_ID_DAYMARKER, DC_MSG_ID_MARKER1};
|
||||
use crate::contact::{Contact, Modifier, Origin};
|
||||
use crate::context::Context;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::dc_tools::EmailAddress;
|
||||
@@ -466,7 +466,7 @@ impl TestContext {
|
||||
|
||||
/// Retrieves the "self" chat.
|
||||
pub async fn get_self_chat(&self) -> Chat {
|
||||
let chat_id = ChatId::create_for_contact(self, ContactId::SELF)
|
||||
let chat_id = ChatId::create_for_contact(self, DC_CONTACT_ID_SELF)
|
||||
.await
|
||||
.unwrap();
|
||||
Chat::load_from_db(self, chat_id).await.unwrap()
|
||||
@@ -851,7 +851,7 @@ async fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: &Message) {
|
||||
&contact_name,
|
||||
contact_id,
|
||||
msgtext.unwrap_or_default(),
|
||||
if msg.get_from_id() == ContactId::SELF {
|
||||
if msg.get_from_id() == DC_CONTACT_ID_SELF {
|
||||
""
|
||||
} else if msg.get_state() == MessageState::InSeen {
|
||||
"[SEEN]"
|
||||
|
||||
Reference in New Issue
Block a user