Skip to content

Commit

Permalink
chore(base): refactor internal helpers related to media
Browse files Browse the repository at this point in the history
Notably, make it super clear what parameters are required to create the
attachment type, since the function doesn't consume the whole
`AttachmentConfig` for realz.
  • Loading branch information
bnjbvr committed Oct 31, 2024
1 parent e08d961 commit e9f90dc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 46 deletions.
13 changes: 6 additions & 7 deletions crates/matrix-sdk/src/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ impl Client {
data: &[u8],
thumbnail: Option<Thumbnail>,
send_progress: SharedObservable<TransmissionProgress>,
) -> Result<(MediaSource, Option<MediaSource>, Option<Box<ThumbnailInfo>>)> {
) -> Result<(MediaSource, Option<(MediaSource, Box<ThumbnailInfo>)>)> {
let upload_thumbnail =
self.upload_encrypted_thumbnail(thumbnail, content_type, send_progress.clone());

Expand All @@ -470,10 +470,9 @@ impl Client {
.await
};

let ((thumbnail_source, thumbnail_info), file) =
try_join(upload_thumbnail, upload_attachment).await?;
let (thumbnail, file) = try_join(upload_thumbnail, upload_attachment).await?;

Ok((MediaSource::Encrypted(Box::new(file)), thumbnail_source, thumbnail_info))
Ok((MediaSource::Encrypted(Box::new(file)), thumbnail))
}

/// Uploads an encrypted thumbnail to the media repository, and returns
Expand All @@ -483,9 +482,9 @@ impl Client {
thumbnail: Option<Thumbnail>,
content_type: &mime::Mime,
send_progress: SharedObservable<TransmissionProgress>,
) -> Result<(Option<MediaSource>, Option<Box<ThumbnailInfo>>)> {
) -> Result<Option<(MediaSource, Box<ThumbnailInfo>)>> {
let Some(thumbnail) = thumbnail else {
return Ok((None, None));
return Ok(None);
};

let mut cursor = Cursor::new(thumbnail.data);
Expand All @@ -501,7 +500,7 @@ impl Client {
mimetype: Some(thumbnail.content_type.as_ref().to_owned())
});

Ok((Some(MediaSource::Encrypted(Box::new(file))), Some(Box::new(thumbnail_info))))
Ok(Some((MediaSource::Encrypted(Box::new(file)), Box::new(thumbnail_info))))
}

/// Claim one-time keys creating new Olm sessions.
Expand Down
13 changes: 6 additions & 7 deletions crates/matrix-sdk/src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ impl Media {
data: Vec<u8>,
thumbnail: Option<Thumbnail>,
send_progress: SharedObservable<TransmissionProgress>,
) -> Result<(MediaSource, Option<MediaSource>, Option<Box<ThumbnailInfo>>)> {
) -> Result<(MediaSource, Option<(MediaSource, Box<ThumbnailInfo>)>)> {
let upload_thumbnail = self.upload_thumbnail(thumbnail, send_progress.clone());

let upload_attachment = async move {
Expand All @@ -623,10 +623,9 @@ impl Media {
.map_err(Error::from)
};

let ((thumbnail_source, thumbnail_info), response) =
try_join(upload_thumbnail, upload_attachment).await?;
let (thumbnail, response) = try_join(upload_thumbnail, upload_attachment).await?;

Ok((MediaSource::Plain(response.content_uri), thumbnail_source, thumbnail_info))
Ok((MediaSource::Plain(response.content_uri), thumbnail))
}

/// Uploads an unencrypted thumbnail to the media repository, and returns
Expand All @@ -635,9 +634,9 @@ impl Media {
&self,
thumbnail: Option<Thumbnail>,
send_progress: SharedObservable<TransmissionProgress>,
) -> Result<(Option<MediaSource>, Option<Box<ThumbnailInfo>>)> {
) -> Result<Option<(MediaSource, Box<ThumbnailInfo>)>> {
let Some(thumbnail) = thumbnail else {
return Ok((None, None));
return Ok(None);
};

let response = self
Expand All @@ -654,6 +653,6 @@ impl Media {
{ mimetype: Some(thumbnail.content_type.as_ref().to_owned()) }
);

Ok((Some(MediaSource::Plain(url)), Some(Box::new(thumbnail_info))))
Ok(Some((MediaSource::Plain(url), Box::new(thumbnail_info))))
}
}
79 changes: 47 additions & 32 deletions crates/matrix-sdk/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ use ruma::{
history_visibility::HistoryVisibility,
message::{
AudioInfo, AudioMessageEventContent, FileInfo, FileMessageEventContent,
ImageMessageEventContent, MessageType, RoomMessageEventContent,
FormattedBody, ImageMessageEventContent, MessageType, RoomMessageEventContent,
UnstableAudioDetailsContentBlock, UnstableVoiceContentBlock, VideoInfo,
VideoMessageEventContent,
},
Expand Down Expand Up @@ -1960,7 +1960,7 @@ impl Room {
};

#[cfg(feature = "e2e-encryption")]
let (media_source, thumbnail_source, thumbnail_info) = if self.is_encrypted().await? {
let (media_source, thumbnail) = if self.is_encrypted().await? {
self.client
.upload_encrypted_media_and_thumbnail(content_type, &data, thumbnail, send_progress)
.await?
Expand All @@ -1979,7 +1979,7 @@ impl Room {
};

#[cfg(not(feature = "e2e-encryption"))]
let (media_source, thumbnail_source, thumbnail_info) = self
let (media_source, thumbnail) = self
.client
.media()
.upload_plain_media_and_thumbnail(content_type, data.clone(), thumbnail, send_progress)
Expand All @@ -1998,7 +1998,7 @@ impl Room {
}

if let Some(((data, height, width), source)) =
thumbnail_cache_info.zip(thumbnail_source.as_ref())
thumbnail_cache_info.zip(thumbnail.as_ref().map(|tuple| &tuple.0))
{
debug!("caching the thumbnail");

Expand All @@ -2022,21 +2022,19 @@ impl Room {
}
}

let msg_type = self.make_attachment_message(
content_type,
media_source,
thumbnail_source,
thumbnail_info,
filename,
config,
let content = Self::make_attachment_event(
self.make_attachment_type(
content_type,
filename,
media_source,
config.caption,
config.formatted_caption,
config.info,
thumbnail,
),
mentions,
);

let mut content = RoomMessageEventContent::new(msg_type);

if let Some(mentions) = mentions {
content = content.add_mentions(mentions);
}

let mut fut = self.send(content);
if let Some(txn_id) = txn_id {
fut = fut.with_transaction_id(txn_id);
Expand All @@ -2046,33 +2044,37 @@ impl Room {

/// Creates the inner [`MessageType`] for an already-uploaded media file
/// provided by its source.
fn make_attachment_message(
#[allow(clippy::too_many_arguments)]
fn make_attachment_type(
&self,
content_type: &Mime,
source: MediaSource,
thumbnail_source: Option<MediaSource>,
thumbnail_info: Option<Box<ThumbnailInfo>>,
filename: &str,
config: AttachmentConfig,
source: MediaSource,
caption: Option<String>,
formatted_caption: Option<FormattedBody>,
info: Option<AttachmentInfo>,
thumbnail: Option<(MediaSource, Box<ThumbnailInfo>)>,
) -> MessageType {
// 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.
// If 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 {
let (body, filename) = match caption {
Some(caption) => (caption, Some(filename.to_owned())),
None => (filename.to_owned(), None),
};

let (thumbnail_source, thumbnail_info) = thumbnail.unzip();

match content_type.type_() {
mime::IMAGE => {
let info = assign!(config.info.map(ImageInfo::from).unwrap_or_default(), {
let info = assign!(info.map(ImageInfo::from).unwrap_or_default(), {
mimetype: Some(content_type.as_ref().to_owned()),
thumbnail_source,
thumbnail_info
});
let content = assign!(ImageMessageEventContent::new(body, source), {
info: Some(Box::new(info)),
formatted: config.formatted_caption,
formatted: formatted_caption,
filename
});
MessageType::Image(content)
Expand All @@ -2082,7 +2084,7 @@ impl Room {
let mut content = AudioMessageEventContent::new(body, source);

if let Some(AttachmentInfo::Voice { audio_info, waveform: Some(waveform_vec) }) =
&config.info
&info
{
if let Some(duration) = audio_info.duration {
let waveform = waveform_vec.iter().map(|v| (*v).into()).collect();
Expand All @@ -2092,29 +2094,29 @@ impl Room {
content.voice = Some(UnstableVoiceContentBlock::new());
}

let mut audio_info = config.info.map(AudioInfo::from).unwrap_or_default();
let mut audio_info = info.map(AudioInfo::from).unwrap_or_default();
audio_info.mimetype = Some(content_type.as_ref().to_owned());
let content = content.info(Box::new(audio_info));

MessageType::Audio(content)
}

mime::VIDEO => {
let info = assign!(config.info.map(VideoInfo::from).unwrap_or_default(), {
let info = assign!(info.map(VideoInfo::from).unwrap_or_default(), {
mimetype: Some(content_type.as_ref().to_owned()),
thumbnail_source,
thumbnail_info
});
let content = assign!(VideoMessageEventContent::new(body, source), {
info: Some(Box::new(info)),
formatted: config.formatted_caption,
formatted: formatted_caption,
filename
});
MessageType::Video(content)
}

_ => {
let info = assign!(config.info.map(FileInfo::from).unwrap_or_default(), {
let info = assign!(info.map(FileInfo::from).unwrap_or_default(), {
mimetype: Some(content_type.as_ref().to_owned()),
thumbnail_source,
thumbnail_info
Expand All @@ -2127,6 +2129,19 @@ impl Room {
}
}

/// Creates the [`RoomMessageEventContent`] based on the message type and
/// mentions.
fn make_attachment_event(
msg_type: MessageType,
mentions: Option<Mentions>,
) -> RoomMessageEventContent {
let mut content = RoomMessageEventContent::new(msg_type);
if let Some(mentions) = mentions {
content = content.add_mentions(mentions);
}
content
}

/// Update the power levels of a select set of users of this room.
///
/// Issue a `power_levels` state event request to the server, changing the
Expand Down

0 comments on commit e9f90dc

Please sign in to comment.