Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
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 bindings/matrix-sdk-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ release = true
crate-type = ["cdylib", "staticlib"]

[features]
default = ["bundled-sqlite"]
default = ["bundled-sqlite", "matrix-sdk-ui/unstable-msc4274"]
bundled-sqlite = ["matrix-sdk/bundled-sqlite"]

[dependencies]
Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk-ui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ All notable changes to this project will be documented in this file.
([#5055](https://github.com/matrix-org/matrix-rust-sdk/pull/5055))
- `Timeline::mark_as_read()` unsets the unread flag of the room if it was set.
([#5055](https://github.com/matrix-org/matrix-rust-sdk/pull/5055))
- Add new method `Timeline::send_gallery` to allow sending MSC4274-style
galleries.
([#5125](https://github.com/matrix-org/matrix-rust-sdk/pull/5125))

## [0.11.0] - 2025-04-11

Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ uniffi = ["dep:uniffi", "matrix-sdk/uniffi", "matrix-sdk-base/uniffi"]
# Add support for encrypted extensible events.
unstable-msc3956 = ["ruma/unstable-msc3956"]

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

[dependencies]
as_variant.workspace = true
async-rx.workspace = true
Expand Down
26 changes: 14 additions & 12 deletions crates/matrix-sdk-ui/src/timeline/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,21 @@ pub fn default_event_filter(event: &AnySyncTimelineEvent, room_version: &RoomVer
return false;
}

matches!(
content.msgtype,
match content.msgtype {
MessageType::Audio(_)
| MessageType::Emote(_)
| MessageType::File(_)
| MessageType::Image(_)
| MessageType::Location(_)
| MessageType::Notice(_)
| MessageType::ServerNotice(_)
| MessageType::Text(_)
| MessageType::Video(_)
| MessageType::VerificationRequest(_)
)
| MessageType::Emote(_)
| MessageType::File(_)
| MessageType::Image(_)
| MessageType::Location(_)
| MessageType::Notice(_)
| MessageType::ServerNotice(_)
| MessageType::Text(_)
| MessageType::Video(_)
| MessageType::VerificationRequest(_) => true,
#[cfg(feature = "unstable-msc4274")]
MessageType::Gallery(_) => false,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this should be true, so as to display galleries by default. Wouldn't this make the test you've added fail, since it'd filter out the gallery event from rendering into an item? Maybe that's why CI's failing now.

Copy link
Copy Markdown
Contributor Author

@Johennes Johennes Jun 2, 2025

Choose a reason for hiding this comment

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

Oh, right! 🤦‍♂️

Have switched it around. It didn't seem to affect the test, however, which is mildly concerning. 🤔

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The test is likely not running; investigating.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hah:

  • CI didn't run the test because the feature flag isn't ever enabled for the UI crate. I think we could decide that we support galleries by default in the timeline, so we could get rid of it now. Alternatively, we could enable the feature just a bit ahead of time in the FFI layer Cargo.toml, so that it's enabled workspace-wide, and included in testing. I think the latter would be great, since the FFI layer likely will want it anyways.
  • @stefanceriu and I noticed a bug that local echoes never get filtered out based on content, and this is what's happening here, since the current is sending a gallery. Can you add, in this test or another one, a gallery message received via sync from another user, so we can make sure that the filtering actually works? (and temporarily revert the patch that switched this from false to true, to make sure it does filter? no need to add a specific test for the filtering)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh! 🤯

Ok, I hope I got all of this right. The test now does fail for me also locally (with the erroneous false). When I switch back to true, it succeeds.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does it? Looks like it's the sending of the media gallery that fails, not the filtering out…

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh, you're right. 🤦‍♂️ Ok, will have to look into what's going on there now. 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looks like the media config requests need mocking after merging in main. Added those and switched back to false so the CI should now fail timing out waiting for the sent gallery.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, it seems to be failing as intended now: no item is pushed, while we expected one 🥳 Good job making the test meaningful and winning over CI!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Lets hope it actually turns green now. 😅🤞

_ => false,
}
}

AnyMessageLikeEventContent::Sticker(_)
Expand Down
22 changes: 11 additions & 11 deletions crates/matrix-sdk-ui/src/timeline/event_item/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,17 +362,17 @@ impl EventTimelineItem {

match self.content() {
TimelineItemContent::MsgLike(msglike) => match &msglike.kind {
MsgLikeKind::Message(message) => {
matches!(
message.msgtype(),
MessageType::Text(_)
| MessageType::Emote(_)
| MessageType::Audio(_)
| MessageType::File(_)
| MessageType::Image(_)
| MessageType::Video(_)
)
}
MsgLikeKind::Message(message) => match message.msgtype() {
MessageType::Text(_)
| MessageType::Emote(_)
| MessageType::Audio(_)
| MessageType::File(_)
| MessageType::Image(_)
| MessageType::Video(_) => true,
#[cfg(feature = "unstable-msc4274")]
MessageType::Gallery(_) => true,
_ => false,
},
MsgLikeKind::Poll(poll) => {
poll.response_data.is_empty() && poll.end_event_timestamp.is_none()
}
Expand Down
45 changes: 45 additions & 0 deletions crates/matrix-sdk-ui/src/timeline/futures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,48 @@ impl<'a> IntoFuture for SendAttachment<'a> {
Box::pin(fut.instrument(tracing_span))
}
}

#[cfg(feature = "unstable-msc4274")]
Comment thread
Johennes marked this conversation as resolved.
pub use galleries::*;

#[cfg(feature = "unstable-msc4274")]
mod galleries {
use std::future::IntoFuture;

use matrix_sdk::attachment::GalleryConfig;
use matrix_sdk_base::boxed_into_future;
use tracing::{Instrument as _, Span};

use super::{Error, Timeline};

pub struct SendGallery<'a> {
timeline: &'a Timeline,
gallery: GalleryConfig,
tracing_span: Span,
}

impl<'a> SendGallery<'a> {
pub(crate) fn new(timeline: &'a Timeline, gallery: GalleryConfig) -> Self {
Self { timeline, gallery, tracing_span: Span::current() }
}
}

impl<'a> IntoFuture for SendGallery<'a> {
type Output = Result<(), Error>;
boxed_into_future!(extra_bounds: 'a);

fn into_future(self) -> Self::IntoFuture {
let Self { timeline, gallery, tracing_span } = self;

let fut = async move {
let send_queue = timeline.room().send_queue();
let fut = send_queue.send_gallery(gallery);
fut.await.map_err(|_| Error::FailedSendingAttachment)?;

Ok(())
};

Box::pin(fut.instrument(tracing_span))
}
}
}
26 changes: 26 additions & 0 deletions crates/matrix-sdk-ui/src/timeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ use std::{fs, path::PathBuf, sync::Arc};
use algorithms::rfind_event_by_item_id;
use event_item::TimelineItemHandle;
use eyeball_im::VectorDiff;
#[cfg(feature = "unstable-msc4274")]
use futures::SendGallery;
use futures_core::Stream;
use imbl::Vector;
#[cfg(feature = "unstable-msc4274")]
use matrix_sdk::attachment::GalleryConfig;
use matrix_sdk::{
attachment::AttachmentConfig,
deserialized_responses::TimelineEvent,
Expand Down Expand Up @@ -416,6 +420,28 @@ impl Timeline {
SendAttachment::new(self, source.into(), mime_type, config)
}

/// Sends a media gallery to the room.
///
/// If the encryption feature is enabled, this method will transparently
/// encrypt the room message if the room is encrypted.
///
/// The attachments and their optional thumbnails are stored in the media
/// cache and can be retrieved at any time, by calling
/// [`Media::get_media_content()`] with the `MediaSource` that can be found
/// in the corresponding `TimelineEventItem`, and using a
/// `MediaFormat::File`.
///
/// # Arguments
/// * `gallery` - A configuration object containing details about the
/// gallery like files, thumbnails, etc.
///
/// [`Media::get_media_content()`]: matrix_sdk::Media::get_media_content
#[cfg(feature = "unstable-msc4274")]
#[instrument(skip_all)]
pub fn send_gallery(&self, gallery: GalleryConfig) -> SendGallery<'_> {
SendGallery::new(self, gallery)
}

/// Redact an event given its [`TimelineEventItemId`] and an optional
/// reason.
pub async fn redact(
Expand Down
Loading