deltachat/
constants.rs

1//! # Constants.
2
3#![allow(missing_docs)]
4
5use deltachat_derive::{FromSql, ToSql};
6use percent_encoding::{AsciiSet, NON_ALPHANUMERIC};
7use serde::{Deserialize, Serialize};
8
9use crate::chat::ChatId;
10
11pub static DC_VERSION_STR: &str = env!("CARGO_PKG_VERSION");
12
13/// Set of characters to percent-encode in email addresses and names.
14pub(crate) const NON_ALPHANUMERIC_WITHOUT_DOT: &AsciiSet = &NON_ALPHANUMERIC.remove(b'.');
15
16#[derive(
17    Debug,
18    Default,
19    Display,
20    Clone,
21    Copy,
22    PartialEq,
23    Eq,
24    FromPrimitive,
25    ToPrimitive,
26    FromSql,
27    ToSql,
28    Serialize,
29    Deserialize,
30)]
31#[repr(i8)]
32pub enum Blocked {
33    #[default]
34    Not = 0,
35    Yes = 1,
36    Request = 2,
37}
38
39#[derive(
40    Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql,
41)]
42#[repr(u8)]
43pub enum MediaQuality {
44    #[default] // also change Config.MediaQuality props(default) on changes
45    Balanced = 0,
46    Worse = 1,
47}
48
49pub const DC_HANDSHAKE_CONTINUE_NORMAL_PROCESSING: i32 = 0x01;
50pub const DC_HANDSHAKE_STOP_NORMAL_PROCESSING: i32 = 0x02;
51pub const DC_HANDSHAKE_ADD_DELETE_JOB: i32 = 0x04;
52
53pub(crate) const DC_FROM_HANDSHAKE: i32 = 0x01;
54
55pub const DC_GCL_ARCHIVED_ONLY: usize = 0x01;
56pub const DC_GCL_NO_SPECIALS: usize = 0x02;
57pub const DC_GCL_ADD_ALLDONE_HINT: usize = 0x04;
58pub const DC_GCL_FOR_FORWARDING: usize = 0x08;
59
60pub const DC_GCL_ADD_SELF: u32 = 0x02;
61pub const DC_GCL_ADDRESS: u32 = 0x04;
62
63// unchanged user avatars are resent to the recipients every some days
64pub(crate) const DC_RESEND_USER_AVATAR_DAYS: i64 = 14;
65
66// warn about an outdated app after a given number of days.
67// reference is the release date.
68// as not all system get speedy updates,
69// do not use too small value that will annoy users checking for nonexistent updates.
70// "90 days" has proven to be too short at some point (user were informed but there was no update)
71pub(crate) const DC_OUTDATED_WARNING_DAYS: i64 = 183;
72
73/// messages that should be deleted get this chat_id; the messages are deleted from the working thread later then. This is also needed as rfc724_mid should be preset as long as the message is not deleted on the server (otherwise it is downloaded again)
74pub const DC_CHAT_ID_TRASH: ChatId = ChatId::new(3);
75/// only an indicator in a chatlist
76pub const DC_CHAT_ID_ARCHIVED_LINK: ChatId = ChatId::new(6);
77/// only an indicator in a chatlist
78pub const DC_CHAT_ID_ALLDONE_HINT: ChatId = ChatId::new(7);
79/// larger chat IDs are "real" chats, their messages are "real" messages.
80pub const DC_CHAT_ID_LAST_SPECIAL: ChatId = ChatId::new(9);
81
82/// Chat type.
83#[derive(
84    Debug,
85    Display,
86    Clone,
87    Copy,
88    PartialEq,
89    Eq,
90    PartialOrd,
91    Ord,
92    FromPrimitive,
93    ToPrimitive,
94    FromSql,
95    ToSql,
96    IntoStaticStr,
97    Serialize,
98    Deserialize,
99)]
100#[repr(u32)]
101pub enum Chattype {
102    /// A 1:1 chat, i.e. a normal chat with a single contact.
103    ///
104    /// Created by [`ChatId::create_for_contact`].
105    Single = 100,
106
107    /// Group chat.
108    ///
109    /// Created by [`crate::chat::create_group`].
110    Group = 120,
111
112    /// An (unencrypted) mailing list,
113    /// created by an incoming mailing list email.
114    Mailinglist = 140,
115
116    /// Outgoing broadcast channel, called "Channel" in the UI.
117    ///
118    /// The user can send into this chat,
119    /// and all recipients will receive messages
120    /// in an `InBroadcast`.
121    ///
122    /// Called `broadcast` here rather than `channel`,
123    /// because the word "channel" already appears a lot in the code,
124    /// which would make it hard to grep for it.
125    ///
126    /// Created by [`crate::chat::create_broadcast`].
127    OutBroadcast = 160,
128
129    /// Incoming broadcast channel, called "Channel" in the UI.
130    ///
131    /// This chat is read-only,
132    /// and we do not know who the other recipients are.
133    ///
134    /// This is similar to a `MailingList`,
135    /// with the main difference being that
136    /// `InBroadcast`s are encrypted.
137    ///
138    /// Called `broadcast` here rather than `channel`,
139    /// because the word "channel" already appears a lot in the code,
140    /// which would make it hard to grep for it.
141    InBroadcast = 165,
142}
143
144pub const DC_MSG_ID_DAYMARKER: u32 = 9;
145pub const DC_MSG_ID_LAST_SPECIAL: u32 = 9;
146
147/// String that indicates that something is left out or truncated.
148pub(crate) const DC_ELLIPSIS: &str = "[...]";
149// how many lines desktop can display when fullscreen (fullscreen at zoomlevel 1x)
150// (taken from "subjective" testing what looks ok)
151pub const DC_DESIRED_TEXT_LINES: usize = 38;
152// how many chars desktop can display per line (from "subjective" testing)
153pub const DC_DESIRED_TEXT_LINE_LEN: usize = 100;
154
155/// Message length limit.
156///
157/// To keep bubbles and chat flow usable and to avoid problems with controls using very long texts,
158/// we limit the text length to `DC_DESIRED_TEXT_LEN`.  If the text is longer, the full text can be
159/// retrieved using has_html()/get_html().
160///
161/// Note that for simplicity maximum length is defined as the number of Unicode Scalar Values (Rust
162/// `char`s), not Unicode Grapheme Clusters.
163pub const DC_DESIRED_TEXT_LEN: usize = DC_DESIRED_TEXT_LINE_LEN * DC_DESIRED_TEXT_LINES;
164
165// Flags for configuring IMAP and SMTP servers.
166// These flags are optional
167// and may be set together with the username, password etc.
168// via dc_set_config() using the key "server_flags".
169
170/// Force OAuth2 authorization.
171///
172/// This flag does not skip automatic configuration.
173/// Before calling configure() with DC_LP_AUTH_OAUTH2 set,
174/// the user has to confirm access at the URL returned by dc_get_oauth2_url().
175pub const DC_LP_AUTH_OAUTH2: i32 = 0x2;
176
177/// Force NORMAL authorization, this is the default.
178/// If this flag is set, automatic configuration is skipped.
179pub const DC_LP_AUTH_NORMAL: i32 = 0x4;
180
181/// if none of these flags are set, the default is chosen
182pub const DC_LP_AUTH_FLAGS: i32 = DC_LP_AUTH_OAUTH2 | DC_LP_AUTH_NORMAL;
183
184// max. weight of images to send w/o recoding
185pub const BALANCED_IMAGE_BYTES: usize = 500_000;
186pub const WORSE_IMAGE_BYTES: usize = 130_000;
187
188// max. width/height and bytes of an avatar
189pub(crate) const BALANCED_AVATAR_SIZE: u32 = 512;
190pub(crate) const BALANCED_AVATAR_BYTES: usize = 60_000;
191pub(crate) const WORSE_AVATAR_SIZE: u32 = 256;
192pub(crate) const WORSE_AVATAR_BYTES: usize = 20_000; // this also fits to Outlook servers don't allowing headers larger than 32k.
193
194// max. width/height of images scaled down because of being too huge
195pub const BALANCED_IMAGE_SIZE: u32 = 1280;
196pub const WORSE_IMAGE_SIZE: u32 = 640;
197
198/// Limit for received images size. Bigger images become `Viewtype::File` to avoid excessive memory
199/// usage by UIs.
200pub const MAX_RCVD_IMAGE_PIXELS: u32 = 50_000_000;
201
202// If more recipients are needed in SMTP's `RCPT TO:` header, the recipient list is split into
203// chunks. This does not affect MIME's `To:` header. Can be overwritten by setting
204// `max_smtp_rcpt_to` in the provider db.
205pub(crate) const DEFAULT_MAX_SMTP_RCPT_TO: usize = 50;
206
207/// Same as `DEFAULT_MAX_SMTP_RCPT_TO`, but for chatmail relays.
208pub(crate) const DEFAULT_CHATMAIL_MAX_SMTP_RCPT_TO: usize = 999;
209
210/// How far the last quota check needs to be in the past to be checked by the background function (in seconds).
211pub(crate) const DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT: u64 = 12 * 60 * 60; // 12 hours
212
213/// How far in the future the sender timestamp of a message is allowed to be, in seconds. Also used
214/// in the group membership consistency algo to reject outdated membership changes.
215pub(crate) const TIMESTAMP_SENT_TOLERANCE: i64 = 60;
216
217// To make text edits clearer for Non-Delta-MUA or old Delta Chats, edited text will be prefixed by EDITED_PREFIX.
218// Newer Delta Chats will remove the prefix as needed.
219pub(crate) const EDITED_PREFIX: &str = "✏️";
220
221/// Period between `sql::housekeeping()` runs.
222pub(crate) const HOUSEKEEPING_PERIOD: i64 = 24 * 60 * 60;
223
224pub(crate) const BROADCAST_INCOMPATIBILITY_MSG: &str = r#"The up to now "experimental channels feature" is about to become an officially supported one. By that, privacy will be improved, it will become faster, and less traffic will be consumed.
225
226As we do not guarantee feature-stability for such experiments, this means, that you will need to create the channel again. 
227
228Here is what to do:
229 • Create a new channel
230 • Tap on the channel name
231 • Tap on "QR Invite Code"
232 • Have all recipients scan the QR code, or send them the link
233
234If you have any questions, please send an email to delta@merlinux.eu or ask at https://support.delta.chat/."#;
235
236/// How many recent messages should be re-sent to a new broadcast member.
237pub(crate) const N_MSGS_TO_NEW_BROADCAST_MEMBER: usize = 10;
238
239#[cfg(test)]
240mod tests {
241    use num_traits::FromPrimitive;
242
243    use super::*;
244
245    #[test]
246    fn test_chattype_values() {
247        // values may be written to disk and must not change
248        assert_eq!(Chattype::Single, Chattype::from_i32(100).unwrap());
249        assert_eq!(Chattype::Group, Chattype::from_i32(120).unwrap());
250        assert_eq!(Chattype::Mailinglist, Chattype::from_i32(140).unwrap());
251        assert_eq!(Chattype::OutBroadcast, Chattype::from_i32(160).unwrap());
252    }
253
254    #[test]
255    fn test_blocked_values() {
256        // values may be written to disk and must not change
257        assert_eq!(Blocked::Not, Blocked::default());
258        assert_eq!(Blocked::Not, Blocked::from_i32(0).unwrap());
259        assert_eq!(Blocked::Yes, Blocked::from_i32(1).unwrap());
260        assert_eq!(Blocked::Request, Blocked::from_i32(2).unwrap());
261    }
262
263    #[test]
264    fn test_mediaquality_values() {
265        // values may be written to disk and must not change
266        assert_eq!(MediaQuality::Balanced, MediaQuality::default());
267        assert_eq!(MediaQuality::Balanced, MediaQuality::from_i32(0).unwrap());
268        assert_eq!(MediaQuality::Worse, MediaQuality::from_i32(1).unwrap());
269    }
270}