mirror of
https://github.com/chatmail/core.git
synced 2026-05-10 18:36:29 +03:00
Compare commits
11 Commits
link2xt/up
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fb2f27831 | ||
|
|
58a09df49a | ||
|
|
ca70fb9b3a | ||
|
|
045b586569 | ||
|
|
18e1ecbb94 | ||
|
|
6fdee2b92d | ||
|
|
9ebd4769f5 | ||
|
|
741d1beed8 | ||
|
|
ac8b2d2fca | ||
|
|
d75c05e717 | ||
|
|
35ceb51ffc |
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -41,6 +41,8 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
- name: Cache rust cargo artifacts
|
- name: Cache rust cargo artifacts
|
||||||
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
||||||
|
with:
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
- name: Run rustfmt
|
- name: Run rustfmt
|
||||||
run: cargo fmt --all -- --check
|
run: cargo fmt --all -- --check
|
||||||
- name: Run clippy
|
- name: Run clippy
|
||||||
@@ -92,6 +94,8 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Cache rust cargo artifacts
|
- name: Cache rust cargo artifacts
|
||||||
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
||||||
|
with:
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
- name: Rustdoc
|
- name: Rustdoc
|
||||||
run: cargo doc --document-private-items --no-deps
|
run: cargo doc --document-private-items --no-deps
|
||||||
|
|
||||||
@@ -135,6 +139,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Cache rust cargo artifacts
|
- name: Cache rust cargo artifacts
|
||||||
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
||||||
|
with:
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
- name: Install nextest
|
- name: Install nextest
|
||||||
uses: taiki-e/install-action@5f57d6cb7cd20b14a8a27f522884c4bc8a187458
|
uses: taiki-e/install-action@5f57d6cb7cd20b14a8a27f522884c4bc8a187458
|
||||||
@@ -169,6 +175,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Cache rust cargo artifacts
|
- name: Cache rust cargo artifacts
|
||||||
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
||||||
|
with:
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
- name: Build C library
|
- name: Build C library
|
||||||
run: cargo build -p deltachat_ffi
|
run: cargo build -p deltachat_ffi
|
||||||
@@ -195,6 +203,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Cache rust cargo artifacts
|
- name: Cache rust cargo artifacts
|
||||||
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
|
||||||
|
with:
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
- name: Build deltachat-rpc-server
|
- name: Build deltachat-rpc-server
|
||||||
run: cargo build -p deltachat-rpc-server
|
run: cargo build -p deltachat-rpc-server
|
||||||
|
|||||||
23
Cargo.lock
generated
23
Cargo.lock
generated
@@ -934,9 +934,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorutils-rs"
|
name = "colorutils-rs"
|
||||||
version = "0.7.6"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e2fc25857fa523662de5cae84225b0e7bfb24a2a3f9ed8802fecf03df7252b1"
|
checksum = "69abc9a8ed011e2b7946769f460b9e76e8b659ece9ef4001b9d8bba3489f796d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"erydanos",
|
"erydanos",
|
||||||
"half",
|
"half",
|
||||||
@@ -1301,9 +1301,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.10.0"
|
version = "2.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
|
checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dbl"
|
name = "dbl"
|
||||||
@@ -2662,7 +2662,7 @@ dependencies = [
|
|||||||
"hyper",
|
"hyper",
|
||||||
"libc",
|
"libc",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2 0.5.9",
|
"socket2 0.6.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
@@ -3268,9 +3268,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.184"
|
version = "0.2.186"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
@@ -3941,15 +3941,14 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.78"
|
version = "0.10.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222"
|
checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.11.0",
|
"bitflags 2.11.0",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
|
||||||
"openssl-macros",
|
"openssl-macros",
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
]
|
]
|
||||||
@@ -3982,9 +3981,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.114"
|
version = "0.9.115"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6"
|
checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ blake3 = "1.8.2"
|
|||||||
brotli = { version = "8", default-features=false, features = ["std"] }
|
brotli = { version = "8", default-features=false, features = ["std"] }
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
chrono = { workspace = true, features = ["alloc", "clock", "std"] }
|
chrono = { workspace = true, features = ["alloc", "clock", "std"] }
|
||||||
colorutils-rs = { version = "0.7.5", default-features = false }
|
colorutils-rs = { version = "0.8.0", default-features = false }
|
||||||
data-encoding = "2.9.0"
|
data-encoding = "2.9.0"
|
||||||
escaper = "0.1"
|
escaper = "0.1"
|
||||||
fast-socks5 = "1"
|
fast-socks5 = "1"
|
||||||
|
|||||||
@@ -4003,8 +4003,6 @@ int dc_msg_get_viewtype (const dc_msg_t* msg);
|
|||||||
* Marked as read on IMAP and MDN may be sent. Use dc_markseen_msgs() to mark messages as being seen.
|
* Marked as read on IMAP and MDN may be sent. Use dc_markseen_msgs() to mark messages as being seen.
|
||||||
*
|
*
|
||||||
* Outgoing message states:
|
* Outgoing message states:
|
||||||
* - @ref DC_STATE_OUT_PREPARING - For files which need time to be prepared before they can be sent,
|
|
||||||
* the message enters this state before @ref DC_STATE_OUT_PENDING. Deprecated.
|
|
||||||
* - @ref DC_STATE_OUT_DRAFT - Message saved as draft using dc_set_draft()
|
* - @ref DC_STATE_OUT_DRAFT - Message saved as draft using dc_set_draft()
|
||||||
* - @ref DC_STATE_OUT_PENDING - The user has pressed the "send" button but the
|
* - @ref DC_STATE_OUT_PENDING - The user has pressed the "send" button but the
|
||||||
* message is not yet sent and is pending in some way. Maybe we're offline (no checkmark).
|
* message is not yet sent and is pending in some way. Maybe we're offline (no checkmark).
|
||||||
@@ -5589,13 +5587,6 @@ int64_t dc_lot_get_timestamp (const dc_lot_t* lot);
|
|||||||
*/
|
*/
|
||||||
#define DC_STATE_IN_SEEN 16
|
#define DC_STATE_IN_SEEN 16
|
||||||
|
|
||||||
/**
|
|
||||||
* Outgoing message being prepared. See dc_msg_get_state() for details.
|
|
||||||
*
|
|
||||||
* @deprecated 2024-12-07
|
|
||||||
*/
|
|
||||||
#define DC_STATE_OUT_PREPARING 18
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outgoing message drafted. See dc_msg_get_state() for details.
|
* Outgoing message drafted. See dc_msg_get_state() for details.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ pub enum LotState {
|
|||||||
MsgInFresh = 10,
|
MsgInFresh = 10,
|
||||||
MsgInNoticed = 13,
|
MsgInNoticed = 13,
|
||||||
MsgInSeen = 16,
|
MsgInSeen = 16,
|
||||||
MsgOutPreparing = 18,
|
|
||||||
MsgOutDraft = 19,
|
MsgOutDraft = 19,
|
||||||
MsgOutPending = 20,
|
MsgOutPending = 20,
|
||||||
MsgOutFailed = 24,
|
MsgOutFailed = 24,
|
||||||
@@ -246,7 +245,6 @@ impl From<MessageState> for LotState {
|
|||||||
InFresh => LotState::MsgInFresh,
|
InFresh => LotState::MsgInFresh,
|
||||||
InNoticed => LotState::MsgInNoticed,
|
InNoticed => LotState::MsgInNoticed,
|
||||||
InSeen => LotState::MsgInSeen,
|
InSeen => LotState::MsgInSeen,
|
||||||
OutPreparing => LotState::MsgOutPreparing,
|
|
||||||
OutDraft => LotState::MsgOutDraft,
|
OutDraft => LotState::MsgOutDraft,
|
||||||
OutPending => LotState::MsgOutPending,
|
OutPending => LotState::MsgOutPending,
|
||||||
OutFailed => LotState::MsgOutFailed,
|
OutFailed => LotState::MsgOutFailed,
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ class MessageState(IntEnum):
|
|||||||
IN_FRESH = 10
|
IN_FRESH = 10
|
||||||
IN_NOTICED = 13
|
IN_NOTICED = 13
|
||||||
IN_SEEN = 16
|
IN_SEEN = 16
|
||||||
OUT_PREPARING = 18
|
|
||||||
OUT_DRAFT = 19
|
OUT_DRAFT = 19
|
||||||
OUT_PENDING = 20
|
OUT_PENDING = 20
|
||||||
OUT_FAILED = 24
|
OUT_FAILED = 24
|
||||||
|
|||||||
@@ -271,15 +271,6 @@ class Chat:
|
|||||||
sent out. This is the same object as was passed in, which
|
sent out. This is the same object as was passed in, which
|
||||||
has been modified with the new state of the core.
|
has been modified with the new state of the core.
|
||||||
"""
|
"""
|
||||||
if msg.is_out_preparing():
|
|
||||||
assert msg.id != 0
|
|
||||||
# get a fresh copy of dc_msg, the core needs it
|
|
||||||
maybe_msg = Message.from_db(self.account, msg.id)
|
|
||||||
if maybe_msg is not None:
|
|
||||||
msg = maybe_msg
|
|
||||||
else:
|
|
||||||
raise ValueError("message does not exist")
|
|
||||||
|
|
||||||
sent_id = lib.dc_send_msg(self.account._dc_context, self.id, msg._dc_msg)
|
sent_id = lib.dc_send_msg(self.account._dc_context, self.id, msg._dc_msg)
|
||||||
if sent_id == 0:
|
if sent_id == 0:
|
||||||
raise ValueError("message could not be sent")
|
raise ValueError("message could not be sent")
|
||||||
@@ -333,26 +324,6 @@ class Chat:
|
|||||||
raise ValueError("message could not be sent")
|
raise ValueError("message could not be sent")
|
||||||
return Message.from_db(self.account, sent_id)
|
return Message.from_db(self.account, sent_id)
|
||||||
|
|
||||||
def send_prepared(self, message):
|
|
||||||
"""send a previously prepared message.
|
|
||||||
|
|
||||||
:param message: a :class:`Message` instance previously returned by
|
|
||||||
:meth:`prepare_file`.
|
|
||||||
:raises ValueError: if message can not be sent.
|
|
||||||
:returns: a :class:`deltachat.message.Message` instance as sent out.
|
|
||||||
"""
|
|
||||||
assert message.id != 0 and message.is_out_preparing()
|
|
||||||
# get a fresh copy of dc_msg, the core needs it
|
|
||||||
msg = Message.from_db(self.account, message.id)
|
|
||||||
|
|
||||||
# pass 0 as chat-id because core-docs say it's ok when out-preparing
|
|
||||||
sent_id = lib.dc_send_msg(self.account._dc_context, 0, msg._dc_msg)
|
|
||||||
if sent_id == 0:
|
|
||||||
raise ValueError("message could not be sent")
|
|
||||||
assert sent_id == msg.id
|
|
||||||
# modify message in place to avoid bad state for the caller
|
|
||||||
msg._dc_msg = Message.from_db(self.account, sent_id)._dc_msg
|
|
||||||
|
|
||||||
def set_draft(self, message):
|
def set_draft(self, message):
|
||||||
"""set message as draft.
|
"""set message as draft.
|
||||||
|
|
||||||
|
|||||||
@@ -351,17 +351,12 @@ class Message:
|
|||||||
def is_outgoing(self):
|
def is_outgoing(self):
|
||||||
"""Return True if Message is outgoing."""
|
"""Return True if Message is outgoing."""
|
||||||
return lib.dc_msg_get_state(self._dc_msg) in (
|
return lib.dc_msg_get_state(self._dc_msg) in (
|
||||||
const.DC_STATE_OUT_PREPARING,
|
|
||||||
const.DC_STATE_OUT_PENDING,
|
const.DC_STATE_OUT_PENDING,
|
||||||
const.DC_STATE_OUT_FAILED,
|
const.DC_STATE_OUT_FAILED,
|
||||||
const.DC_STATE_OUT_MDN_RCVD,
|
const.DC_STATE_OUT_MDN_RCVD,
|
||||||
const.DC_STATE_OUT_DELIVERED,
|
const.DC_STATE_OUT_DELIVERED,
|
||||||
)
|
)
|
||||||
|
|
||||||
def is_out_preparing(self):
|
|
||||||
"""Return True if Message is outgoing, but its file is being prepared."""
|
|
||||||
return self._msgstate == const.DC_STATE_OUT_PREPARING
|
|
||||||
|
|
||||||
def is_out_pending(self):
|
def is_out_pending(self):
|
||||||
"""Return True if Message is outgoing, but is pending (no single checkmark)."""
|
"""Return True if Message is outgoing, but is pending (no single checkmark)."""
|
||||||
return self._msgstate == const.DC_STATE_OUT_PENDING
|
return self._msgstate == const.DC_STATE_OUT_PENDING
|
||||||
|
|||||||
12
src/chat.rs
12
src/chat.rs
@@ -2613,7 +2613,7 @@ pub async fn send_msg(context: &Context, chat_id: ChatId, msg: &mut Message) ->
|
|||||||
"chat_id cannot be a special chat: {chat_id}"
|
"chat_id cannot be a special chat: {chat_id}"
|
||||||
);
|
);
|
||||||
|
|
||||||
if msg.state != MessageState::Undefined && msg.state != MessageState::OutPreparing {
|
if msg.state != MessageState::Undefined {
|
||||||
msg.param.remove(Param::GuaranteeE2ee);
|
msg.param.remove(Param::GuaranteeE2ee);
|
||||||
msg.param.remove(Param::ForcePlaintext);
|
msg.param.remove(Param::ForcePlaintext);
|
||||||
// create_send_msg_jobs() will update `param` in the db.
|
// create_send_msg_jobs() will update `param` in the db.
|
||||||
@@ -2721,10 +2721,7 @@ async fn prepare_send_msg(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if matches!(
|
if msg.state == MessageState::Undefined
|
||||||
msg.state,
|
|
||||||
MessageState::Undefined | MessageState::OutPreparing
|
|
||||||
)
|
|
||||||
// Legacy SecureJoin "v*-request" messages are unencrypted.
|
// Legacy SecureJoin "v*-request" messages are unencrypted.
|
||||||
&& msg.param.get_cmd() != SystemMessage::SecurejoinMessage
|
&& msg.param.get_cmd() != SystemMessage::SecurejoinMessage
|
||||||
&& chat.is_encrypted(context).await?
|
&& chat.is_encrypted(context).await?
|
||||||
@@ -2937,8 +2934,8 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
|
|||||||
UPDATE msgs SET
|
UPDATE msgs SET
|
||||||
timestamp=(
|
timestamp=(
|
||||||
SELECT MAX(timestamp) FROM msgs INDEXED BY msgs_index7 WHERE
|
SELECT MAX(timestamp) FROM msgs INDEXED BY msgs_index7 WHERE
|
||||||
-- From `InFresh` to `OutMdnRcvd` inclusive except `OutDraft`.
|
-- From `InFresh` to `OutDelivered` inclusive, except `OutDraft`.
|
||||||
state IN(10,13,16,18,20,24,26,28) AND
|
state IN(10,13,16,18,20,24,26) AND
|
||||||
hidden IN(0,1) AND
|
hidden IN(0,1) AND
|
||||||
chat_id=? AND
|
chat_id=? AND
|
||||||
id<=?
|
id<=?
|
||||||
@@ -4539,6 +4536,7 @@ pub async fn forward_msgs_2ctx(
|
|||||||
|
|
||||||
msg.state = MessageState::OutPending;
|
msg.state = MessageState::OutPending;
|
||||||
msg.rfc724_mid = create_outgoing_rfc724_mid();
|
msg.rfc724_mid = create_outgoing_rfc724_mid();
|
||||||
|
msg.pre_rfc724_mid.clear();
|
||||||
msg.timestamp_sort = curr_timestamp;
|
msg.timestamp_sort = curr_timestamp;
|
||||||
chat.prepare_msg_raw(ctx_dst, &mut msg, None).await?;
|
chat.prepare_msg_raw(ctx_dst, &mut msg, None).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -1381,13 +1381,8 @@ pub enum MessageState {
|
|||||||
/// IMAP and MDN may be sent.
|
/// IMAP and MDN may be sent.
|
||||||
InSeen = 16,
|
InSeen = 16,
|
||||||
|
|
||||||
/// For files which need time to be prepared before they can be
|
// Deprecated 2024-12-07. Removed 2026-04.
|
||||||
/// sent, the message enters this state before
|
// OutPreparing = 18,
|
||||||
/// OutPending.
|
|
||||||
///
|
|
||||||
/// Deprecated 2024-12-07.
|
|
||||||
OutPreparing = 18,
|
|
||||||
|
|
||||||
/// Message saved as draft.
|
/// Message saved as draft.
|
||||||
OutDraft = 19,
|
OutDraft = 19,
|
||||||
|
|
||||||
@@ -1420,7 +1415,6 @@ impl std::fmt::Display for MessageState {
|
|||||||
Self::InFresh => "Fresh",
|
Self::InFresh => "Fresh",
|
||||||
Self::InNoticed => "Noticed",
|
Self::InNoticed => "Noticed",
|
||||||
Self::InSeen => "Seen",
|
Self::InSeen => "Seen",
|
||||||
Self::OutPreparing => "Preparing",
|
|
||||||
Self::OutDraft => "Draft",
|
Self::OutDraft => "Draft",
|
||||||
Self::OutPending => "Pending",
|
Self::OutPending => "Pending",
|
||||||
Self::OutFailed => "Failed",
|
Self::OutFailed => "Failed",
|
||||||
@@ -1437,7 +1431,7 @@ impl MessageState {
|
|||||||
use MessageState::*;
|
use MessageState::*;
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
OutPreparing | OutPending | OutDelivered | OutMdnRcvd // OutMdnRcvd can still fail because it could be a group message and only some recipients failed.
|
OutPending | OutDelivered | OutMdnRcvd // OutMdnRcvd can still fail because it could be a group message and only some recipients failed.
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1446,7 +1440,7 @@ impl MessageState {
|
|||||||
use MessageState::*;
|
use MessageState::*;
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
OutPreparing | OutDraft | OutPending | OutFailed | OutDelivered | OutMdnRcvd
|
OutDraft | OutPending | OutFailed | OutDelivered | OutMdnRcvd
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -231,10 +231,7 @@ static DNS_PRELOAD: LazyLock<HashMap<&'static str, Vec<IpAddr>>> = LazyLock::new
|
|||||||
HashMap::from([
|
HashMap::from([
|
||||||
(
|
(
|
||||||
"imap.163.com",
|
"imap.163.com",
|
||||||
vec![
|
vec![IpAddr::V4(Ipv4Addr::new(111, 124, 203, 45))],
|
||||||
IpAddr::V4(Ipv4Addr::new(111, 124, 203, 45)),
|
|
||||||
IpAddr::V4(Ipv4Addr::new(111, 124, 203, 50)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"smtp.163.com",
|
"smtp.163.com",
|
||||||
@@ -425,12 +422,12 @@ static DNS_PRELOAD: LazyLock<HashMap<&'static str, Vec<IpAddr>>> = LazyLock::new
|
|||||||
"nine.testrun.org",
|
"nine.testrun.org",
|
||||||
vec![
|
vec![
|
||||||
IpAddr::V4(Ipv4Addr::new(128, 140, 126, 197)),
|
IpAddr::V4(Ipv4Addr::new(128, 140, 126, 197)),
|
||||||
|
IpAddr::V4(Ipv4Addr::new(116, 202, 233, 236)),
|
||||||
IpAddr::V4(Ipv4Addr::new(216, 144, 228, 100)),
|
IpAddr::V4(Ipv4Addr::new(216, 144, 228, 100)),
|
||||||
IpAddr::V4(Ipv4Addr::new(77, 42, 49, 41)),
|
IpAddr::V6(Ipv6Addr::new(0x2a01, 0x4f8, 0x241, 0x4ce8, 0, 0, 0, 2)),
|
||||||
IpAddr::V6(Ipv6Addr::new(
|
IpAddr::V6(Ipv6Addr::new(
|
||||||
0x2001, 0x41d0, 0x701, 0x1100, 0, 0, 0, 0x8ab1,
|
0x2001, 0x41d0, 0x701, 0x1100, 0, 0, 0, 0x8ab1,
|
||||||
)),
|
)),
|
||||||
IpAddr::V6(Ipv6Addr::new(0x2a01, 0x4f9, 0xfff1, 0x59, 0, 0, 0, 1)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -700,10 +697,6 @@ static DNS_PRELOAD: LazyLock<HashMap<&'static str, Vec<IpAddr>>> = LazyLock::new
|
|||||||
"chatmail.hackea.org",
|
"chatmail.hackea.org",
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(82, 165, 11, 85))],
|
vec![IpAddr::V4(Ipv4Addr::new(82, 165, 11, 85))],
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"chat.adminforge.de",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(94, 130, 17, 142))],
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"chika.aangat.lahat.computer",
|
"chika.aangat.lahat.computer",
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(71, 19, 150, 113))],
|
vec![IpAddr::V4(Ipv4Addr::new(71, 19, 150, 113))],
|
||||||
@@ -745,46 +738,6 @@ static DNS_PRELOAD: LazyLock<HashMap<&'static str, Vec<IpAddr>>> = LazyLock::new
|
|||||||
"danneskjold.de",
|
"danneskjold.de",
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(46, 62, 216, 132))],
|
vec![IpAddr::V4(Ipv4Addr::new(46, 62, 216, 132))],
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"chat.in-the.eu",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(78, 46, 190, 129))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"chat.nuvon.app",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(178, 238, 38, 165))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"nibblehole.com",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(94, 247, 42, 209))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"chat.zashm.org",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(91, 245, 76, 39))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"chat.sus.fr",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(152, 67, 76, 190))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"delta.thelab.uno",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(146, 59, 228, 39))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"chat.vim.wtf",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(116, 203, 206, 170))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"uninterest.ing",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(172, 245, 70, 237))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"sweetfern.net",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(178, 156, 228, 133))],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"delta.disobey.net",
|
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(37, 74, 102, 44))],
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"darkrun.dev",
|
"darkrun.dev",
|
||||||
vec![IpAddr::V4(Ipv4Addr::new(72, 11, 149, 146))],
|
vec![IpAddr::V4(Ipv4Addr::new(72, 11, 149, 146))],
|
||||||
|
|||||||
@@ -66,12 +66,6 @@ impl Context {
|
|||||||
|
|
||||||
/// Updates `quota.recent`, sets `quota.modified` to the current time
|
/// Updates `quota.recent`, sets `quota.modified` to the current time
|
||||||
/// and emits an event to let the UIs update connectivity view.
|
/// and emits an event to let the UIs update connectivity view.
|
||||||
///
|
|
||||||
/// Moreover, once each time quota gets larger than `QUOTA_WARN_THRESHOLD_PERCENTAGE`,
|
|
||||||
/// a device message is added.
|
|
||||||
/// As the message is added only once, the user is not spammed
|
|
||||||
/// in case for some providers the quota is always at ~100%
|
|
||||||
/// and new space is allocated as needed.
|
|
||||||
pub(crate) async fn update_recent_quota(
|
pub(crate) async fn update_recent_quota(
|
||||||
&self,
|
&self,
|
||||||
session: &mut ImapSession,
|
session: &mut ImapSession,
|
||||||
|
|||||||
@@ -806,8 +806,6 @@ UPDATE config SET value=? WHERE keyname='configured_addr' AND value!=?1
|
|||||||
if transport_changed {
|
if transport_changed {
|
||||||
info!(context, "Primary transport changed to {from_addr:?}.");
|
info!(context, "Primary transport changed to {from_addr:?}.");
|
||||||
context.sql.uncache_raw_config("configured_addr").await;
|
context.sql.uncache_raw_config("configured_addr").await;
|
||||||
|
|
||||||
// Regenerate User ID in V4 keys.
|
|
||||||
context.self_public_key.lock().await.take();
|
context.self_public_key.lock().await.take();
|
||||||
|
|
||||||
context.emit_event(EventType::TransportsModified);
|
context.emit_event(EventType::TransportsModified);
|
||||||
|
|||||||
@@ -2373,6 +2373,18 @@ ALTER TABLE contacts ADD COLUMN name_normalized TEXT;
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inc_and_check(&mut migration_version, 152)?;
|
||||||
|
if dbversion < migration_version {
|
||||||
|
sql.execute_migration(
|
||||||
|
"
|
||||||
|
UPDATE msgs SET state=26 WHERE state=28; -- Change OutMdnRcvd to OutDelivered.
|
||||||
|
UPDATE msgs SET state=19 WHERE state=24; -- Change OutPreparing to OutFailed.
|
||||||
|
",
|
||||||
|
migration_version,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
let new_version = sql
|
let new_version = sql
|
||||||
.get_raw_config_int(VERSION_CFG)
|
.get_raw_config_int(VERSION_CFG)
|
||||||
.await?
|
.await?
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
//! Tests about forwarding and saving Pre-Messages
|
//! Tests about forwarding and saving Pre-Messages
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
@@ -8,6 +10,7 @@ use crate::chatlist::get_last_message_for_chat;
|
|||||||
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD};
|
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD};
|
||||||
use crate::message::{Message, Viewtype};
|
use crate::message::{Message, Viewtype};
|
||||||
use crate::test_utils::TestContextManager;
|
use crate::test_utils::TestContextManager;
|
||||||
|
use crate::tests::pre_messages::util::send_large_file_message;
|
||||||
|
|
||||||
/// Test that forwarding Pre-Message should forward additional text to not be empty
|
/// Test that forwarding Pre-Message should forward additional text to not be empty
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
@@ -86,6 +89,43 @@ async fn test_forwarding_pre_message_empty_text() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_receive_both() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
let alice_chat_id = alice.create_group_with_members("", &[bob]).await;
|
||||||
|
|
||||||
|
let (pre_message, post_message, alice_msg_id) =
|
||||||
|
send_large_file_message(alice, alice_chat_id, Viewtype::File, &vec![0u8; 200_000]).await?;
|
||||||
|
|
||||||
|
let msg = bob.recv_msg(&pre_message).await;
|
||||||
|
let _ = bob.recv_msg_trash(&post_message).await;
|
||||||
|
let msg = Message::load_from_db(bob, msg.id).await?;
|
||||||
|
assert_eq!(msg.download_state(), DownloadState::Done);
|
||||||
|
assert_eq!(msg.text, "test".to_owned());
|
||||||
|
|
||||||
|
forward_msgs(alice, &[alice_msg_id], alice_chat_id).await?;
|
||||||
|
let rev_order = false;
|
||||||
|
let msg = bob
|
||||||
|
.recv_msg(
|
||||||
|
&alice
|
||||||
|
.pop_sent_msg_ex(rev_order, Duration::ZERO)
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(msg.download_state(), DownloadState::Available);
|
||||||
|
assert_eq!(msg.is_forwarded(), true);
|
||||||
|
assert_eq!(msg.text, "test".to_owned());
|
||||||
|
let _ = bob.recv_msg_trash(&alice.pop_sent_msg().await).await;
|
||||||
|
let msg = Message::load_from_db(bob, msg.id).await?;
|
||||||
|
assert_eq!(msg.download_state(), DownloadState::Done);
|
||||||
|
assert_eq!(msg.is_forwarded(), true);
|
||||||
|
assert_eq!(msg.text, "test".to_owned());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Test that forwarding Pre-Message should forward additional text to not be empty
|
/// Test that forwarding Pre-Message should forward additional text to not be empty
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_saving_pre_message_empty_text() -> Result<()> {
|
async fn test_saving_pre_message_empty_text() -> Result<()> {
|
||||||
|
|||||||
@@ -791,7 +791,18 @@ pub(crate) async fn sync_transports(
|
|||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.transaction(|transaction| {
|
.transaction(|transaction| {
|
||||||
|
let configured_addr = transaction.query_row(
|
||||||
|
"SELECT value FROM config WHERE keyname='configured_addr'",
|
||||||
|
(),
|
||||||
|
|row| {
|
||||||
|
let addr: String = row.get(0)?;
|
||||||
|
Ok(addr)
|
||||||
|
},
|
||||||
|
)?;
|
||||||
for RemovedTransportData { addr, timestamp } in removed_transports {
|
for RemovedTransportData { addr, timestamp } in removed_transports {
|
||||||
|
if *addr == configured_addr {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
modified |= transaction.execute(
|
modified |= transaction.execute(
|
||||||
"DELETE FROM transports
|
"DELETE FROM transports
|
||||||
WHERE addr=? AND add_timestamp<=?",
|
WHERE addr=? AND add_timestamp<=?",
|
||||||
|
|||||||
@@ -550,7 +550,7 @@ impl Context {
|
|||||||
|
|
||||||
let send_now = !matches!(
|
let send_now = !matches!(
|
||||||
instance.state,
|
instance.state,
|
||||||
MessageState::Undefined | MessageState::OutPreparing | MessageState::OutDraft
|
MessageState::Undefined | MessageState::OutDraft
|
||||||
);
|
);
|
||||||
|
|
||||||
status_update.uid = Some(create_id());
|
status_update.uid = Some(create_id());
|
||||||
|
|||||||
Reference in New Issue
Block a user