rush_sync_server/output/
message.rs

1use crate::core::prelude::*;
2use crate::input::keyboard::KeyAction;
3use crate::output::scroll::ScrollState;
4use unicode_segmentation::UnicodeSegmentation;
5
6pub struct Message {
7    pub content: String,
8    pub current_length: usize,
9    pub timestamp: Instant,
10}
11
12pub struct MessageManager<'a> {
13    pub messages: Vec<Message>,
14    config: &'a Config,
15    pub scroll_state: ScrollState,
16}
17
18impl<'a> MessageManager<'a> {
19    pub fn new(config: &'a Config) -> Self {
20        let scroll_state = ScrollState::new();
21        Self {
22            messages: Vec::with_capacity(config.max_messages),
23            config,
24            scroll_state,
25        }
26    }
27
28    // Neue Methode um die gesamte Content-Höhe zu erhalten
29
30    pub fn clear_messages(&mut self) {
31        self.messages.clear();
32        self.scroll_state.force_auto_scroll();
33    }
34
35    pub fn get_content_height(&self) -> usize {
36        self.messages.len()
37    }
38
39    pub fn get_messages(&self) -> Vec<(&String, usize)> {
40        let (start, end) = self.scroll_state.get_visible_range();
41        let start = start.min(self.messages.len());
42        let end = end.min(self.messages.len());
43
44        if start >= end {
45            return Vec::new();
46        }
47
48        self.messages[start..end]
49            .iter()
50            .map(|msg| (&msg.content, msg.current_length))
51            .collect()
52    }
53
54    pub fn add_message(&mut self, content: String) {
55        if self.messages.len() >= self.config.max_messages {
56            self.messages.remove(0);
57            if self.scroll_state.offset > 0 {
58                self.scroll_state.offset = self.scroll_state.offset.saturating_sub(1);
59            }
60        }
61
62        self.messages.push(Message {
63            content,
64            current_length: 1,
65            timestamp: Instant::now(),
66        });
67
68        // Erzwinge Auto-Scroll bei neuer Nachricht
69        self.scroll_state.force_auto_scroll();
70
71        // Update dimensions with current window height
72        self.scroll_state
73            .update_dimensions(self.scroll_state.window_height, self.messages.len());
74    }
75
76    pub fn handle_scroll(&mut self, action: KeyAction, window_height: usize) {
77        // Update dimensions vor dem Scrollen
78        self.scroll_state
79            .update_dimensions(window_height, self.messages.len());
80
81        match action {
82            KeyAction::ScrollUp => {
83                self.scroll_state.scroll_up(1);
84            }
85            KeyAction::ScrollDown => {
86                self.scroll_state.scroll_down(1);
87            }
88            KeyAction::PageUp => {
89                let scroll_amount = window_height.saturating_sub(1);
90                self.scroll_state.scroll_up(scroll_amount);
91            }
92            KeyAction::PageDown => {
93                let scroll_amount = window_height.saturating_sub(1);
94                self.scroll_state.scroll_down(scroll_amount);
95            }
96            _ => {}
97        }
98    }
99
100    pub fn get_visible_messages(&self) -> Vec<(&String, usize)> {
101        self.get_messages()
102    }
103
104    pub fn update_typewriter(&mut self) {
105        if let Some(last_message) = self.messages.last_mut() {
106            let total_length = last_message.content.graphemes(true).count();
107
108            if last_message.current_length < total_length
109                && last_message.timestamp.elapsed() >= self.config.typewriter_delay
110            {
111                last_message.current_length += 1;
112                last_message.timestamp = Instant::now();
113            }
114        }
115    }
116
117    pub fn log(&mut self, level: &str, message: &str) {
118        let log_message = format!("[{}] {}", level, message);
119        self.add_message(log_message);
120    }
121}