From ec42dd491a1de0cb996ed70923572c8cac1260e8 Mon Sep 17 00:00:00 2001 From: Yorusaka Miyabi <23130178+ShadowRZ@users.noreply.github.com> Date: Fri, 27 Dec 2024 19:51:51 +0800 Subject: [PATCH] events: Add unstable support for MSC2545 for image packs --- crates/ruma-events/CHANGELOG.md | 1 + crates/ruma-events/Cargo.toml | 1 + crates/ruma-events/src/enums.rs | 9 ++ crates/ruma-events/src/image_pack.rs | 169 +++++++++++++++++++++++++++ crates/ruma-events/src/lib.rs | 2 + crates/ruma/Cargo.toml | 2 + 6 files changed, 184 insertions(+) create mode 100644 crates/ruma-events/src/image_pack.rs diff --git a/crates/ruma-events/CHANGELOG.md b/crates/ruma-events/CHANGELOG.md index 563a0f43..3ff6dc1b 100644 --- a/crates/ruma-events/CHANGELOG.md +++ b/crates/ruma-events/CHANGELOG.md @@ -15,6 +15,7 @@ Improvements: - Add unstable support for the `is_animated` flag for images, according to MSC4230. +- Add unstable support for MSC2545 for image packs. # 0.30.0 diff --git a/crates/ruma-events/Cargo.toml b/crates/ruma-events/Cargo.toml index c1afde70..251b2f4d 100644 --- a/crates/ruma-events/Cargo.toml +++ b/crates/ruma-events/Cargo.toml @@ -20,6 +20,7 @@ markdown = ["dep:pulldown-cmark"] unstable-exhaustive-types = [] unstable-msc1767 = [] unstable-msc2448 = [] +unstable-msc2545 = [] unstable-msc2747 = [] unstable-msc2867 = [] unstable-msc3061 = [] diff --git a/crates/ruma-events/src/enums.rs b/crates/ruma-events/src/enums.rs index a481c7b4..34ba59cc 100644 --- a/crates/ruma-events/src/enums.rs +++ b/crates/ruma-events/src/enums.rs @@ -17,6 +17,12 @@ event_enum! { "m.push_rules" => super::push_rules, "m.secret_storage.default_key" => super::secret_storage::default_key, "m.secret_storage.key.*" => super::secret_storage::key, + #[cfg(feature = "unstable-msc2545")] + #[ruma_enum(ident = AccountImagePack, alias = "m.image_pack")] + "im.ponies.user_emotes" => super::image_pack, + #[cfg(feature = "unstable-msc2545")] + #[ruma_enum(ident = ImagePackRooms, alias = "m.image_pack.rooms")] + "im.ponies.emote_rooms" => super::image_pack, } /// Any room account data event. @@ -130,6 +136,9 @@ event_enum! { "m.room.topic" => super::room::topic, "m.space.child" => super::space::child, "m.space.parent" => super::space::parent, + #[cfg(feature = "unstable-msc2545")] + #[ruma_enum(ident = RoomImagePack, alias = "m.image_pack")] + "im.ponies.room_emotes" => super::image_pack, #[cfg(feature = "unstable-msc3489")] #[ruma_enum(alias = "m.beacon_info")] "org.matrix.msc3672.beacon_info" => super::beacon_info, diff --git a/crates/ruma-events/src/image_pack.rs b/crates/ruma-events/src/image_pack.rs new file mode 100644 index 00000000..7765143e --- /dev/null +++ b/crates/ruma-events/src/image_pack.rs @@ -0,0 +1,169 @@ +//! Types for image packs in Matrix ([MSC2545]). +//! +//! [MSC2545]: https://github.com/matrix-org/matrix-spec-proposals/pull/2545 + +use std::collections::{BTreeMap, BTreeSet}; + +use ruma_common::{serde::StringEnum, OwnedMxcUri, OwnedRoomId}; +use ruma_macros::EventContent; +use serde::{Deserialize, Serialize}; + +use crate::{room::ImageInfo, PrivOwnedStr}; + +/// The content of an `im.ponies.room_emotes` event, +/// the unstable version of `m.image_pack` in room state events. +/// +/// State key is the identifier for the image pack in [ImagePackRoomsEventContent]. +#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)] +#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)] +#[ruma_event(type = "im.ponies.room_emotes", kind = State, state_key_type = String)] +pub struct RoomImagePackEventContent { + /// A list of images available in this image pack. + /// + /// Keys in the map are shortcodes for the images. + pub images: BTreeMap, + + /// Image pack info. + #[serde(skip_serializing_if = "Option::is_none")] + pub pack: Option, +} + +impl RoomImagePackEventContent { + /// Creates a new `RoomImagePackEventContent` with a list of images. + pub fn new(images: BTreeMap) -> Self { + Self { images, pack: None } + } +} + +/// The content of an `im.ponies.user_emotes` event, +/// the unstable version of `m.image_pack` in account data events. +#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)] +#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)] +#[ruma_event(type = "im.ponies.user_emotes", kind = GlobalAccountData)] +pub struct AccountImagePackEventContent { + /// A list of images available in this image pack. + /// + /// Keys in the map are shortcodes for the images. + pub images: BTreeMap, + + /// Image pack info. + #[serde(skip_serializing_if = "Option::is_none")] + pub pack: Option, +} + +impl AccountImagePackEventContent { + /// Creates a new `AccountImagePackEventContent` with a list of images. + pub fn new(images: BTreeMap) -> Self { + Self { images, pack: None } + } +} + +/// An image object in a image pack. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)] +pub struct PackImage { + /// The MXC URI to the media file. + pub url: OwnedMxcUri, + + /// An optional text body for this image. + /// Useful for the sticker body text or the emote alt text. + /// + /// Defaults to the shortcode. + #[serde(skip_serializing_if = "Option::is_none")] + pub body: Option, + + /// The [ImageInfo] object used for the `info` block of `m.sticker` events. + #[serde(skip_serializing_if = "Option::is_none")] + pub info: Option, + + /// The usages for the image. + #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] + pub usage: BTreeSet, +} + +impl PackImage { + /// Creates a new `PackImage` with the given MXC URI to the media file. + pub fn new(url: OwnedMxcUri) -> Self { + Self { url, body: None, info: None, usage: BTreeSet::new() } + } +} + +/// A description for the pack. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)] +pub struct PackInfo { + /// A display name for the pack. + /// This does not have to be unique from other packs in a room. + /// + /// Defaults to the room name, if the image pack event is in the room. + #[serde(skip_serializing_if = "Option::is_none")] + pub display_name: Option, + + /// The MXC URI of an avatar/icon to display for the pack. + /// + /// Defaults to the room avatar, if the pack is in the room. + /// Otherwise, the pack does not have an avatar. + #[serde(skip_serializing_if = "Option::is_none")] + pub avatar_url: Option, + + /// The usages for the pack. + #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] + pub usage: BTreeSet, + + /// The attribution of this pack. + #[serde(skip_serializing_if = "Option::is_none")] + pub attribution: Option, +} + +impl PackInfo { + /// Creates a new empty `PackInfo`. + pub fn new() -> Self { + Self::default() + } +} + +/// Usages for either an image pack or an individual image. +#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, StringEnum)] +#[ruma_enum(rename_all = "snake_case")] +#[non_exhaustive] +pub enum PackUsage { + /// Pack or image is usable as a emoticon. + Emoticon, + + /// Pack or image is usable as a sticker. + Sticker, + + #[doc(hidden)] + _Custom(PrivOwnedStr), +} + +/// The content of an `im.ponies.emote_rooms` event, +/// the unstable version of `m.image_pack.rooms`. +#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)] +#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)] +#[ruma_event(type = "im.ponies.emote_rooms", kind = GlobalAccountData)] +pub struct ImagePackRoomsEventContent { + /// A map of enabled image packs in each room. + pub rooms: BTreeMap>, +} + +impl ImagePackRoomsEventContent { + /// Creates a new `ImagePackRoomsEventContent` + /// with a map of enabled image packs in each room. + pub fn new(rooms: BTreeMap>) -> Self { + Self { rooms } + } +} + +/// Additional metadatas for a enabled room image pack. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)] +pub struct ImagePackRoomContent {} + +impl ImagePackRoomContent { + /// Creates a new empty `ImagePackRoomContent`. + pub fn new() -> Self { + Self {} + } +} diff --git a/crates/ruma-events/src/lib.rs b/crates/ruma-events/src/lib.rs index 95fb2a87..c350b211 100644 --- a/crates/ruma-events/src/lib.rs +++ b/crates/ruma-events/src/lib.rs @@ -158,6 +158,8 @@ pub mod identity_server; pub mod ignored_user_list; #[cfg(feature = "unstable-msc3552")] pub mod image; +#[cfg(feature = "unstable-msc2545")] +pub mod image_pack; pub mod key; #[cfg(feature = "unstable-msc3488")] pub mod location; diff --git a/crates/ruma/Cargo.toml b/crates/ruma/Cargo.toml index 477e4e0f..94e370be 100644 --- a/crates/ruma/Cargo.toml +++ b/crates/ruma/Cargo.toml @@ -223,6 +223,7 @@ unstable-msc2448 = [ "ruma-events?/unstable-msc2448", "ruma-federation-api?/unstable-msc2448", ] +unstable-msc2545 = ["ruma-events?/unstable-msc2545"] unstable-msc2654 = ["ruma-client-api?/unstable-msc2654"] unstable-msc2666 = ["ruma-client-api?/unstable-msc2666"] unstable-msc2747 = ["ruma-events?/unstable-msc2747"] @@ -281,6 +282,7 @@ unstable-unspecified = [ __unstable-mscs = [ "unstable-msc1767", "unstable-msc2448", + "unstable-msc2545", "unstable-msc2654", "unstable-msc2666", "unstable-msc2747",