Skip to content

Commit bbe8a23

Browse files
committed
updated tui for new weather api
1 parent 4a4a46e commit bbe8a23

File tree

5 files changed

+71
-50
lines changed

5 files changed

+71
-50
lines changed

tui/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ edition = "2021"
1111
color-eyre = { version = "0.6.3" }
1212
crossterm = { version = "0.28.1" }
1313
ratatui = { version = "0.29.0" }
14-
common = { path = "../common" }
14+
common = { path = "../common", features = ["network"] }
1515
tokio = "1.39.2"
1616
chrono = "0.4.38"
1717
simplelog = "0.12.2"

tui/src/app.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::time::{Duration, SystemTime};
55

66
use ratatui::{
77
crossterm::event::{self, poll, Event, KeyCode, KeyEvent, KeyEventKind},
8-
layout::{Constraint, Layout, Rect},
8+
layout::{Constraint, Layout},
99
Frame,
1010
};
1111

@@ -46,35 +46,19 @@ impl App {
4646
}
4747

4848
fn render_frame(&self, frame: &mut Frame) {
49-
let chunks = Layout::horizontal([
50-
Constraint::Ratio(1, 3); 3
51-
])
52-
.split(frame.area());
53-
54-
let middle_split = Layout::vertical([
55-
Constraint::Ratio(4, 5),
56-
Constraint::Ratio(1, 5),
57-
])
58-
.split(chunks[1]);
59-
60-
frame.render_widget(
61-
&self.weather,
62-
chunks[0],
63-
);
64-
frame.render_widget(
65-
&self.datetime,
66-
middle_split[0],
67-
);
68-
frame.render_widget(
69-
&self.currency,
70-
middle_split[1],
71-
);
72-
frame.render_widget(
73-
&self.transports,
74-
chunks[2],
75-
);
49+
let chunks = Layout::horizontal([Constraint::Ratio(1, 3); 3])
50+
.split(frame.area());
51+
52+
let middle_split = Layout::vertical([Constraint::Ratio(4, 5), Constraint::Ratio(1, 5)])
53+
.split(chunks[1]);
54+
55+
frame.render_widget(&self.weather, chunks[0]);
56+
frame.render_widget(&self.datetime, middle_split[0]);
57+
frame.render_widget(&self.currency, middle_split[1]);
58+
frame.render_widget(&self.transports, chunks[2]);
7659
}
7760

61+
/// Updates the state of the application every frame
7862
fn update_state(&mut self) -> io::Result<()> {
7963
match SystemTime::now().duration_since(self.weather.last_refresh) {
8064
Ok(duration) => {
@@ -103,6 +87,18 @@ impl App {
10387
Err(e) => self.transports.departures.error = Some(e.to_string()),
10488
}
10589

90+
match SystemTime::now().duration_since(self.weather.last_forecast_change) {
91+
Ok(duration) => {
92+
if duration.as_secs() > 5 {
93+
self.weather.current_forecast_day = (self.weather.current_forecast_day + 1) % 7;
94+
self.weather.last_forecast_change = SystemTime::now();
95+
}
96+
},
97+
Err(e) => {
98+
eprintln!("Error: {}", e.to_string());
99+
}
100+
}
101+
106102
Ok(())
107103
}
108104

tui/src/currency.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ use std::time::{Duration, SystemTime};
33

44
use ratatui::{
55
buffer::Buffer,
6-
layout::{Alignment, Rect},
6+
layout::Rect,
77
style::Stylize,
88
text::{Line, Text},
99
widgets::{
10-
block::{Position, Title},
1110
Block, Paragraph, Widget,
1211
},
1312
};
@@ -44,7 +43,7 @@ impl CurrencyComponent {
4443

4544
impl Widget for &CurrencyComponent {
4645
fn render(self, area: Rect, buf: &mut Buffer) {
47-
let last_refreshed = Title::from(Line::from(
46+
let last_refreshed = Line::from(
4847
match SystemTime::now().duration_since(self.last_refresh) {
4948
Ok(duration) => {
5049
let minutes = duration.as_secs() / 60;
@@ -56,14 +55,11 @@ impl Widget for &CurrencyComponent {
5655
}
5756
Err(e) => format!("Err: {}", e.to_string()),
5857
},
59-
));
60-
61-
let currency_block = Block::new().title(
62-
last_refreshed
63-
.alignment(Alignment::Center)
64-
.position(Position::Bottom),
6558
);
6659

60+
let currency_block = Block::new()
61+
.title_bottom(last_refreshed.centered());
62+
6763
let currency_text: Text = match &self.conversion {
6864
Ok(conversion) => {
6965
let refresh_date = {

tui/src/transports.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ use std::time::{Duration, SystemTime};
33

44
use ratatui::{
55
buffer::Buffer,
6-
layout::{Alignment, Rect},
6+
layout::Rect,
77
style::Stylize,
88
symbols::border,
99
text::{Line, Text},
1010
widgets::{
11-
block::{Position, Title},
1211
Block, Borders, Paragraph, Widget,
1312
},
1413
};
@@ -64,7 +63,7 @@ impl Default for TransportComponent {
6463

6564
impl Widget for &TransportComponent {
6665
fn render(self, area: Rect, buf: &mut Buffer) {
67-
let last_refreshed = Title::from(Line::from(
66+
let last_refreshed = Line::from(
6867
match SystemTime::now().duration_since(self.last_refresh) {
6968
Ok(duration) => {
7069
let seconds = duration.as_secs();
@@ -76,15 +75,11 @@ impl Widget for &TransportComponent {
7675
}
7776
Err(e) => format!("Err: {}", e.to_string()),
7877
},
79-
));
78+
);
8079

8180
let weather_block = Block::new()
8281
.borders(Borders::LEFT)
83-
.title(
84-
last_refreshed
85-
.alignment(Alignment::Center)
86-
.position(Position::Bottom),
87-
)
82+
.title_bottom(last_refreshed.centered())
8883
.border_set(border::THICK);
8984

9085
let counter_text: Text = if let Some(e) = &self.departures.error {

tui/src/weather.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
use chrono::prelude::{DateTime, Local, Timelike};
1+
use chrono::prelude::{Local, Timelike};
22
use std::time::{Duration, SystemTime};
33

44
use ratatui::{
55
buffer::Buffer,
6-
layout::{Alignment, Rect},
6+
layout::Rect,
77
style::Stylize,
88
symbols::border,
99
text::{Line, Text},
1010
widgets::{
11-
block::{Position, Title},
1211
Block, Borders, Paragraph, Widget,
1312
},
1413
};
@@ -23,6 +22,7 @@ pub struct WeatherComponent {
2322
pub weather: Result<WeatherInfo, String>,
2423
pub cooldown: Duration,
2524
pub current_forecast_day: u8,
25+
pub last_forecast_change: SystemTime,
2626
}
2727

2828
impl WeatherComponent {
@@ -41,6 +41,7 @@ impl Default for WeatherComponent {
4141
weather: Err("No weather was fetched yet".to_string()),
4242
cooldown: Duration::from_secs(30 * 60),
4343
current_forecast_day: 0,
44+
last_forecast_change: SystemTime::now(),
4445
}
4546
}
4647
}
@@ -80,6 +81,13 @@ impl Widget for &WeatherComponent {
8081
let sunset = {
8182
format!("{:02}:{:02}", sun_info.1.hour(), sun_info.1.minute())
8283
};
84+
let daytime = {
85+
let daytime = sun_info.2 as i32;
86+
let hours = daytime / 3600;
87+
let minutes = (daytime - hours * 3600) / 60;
88+
let seconds = daytime % 60;
89+
format!("{:02}h {:02}m {:02}s", hours, minutes, seconds)
90+
};
8391

8492
let separator = "-".repeat((0.66 * area.width as f32) as usize);
8593

@@ -142,10 +150,36 @@ impl Widget for &WeatherComponent {
142150
Line::from(""),
143151
Line::from(separator.clone()).centered(),
144152
Line::from("Forecast".bold()).centered(),
153+
Line::from(format!("{:6} Min | Max | UV | F Min | F Max", "Date")).centered(),
154+
Line::from(match forecast.get(self.current_forecast_day as usize) {
155+
Some(f) => format!(
156+
"{:6} {:3.0} | {:3.0} | {:1.2} | {:3.0} | {:3.0}",
157+
f.time.format("%a %d"),
158+
f.temperature_2m_min,
159+
f.temperature_2m_max,
160+
f.uv_index_max,
161+
f.apparent_temperature_min,
162+
f.apparent_temperature_max
163+
),
164+
None => "No forecast available".to_string(),
165+
}).centered(),
166+
Line::from(match forecast.get((self.current_forecast_day as usize + 1) % 7) {
167+
Some(f) => format!(
168+
"{:6} {:3.0} | {:3.0} | {:1.2} | {:3.0} | {:3.0}",
169+
f.time.format("%a %d"),
170+
f.temperature_2m_min,
171+
f.temperature_2m_max,
172+
f.uv_index_max,
173+
f.apparent_temperature_min,
174+
f.apparent_temperature_max
175+
),
176+
None => "No forecast available".to_string(),
177+
}).centered(),
145178
Line::from(separator.clone()).centered(),
146179
Line::from("🌕 Day time ☀️".bold()).centered(),
147180
Line::from(""),
148181
Line::from(format!("🌅 {} 🌄 {}", sunrise, sunset)).centered(),
182+
Line::from(format!("({})", daytime)).centered(),
149183
])
150184
}
151185
Err(e) => {

0 commit comments

Comments
 (0)