
Major improvements leveraging the shared church-core library: - **Replace custom Event struct**: Now using church-core::Event directly with built-in helper methods (formatted_date, clean_description, etc.) - **Remove duplicate HTML cleaning**: Using church-core's clean_description() - **Simplify API integration**: Replace custom ApiClient with church-core's ChurchApiClient and standardized endpoints - **Remove redundant dependencies**: html2text, chrono no longer needed - **Clean up configuration**: Remove unused cache settings, church-core handles caching - **Streamline image loading**: Remove redundant HEAD requests, keep essential validation Result: 37+ lines of duplicate code removed, 2 dependencies eliminated, zero functionality lost. Project now maximizes church-core capabilities while maintaining all original features. Fixes: Eliminates code duplication and maintenance overhead
181 lines
6.6 KiB
Rust
181 lines
6.6 KiB
Rust
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()
|
|
} |