From 46a5f0ca1fadcd4707d185e527049aedd4e743cb Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sat, 30 Dec 2023 09:18:56 +0100 Subject: [PATCH 01/17] ffi: Expose filename and formatted body fields for media captions In relevance to MSC2530 --- bindings/matrix-sdk-ffi/src/ruma.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/ruma.rs b/bindings/matrix-sdk-ffi/src/ruma.rs index cc0e317e860..fc85768e3f9 100644 --- a/bindings/matrix-sdk-ffi/src/ruma.rs +++ b/bindings/matrix-sdk-ffi/src/ruma.rs @@ -174,18 +174,25 @@ impl TryFrom for RumaMessageType { } MessageType::Image { content } => Self::Image( RumaImageMessageEventContent::new(content.body, (*content.source).clone()) + .formatted(content.formatted.map(Into::into)) + .filename(content.filename) .info(content.info.map(Into::into).map(Box::new)), ), MessageType::Audio { content } => Self::Audio( RumaAudioMessageEventContent::new(content.body, (*content.source).clone()) + .formatted(content.formatted.map(Into::into)) + .filename(content.filename) .info(content.info.map(Into::into).map(Box::new)), ), MessageType::Video { content } => Self::Video( RumaVideoMessageEventContent::new(content.body, (*content.source).clone()) + .formatted(content.formatted.map(Into::into)) + .filename(content.filename) .info(content.info.map(Into::into).map(Box::new)), ), MessageType::File { content } => Self::File( RumaFileMessageEventContent::new(content.body, (*content.source).clone()) + .formatted(content.formatted.map(Into::into)) .filename(content.filename) .info(content.info.map(Into::into).map(Box::new)), ), @@ -221,6 +228,8 @@ impl From for MessageType { RumaMessageType::Image(c) => MessageType::Image { content: ImageMessageContent { body: c.body.clone(), + formatted: c.formatted.as_ref().map(Into::into), + filename: c.filename.clone(), source: Arc::new(c.source.clone()), info: c.info.as_deref().map(Into::into), }, @@ -228,6 +237,8 @@ impl From for MessageType { RumaMessageType::Audio(c) => MessageType::Audio { content: AudioMessageContent { body: c.body.clone(), + formatted: c.formatted.as_ref().map(Into::into), + filename: c.filename.clone(), source: Arc::new(c.source.clone()), info: c.info.as_deref().map(Into::into), audio: c.audio.map(Into::into), @@ -237,6 +248,8 @@ impl From for MessageType { RumaMessageType::Video(c) => MessageType::Video { content: VideoMessageContent { body: c.body.clone(), + formatted: c.formatted.as_ref().map(Into::into), + filename: c.filename.clone(), source: Arc::new(c.source.clone()), info: c.info.as_deref().map(Into::into), }, @@ -244,6 +257,7 @@ impl From for MessageType { RumaMessageType::File(c) => MessageType::File { content: FileMessageContent { body: c.body.clone(), + formatted: c.formatted.as_ref().map(Into::into), filename: c.filename.clone(), source: Arc::new(c.source.clone()), info: c.info.as_deref().map(Into::into), @@ -295,6 +309,8 @@ pub struct EmoteMessageContent { #[derive(Clone, uniffi::Record)] pub struct ImageMessageContent { pub body: String, + pub formatted: Option, + pub filename: Option, pub source: Arc, pub info: Option, } @@ -302,6 +318,8 @@ pub struct ImageMessageContent { #[derive(Clone, uniffi::Record)] pub struct AudioMessageContent { pub body: String, + pub formatted: Option, + pub filename: Option, pub source: Arc, pub info: Option, pub audio: Option, @@ -311,6 +329,8 @@ pub struct AudioMessageContent { #[derive(Clone, uniffi::Record)] pub struct VideoMessageContent { pub body: String, + pub formatted: Option, + pub filename: Option, pub source: Arc, pub info: Option, } @@ -318,6 +338,7 @@ pub struct VideoMessageContent { #[derive(Clone, uniffi::Record)] pub struct FileMessageContent { pub body: String, + pub formatted: Option, pub filename: Option, pub source: Arc, pub info: Option, From ed39ed5b90526ea613674e5fc4926927dd6ddae1 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sat, 16 Mar 2024 21:00:11 +0100 Subject: [PATCH 02/17] MSC2530: added the ability to send media with captions Signed-off-by: Marco Antonio Alvarez --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 46 ++++--- crates/matrix-sdk-ui/src/timeline/futures.rs | 16 ++- crates/matrix-sdk-ui/src/timeline/mod.rs | 77 ++++++----- crates/matrix-sdk/src/encryption/mod.rs | 103 +++++++------- crates/matrix-sdk/src/media.rs | 57 +++++--- crates/matrix-sdk/src/room/futures.rs | 42 +++--- crates/matrix-sdk/src/room/mod.rs | 137 +++++++++++-------- 7 files changed, 279 insertions(+), 199 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index a118b290ba7..63fb8abc7c0 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::HashMap, fmt::Write as _, fs, sync::Arc}; - use anyhow::{Context, Result}; use as_variant::as_variant; use eyeball_im::VectorDiff; @@ -25,7 +23,9 @@ use matrix_sdk::attachment::{ use matrix_sdk_ui::timeline::{BackPaginationStatus, EventItemOrigin, Profile, TimelineDetails}; use mime::Mime; use ruma::{ + EventId, events::{ + AnyMessageLikeEventContent, location::{AssetType as RumaAssetType, LocationContent, ZoomLevel}, poll::{ unstable_end::UnstablePollEndEventContent, @@ -38,13 +38,13 @@ use ruma::{ receipt::ReceiptThread, relation::Annotation, room::message::{ - ForwardThread, LocationMessageEventContent, MessageType, - RoomMessageEventContentWithoutRelation, + FormattedBody as RumaFormattedBody, ForwardThread, LocationMessageEventContent, + MessageType, + RoomMessageEventContentWithoutRelation }, - AnyMessageLikeEventContent, }, - EventId, }; +use std::{collections::HashMap, fmt::Write as _, fs, sync::Arc}; use tokio::{ sync::Mutex, task::{AbortHandle, JoinHandle}, @@ -56,15 +56,15 @@ use crate::{ client::ProgressWatcher, error::{ClientError, RoomError}, helpers::unwrap_or_clone_arc, - ruma::{AssetType, AudioInfo, FileInfo, ImageInfo, PollKind, ThumbnailInfo, VideoInfo}, - task_handle::TaskHandle, + ruma::{AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, VideoInfo}, RUNTIME, + task_handle::TaskHandle, }; -mod content; - pub use self::content::{Reaction, ReactionSenderData, TimelineItemContent}; +mod content; + #[derive(uniffi::Object)] #[repr(transparent)] pub struct Timeline { @@ -106,12 +106,18 @@ impl Timeline { async fn send_attachment( &self, + caption: Option, + formatted: Option, url: String, mime_type: Mime, attachment_config: AttachmentConfig, progress_watcher: Option>, ) -> Result<(), RoomError> { - let request = self.inner.send_attachment(url, mime_type, attachment_config); + let formatted: Option = match formatted { + Some(p) => Some(RumaFormattedBody::from(p)), + None => None + }; + let request = self.inner.send_attachment(caption, formatted, url, mime_type, attachment_config); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); RUNTIME.spawn(async move { @@ -215,6 +221,8 @@ impl Timeline { pub fn send_image( self: Arc, + caption: Option, + formatted: Option, url: String, thumbnail_url: Option, image_info: ImageInfo, @@ -240,12 +248,14 @@ impl Timeline { _ => AttachmentConfig::new().info(attachment_info), }; - self.send_attachment(url, mime_type, attachment_config, progress_watcher).await + self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await })) } pub fn send_video( self: Arc, + caption: Option, + formatted: Option, url: String, thumbnail_url: Option, video_info: VideoInfo, @@ -271,12 +281,14 @@ impl Timeline { _ => AttachmentConfig::new().info(attachment_info), }; - self.send_attachment(url, mime_type, attachment_config, progress_watcher).await + self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await })) } pub fn send_audio( self: Arc, + caption: Option, + formatted: Option, url: String, audio_info: AudioInfo, progress_watcher: Option>, @@ -293,12 +305,14 @@ impl Timeline { let attachment_info = AttachmentInfo::Audio(base_audio_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(url, mime_type, attachment_config, progress_watcher).await + self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await })) } pub fn send_voice_message( self: Arc, + caption: Option, + formatted: Option, url: String, audio_info: AudioInfo, waveform: Vec, @@ -317,7 +331,7 @@ impl Timeline { AttachmentInfo::Voice { audio_info: base_audio_info, waveform: Some(waveform) }; let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(url, mime_type, attachment_config, progress_watcher).await + self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await })) } @@ -339,7 +353,7 @@ impl Timeline { let attachment_info = AttachmentInfo::File(base_file_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(url, mime_type, attachment_config, progress_watcher).await + self.send_attachment(None, None, url, mime_type, attachment_config, progress_watcher).await })) } diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index d7d9e1bd36b..4131232eb64 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -1,15 +1,17 @@ -use std::{fs, future::IntoFuture, path::Path}; - use eyeball::{SharedObservable, Subscriber}; use matrix_sdk::{attachment::AttachmentConfig, TransmissionProgress}; use matrix_sdk_base::boxed_into_future; use mime::Mime; +use ruma::events::room::message::FormattedBody; +use std::{fs, future::IntoFuture, path::Path}; use tracing::{Instrument as _, Span}; use super::{Error, Timeline}; pub struct SendAttachment<'a> { timeline: &'a Timeline, + caption: Option, + formatted: Option, url: String, mime_type: Mime, config: AttachmentConfig, @@ -20,12 +22,16 @@ pub struct SendAttachment<'a> { impl<'a> SendAttachment<'a> { pub(crate) fn new( timeline: &'a Timeline, + caption: Option, + formatted: Option, url: String, mime_type: Mime, config: AttachmentConfig, ) -> Self { Self { timeline, + caption, + formatted, url, mime_type, config, @@ -47,9 +53,9 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { timeline, url, mime_type, config, tracing_span, send_progress } = self; + let Self { timeline, caption, formatted, url, mime_type, config, tracing_span, send_progress } = self; let fut = async move { - let body = Path::new(&url) + let urlbody = Path::new(&url) .file_name() .ok_or(Error::InvalidAttachmentFileName)? .to_str() @@ -58,7 +64,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { timeline .room() - .send_attachment(body, &mime_type, data, config) + .send_attachment(caption, formatted, urlbody, &mime_type, data, config) .with_send_progress_observable(send_progress) .await .map_err(|_| Error::FailedSendingAttachment)?; diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index 85a50022a18..925803ed6d8 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -16,73 +16,47 @@ //! //! See [`Timeline`] for details. -use std::{pin::Pin, sync::Arc, task::Poll}; - use eyeball::{SharedObservable, Subscriber}; use eyeball_im::VectorDiff; use futures_core::Stream; use imbl::Vector; use matrix_sdk::{ attachment::AttachmentConfig, + Client, event_cache::{EventCacheDropHandles, RoomEventCache}, event_handler::EventHandlerHandle, executor::JoinHandle, - room::{Receipts, Room}, - Client, Result, + Result, room::{Receipts, Room}, }; use matrix_sdk_base::RoomState; use mime::Mime; use pin_project_lite::pin_project; use ruma::{ api::client::receipt::create_receipt::v3::ReceiptType, + EventId, events::{ + AnyMessageLikeEventContent, + AnySyncTimelineEvent, poll::unstable_start::{ ReplacementUnstablePollStartEventContent, UnstablePollStartContentBlock, UnstablePollStartEventContent, }, reaction::ReactionEventContent, receipt::{Receipt, ReceiptThread}, - relation::Annotation, - room::{ + relation::Annotation, room::{ message::{ - AddMentions, ForwardThread, OriginalRoomMessageEvent, ReplacementMetadata, - RoomMessageEventContent, RoomMessageEventContentWithoutRelation, + AddMentions, FormattedBody, ForwardThread, OriginalRoomMessageEvent, ReplacementMetadata, RoomMessageEventContent, RoomMessageEventContentWithoutRelation }, redaction::RoomRedactionEventContent, }, - AnyMessageLikeEventContent, AnySyncTimelineEvent, - }, - uint, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, RoomVersionId, - TransactionId, UserId, + }, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, RoomVersionId, TransactionId, + uint, UserId, }; +use std::{pin::Pin, sync::Arc, task::Poll}; use thiserror::Error; use tokio::sync::mpsc::Sender; use tracing::{debug, error, instrument, trace, warn}; -use self::futures::SendAttachment; - -mod builder; -mod error; -mod event_handler; -mod event_item; -pub mod event_type_filter; -pub mod futures; -mod inner; -mod item; -mod pagination; -mod polls; -mod queue; -mod reactions; -mod read_receipts; -mod sliding_sync_ext; -#[cfg(test)] -mod tests; -#[cfg(feature = "e2e-encryption")] -mod to_device; -mod traits; -mod util; -mod virtual_item; - pub use self::{ builder::TimelineBuilder, error::{Error, UnsupportedEditItem, UnsupportedReplyItem}, @@ -108,6 +82,29 @@ use self::{ reactions::ReactionToggleResult, util::rfind_event_by_id, }; +use self::futures::SendAttachment; + +mod builder; +mod error; +mod event_handler; +mod event_item; +pub mod event_type_filter; +pub mod futures; +mod inner; +mod item; +mod pagination; +mod polls; +mod queue; +mod reactions; +mod read_receipts; +mod sliding_sync_ext; +#[cfg(test)] +mod tests; +#[cfg(feature = "e2e-encryption")] +mod to_device; +mod traits; +mod util; +mod virtual_item; /// A high-level view into a regularĀ¹ room's contents. /// @@ -513,6 +510,10 @@ impl Timeline { /// /// # Arguments /// + /// * `caption` - The url for the file to be sent + /// + /// * `formatted` - The url for the file to be sent + /// /// * `url` - The url for the file to be sent /// /// * `mime_type` - The attachment's mime type @@ -523,11 +524,13 @@ impl Timeline { #[instrument(skip_all)] pub fn send_attachment( &self, + caption: Option, + formatted: Option, url: String, mime_type: Mime, config: AttachmentConfig, ) -> SendAttachment<'_> { - SendAttachment::new(self, url, mime_type, config) + SendAttachment::new(self, caption, formatted, url, mime_type, config) } /// Retry sending a message that previously failed to send. diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index 5ce64635908..bed3cc10202 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -16,14 +16,6 @@ #![doc = include_str!("../docs/encryption.md")] #![cfg_attr(target_arch = "wasm32", allow(unused_imports))] -use std::{ - collections::{BTreeMap, HashSet}, - io::{Cursor, Read, Write}, - iter, - path::PathBuf, - sync::{Arc, Mutex as StdMutex}, -}; - use eyeball::{SharedObservable, Subscriber}; use futures_core::Stream; use futures_util::{ @@ -33,6 +25,15 @@ use futures_util::{ use matrix_sdk_base::crypto::{ CrossSigningBootstrapRequests, OlmMachine, OutgoingRequest, RoomMessageRequest, ToDeviceRequest, }; +pub use matrix_sdk_base::crypto::{ + CrossSigningStatus, + CryptoStoreError, DecryptorError, EventError, KeyExportError, LocalTrust, MediaEncryptionInfo, + MegolmError, olm::{ + SessionCreationError as MegolmSessionCreationError, + SessionExportError as OlmSessionExportError, + }, OlmError, RoomKeyImportResult, SecretImportError, SessionCreationError, + SignatureError, VERSION, vodozemac, +}; use matrix_sdk_common::executor::spawn; use ruma::{ api::client::{ @@ -47,36 +48,45 @@ use ruma::{ uiaa::AuthData, }, assign, + DeviceId, events::room::{ - message::{ - AudioMessageEventContent, FileInfo, FileMessageEventContent, ImageMessageEventContent, - MessageType, VideoInfo, VideoMessageEventContent, - }, - ImageInfo, MediaSource, ThumbnailInfo, - }, - DeviceId, OwnedDeviceId, OwnedUserId, TransactionId, UserId, + ImageInfo, + MediaSource, message::{ + AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, + ImageMessageEventContent, MessageType, VideoInfo, VideoMessageEventContent + }, ThumbnailInfo, + }, OwnedDeviceId, OwnedUserId, TransactionId, UserId, +}; +use std::{ + collections::{BTreeMap, HashSet}, + io::{Cursor, Read, Write}, + iter, + path::PathBuf, + sync::{Arc, Mutex as StdMutex}, }; use tokio::sync::RwLockReadGuard; use tracing::{debug, error, instrument, trace, warn}; -use self::{ - backups::{types::BackupClientState, Backups}, - futures::PrepareEncryptedFile, - identities::{DeviceUpdates, IdentityUpdates}, - recovery::{Recovery, RecoveryState}, - secret_storage::SecretStorage, - tasks::{BackupDownloadTask, BackupUploadingTask, ClientTasks}, -}; use crate::{ attachment::{AttachmentInfo, Thumbnail}, + Client, client::ClientInner, encryption::{ identities::{Device, UserDevices}, verification::{SasVerification, Verification, VerificationRequest}, }, - error::HttpResult, - store_locks::CrossProcessStoreLockGuard, - Client, Error, Result, Room, TransmissionProgress, + Error, + error::HttpResult, Result, Room, store_locks::CrossProcessStoreLockGuard, TransmissionProgress, +}; +pub use crate::error::RoomKeyImportError; + +use self::{ + backups::{Backups, types::BackupClientState}, + futures::PrepareEncryptedFile, + identities::{DeviceUpdates, IdentityUpdates}, + recovery::{Recovery, RecoveryState}, + secret_storage::SecretStorage, + tasks::{BackupDownloadTask, BackupUploadingTask, ClientTasks}, }; pub mod backups; @@ -87,18 +97,6 @@ pub mod secret_storage; pub(crate) mod tasks; pub mod verification; -pub use matrix_sdk_base::crypto::{ - olm::{ - SessionCreationError as MegolmSessionCreationError, - SessionExportError as OlmSessionExportError, - }, - vodozemac, CrossSigningStatus, CryptoStoreError, DecryptorError, EventError, KeyExportError, - LocalTrust, MediaEncryptionInfo, MegolmError, OlmError, RoomKeyImportResult, SecretImportError, - SessionCreationError, SignatureError, VERSION, -}; - -pub use crate::error::RoomKeyImportError; - /// All the data related to the encryption state. pub(crate) struct EncryptionData { /// Background tasks related to encryption (key backup, initialization @@ -298,10 +296,13 @@ impl Client { } /// Encrypt and upload the file to be read from `reader` and construct an - /// attachment message with `body`, `content_type`, `info` and `thumbnail`. + /// attachment message with `body`, `content_type`, `info` and `thumbnail`, + /// optionanly with `formatted` and `filename`. pub(crate) async fn prepare_encrypted_attachment_message( &self, - body: &str, + caption: Option, + formatted: Option, + url: &str, content_type: &mime::Mime, data: Vec, info: Option, @@ -321,6 +322,15 @@ impl Client { let ((thumbnail_source, thumbnail_info), file) = try_join(upload_thumbnail, upload_attachment).await?; + let body: &str = match &caption { + Some(p) => p, + None => url, + }; + let filename = match &caption { + Some(p) => Some(String::from(p)), + None => None + }; + Ok(match content_type.type_() { mime::IMAGE => { let info = assign!(info.map(ImageInfo::from).unwrap_or_default(), { @@ -329,7 +339,9 @@ impl Client { thumbnail_info }); let content = assign!(ImageMessageEventContent::encrypted(body.to_owned(), file), { - info: Some(Box::new(info)) + info: Some(Box::new(info)), + formatted: formatted, + filename: filename }); MessageType::Image(content) } @@ -1435,12 +1447,10 @@ impl Encryption { #[cfg(all(test, not(target_arch = "wasm32")))] mod tests { - use std::time::Duration; - use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ - async_test, test_json, GlobalAccountDataTestEvent, JoinedRoomBuilder, StateTestEvent, - SyncResponseBuilder, DEFAULT_TEST_ROOM_ID, + async_test, DEFAULT_TEST_ROOM_ID, GlobalAccountDataTestEvent, JoinedRoomBuilder, StateTestEvent, + SyncResponseBuilder, test_json, }; use ruma::{ device_id, event_id, @@ -1448,16 +1458,17 @@ mod tests { user_id, }; use serde_json::json; + use std::time::Duration; use wiremock::{ matchers::{header, method, path_regex}, Mock, MockServer, ResponseTemplate, }; use crate::{ + Client, config::RequestConfig, matrix_auth::{MatrixSession, MatrixSessionTokens}, test_utils::logged_in_client, - Client, }; #[async_test] diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index 8516d3d953c..b8e8647c8a6 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -15,12 +15,6 @@ //! High-level media API. -#[cfg(feature = "e2e-encryption")] -use std::io::Read; -use std::time::Duration; -#[cfg(not(target_arch = "wasm32"))] -use std::{fmt, fs::File, io, path::Path}; - use eyeball::SharedObservable; use futures_util::future::try_join; pub use matrix_sdk_base::media::*; @@ -29,24 +23,29 @@ use ruma::{ api::client::media::{create_content, get_content, get_content_thumbnail}, assign, events::room::{ - message::{ + ImageInfo, + MediaSource, message::{ self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, - ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, + FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent, - }, - ImageInfo, MediaSource, ThumbnailInfo, + }, ThumbnailInfo, }, MxcUri, }; #[cfg(not(target_arch = "wasm32"))] +use std::{fmt, fs::File, io, path::Path}; +#[cfg(feature = "e2e-encryption")] +use std::io::Read; +use std::time::Duration; +#[cfg(not(target_arch = "wasm32"))] use tempfile::{Builder as TempFileBuilder, NamedTempFile, TempDir}; #[cfg(not(target_arch = "wasm32"))] use tokio::{fs::File as TokioFile, io::AsyncWriteExt}; use crate::{ attachment::{AttachmentInfo, Thumbnail}, - futures::SendRequest, - Client, Result, TransmissionProgress, + Client, + futures::SendRequest, Result, TransmissionProgress, }; /// A conservative upload speed of 1Mbps @@ -437,10 +436,13 @@ impl Media { } /// Upload the file bytes in `data` and construct an attachment - /// message with `body`, `content_type`, `info` and `thumbnail`. + /// message with `body`, `content_type`, `info` and `thumbnail`, + /// optionally with `formatted` and `filename`. pub(crate) async fn prepare_attachment_message( &self, - body: &str, + caption: Option, + formatted: Option, + url: &str, content_type: &Mime, data: Vec, info: Option, @@ -459,6 +461,14 @@ impl Media { let ((thumbnail_source, thumbnail_info), response) = try_join(upload_thumbnail, upload_attachment).await?; + let body: &str = match &caption { + Some(p) => p, + None => url, + }; + let filename = match &caption { + Some(_) => Some(String::from(url)), + None => None + }; let url = response.content_uri; Ok(match content_type.type_() { @@ -469,12 +479,17 @@ impl Media { thumbnail_info, }); MessageType::Image( - ImageMessageEventContent::plain(body.to_owned(), url).info(Box::new(info)), + ImageMessageEventContent::plain(body.to_owned(), url) + .info(Box::new(info)) + .filename(filename) + .formatted(formatted), ) } mime::AUDIO => { let audio_message_event_content = - message::AudioMessageEventContent::plain(body.to_owned(), url); + message::AudioMessageEventContent::plain(body.to_owned(), url) + .filename(filename) + .formatted(formatted); MessageType::Audio(update_audio_message_event( audio_message_event_content, content_type, @@ -488,7 +503,10 @@ impl Media { thumbnail_info }); MessageType::Video( - VideoMessageEventContent::plain(body.to_owned(), url).info(Box::new(info)), + VideoMessageEventContent::plain(body.to_owned(), url) + .info(Box::new(info)) + .filename(filename) + .formatted(formatted) ) } _ => { @@ -498,7 +516,10 @@ impl Media { thumbnail_info }); MessageType::File( - FileMessageEventContent::plain(body.to_owned(), url).info(Box::new(info)), + FileMessageEventContent::plain(body.to_owned(), url) + .info(Box::new(info)) + .filename(filename) + .formatted(formatted), ) } }) diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index b599df1d5bf..a74b2e9f668 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -16,28 +16,26 @@ #![deny(unreachable_pub)] -use std::future::IntoFuture; -#[cfg(feature = "image-proc")] -use std::io::Cursor; - use eyeball::SharedObservable; use matrix_sdk_common::boxed_into_future; use mime::Mime; -#[cfg(doc)] -use ruma::events::{MessageLikeUnsigned, SyncMessageLikeEvent}; use ruma::{ api::client::message::send_message_event, assign, - events::{AnyMessageLikeEventContent, MessageLikeEventContent}, - serde::Raw, - OwnedTransactionId, TransactionId, + events::{AnyMessageLikeEventContent, MessageLikeEventContent, room::message::FormattedBody}, + OwnedTransactionId, + serde::Raw, TransactionId, }; +#[cfg(doc)] +use ruma::events::{MessageLikeUnsigned, SyncMessageLikeEvent}; +use std::future::IntoFuture; +#[cfg(feature = "image-proc")] +use std::io::Cursor; use tracing::{debug, info, Instrument, Span}; -use super::Room; use crate::{ - attachment::AttachmentConfig, utils::IntoRawMessageLikeEventContent, Result, - TransmissionProgress, + attachment::AttachmentConfig, Result, TransmissionProgress, + utils::IntoRawMessageLikeEventContent, }; #[cfg(feature = "image-proc")] use crate::{ @@ -45,6 +43,8 @@ use crate::{ error::ImageError, }; +use super::Room; + /// Future returned by [`Room::send`]. #[allow(missing_debug_implementations)] pub struct SendMessageLikeEvent<'a> { @@ -216,7 +216,9 @@ impl<'a> IntoFuture for SendRawMessageLikeEvent<'a> { #[allow(missing_debug_implementations)] pub struct SendAttachment<'a> { room: &'a Room, - body: &'a str, + caption: Option, + formatted: Option, + url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, @@ -227,14 +229,18 @@ pub struct SendAttachment<'a> { impl<'a> SendAttachment<'a> { pub(crate) fn new( room: &'a Room, - body: &'a str, + caption: Option, + formatted: Option, + url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, ) -> Self { Self { room, - body, + caption, + formatted, + url, content_type, data, config, @@ -260,10 +266,10 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { room, body, content_type, data, config, tracing_span, send_progress } = self; + let Self { room, caption, formatted, url, content_type, data, config, tracing_span, send_progress } = self; let fut = async move { if config.thumbnail.is_some() { - room.prepare_and_send_attachment(body, content_type, data, config, send_progress) + room.prepare_and_send_attachment(caption, formatted, url, content_type, data, config, send_progress) .await } else { #[cfg(not(feature = "image-proc"))] @@ -322,7 +328,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { thumbnail_size: None, }; - room.prepare_and_send_attachment(body, content_type, data, config, send_progress) + room.prepare_and_send_attachment(caption, formatted, url, content_type, data, config, send_progress) .await } }; diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index d3bdafe93d3..905fb30ab0d 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1,13 +1,5 @@ //! High-level room API -use std::{ - borrow::Borrow, - collections::{BTreeMap, HashMap}, - ops::Deref, - sync::Arc, - time::Duration, -}; - use eyeball::SharedObservable; use futures_core::Stream; use futures_util::stream::FuturesUnordered; @@ -16,16 +8,11 @@ use matrix_sdk_base::{ RawAnySyncOrStrippedState, RawSyncOrStrippedState, SyncOrStrippedState, TimelineEvent, }, instant::Instant, - store::StateStoreExt, - RoomMemberships, StateChanges, + RoomMemberships, + StateChanges, store::StateStoreExt, }; use matrix_sdk_common::timeout::timeout; use mime::Mime; -#[cfg(feature = "e2e-encryption")] -use ruma::events::{ - room::encrypted::OriginalSyncRoomEncryptedEvent, AnySyncMessageLikeEvent, AnySyncTimelineEvent, - SyncMessageLikeEvent, -}; use ruma::{ api::client::{ config::{set_global_account_data, set_room_account_data}, @@ -34,8 +21,8 @@ use ruma::{ filter::LazyLoadOptions, membership::{ ban_user, forget_room, get_member_events, - invite_user::{self, v3::InvitationRecipient}, - join_room_by_id, kick_user, leave_room, unban_user, Invite3pid, + Invite3pid, + invite_user::{self, v3::InvitationRecipient}, join_room_by_id, kick_user, leave_room, unban_user, }, message::send_message_event, read_marker::set_read_marker, @@ -47,59 +34,72 @@ use ruma::{ typing::create_typing_event::{self, v3::Typing}, }, assign, + EventId, events::{ + AnyRoomAccountDataEvent, + AnyStateEvent, direct::DirectEventContent, + EmptyStateKey, marked_unread::MarkedUnreadEventContent, - receipt::{Receipt, ReceiptThread, ReceiptType}, - room::{ + MessageLikeEventContent, + MessageLikeEventType, + receipt::{Receipt, ReceiptThread, ReceiptType}, RedactContent, RedactedStateEventContent, room::{ avatar::{self, RoomAvatarEventContent}, encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility, - message::RoomMessageEventContent, + MediaSource, + message::{FormattedBody, RoomMessageEventContent}, name::RoomNameEventContent, power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent}, server_acl::RoomServerAclEventContent, topic::RoomTopicEventContent, - MediaSource, }, - space::{child::SpaceChildEventContent, parent::SpaceParentEventContent}, - tag::{TagInfo, TagName}, - typing::SyncTypingEvent, - AnyRoomAccountDataEvent, AnyStateEvent, EmptyStateKey, MessageLikeEventContent, - MessageLikeEventType, RedactContent, RedactedStateEventContent, RoomAccountDataEvent, - RoomAccountDataEventContent, RoomAccountDataEventType, StateEventContent, StateEventType, - StaticEventContent, StaticStateEventContent, SyncStateEvent, + RoomAccountDataEvent, RoomAccountDataEventContent, RoomAccountDataEventType, space::{child::SpaceChildEventContent, parent::SpaceParentEventContent}, + StateEventContent, StateEventType, StaticEventContent, StaticStateEventContent, + SyncStateEvent, tag::{TagInfo, TagName}, typing::SyncTypingEvent, }, - push::{Action, PushConditionRoomCtx}, - serde::Raw, - uint, EventId, Int, MatrixToUri, MatrixUri, MxcUri, OwnedEventId, OwnedRoomId, OwnedServerName, - OwnedTransactionId, OwnedUserId, TransactionId, UInt, UserId, + Int, + MatrixToUri, MatrixUri, MxcUri, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedTransactionId, OwnedUserId, push::{Action, PushConditionRoomCtx}, + serde::Raw, TransactionId, uint, UInt, UserId, +}; +#[cfg(feature = "e2e-encryption")] +use ruma::events::{ + AnySyncMessageLikeEvent, AnySyncTimelineEvent, room::encrypted::OriginalSyncRoomEncryptedEvent, + SyncMessageLikeEvent, }; use serde::de::DeserializeOwned; +use std::{ + borrow::Borrow, + collections::{BTreeMap, HashMap}, + ops::Deref, + sync::Arc, + time::Duration, +}; use thiserror::Error; use tokio::sync::broadcast; use tracing::{debug, info, instrument, warn}; -use self::futures::{SendAttachment, SendMessageLikeEvent, SendRawMessageLikeEvent}; -pub use self::{ - member::{RoomMember, RoomMemberRole}, - messages::{Messages, MessagesOptions}, -}; -#[cfg(doc)] -use crate::event_cache::EventCache; use crate::{ attachment::AttachmentConfig, + BaseRoom, + Client, config::RequestConfig, + Error, error::WrongRoomState, event_cache::{self, EventCacheDropHandles, RoomEventCache}, event_handler::{EventHandler, EventHandlerDropGuard, EventHandlerHandle, SyncEvent}, - media::{MediaFormat, MediaRequest}, - notification_settings::{IsEncrypted, IsOneToOne, RoomNotificationMode}, - room::power_levels::{RoomPowerLevelChanges, RoomPowerLevelsExt}, - sync::RoomUpdate, - utils::{IntoRawMessageLikeEventContent, IntoRawStateEventContent}, - BaseRoom, Client, Error, HttpError, HttpResult, Result, RoomState, TransmissionProgress, + HttpError, + HttpResult, + media::{MediaFormat, MediaRequest}, notification_settings::{IsEncrypted, IsOneToOne, RoomNotificationMode}, Result, room::power_levels::{RoomPowerLevelChanges, RoomPowerLevelsExt}, RoomState, sync::RoomUpdate, TransmissionProgress, utils::{IntoRawMessageLikeEventContent, IntoRawStateEventContent}, +}; +#[cfg(doc)] +use crate::event_cache::EventCache; + +pub use self::{ + member::{RoomMember, RoomMemberRole}, + messages::{Messages, MessagesOptions}, }; +use self::futures::{SendAttachment, SendMessageLikeEvent, SendRawMessageLikeEvent}; pub mod futures; mod member; @@ -1421,7 +1421,7 @@ impl Room { #[instrument(skip_all)] pub async fn enable_encryption(&self) -> Result<()> { use ruma::{ - events::room::encryption::RoomEncryptionEventContent, EventEncryptionAlgorithm, + EventEncryptionAlgorithm, events::room::encryption::RoomEncryptionEventContent, }; const SYNC_WAIT_TIME: Duration = Duration::from_secs(3); @@ -1692,8 +1692,13 @@ impl Room { /// [`upload()`] and afterwards the [`send()`]. /// /// # Arguments - /// * `body` - A textual representation of the media that is going to be - /// uploaded. Usually the file name. + /// * `caption` - An optional caption of the media that is going to be + /// uploaded. + /// + /// * `formatted` - A optional formatted caption of the media that is going to be + /// uploaded. + /// + /// * `url` - The file name. /// /// * `content_type` - The type of the media, this will be used as the /// content-type header. @@ -1732,12 +1737,14 @@ impl Room { #[instrument(skip_all)] pub fn send_attachment<'a>( &'a self, - body: &'a str, + caption: Option, + formatted: Option, + url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, ) -> SendAttachment<'a> { - SendAttachment::new(self, body, content_type, data, config) + SendAttachment::new(self, caption, formatted, url, content_type, data, config) } /// Prepare and send an attachment to this room. @@ -1752,8 +1759,13 @@ impl Room { /// [`send()`](#method.send). /// /// # Arguments - /// * `body` - A textual representation of the media that is going to be - /// uploaded. Usually the file name. + /// * `caption` - An optional caption of the media that is going to be + /// uploaded. + /// + /// * `formatted` - A optional formatted caption of the media that is going to be + /// uploaded. + /// + /// * `url` - The file name. /// /// * `content_type` - The type of the media, this will be used as the /// content-type header. @@ -1764,7 +1776,9 @@ impl Room { /// * `config` - Metadata and configuration for the attachment. pub(super) async fn prepare_and_send_attachment<'a>( &'a self, - body: &'a str, + caption: Option, + formatted: Option, + url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, @@ -1776,7 +1790,9 @@ impl Room { let content = if self.is_encrypted().await? { self.client .prepare_encrypted_attachment_message( - body, + caption, + formatted, + url, content_type, data, config.info, @@ -1788,7 +1804,9 @@ impl Room { self.client .media() .prepare_attachment_message( - body, + caption, + formatted, + url, content_type, data, config.info, @@ -2851,7 +2869,7 @@ pub struct TryFromReportedContentScoreError(()); mod tests { use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ - async_test, test_json, JoinedRoomBuilder, StateTestEvent, SyncResponseBuilder, + async_test, JoinedRoomBuilder, StateTestEvent, SyncResponseBuilder, test_json, }; use ruma::{device_id, int, user_id}; use wiremock::{ @@ -2859,17 +2877,18 @@ mod tests { Mock, MockServer, ResponseTemplate, }; - use super::ReportedContentScore; use crate::{ + Client, config::RequestConfig, matrix_auth::{MatrixSession, MatrixSessionTokens}, - Client, }; + use super::ReportedContentScore; + #[cfg(all(feature = "sqlite", feature = "e2e-encryption"))] #[async_test] async fn test_cache_invalidation_while_encrypt() { - use matrix_sdk_test::{message_like_event_content, DEFAULT_TEST_ROOM_ID}; + use matrix_sdk_test::{DEFAULT_TEST_ROOM_ID, message_like_event_content}; let sqlite_path = std::env::temp_dir().join("cache_invalidation_while_encrypt.db"); let session = MatrixSession { From 7aa59a6296cc59e391d54449759aacf26fc9c53e Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sat, 16 Mar 2024 21:02:25 +0100 Subject: [PATCH 03/17] signoff Signed-off-by: Marco Antonio Alvarez From 9bdd989614ecefb95c0793152ef9b5c3db3dedfb Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sat, 16 Mar 2024 21:47:37 +0100 Subject: [PATCH 04/17] fixing the import messup --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 14 +-- crates/matrix-sdk-ui/src/timeline/futures.rs | 3 +- crates/matrix-sdk-ui/src/timeline/mod.rs | 66 +++++++------- crates/matrix-sdk/src/encryption/mod.rs | 72 +++++++-------- crates/matrix-sdk/src/media.rs | 27 +++--- crates/matrix-sdk/src/room/futures.rs | 24 ++--- crates/matrix-sdk/src/room/mod.rs | 88 +++++++++---------- .../tests/integration/room/joined.rs | 8 +- examples/image_bot/src/main.rs | 2 +- 9 files changed, 156 insertions(+), 148 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 63fb8abc7c0..8de9cfd0844 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{collections::HashMap, fmt::Write as _, fs, sync::Arc}; + use anyhow::{Context, Result}; use as_variant::as_variant; use eyeball_im::VectorDiff; @@ -23,9 +25,7 @@ use matrix_sdk::attachment::{ use matrix_sdk_ui::timeline::{BackPaginationStatus, EventItemOrigin, Profile, TimelineDetails}; use mime::Mime; use ruma::{ - EventId, events::{ - AnyMessageLikeEventContent, location::{AssetType as RumaAssetType, LocationContent, ZoomLevel}, poll::{ unstable_end::UnstablePollEndEventContent, @@ -39,12 +39,12 @@ use ruma::{ relation::Annotation, room::message::{ FormattedBody as RumaFormattedBody, ForwardThread, LocationMessageEventContent, - MessageType, - RoomMessageEventContentWithoutRelation + MessageType, RoomMessageEventContentWithoutRelation }, + AnyMessageLikeEventContent, }, + EventId, }; -use std::{collections::HashMap, fmt::Write as _, fs, sync::Arc}; use tokio::{ sync::Mutex, task::{AbortHandle, JoinHandle}, @@ -57,11 +57,11 @@ use crate::{ error::{ClientError, RoomError}, helpers::unwrap_or_clone_arc, ruma::{AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, VideoInfo}, - RUNTIME, task_handle::TaskHandle, + RUNTIME, }; -pub use self::content::{Reaction, ReactionSenderData, TimelineItemContent}; +use self::content::{Reaction, ReactionSenderData, TimelineItemContent}; mod content; diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 4131232eb64..9c2a7d19806 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -1,9 +1,10 @@ +use std::{fs, future::IntoFuture, path::Path}; + use eyeball::{SharedObservable, Subscriber}; use matrix_sdk::{attachment::AttachmentConfig, TransmissionProgress}; use matrix_sdk_base::boxed_into_future; use mime::Mime; use ruma::events::room::message::FormattedBody; -use std::{fs, future::IntoFuture, path::Path}; use tracing::{Instrument as _, Span}; use super::{Error, Timeline}; diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index 925803ed6d8..a1f05c55105 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -16,47 +16,72 @@ //! //! See [`Timeline`] for details. +use std::{pin::Pin, sync::Arc, task::Poll}; + use eyeball::{SharedObservable, Subscriber}; use eyeball_im::VectorDiff; use futures_core::Stream; use imbl::Vector; use matrix_sdk::{ attachment::AttachmentConfig, - Client, event_cache::{EventCacheDropHandles, RoomEventCache}, event_handler::EventHandlerHandle, executor::JoinHandle, - Result, room::{Receipts, Room}, + room::{Receipts, Room}, + Client, Result, }; use matrix_sdk_base::RoomState; use mime::Mime; use pin_project_lite::pin_project; use ruma::{ api::client::receipt::create_receipt::v3::ReceiptType, - EventId, events::{ - AnyMessageLikeEventContent, - AnySyncTimelineEvent, poll::unstable_start::{ ReplacementUnstablePollStartEventContent, UnstablePollStartContentBlock, UnstablePollStartEventContent, }, reaction::ReactionEventContent, receipt::{Receipt, ReceiptThread}, - relation::Annotation, room::{ + relation::Annotation, + room::{ message::{ AddMentions, FormattedBody, ForwardThread, OriginalRoomMessageEvent, ReplacementMetadata, RoomMessageEventContent, RoomMessageEventContentWithoutRelation }, redaction::RoomRedactionEventContent, }, - }, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, RoomVersionId, TransactionId, - uint, UserId, + AnyMessageLikeEventContent, AnySyncTimelineEvent, + }, + uint, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, RoomVersionId, + TransactionId, UserId, }; -use std::{pin::Pin, sync::Arc, task::Poll}; use thiserror::Error; use tokio::sync::mpsc::Sender; use tracing::{debug, error, instrument, trace, warn}; +use self::futures::SendAttachment; + +mod builder; +mod error; +mod event_handler; +mod event_item; +pub mod event_type_filter; +pub mod futures; +mod inner; +mod item; +mod pagination; +mod polls; +mod queue; +mod reactions; +mod read_receipts; +mod sliding_sync_ext; +#[cfg(test)] +mod tests; +#[cfg(feature = "e2e-encryption")] +mod to_device; +mod traits; +mod util; +mod virtual_item; + pub use self::{ builder::TimelineBuilder, error::{Error, UnsupportedEditItem, UnsupportedReplyItem}, @@ -82,29 +107,6 @@ use self::{ reactions::ReactionToggleResult, util::rfind_event_by_id, }; -use self::futures::SendAttachment; - -mod builder; -mod error; -mod event_handler; -mod event_item; -pub mod event_type_filter; -pub mod futures; -mod inner; -mod item; -mod pagination; -mod polls; -mod queue; -mod reactions; -mod read_receipts; -mod sliding_sync_ext; -#[cfg(test)] -mod tests; -#[cfg(feature = "e2e-encryption")] -mod to_device; -mod traits; -mod util; -mod virtual_item; /// A high-level view into a regularĀ¹ room's contents. /// diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index bed3cc10202..e3ce381d6ec 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -16,6 +16,14 @@ #![doc = include_str!("../docs/encryption.md")] #![cfg_attr(target_arch = "wasm32", allow(unused_imports))] +use std::{ + collections::{BTreeMap, HashSet}, + io::{Cursor, Read, Write}, + iter, + path::PathBuf, + sync::{Arc, Mutex as StdMutex}, +}; + use eyeball::{SharedObservable, Subscriber}; use futures_core::Stream; use futures_util::{ @@ -25,15 +33,6 @@ use futures_util::{ use matrix_sdk_base::crypto::{ CrossSigningBootstrapRequests, OlmMachine, OutgoingRequest, RoomMessageRequest, ToDeviceRequest, }; -pub use matrix_sdk_base::crypto::{ - CrossSigningStatus, - CryptoStoreError, DecryptorError, EventError, KeyExportError, LocalTrust, MediaEncryptionInfo, - MegolmError, olm::{ - SessionCreationError as MegolmSessionCreationError, - SessionExportError as OlmSessionExportError, - }, OlmError, RoomKeyImportResult, SecretImportError, SessionCreationError, - SignatureError, VERSION, vodozemac, -}; use matrix_sdk_common::executor::spawn; use ruma::{ api::client::{ @@ -48,45 +47,36 @@ use ruma::{ uiaa::AuthData, }, assign, - DeviceId, events::room::{ - ImageInfo, - MediaSource, message::{ - AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, + message::{ + AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, ImageMessageEventContent, MessageType, VideoInfo, VideoMessageEventContent - }, ThumbnailInfo, - }, OwnedDeviceId, OwnedUserId, TransactionId, UserId, -}; -use std::{ - collections::{BTreeMap, HashSet}, - io::{Cursor, Read, Write}, - iter, - path::PathBuf, - sync::{Arc, Mutex as StdMutex}, + }, + ImageInfo, MediaSource, ThumbnailInfo, + }, + DeviceId, OwnedDeviceId, OwnedUserId, TransactionId, UserId, }; use tokio::sync::RwLockReadGuard; use tracing::{debug, error, instrument, trace, warn}; +use self::{ + backups::{types::BackupClientState, Backups}, + futures::PrepareEncryptedFile, + identities::{DeviceUpdates, IdentityUpdates}, + recovery::{Recovery, RecoveryState}, + secret_storage::SecretStorage, + tasks::{BackupDownloadTask, BackupUploadingTask, ClientTasks}, +}; use crate::{ attachment::{AttachmentInfo, Thumbnail}, - Client, client::ClientInner, encryption::{ identities::{Device, UserDevices}, verification::{SasVerification, Verification, VerificationRequest}, }, - Error, - error::HttpResult, Result, Room, store_locks::CrossProcessStoreLockGuard, TransmissionProgress, -}; -pub use crate::error::RoomKeyImportError; - -use self::{ - backups::{Backups, types::BackupClientState}, - futures::PrepareEncryptedFile, - identities::{DeviceUpdates, IdentityUpdates}, - recovery::{Recovery, RecoveryState}, - secret_storage::SecretStorage, - tasks::{BackupDownloadTask, BackupUploadingTask, ClientTasks}, + error::HttpResult, + store_locks::CrossProcessStoreLockGuard, + Client, Error, Result, Room, TransmissionProgress, }; pub mod backups; @@ -97,6 +87,18 @@ pub mod secret_storage; pub(crate) mod tasks; pub mod verification; +pub use matrix_sdk_base::crypto::{ + olm::{ + SessionCreationError as MegolmSessionCreationError, + SessionExportError as OlmSessionExportError, + }, + vodozemac, CrossSigningStatus, CryptoStoreError, DecryptorError, EventError, KeyExportError, + LocalTrust, MediaEncryptionInfo, MegolmError, OlmError, RoomKeyImportResult, SecretImportError, + SessionCreationError, SignatureError, VERSION, +}; + +pub use crate::error::RoomKeyImportError; + /// All the data related to the encryption state. pub(crate) struct EncryptionData { /// Background tasks related to encryption (key backup, initialization diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index b8e8647c8a6..07856126478 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -15,6 +15,12 @@ //! High-level media API. +#[cfg(feature = "e2e-encryption")] +use std::io::Read; +use std::time::Duration; +#[cfg(not(target_arch = "wasm32"))] +use std::{fmt, fs::File, io, path::Path}; + use eyeball::SharedObservable; use futures_util::future::try_join; pub use matrix_sdk_base::media::*; @@ -23,29 +29,24 @@ use ruma::{ api::client::media::{create_content, get_content, get_content_thumbnail}, assign, events::room::{ - ImageInfo, - MediaSource, message::{ - self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, - FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, - UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent, - }, ThumbnailInfo, + message::{ + self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, + FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, + UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent + }, + ImageInfo, MediaSource, ThumbnailInfo, }, MxcUri, }; #[cfg(not(target_arch = "wasm32"))] -use std::{fmt, fs::File, io, path::Path}; -#[cfg(feature = "e2e-encryption")] -use std::io::Read; -use std::time::Duration; -#[cfg(not(target_arch = "wasm32"))] use tempfile::{Builder as TempFileBuilder, NamedTempFile, TempDir}; #[cfg(not(target_arch = "wasm32"))] use tokio::{fs::File as TokioFile, io::AsyncWriteExt}; use crate::{ attachment::{AttachmentInfo, Thumbnail}, - Client, - futures::SendRequest, Result, TransmissionProgress, + futures::SendRequest, + Client, Result, TransmissionProgress, }; /// A conservative upload speed of 1Mbps diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index a74b2e9f668..28c19bcf7fe 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -16,26 +16,28 @@ #![deny(unreachable_pub)] +use std::future::IntoFuture; +#[cfg(feature = "image-proc")] +use std::io::Cursor; + use eyeball::SharedObservable; use matrix_sdk_common::boxed_into_future; use mime::Mime; +#[cfg(doc)] +use ruma::events::{MessageLikeUnsigned, SyncMessageLikeEvent}; use ruma::{ api::client::message::send_message_event, assign, - events::{AnyMessageLikeEventContent, MessageLikeEventContent, room::message::FormattedBody}, - OwnedTransactionId, - serde::Raw, TransactionId, + events::{room::message::FormattedBody, AnyMessageLikeEventContent, MessageLikeEventContent}, + serde::Raw, + OwnedTransactionId, TransactionId, }; -#[cfg(doc)] -use ruma::events::{MessageLikeUnsigned, SyncMessageLikeEvent}; -use std::future::IntoFuture; -#[cfg(feature = "image-proc")] -use std::io::Cursor; use tracing::{debug, info, Instrument, Span}; +use super::Room; use crate::{ - attachment::AttachmentConfig, Result, TransmissionProgress, - utils::IntoRawMessageLikeEventContent, + attachment::AttachmentConfig, utils::IntoRawMessageLikeEventContent, Result, + TransmissionProgress, }; #[cfg(feature = "image-proc")] use crate::{ @@ -43,8 +45,6 @@ use crate::{ error::ImageError, }; -use super::Room; - /// Future returned by [`Room::send`]. #[allow(missing_debug_implementations)] pub struct SendMessageLikeEvent<'a> { diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 905fb30ab0d..df688ced440 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1,5 +1,13 @@ //! High-level room API +use std::{ + borrow::Borrow, + collections::{BTreeMap, HashMap}, + ops::Deref, + sync::Arc, + time::Duration, +}; + use eyeball::SharedObservable; use futures_core::Stream; use futures_util::stream::FuturesUnordered; @@ -8,11 +16,16 @@ use matrix_sdk_base::{ RawAnySyncOrStrippedState, RawSyncOrStrippedState, SyncOrStrippedState, TimelineEvent, }, instant::Instant, - RoomMemberships, - StateChanges, store::StateStoreExt, + store::StateStoreExt, + RoomMemberships, StateChanges, }; use matrix_sdk_common::timeout::timeout; use mime::Mime; +#[cfg(feature = "e2e-encryption")] +use ruma::events::{ + room::encrypted::OriginalSyncRoomEncryptedEvent, AnySyncMessageLikeEvent, AnySyncTimelineEvent, + SyncMessageLikeEvent, +}; use ruma::{ api::client::{ config::{set_global_account_data, set_room_account_data}, @@ -21,8 +34,8 @@ use ruma::{ filter::LazyLoadOptions, membership::{ ban_user, forget_room, get_member_events, - Invite3pid, - invite_user::{self, v3::InvitationRecipient}, join_room_by_id, kick_user, leave_room, unban_user, + invite_user::{self, v3::InvitationRecipient}, + join_room_by_id, kick_user, leave_room, unban_user, Invite3pid, }, message::send_message_event, read_marker::set_read_marker, @@ -34,72 +47,59 @@ use ruma::{ typing::create_typing_event::{self, v3::Typing}, }, assign, - EventId, events::{ - AnyRoomAccountDataEvent, - AnyStateEvent, direct::DirectEventContent, - EmptyStateKey, marked_unread::MarkedUnreadEventContent, - MessageLikeEventContent, - MessageLikeEventType, - receipt::{Receipt, ReceiptThread, ReceiptType}, RedactContent, RedactedStateEventContent, room::{ + receipt::{Receipt, ReceiptThread, ReceiptType}, + room::{ avatar::{self, RoomAvatarEventContent}, encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility, - MediaSource, message::{FormattedBody, RoomMessageEventContent}, name::RoomNameEventContent, power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent}, server_acl::RoomServerAclEventContent, topic::RoomTopicEventContent, + MediaSource, }, - RoomAccountDataEvent, RoomAccountDataEventContent, RoomAccountDataEventType, space::{child::SpaceChildEventContent, parent::SpaceParentEventContent}, - StateEventContent, StateEventType, StaticEventContent, StaticStateEventContent, - SyncStateEvent, tag::{TagInfo, TagName}, typing::SyncTypingEvent, + space::{child::SpaceChildEventContent, parent::SpaceParentEventContent}, + tag::{TagInfo, TagName}, + typing::SyncTypingEvent, + AnyRoomAccountDataEvent, AnyStateEvent, EmptyStateKey, MessageLikeEventContent, + MessageLikeEventType, RedactContent, RedactedStateEventContent, RoomAccountDataEvent, + RoomAccountDataEventContent, RoomAccountDataEventType, StateEventContent, StateEventType, + StaticEventContent, StaticStateEventContent, SyncStateEvent, }, - Int, - MatrixToUri, MatrixUri, MxcUri, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedTransactionId, OwnedUserId, push::{Action, PushConditionRoomCtx}, - serde::Raw, TransactionId, uint, UInt, UserId, -}; -#[cfg(feature = "e2e-encryption")] -use ruma::events::{ - AnySyncMessageLikeEvent, AnySyncTimelineEvent, room::encrypted::OriginalSyncRoomEncryptedEvent, - SyncMessageLikeEvent, + push::{Action, PushConditionRoomCtx}, + serde::Raw, + uint, EventId, Int, MatrixToUri, MatrixUri, MxcUri, OwnedEventId, OwnedRoomId, OwnedServerName, + OwnedTransactionId, OwnedUserId, TransactionId, UInt, UserId, }; use serde::de::DeserializeOwned; -use std::{ - borrow::Borrow, - collections::{BTreeMap, HashMap}, - ops::Deref, - sync::Arc, - time::Duration, -}; use thiserror::Error; use tokio::sync::broadcast; use tracing::{debug, info, instrument, warn}; +use self::futures::{SendAttachment, SendMessageLikeEvent, SendRawMessageLikeEvent}; +pub use self::{ + member::{RoomMember, RoomMemberRole}, + messages::{Messages, MessagesOptions}, +}; +#[cfg(doc)] +use crate::event_cache::EventCache; use crate::{ attachment::AttachmentConfig, - BaseRoom, - Client, config::RequestConfig, - Error, error::WrongRoomState, event_cache::{self, EventCacheDropHandles, RoomEventCache}, event_handler::{EventHandler, EventHandlerDropGuard, EventHandlerHandle, SyncEvent}, - HttpError, - HttpResult, - media::{MediaFormat, MediaRequest}, notification_settings::{IsEncrypted, IsOneToOne, RoomNotificationMode}, Result, room::power_levels::{RoomPowerLevelChanges, RoomPowerLevelsExt}, RoomState, sync::RoomUpdate, TransmissionProgress, utils::{IntoRawMessageLikeEventContent, IntoRawStateEventContent}, -}; -#[cfg(doc)] -use crate::event_cache::EventCache; - -pub use self::{ - member::{RoomMember, RoomMemberRole}, - messages::{Messages, MessagesOptions}, + media::{MediaFormat, MediaRequest}, + notification_settings::{IsEncrypted, IsOneToOne, RoomNotificationMode}, + room::power_levels::{RoomPowerLevelChanges, RoomPowerLevelsExt}, + sync::RoomUpdate, + utils::{IntoRawMessageLikeEventContent, IntoRawStateEventContent}, + BaseRoom, Client, Error, HttpError, HttpResult, Result, RoomState, TransmissionProgress, }; -use self::futures::{SendAttachment, SendMessageLikeEvent, SendRawMessageLikeEvent}; pub mod futures; mod member; diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index 442ee5b67f1..edbb039095b 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -370,6 +370,8 @@ async fn room_attachment_send() { let response = room .send_attachment( + None, + None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), @@ -426,7 +428,7 @@ async fn room_attachment_send_info() { })); let response = room - .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) + .send_attachment(None, None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) .await .unwrap(); @@ -479,7 +481,7 @@ async fn room_attachment_send_wrong_info() { })); let response = - room.send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config).await; + room.send_attachment(None, None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config).await; response.unwrap_err(); } @@ -546,7 +548,7 @@ async fn room_attachment_send_info_thumbnail() { })); let response = room - .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) + .send_attachment(None, None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) .await .unwrap(); diff --git a/examples/image_bot/src/main.rs b/examples/image_bot/src/main.rs index 10e5515a919..e16db136855 100644 --- a/examples/image_bot/src/main.rs +++ b/examples/image_bot/src/main.rs @@ -17,7 +17,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, image: if text_content.body.contains("!image") { println!("sending image"); - room.send_attachment("cat", &mime::IMAGE_JPEG, image, AttachmentConfig::new()) + room.send_attachment(None, None, "cat", &mime::IMAGE_JPEG, image, AttachmentConfig::new()) .await .unwrap(); From e21a0d21d9e22d34db30689f5bcc824dc51e4fef Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 10:37:40 +0100 Subject: [PATCH 05/17] fix missing parameters in documentation --- crates/matrix-sdk/src/attachment.rs | 2 ++ crates/matrix-sdk/src/room/mod.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/crates/matrix-sdk/src/attachment.rs b/crates/matrix-sdk/src/attachment.rs index 9a3b1b59b5d..66494b72e33 100644 --- a/crates/matrix-sdk/src/attachment.rs +++ b/crates/matrix-sdk/src/attachment.rs @@ -332,6 +332,8 @@ impl Default for AttachmentConfig { /// if let Some(room) = client.get_room(&room_id) { /// room.send_attachment( /// "My favorite cat", +/// None, +/// "my_favorite_cat.jpg", /// &mime::IMAGE_JPEG, /// image, /// config, diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index df688ced440..66b8b94700b 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1724,6 +1724,8 @@ impl Room { /// if let Some(room) = client.get_room(&room_id) { /// room.send_attachment( /// "My favorite cat", + /// None, + /// "my_favorite_cat.jpg", /// &mime::IMAGE_JPEG, /// image, /// AttachmentConfig::new(), From e165e1c93c77edf2625519d9960bc26a302c0187 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 11:04:55 +0100 Subject: [PATCH 06/17] fix formatting --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 54 +++++++++++++++---- crates/matrix-sdk-ui/src/timeline/futures.rs | 11 +++- crates/matrix-sdk-ui/src/timeline/mod.rs | 4 +- crates/matrix-sdk/src/encryption/mod.rs | 12 ++--- crates/matrix-sdk/src/media.rs | 6 +-- crates/matrix-sdk/src/room/futures.rs | 34 ++++++++++-- crates/matrix-sdk/src/room/mod.rs | 19 ++++--- .../tests/integration/room/joined.rs | 5 +- 8 files changed, 106 insertions(+), 39 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 8de9cfd0844..080c3888810 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -39,7 +39,7 @@ use ruma::{ relation::Annotation, room::message::{ FormattedBody as RumaFormattedBody, ForwardThread, LocationMessageEventContent, - MessageType, RoomMessageEventContentWithoutRelation + MessageType, RoomMessageEventContentWithoutRelation, }, AnyMessageLikeEventContent, }, @@ -52,17 +52,19 @@ use tokio::{ use tracing::{error, info, warn}; use uuid::Uuid; +use self::content::{Reaction, ReactionSenderData, TimelineItemContent}; use crate::{ client::ProgressWatcher, error::{ClientError, RoomError}, helpers::unwrap_or_clone_arc, - ruma::{AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, VideoInfo}, + ruma::{ + AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, + VideoInfo, + }, task_handle::TaskHandle, RUNTIME, }; -use self::content::{Reaction, ReactionSenderData, TimelineItemContent}; - mod content; #[derive(uniffi::Object)] @@ -115,9 +117,10 @@ impl Timeline { ) -> Result<(), RoomError> { let formatted: Option = match formatted { Some(p) => Some(RumaFormattedBody::from(p)), - None => None + None => None, }; - let request = self.inner.send_attachment(caption, formatted, url, mime_type, attachment_config); + let request = + self.inner.send_attachment(caption, formatted, url, mime_type, attachment_config); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); RUNTIME.spawn(async move { @@ -248,7 +251,14 @@ impl Timeline { _ => AttachmentConfig::new().info(attachment_info), }; - self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await + self.send_attachment( + caption, + formatted, + url, + mime_type, + attachment_config, + progress_watcher + ).await })) } @@ -281,7 +291,14 @@ impl Timeline { _ => AttachmentConfig::new().info(attachment_info), }; - self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await + self.send_attachment( + caption, + formatted, + url, + mime_type, + attachment_config, + progress_watcher + ).await })) } @@ -305,7 +322,14 @@ impl Timeline { let attachment_info = AttachmentInfo::Audio(base_audio_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await + self.send_attachment( + caption, + formatted, + url, + mime_type, + attachment_config, + progress_watcher + ).await })) } @@ -331,7 +355,14 @@ impl Timeline { AttachmentInfo::Voice { audio_info: base_audio_info, waveform: Some(waveform) }; let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(caption, formatted, url, mime_type, attachment_config, progress_watcher).await + self.send_attachment( + caption, + formatted, + url, + mime_type, + attachment_config, + progress_watcher + ).await })) } @@ -353,7 +384,8 @@ impl Timeline { let attachment_info = AttachmentInfo::File(base_file_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(None, None, url, mime_type, attachment_config, progress_watcher).await + self.send_attachment(None, None, url, mime_type, attachment_config, progress_watcher) + .await })) } diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 9c2a7d19806..9ae56ca12f1 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -54,7 +54,16 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { timeline, caption, formatted, url, mime_type, config, tracing_span, send_progress } = self; + let Self { + timeline, + caption, + formatted, + url, + mime_type, + config, + tracing_span, + send_progress + } = self; let fut = async move { let urlbody = Path::new(&url) .file_name() diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index a1f05c55105..27132dc0972 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -45,7 +45,9 @@ use ruma::{ relation::Annotation, room::{ message::{ - AddMentions, FormattedBody, ForwardThread, OriginalRoomMessageEvent, ReplacementMetadata, RoomMessageEventContent, RoomMessageEventContentWithoutRelation + AddMentions, FormattedBody, ForwardThread, OriginalRoomMessageEvent, + ReplacementMetadata, RoomMessageEventContent, + RoomMessageEventContentWithoutRelation, }, redaction::RoomRedactionEventContent, }, diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index e3ce381d6ec..446b267adc5 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -50,7 +50,7 @@ use ruma::{ events::room::{ message::{ AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, - ImageMessageEventContent, MessageType, VideoInfo, VideoMessageEventContent + ImageMessageEventContent, MessageType, VideoInfo, VideoMessageEventContent, }, ImageInfo, MediaSource, ThumbnailInfo, }, @@ -330,7 +330,7 @@ impl Client { }; let filename = match &caption { Some(p) => Some(String::from(p)), - None => None + None => None, }; Ok(match content_type.type_() { @@ -1449,10 +1449,11 @@ impl Encryption { #[cfg(all(test, not(target_arch = "wasm32")))] mod tests { + use std::time::Duration; use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ - async_test, DEFAULT_TEST_ROOM_ID, GlobalAccountDataTestEvent, JoinedRoomBuilder, StateTestEvent, - SyncResponseBuilder, test_json, + async_test, test_json, GlobalAccountDataTestEvent, JoinedRoomBuilder, StateTestEvent, + SyncResponseBuilder, DEFAULT_TEST_ROOM_ID, }; use ruma::{ device_id, event_id, @@ -1460,17 +1461,16 @@ mod tests { user_id, }; use serde_json::json; - use std::time::Duration; use wiremock::{ matchers::{header, method, path_regex}, Mock, MockServer, ResponseTemplate, }; use crate::{ - Client, config::RequestConfig, matrix_auth::{MatrixSession, MatrixSessionTokens}, test_utils::logged_in_client, + Client, }; #[async_test] diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index 07856126478..1cc782aad6c 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -32,7 +32,7 @@ use ruma::{ message::{ self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, - UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent + UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent, }, ImageInfo, MediaSource, ThumbnailInfo, }, @@ -468,7 +468,7 @@ impl Media { }; let filename = match &caption { Some(_) => Some(String::from(url)), - None => None + None => None, }; let url = response.content_uri; @@ -507,7 +507,7 @@ impl Media { VideoMessageEventContent::plain(body.to_owned(), url) .info(Box::new(info)) .filename(filename) - .formatted(formatted) + .formatted(formatted), ) } _ => { diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index 28c19bcf7fe..8420b8dc011 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -266,11 +266,28 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { room, caption, formatted, url, content_type, data, config, tracing_span, send_progress } = self; + let Self { + room, + caption, + formatted, + url, + content_type, + data, + config, + tracing_span, + send_progress + } = self; let fut = async move { if config.thumbnail.is_some() { - room.prepare_and_send_attachment(caption, formatted, url, content_type, data, config, send_progress) - .await + room.prepare_and_send_attachment( + caption, + formatted, + url, + content_type, + data, + config, + send_progress + ).await } else { #[cfg(not(feature = "image-proc"))] let thumbnail = None; @@ -328,8 +345,15 @@ impl<'a> IntoFuture for SendAttachment<'a> { thumbnail_size: None, }; - room.prepare_and_send_attachment(caption, formatted, url, content_type, data, config, send_progress) - .await + room.prepare_and_send_attachment( + caption, + formatted, + url, + content_type, + data, + config, + send_progress + ).await } }; diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 66b8b94700b..c681ef823ec 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1421,7 +1421,7 @@ impl Room { #[instrument(skip_all)] pub async fn enable_encryption(&self) -> Result<()> { use ruma::{ - EventEncryptionAlgorithm, events::room::encryption::RoomEncryptionEventContent, + events::room::encryption::RoomEncryptionEventContent, EventEncryptionAlgorithm, }; const SYNC_WAIT_TIME: Duration = Duration::from_secs(3); @@ -1695,8 +1695,8 @@ impl Room { /// * `caption` - An optional caption of the media that is going to be /// uploaded. /// - /// * `formatted` - A optional formatted caption of the media that is going to be - /// uploaded. + /// * `formatted` - A optional formatted caption of the media that is going + /// to be uploaded. /// /// * `url` - The file name. /// @@ -1764,8 +1764,8 @@ impl Room { /// * `caption` - An optional caption of the media that is going to be /// uploaded. /// - /// * `formatted` - A optional formatted caption of the media that is going to be - /// uploaded. + /// * `formatted` - A optional formatted caption of the media that is going + /// to be uploaded. /// /// * `url` - The file name. /// @@ -2871,7 +2871,7 @@ pub struct TryFromReportedContentScoreError(()); mod tests { use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ - async_test, JoinedRoomBuilder, StateTestEvent, SyncResponseBuilder, test_json, + async_test, test_json, JoinedRoomBuilder, StateTestEvent, SyncResponseBuilder, }; use ruma::{device_id, int, user_id}; use wiremock::{ @@ -2879,18 +2879,17 @@ mod tests { Mock, MockServer, ResponseTemplate, }; + use super::ReportedContentScore; use crate::{ - Client, config::RequestConfig, matrix_auth::{MatrixSession, MatrixSessionTokens}, + Client, }; - use super::ReportedContentScore; - #[cfg(all(feature = "sqlite", feature = "e2e-encryption"))] #[async_test] async fn test_cache_invalidation_while_encrypt() { - use matrix_sdk_test::{DEFAULT_TEST_ROOM_ID, message_like_event_content}; + use matrix_sdk_test::{message_like_event_content, DEFAULT_TEST_ROOM_ID}; let sqlite_path = std::env::temp_dir().join("cache_invalidation_while_encrypt.db"); let session = MatrixSession { diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index edbb039095b..d624061bb35 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -480,8 +480,9 @@ async fn room_attachment_send_wrong_info() { blurhash: None, })); - let response = - room.send_attachment(None, None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config).await; + let response = room + .send_attachment(Some("image caption".to_string()), None, "image.jpg", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) + .await; response.unwrap_err(); } From 74ca82151232196fdfb1accaf246f4e946c83ed8 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 11:51:41 +0100 Subject: [PATCH 07/17] move optional parameters to the end --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 40 +++++++++--------- crates/matrix-sdk-ui/src/timeline/futures.rs | 18 ++++---- crates/matrix-sdk-ui/src/timeline/mod.rs | 15 +++---- crates/matrix-sdk/src/encryption/mod.rs | 15 +++---- crates/matrix-sdk/src/media.rs | 16 ++++--- crates/matrix-sdk/src/room/futures.rs | 24 +++++------ crates/matrix-sdk/src/room/mod.rs | 42 +++++++++---------- .../tests/integration/room/joined.rs | 18 +++++--- examples/image_bot/src/main.rs | 2 +- 9 files changed, 96 insertions(+), 94 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 080c3888810..2394ca70758 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -108,11 +108,11 @@ impl Timeline { async fn send_attachment( &self, - caption: Option, - formatted: Option, url: String, mime_type: Mime, attachment_config: AttachmentConfig, + caption: Option, + formatted: Option, progress_watcher: Option>, ) -> Result<(), RoomError> { let formatted: Option = match formatted { @@ -120,7 +120,7 @@ impl Timeline { None => None, }; let request = - self.inner.send_attachment(caption, formatted, url, mime_type, attachment_config); + self.inner.send_attachment(url, mime_type, attachment_config, caption, formatted); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); RUNTIME.spawn(async move { @@ -224,11 +224,11 @@ impl Timeline { pub fn send_image( self: Arc, - caption: Option, - formatted: Option, url: String, thumbnail_url: Option, image_info: ImageInfo, + caption: Option, + formatted: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -252,11 +252,11 @@ impl Timeline { }; self.send_attachment( - caption, - formatted, url, mime_type, attachment_config, + caption, + formatted, progress_watcher ).await })) @@ -264,11 +264,11 @@ impl Timeline { pub fn send_video( self: Arc, - caption: Option, - formatted: Option, url: String, thumbnail_url: Option, video_info: VideoInfo, + caption: Option, + formatted: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -292,11 +292,11 @@ impl Timeline { }; self.send_attachment( - caption, - formatted, url, mime_type, attachment_config, + caption, + formatted, progress_watcher ).await })) @@ -304,10 +304,10 @@ impl Timeline { pub fn send_audio( self: Arc, - caption: Option, - formatted: Option, url: String, audio_info: AudioInfo, + caption: Option, + formatted: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -323,11 +323,11 @@ impl Timeline { let attachment_config = AttachmentConfig::new().info(attachment_info); self.send_attachment( - caption, - formatted, url, mime_type, attachment_config, + caption, + formatted, progress_watcher ).await })) @@ -335,11 +335,11 @@ impl Timeline { pub fn send_voice_message( self: Arc, - caption: Option, - formatted: Option, url: String, audio_info: AudioInfo, waveform: Vec, + caption: Option, + formatted: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -356,11 +356,11 @@ impl Timeline { let attachment_config = AttachmentConfig::new().info(attachment_info); self.send_attachment( - caption, - formatted, url, mime_type, attachment_config, + caption, + formatted, progress_watcher ).await })) @@ -384,7 +384,7 @@ impl Timeline { let attachment_info = AttachmentInfo::File(base_file_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(None, None, url, mime_type, attachment_config, progress_watcher) + self.send_attachment(url, mime_type, attachment_config, None, None, progress_watcher) .await })) } diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 9ae56ca12f1..6e0e915a99f 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -11,11 +11,11 @@ use super::{Error, Timeline}; pub struct SendAttachment<'a> { timeline: &'a Timeline, - caption: Option, - formatted: Option, url: String, mime_type: Mime, config: AttachmentConfig, + caption: Option, + formatted: Option, tracing_span: Span, pub(crate) send_progress: SharedObservable, } @@ -23,19 +23,19 @@ pub struct SendAttachment<'a> { impl<'a> SendAttachment<'a> { pub(crate) fn new( timeline: &'a Timeline, - caption: Option, - formatted: Option, url: String, mime_type: Mime, config: AttachmentConfig, + caption: Option, + formatted: Option, ) -> Self { Self { timeline, - caption, - formatted, url, mime_type, config, + caption, + formatted, tracing_span: Span::current(), send_progress: Default::default(), } @@ -56,11 +56,11 @@ impl<'a> IntoFuture for SendAttachment<'a> { fn into_future(self) -> Self::IntoFuture { let Self { timeline, - caption, - formatted, url, mime_type, config, + caption, + formatted, tracing_span, send_progress } = self; @@ -74,7 +74,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { timeline .room() - .send_attachment(caption, formatted, urlbody, &mime_type, data, config) + .send_attachment(urlbody, &mime_type, data, config, caption, formatted) .with_send_progress_observable(send_progress) .await .map_err(|_| Error::FailedSendingAttachment)?; diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index 27132dc0972..57973336515 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -514,27 +514,28 @@ impl Timeline { /// /// # Arguments /// - /// * `caption` - The url for the file to be sent - /// - /// * `formatted` - The url for the file to be sent - /// /// * `url` - The url for the file to be sent /// /// * `mime_type` - The attachment's mime type /// /// * `config` - An attachment configuration object containing details about /// the attachment + /// + /// * `caption` - An optional caption of this attachment + /// + /// * `formatted` - An optional formatted caption of this attachment + /// /// like a thumbnail, its size, duration etc. #[instrument(skip_all)] pub fn send_attachment( &self, - caption: Option, - formatted: Option, url: String, mime_type: Mime, config: AttachmentConfig, + caption: Option, + formatted: Option, ) -> SendAttachment<'_> { - SendAttachment::new(self, caption, formatted, url, mime_type, config) + SendAttachment::new(self, url, mime_type, config, caption, formatted) } /// Retry sending a message that previously failed to send. diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index 446b267adc5..191ba113857 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -302,13 +302,13 @@ impl Client { /// optionanly with `formatted` and `filename`. pub(crate) async fn prepare_encrypted_attachment_message( &self, - caption: Option, - formatted: Option, url: &str, content_type: &mime::Mime, data: Vec, info: Option, thumbnail: Option, + caption: Option, + formatted: Option, send_progress: SharedObservable, ) -> Result { let upload_thumbnail = @@ -324,13 +324,10 @@ impl Client { let ((thumbnail_source, thumbnail_info), file) = try_join(upload_thumbnail, upload_attachment).await?; - let body: &str = match &caption { - Some(p) => p, - None => url, - }; - let filename = match &caption { - Some(p) => Some(String::from(p)), - None => None, + let url = url.to_owned(); + let (body, filename) = match caption { + Some(caption) => (caption, Some(url)), + None => (url, None), }; Ok(match content_type.type_() { diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index 1cc782aad6c..3cd0bfe4b02 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -441,13 +441,13 @@ impl Media { /// optionally with `formatted` and `filename`. pub(crate) async fn prepare_attachment_message( &self, - caption: Option, - formatted: Option, url: &str, content_type: &Mime, data: Vec, info: Option, thumbnail: Option, + caption: Option, + formatted: Option, send_progress: SharedObservable, ) -> Result { let upload_thumbnail = self.upload_thumbnail(thumbnail, send_progress.clone()); @@ -462,14 +462,12 @@ impl Media { let ((thumbnail_source, thumbnail_info), response) = try_join(upload_thumbnail, upload_attachment).await?; - let body: &str = match &caption { - Some(p) => p, - None => url, - }; - let filename = match &caption { - Some(_) => Some(String::from(url)), - None => None, + let url = url.to_owned(); + let (body, filename)= match caption { + Some(caption) => (caption, Some(url)), + None => (url, None), }; + let url = response.content_uri; Ok(match content_type.type_() { diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index 8420b8dc011..e015991c104 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -216,12 +216,12 @@ impl<'a> IntoFuture for SendRawMessageLikeEvent<'a> { #[allow(missing_debug_implementations)] pub struct SendAttachment<'a> { room: &'a Room, - caption: Option, - formatted: Option, url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, + caption: Option, + formatted: Option, tracing_span: Span, send_progress: SharedObservable, } @@ -229,21 +229,21 @@ pub struct SendAttachment<'a> { impl<'a> SendAttachment<'a> { pub(crate) fn new( room: &'a Room, - caption: Option, - formatted: Option, url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, + caption: Option, + formatted: Option, ) -> Self { Self { room, - caption, - formatted, url, content_type, data, config, + caption, + formatted, tracing_span: Span::current(), send_progress: Default::default(), } @@ -268,24 +268,24 @@ impl<'a> IntoFuture for SendAttachment<'a> { fn into_future(self) -> Self::IntoFuture { let Self { room, - caption, - formatted, url, content_type, data, config, + caption, + formatted, tracing_span, send_progress } = self; let fut = async move { if config.thumbnail.is_some() { room.prepare_and_send_attachment( - caption, - formatted, url, content_type, data, config, + caption, + formatted, send_progress ).await } else { @@ -346,12 +346,12 @@ impl<'a> IntoFuture for SendAttachment<'a> { }; room.prepare_and_send_attachment( - caption, - formatted, url, content_type, data, config, + caption, + formatted, send_progress ).await } diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index c681ef823ec..a1c73635897 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1692,12 +1692,6 @@ impl Room { /// [`upload()`] and afterwards the [`send()`]. /// /// # Arguments - /// * `caption` - An optional caption of the media that is going to be - /// uploaded. - /// - /// * `formatted` - A optional formatted caption of the media that is going - /// to be uploaded. - /// /// * `url` - The file name. /// /// * `content_type` - The type of the media, this will be used as the @@ -1708,6 +1702,12 @@ impl Room { /// /// * `config` - Metadata and configuration for the attachment. /// + /// * `caption` - An optional caption of the media that is going to be + /// uploaded. + /// + /// * `formatted` - A optional formatted caption of the media that is going + /// to be uploaded. + /// /// # Examples /// /// ```no_run @@ -1739,14 +1739,14 @@ impl Room { #[instrument(skip_all)] pub fn send_attachment<'a>( &'a self, - caption: Option, - formatted: Option, url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, + caption: Option, + formatted: Option, ) -> SendAttachment<'a> { - SendAttachment::new(self, caption, formatted, url, content_type, data, config) + SendAttachment::new(self, url, content_type, data, config, caption, formatted) } /// Prepare and send an attachment to this room. @@ -1761,12 +1761,6 @@ impl Room { /// [`send()`](#method.send). /// /// # Arguments - /// * `caption` - An optional caption of the media that is going to be - /// uploaded. - /// - /// * `formatted` - A optional formatted caption of the media that is going - /// to be uploaded. - /// /// * `url` - The file name. /// /// * `content_type` - The type of the media, this will be used as the @@ -1776,14 +1770,20 @@ impl Room { /// media. /// /// * `config` - Metadata and configuration for the attachment. + /// + /// * `caption` - An optional caption of the media that is going to be + /// uploaded. + /// + /// * `formatted` - A optional formatted caption of the media that is going + /// to be uploaded. pub(super) async fn prepare_and_send_attachment<'a>( &'a self, - caption: Option, - formatted: Option, url: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, + caption: Option, + formatted: Option, send_progress: SharedObservable, ) -> Result { self.ensure_room_joined()?; @@ -1792,13 +1792,13 @@ impl Room { let content = if self.is_encrypted().await? { self.client .prepare_encrypted_attachment_message( - caption, - formatted, url, content_type, data, config.info, config.thumbnail, + caption, + formatted, send_progress, ) .await? @@ -1806,13 +1806,13 @@ impl Room { self.client .media() .prepare_attachment_message( - caption, - formatted, url, content_type, data, config.info, config.thumbnail, + caption, + formatted, send_progress, ) .await? diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index d624061bb35..9a9256955e7 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -370,12 +370,12 @@ async fn room_attachment_send() { let response = room .send_attachment( - None, - None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), AttachmentConfig::new(), + None, + None, ) .await .unwrap(); @@ -428,7 +428,7 @@ async fn room_attachment_send_info() { })); let response = room - .send_attachment(None, None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) + .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, None, None) .await .unwrap(); @@ -481,8 +481,14 @@ async fn room_attachment_send_wrong_info() { })); let response = room - .send_attachment(Some("image caption".to_string()), None, "image.jpg", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) - .await; + .send_attachment( + "image.jpg", + &mime::IMAGE_JPEG, + b"Hello world".to_vec(), + config, + Some("image caption".to_string()), + None + ).await; response.unwrap_err(); } @@ -549,7 +555,7 @@ async fn room_attachment_send_info_thumbnail() { })); let response = room - .send_attachment(None, None, "image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) + .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, None, None, ) .await .unwrap(); diff --git a/examples/image_bot/src/main.rs b/examples/image_bot/src/main.rs index e16db136855..b75dd3ea9a8 100644 --- a/examples/image_bot/src/main.rs +++ b/examples/image_bot/src/main.rs @@ -17,7 +17,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, image: if text_content.body.contains("!image") { println!("sending image"); - room.send_attachment(None, None, "cat", &mime::IMAGE_JPEG, image, AttachmentConfig::new()) + room.send_attachment("cat", &mime::IMAGE_JPEG, image, AttachmentConfig::new(), None, None) .await .unwrap(); From 24931fe043b7198459434d6c0475bd36ff535b2b Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 12:17:51 +0100 Subject: [PATCH 08/17] more formatting fixes --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 58 ++++++++++--------- crates/matrix-sdk-ui/src/timeline/futures.rs | 16 ++--- crates/matrix-sdk-ui/src/timeline/mod.rs | 2 +- crates/matrix-sdk/src/encryption/mod.rs | 5 +- crates/matrix-sdk/src/media.rs | 6 +- crates/matrix-sdk/src/room/futures.rs | 46 +++++++-------- crates/matrix-sdk/src/room/mod.rs | 8 +-- .../tests/integration/room/joined.rs | 14 ++--- 8 files changed, 80 insertions(+), 75 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 2394ca70758..d9927aec58b 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -58,7 +58,7 @@ use crate::{ error::{ClientError, RoomError}, helpers::unwrap_or_clone_arc, ruma::{ - AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, + AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, VideoInfo, }, task_handle::TaskHandle, @@ -119,7 +119,7 @@ impl Timeline { Some(p) => Some(RumaFormattedBody::from(p)), None => None, }; - let request = + let request = self.inner.send_attachment(url, mime_type, attachment_config, caption, formatted); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); @@ -252,13 +252,14 @@ impl Timeline { }; self.send_attachment( - url, - mime_type, - attachment_config, + url, + mime_type, + attachment_config, caption, - formatted, - progress_watcher - ).await + formatted, + progress_watcher, + ) + .await })) } @@ -292,13 +293,14 @@ impl Timeline { }; self.send_attachment( - url, - mime_type, - attachment_config, - caption, + url, + mime_type, + attachment_config, + caption, formatted, - progress_watcher - ).await + progress_watcher, + ) + .await })) } @@ -323,13 +325,14 @@ impl Timeline { let attachment_config = AttachmentConfig::new().info(attachment_info); self.send_attachment( - url, - mime_type, - attachment_config, - caption, - formatted, - progress_watcher - ).await + url, + mime_type, + attachment_config, + caption, + formatted, + progress_watcher, + ) + .await })) } @@ -357,12 +360,13 @@ impl Timeline { self.send_attachment( url, - mime_type, - attachment_config, - caption, - formatted, - progress_watcher - ).await + mime_type, + attachment_config, + caption, + formatted, + progress_watcher, + ) + .await })) } diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 6e0e915a99f..d5ef74ef971 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -55,14 +55,14 @@ impl<'a> IntoFuture for SendAttachment<'a> { fn into_future(self) -> Self::IntoFuture { let Self { - timeline, - url, - mime_type, - config, - caption, - formatted, - tracing_span, - send_progress + timeline, + url, + mime_type, + config, + caption, + formatted, + tracing_span, + send_progress, } = self; let fut = async move { let urlbody = Path::new(&url) diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index 57973336515..c23d0ba31a9 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -520,7 +520,7 @@ impl Timeline { /// /// * `config` - An attachment configuration object containing details about /// the attachment - /// + /// /// * `caption` - An optional caption of this attachment /// /// * `formatted` - An optional formatted caption of this attachment diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index 191ba113857..1efee6756ff 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -49,7 +49,7 @@ use ruma::{ assign, events::room::{ message::{ - AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, + AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, ImageMessageEventContent, MessageType, VideoInfo, VideoMessageEventContent, }, ImageInfo, MediaSource, ThumbnailInfo, @@ -329,7 +329,7 @@ impl Client { Some(caption) => (caption, Some(url)), None => (url, None), }; - + Ok(match content_type.type_() { mime::IMAGE => { let info = assign!(info.map(ImageInfo::from).unwrap_or_default(), { @@ -1447,6 +1447,7 @@ impl Encryption { #[cfg(all(test, not(target_arch = "wasm32")))] mod tests { use std::time::Duration; + use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ async_test, test_json, GlobalAccountDataTestEvent, JoinedRoomBuilder, StateTestEvent, diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index 3cd0bfe4b02..d07246fb3f7 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -30,8 +30,8 @@ use ruma::{ assign, events::room::{ message::{ - self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, - FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, + self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, + FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent, }, ImageInfo, MediaSource, ThumbnailInfo, @@ -463,7 +463,7 @@ impl Media { try_join(upload_thumbnail, upload_attachment).await?; let url = url.to_owned(); - let (body, filename)= match caption { + let (body, filename) = match caption { Some(caption) => (caption, Some(url)), None => (url, None), }; diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index e015991c104..2527be139b2 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -267,26 +267,26 @@ impl<'a> IntoFuture for SendAttachment<'a> { fn into_future(self) -> Self::IntoFuture { let Self { - room, - url, - content_type, - data, - config, - caption, - formatted, - tracing_span, - send_progress + room, + url, + content_type, + data, + config, + caption, + formatted, + tracing_span, + send_progress, } = self; let fut = async move { if config.thumbnail.is_some() { room.prepare_and_send_attachment( - url, - content_type, - data, - config, - caption, - formatted, - send_progress + url, + content_type, + data, + config, + caption, + formatted, + send_progress, ).await } else { #[cfg(not(feature = "image-proc"))] @@ -346,13 +346,13 @@ impl<'a> IntoFuture for SendAttachment<'a> { }; room.prepare_and_send_attachment( - url, - content_type, - data, - config, - caption, - formatted, - send_progress + url, + content_type, + data, + config, + caption, + formatted, + send_progress, ).await } }; diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index a1c73635897..1e01ab55b5d 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1421,7 +1421,7 @@ impl Room { #[instrument(skip_all)] pub async fn enable_encryption(&self) -> Result<()> { use ruma::{ - events::room::encryption::RoomEncryptionEventContent, EventEncryptionAlgorithm, + events::room::encryption::RoomEncryptionEventContent, EventEncryptionAlgorithm, }; const SYNC_WAIT_TIME: Duration = Duration::from_secs(3); @@ -1705,7 +1705,7 @@ impl Room { /// * `caption` - An optional caption of the media that is going to be /// uploaded. /// - /// * `formatted` - A optional formatted caption of the media that is going + /// * `formatted` - A optional formatted caption of the media that is going /// to be uploaded. /// /// # Examples @@ -1770,7 +1770,7 @@ impl Room { /// media. /// /// * `config` - Metadata and configuration for the attachment. - /// + /// /// * `caption` - An optional caption of the media that is going to be /// uploaded. /// @@ -2871,7 +2871,7 @@ pub struct TryFromReportedContentScoreError(()); mod tests { use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ - async_test, test_json, JoinedRoomBuilder, StateTestEvent, SyncResponseBuilder, + async_test, test_json, JoinedRoomBuilder, StateTestEvent, SyncResponseBuilder, }; use ruma::{device_id, int, user_id}; use wiremock::{ diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index 9a9256955e7..7207b36cd6b 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -482,12 +482,12 @@ async fn room_attachment_send_wrong_info() { let response = room .send_attachment( - "image.jpg", - &mime::IMAGE_JPEG, - b"Hello world".to_vec(), - config, - Some("image caption".to_string()), - None + "image.jpg", + &mime::IMAGE_JPEG, + b"Hello world".to_vec(), + config, + Some("image caption".to_string()), + None, ).await; response.unwrap_err(); @@ -555,7 +555,7 @@ async fn room_attachment_send_info_thumbnail() { })); let response = room - .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, None, None, ) + .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, None, None) .await .unwrap(); From 4c6fa670750bfd6df3bc4dc9ba7d10b0c7d43ac9 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 12:20:47 +0100 Subject: [PATCH 09/17] more formatting fixes --- crates/matrix-sdk-ui/src/timeline/futures.rs | 2 +- crates/matrix-sdk/src/encryption/mod.rs | 2 +- crates/matrix-sdk/src/room/futures.rs | 8 +++++--- crates/matrix-sdk/tests/integration/room/joined.rs | 3 ++- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index d5ef74ef971..99a46dd1573 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -54,7 +54,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { + let Self { timeline, url, mime_type, diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index 1efee6756ff..d5bd4e11fbc 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -1447,7 +1447,7 @@ impl Encryption { #[cfg(all(test, not(target_arch = "wasm32")))] mod tests { use std::time::Duration; - + use matrix_sdk_base::SessionMeta; use matrix_sdk_test::{ async_test, test_json, GlobalAccountDataTestEvent, JoinedRoomBuilder, StateTestEvent, diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index 2527be139b2..6d6945c7f21 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -266,7 +266,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { + let Self { room, url, content_type, @@ -287,7 +287,8 @@ impl<'a> IntoFuture for SendAttachment<'a> { caption, formatted, send_progress, - ).await + ) + .await } else { #[cfg(not(feature = "image-proc"))] let thumbnail = None; @@ -353,7 +354,8 @@ impl<'a> IntoFuture for SendAttachment<'a> { caption, formatted, send_progress, - ).await + ) + .await } }; diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index 7207b36cd6b..4539d7ae64a 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -488,7 +488,8 @@ async fn room_attachment_send_wrong_info() { config, Some("image caption".to_string()), None, - ).await; + ) + .await; response.unwrap_err(); } From 76d58dca4df57bd47f2b52f8032b35ae68d7c807 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 12:37:14 +0100 Subject: [PATCH 10/17] rename url parameter to filename in send_attachment and helpers --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 4 ++-- crates/matrix-sdk-ui/src/timeline/futures.rs | 14 ++++++------- crates/matrix-sdk-ui/src/timeline/mod.rs | 6 +++--- crates/matrix-sdk/src/encryption/mod.rs | 8 +++---- crates/matrix-sdk/src/media.rs | 8 +++---- crates/matrix-sdk/src/room/mod.rs | 22 +++++++++++--------- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index d9927aec58b..0d0838f9d3b 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -108,7 +108,7 @@ impl Timeline { async fn send_attachment( &self, - url: String, + filename: String, mime_type: Mime, attachment_config: AttachmentConfig, caption: Option, @@ -120,7 +120,7 @@ impl Timeline { None => None, }; let request = - self.inner.send_attachment(url, mime_type, attachment_config, caption, formatted); + self.inner.send_attachment(filename, mime_type, attachment_config, caption, formatted); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); RUNTIME.spawn(async move { diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 99a46dd1573..624c0ea1d99 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -11,7 +11,7 @@ use super::{Error, Timeline}; pub struct SendAttachment<'a> { timeline: &'a Timeline, - url: String, + filename: String, mime_type: Mime, config: AttachmentConfig, caption: Option, @@ -23,7 +23,7 @@ pub struct SendAttachment<'a> { impl<'a> SendAttachment<'a> { pub(crate) fn new( timeline: &'a Timeline, - url: String, + filename: String, mime_type: Mime, config: AttachmentConfig, caption: Option, @@ -31,7 +31,7 @@ impl<'a> SendAttachment<'a> { ) -> Self { Self { timeline, - url, + filename, mime_type, config, caption, @@ -56,7 +56,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { fn into_future(self) -> Self::IntoFuture { let Self { timeline, - url, + filename, mime_type, config, caption, @@ -65,16 +65,16 @@ impl<'a> IntoFuture for SendAttachment<'a> { send_progress, } = self; let fut = async move { - let urlbody = Path::new(&url) + let body = Path::new(&filename) .file_name() .ok_or(Error::InvalidAttachmentFileName)? .to_str() .expect("path was created from UTF-8 string, hence filename part is UTF-8 too"); - let data = fs::read(&url).map_err(|_| Error::InvalidAttachmentData)?; + let data = fs::read(&filename).map_err(|_| Error::InvalidAttachmentData)?; timeline .room() - .send_attachment(urlbody, &mime_type, data, config, caption, formatted) + .send_attachment(body, &mime_type, data, config, caption, formatted) .with_send_progress_observable(send_progress) .await .map_err(|_| Error::FailedSendingAttachment)?; diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index c23d0ba31a9..076e58363b9 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -514,7 +514,7 @@ impl Timeline { /// /// # Arguments /// - /// * `url` - The url for the file to be sent + /// * `filename` - The filename of the file to be sent /// /// * `mime_type` - The attachment's mime type /// @@ -529,13 +529,13 @@ impl Timeline { #[instrument(skip_all)] pub fn send_attachment( &self, - url: String, + filename: String, mime_type: Mime, config: AttachmentConfig, caption: Option, formatted: Option, ) -> SendAttachment<'_> { - SendAttachment::new(self, url, mime_type, config, caption, formatted) + SendAttachment::new(self, filename, mime_type, config, caption, formatted) } /// Retry sending a message that previously failed to send. diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index d5bd4e11fbc..ab172595379 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -302,7 +302,7 @@ impl Client { /// optionanly with `formatted` and `filename`. pub(crate) async fn prepare_encrypted_attachment_message( &self, - url: &str, + filename: &str, content_type: &mime::Mime, data: Vec, info: Option, @@ -324,10 +324,10 @@ impl Client { let ((thumbnail_source, thumbnail_info), file) = try_join(upload_thumbnail, upload_attachment).await?; - let url = url.to_owned(); + let filename = filename.to_owned(); let (body, filename) = match caption { - Some(caption) => (caption, Some(url)), - None => (url, None), + Some(caption) => (caption, Some(filename)), + None => (filename, None), }; Ok(match content_type.type_() { diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index d07246fb3f7..b02feae9aa0 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -441,7 +441,7 @@ impl Media { /// optionally with `formatted` and `filename`. pub(crate) async fn prepare_attachment_message( &self, - url: &str, + filename: &str, content_type: &Mime, data: Vec, info: Option, @@ -462,10 +462,10 @@ impl Media { let ((thumbnail_source, thumbnail_info), response) = try_join(upload_thumbnail, upload_attachment).await?; - let url = url.to_owned(); + let filename = filename.to_owned(); let (body, filename) = match caption { - Some(caption) => (caption, Some(url)), - None => (url, None), + Some(caption) => (caption, Some(filename)), + None => (filename, None), }; let url = response.content_uri; diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 1e01ab55b5d..a8a4111293d 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1692,7 +1692,7 @@ impl Room { /// [`upload()`] and afterwards the [`send()`]. /// /// # Arguments - /// * `url` - The file name. + /// * `filename` - The file name. /// /// * `content_type` - The type of the media, this will be used as the /// content-type header. @@ -1723,12 +1723,12 @@ impl Room { /// /// if let Some(room) = client.get_room(&room_id) { /// room.send_attachment( - /// "My favorite cat", - /// None, /// "my_favorite_cat.jpg", /// &mime::IMAGE_JPEG, /// image, /// AttachmentConfig::new(), + /// "My favorite cat", + /// None, /// ).await?; /// } /// # anyhow::Ok(()) }; @@ -1739,14 +1739,14 @@ impl Room { #[instrument(skip_all)] pub fn send_attachment<'a>( &'a self, - url: &'a str, + filename: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, caption: Option, formatted: Option, ) -> SendAttachment<'a> { - SendAttachment::new(self, url, content_type, data, config, caption, formatted) + SendAttachment::new(self, filename, content_type, data, config, caption, formatted) } /// Prepare and send an attachment to this room. @@ -1761,7 +1761,7 @@ impl Room { /// [`send()`](#method.send). /// /// # Arguments - /// * `url` - The file name. + /// * `filename` - The file name. /// /// * `content_type` - The type of the media, this will be used as the /// content-type header. @@ -1778,7 +1778,7 @@ impl Room { /// to be uploaded. pub(super) async fn prepare_and_send_attachment<'a>( &'a self, - url: &'a str, + filename: &'a str, content_type: &'a Mime, data: Vec, config: AttachmentConfig, @@ -1792,7 +1792,7 @@ impl Room { let content = if self.is_encrypted().await? { self.client .prepare_encrypted_attachment_message( - url, + filename, content_type, data, config.info, @@ -1806,7 +1806,7 @@ impl Room { self.client .media() .prepare_attachment_message( - url, + filename, content_type, data, config.info, @@ -1823,11 +1823,13 @@ impl Room { .client .media() .prepare_attachment_message( - body, + filename, content_type, data, config.info, config.thumbnail, + caption, + formatted, send_progress, ) .await?; From 3ab9e1af2b51abc71c013b3affee997992bbccb5 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Sun, 17 Mar 2024 12:44:31 +0100 Subject: [PATCH 11/17] fix send_attachment documentation example --- crates/matrix-sdk/src/room/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index a8a4111293d..1b43772398c 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1727,7 +1727,7 @@ impl Room { /// &mime::IMAGE_JPEG, /// image, /// AttachmentConfig::new(), - /// "My favorite cat", + /// Some(String::from("My favorite cat")), /// None, /// ).await?; /// } From 1798315cb5c2f82117c3c6bc601e2002483cb63e Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Mon, 18 Mar 2024 17:06:25 +0100 Subject: [PATCH 12/17] move caption and formatted_caption into attachmentconfig --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 50 ++++++++----------- crates/matrix-sdk-ui/src/timeline/futures.rs | 11 +--- crates/matrix-sdk-ui/src/timeline/mod.rs | 9 ++-- crates/matrix-sdk/src/attachment.rs | 30 +++++++++-- crates/matrix-sdk/src/encryption/mod.rs | 39 ++++++++------- crates/matrix-sdk/src/media.rs | 37 +++++++------- crates/matrix-sdk/src/room/futures.rs | 16 ++---- crates/matrix-sdk/src/room/mod.rs | 30 +++-------- .../tests/integration/room/joined.rs | 11 ++-- examples/image_bot/src/main.rs | 2 +- 10 files changed, 106 insertions(+), 129 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 0d0838f9d3b..f884aff9236 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -38,8 +38,7 @@ use ruma::{ receipt::ReceiptThread, relation::Annotation, room::message::{ - FormattedBody as RumaFormattedBody, ForwardThread, LocationMessageEventContent, - MessageType, RoomMessageEventContentWithoutRelation, + ForwardThread, LocationMessageEventContent, MessageType, RoomMessageEventContentWithoutRelation }, AnyMessageLikeEventContent, }, @@ -58,8 +57,7 @@ use crate::{ error::{ClientError, RoomError}, helpers::unwrap_or_clone_arc, ruma::{ - AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, - VideoInfo, + AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, VideoInfo }, task_handle::TaskHandle, RUNTIME, @@ -111,16 +109,10 @@ impl Timeline { filename: String, mime_type: Mime, attachment_config: AttachmentConfig, - caption: Option, - formatted: Option, progress_watcher: Option>, ) -> Result<(), RoomError> { - let formatted: Option = match formatted { - Some(p) => Some(RumaFormattedBody::from(p)), - None => None, - }; let request = - self.inner.send_attachment(filename, mime_type, attachment_config, caption, formatted); + self.inner.send_attachment(filename, mime_type, attachment_config); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); RUNTIME.spawn(async move { @@ -228,7 +220,7 @@ impl Timeline { thumbnail_url: Option, image_info: ImageInfo, caption: Option, - formatted: Option, + formatted_caption: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -249,14 +241,14 @@ impl Timeline { AttachmentConfig::with_thumbnail(thumbnail).info(attachment_info) } _ => AttachmentConfig::new().info(attachment_info), - }; + } + .caption(caption) + .formatted_caption(formatted_caption.map(Into::into)); self.send_attachment( url, mime_type, attachment_config, - caption, - formatted, progress_watcher, ) .await @@ -269,7 +261,7 @@ impl Timeline { thumbnail_url: Option, video_info: VideoInfo, caption: Option, - formatted: Option, + formatted_caption: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -289,15 +281,15 @@ impl Timeline { self.build_thumbnail_info(thumbnail_url, thumbnail_image_info)?; AttachmentConfig::with_thumbnail(thumbnail).info(attachment_info) } - _ => AttachmentConfig::new().info(attachment_info), - }; + _ => AttachmentConfig::new().info(attachment_info) + } + .caption(caption). + formatted_caption(formatted_caption.map(Into::into)); self.send_attachment( url, mime_type, attachment_config, - caption, - formatted, progress_watcher, ) .await @@ -309,7 +301,7 @@ impl Timeline { url: String, audio_info: AudioInfo, caption: Option, - formatted: Option, + formatted_caption: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -322,14 +314,14 @@ impl Timeline { .map_err(|_| RoomError::InvalidAttachmentData)?; let attachment_info = AttachmentInfo::Audio(base_audio_info); - let attachment_config = AttachmentConfig::new().info(attachment_info); + let attachment_config = AttachmentConfig::new().info(attachment_info) + .caption(caption) + .formatted_caption(formatted_caption.map(Into::into)); self.send_attachment( url, mime_type, attachment_config, - caption, - formatted, progress_watcher, ) .await @@ -342,7 +334,7 @@ impl Timeline { audio_info: AudioInfo, waveform: Vec, caption: Option, - formatted: Option, + formatted_caption: Option, progress_watcher: Option>, ) -> Arc { SendAttachmentJoinHandle::new(RUNTIME.spawn(async move { @@ -356,14 +348,14 @@ impl Timeline { let attachment_info = AttachmentInfo::Voice { audio_info: base_audio_info, waveform: Some(waveform) }; - let attachment_config = AttachmentConfig::new().info(attachment_info); + let attachment_config = AttachmentConfig::new().info(attachment_info) + .caption(caption) + .formatted_caption(formatted_caption.map(Into::into)); self.send_attachment( url, mime_type, attachment_config, - caption, - formatted, progress_watcher, ) .await @@ -388,7 +380,7 @@ impl Timeline { let attachment_info = AttachmentInfo::File(base_file_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(url, mime_type, attachment_config, None, None, progress_watcher) + self.send_attachment(url, mime_type, attachment_config, progress_watcher) .await })) } diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 624c0ea1d99..76ded5a77bc 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -4,7 +4,6 @@ use eyeball::{SharedObservable, Subscriber}; use matrix_sdk::{attachment::AttachmentConfig, TransmissionProgress}; use matrix_sdk_base::boxed_into_future; use mime::Mime; -use ruma::events::room::message::FormattedBody; use tracing::{Instrument as _, Span}; use super::{Error, Timeline}; @@ -14,8 +13,6 @@ pub struct SendAttachment<'a> { filename: String, mime_type: Mime, config: AttachmentConfig, - caption: Option, - formatted: Option, tracing_span: Span, pub(crate) send_progress: SharedObservable, } @@ -26,16 +23,12 @@ impl<'a> SendAttachment<'a> { filename: String, mime_type: Mime, config: AttachmentConfig, - caption: Option, - formatted: Option, ) -> Self { Self { timeline, filename, mime_type, config, - caption, - formatted, tracing_span: Span::current(), send_progress: Default::default(), } @@ -59,8 +52,6 @@ impl<'a> IntoFuture for SendAttachment<'a> { filename, mime_type, config, - caption, - formatted, tracing_span, send_progress, } = self; @@ -74,7 +65,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { timeline .room() - .send_attachment(body, &mime_type, data, config, caption, formatted) + .send_attachment(body, &mime_type, data, config) .with_send_progress_observable(send_progress) .await .map_err(|_| Error::FailedSendingAttachment)?; diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index 076e58363b9..c782aeb3393 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -45,9 +45,8 @@ use ruma::{ relation::Annotation, room::{ message::{ - AddMentions, FormattedBody, ForwardThread, OriginalRoomMessageEvent, - ReplacementMetadata, RoomMessageEventContent, - RoomMessageEventContentWithoutRelation, + AddMentions, ForwardThread, OriginalRoomMessageEvent, ReplacementMetadata, + RoomMessageEventContent, RoomMessageEventContentWithoutRelation, }, redaction::RoomRedactionEventContent, }, @@ -532,10 +531,8 @@ impl Timeline { filename: String, mime_type: Mime, config: AttachmentConfig, - caption: Option, - formatted: Option, ) -> SendAttachment<'_> { - SendAttachment::new(self, filename, mime_type, config, caption, formatted) + SendAttachment::new(self, filename, mime_type, config) } /// Retry sending a message that previously failed to send. diff --git a/crates/matrix-sdk/src/attachment.rs b/crates/matrix-sdk/src/attachment.rs index 66494b72e33..a8417a67555 100644 --- a/crates/matrix-sdk/src/attachment.rs +++ b/crates/matrix-sdk/src/attachment.rs @@ -23,7 +23,7 @@ use image::GenericImageView; use ruma::{ assign, events::room::{ - message::{AudioInfo, FileInfo, VideoInfo}, + message::{AudioInfo, FileInfo, FormattedBody, VideoInfo}, ImageInfo, ThumbnailInfo, }, OwnedTransactionId, TransactionId, UInt, @@ -190,6 +190,8 @@ pub struct AttachmentConfig { pub(crate) txn_id: Option, pub(crate) info: Option, pub(crate) thumbnail: Option, + pub(crate) caption: Option, + pub(crate) formatted_caption: Option, #[cfg(feature = "image-proc")] pub(crate) generate_thumbnail: bool, #[cfg(feature = "image-proc")] @@ -205,6 +207,8 @@ impl AttachmentConfig { txn_id: Default::default(), info: Default::default(), thumbnail: None, + caption: None, + formatted_caption: None, #[cfg(feature = "image-proc")] generate_thumbnail: Default::default(), #[cfg(feature = "image-proc")] @@ -247,6 +251,8 @@ impl AttachmentConfig { txn_id: Default::default(), info: Default::default(), thumbnail: Some(thumbnail), + caption: None, + formatted_caption: None, #[cfg(feature = "image-proc")] generate_thumbnail: Default::default(), #[cfg(feature = "image-proc")] @@ -278,6 +284,26 @@ impl AttachmentConfig { self.info = Some(info); self } + + /// Set the optional caption + /// + /// # Arguments + /// + /// * `caption` - The optional caption + pub fn caption(mut self, caption: Option) -> 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) -> Self { + self.formatted_caption = formatted_caption; + self + } } impl Default for AttachmentConfig { @@ -331,8 +357,6 @@ impl Default for AttachmentConfig { /// /// if let Some(room) = client.get_room(&room_id) { /// room.send_attachment( -/// "My favorite cat", -/// None, /// "my_favorite_cat.jpg", /// &mime::IMAGE_JPEG, /// image, diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index ab172595379..d810d2ef108 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -49,8 +49,8 @@ use ruma::{ assign, events::room::{ message::{ - AudioMessageEventContent, FileInfo, FileMessageEventContent, FormattedBody, - ImageMessageEventContent, MessageType, VideoInfo, VideoMessageEventContent, + AudioMessageEventContent, FileInfo, FileMessageEventContent, ImageMessageEventContent, + MessageType, VideoInfo, VideoMessageEventContent, }, ImageInfo, MediaSource, ThumbnailInfo, }, @@ -68,7 +68,7 @@ use self::{ tasks::{BackupDownloadTask, BackupUploadingTask, ClientTasks}, }; use crate::{ - attachment::{AttachmentInfo, Thumbnail}, + attachment::{AttachmentConfig, Thumbnail}, client::ClientInner, encryption::{ identities::{Device, UserDevices}, @@ -305,14 +305,11 @@ impl Client { filename: &str, content_type: &mime::Mime, data: Vec, - info: Option, - thumbnail: Option, - caption: Option, - formatted: Option, + config: AttachmentConfig, send_progress: SharedObservable, ) -> Result { let upload_thumbnail = - self.upload_encrypted_thumbnail(thumbnail, content_type, send_progress.clone()); + self.upload_encrypted_thumbnail(config.thumbnail, content_type, send_progress.clone()); let upload_attachment = async { let mut cursor = Cursor::new(data); @@ -324,23 +321,25 @@ impl Client { let ((thumbnail_source, thumbnail_info), file) = try_join(upload_thumbnail, upload_attachment).await?; - let filename = filename.to_owned(); - let (body, filename) = match caption { - Some(caption) => (caption, Some(filename)), - None => (filename, None), + // if config.caption is set, use it as body, and filename as the file name + // otherwise, body is the filename, and the filename is not set + // https://github.com/tulir/matrix-spec-proposals/blob/body-as-caption/proposals/2530-body-as-caption.md + let (body, filename) = match config.caption { + Some(caption) => (caption, Some(filename.to_owned())), + None => (filename.to_owned(), None), }; Ok(match content_type.type_() { mime::IMAGE => { - let info = assign!(info.map(ImageInfo::from).unwrap_or_default(), { + let info = assign!(config.info.map(ImageInfo::from).unwrap_or_default(), { mimetype: Some(content_type.as_ref().to_owned()), thumbnail_source, thumbnail_info }); let content = assign!(ImageMessageEventContent::encrypted(body.to_owned(), file), { info: Some(Box::new(info)), - formatted: formatted, - filename: filename + formatted: config.formatted_caption, + filename }); MessageType::Image(content) } @@ -350,22 +349,24 @@ impl Client { MessageType::Audio(crate::media::update_audio_message_event( audio_message_event_content, content_type, - info, + config.info, )) } mime::VIDEO => { - let info = assign!(info.map(VideoInfo::from).unwrap_or_default(), { + let info = assign!(config.info.map(VideoInfo::from).unwrap_or_default(), { mimetype: Some(content_type.as_ref().to_owned()), thumbnail_source, thumbnail_info }); let content = assign!(VideoMessageEventContent::encrypted(body.to_owned(), file), { - info: Some(Box::new(info)) + info: Some(Box::new(info)), + formatted: config.formatted_caption, + filename }); MessageType::Video(content) } _ => { - let info = assign!(info.map(FileInfo::from).unwrap_or_default(), { + let info = assign!(config.info.map(FileInfo::from).unwrap_or_default(), { mimetype: Some(content_type.as_ref().to_owned()), thumbnail_source, thumbnail_info diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index b02feae9aa0..10a6d7d5983 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -31,7 +31,7 @@ use ruma::{ events::room::{ message::{ self, AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent, - FormattedBody, ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, + ImageMessageEventContent, MessageType, UnstableAudioDetailsContentBlock, UnstableVoiceContentBlock, VideoInfo, VideoMessageEventContent, }, ImageInfo, MediaSource, ThumbnailInfo, @@ -44,7 +44,7 @@ use tempfile::{Builder as TempFileBuilder, NamedTempFile, TempDir}; use tokio::{fs::File as TokioFile, io::AsyncWriteExt}; use crate::{ - attachment::{AttachmentInfo, Thumbnail}, + attachment::{AttachmentConfig, AttachmentInfo, Thumbnail}, futures::SendRequest, Client, Result, TransmissionProgress, }; @@ -444,13 +444,10 @@ impl Media { filename: &str, content_type: &Mime, data: Vec, - info: Option, - thumbnail: Option, - caption: Option, - formatted: Option, + config: AttachmentConfig, send_progress: SharedObservable, ) -> Result { - let upload_thumbnail = self.upload_thumbnail(thumbnail, send_progress.clone()); + let upload_thumbnail = self.upload_thumbnail(config.thumbnail, send_progress.clone()); let upload_attachment = async move { self.upload(content_type, data) @@ -462,17 +459,19 @@ impl Media { let ((thumbnail_source, thumbnail_info), response) = try_join(upload_thumbnail, upload_attachment).await?; - let filename = filename.to_owned(); - let (body, filename) = match caption { - Some(caption) => (caption, Some(filename)), - None => (filename, None), + // if config.caption is set, use it as body, and filename as the file name + // otherwise, body is the filename, and the filename is not set + // https://github.com/tulir/matrix-spec-proposals/blob/body-as-caption/proposals/2530-body-as-caption.md + let (body, filename) = match config.caption { + Some(caption) => (caption, Some(filename.to_owned())), + None => (filename.to_owned(), None), }; let url = response.content_uri; Ok(match content_type.type_() { mime::IMAGE => { - let info = assign!(info.map(ImageInfo::from).unwrap_or_default(), { + let info = assign!(config.info.map(ImageInfo::from).unwrap_or_default(), { mimetype: Some(content_type.as_ref().to_owned()), thumbnail_source, thumbnail_info, @@ -481,22 +480,22 @@ impl Media { ImageMessageEventContent::plain(body.to_owned(), url) .info(Box::new(info)) .filename(filename) - .formatted(formatted), + .formatted(config.formatted_caption), ) } mime::AUDIO => { let audio_message_event_content = message::AudioMessageEventContent::plain(body.to_owned(), url) .filename(filename) - .formatted(formatted); + .formatted(config.formatted_caption); MessageType::Audio(update_audio_message_event( audio_message_event_content, content_type, - info, + config.info, )) } mime::VIDEO => { - let info = assign!(info.map(VideoInfo::from).unwrap_or_default(), { + let info = assign!(config.info.map(VideoInfo::from).unwrap_or_default(), { mimetype: Some(content_type.as_ref().to_owned()), thumbnail_source, thumbnail_info @@ -505,11 +504,11 @@ impl Media { VideoMessageEventContent::plain(body.to_owned(), url) .info(Box::new(info)) .filename(filename) - .formatted(formatted), + .formatted(config.formatted_caption), ) } _ => { - let info = assign!(info.map(FileInfo::from).unwrap_or_default(), { + let info = assign!(config.info.map(FileInfo::from).unwrap_or_default(), { mimetype: Some(content_type.as_ref().to_owned()), thumbnail_source, thumbnail_info @@ -518,7 +517,7 @@ impl Media { FileMessageEventContent::plain(body.to_owned(), url) .info(Box::new(info)) .filename(filename) - .formatted(formatted), + .formatted(config.formatted_caption), ) } }) diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index 6d6945c7f21..e2642c6c739 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -28,7 +28,7 @@ use ruma::events::{MessageLikeUnsigned, SyncMessageLikeEvent}; use ruma::{ api::client::message::send_message_event, assign, - events::{room::message::FormattedBody, AnyMessageLikeEventContent, MessageLikeEventContent}, + events::{AnyMessageLikeEventContent, MessageLikeEventContent}, serde::Raw, OwnedTransactionId, TransactionId, }; @@ -220,8 +220,6 @@ pub struct SendAttachment<'a> { content_type: &'a Mime, data: Vec, config: AttachmentConfig, - caption: Option, - formatted: Option, tracing_span: Span, send_progress: SharedObservable, } @@ -233,8 +231,6 @@ impl<'a> SendAttachment<'a> { content_type: &'a Mime, data: Vec, config: AttachmentConfig, - caption: Option, - formatted: Option, ) -> Self { Self { room, @@ -242,8 +238,6 @@ impl<'a> SendAttachment<'a> { content_type, data, config, - caption, - formatted, tracing_span: Span::current(), send_progress: Default::default(), } @@ -272,8 +266,6 @@ impl<'a> IntoFuture for SendAttachment<'a> { content_type, data, config, - caption, - formatted, tracing_span, send_progress, } = self; @@ -284,8 +276,6 @@ impl<'a> IntoFuture for SendAttachment<'a> { content_type, data, config, - caption, - formatted, send_progress, ) .await @@ -340,6 +330,8 @@ impl<'a> IntoFuture for SendAttachment<'a> { txn_id: config.txn_id, info: config.info, thumbnail, + caption: config.caption, + formatted_caption: config.formatted_caption, #[cfg(feature = "image-proc")] generate_thumbnail: false, #[cfg(feature = "image-proc")] @@ -351,8 +343,6 @@ impl<'a> IntoFuture for SendAttachment<'a> { content_type, data, config, - caption, - formatted, send_progress, ) .await diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 1b43772398c..415ec32c98a 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -55,7 +55,7 @@ use ruma::{ avatar::{self, RoomAvatarEventContent}, encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility, - message::{FormattedBody, RoomMessageEventContent}, + message::RoomMessageEventContent, name::RoomNameEventContent, power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent}, server_acl::RoomServerAclEventContent, @@ -1705,7 +1705,7 @@ impl Room { /// * `caption` - An optional caption of the media that is going to be /// uploaded. /// - /// * `formatted` - A optional formatted caption of the media that is going + /// * `formatted_caption` - A optional formatted caption of the media that is going /// to be uploaded. /// /// # Examples @@ -1727,8 +1727,6 @@ impl Room { /// &mime::IMAGE_JPEG, /// image, /// AttachmentConfig::new(), - /// Some(String::from("My favorite cat")), - /// None, /// ).await?; /// } /// # anyhow::Ok(()) }; @@ -1743,10 +1741,8 @@ impl Room { content_type: &'a Mime, data: Vec, config: AttachmentConfig, - caption: Option, - formatted: Option, ) -> SendAttachment<'a> { - SendAttachment::new(self, filename, content_type, data, config, caption, formatted) + SendAttachment::new(self, filename, content_type, data, config) } /// Prepare and send an attachment to this room. @@ -1782,12 +1778,11 @@ impl Room { content_type: &'a Mime, data: Vec, config: AttachmentConfig, - caption: Option, - formatted: Option, send_progress: SharedObservable, ) -> Result { self.ensure_room_joined()?; + let txn_id = config.txn_id.to_owned(); #[cfg(feature = "e2e-encryption")] let content = if self.is_encrypted().await? { self.client @@ -1795,10 +1790,7 @@ impl Room { filename, content_type, data, - config.info, - config.thumbnail, - caption, - formatted, + config, send_progress, ) .await? @@ -1809,10 +1801,7 @@ impl Room { filename, content_type, data, - config.info, - config.thumbnail, - caption, - formatted, + config, send_progress, ) .await? @@ -1826,16 +1815,13 @@ impl Room { filename, content_type, data, - config.info, - config.thumbnail, - caption, - formatted, + config, send_progress, ) .await?; let mut fut = self.send(RoomMessageEventContent::new(content)); - if let Some(txn_id) = &config.txn_id { + if let Some(txn_id) = &txn_id { fut = fut.with_transaction_id(txn_id); } fut.await diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index 4539d7ae64a..803705b31ed 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -374,8 +374,6 @@ async fn room_attachment_send() { &mime::IMAGE_JPEG, b"Hello world".to_vec(), AttachmentConfig::new(), - None, - None, ) .await .unwrap(); @@ -425,10 +423,11 @@ async fn room_attachment_send_info() { width: Some(uint!(800)), size: None, blurhash: None, - })); + })) + .caption(Some("image caption".to_owned())); let response = room - .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, None, None) + .send_attachment("image.jpg", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) .await .unwrap(); @@ -486,8 +485,6 @@ async fn room_attachment_send_wrong_info() { &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, - Some("image caption".to_string()), - None, ) .await; @@ -556,7 +553,7 @@ async fn room_attachment_send_info_thumbnail() { })); let response = room - .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config, None, None) + .send_attachment("image", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) .await .unwrap(); diff --git a/examples/image_bot/src/main.rs b/examples/image_bot/src/main.rs index b75dd3ea9a8..6505fda5265 100644 --- a/examples/image_bot/src/main.rs +++ b/examples/image_bot/src/main.rs @@ -17,7 +17,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, image: if text_content.body.contains("!image") { println!("sending image"); - room.send_attachment("cat", &mime::IMAGE_JPEG, image, AttachmentConfig::new(), None, None) + room.send_attachment("cat.jpg", &mime::IMAGE_JPEG, image, AttachmentConfig::new().caption(Some("my pretty cat".to_owned()))) .await .unwrap(); From 053a656d32a74b875c8328aeb93fc8d81596934e Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Mon, 18 Mar 2024 17:22:31 +0100 Subject: [PATCH 13/17] fix formatting --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 58 ++++++------------- crates/matrix-sdk-ui/src/timeline/futures.rs | 9 +-- crates/matrix-sdk/src/room/futures.rs | 30 ++-------- crates/matrix-sdk/src/room/mod.rs | 24 ++------ .../tests/integration/room/joined.rs | 43 +++++++------- examples/image_bot/src/main.rs | 11 +++- 6 files changed, 58 insertions(+), 117 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index f884aff9236..d5b1d084ce3 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -38,7 +38,8 @@ use ruma::{ receipt::ReceiptThread, relation::Annotation, room::message::{ - ForwardThread, LocationMessageEventContent, MessageType, RoomMessageEventContentWithoutRelation + ForwardThread, LocationMessageEventContent, MessageType, + RoomMessageEventContentWithoutRelation }, AnyMessageLikeEventContent, }, @@ -57,7 +58,8 @@ use crate::{ error::{ClientError, RoomError}, helpers::unwrap_or_clone_arc, ruma::{ - AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, VideoInfo + AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, + VideoInfo }, task_handle::TaskHandle, RUNTIME, @@ -111,8 +113,7 @@ impl Timeline { attachment_config: AttachmentConfig, progress_watcher: Option>, ) -> Result<(), RoomError> { - let request = - self.inner.send_attachment(filename, mime_type, attachment_config); + let request = self.inner.send_attachment(filename, mime_type, attachment_config); if let Some(progress_watcher) = progress_watcher { let mut subscriber = request.subscribe_to_send_progress(); RUNTIME.spawn(async move { @@ -245,13 +246,7 @@ impl Timeline { .caption(caption) .formatted_caption(formatted_caption.map(Into::into)); - self.send_attachment( - url, - mime_type, - attachment_config, - progress_watcher, - ) - .await + self.send_attachment(url, mime_type, attachment_config, progress_watcher).await })) } @@ -281,18 +276,12 @@ impl Timeline { self.build_thumbnail_info(thumbnail_url, thumbnail_image_info)?; AttachmentConfig::with_thumbnail(thumbnail).info(attachment_info) } - _ => AttachmentConfig::new().info(attachment_info) + _ => AttachmentConfig::new().info(attachment_info), } - .caption(caption). - formatted_caption(formatted_caption.map(Into::into)); - - self.send_attachment( - url, - mime_type, - attachment_config, - progress_watcher, - ) - .await + .caption(caption) + .formatted_caption(formatted_caption.map(Into::into)); + + self.send_attachment(url, mime_type, attachment_config, progress_watcher).await })) } @@ -314,17 +303,12 @@ impl Timeline { .map_err(|_| RoomError::InvalidAttachmentData)?; let attachment_info = AttachmentInfo::Audio(base_audio_info); - let attachment_config = AttachmentConfig::new().info(attachment_info) + let attachment_config = AttachmentConfig::new() + .info(attachment_info) .caption(caption) .formatted_caption(formatted_caption.map(Into::into)); - self.send_attachment( - url, - mime_type, - attachment_config, - progress_watcher, - ) - .await + self.send_attachment(url, mime_type, attachment_config,progress_watcher).await })) } @@ -348,17 +332,12 @@ impl Timeline { let attachment_info = AttachmentInfo::Voice { audio_info: base_audio_info, waveform: Some(waveform) }; - let attachment_config = AttachmentConfig::new().info(attachment_info) + let attachment_config = AttachmentConfig::new() + .info(attachment_info) .caption(caption) .formatted_caption(formatted_caption.map(Into::into)); - self.send_attachment( - url, - mime_type, - attachment_config, - progress_watcher, - ) - .await + self.send_attachment(url, mime_type, attachment_config, progress_watcher).await })) } @@ -380,8 +359,7 @@ impl Timeline { let attachment_info = AttachmentInfo::File(base_file_info); let attachment_config = AttachmentConfig::new().info(attachment_info); - self.send_attachment(url, mime_type, attachment_config, progress_watcher) - .await + self.send_attachment(url, mime_type, attachment_config, progress_watcher).await })) } diff --git a/crates/matrix-sdk-ui/src/timeline/futures.rs b/crates/matrix-sdk-ui/src/timeline/futures.rs index 76ded5a77bc..459be113de1 100644 --- a/crates/matrix-sdk-ui/src/timeline/futures.rs +++ b/crates/matrix-sdk-ui/src/timeline/futures.rs @@ -47,14 +47,7 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { - timeline, - filename, - mime_type, - config, - tracing_span, - send_progress, - } = self; + let Self { timeline, filename, mime_type, config, tracing_span, send_progress } = self; let fut = async move { let body = Path::new(&filename) .file_name() diff --git a/crates/matrix-sdk/src/room/futures.rs b/crates/matrix-sdk/src/room/futures.rs index e2642c6c739..4c3a749d0ca 100644 --- a/crates/matrix-sdk/src/room/futures.rs +++ b/crates/matrix-sdk/src/room/futures.rs @@ -260,25 +260,11 @@ impl<'a> IntoFuture for SendAttachment<'a> { boxed_into_future!(extra_bounds: 'a); fn into_future(self) -> Self::IntoFuture { - let Self { - room, - url, - content_type, - data, - config, - tracing_span, - send_progress, - } = self; + let Self { room, url, content_type, data, config, tracing_span, send_progress } = self; let fut = async move { if config.thumbnail.is_some() { - room.prepare_and_send_attachment( - url, - content_type, - data, - config, - send_progress, - ) - .await + room.prepare_and_send_attachment(url, content_type, data, config, send_progress) + .await } else { #[cfg(not(feature = "image-proc"))] let thumbnail = None; @@ -338,14 +324,8 @@ impl<'a> IntoFuture for SendAttachment<'a> { thumbnail_size: None, }; - room.prepare_and_send_attachment( - url, - content_type, - data, - config, - send_progress, - ) - .await + room.prepare_and_send_attachment(url, content_type, data, config, send_progress) + .await } }; diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 415ec32c98a..bb6414943a5 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1770,8 +1770,8 @@ impl Room { /// * `caption` - An optional caption of the media that is going to be /// uploaded. /// - /// * `formatted` - A optional formatted caption of the media that is going - /// to be uploaded. + /// * `formatted` - A optional formatted caption of the media that + /// is going to be uploaded. pub(super) async fn prepare_and_send_attachment<'a>( &'a self, filename: &'a str, @@ -1786,25 +1786,13 @@ impl Room { #[cfg(feature = "e2e-encryption")] let content = if self.is_encrypted().await? { self.client - .prepare_encrypted_attachment_message( - filename, - content_type, - data, - config, - send_progress, - ) - .await? + .prepare_encrypted_attachment_message(filename, content_type, data, config, send_progress) + .await? } else { self.client .media() - .prepare_attachment_message( - filename, - content_type, - data, - config, - send_progress, - ) - .await? + .prepare_attachment_message(filename, content_type, data, config, send_progress) + .await? }; #[cfg(not(feature = "e2e-encryption"))] diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index 803705b31ed..fb57f188f54 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -418,13 +418,14 @@ async fn room_attachment_send_info() { let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap(); - let config = AttachmentConfig::new().info(AttachmentInfo::Image(BaseImageInfo { - height: Some(uint!(600)), - width: Some(uint!(800)), - size: None, - blurhash: None, - })) - .caption(Some("image caption".to_owned())); + let config = AttachmentConfig::new() + .info(AttachmentInfo::Image(BaseImageInfo { + height: Some(uint!(600)), + width: Some(uint!(800)), + size: None, + blurhash: None, + })) + .caption(Some("image caption".to_owned())); let response = room .send_attachment("image.jpg", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config) @@ -471,22 +472,18 @@ async fn room_attachment_send_wrong_info() { let room = client.get_room(&DEFAULT_TEST_ROOM_ID).unwrap(); - let config = AttachmentConfig::new().info(AttachmentInfo::Video(BaseVideoInfo { - height: Some(uint!(600)), - width: Some(uint!(800)), - duration: Some(Duration::from_millis(3600)), - size: None, - blurhash: None, - })); - - let response = room - .send_attachment( - "image.jpg", - &mime::IMAGE_JPEG, - b"Hello world".to_vec(), - config, - ) - .await; + let config = AttachmentConfig::new() + .info(AttachmentInfo::Video(BaseVideoInfo { + height: Some(uint!(600)), + width: Some(uint!(800)), + duration: Some(Duration::from_millis(3600)), + size: None, + blurhash: None, + })) + .caption(Some("image caption".to_owned())); + + let response = + room.send_attachment("image.jpg", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config).await; response.unwrap_err(); } diff --git a/examples/image_bot/src/main.rs b/examples/image_bot/src/main.rs index 6505fda5265..6ab8c72a98b 100644 --- a/examples/image_bot/src/main.rs +++ b/examples/image_bot/src/main.rs @@ -17,9 +17,14 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, image: if text_content.body.contains("!image") { println!("sending image"); - room.send_attachment("cat.jpg", &mime::IMAGE_JPEG, image, AttachmentConfig::new().caption(Some("my pretty cat".to_owned()))) - .await - .unwrap(); + room.send_attachment( + "cat.jpg", + &mime::IMAGE_JPEG, + image, + AttachmentConfig::new().caption(Some("my pretty cat".to_owned())) + ) + .await + .unwrap(); println!("message sent"); } From 79fb2c6adac48bef261bac6c5c72cdcb3956c903 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Mon, 18 Mar 2024 17:28:19 +0100 Subject: [PATCH 14/17] fix formatting --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 6 ++-- crates/matrix-sdk/src/room/mod.rs | 30 ++++++------------- .../tests/integration/room/joined.rs | 2 +- examples/image_bot/src/main.rs | 2 +- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index d5b1d084ce3..48859c77c2e 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -39,7 +39,7 @@ use ruma::{ relation::Annotation, room::message::{ ForwardThread, LocationMessageEventContent, MessageType, - RoomMessageEventContentWithoutRelation + RoomMessageEventContentWithoutRelation, }, AnyMessageLikeEventContent, }, @@ -59,7 +59,7 @@ use crate::{ helpers::unwrap_or_clone_arc, ruma::{ AssetType, AudioInfo, FileInfo, FormattedBody, ImageInfo, PollKind, ThumbnailInfo, - VideoInfo + VideoInfo, }, task_handle::TaskHandle, RUNTIME, @@ -308,7 +308,7 @@ impl Timeline { .caption(caption) .formatted_caption(formatted_caption.map(Into::into)); - self.send_attachment(url, mime_type, attachment_config,progress_watcher).await + self.send_attachment(url, mime_type, attachment_config, progress_watcher).await })) } diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index bb6414943a5..95fa0403337 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1702,12 +1702,6 @@ impl Room { /// /// * `config` - Metadata and configuration for the attachment. /// - /// * `caption` - An optional caption of the media that is going to be - /// uploaded. - /// - /// * `formatted_caption` - A optional formatted caption of the media that is going - /// to be uploaded. - /// /// # Examples /// /// ```no_run @@ -1766,12 +1760,6 @@ impl Room { /// media. /// /// * `config` - Metadata and configuration for the attachment. - /// - /// * `caption` - An optional caption of the media that is going to be - /// uploaded. - /// - /// * `formatted` - A optional formatted caption of the media that - /// is going to be uploaded. pub(super) async fn prepare_and_send_attachment<'a>( &'a self, filename: &'a str, @@ -1786,8 +1774,14 @@ impl Room { #[cfg(feature = "e2e-encryption")] let content = if self.is_encrypted().await? { self.client - .prepare_encrypted_attachment_message(filename, content_type, data, config, send_progress) - .await? + .prepare_encrypted_attachment_message( + filename, + content_type, + data, + config, + send_progress + ) + .await? } else { self.client .media() @@ -1799,13 +1793,7 @@ impl Room { let content = self .client .media() - .prepare_attachment_message( - filename, - content_type, - data, - config, - send_progress, - ) + .prepare_attachment_message(filename, content_type, data, config,send_progress) .await?; let mut fut = self.send(RoomMessageEventContent::new(content)); diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index fb57f188f54..8c753fcdb3a 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -482,7 +482,7 @@ async fn room_attachment_send_wrong_info() { })) .caption(Some("image caption".to_owned())); - let response = + let response = room.send_attachment("image.jpg", &mime::IMAGE_JPEG, b"Hello world".to_vec(), config).await; response.unwrap_err(); diff --git a/examples/image_bot/src/main.rs b/examples/image_bot/src/main.rs index 6ab8c72a98b..d5f7a07c0f5 100644 --- a/examples/image_bot/src/main.rs +++ b/examples/image_bot/src/main.rs @@ -21,7 +21,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room, image: "cat.jpg", &mime::IMAGE_JPEG, image, - AttachmentConfig::new().caption(Some("my pretty cat".to_owned())) + AttachmentConfig::new().caption(Some("my pretty cat".to_owned())), ) .await .unwrap(); From 91816e3f763437f290ebb3d3e9b40bcae4a2b805 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Mon, 18 Mar 2024 17:47:26 +0100 Subject: [PATCH 15/17] fix formatting (hopefully the last one) --- crates/matrix-sdk/src/room/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 95fa0403337..859020df324 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1779,21 +1779,21 @@ impl Room { content_type, data, config, - send_progress + send_progress, ) .await? } else { self.client .media() .prepare_attachment_message(filename, content_type, data, config, send_progress) - .await? + .await? }; #[cfg(not(feature = "e2e-encryption"))] let content = self .client .media() - .prepare_attachment_message(filename, content_type, data, config,send_progress) + .prepare_attachment_message(filename, content_type, data, config, send_progress) .await?; let mut fut = self.send(RoomMessageEventContent::new(content)); From 9f89e2d2a90503e4631135e1db504c9f20a62d13 Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Tue, 19 Mar 2024 10:16:00 +0100 Subject: [PATCH 16/17] updated stale comments --- crates/matrix-sdk-ui/src/timeline/mod.rs | 4 ---- crates/matrix-sdk/src/encryption/mod.rs | 4 ++-- crates/matrix-sdk/src/media.rs | 4 ++-- crates/matrix-sdk/src/room/mod.rs | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk-ui/src/timeline/mod.rs b/crates/matrix-sdk-ui/src/timeline/mod.rs index c782aeb3393..a56a51fdccb 100644 --- a/crates/matrix-sdk-ui/src/timeline/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/mod.rs @@ -520,10 +520,6 @@ impl Timeline { /// * `config` - An attachment configuration object containing details about /// the attachment /// - /// * `caption` - An optional caption of this attachment - /// - /// * `formatted` - An optional formatted caption of this attachment - /// /// like a thumbnail, its size, duration etc. #[instrument(skip_all)] pub fn send_attachment( diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index d810d2ef108..82c7e4dd059 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -298,8 +298,8 @@ impl Client { } /// Encrypt and upload the file to be read from `reader` and construct an - /// attachment message with `body`, `content_type`, `info` and `thumbnail`, - /// optionanly with `formatted` and `filename`. + /// attachment message with `body`, `content_type`, `info`, optionally with + /// `formatted` and `filename` if present in `config`. pub(crate) async fn prepare_encrypted_attachment_message( &self, filename: &str, diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index 10a6d7d5983..22d6a35d46b 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -437,8 +437,8 @@ impl Media { } /// Upload the file bytes in `data` and construct an attachment - /// message with `body`, `content_type`, `info` and `thumbnail`, - /// optionally with `formatted` and `filename`. + /// message with `body`, `content_type`, `info`, optionally with + /// `formatted` and `filename` if present in `config` pub(crate) async fn prepare_attachment_message( &self, filename: &str, diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 859020df324..af4d4e1784b 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -1770,7 +1770,7 @@ impl Room { ) -> Result { self.ensure_room_joined()?; - let txn_id = config.txn_id.to_owned(); + let txn_id = config.txn_id.clone(); #[cfg(feature = "e2e-encryption")] let content = if self.is_encrypted().await? { self.client From 58529c3958c6ef2abd3cf5614593f54e47648c7d Mon Sep 17 00:00:00 2001 From: Marco Antonio Alvarez Date: Tue, 19 Mar 2024 10:30:13 +0100 Subject: [PATCH 17/17] simplify attachment message comments --- crates/matrix-sdk/src/encryption/mod.rs | 3 +-- crates/matrix-sdk/src/media.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index 82c7e4dd059..de5774c1ac9 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -298,8 +298,7 @@ impl Client { } /// Encrypt and upload the file to be read from `reader` and construct an - /// attachment message with `body`, `content_type`, `info`, optionally with - /// `formatted` and `filename` if present in `config`. + /// attachment message. pub(crate) async fn prepare_encrypted_attachment_message( &self, filename: &str, diff --git a/crates/matrix-sdk/src/media.rs b/crates/matrix-sdk/src/media.rs index 22d6a35d46b..708bbbf99f0 100644 --- a/crates/matrix-sdk/src/media.rs +++ b/crates/matrix-sdk/src/media.rs @@ -437,8 +437,7 @@ impl Media { } /// Upload the file bytes in `data` and construct an attachment - /// message with `body`, `content_type`, `info`, optionally with - /// `formatted` and `filename` if present in `config` + /// message. pub(crate) async fn prepare_attachment_message( &self, filename: &str,