Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0c3161b
feat(send_queue): Implement sending of MSC4274 galleries
Johennes Apr 25, 2025
d749ebe
Merge branch 'main' into johannes/msc4274-step2
Johennes May 23, 2025
9a62767
Use an OwnedTransactionId to avoid cloning
Johennes May 23, 2025
58626d2
Add missing trailing periods in comments
Johennes May 23, 2025
932dbf9
Move client and cache store outside of loop
Johennes May 23, 2025
c6731ca
Prevent sending empty galleries
Johennes May 23, 2025
47fe934
Remove superfluous type annotations
Johennes May 23, 2025
49c9576
Pre-allocate capacity for item vectors
Johennes May 23, 2025
421f5bd
Extract macro for MessageType / GalleryItemType
Johennes May 23, 2025
b5f4828
Remove superfluous self
Johennes May 23, 2025
7149b73
Rename make_message_event to make_media_event
Johennes May 23, 2025
0e58e50
Bundle items with GalleryConfig
Johennes May 23, 2025
fc4aa7e
Avoid type annotation and pre-allocate vector
Johennes May 23, 2025
e47706e
Avoid unnecessary type annotation
Johennes May 23, 2025
4028bb4
Use let / else to reduce indentation
Johennes May 23, 2025
3acc0e8
Relocate and rephrase comment for FinishGalleryItemInfo
Johennes May 23, 2025
7e7a38c
Extract shared function to update cache keys
Johennes May 23, 2025
aaa392c
Extract method to push thumbnail & media requests
Johennes May 26, 2025
26601a4
Move pushing the dependent media request out of the if / else
Johennes May 26, 2025
b5b6723
Avoid unwrapping last_upload_file_txn
Johennes May 26, 2025
9a491b6
Extract method for caching
Johennes May 26, 2025
6b2b3f0
Merge branch 'main' into johannes/msc4274-step2
Johennes May 26, 2025
946e05a
Rename config parameter to gallery
Johennes May 27, 2025
662d6c7
Remove superfluous blank line
Johennes May 27, 2025
f235e56
Reduce indentation by returning early
Johennes May 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/matrix-sdk-base/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ mod send_queue;
#[cfg(any(test, feature = "testing"))]
pub use self::integration_tests::StateStoreIntegrationTests;
#[cfg(feature = "unstable-msc4274")]
pub use self::send_queue::AccumulatedSentMediaInfo;
pub use self::send_queue::{AccumulatedSentMediaInfo, FinishGalleryItemInfo};
pub use self::{
memory_store::MemoryStore,
send_queue::{
Expand Down
37 changes: 37 additions & 0 deletions crates/matrix-sdk-base/src/store/send_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,19 @@ pub enum DependentQueuedRequestKind {
/// Information about the thumbnail, if present.
thumbnail_info: Option<FinishUploadThumbnailInfo>,
},

/// Finish a gallery upload by updating references to the media cache and
/// sending the final gallery event with the remote MXC URIs.
#[cfg(feature = "unstable-msc4274")]
FinishGallery {
/// Local echo for the event (containing the local MXC URIs).
///
/// `Box` the local echo so that it reduces the size of the whole enum.
local_echo: Box<RoomMessageEventContent>,

/// Metadata about the gallery items.
item_infos: Vec<FinishGalleryItemInfo>,
},
}

/// If parent_is_thumbnail_upload is missing, we assume the request is for a
Expand Down Expand Up @@ -285,6 +298,18 @@ pub struct FinishUploadThumbnailInfo {
pub height: Option<UInt>,
}

/// Detailed record about a file and thumbnail. When finishing a gallery
/// upload, one [`FinishGalleryItemInfo`] will be used for each media in the
/// gallery.
#[cfg(feature = "unstable-msc4274")]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FinishGalleryItemInfo {
/// Transaction id for the file upload.
pub file_upload: OwnedTransactionId,
/// Information about the thumbnail, if present.
pub thumbnail_info: Option<FinishUploadThumbnailInfo>,
}

/// A transaction id identifying a [`DependentQueuedRequest`] rather than its
/// parent [`QueuedRequest`].
///
Expand Down Expand Up @@ -369,6 +394,13 @@ pub struct AccumulatedSentMediaInfo {
pub thumbnail: Option<MediaSource>,
}

#[cfg(feature = "unstable-msc4274")]
impl From<AccumulatedSentMediaInfo> for SentMediaInfo {
fn from(value: AccumulatedSentMediaInfo) -> Self {
Self { file: value.file, thumbnail: value.thumbnail, accumulated: vec![] }
}
}

/// A unique key (identifier) indicating that a transaction has been
/// successfully sent to the server.
///
Expand Down Expand Up @@ -442,6 +474,11 @@ impl DependentQueuedRequest {
// This one graduates into a new media event.
true
}
#[cfg(feature = "unstable-msc4274")]
DependentQueuedRequestKind::FinishGallery { .. } => {
// This one graduates into a new gallery event.
true
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ All notable changes to this project will be documented in this file.
flag of the room if an unthreaded read receipt is sent.
([#5055](https://github.com/matrix-org/matrix-rust-sdk/pull/5055))
- `Client::is_user_ignored(&UserId)` can be used to check if a user is currently ignored. ([#5081](https://github.com/matrix-org/matrix-rust-sdk/pull/5081))
- `RoomSendQueue::send_gallery` has been added to allow sending MSC4274-style media galleries
via the send queue under the `unstable-msc4274` feature.
([#4977](https://github.com/matrix-org/matrix-rust-sdk/pull/4977))

### Bug fixes

Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ docsrs = ["e2e-encryption", "sqlite", "indexeddb", "sso-login", "qrcode"]
experimental-share-history-on-invite = []

# Add support for inline media galleries via msgtypes
unstable-msc4274 = ["matrix-sdk-base/unstable-msc4274"]
unstable-msc4274 = ["ruma/unstable-msc4274", "matrix-sdk-base/unstable-msc4274"]

[dependencies]
anyhow = { workspace = true, optional = true }
Expand Down
132 changes: 123 additions & 9 deletions crates/matrix-sdk/src/attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use ruma::{
},
Mentions,
},
OwnedTransactionId, TransactionId, UInt,
OwnedTransactionId, UInt,
};

use crate::room::reply::Reply;
Expand Down Expand Up @@ -219,8 +219,8 @@ impl AttachmentConfig {
/// in its unsigned field as `transaction_id`. If not given, one is
/// created for the message.
#[must_use]
pub fn txn_id(mut self, txn_id: &TransactionId) -> Self {
self.txn_id = Some(txn_id.to_owned());
pub fn txn_id(mut self, txn_id: OwnedTransactionId) -> Self {
self.txn_id = Some(txn_id);
self
}

Expand All @@ -236,21 +236,21 @@ impl AttachmentConfig {
self
}

/// Set the optional caption
/// Set the optional caption.
///
/// # Arguments
///
/// * `caption` - The optional caption
/// * `caption` - The optional caption.
pub fn caption(mut self, caption: Option<String>) -> Self {
self.caption = caption;
self
}

/// Set the optional formatted caption
/// Set the optional formatted caption.
///
/// # Arguments
///
/// * `formatted_caption` - The optional formatted caption
/// * `formatted_caption` - The optional formatted caption.
pub fn formatted_caption(mut self, formatted_caption: Option<FormattedBody>) -> Self {
self.formatted_caption = formatted_caption;
self
Expand All @@ -260,7 +260,7 @@ impl AttachmentConfig {
///
/// # Arguments
///
/// * `mentions` - The mentions of the message
/// * `mentions` - The mentions of the message.
pub fn mentions(mut self, mentions: Option<Mentions>) -> Self {
self.mentions = mentions;
self
Expand All @@ -270,9 +270,123 @@ impl AttachmentConfig {
///
/// # Arguments
///
/// * `reply` - The reply information of the message
/// * `reply` - The reply information of the message.
pub fn reply(mut self, reply: Option<Reply>) -> Self {
self.reply = reply;
self
}
}

/// Configuration for sending a gallery.
#[cfg(feature = "unstable-msc4274")]
#[derive(Debug, Default)]
pub struct GalleryConfig {
pub(crate) txn_id: Option<OwnedTransactionId>,
pub(crate) items: Vec<GalleryItemInfo>,
pub(crate) caption: Option<String>,
pub(crate) formatted_caption: Option<FormattedBody>,
pub(crate) mentions: Option<Mentions>,
pub(crate) reply: Option<Reply>,
}

#[cfg(feature = "unstable-msc4274")]
impl GalleryConfig {
/// Create a new empty `GalleryConfig`.
pub fn new() -> Self {
Self::default()
}

/// Set the transaction ID to send.
///
/// # Arguments
///
/// * `txn_id` - A unique ID that can be attached to a `MessageEvent` held
/// in its unsigned field as `transaction_id`. If not given, one is
/// created for the message.
#[must_use]
pub fn txn_id(mut self, txn_id: OwnedTransactionId) -> Self {
self.txn_id = Some(txn_id);
self
}

/// Adds a media item to the gallery.
///
/// # Arguments
///
/// * `item` - Information about the item to be added.
#[must_use]
pub fn add_item(mut self, item: GalleryItemInfo) -> Self {
self.items.push(item);
self
}

/// Set the optional caption.
///
/// # Arguments
///
/// * `caption` - The optional caption.
pub fn caption(mut self, caption: Option<String>) -> Self {
self.caption = caption;
self
}

/// Set the optional formatted caption.
///
/// # Arguments
///
/// * `formatted_caption` - The optional formatted caption.
pub fn formatted_caption(mut self, formatted_caption: Option<FormattedBody>) -> Self {
self.formatted_caption = formatted_caption;
self
}

/// Set the mentions of the message.
///
/// # Arguments
///
/// * `mentions` - The mentions of the message.
pub fn mentions(mut self, mentions: Option<Mentions>) -> Self {
self.mentions = mentions;
self
}

/// Set the reply information of the message.
///
/// # Arguments
///
/// * `reply` - The reply information of the message.
pub fn reply(mut self, reply: Option<Reply>) -> Self {
self.reply = reply;
self
}

/// Returns the number of media items in the gallery.
pub fn len(&self) -> usize {
self.items.len()
}

/// Checks whether the gallery contains any media items or not.
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
}

#[cfg(feature = "unstable-msc4274")]
#[derive(Debug)]
/// Metadata for a gallery item
pub struct GalleryItemInfo {
/// The filename.
pub filename: String,
/// The mime type.
pub content_type: mime::Mime,
/// The binary data.
pub data: Vec<u8>,
/// The attachment info.
pub attachment_info: AttachmentInfo,
/// The caption.
pub caption: Option<String>,
/// The formatted caption.
pub formatted_caption: Option<FormattedBody>,
/// The thumbnail.
pub thumbnail: Option<Thumbnail>,
}
6 changes: 6 additions & 0 deletions crates/matrix-sdk/src/room/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ pub(crate) fn update_media_caption(
event.formatted = formatted_caption;
true
}
#[cfg(feature = "unstable-msc4274")]
MessageType::Gallery(event) => {
event.body = caption.unwrap_or_default();
event.formatted = formatted_caption;
true
}
MessageType::Image(event) => {
set_caption!(event, caption);
event.formatted = formatted_caption;
Expand Down
Loading
Loading