• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

voiceapiai / ralertsinua / #3

08 May 2024 01:27PM UTC coverage: 14.67%. First build
#3

Pull #7

voznik
fix: improve models, get by uid, tests, clean-up
Pull Request #7: feat(models): alert models from python compatibility

105 of 218 new or added lines in 17 files covered. (48.17%)

131 of 893 relevant lines covered (14.67%)

0.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/components/map.rs
1
use color_eyre::eyre::Result;
2
use ralertsinua_geo::*;
3
use ratatui::{
4
    prelude::*,
5
    widgets::{
6
        canvas::{Canvas, Painter, Shape},
7
        *,
8
    },
9
};
10
use rust_i18n::t;
11
use std::sync::Arc;
12
use tokio::sync::mpsc::UnboundedSender;
13
use tracing::debug;
14

15
use super::{Component, Frame};
16
use crate::{action::Action, config::*, constants::*, layout::*};
17

18
#[allow(unused)]
19
const PADDING: f64 = 0.5;
20

21
#[derive(Debug)]
22
pub struct Map {
23
    command_tx: Option<UnboundedSender<Action>>,
24
    #[allow(unused)]
25
    config: Arc<dyn ConfigService>,
26
    // facade: Arc<dyn AlertsInUaFacade>,
27
    geo_client: Arc<dyn AlertsInUaGeo>,
28
    selected_region: Option<Region>,
29
}
30

31
impl Map {
NEW
32
    pub fn new(config: Arc<dyn ConfigService>, geo_client: Arc<dyn AlertsInUaGeo>) -> Self {
×
33
        Self {
34
            command_tx: Option::default(),
×
35
            // facade,
36
            config,
37
            geo_client,
38
            selected_region: None,
39
        }
40
    }
41

42
    fn get_curr_area(&self, r: &Rect) -> Result<Rect> {
×
43
        let percent = 50;
×
NEW
44
        let curr_area = match self.selected_region.is_none() {
×
45
            false => {
46
                // INFO: https://ratatui.rs/how-to/layout/center-a-rect/
47
                let popup_layout = Layout::default()
×
48
                    .direction(Direction::Vertical)
×
49
                    .constraints([
×
50
                        Constraint::Percentage((100 - percent) / 2),
×
51
                        Constraint::Percentage(percent),
×
52
                        Constraint::Percentage((100 - percent) / 2),
×
53
                    ])
54
                    .split(*r);
×
55

56
                Layout::default()
×
57
                    .direction(Direction::Horizontal)
×
58
                    .constraints([
×
59
                        Constraint::Percentage((100 - percent) / 2),
×
60
                        Constraint::Percentage(percent),
×
61
                        Constraint::Percentage((100 - percent) / 2),
×
62
                    ])
63
                    .split(popup_layout[1])[1]
×
64
            }
65
            true => *r,
×
66
        };
67
        Ok(curr_area)
×
68
    }
69
}
70

71
/// Implement the Shape trait to draw map borders on canvas
72
impl Shape for Map {
73
    #[inline]
74
    fn draw(&self, painter: &mut Painter) {
×
NEW
75
        let selected_region = self.selected_region.clone();
×
NEW
76
        let borders = self.geo_client.borders();
×
77
        // If region was selected means we have last selected geo - then iterate region borders
NEW
78
        if selected_region.is_some() {
×
NEW
79
            let borders = selected_region.unwrap().borders().unwrap();
×
80
        };
NEW
81
        borders.exterior().coords().for_each(|coord| {
×
82
            if let Some((x, y)) = painter.get_point(coord.x, coord.y) {
×
83
                painter.paint(x, y, *MARKER_COLOR);
×
84
            }
85
        });
86
    }
87
}
88

89
impl Component for Map {
90
    fn display(&self) -> Result<String> {
×
NEW
91
        let regions = self.geo_client.regions();
×
NEW
92
        debug!("Map->regions: len: {}", regions.len());
×
93
        Ok("Map".to_string())
×
94
    }
95

96
    fn placement(&self) -> LayoutPoint {
×
97
        LayoutPoint(LayoutArea::Left, Some(LayoutTab::Tab1))
×
98
    }
99

100
    fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
×
101
        self.command_tx = Some(tx);
×
102
        Ok(())
×
103
    }
104

105
    fn update(&mut self, action: Action) -> Result<Option<Action>> {
×
106
        match action {
×
107
            Action::Tick => {}
NEW
108
            Action::Selected(a) => match a {
×
NEW
109
                Some(a) => {
×
NEW
110
                    self.selected_region =
×
NEW
111
                        self.geo_client.get_region_by_uid(a.location_uid).cloned()
×
112
                }
113
                None => {
NEW
114
                    self.selected_region = None;
×
115
                }
116
            },
117
            _ => {}
118
        }
119
        Ok(None)
×
120
    }
121

122
    fn draw(&mut self, f: &mut Frame<'_>, area: &Rect) -> Result<()> {
×
NEW
123
        let (x_bounds, y_bounds) = if self.selected_region.is_some() {
×
NEW
124
            self.selected_region.clone().unwrap().get_x_y_bounds()
×
125
        } else {
NEW
126
            self.geo_client.get_x_y_bounds()
×
127
        };
128

129
        // let (x_bounds, y_bounds) = self.geo_client.get_x_y_bounds();
130

NEW
131
        let area = self.get_curr_area(area)?;
×
132
        let widget = Canvas::default()
×
133
            .block(
134
                Block::default()
×
135
                    .borders(Borders::ALL)
×
136
                    .title(t!("views.Map.title").to_string().light_blue())
×
137
                    .title_alignment(Alignment::Center),
×
138
            )
139
            .marker(Marker::Braille)
×
140
            .x_bounds(x_bounds)
141
            .y_bounds(y_bounds)
142
            .paint(|ctx| {
×
143
                ctx.draw(self);
×
144
            })
145
            .background_color(Color::Reset);
×
146
        f.render_widget(widget, area);
×
147
        Ok(())
×
148
    }
149
}
150

151
/* #[cfg(test)]
152
mod tests {
153
    use super::*;
154
    use geo::HasDimensions;
155

156
    #[test]
157
    fn test_map_new() {
158
        let map = Map::new(Ukraine::new_arc(), Arc::new(Config::init().unwrap()));
159
        assert!(map.command_tx.is_none());
160
        assert!(!map.map.borders().is_empty());
161
        assert!(map.ukraine.read().unwrap().regions().is_empty());
162
        // match map.borders.try_from()
163
    }
164
} */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc