use crate::{ActiveAppEnv, StaticAssetProperties, StaticCowStr, StaticStr, UiPaint};
use file_format::FileFormat;
use std::borrow::Cow;
use tao::window::Theme as WryTheme;
pub const PUPPETEER_APP_ELEMENT: &str = r#"<div id="puppeteer_app"></div>"#;
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct ColorPalette {
pub primary: StaticStr, pub secondary: StaticStr, pub tertiary: StaticStr, }
impl Default for ColorPalette {
fn default() -> Self {
ColorPalette {
primary: "#FFFFFF",
secondary: "#000000",
tertiary: "#E6E6E6",
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Shell {
head_links: Vec<StaticCowStr>,
styles: Vec<StaticCowStr>,
scripts: Vec<StaticCowStr>,
fonts: Vec<StaticCowStr>,
palette: ColorPalette,
}
impl Shell {
pub fn new() -> Self {
Shell::default()
}
pub fn add_head_links(mut self, element: StaticStr) -> Self {
self.head_links.push(Cow::Borrowed(element));
self
}
pub fn add_style(mut self, style: StaticStr) -> Self {
self.styles.push(Cow::Borrowed(style));
self
}
pub fn add_styles(mut self, styles: impl AsRef<[StaticCowStr]>) -> Self {
self.styles.extend_from_slice(styles.as_ref());
self
}
pub fn add_const_styles(mut self, styles: impl AsRef<[&'static str]>) -> Self {
styles
.as_ref()
.iter()
.for_each(|style| self.styles.push(Cow::Borrowed(style)));
self
}
pub fn add_script(mut self, script: StaticCowStr) -> Self {
self.scripts.push(script);
self
}
pub fn add_scripts(mut self, scripts: impl AsRef<[StaticCowStr]>) -> Self {
self.scripts.extend_from_slice(scripts.as_ref());
self
}
pub fn add_const_scripts(mut self, scripts: impl AsRef<[&'static str]>) -> Self {
scripts
.as_ref()
.iter()
.for_each(|script| self.scripts.push(Cow::Borrowed(script)));
self
}
pub fn head_links(&self) -> &[StaticCowStr] {
self.head_links.as_slice()
}
pub fn styles(&self) -> &[StaticCowStr] {
self.styles.as_slice()
}
pub fn scripts(&self) -> &[StaticCowStr] {
self.scripts.as_slice()
}
pub fn add_fonts(mut self, app_env: &ActiveAppEnv) -> Self {
app_env.fonts.iter().for_each(|font| {
let file_format_detected = font.format();
if file_format_detected != FileFormat::WebOpenFontFormat2 {
panic!(
"Invalid font type `{:?}` for file `{}`",
font.format(),
font.name
);
}
tracing::info!("LOADED FONT: {:?}", &font.name());
let injector = Cow::Borrowed("var dataUri = \"")
+ font.base64()
+ "\";"
+ Cow::Borrowed(
r#"
var fontFace = new FontFace(""#,
)
+ font.name()
+ Cow::Borrowed(
r#"", `url(${dataUri})`, {
style: "normal",
weight: "normal",
stretch: "condensed",
});
document.fonts.add(fontFace);
"#,
); self.fonts.push(Cow::Owned(injector.to_string()));
});
self
}
}
impl UiPaint for Shell {
fn to_html(&self) -> Cow<str> {
let head_links = self.head_links.iter().cloned().collect::<String>();
let styles = self.styles.iter().cloned().collect::<String>();
let scripts = self.scripts.iter().cloned().collect::<String>();
let fonts = self
.fonts
.iter()
.map(|font| font.to_string())
.collect::<String>();
Cow::Borrowed("<!DOCTYPE html>")
+ "<head>"
+ r#"<meta charset="UTF-8">"#
+ r#"<meta name="viewport" content="width=device-width, initial-scale=1.0">"#
+ Cow::Owned(head_links)
+ "<style>"
+ Cow::Owned(styles)
+ "</style>"
+ "</head>"
+ "<body>"
+ "<script>"
+ Cow::Owned(fonts)
+ "</script>"
+ PUPPETEER_APP_ELEMENT
+ Cow::Owned(scripts)
+ "</body>"
+ "</html>"
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Theme {
Dark,
Light,
System,
}
impl Theme {
pub fn toggle_theme(&self) -> Self {
match self {
Self::Dark => Self::Light,
Self::Light => Self::Dark,
Self::System => Self::Dark,
}
}
}
impl From<WryTheme> for Theme {
fn from(value: WryTheme) -> Self {
match value {
WryTheme::Dark => Theme::Dark,
WryTheme::Light => Theme::Light,
_ => Theme::System,
}
}
}