make weather async and add boot task to main iced app

This commit is contained in:
death916 2026-03-25 05:24:45 -07:00
parent 535d1f4110
commit 2402edb209
3 changed files with 36 additions and 14 deletions

View file

@ -20,7 +20,7 @@ const WEATHER_UPDATE_TIME_MINS: u64 = 30;
pub fn main() -> iced::Result {
iced::application(
|| (RustClock::default(), Task::none()), // Wrap it in a closure
|| (RustClock::default(), Task::perform(weather::get_weather(), Message::UpdateWeatherImg)), // Wrap it in a closure
RustClock::update,
RustClock::view,
)
@ -45,7 +45,8 @@ enum Message {
PaneResized(pane_grid::ResizeEvent),
RunSportsUpdate,
UpdateTime,
UpdateWeather,
RunWeatherUpdate,
UpdateWeatherImg(Handle),
}
#[derive(Debug)]
@ -62,23 +63,32 @@ struct RustClock {
weather_handle: Option<Handle>,
}
impl RustClock {
fn update(&mut self, message: Message) {
fn update(&mut self, message: Message) -> iced::Task<Message> {
match message {
Message::PaneDragged(pane_grid::DragEvent::Dropped { pane, target }) => {
self.panes.drop(pane, target);
Task::none()
}
Message::PaneDragged(_) => {}
Message::PaneDragged(_) => Task::none(),
Message::PaneResized(pane_grid::ResizeEvent { split, ratio }) => {
self.panes.resize(split, ratio);
Task::none()
}
Message::RunSportsUpdate => {
self.nba_scores = sports::update_nba();
self.mlb_scores = sports::update_mlb();
Task::none()
}
Message::UpdateTime => {
self.current_time = Local::now();
Task::none()
}
Message::RunWeatherUpdate => Task::perform(weather::get_weather(), Message::UpdateWeatherImg),
Message::UpdateWeatherImg(handle) => {
self.weather_handle = Some(handle);
Task::none()
}
Message::UpdateWeather => self.weather_handle = weather::get_weather(),
}
}
@ -89,7 +99,7 @@ impl RustClock {
iced::time::every(Duration::from_mins(UPDATE_SPORTS_TIME_MINS))
.map(|_| Message::RunSportsUpdate),
iced::time::every(Duration::from_mins(WEATHER_UPDATE_TIME_MINS))
.map(|_| Message::UpdateWeather),
.map(|_| Message::RunWeatherUpdate),
])
}
@ -127,6 +137,7 @@ impl Default for RustClock {
.map(|(k, v)| (k, Handle::from_bytes(v)))
.collect();
RustClock {
current_time: Local::now(),
next_alarm: None,
@ -136,7 +147,7 @@ impl Default for RustClock {
mlb_scores: { sports::update_mlb() },
mlb_logos,
nba_logos,
weather_handle: weather::get_weather(),
weather_handle: None,
panes: {
let config = Configuration::Split {
axis: pane_grid::Axis::Horizontal,

View file

@ -155,3 +155,4 @@ pub fn render_weather_pane<'a>(
.center_y(Fill)
.into()
}

View file

@ -1,16 +1,26 @@
use iced::widget::image::Handle;
use ureq;
use reqwest;
pub fn get_weather() -> Option<Handle> {
let image = ureq::get("https://v2.wttr.in/Sacramento.png?u0")
.header("User-Agent", "deathclock-app/1.0")
.call()
pub async fn get_weather() -> Handle {
let image = reqwest::get("https://v2.wttr.in/Sacramento.png?u0")
.await
.unwrap()
.into_body()
.read_to_vec()
.bytes()
.await
.unwrap();
let handle = Some(Handle::from_bytes(image));
let handle = handle.unwrap();
//TODO better error handling
dbg!("updating weather");
handle
}
#[tokio::test]
async fn test_get_weather() {
let handle = get_weather().await;
let handle_type: Handle = handle.clone();
assert_eq!(handle_type, handle);
}