Refactor weather popup to use WeatherResponse and Config directly

- Update `main.rs` to pass `WeatherResponse` and `Config` directly to the `show_popup` function.
- Refactore `show_popup.rs` to receive `WeatherResponse` and `Config` as parameters and handle UI rendering accordingly.
- Remove redundant parsing of weather data and configuration within the popup.
- Simplifie the data flow by directly passing the necessary structures to the popup.
This commit is contained in:
Candifloss 2025-11-07 17:53:05 +05:30
parent b169bc9530
commit 3540f8d75a
2 changed files with 44 additions and 93 deletions

View File

@ -22,39 +22,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.join("candydesktop/owm_widget.json"); .join("candydesktop/owm_widget.json");
let json_data = fs::read_to_string(&cache_path)?; let json_data = fs::read_to_string(&cache_path)?;
let resp: WeatherResponse = serde_json::from_str(&json_data)?; let weather_data: WeatherResponse = serde_json::from_str(&json_data)?;
let city = resp.name.clone().unwrap_or_else(|| "Unknown".into()); show_popup::show_popup(weather_data, cfg)?;
let country = resp
.sys
.as_ref()
.and_then(|s| s.country.clone())
.unwrap_or_else(|| String::new());
let (weather_main, weather_description, icon) = if let Some(w) = resp.weather.first() {
(w.main.clone(), w.description.clone(), w.icon.clone())
} else {
("N/A".into(), "N/A".into(), String::new())
};
let temp = resp.main.as_ref().and_then(|m| m.temp).unwrap_or(0.0);
let temperature = format!("{temp:.1}");
let unit = match cfg.query_params.units.as_str() {
"metric" => 'C',
"imperial" => 'F',
"standard" => 'K',
_ => '?',
};
show_popup::show_popup(
city,
country,
weather_main,
weather_description,
icon,
temperature,
unit,
)?;
} }
other => return Err(format!("Unsupported api_version: {other:?}").into()), other => return Err(format!("Unsupported api_version: {other:?}").into()),
} }

View File

@ -5,39 +5,20 @@ use iced::{
widget::{Column, Row, Space, Text, column, row}, widget::{Column, Row, Space, Text, column, row},
window, window,
}; };
use owm_rs::free_api_v25::current::WeatherResponse;
use owm_widg_config;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Message {} enum Message {}
struct WeatherPopup { struct WeatherPopup {
city: String, resp: WeatherResponse,
country: String, conf: owm_widg_config::config::Config,
weather_main: String,
weather_description: String,
icon_code: String,
temperature: String,
unit: char,
} }
impl WeatherPopup { impl WeatherPopup {
fn new( fn new(resp: WeatherResponse, conf: owm_widg_config::config::Config) -> Self {
city: String, Self { resp, conf }
country: String,
weather_main: String,
weather_description: String,
icon_code: String,
temperature: String,
unit: char,
) -> Self {
Self {
city,
country,
weather_main,
weather_description,
icon_code,
temperature,
unit,
}
} }
fn update(&mut self, _message: Message) -> Task<Message> { fn update(&mut self, _message: Message) -> Task<Message> {
@ -45,11 +26,35 @@ impl WeatherPopup {
} }
fn view(&self) -> iced::Element<Message> { fn view(&self) -> iced::Element<Message> {
// Data
let default_font = "IosevkaTermSlab Nerd Font Mono"; let default_font = "IosevkaTermSlab Nerd Font Mono";
let city = self.resp.name.clone().unwrap_or_else(|| "Unknown".into());
let country = self
.resp
.sys
.as_ref()
.and_then(|s| s.country.clone())
.unwrap_or_else(|| String::new());
let (weather_main, weather_description, icon_code) =
if let Some(w) = self.resp.weather.first() {
(w.main.clone(), w.description.clone(), w.icon.clone())
} else {
("N/A".into(), "N/A".into(), String::new())
};
let temp = self.resp.main.as_ref().and_then(|m| m.temp).unwrap_or(0.0);
let temperature = format!("{temp:.1}");
let unit = match self.conf.query_params.units.as_str() {
"metric" => 'C',
"imperial" => 'F',
"standard" => 'K',
_ => '?',
};
// UI
column![ column![
// City and country // City and country
Row::with_children(vec![ Row::with_children(vec![
Text::new(format!("{}, {}", self.city, self.country)) Text::new(format!("{city}, {country}"))
.font(Font { .font(Font {
family: Family::Name(default_font), family: Family::Name(default_font),
..Font::DEFAULT ..Font::DEFAULT
@ -60,7 +65,7 @@ impl WeatherPopup {
.width(Length::Fill), .width(Length::Fill),
// Weather icon and temperature // Weather icon and temperature
Row::with_children(vec![ Row::with_children(vec![
Text::new(icon_to_nerd_font(&self.icon_code)) Text::new(icon_to_nerd_font(&icon_code))
.font(Font { .font(Font {
family: Family::Name(default_font), family: Family::Name(default_font),
..Font::DEFAULT ..Font::DEFAULT
@ -69,7 +74,7 @@ impl WeatherPopup {
.size(40) .size(40)
.into(), .into(),
Space::with_width(Length::Fill).into(), Space::with_width(Length::Fill).into(),
Text::new(format!("{}°{}", self.temperature, self.unit)) Text::new(format!("{temperature}°{unit}"))
.font(Font { .font(Font {
family: Family::Name(default_font), family: Family::Name(default_font),
..Font::DEFAULT ..Font::DEFAULT
@ -80,16 +85,13 @@ impl WeatherPopup {
.width(Length::Fill), .width(Length::Fill),
// Weather description // Weather description
Row::with_children(vec![ Row::with_children(vec![
Text::new(format!( Text::new(format!("{weather_main} - {weather_description}"))
"{} - {}", .font(Font {
self.weather_main, self.weather_description family: Family::Name(default_font),
)) ..Font::DEFAULT
.font(Font { })
family: Family::Name(default_font), .size(16)
..Font::DEFAULT .into(),
})
.size(16)
.into(),
]) ])
.width(Length::Fill), .width(Length::Fill),
] ]
@ -100,15 +102,7 @@ impl WeatherPopup {
} }
} }
pub fn show_popup( pub fn show_popup(resp: WeatherResponse, conf: owm_widg_config::config::Config) -> iced::Result {
city: String,
country: String,
weather_main: String,
weather_description: String,
icon_code: String,
temperature: String,
unit: char,
) -> iced::Result {
iced::application( iced::application(
"Weather Popup", // Title "Weather Popup", // Title
WeatherPopup::update, WeatherPopup::update,
@ -123,20 +117,7 @@ pub fn show_popup(
decorations: false, decorations: false,
..window::Settings::default() ..window::Settings::default()
}) })
.run_with(move || { .run_with(move || (WeatherPopup::new(resp, conf), Task::none()))
(
WeatherPopup::new(
city,
country,
weather_main,
weather_description,
icon_code,
temperature,
unit,
),
Task::none(),
)
})
} }
/// Convert OWM icon codes (e.g. "01d", "09n") to Nerd Font weather glyphs. /// Convert OWM icon codes (e.g. "01d", "09n") to Nerd Font weather glyphs.