It doesn't make sense to set a thread identifier for the receipt of the latest event: the event might not belong to that thread, and the SDK would need to check that,
since the latest event isn't reachable from the outside world (the reason why `mark_as_read` had been introduced). So let's remove it for now, and
add comments related to threaded receipts.
This slightly changes the API when interacting from the FFI layer:
- instead of `mark_as_unread` and `mark_as_read`, there's now a single method `set_unread_flag(bool)`, which callers may call with true (i.e. unread) or false (i.e. not unread).
- there's a new method `mark_as_read` which sends a read receipt to the latest event in the timeline, using other commits from the same PR,
- forcing a room as read requires calling first `set_unread_flag(false)` then `mark_as_read()`
It's wrong that the first client, used only to determine how to log in and find the user id, try to run the encryption initialization tasks.
In particular, it should not even try to bootstrap the account, as this may send OTKs to the server, which the client will forget about as soon
as it's respawned as a database-backed client.
I have also changed the priorities so that manual updates are preferred.
This means that duplicate updates do not happen if the room was previously unknown.
Signed-off-by: Timo Kösters <timo@koesters.xyz>
Vectors grow in powers of two while reading, which is doubly wasteful:
* causes every byte to be copied in average once
* leaves the vector in average 25% larger than it needs to be, wasting memory.
For example, adding this test to
`crates/matrix-sdk-crypto/src/file_encryption/attachments.rs`:
```
fn encrypt_decrypt_minimize_memory() {
let data = std::iter::repeat("abcdefg").take(10000).collect::<String>();
let mut cursor = Cursor::new(data.clone());
let mut encryptor = AttachmentEncryptor::new(&mut cursor);
let mut encrypted = Vec::new();
encryptor.read_to_end(&mut encrypted).unwrap();
let key = encryptor.finish();
assert_ne!(encrypted.as_slice(), data.as_bytes());
let mut cursor = Cursor::new(encrypted);
let mut decryptor = AttachmentDecryptor::new(&mut cursor, key).unwrap();
let mut decrypted_data = Vec::new();
decryptor.read_to_end(&mut decrypted_data).unwrap();
assert_eq!(
decrypted_data.len(),
decrypted_data.capacity(),
"{} bytes wasted by decrypted_data",
decrypted_data.capacity() - decrypted_data.len()
);
}
```
errors with:
```
assertion `left == right` failed: 61072 bytes wasted by decrypted_data
left: 70000
right: 131072
```
By initially setting this capacity, the vector should be slightly larger
than needed from the start, avoiding both copying and leftover capacity
after decryption is done.
`matrix_sdk_ui::timeline::Message::msgtype` returns `&MessageType`,
and variants of `MessageType` implement `MediaEventContent`, so it is
allowing references here avoids cloning message content.