revolt_database/models/channel_unreads/ops/
reference.rs

1use revolt_result::Result;
2use ulid::Ulid;
3
4use crate::{ChannelCompositeKey, ChannelUnread, ReferenceDb};
5
6use super::AbstractChannelUnreads;
7
8#[async_trait]
9impl AbstractChannelUnreads for ReferenceDb {
10    /// Acknowledge a message.
11    async fn acknowledge_message(
12        &self,
13        channel_id: &str,
14        user_id: &str,
15        message_id: &str,
16    ) -> Result<Option<ChannelUnread>> {
17        let mut unreads = self.channel_unreads.lock().await;
18        let key = ChannelCompositeKey {
19            channel: channel_id.to_string(),
20            user: user_id.to_string(),
21        };
22
23        if let Some(unread) = unreads.get_mut(&key) {
24            unread.mentions = None;
25            unread.last_id.replace(message_id.to_string());
26        } else {
27            unreads.insert(
28                key.clone(),
29                ChannelUnread {
30                    id: key.clone(),
31                    last_id: Some(message_id.to_string()),
32                    mentions: None,
33                },
34            );
35        }
36
37        Ok(unreads.get(&key).cloned())
38    }
39
40    /// Acknowledge many channels.
41    async fn acknowledge_channels(&self, user_id: &str, channel_ids: &[String]) -> Result<()> {
42        let current_time = Ulid::new().to_string();
43        for channel_id in channel_ids {
44            #[allow(clippy::disallowed_methods)]
45            self.acknowledge_message(channel_id, user_id, &current_time)
46                .await?;
47        }
48
49        Ok(())
50    }
51
52    /// Add a mention.
53    async fn add_mention_to_unread<'a>(
54        &self,
55        channel_id: &str,
56        user_id: &str,
57        message_ids: &[String],
58    ) -> Result<()> {
59        let mut unreads = self.channel_unreads.lock().await;
60        let key = ChannelCompositeKey {
61            channel: channel_id.to_string(),
62            user: user_id.to_string(),
63        };
64
65        if let Some(unread) = unreads.get_mut(&key) {
66            unread.mentions.replace(message_ids.to_vec());
67        } else {
68            unreads.insert(
69                key.clone(),
70                ChannelUnread {
71                    id: key,
72                    last_id: None,
73                    mentions: Some(message_ids.to_vec()),
74                },
75            );
76        }
77
78        Ok(())
79    }
80
81    /// Add a mention to multiple users.
82    async fn add_mention_to_many_unreads<'a>(
83        &self,
84        channel_id: &str,
85        user_ids: &[String],
86        message_ids: &[String],
87    ) -> Result<()> {
88        let mut unreads = self.channel_unreads.lock().await;
89
90        for user_id in user_ids {
91            let key = ChannelCompositeKey {
92                channel: channel_id.to_string(),
93                user: user_id.to_string(),
94            };
95
96            if let Some(unread) = unreads.get_mut(&key) {
97                unread.mentions.replace(message_ids.to_vec());
98            } else {
99                unreads.insert(
100                    key.clone(),
101                    ChannelUnread {
102                        id: key,
103                        last_id: None,
104                        mentions: Some(message_ids.to_vec()),
105                    },
106                );
107            }
108        }
109
110        Ok(())
111    }
112
113    async fn fetch_unread_mentions(&self, user_id: &str) -> Result<Vec<ChannelUnread>> {
114        let unreads = self.channel_unreads.lock().await;
115        Ok(unreads
116            .values()
117            .filter(|unread| unread.id.user == user_id && unread.mentions.is_some())
118            .cloned()
119            .collect())
120    }
121
122    /// Fetch all channel unreads for a user.
123    async fn fetch_unreads(&self, user_id: &str) -> Result<Vec<ChannelUnread>> {
124        let unreads = self.channel_unreads.lock().await;
125        Ok(unreads
126            .values()
127            .filter(|unread| unread.id.user == user_id)
128            .cloned()
129            .collect())
130    }
131
132    /// Fetch unread for a specific user in a channel.
133    async fn fetch_unread(&self, user_id: &str, channel_id: &str) -> Result<Option<ChannelUnread>> {
134        let unreads = self.channel_unreads.lock().await;
135
136        Ok(unreads
137            .get(&ChannelCompositeKey {
138                channel: channel_id.to_string(),
139                user: user_id.to_string(),
140            })
141            .cloned())
142    }
143}