use crate::ui::UIWidget; use maud::{Markup, PreEscaped, Render, html}; #[allow(non_snake_case)] #[must_use] pub fn Image(src: &str) -> ImageWidget { ImageWidget { src: src.to_owned(), alt: String::new(), width: None, height: None, caption: None, } } pub struct ImageWidget { src: String, alt: String, width: Option, height: Option, caption: Option, } impl Render for ImageWidget { fn render(&self) -> Markup { self.render_with_class("") } } impl ImageWidget { #[must_use] pub fn alt(mut self, alt: &str) -> Self { self.alt = alt.to_string(); self } #[must_use] pub fn width(mut self, width: u32) -> Self { self.width = Some(width); self } #[must_use] pub fn height(mut self, height: u32) -> Self { self.height = Some(height); self } #[must_use] pub fn caption(mut self, caption: &str) -> Self { self.caption = Some(caption.to_string()); self } pub fn build_img(&self, class: &str) -> PreEscaped { let mut str = "")); PreEscaped(str) } } impl UIWidget for ImageWidget { fn can_inherit(&self) -> bool { true } fn base_class(&self) -> Vec { vec![] } fn extended_class(&self) -> Vec { self.base_class() } fn render_with_class(&self, class: &str) -> Markup { if let Some(caption) = &self.caption { return html! { figure class="w-fit" { (self.build_img(class)) figcaption class="mt-2 text-sm text-center text-gray-500 dark:text-gray-400" { (caption) }; } }; } self.build_img(class) } } #[allow(non_snake_case)] #[must_use] pub fn Video() -> VideoWidget { VideoWidget { src: Vec::new(), controls: false, autoplay: false, looping: false, muted: false, poster: None, width: None, height: None, } } pub struct VideoWidget { src: Vec, controls: bool, autoplay: bool, looping: bool, muted: bool, poster: Option, width: Option, height: Option, } impl Render for VideoWidget { fn render(&self) -> Markup { self.render_with_class("") } } impl VideoWidget { pub fn add_src(mut self, src: SourceWidget) -> Self { self.src.push(src); self } pub fn controls(mut self) -> Self { self.controls = true; self } pub fn autoplay(mut self) -> Self { self.autoplay = true; self } pub fn looping(mut self) -> Self { self.looping = true; self } pub fn muted(mut self) -> Self { self.muted = true; self } pub fn poster(mut self, poster: &str) -> Self { self.poster = Some(poster.to_string()); self } pub fn width(mut self, w: u32) -> Self { self.width = Some(w); self } pub fn height(mut self, h: u32) -> Self { self.height = Some(h); self } } impl UIWidget for VideoWidget { fn can_inherit(&self) -> bool { true } fn base_class(&self) -> Vec { vec![] } fn extended_class(&self) -> Vec { self.base_class() } fn render_with_class(&self, class: &str) -> Markup { let mut ret = " "); for src in &self.src { ret.push_str(&src.render().0); } ret.push_str("\nYour browser does not support the video tag.\n"); PreEscaped(ret) } } #[allow(non_snake_case)] #[must_use] pub fn Source(src: &str, mime: Option) -> SourceWidget { SourceWidget { src: src.to_owned(), mime, } } pub struct SourceWidget { src: String, mime: Option, } impl Render for SourceWidget { fn render(&self) -> Markup { self.render_with_class("") } } impl UIWidget for SourceWidget { fn can_inherit(&self) -> bool { false } fn base_class(&self) -> Vec { vec![] } fn extended_class(&self) -> Vec { self.base_class() } fn render_with_class(&self, _: &str) -> Markup { html! { @if let Some(mime) = &self.mime { source src=(self.src) type=(mime); } @else { source src=(self.src); }; } } }