pub mod lights;
pub mod listen;
use std::sync::Arc;
use iced::{
advanced::graphics::core::Element,
font::{Stretch, Weight},
theme,
widget::{container, row, text, Column},
Color, Font, Length, Renderer, Subscription,
};
use crate::{
oracle::Oracle,
subscriptions::MaybePendingImage,
widgets::{
image_background::image_background,
room_navigation::{Page, RoomNavigation},
},
};
#[derive(Debug)]
pub struct Room {
id: &'static str,
room: crate::oracle::Room,
lights: lights::Lights,
listen: listen::Listen,
current_page: Page,
}
impl Room {
pub fn new(id: &'static str, oracle: Arc<Oracle>) -> Self {
let room = oracle.room(id).clone();
Self {
id,
listen: listen::Listen::new(oracle.clone(), &room),
lights: lights::Lights::new(oracle, &room),
room,
current_page: Page::Listen,
}
}
pub fn room_id(&self) -> &'static str {
self.id
}
pub fn update(&mut self, event: Message) -> Option<Event> {
match event {
Message::Lights(v) => self.lights.update(v).map(Event::Lights),
Message::Listen(v) => self.listen.update(v).map(Event::Listen),
Message::ChangePage(page) => {
self.current_page = page;
None
}
Message::Exit => Some(Event::Exit),
}
}
pub fn view(&self) -> Element<'_, Message, Renderer> {
let header = container(
text(self.room.name.as_ref())
.size(60)
.font(Font {
weight: Weight::Bold,
stretch: Stretch::Condensed,
..Font::with_name("Helvetica Neue")
})
.style(theme::Text::Color(Color::WHITE)),
)
.padding([40, 40, 0, 40]);
let mut col = Column::new().spacing(20).push(header);
col = col.push(match self.current_page {
Page::Climate => Element::from(row![]),
Page::Listen => self.listen.view().map(Message::Listen),
Page::Lights => self.lights.view().map(Message::Lights),
});
let background = match self.current_page {
Page::Listen => self
.listen
.background
.as_ref()
.and_then(MaybePendingImage::handle),
_ => None,
};
row![
RoomNavigation::new(self.current_page)
.width(Length::FillPortion(2))
.on_change(Message::ChangePage)
.on_exit(Message::Exit),
image_background(
background.unwrap_or_else(|| crate::theme::Image::Sunset.into()),
col.width(Length::Fill).into()
)
.width(Length::FillPortion(15))
.height(Length::Fill),
]
.height(Length::Fill)
.width(Length::Fill)
.into()
}
pub fn subscription(&self) -> Subscription<Message> {
Subscription::batch([
self.listen.subscription().map(Message::Listen),
self.lights.subscription().map(Message::Lights),
])
}
}
pub enum Event {
Lights(lights::Event),
Listen(listen::Event),
Exit,
}
#[derive(Clone, Debug)]
pub enum Message {
Lights(lights::Message),
Listen(listen::Message),
ChangePage(Page),
Exit,
}