mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
feat: Get rid of MessageState::{OutPreparing, OutMdnRcvd} in the db
`OutPreparing` is deprecated since 2024-12-07, replace it with `OutDraft` to let the user review
such messages if any. `OutMdnRcvd` is not used in the db for new messages since
a30c6ae1f7, `OutDelivered` is stored instead.
This commit is contained in:
@@ -4020,8 +4020,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).
|
||||||
@@ -5604,13 +5602,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
|
||||||
|
|||||||
11
src/chat.rs
11
src/chat.rs
@@ -2623,7 +2623,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.
|
||||||
@@ -2731,10 +2731,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?
|
||||||
@@ -2947,8 +2944,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 WHERE
|
SELECT MAX(timestamp) FROM msgs 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=?
|
chat_id=?
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1387,13 +1387,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,
|
||||||
|
|
||||||
@@ -1426,7 +1421,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",
|
||||||
@@ -1443,7 +1437,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.
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1452,7 +1446,7 @@ impl MessageState {
|
|||||||
use MessageState::*;
|
use MessageState::*;
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
OutPreparing | OutDraft | OutPending | OutFailed | OutDelivered | OutMdnRcvd
|
OutDraft | OutPending | OutFailed | OutDelivered | OutMdnRcvd
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2376,6 +2376,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=18; -- Change OutPreparing to OutDraft.
|
||||||
|
",
|
||||||
|
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?
|
||||||
|
|||||||
@@ -544,7 +544,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