events: Fix plain text reply constructors
Send a formatted_body, according to the spec
This commit is contained in:
parent
002d863738
commit
1e1fa06342
@ -19,6 +19,9 @@ Breaking changes:
|
|||||||
* Change `events::room` media types to use `Duration` where applicable
|
* Change `events::room` media types to use `Duration` where applicable
|
||||||
* Move `prev_content` into `unsigned`
|
* Move `prev_content` into `unsigned`
|
||||||
* Rename `identifiers::Error` to `IdParseError`
|
* Rename `identifiers::Error` to `IdParseError`
|
||||||
|
* Fix the `RoomMessageEventContent::*_reply_plain` methods that now return a
|
||||||
|
message with a `formatted_body`, according to the spec. Therefore, they only
|
||||||
|
accept `OriginalRoomMessageEvent`s like their HTML counterparts.
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
|
@ -42,8 +42,6 @@ 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.
|
||||||
@ -105,28 +103,34 @@ impl RoomMessageEventContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a plain text reply to a message.
|
/// Creates a plain text reply to a message.
|
||||||
|
///
|
||||||
|
/// This constructor requires an [`OriginalRoomMessageEvent`] since it creates a permalink to
|
||||||
|
/// the previous message, for which the room ID is required. If you want to reply to an
|
||||||
|
/// [`OriginalSyncRoomMessageEvent`], you have to convert it first by calling
|
||||||
|
/// [`.into_full_event()`][crate::events::OriginalSyncMessageLikeEvent::into_full_event].
|
||||||
pub fn text_reply_plain(
|
pub fn text_reply_plain(
|
||||||
reply: impl fmt::Display,
|
reply: impl fmt::Display,
|
||||||
original_message: &impl ReplyBaseEvent,
|
original_message: &OriginalRoomMessageEvent,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let quoted = reply::get_plain_quote_fallback(original_message);
|
let quoted = reply::get_plain_quote_fallback(original_message);
|
||||||
|
let quoted_html = reply::get_html_quote_fallback(original_message);
|
||||||
|
|
||||||
let body = format!("{}\n\n{}", quoted, reply);
|
let body = format!("{}\n\n{}", quoted, reply);
|
||||||
|
let html_body = format!("{}\n\n{}", quoted_html, reply);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
relates_to: Some(Relation::Reply {
|
relates_to: Some(Relation::Reply {
|
||||||
in_reply_to: InReplyTo { event_id: original_message.event_id().to_owned() },
|
in_reply_to: InReplyTo { event_id: original_message.event_id.to_owned() },
|
||||||
}),
|
}),
|
||||||
..Self::text_plain(body)
|
..Self::text_html(body, html_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
|
/// This constructor requires an [`OriginalRoomMessageEvent`] since it creates a permalink to
|
||||||
/// [`RoomMessageEvent`] since it creates a permalink to the previous message, for which the
|
/// the previous message, for which the room ID is required. If you want to reply to an
|
||||||
/// room ID is required. If you want to reply to a [`SyncRoomMessageEvent`], you have to convert
|
/// [`OriginalSyncRoomMessageEvent`], you have to convert it first by calling
|
||||||
/// it first by calling
|
|
||||||
/// [`.into_full_event()`][crate::events::OriginalSyncMessageLikeEvent::into_full_event].
|
/// [`.into_full_event()`][crate::events::OriginalSyncMessageLikeEvent::into_full_event].
|
||||||
pub fn text_reply_html(
|
pub fn text_reply_html(
|
||||||
reply: impl fmt::Display,
|
reply: impl fmt::Display,
|
||||||
@ -148,27 +152,34 @@ impl RoomMessageEventContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a plain text notice reply to a message.
|
/// Creates a plain text notice reply to a message.
|
||||||
|
///
|
||||||
|
/// This constructor requires an [`OriginalRoomMessageEvent`] since it creates a permalink to
|
||||||
|
/// the previous message, for which the room ID is required. If you want to reply to an
|
||||||
|
/// [`OriginalSyncRoomMessageEvent`], you have to convert it first by calling
|
||||||
|
/// [`.into_full_event()`][crate::events::OriginalSyncMessageLikeEvent::into_full_event].
|
||||||
pub fn notice_reply_plain(
|
pub fn notice_reply_plain(
|
||||||
reply: impl fmt::Display,
|
reply: impl fmt::Display,
|
||||||
original_message: &impl ReplyBaseEvent,
|
original_message: &OriginalRoomMessageEvent,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let quoted = reply::get_plain_quote_fallback(original_message);
|
let quoted = reply::get_plain_quote_fallback(original_message);
|
||||||
|
let quoted_html = reply::get_html_quote_fallback(original_message);
|
||||||
|
|
||||||
let body = format!("{}\n\n{}", quoted, reply);
|
let body = format!("{}\n\n{}", quoted, reply);
|
||||||
|
let html_body = format!("{}\n\n{}", quoted_html, reply);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
relates_to: Some(Relation::Reply {
|
relates_to: Some(Relation::Reply {
|
||||||
in_reply_to: InReplyTo { event_id: original_message.event_id().to_owned() },
|
in_reply_to: InReplyTo { event_id: original_message.event_id.to_owned() },
|
||||||
}),
|
}),
|
||||||
..Self::notice_plain(body)
|
..Self::notice_html(body, html_body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a html text notice reply to a message.
|
/// Creates a html text notice reply to a message.
|
||||||
///
|
///
|
||||||
/// Different from `notice_reply_plain`, this constructor requires specifically a
|
/// This constructor requires an [`OriginalRoomMessageEvent`] since it creates a permalink to
|
||||||
/// [`RoomMessageEvent`] since it creates a permalink to the previous message, for which the
|
/// the previous message, for which the room ID is required. If you want to reply to an
|
||||||
/// room ID is required. If you want to reply to a [`SyncRoomMessageEvent`], you have to convert
|
/// [`OriginalSyncRoomMessageEvent`], you have to convert it first by calling
|
||||||
/// it first by calling
|
|
||||||
/// [`.into_full_event()`][crate::events::OriginalSyncMessageLikeEvent::into_full_event].
|
/// [`.into_full_event()`][crate::events::OriginalSyncMessageLikeEvent::into_full_event].
|
||||||
pub fn notice_reply_html(
|
pub fn notice_reply_html(
|
||||||
reply: impl fmt::Display,
|
reply: impl fmt::Display,
|
||||||
|
@ -1,59 +1,11 @@
|
|||||||
use indoc::formatdoc;
|
use indoc::formatdoc;
|
||||||
|
|
||||||
use super::{
|
use super::{FormattedBody, MessageType, OriginalRoomMessageEvent};
|
||||||
FormattedBody, MessageType, OriginalRoomMessageEvent, OriginalSyncRoomMessageEvent,
|
|
||||||
RoomMessageEventContent,
|
|
||||||
};
|
|
||||||
use crate::{EventId, UserId};
|
|
||||||
|
|
||||||
/// An event that can be replied to.
|
pub fn get_plain_quote_fallback(original_message: &OriginalRoomMessageEvent) -> String {
|
||||||
///
|
let sender = &original_message.sender;
|
||||||
/// This trait only exists to allow the plain-text `reply` constructors on `MessageLikeEventContent`
|
|
||||||
/// 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)]
|
match &original_message.content.msgtype {
|
||||||
fn sender(&self) -> &UserId;
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn content(&self) -> &RoomMessageEventContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReplyBaseEvent for OriginalRoomMessageEvent {
|
|
||||||
fn event_id(&self) -> &EventId {
|
|
||||||
&self.event_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sender(&self) -> &UserId {
|
|
||||||
&self.sender
|
|
||||||
}
|
|
||||||
|
|
||||||
fn content(&self) -> &RoomMessageEventContent {
|
|
||||||
&self.content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ReplyBaseEvent for OriginalSyncRoomMessageEvent {
|
|
||||||
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.", sender)
|
format!("> <{}> sent an audio file.", sender)
|
||||||
}
|
}
|
||||||
@ -301,10 +253,12 @@ fn formatted_or_plain_body<'a>(formatted: &'a Option<FormattedBody>, body: &'a s
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
event_id, events::MessageLikeUnsigned, room_id, user_id, MilliSecondsSinceUnixEpoch,
|
event_id,
|
||||||
|
events::{room::message::RoomMessageEventContent, MessageLikeUnsigned},
|
||||||
|
room_id, user_id, MilliSecondsSinceUnixEpoch,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{OriginalRoomMessageEvent, RoomMessageEventContent};
|
use super::OriginalRoomMessageEvent;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn plain_quote_fallback_multiline() {
|
fn plain_quote_fallback_multiline() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user