events: Improve usability and docs of m.room.message
reply constructors
This commit is contained in:
parent
24950b208e
commit
49e5d45ac9
@ -20,6 +20,8 @@ pub mod feedback;
|
|||||||
mod relation_serde;
|
mod relation_serde;
|
||||||
mod reply;
|
mod reply;
|
||||||
|
|
||||||
|
pub use reply::ReplyBaseEvent;
|
||||||
|
|
||||||
/// The content of an `m.room.message` event.
|
/// The content of an `m.room.message` event.
|
||||||
///
|
///
|
||||||
/// This event is used when sending messages in a room.
|
/// This event is used when sending messages in a room.
|
||||||
@ -81,20 +83,28 @@ impl RoomMessageEventContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a plain text reply to a message.
|
/// Creates a plain text reply to a message.
|
||||||
pub fn text_reply_plain(reply: impl fmt::Display, original_message: &RoomMessageEvent) -> Self {
|
pub fn text_reply_plain(
|
||||||
|
reply: impl fmt::Display,
|
||||||
|
original_message: &impl ReplyBaseEvent,
|
||||||
|
) -> Self {
|
||||||
let quoted = reply::get_plain_quote_fallback(original_message);
|
let quoted = reply::get_plain_quote_fallback(original_message);
|
||||||
|
|
||||||
let body = format!("{}\n\n{}", quoted, reply);
|
let body = format!("{}\n\n{}", quoted, reply);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
relates_to: Some(Relation::Reply {
|
relates_to: Some(Relation::Reply {
|
||||||
in_reply_to: InReplyTo { event_id: original_message.event_id.clone() },
|
in_reply_to: InReplyTo { event_id: original_message.event_id().clone() },
|
||||||
}),
|
}),
|
||||||
..Self::text_plain(body)
|
..Self::text_plain(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a html text reply to a message.
|
/// Creates a html text reply to a message.
|
||||||
|
///
|
||||||
|
/// Different from `text_reply_plain`, this constructor requires specifically a
|
||||||
|
/// [`RoomMessageEvent`] since it creates a permalink to the previous message, for which the
|
||||||
|
/// room ID is required. If you want to reply to a [`SyncRoomMessageEvent`], you have to convert
|
||||||
|
/// it first by calling [`.into_full_event()`][crate::SyncMessageEvent::into_full_event].
|
||||||
pub fn text_reply_html(
|
pub fn text_reply_html(
|
||||||
reply: impl fmt::Display,
|
reply: impl fmt::Display,
|
||||||
html_reply: impl fmt::Display,
|
html_reply: impl fmt::Display,
|
||||||
@ -115,16 +125,21 @@ impl RoomMessageEventContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a plain text notice reply to a message.
|
/// Creates a plain text notice reply to a message.
|
||||||
|
///
|
||||||
|
/// Different from `notice_reply_plain`, this constructor requires specifically a
|
||||||
|
/// [`RoomMessageEvent`] since it creates a permalink to the previous message, for which the
|
||||||
|
/// room ID is required. If you want to reply to a [`SyncRoomMessageEvent`], you have to convert
|
||||||
|
/// it first by calling [`.into_full_event()`][crate::SyncMessageEvent::into_full_event].
|
||||||
pub fn notice_reply_plain(
|
pub fn notice_reply_plain(
|
||||||
reply: impl fmt::Display,
|
reply: impl fmt::Display,
|
||||||
original_message: &RoomMessageEvent,
|
original_message: &impl ReplyBaseEvent,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let quoted = reply::get_plain_quote_fallback(original_message);
|
let quoted = reply::get_plain_quote_fallback(original_message);
|
||||||
|
|
||||||
let body = format!("{}\n\n{}", quoted, reply);
|
let body = format!("{}\n\n{}", quoted, reply);
|
||||||
Self {
|
Self {
|
||||||
relates_to: Some(Relation::Reply {
|
relates_to: Some(Relation::Reply {
|
||||||
in_reply_to: InReplyTo { event_id: original_message.event_id.clone() },
|
in_reply_to: InReplyTo { event_id: original_message.event_id().clone() },
|
||||||
}),
|
}),
|
||||||
..Self::notice_plain(body)
|
..Self::notice_plain(body)
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,90 @@
|
|||||||
use indoc::formatdoc;
|
use indoc::formatdoc;
|
||||||
|
use ruma_identifiers::{EventId, UserId};
|
||||||
|
|
||||||
use super::{FormattedBody, MessageType, RoomMessageEvent};
|
use super::{
|
||||||
|
FormattedBody, MessageType, RoomMessageEvent, RoomMessageEventContent, SyncRoomMessageEvent,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn get_plain_quote_fallback(original_message: &RoomMessageEvent) -> String {
|
/// An event that can be replied to.
|
||||||
match &original_message.content.msgtype {
|
///
|
||||||
|
/// This trait only exists to allow the plain-text `reply` constructors on `MessageEventContent` to
|
||||||
|
/// use either a [`RoomMessageEvent`] or a [`SyncRoomMessageEvent`] as the event being replied to.
|
||||||
|
pub trait ReplyBaseEvent {
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn event_id(&self) -> &EventId;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn sender(&self) -> &UserId;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn content(&self) -> &RoomMessageEventContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReplyBaseEvent for RoomMessageEvent {
|
||||||
|
fn event_id(&self) -> &EventId {
|
||||||
|
&self.event_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sender(&self) -> &UserId {
|
||||||
|
&self.sender
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content(&self) -> &RoomMessageEventContent {
|
||||||
|
&self.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReplyBaseEvent for SyncRoomMessageEvent {
|
||||||
|
fn event_id(&self) -> &EventId {
|
||||||
|
&self.event_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sender(&self) -> &UserId {
|
||||||
|
&self.sender
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content(&self) -> &RoomMessageEventContent {
|
||||||
|
&self.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_plain_quote_fallback(original_message: &impl ReplyBaseEvent) -> String {
|
||||||
|
let sender = original_message.sender();
|
||||||
|
|
||||||
|
match &original_message.content().msgtype {
|
||||||
MessageType::Audio(_) => {
|
MessageType::Audio(_) => {
|
||||||
format!("> <{}> sent an audio file.", original_message.sender)
|
format!("> <{}> sent an audio file.", sender)
|
||||||
}
|
}
|
||||||
MessageType::Emote(content) => {
|
MessageType::Emote(content) => {
|
||||||
format!("> * <{}> {}", original_message.sender, content.body)
|
format!("> * <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
MessageType::File(_) => {
|
MessageType::File(_) => {
|
||||||
format!("> <{}> sent a file.", original_message.sender)
|
format!("> <{}> sent a file.", sender)
|
||||||
}
|
}
|
||||||
MessageType::Image(_) => {
|
MessageType::Image(_) => {
|
||||||
format!("> <{}> sent an image.", original_message.sender)
|
format!("> <{}> sent an image.", sender)
|
||||||
}
|
}
|
||||||
MessageType::Location(content) => {
|
MessageType::Location(content) => {
|
||||||
format!("> <{}> {}", original_message.sender, content.body)
|
format!("> <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
MessageType::Notice(content) => {
|
MessageType::Notice(content) => {
|
||||||
format!("> <{}> {}", original_message.sender, content.body)
|
format!("> <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
MessageType::ServerNotice(content) => {
|
MessageType::ServerNotice(content) => {
|
||||||
format!("> <{}> {}", original_message.sender, content.body)
|
format!("> <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
MessageType::Text(content) => {
|
MessageType::Text(content) => {
|
||||||
format!("> <{}> {}", original_message.sender, content.body)
|
format!("> <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
MessageType::Video(_) => {
|
MessageType::Video(_) => {
|
||||||
format!("> <{}> sent a video.", original_message.sender)
|
format!("> <{}> sent a video.", sender)
|
||||||
}
|
}
|
||||||
MessageType::_Custom(content) => {
|
MessageType::_Custom(content) => {
|
||||||
format!("> <{}> {}", original_message.sender, content.body)
|
format!("> <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "unstable-pre-spec")]
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
MessageType::VerificationRequest(content) => {
|
MessageType::VerificationRequest(content) => {
|
||||||
format!("> <{}> {}", original_message.sender, content.body)
|
format!("> <{}> {}", sender, content.body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.replace('\n', "\n> ")
|
.replace('\n', "\n> ")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user