1use std::time::Duration;
6
7use js_int::UInt;
8use ruma_macros::EventContent;
9use serde::{Deserialize, Serialize};
10
11use super::{
12 file::{CaptionContentBlock, FileContentBlock},
13 image::ThumbnailContentBlock,
14 message::TextContentBlock,
15 room::message::Relation,
16};
17
18#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
26#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
27#[ruma_event(type = "org.matrix.msc1767.video", kind = MessageLike, without_relation)]
28pub struct VideoEventContent {
29 #[serde(rename = "org.matrix.msc1767.text")]
31 pub text: TextContentBlock,
32
33 #[serde(rename = "org.matrix.msc1767.file")]
35 pub file: FileContentBlock,
36
37 #[serde(rename = "org.matrix.msc1767.video_details", skip_serializing_if = "Option::is_none")]
39 pub video_details: Option<VideoDetailsContentBlock>,
40
41 #[serde(
45 rename = "org.matrix.msc1767.thumbnail",
46 default,
47 skip_serializing_if = "ThumbnailContentBlock::is_empty"
48 )]
49 pub thumbnail: ThumbnailContentBlock,
50
51 #[serde(rename = "org.matrix.msc1767.caption", skip_serializing_if = "Option::is_none")]
53 pub caption: Option<CaptionContentBlock>,
54
55 #[cfg(feature = "unstable-msc3955")]
57 #[serde(
58 default,
59 skip_serializing_if = "ruma_common::serde::is_default",
60 rename = "org.matrix.msc1767.automated"
61 )]
62 pub automated: bool,
63
64 #[serde(
66 flatten,
67 skip_serializing_if = "Option::is_none",
68 deserialize_with = "crate::room::message::relation_serde::deserialize_relation"
69 )]
70 pub relates_to: Option<Relation<VideoEventContentWithoutRelation>>,
71}
72
73impl VideoEventContent {
74 pub fn new(text: TextContentBlock, file: FileContentBlock) -> Self {
76 Self {
77 text,
78 file,
79 video_details: None,
80 thumbnail: Default::default(),
81 caption: None,
82 #[cfg(feature = "unstable-msc3955")]
83 automated: false,
84 relates_to: None,
85 }
86 }
87
88 pub fn with_plain_text(plain_text: impl Into<String>, file: FileContentBlock) -> Self {
91 Self {
92 text: TextContentBlock::plain(plain_text),
93 file,
94 video_details: None,
95 thumbnail: Default::default(),
96 caption: None,
97 #[cfg(feature = "unstable-msc3955")]
98 automated: false,
99 relates_to: None,
100 }
101 }
102}
103
104#[derive(Clone, Debug, Serialize, Deserialize)]
106#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
107pub struct VideoDetailsContentBlock {
108 pub width: UInt,
110
111 pub height: UInt,
113
114 #[serde(
116 with = "ruma_common::serde::duration::opt_secs",
117 default,
118 skip_serializing_if = "Option::is_none"
119 )]
120 pub duration: Option<Duration>,
121}
122
123impl VideoDetailsContentBlock {
124 pub fn new(width: UInt, height: UInt) -> Self {
126 Self { width, height, duration: None }
127 }
128}