1// Copyright 2024 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
1415use as_variant::as_variant;
16use ruma::OwnedEventId;
1718use super::{EncryptedMessage, InReplyToDetails, Message, PollState, Sticker};
19use crate::timeline::ReactionsByKeyBySender;
2021#[derive(Clone, Debug)]
22pub enum MsgLikeKind {
23/// An `m.room.message` event or extensible event, including edits.
24Message(Message),
2526/// An `m.sticker` event.
27Sticker(Sticker),
2829/// An `m.poll.start` event.
30Poll(PollState),
3132/// A redacted message.
33Redacted,
3435/// An `m.room.encrypted` event that could not be decrypted.
36UnableToDecrypt(EncryptedMessage),
37}
3839/// A special kind of [`super::TimelineItemContent`] that groups together
40/// different room message types with their respective reactions and thread
41/// information.
42#[derive(Clone, Debug)]
43pub struct MsgLikeContent {
44pub kind: MsgLikeKind,
45pub reactions: ReactionsByKeyBySender,
46/// Event ID of the thread root, if this is a threaded message.
47pub thread_root: Option<OwnedEventId>,
48/// The event this message is replying to, if any.
49pub in_reply_to: Option<InReplyToDetails>,
50}
5152impl MsgLikeContent {
53#[cfg(not(tarpaulin_include))] // debug-logging functionality
54pub(crate) fn debug_string(&self) -> &'static str {
55match self.kind {
56 MsgLikeKind::Message(_) => "a message",
57 MsgLikeKind::Sticker(_) => "a sticker",
58 MsgLikeKind::Poll(_) => "a poll",
59 MsgLikeKind::Redacted => "a redacted message",
60 MsgLikeKind::UnableToDecrypt(_) => "an encrypted message we couldn't decrypt",
61 }
62 }
6364pub fn redacted() -> Self {
65Self {
66 kind: MsgLikeKind::Redacted,
67 reactions: Default::default(),
68 thread_root: None,
69 in_reply_to: None,
70 }
71 }
7273pub fn unable_to_decrypt(encrypted_message: EncryptedMessage) -> Self {
74Self {
75 kind: MsgLikeKind::UnableToDecrypt(encrypted_message),
76 reactions: Default::default(),
77 thread_root: None,
78 in_reply_to: None,
79 }
80 }
8182/// Whether this item is part of a thread.
83pub fn is_threaded(&self) -> bool {
84self.thread_root.is_some()
85 }
8687pub fn with_in_reply_to(&self, in_reply_to: InReplyToDetails) -> Self {
88Self { in_reply_to: Some(in_reply_to), ..self.clone() }
89 }
9091/// If `kind` is of the [`MsgLikeKind`][MsgLikeKind::Message] variant,
92 /// return the inner [`Message`].
93pub fn as_message(&self) -> Option<Message> {
94as_variant!(&self.kind, MsgLikeKind::Message(message) => message.clone())
95 }
96}