diff --git a/crates/ruma-common/CHANGELOG.md b/crates/ruma-common/CHANGELOG.md index 44f96d9c..81d5f367 100644 --- a/crates/ruma-common/CHANGELOG.md +++ b/crates/ruma-common/CHANGELOG.md @@ -13,6 +13,8 @@ Improvements: * Stabilize default room server ACL push rule * Stabilize `room_types` in `directory::Filter` and `room_type` in `directory::PublicRoomsChunk` * Stabilize support for private read receipts +* Add stable support for threads + * Move `Relation::Thread` and associated types and methods out of `unstable-msc3440` # 0.10.3 diff --git a/crates/ruma-common/Cargo.toml b/crates/ruma-common/Cargo.toml index ebf052d3..10316960 100644 --- a/crates/ruma-common/Cargo.toml +++ b/crates/ruma-common/Cargo.toml @@ -38,7 +38,6 @@ unstable-msc2870 = [] unstable-msc3245 = ["unstable-msc3246"] unstable-msc3246 = ["unstable-msc3551", "dep:thiserror"] unstable-msc3381 = ["unstable-msc1767"] -unstable-msc3440 = [] unstable-msc3488 = ["unstable-msc1767"] unstable-msc3551 = ["unstable-msc1767"] unstable-msc3552 = ["unstable-msc3551"] diff --git a/crates/ruma-common/src/events/relation.rs b/crates/ruma-common/src/events/relation.rs index 1f06222f..10aa2cfe 100644 --- a/crates/ruma-common/src/events/relation.rs +++ b/crates/ruma-common/src/events/relation.rs @@ -4,17 +4,16 @@ use std::fmt::Debug; -#[cfg(any(feature = "unstable-msc2677", feature = "unstable-msc3440"))] use js_int::UInt; use serde::{Deserialize, Serialize}; -#[cfg(feature = "unstable-msc3440")] -use super::AnySyncMessageLikeEvent; -#[cfg(feature = "unstable-msc3440")] -use crate::serde::Raw; +use super::AnyMessageLikeEvent; #[cfg(any(feature = "unstable-msc2676", feature = "unstable-msc2677"))] use crate::MilliSecondsSinceUnixEpoch; -use crate::{serde::StringEnum, PrivOwnedStr}; +use crate::{ + serde::{Raw, StringEnum}, + PrivOwnedStr, +}; #[cfg(feature = "unstable-msc2676")] use crate::{OwnedEventId, OwnedUserId}; @@ -112,11 +111,10 @@ impl BundledReplacement { /// A bundled thread. #[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] pub struct BundledThread { /// The latest event in the thread. - pub latest_event: Box>, + pub latest_event: Box>, /// The number of events in the thread. pub count: UInt, @@ -125,11 +123,10 @@ pub struct BundledThread { pub current_user_participated: bool, } -#[cfg(feature = "unstable-msc3440")] impl BundledThread { /// Creates a new `BundledThread` with the given event, count and user participated flag. pub fn new( - latest_event: Box>, + latest_event: Box>, count: UInt, current_user_participated: bool, ) -> Self { @@ -154,8 +151,7 @@ pub struct Relations { pub replace: Option, /// Thread relation. - #[cfg(feature = "unstable-msc3440")] - #[serde(rename = "io.element.thread", alias = "m.thread")] + #[serde(rename = "m.thread")] pub thread: Option, } @@ -182,8 +178,7 @@ pub enum RelationType { Replacement, /// `m.thread`, a participant to a thread. - #[cfg(feature = "unstable-msc3440")] - #[ruma_enum(rename = "io.element.thread", alias = "m.thread")] + #[ruma_enum(rename = "m.thread")] Thread, #[doc(hidden)] diff --git a/crates/ruma-common/src/events/room/encrypted.rs b/crates/ruma-common/src/events/room/encrypted.rs index 5f6f5e2e..62149fe4 100644 --- a/crates/ruma-common/src/events/room/encrypted.rs +++ b/crates/ruma-common/src/events/room/encrypted.rs @@ -102,7 +102,6 @@ pub enum Relation { Annotation(Annotation), /// An event that belongs to a thread. - #[cfg(feature = "unstable-msc3440")] Thread(Thread), #[doc(hidden)] @@ -117,7 +116,6 @@ impl From for Relation { message::Relation::Replacement(re) => { Self::Replacement(Replacement { event_id: re.event_id }) } - #[cfg(feature = "unstable-msc3440")] message::Relation::Thread(t) => Self::Thread(Thread { event_id: t.event_id, in_reply_to: t.in_reply_to, @@ -178,7 +176,6 @@ impl Annotation { /// A thread relation for an event. #[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] pub struct Thread { /// The ID of the root message in the thread. @@ -199,7 +196,6 @@ pub struct Thread { pub is_falling_back: bool, } -#[cfg(feature = "unstable-msc3440")] impl Thread { /// Convenience method to create a regular `Thread` with the given event ID and latest /// message-like event ID. diff --git a/crates/ruma-common/src/events/room/encrypted/relation_serde.rs b/crates/ruma-common/src/events/room/encrypted/relation_serde.rs index e12287ef..ecea6027 100644 --- a/crates/ruma-common/src/events/room/encrypted/relation_serde.rs +++ b/crates/ruma-common/src/events/room/encrypted/relation_serde.rs @@ -4,10 +4,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::Annotation; #[cfg(feature = "unstable-msc2676")] use super::Replacement; -#[cfg(feature = "unstable-msc3440")] -use super::Thread; -use super::{InReplyTo, Reference, Relation}; -#[cfg(feature = "unstable-msc3440")] +use super::{InReplyTo, Reference, Relation, Thread}; use crate::OwnedEventId; impl<'de> Deserialize<'de> for Relation { @@ -17,7 +14,6 @@ impl<'de> Deserialize<'de> for Relation { { let ev = EventWithRelatesToJsonRepr::deserialize(deserializer)?; - #[cfg(feature = "unstable-msc3440")] if let Some( RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id, is_falling_back }) | RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { event_id, is_falling_back }), @@ -40,7 +36,6 @@ impl<'de> Deserialize<'de> for Relation { RelationJsonRepr::Replacement(Replacement { event_id }) => { Relation::Replacement(Replacement { event_id }) } - #[cfg(feature = "unstable-msc3440")] RelationJsonRepr::ThreadStable(_) | RelationJsonRepr::ThreadUnstable(_) => { unreachable!() } @@ -80,11 +75,10 @@ impl Serialize for Relation { Relation::Reply { in_reply_to } => { RelatesToJsonRepr { in_reply_to: Some(in_reply_to.clone()), ..Default::default() } } - #[cfg(feature = "unstable-msc3440")] Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }) => { RelatesToJsonRepr { in_reply_to: Some(in_reply_to.clone()), - relation: Some(RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { + relation: Some(RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id: event_id.clone(), is_falling_back: *is_falling_back, })), @@ -123,7 +117,6 @@ impl RelatesToJsonRepr { /// A thread relation without the reply fallback, with stable names. #[derive(Clone, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] struct ThreadStableJsonRepr { /// The ID of the root message in the thread. pub event_id: OwnedEventId, @@ -136,7 +129,6 @@ struct ThreadStableJsonRepr { /// A thread relation without the reply fallback, with unstable names. #[derive(Clone, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] struct ThreadUnstableJsonRepr { /// The ID of the root message in the thread. pub event_id: OwnedEventId, @@ -170,12 +162,10 @@ enum RelationJsonRepr { Replacement(Replacement), /// An event that belongs to a thread, with stable names. - #[cfg(feature = "unstable-msc3440")] #[serde(rename = "m.thread")] ThreadStable(ThreadStableJsonRepr), /// An event that belongs to a thread, with unstable names. - #[cfg(feature = "unstable-msc3440")] #[serde(rename = "io.element.thread")] ThreadUnstable(ThreadUnstableJsonRepr), diff --git a/crates/ruma-common/src/events/room/message.rs b/crates/ruma-common/src/events/room/message.rs index 8220f146..dd350ad0 100644 --- a/crates/ruma-common/src/events/room/message.rs +++ b/crates/ruma-common/src/events/room/message.rs @@ -166,7 +166,6 @@ impl RoomMessageEventContent { /// If `message` is a text, an emote or a notice message, it is modified to include the rich /// reply fallback. #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/rich_reply.md"))] - #[cfg(feature = "unstable-msc3440")] pub fn reply( message: MessageType, original_message: &OriginalRoomMessageEvent, @@ -198,7 +197,7 @@ impl RoomMessageEventContent { .as_ref() .filter(|_| forward_thread == ForwardThread::Yes) { - Relation::Thread(Thread::reply(event_id.clone(), original_message.event_id.clone())) + Relation::Thread(Thread::plain(event_id.clone(), original_message.event_id.clone())) } else { Relation::Reply { in_reply_to: InReplyTo { event_id: original_message.event_id.clone() }, @@ -217,17 +216,16 @@ impl RoomMessageEventContent { /// If `message` is a text, an emote or a notice message, and this is a reply in the thread, it /// is modified to include the rich reply fallback. #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/rich_reply.md"))] - #[cfg(feature = "unstable-msc3440")] pub fn for_thread( message: MessageType, previous_message: &OriginalRoomMessageEvent, - is_reply: ReplyInThread, + is_reply: ReplyWithinThread, ) -> Self { let make_reply = |body, formatted: Option| { reply::plain_and_formatted_reply_body(body, formatted.map(|f| f.body), previous_message) }; - let msgtype = if is_reply == ReplyInThread::Yes { + let msgtype = if is_reply == ReplyWithinThread::Yes { // If this is a real reply, add the rich reply fallback. match message { MessageType::Text(TextMessageEventContent { body, formatted, .. }) => { @@ -261,7 +259,7 @@ impl RoomMessageEventContent { relates_to: Some(Relation::Thread(Thread { event_id: thread_root, in_reply_to: InReplyTo { event_id: previous_message.event_id.clone() }, - is_falling_back: is_reply == ReplyInThread::No, + is_falling_back: is_reply == ReplyWithinThread::No, })), } } @@ -314,15 +312,15 @@ impl RoomMessageEventContent { } /// Whether or not to forward a [`Relation::Thread`] when sending a reply. -#[cfg(feature = "unstable-msc3440")] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[allow(clippy::exhaustive_enums)] pub enum ForwardThread { /// The thread relation in the original message is forwarded if it exists. /// - /// This should be set if your client doesn't support threads (see [MSC3440]). + /// This should be set if your client doesn't render threads (see the [info + /// box for clients which are acutely aware of threads]). /// - /// [MSC3440]: https://github.com/matrix-org/matrix-spec-proposals/pull/3440 + /// [info box for clients which are acutely aware of threads]: https://spec.matrix.org/v1.4/client-server-api/#fallback-for-unthreaded-clients Yes, /// Create a reply in the main conversation even if the original message is in a thread. @@ -332,20 +330,21 @@ pub enum ForwardThread { } /// Whether or not the message is a reply inside a thread. -#[cfg(feature = "unstable-msc3440")] #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[allow(clippy::exhaustive_enums)] -pub enum ReplyInThread { +pub enum ReplyWithinThread { /// This is a reply. /// - /// Create a proper reply _in_ the thread. + /// Create a [reply within the thread]. + /// + /// [reply within the thread]: https://spec.matrix.org/v1.4/client-server-api/#replies-within-threads Yes, /// This is not a reply. /// - /// Create a regular message in the thread, with a reply fallback, according to [MSC3440]. + /// Create a regular message in the thread, with a [fallback for unthreaded clients]. /// - /// [MSC3440]: https://github.com/matrix-org/matrix-spec-proposals/pull/3440 + /// [fallback for unthreaded clients]: https://spec.matrix.org/v1.4/client-server-api/#fallback-for-unthreaded-clients No, } @@ -520,7 +519,6 @@ pub enum Relation { Replacement(Replacement), /// An event that belongs to a thread. - #[cfg(feature = "unstable-msc3440")] Thread(Thread), #[doc(hidden)] @@ -564,7 +562,6 @@ impl Replacement { /// The content of a thread relation. #[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] pub struct Thread { /// The ID of the root message in the thread. @@ -585,7 +582,6 @@ pub struct Thread { pub is_falling_back: bool, } -#[cfg(feature = "unstable-msc3440")] impl Thread { /// Convenience method to create a regular `Thread` with the given event ID and latest /// message-like event ID. diff --git a/crates/ruma-common/src/events/room/message/relation_serde.rs b/crates/ruma-common/src/events/room/message/relation_serde.rs index c68d4b67..1afd392d 100644 --- a/crates/ruma-common/src/events/room/message/relation_serde.rs +++ b/crates/ruma-common/src/events/room/message/relation_serde.rs @@ -4,10 +4,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::Replacement; #[cfg(feature = "unstable-msc2676")] use super::RoomMessageEventContent; -#[cfg(feature = "unstable-msc3440")] -use super::Thread; -use super::{InReplyTo, Relation}; -#[cfg(any(feature = "unstable-msc2676", feature = "unstable-msc3440"))] +use super::{InReplyTo, Relation, Thread}; use crate::OwnedEventId; impl<'de> Deserialize<'de> for Relation { @@ -17,7 +14,6 @@ impl<'de> Deserialize<'de> for Relation { { let ev = EventWithRelatesToJsonRepr::deserialize(deserializer)?; - #[cfg(feature = "unstable-msc3440")] if let Some( RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id, is_falling_back }) | RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { event_id, is_falling_back }), @@ -44,7 +40,6 @@ impl<'de> Deserialize<'de> for Relation { // FIXME: Maybe we should log this, though at this point we don't even have // access to the rel_type of the unknown relation. RelationJsonRepr::Unknown => Relation::_Custom, - #[cfg(feature = "unstable-msc3440")] RelationJsonRepr::ThreadStable(_) | RelationJsonRepr::ThreadUnstable(_) => { unreachable!() } @@ -80,11 +75,10 @@ impl Serialize for Relation { new_content: Some(new_content.clone()), } } - #[cfg(feature = "unstable-msc3440")] Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }) => { EventWithRelatesToJsonRepr::new(RelatesToJsonRepr { in_reply_to: Some(in_reply_to.clone()), - relation: Some(RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { + relation: Some(RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id: event_id.clone(), is_falling_back: *is_falling_back, })), @@ -144,13 +138,11 @@ enum RelationJsonRepr { #[serde(rename = "m.replace")] Replacement(ReplacementJsonRepr), - /// An event that belongs to a thread, with unstable names. - #[cfg(feature = "unstable-msc3440")] + /// An event that belongs to a thread, with stable names. #[serde(rename = "m.thread")] ThreadStable(ThreadStableJsonRepr), /// An event that belongs to a thread, with unstable names. - #[cfg(feature = "unstable-msc3440")] #[serde(rename = "io.element.thread")] ThreadUnstable(ThreadUnstableJsonRepr), @@ -170,7 +162,6 @@ struct ReplacementJsonRepr { /// A thread relation without the reply fallback, with stable names. #[derive(Clone, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] struct ThreadStableJsonRepr { /// The ID of the root message in the thread. event_id: OwnedEventId, @@ -183,7 +174,6 @@ struct ThreadStableJsonRepr { /// A thread relation without the reply fallback, with unstable names. #[derive(Clone, Deserialize, Serialize)] -#[cfg(feature = "unstable-msc3440")] struct ThreadUnstableJsonRepr { /// The ID of the root message in the thread. event_id: OwnedEventId, diff --git a/crates/ruma-common/tests/events/relations.rs b/crates/ruma-common/tests/events/relations.rs index e65297c2..d53736af 100644 --- a/crates/ruma-common/tests/events/relations.rs +++ b/crates/ruma-common/tests/events/relations.rs @@ -149,7 +149,6 @@ fn replacement_deserialize() { } #[test] -#[cfg(feature = "unstable-msc3440")] fn thread_plain_serialize() { use ruma_common::events::room::message::Thread; @@ -172,12 +171,12 @@ fn thread_plain_serialize() { "msgtype": "m.text", "body": "", "m.relates_to": { - "rel_type": "io.element.thread", + "rel_type": "m.thread", "event_id": "$1598361704261elfgc", "m.in_reply_to": { "event_id": "$latesteventid", }, - "io.element.show_reply": true, + "is_falling_back": true, }, }) ); @@ -190,19 +189,18 @@ fn thread_plain_serialize() { "body": "", "org.matrix.msc1767.text": "", "m.relates_to": { - "rel_type": "io.element.thread", + "rel_type": "m.thread", "event_id": "$1598361704261elfgc", "m.in_reply_to": { "event_id": "$latesteventid", }, - "io.element.show_reply": true, + "is_falling_back": true, }, }) ); } #[test] -#[cfg(feature = "unstable-msc3440")] fn thread_reply_serialize() { use ruma_common::events::room::message::Thread; @@ -225,7 +223,7 @@ fn thread_reply_serialize() { "msgtype": "m.text", "body": "", "m.relates_to": { - "rel_type": "io.element.thread", + "rel_type": "m.thread", "event_id": "$1598361704261elfgc", "m.in_reply_to": { "event_id": "$repliedtoeventid", @@ -242,7 +240,7 @@ fn thread_reply_serialize() { "body": "", "org.matrix.msc1767.text": "", "m.relates_to": { - "rel_type": "io.element.thread", + "rel_type": "m.thread", "event_id": "$1598361704261elfgc", "m.in_reply_to": { "event_id": "$repliedtoeventid", @@ -253,7 +251,6 @@ fn thread_reply_serialize() { } #[test] -#[cfg(feature = "unstable-msc3440")] fn thread_stable_deserialize() { let json = json!({ "msgtype": "m.text", @@ -281,7 +278,6 @@ fn thread_stable_deserialize() { } #[test] -#[cfg(feature = "unstable-msc3440")] fn thread_unstable_deserialize() { let json = json!({ "msgtype": "m.text", diff --git a/crates/ruma/Cargo.toml b/crates/ruma/Cargo.toml index 317d8727..410076f2 100644 --- a/crates/ruma/Cargo.toml +++ b/crates/ruma/Cargo.toml @@ -141,7 +141,6 @@ unstable-msc2967 = ["ruma-client-api?/unstable-msc2967"] unstable-msc3245 = ["ruma-common/unstable-msc3245"] unstable-msc3246 = ["ruma-common/unstable-msc3246"] unstable-msc3381 = ["ruma-common/unstable-msc3381"] -unstable-msc3440 = ["ruma-common/unstable-msc3440"] unstable-msc3488 = [ "ruma-client-api?/unstable-msc3488", "ruma-common/unstable-msc3488", @@ -179,7 +178,6 @@ __ci = [ "unstable-msc3245", "unstable-msc3246", "unstable-msc3381", - "unstable-msc3440", "unstable-msc3488", "unstable-msc3551", "unstable-msc3552",