mirror of
https://github.com/Death916/deathclock.git
synced 2026-04-10 03:04:40 -07:00
178 lines
5.9 KiB
Rust
178 lines
5.9 KiB
Rust
// #![allow(dead_code)]
|
|
mod news;
|
|
mod panes;
|
|
mod sports;
|
|
mod weather;
|
|
use chrono::{DateTime, Local};
|
|
use iced::Element;
|
|
use iced::Subscription;
|
|
use iced::Task;
|
|
use iced::time::Duration;
|
|
use iced::widget::image::Handle;
|
|
use iced::widget::pane_grid;
|
|
use iced::widget::pane_grid::Configuration;
|
|
use sports::Game;
|
|
use std::collections::HashMap;
|
|
|
|
const CLOCK_UPDATE_TIME_MS: u64 = 1500;
|
|
const UPDATE_SPORTS_TIME_MINS: u64 = 5;
|
|
const WEATHER_UPDATE_TIME_MINS: u64 = 30;
|
|
|
|
pub fn main() -> iced::Result {
|
|
iced::application(
|
|
|| (RustClock::default(), Task::perform(weather::get_weather(), Message::UpdateWeatherImg)), // Wrap it in a closure
|
|
RustClock::update,
|
|
RustClock::view,
|
|
)
|
|
.title("RustClock")
|
|
.subscription(RustClock::subscription)
|
|
.run()
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
enum PaneType {
|
|
MlbPane,
|
|
NflPane,
|
|
NbaPane,
|
|
Weather,
|
|
Clock,
|
|
News,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
enum Message {
|
|
PaneDragged(pane_grid::DragEvent),
|
|
PaneResized(pane_grid::ResizeEvent),
|
|
RunSportsUpdate,
|
|
UpdateTime,
|
|
RunWeatherUpdate,
|
|
UpdateWeatherImg(Handle),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct RustClock {
|
|
current_time: DateTime<Local>,
|
|
next_alarm: Option<DateTime<Local>>,
|
|
news: Vec<String>,
|
|
location: String,
|
|
nba_scores: Vec<Game>,
|
|
mlb_scores: Vec<Game>,
|
|
panes: pane_grid::State<PaneType>,
|
|
nba_logos: HashMap<String, Handle>,
|
|
mlb_logos: HashMap<String, Handle>,
|
|
weather_handle: Option<Handle>,
|
|
}
|
|
impl RustClock {
|
|
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(_) => 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()
|
|
}
|
|
}
|
|
}
|
|
|
|
fn subscription(&self) -> Subscription<Message> {
|
|
Subscription::batch(vec![
|
|
iced::time::every(Duration::from_millis(CLOCK_UPDATE_TIME_MS))
|
|
.map(|_| Message::UpdateTime),
|
|
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::RunWeatherUpdate),
|
|
])
|
|
}
|
|
|
|
fn view(state: &RustClock) -> Element<'_, Message> {
|
|
pane_grid(&state.panes, |_panes, pane_state, _is_maximized| {
|
|
let content: Element<'_, Message> = match pane_state {
|
|
PaneType::NbaPane => panes::render_nba_pane(&state.nba_scores, &state.nba_logos),
|
|
PaneType::NflPane => panes::render_nfl_pane(),
|
|
PaneType::News => panes::render_news_pane(),
|
|
PaneType::MlbPane => panes::render_mlb_pane(&state.mlb_scores, &state.mlb_logos),
|
|
PaneType::Clock => panes::render_clock_pane(),
|
|
PaneType::Weather => {
|
|
panes::render_weather_pane(&state.weather_handle, &state.location)
|
|
}
|
|
};
|
|
pane_grid::Content::new(content)
|
|
})
|
|
.on_drag(Message::PaneDragged)
|
|
.on_resize(10, Message::PaneResized)
|
|
.into()
|
|
}
|
|
}
|
|
|
|
impl Default for RustClock {
|
|
fn default() -> Self {
|
|
let mlb_logos_bytes = sports::get_mlb_logos();
|
|
let nba_logos_bytes = sports::get_nba_logos();
|
|
|
|
let mlb_logos: HashMap<String, Handle> = mlb_logos_bytes
|
|
.into_iter()
|
|
.map(|(k, v)| (k, Handle::from_bytes(v)))
|
|
.collect();
|
|
let nba_logos: HashMap<String, Handle> = nba_logos_bytes
|
|
.into_iter()
|
|
.map(|(k, v)| (k, Handle::from_bytes(v)))
|
|
.collect();
|
|
|
|
|
|
RustClock {
|
|
current_time: Local::now(),
|
|
next_alarm: None,
|
|
news: Vec::new(),
|
|
location: "Sacramento".to_string(),
|
|
nba_scores: { sports::update_nba() },
|
|
mlb_scores: { sports::update_mlb() },
|
|
mlb_logos,
|
|
nba_logos,
|
|
weather_handle: None,
|
|
panes: {
|
|
let config = Configuration::Split {
|
|
axis: pane_grid::Axis::Horizontal,
|
|
ratio: 0.05,
|
|
a: Box::new(Configuration::Pane(PaneType::Clock)),
|
|
b: Box::new(Configuration::Split {
|
|
axis: pane_grid::Axis::Vertical,
|
|
ratio: 0.25,
|
|
a: Box::new(Configuration::Pane(PaneType::NbaPane)),
|
|
b: Box::new(Configuration::Split {
|
|
axis: pane_grid::Axis::Vertical,
|
|
ratio: 0.65,
|
|
a: Box::new(Configuration::Pane(PaneType::Weather)),
|
|
b: Box::new(Configuration::Split {
|
|
axis: pane_grid::Axis::Horizontal,
|
|
ratio: 0.7,
|
|
a: Box::new(Configuration::Pane(PaneType::MlbPane)),
|
|
b: Box::new(Configuration::Pane(PaneType::NflPane)),
|
|
}),
|
|
}),
|
|
}),
|
|
};
|
|
|
|
pane_grid::State::with_configuration(config)
|
|
},
|
|
}
|
|
}
|
|
}
|