diff --git a/crates/ruma-common/src/events/poll/start.rs b/crates/ruma-common/src/events/poll/start.rs index d82f696f..24d348c7 100644 --- a/crates/ruma-common/src/events/poll/start.rs +++ b/crates/ruma-common/src/events/poll/start.rs @@ -10,7 +10,11 @@ mod poll_answers_serde; use poll_answers_serde::PollAnswersDeHelper; -use crate::{events::message::TextContentBlock, serde::StringEnum, PrivOwnedStr}; +use crate::{ + events::{message::TextContentBlock, room::message::Relation}, + serde::StringEnum, + PrivOwnedStr, +}; use super::{ compile_poll_results, @@ -30,7 +34,7 @@ use super::{ /// [`UnstablePollStartEventContent`]: super::unstable_start::UnstablePollStartEventContent #[derive(Clone, Debug, Serialize, Deserialize, EventContent)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -#[ruma_event(type = "m.poll.start", kind = MessageLike)] +#[ruma_event(type = "m.poll.start", kind = MessageLike, without_relation)] pub struct PollStartEventContent { /// The poll content of the message. #[serde(rename = "m.poll")] @@ -40,6 +44,14 @@ pub struct PollStartEventContent { #[serde(rename = "m.text")] pub text: TextContentBlock, + /// Information about related messages. + #[serde( + flatten, + skip_serializing_if = "Option::is_none", + deserialize_with = "crate::events::room::message::relation_serde::deserialize_relation" + )] + pub relates_to: Option>, + /// Whether this message is automated. #[cfg(feature = "unstable-msc3955")] #[serde( @@ -57,6 +69,7 @@ impl PollStartEventContent { Self { poll, text, + relates_to: None, #[cfg(feature = "unstable-msc3955")] automated: false, } @@ -65,12 +78,7 @@ impl PollStartEventContent { /// Creates a new `PollStartEventContent` with the given plain text fallback /// representation and poll content. pub fn with_plain_text(plain_text: impl Into, poll: PollContentBlock) -> Self { - Self { - poll, - text: TextContentBlock::plain(plain_text), - #[cfg(feature = "unstable-msc3955")] - automated: false, - } + Self::new(TextContentBlock::plain(plain_text), poll) } } diff --git a/crates/ruma-common/src/events/poll/unstable_start.rs b/crates/ruma-common/src/events/poll/unstable_start.rs index 50e17507..1366c075 100644 --- a/crates/ruma-common/src/events/poll/unstable_start.rs +++ b/crates/ruma-common/src/events/poll/unstable_start.rs @@ -9,6 +9,8 @@ use serde::{Deserialize, Serialize}; mod unstable_poll_answers_serde; mod unstable_poll_kind_serde; +use crate::events::room::message::Relation; + use self::unstable_poll_answers_serde::UnstablePollAnswersDeHelper; use super::{ compile_unstable_poll_results, generate_poll_end_fallback_text, @@ -29,7 +31,7 @@ use super::{ /// [`PollStartEventContent`]: super::start::PollStartEventContent #[derive(Clone, Debug, Serialize, Deserialize, EventContent)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -#[ruma_event(type = "org.matrix.msc3381.poll.start", kind = MessageLike)] +#[ruma_event(type = "org.matrix.msc3381.poll.start", kind = MessageLike, without_relation)] pub struct UnstablePollStartEventContent { /// The poll content of the message. #[serde(rename = "org.matrix.msc3381.poll.start")] @@ -38,18 +40,26 @@ pub struct UnstablePollStartEventContent { /// Text representation of the message, for clients that don't support polls. #[serde(rename = "org.matrix.msc1767.text")] pub text: Option, + + /// Information about related messages. + #[serde( + flatten, + skip_serializing_if = "Option::is_none", + deserialize_with = "crate::events::room::message::relation_serde::deserialize_relation" + )] + pub relates_to: Option>, } impl UnstablePollStartEventContent { /// Creates a new `PollStartEventContent` with the given poll content. pub fn new(poll_start: UnstablePollStartContentBlock) -> Self { - Self { poll_start, text: None } + Self { poll_start, text: None, relates_to: None } } /// Creates a new `PollStartEventContent` with the given plain text fallback /// representation and poll content. pub fn plain_text(text: impl Into, poll_start: UnstablePollStartContentBlock) -> Self { - Self { poll_start, text: Some(text.into()) } + Self { poll_start, text: Some(text.into()), relates_to: None } } } diff --git a/crates/ruma-common/tests/events/poll.rs b/crates/ruma-common/tests/events/poll.rs index 6bb13d89..ef4ff7e5 100644 --- a/crates/ruma-common/tests/events/poll.rs +++ b/crates/ruma-common/tests/events/poll.rs @@ -25,6 +25,7 @@ use ruma_common::{ }, }, relation::Reference, + room::message::Relation, AnyMessageLikeEvent, MessageLikeEvent, }, owned_event_id, MilliSecondsSinceUnixEpoch, @@ -176,6 +177,33 @@ fn start_event_deserialization() { }, ] }, + "m.new_content": { + "m.text": [ + { "body": "How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!" } + ], + "m.poll": { + "question": { "m.text": [{ "body": "How's the weather?" }] }, + "max_selections": 2, + "answers": [ + { + "m.id": "not-bad", + "m.text": [{ "body": "Not bad…" }], + }, + { + "m.id": "fine", + "m.text": [{ "body": "Fine." }], + }, + { + "m.id": "amazing", + "m.text": [{ "body": "Amazing!" }], + }, + ] + }, + }, + "m.relates_to": { + "rel_type": "m.replace", + "event_id": "$previous_event_id", + }, }, "event_id": "$event:notareal.hs", "origin_server_ts": 134_829_848, @@ -205,6 +233,7 @@ fn start_event_deserialization() { assert_eq!(answers[1].text[0].body, "Fine."); assert_eq!(answers[2].id, "amazing"); assert_eq!(answers[2].text[0].body, "Amazing!"); + assert_matches!(message_event.content.relates_to, Some(Relation::Replacement(_))); } #[test] @@ -413,6 +442,31 @@ fn unstable_start_event_deserialization() { }, ] }, + "m.new_content": { + "org.matrix.msc1767.text": "How's the weather?\n1. Not bad…\n2. Fine.\n3. Amazing!", + "org.matrix.msc3381.poll.start": { + "question": { "org.matrix.msc1767.text": "How's the weather?" }, + "max_selections": 2, + "answers": [ + { + "id": "not-bad", + "org.matrix.msc1767.text": "Not bad…", + }, + { + "id": "fine", + "org.matrix.msc1767.text": "Fine.", + }, + { + "id": "amazing", + "org.matrix.msc1767.text": "Amazing!", + }, + ] + }, + }, + "m.relates_to": { + "rel_type": "m.replace", + "event_id": "$previous_event_id", + }, }, "event_id": "$event:notareal.hs", "origin_server_ts": 134_829_848, @@ -442,6 +496,7 @@ fn unstable_start_event_deserialization() { assert_eq!(answers[1].text, "Fine."); assert_eq!(answers[2].id, "amazing"); assert_eq!(answers[2].text, "Amazing!"); + assert_matches!(message_event.content.relates_to, Some(Relation::Replacement(_))); } #[test]