use iced::widget::{column, row, image, container, text}; use iced::{Element, Length, Theme}; use church_core::Event; use crate::{Message, LOADING_FRAMES, SETTINGS, cache::ImageCache}; pub fn render_event_title(event: &Event) -> Element<'_, Message, Theme> { container( text(&event.title) .size(if event.title.len() > 50 { SETTINGS.ui.font_sizes.title_small } else { SETTINGS.ui.font_sizes.title_large }) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.title_color()), ..Default::default() }) ) .width(Length::Fill) .padding(SETTINGS.ui.spacing.container_padding) .into() } pub fn render_event_image<'a>( event: &Event, image_cache: &ImageCache, loading_frame: usize ) -> Element<'a, Message, Theme> { container( if let Some(ref image_url) = event.image { if let Some(handle) = image_cache.get(image_url) { container( image::Image::new(handle.clone()) .width(Length::Fixed(SETTINGS.ui.image_width)) .height(Length::Fixed(SETTINGS.ui.image_height)) ) .style(|_: &Theme| container::Style { background: Some(SETTINGS.theme.image_bg_color().into()), ..Default::default() }) } else { container( column![ text(LOADING_FRAMES[loading_frame]) .size(SETTINGS.ui.font_sizes.loading_animation) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.accent_color()), ..Default::default() }), text("Loading image...") .size(SETTINGS.ui.font_sizes.loading_text) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.secondary_text_color()), ..Default::default() }) ] .spacing(SETTINGS.ui.spacing.loading_container_spacing) .align_x(iced::alignment::Horizontal::Center) ) } } else { container( text("No image available") .size(SETTINGS.ui.font_sizes.no_image_text) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.secondary_text_color()), ..Default::default() }) ) } ) .width(Length::Fixed(SETTINGS.ui.image_width)) .height(Length::Fixed(SETTINGS.ui.image_height)) .style(|_: &Theme| container::Style { background: Some(SETTINGS.theme.image_bg_color().into()), ..Default::default() }) .into() } pub fn render_event_category(event: &Event) -> Element<'_, Message, Theme> { container( text(event.category.to_string().to_uppercase()) .size(SETTINGS.ui.font_sizes.category) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.text_color()), ..Default::default() }) ) .padding(SETTINGS.ui.spacing.category_container_padding) .style(|_: &Theme| container::Style { background: Some(SETTINGS.theme.category_color().into()), ..Default::default() }) .into() } pub fn render_event_datetime(event: &Event) -> Element<'_, Message, Theme> { container( column![ text(event.formatted_date()) .size(SETTINGS.ui.font_sizes.date) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.date_color()), ..Default::default() }), text(format!("{} - {}", event.formatted_start_time(), event.formatted_end_time())) .size(SETTINGS.ui.font_sizes.time) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.time_color()), ..Default::default() }) ] .spacing(SETTINGS.ui.spacing.datetime_container_spacing) ) .padding(SETTINGS.ui.spacing.datetime_container_padding) .into() } pub fn render_event_location(event: &Event) -> Element<'_, Message, Theme> { if !event.location.is_empty() { container( row![ text("⌾") // Location/target symbol .size(SETTINGS.ui.font_sizes.location_icon) .font(iced::Font::with_name("Segoe UI Symbol")) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.location_icon_color()), ..Default::default() }), text(&event.location) .size(SETTINGS.ui.font_sizes.location_text) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.secondary_text_color()), ..Default::default() }) ] .spacing(SETTINGS.ui.spacing.location_row_spacing) .align_y(iced::Alignment::Center) ) .padding(SETTINGS.ui.spacing.location_row_padding) .into() } else { container(text("")).into() } } pub fn render_event_description(event: &Event) -> Element<'_, Message, Theme> { container( text(event.clean_description()) .size(SETTINGS.ui.font_sizes.description) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.text_color()), ..Default::default() }) ) .width(Length::Fill) .height(Length::Fill) .padding(SETTINGS.ui.spacing.description_container_padding) .style(|_: &Theme| container::Style { background: Some(SETTINGS.theme.description_bg_color().into()), ..Default::default() }) .into() } pub fn render_loading_screen() -> Element<'static, Message, Theme> { container( text("Loading events...") .size(SETTINGS.ui.font_sizes.loading_events) .style(|_: &Theme| text::Style { color: Some(SETTINGS.theme.accent_color()), ..Default::default() }) ) .width(Length::Fill) .height(Length::Fill) .center_x(Length::Fill) .center_y(Length::Fill) .into() }