iced_chat_widget/
state.rs

1use std::collections::HashMap;
2
3use rand::Rng;
4
5use crate::message::ChatMessage;
6
7pub struct ChatState<M>
8where
9    M: ChatMessage,
10{
11    auto_scroll: bool,
12    messages: HashMap<u32, M>,
13    on_message_actions: HashMap<u32, Box<dyn Fn(&M)>>,
14    rng: rand::rngs::ThreadRng,
15}
16
17impl<M> ChatState<M>
18where
19    M: ChatMessage + Clone + 'static,
20{
21    pub fn new() -> Self {
22        Self {
23            auto_scroll: true,
24            messages: HashMap::new(),
25            on_message_actions: HashMap::new(),
26            rng: rand::rng(),
27        }
28    }
29
30    pub fn automatic_scroll(&self) -> bool {
31        self.auto_scroll
32    }
33
34    pub fn set_automatic_scroll(&mut self, value: bool) {
35        self.auto_scroll = value;
36    }
37
38    pub fn subscribe_on_message_action<F>(&mut self, callback: F) -> u32
39    where
40        F: Fn(&M) + 'static,
41    {
42        let id = self.rng.random::<u32>();
43        self.on_message_actions.insert(id, Box::new(callback));
44        id
45    }
46
47    pub fn unsubscribe_on_message_action<F>(&mut self, callback_id: &u32)
48    where
49        F: Fn(&M) + 'static,
50    {
51        self.on_message_actions.remove(callback_id);
52    }
53
54    pub fn clear_messages(&mut self) {
55        self.messages.clear();
56    }
57
58    pub fn get_message(&self, message_id: &u32) -> Option<&M> {
59        self.messages.get(message_id)
60    }
61
62    pub fn get_message_mut(&mut self, message_id: &u32) -> Option<&mut M> {
63        self.messages.get_mut(message_id)
64    }
65
66    pub fn get_messages(&self, message_ids: Vec<&u32>) -> Vec<&M> {
67        message_ids
68            .iter()
69            .filter_map(|id| self.messages.get(id))
70            .collect()
71    }
72
73    pub fn get_messages_ids(&self) -> Vec<u32> {
74        self.messages.keys().cloned().collect()
75    }
76
77    pub fn get_message_pairs(&self, message_ids: &Vec<u32>) -> Vec<(u32, &M)> {
78        message_ids
79            .iter()
80            .filter_map(|id| self.messages.get(id).map(|msg| (*id, msg)))
81            .collect()
82    }
83
84    pub fn get_all_message_pairs(&self) -> Vec<(u32, &M)> {
85        self.messages.iter().map(|(id, msg)| (*id, msg)).collect()
86    }
87
88    pub fn add_messages(&mut self, messages: &Vec<M>) -> Vec<(u32, &M)> {
89        let messages_internal = messages.clone();
90
91        let new_message_ids: Vec<u32> = messages_internal
92            .iter()
93            .map(|message| {
94                let (new_message_id, _) = self.insert_message(message.clone());
95                new_message_id
96            })
97            .collect();
98        self.get_message_pairs(&new_message_ids)
99    }
100
101    pub fn add_message(&mut self, message: M) -> (u32, &M) {
102        let message = message.clone();
103        self.insert_message(message)
104    }
105
106    fn insert_message(&mut self, mut message: M) -> (u32, &M) {
107        let id = self.rng.random::<u32>();
108        message.set_id(id);
109        self.messages.insert(id, message);
110
111        let message = &self.messages[&id];
112        for callback in self.on_message_actions.values() {
113            callback(message);
114        }
115
116        (id, message)
117    }
118}