Skip to content

Conversation

@Simon-Laux
Copy link
Contributor

@Simon-Laux Simon-Laux commented Nov 12, 2025

This PR implements receiving of pre-message, download of post-messages and the new logic for deciding what to fetch when from IMAP.

This is part of #7367


progress:

  • changes to imap loop
  • change download table to work with rfc724_mid instead of msg_id (added db migration for it)
  • add a table for available_post_msgs
  • move download logic from scheduler.rs to download.rs
  • receive_imf
    • implement pre message
    • implement post message (if pre message exists then replace only attachment and change view type)
  • Metadata in pre-message in header as struct (atleast attachment size, so UI can ask for correct size to display on dl button)
  • delete metadata params once message is downloaded
  • write tests (recycle old tests that I removed in remove: partial downloads (remove creation of the stub messages) #7373 and write new ones) - progress in feat: receive pre-messages and adapt download on demand #7431 (comment)
  • add metadata text to pre-messages and an option to disable that behaviour
  • handle forwarding pre-message bugfixing branch #7560
  • handle save message (saving to saved messages chat) draft: start with saving pre-message to self messages and test. #7561
  • bug: fix auto download
  • bug: available_post_msgs gets no entries
  • rename to pre-message, post-message and normal message
  • make sure multi device works and post message is not deleted by first device that downloaded it (maybe we need a local trashing if this is a problem?)
  • test: make sure message deletion deletes both messages, regardless of what order they arrived in
  • use HidePreMessageMetadataText in tests or remove the note that it is used in tests from it's docs removed the config option
code quality / nitpicking
  • use tcm.section("..."); instead of comments in tests
  • check which log statements are important and remove the non relevant ones.

specific aspects that should become reality:

  • In receive_imf, the post-message can be handled similarly to Chat-Edit (grep for "ChatEdit" in receive_imf.rs).
  • As opposed to the current download-on-demand, we won't replace the whole msgs row, because this way, it will just work if an edit-message is received, and then later the user requests to download the attachment.
    • Need to change Viewtype, probably metadata params like image size
  • pre-message gets Viewtype::Text in the database until downloaded
  • background_fetch should not download messages with the Chat-Is-Post-Message header.
  • background_fetch: If a large message without Chat-Is-Post-Message header. is received, the UI should be notified via an event. postponed
  • A read receipt should be shown already when the user saw the pre-message. feat: pre messages can now get read receipts #7433

Later (not in this pr, not now)

  • metadata: thumbnails (image, no video thumbnail because it may be too hard)
  • metadata: webxdc name
  • faq/inApp: mention/explain somewhere that the download limit is now only about large attachments sent via chatmail/deltachat which trigger the pre-message/post-message split
  • write specs (used headers, the format of metadata header and the principles behind how this feature works)

API Changes:

  • all: change Message.get_filebytes - if message is not downloaded pre message, and metadata is available, then it returns the size that the file has after download, so ui can use this to show download size
  • duration and dimensions (width, heigth) are already set in pre-messages (if they contain that metadata)

@Simon-Laux Simon-Laux force-pushed the simon/sending-pre-message branch 3 times, most recently from 2b900c3 to 305498d Compare November 16, 2025 20:07
@Simon-Laux Simon-Laux force-pushed the simon/receive-pre-messages branch 4 times, most recently from b94964a to ce97ba3 Compare November 23, 2025 02:27
@Simon-Laux Simon-Laux force-pushed the simon/receive-pre-messages branch from cd716c5 to 4c14566 Compare November 26, 2025 14:13
Base automatically changed from simon/sending-pre-message to pre-messages November 26, 2025 14:14
@Simon-Laux Simon-Laux force-pushed the simon/receive-pre-messages branch from 4c14566 to ca6bf65 Compare November 26, 2025 15:09
@Hocuri
Copy link
Collaborator

Hocuri commented Dec 1, 2025

background_fetch: If a large message without Chat-Is-Full-Message header. is received, the UI should be notified via an event.

  • rust: add Message.get_full_message_viewtype to get view type that message will have after being downloaded.

  • jsonrpc: add full_message_view_type to Message and MessageInfo

In the first iteration, it's not necessary to emit an event, or add any new API. (not sure how the event landed in the "steps" at #7367, but it already is in the "Future Possibilities")

@Simon-Laux Simon-Laux marked this pull request as ready for review December 1, 2025 15:46

chat::mark_old_messages_as_noticed(context, received_msgs).await?;

// TODO: is there correct place for this?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

address to do comment

.context("delete_expired_imap_messages")?;

//-------
// TODO: verify that this is the correct position for this call
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • address todo comment

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guarding against lost pre-messages is optional, so, wouldn't actually be required for this first iteration of pre-messages. It's there now, but if this requires any further thought, we should just leave away.

From a logical standpoint, I would put it to the end of fetch_move_delete(), but it should be fine here, too (without me deeply thinking into this).

Copy link
Contributor Author

@Simon-Laux Simon-Laux Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I put it here so it does only run on normal fetch and not on background fetch, because those post messages could be huge.

EDIT: I will think about it again, I'm a bit confused again.

@Simon-Laux
Copy link
Contributor Author

Simon-Laux commented Dec 1, 2025

Progress of the tests

Overview about the recycled(♻️) and dropped(🗑️) tests of the tests that I removed in #7373

All the recycled tests were already recycled/re-made except for some which are still to do:

  • test_partial_group_consistency
  • test_msg_seen_on_imap_when_downloaded
  • test_download_limit_chat_assignment

Furthermore there need to be new tests to test the downloading/scheduling changes.


TODO Tests

  • sending pre-message, post-message
  • metadata in pre-message
  • process receiving
  • display attachment info in pre-message
  • test scheduler imap fetching
  • test failing download sets state to failed
  • test_download_limit_chat_assignment
  • multi device tests
  • deletion tests

postponed to do tests

  • rust: test_msg_seen_on_imap_when_downloaded (I guess this is for syncing seen state between devices)
  • rust: test_partial_group_consistency

discarded/ignored test ideas

maybe we should reconsider / discuss those?

  • test that full message, replacing pre-message does not work if the message encryption state is not the same for both messages (both full- and pre-message)
    • unencrypted pre- and full-message are not sent

@Simon-Laux Simon-Laux force-pushed the simon/receive-pre-messages branch from 778dae2 to 2a3d5a3 Compare December 3, 2025 16:40
"Message is a Pre-Message (post_msg_exists:{post_msg_exists})."
);
post_msg_exists
// TODO find out if trashing affects multi device usage?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • address todo comment

@link2xt link2xt force-pushed the simon/receive-pre-messages branch 2 times, most recently from b7fb4cb to b6dc11a Compare December 9, 2025 14:20
fix python lint errors

receive pre-mesages, start with changes to imap loop.

refactor: move download code from `scheduler.rs` to `download.rs`, also
move `get_msg_id_by_rfc724_mid` to `MsgId::get_by_rfc724_mid`

`MAX_FETCH_MSG_SIZE` is no longer unused

Parse if it is a pre-message or full-message

start with receiving logic

get rid of `MsgId::get_by_rfc724_mid` because it was a duplicate of
`message::rfc724_mid_exists`

docs: add hint to `MimeMessage::from_bytes` stating that it has
side-effects.

receiving full message

send and receive `attachment_size` and set viewtype to text in
pre_message

metadata as struct in pre-message in header. And fill params that we can
already fill from the metadata. Also add a new api to check what
viewtype the message will have once downloaded.

api: jsonrpc: add `full_message_view_type` to `Message` and
`MessageInfo`

make PreMsgMetadata.to_header_value not consume self/PreMsgMetadata

add api to merge params

on download full message: merge new params into old params and remove
full-message metadata params

move tests to `src/tests/pre_messages.rs`

dynamically allocate test attachment bytes

fix detection of pre-messages. (it looked for the ChatFullMessageId
header in the unencrypted headers before)

fix setting dl state to avaiable on pre-messages

fix: save pre message with rfc724_mid of full message als disable
replacement for full messages

add some receiving tests and update test todo for premessage metadata

test: process full message before pre-message

test receive normal message

some serialization tests for PreMsgMetadata

remove outdated todo comment

test that pre-message contains message text

PreMsgMetadata: test_build_from_file_msg and test_build_from_file_msg

test: test_receive_pre_message_image

Test receiving the full message after receiving an edit after receiving
the pre-message

test_reaction_on_pre_message

test_full_download_after_trashed

test_webxdc_update_for_not_downloaded_instance

simplify fake webxdc generation in
test_webxdc_update_for_not_downloaded_instance

test_markseen_pre_msg

test_pre_msg_can_start_chat and test_full_msg_can_start_chat

test_download_later_keeps_message_order

test_chatlist_event_on_full_msg_download

fix download not working

log splitting into pre-message

add pre-message info to text when loading from db. this can be disabled
with config key `hide_pre_message_metadata_text` if ui wants to display
it in a prettier way.

update `download_limit` documentation

more logging: log size of pre and post messages

rename full message to Post-Message

split up the pre-message tests into multiple files

dedup test code by extracting code to create test messages into util
methods

remove post_message_view_type from api, now it is only used internally
for tests

remove `hide_pre_message_metadata_text` config option, as there
currently is no way to get the full message viewtype anymore

Update src/download.rs
resolve comment

use `parse_message_id` instead of removing `<>`parenthesis it manually

fix available_post_msgs gets no entries
handle forwarding and add a test for it.

convert comment to log warning event on unexpected download failure

add doc comment to `simple_imap_loop`

more logging

handle saving pre-message to self messages and test.
@link2xt link2xt force-pushed the simon/receive-pre-messages branch from b6dc11a to bfc58e9 Compare December 9, 2025 14:29
Immediately fully download all messages that do not have the
`Chat-Is-Post-Message` header. This way, we simplify the logic for when
which messages are downloaded, there are no differences at all anymore
between 'background_fetch' and 'normal fetch'.

Also, we prevent message reordering when reveiving a message from a
legacy client.

Messages larger than 1MB without `Chat-Is-Post-Message` should be rare,
so, we do not expect this to really worsen things.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants