common: Add support for voice message events
This commit is contained in:
parent
d1e70c3d9f
commit
9b870cd9af
@ -33,6 +33,7 @@ unstable-msc2448 = []
|
||||
unstable-msc2675 = []
|
||||
unstable-msc2676 = []
|
||||
unstable-msc2677 = []
|
||||
unstable-msc3245 = ["unstable-msc3246"]
|
||||
unstable-msc3246 = ["unstable-msc3551", "thiserror"]
|
||||
unstable-msc3440 = []
|
||||
unstable-msc3488 = ["unstable-msc1767"]
|
||||
|
@ -185,6 +185,8 @@ pub mod tag;
|
||||
pub mod typing;
|
||||
#[cfg(feature = "unstable-msc3553")]
|
||||
pub mod video;
|
||||
#[cfg(feature = "unstable-msc3245")]
|
||||
pub mod voice;
|
||||
|
||||
#[cfg(feature = "unstable-msc2675")]
|
||||
pub use self::relation::Relations;
|
||||
|
@ -67,6 +67,8 @@ event_enum! {
|
||||
"m.sticker",
|
||||
#[cfg(feature = "unstable-msc3553")]
|
||||
"m.video",
|
||||
#[cfg(feature = "unstable-msc3245")]
|
||||
"m.voice",
|
||||
}
|
||||
|
||||
/// Any state event.
|
||||
@ -374,6 +376,8 @@ impl AnyMessageLikeEventContent {
|
||||
Self::Notice(ev) => ev.relates_to.clone().map(Into::into),
|
||||
#[cfg(feature = "unstable-msc1767")]
|
||||
Self::Emote(ev) => ev.relates_to.clone().map(Into::into),
|
||||
#[cfg(feature = "unstable-msc3245")]
|
||||
Self::Voice(ev) => ev.relates_to.clone().map(Into::into),
|
||||
#[cfg(feature = "unstable-msc3246")]
|
||||
Self::Audio(ev) => ev.relates_to.clone().map(Into::into),
|
||||
#[cfg(feature = "unstable-msc3488")]
|
||||
|
72
crates/ruma-common/src/events/voice.rs
Normal file
72
crates/ruma-common/src/events/voice.rs
Normal file
@ -0,0 +1,72 @@
|
||||
//! Types for voice message events ([MSC3245]).
|
||||
//!
|
||||
//! [MSC3245]: https://github.com/matrix-org/matrix-spec-proposals/pull/3245
|
||||
|
||||
use ruma_macros::EventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
audio::AudioContent, file::FileContent, message::MessageContent, room::message::Relation,
|
||||
};
|
||||
|
||||
/// The payload for an extensible audio message.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
#[ruma_event(type = "m.voice", kind = MessageLike)]
|
||||
pub struct VoiceEventContent {
|
||||
/// The text representation of the message.
|
||||
#[serde(flatten)]
|
||||
pub message: MessageContent,
|
||||
|
||||
/// The file content of the message.
|
||||
#[serde(rename = "org.matrix.msc1767.file")]
|
||||
pub file: FileContent,
|
||||
|
||||
/// The audio content of the message.
|
||||
#[serde(rename = "org.matrix.msc1767.audio")]
|
||||
pub audio: AudioContent,
|
||||
|
||||
/// The audio content of the message.
|
||||
#[serde(rename = "org.matrix.msc3245.voice")]
|
||||
pub voice: VoiceContent,
|
||||
|
||||
/// Information about related messages.
|
||||
#[serde(flatten, skip_serializing_if = "Option::is_none")]
|
||||
pub relates_to: Option<Relation>,
|
||||
}
|
||||
|
||||
impl VoiceEventContent {
|
||||
/// Creates a new `VoiceEventContent` with the given plain text representation and file.
|
||||
pub fn plain(message: impl Into<String>, file: FileContent) -> Self {
|
||||
Self {
|
||||
message: MessageContent::plain(message),
|
||||
file,
|
||||
audio: Default::default(),
|
||||
voice: Default::default(),
|
||||
relates_to: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `VoiceEventContent` with the given message and file.
|
||||
pub fn with_message(message: MessageContent, file: FileContent) -> Self {
|
||||
Self {
|
||||
message,
|
||||
file,
|
||||
audio: Default::default(),
|
||||
voice: Default::default(),
|
||||
relates_to: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Voice content.
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct VoiceContent {}
|
||||
|
||||
impl VoiceContent {
|
||||
/// Creates a new empty `VoiceContent`.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
@ -22,3 +22,4 @@ mod state_event;
|
||||
mod stripped;
|
||||
mod to_device;
|
||||
mod video;
|
||||
mod voice;
|
||||
|
143
crates/ruma-common/tests/events/voice.rs
Normal file
143
crates/ruma-common/tests/events/voice.rs
Normal file
@ -0,0 +1,143 @@
|
||||
#![cfg(feature = "unstable-msc3245")]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use assign::assign;
|
||||
use js_int::uint;
|
||||
use matches::assert_matches;
|
||||
use ruma_common::{
|
||||
event_id,
|
||||
events::{
|
||||
audio::AudioContent,
|
||||
file::{FileContent, FileContentInfo},
|
||||
room::message::{InReplyTo, Relation},
|
||||
voice::VoiceEventContent,
|
||||
AnyMessageLikeEvent, MessageLikeEvent, Unsigned,
|
||||
},
|
||||
mxc_uri, room_id, user_id, MilliSecondsSinceUnixEpoch,
|
||||
};
|
||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||
|
||||
#[test]
|
||||
fn event_serialization() {
|
||||
let event = MessageLikeEvent {
|
||||
content: assign!(
|
||||
VoiceEventContent::plain(
|
||||
"Voice message",
|
||||
FileContent::plain(
|
||||
mxc_uri!("mxc://notareal.hs/abcdef").to_owned(),
|
||||
Some(Box::new(assign!(
|
||||
FileContentInfo::new(),
|
||||
{
|
||||
name: Some("voice_message.ogg".to_owned()),
|
||||
mimetype: Some("audio/opus".to_owned()),
|
||||
size: Some(uint!(897_774)),
|
||||
}
|
||||
))),
|
||||
)
|
||||
),
|
||||
{
|
||||
audio: assign!(
|
||||
AudioContent::new(),
|
||||
{
|
||||
duration: Some(Duration::from_secs(23))
|
||||
}
|
||||
),
|
||||
relates_to: Some(Relation::Reply {
|
||||
in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()),
|
||||
}),
|
||||
}
|
||||
),
|
||||
event_id: event_id!("$event:notareal.hs").to_owned(),
|
||||
sender: user_id!("@user:notareal.hs").to_owned(),
|
||||
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(134_829_848)),
|
||||
room_id: room_id!("!roomid:notareal.hs").to_owned(),
|
||||
unsigned: Unsigned::default(),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
to_json_value(&event).unwrap(),
|
||||
json!({
|
||||
"content": {
|
||||
"org.matrix.msc1767.text": "Voice message",
|
||||
"org.matrix.msc1767.file": {
|
||||
"url": "mxc://notareal.hs/abcdef",
|
||||
"name": "voice_message.ogg",
|
||||
"mimetype": "audio/opus",
|
||||
"size": 897_774,
|
||||
},
|
||||
"org.matrix.msc1767.audio": {
|
||||
"duration": 23_000,
|
||||
},
|
||||
"org.matrix.msc3245.voice": {},
|
||||
"m.relates_to": {
|
||||
"m.in_reply_to": {
|
||||
"event_id": "$replyevent:example.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
"event_id": "$event:notareal.hs",
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "m.voice",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_event_deserialization() {
|
||||
let json_data = json!({
|
||||
"content": {
|
||||
"org.matrix.msc1767.text": "Voice message",
|
||||
"org.matrix.msc1767.file": {
|
||||
"url": "mxc://notareal.hs/abcdef",
|
||||
"name": "voice_message.ogg",
|
||||
"mimetype": "audio/opus",
|
||||
"size": 123_774,
|
||||
},
|
||||
"org.matrix.msc1767.audio": {
|
||||
"duration": 5_300,
|
||||
},
|
||||
"org.matrix.msc3245.voice": {},
|
||||
},
|
||||
"event_id": "$event:notareal.hs",
|
||||
"origin_server_ts": 134_829_848,
|
||||
"room_id": "!roomid:notareal.hs",
|
||||
"sender": "@user:notareal.hs",
|
||||
"type": "m.voice",
|
||||
});
|
||||
|
||||
assert_matches!(
|
||||
from_json_value::<AnyMessageLikeEvent>(json_data).unwrap(),
|
||||
AnyMessageLikeEvent::Voice(MessageLikeEvent {
|
||||
content: VoiceEventContent {
|
||||
message,
|
||||
file: FileContent {
|
||||
url,
|
||||
info: Some(info),
|
||||
..
|
||||
},
|
||||
audio,
|
||||
..
|
||||
},
|
||||
event_id,
|
||||
origin_server_ts,
|
||||
room_id,
|
||||
sender,
|
||||
unsigned
|
||||
}) if event_id == event_id!("$event:notareal.hs")
|
||||
&& message.find_plain() == Some("Voice message")
|
||||
&& message.find_html().is_none()
|
||||
&& url == "mxc://notareal.hs/abcdef"
|
||||
&& info.name.as_deref() == Some("voice_message.ogg")
|
||||
&& info.mimetype.as_deref() == Some("audio/opus")
|
||||
&& info.size == Some(uint!(123_774))
|
||||
&& audio.duration == Some(Duration::from_millis(5_300))
|
||||
&& audio.waveform.is_none()
|
||||
&& origin_server_ts == MilliSecondsSinceUnixEpoch(uint!(134_829_848))
|
||||
&& room_id == room_id!("!roomid:notareal.hs")
|
||||
&& sender == user_id!("@user:notareal.hs")
|
||||
&& unsigned.is_empty()
|
||||
);
|
||||
}
|
@ -117,6 +117,7 @@ unstable-msc2448 = [
|
||||
unstable-msc2675 = ["ruma-common/unstable-msc2675"]
|
||||
unstable-msc2676 = ["ruma-common/unstable-msc2676"]
|
||||
unstable-msc2677 = ["ruma-common/unstable-msc2677"]
|
||||
unstable-msc3245 = ["ruma-common/unstable-msc3245"]
|
||||
unstable-msc3246 = ["ruma-common/unstable-msc3246"]
|
||||
unstable-msc3440 = [
|
||||
"ruma-client-api/unstable-msc3440",
|
||||
@ -142,6 +143,7 @@ __ci = [
|
||||
"unstable-msc2675",
|
||||
"unstable-msc2676",
|
||||
"unstable-msc2677",
|
||||
"unstable-msc3245",
|
||||
"unstable-msc3246",
|
||||
"unstable-msc3440",
|
||||
"unstable-msc3488",
|
||||
|
Loading…
x
Reference in New Issue
Block a user