use dioxus::prelude::*; #[derive(PartialEq, Props, Clone)] pub struct UserPrefs { theme: ThemePref, font: FontPref, } #[derive(PartialEq, Clone)] pub enum ThemePref { Light, Dark, Auto, } #[derive(PartialEq, Clone)] pub enum FontPref { NerdFont, OpenDyslexic, } pub enum ThemedComponent { Page, Card, Button, } impl UserPrefs { // TailwindCSS has a difficult time determining which classes we'll need for our site, // the easiest way to fix this is to simply list all of them our in commented out class // attributes, so all of these we *will* use, and TailwindCSS will know to compile them. // class: "bg-alice-werefox-grey-light dark:bg-alice-werefox-grey" // class: "bg-alice-werefox-grey" // class: "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark" // class: "dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light" // class: "bg-alice-werefox-grey-dark ring-alice-werefox-red text-alice-werefox-grey-light" // class: "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark" // class: "hover:text-alice-werefox-blue-dark" // class: "hover:ring-alice-werefox-blue dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red" // class: "bg-alice-werefox-grey-dark ring-alice-werefox-red" // class: "dark:text-alice-werefox-grey-light dark:hover:text-alice-werefox-blue-light dark:hover:ring-alice-werefox-blue" // class: "text-alice-werefox-grey-light hover:text-alice-werefox-blue-light hover:ring-alice-werefox-blue" const PAGE_CLASSES: &str = "bg-alice-werefox-grey-light dark:bg-alice-werefox-grey"; const CARD_CLASSES: &str = "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light"; const BUTTON_CLASSES: &str = "bg-alice-werefox-grey-lightest ring-alice-werefox-red-dark text-alice-werefox-grey-dark hover:text-alice-werefox-blue-dark hover:ring-alice-werefox-blue dark:bg-alice-werefox-grey-dark dark:ring-alice-werefox-red dark:text-alice-werefox-grey-light dark:hover:text-alice-werefox-blue-light dark:hover:ring-alice-werefox-blue"; pub fn new(theme: ThemePref, font: FontPref) -> UserPrefs { UserPrefs { theme, font } } // I'm really about to write a ceil() function because I refuse to force devs to use Nightly fn ceil(n: usize) -> usize { if n.rem_euclid(2) == 0 { n / 2 } else { n - 1 / 2 } } pub fn get_pref_classes(&self, component: ThemedComponent) -> (String, String) { let theme = self.get_theme_classes(component).clone(); let font = self.get_font_class().clone(); (theme, font) } pub fn get_theme_classes(&self, component: ThemedComponent) -> String { match &self.theme { ThemePref::Light => match component { ThemedComponent::Page => Self::PAGE_CLASSES .split_at(Self::ceil(Self::PAGE_CLASSES.len() / 2)) .0 .to_string(), ThemedComponent::Card => Self::CARD_CLASSES .split_at(Self::ceil(Self::CARD_CLASSES.len() / 2)) .0 .to_string(), ThemedComponent::Button => Self::BUTTON_CLASSES .split_at(Self::ceil(Self::BUTTON_CLASSES.len() / 2)) .0 .to_string(), }, ThemePref::Dark => match component { ThemedComponent::Page => { let remove_dark_tags = Self::PAGE_CLASSES.split("dark:").collect::(); let split_whitespace = remove_dark_tags.as_str().split(" "); let split_whitespace_length = split_whitespace.clone().count(); split_whitespace .skip(Self::ceil(split_whitespace_length / 2)) .map(|e| format!("{e} ")) .collect::() } ThemedComponent::Card => { let remove_dark_tags = Self::CARD_CLASSES.split("dark:").collect::(); let split_whitespace = remove_dark_tags.as_str().split(" "); let split_whitespace_length = split_whitespace.clone().count(); split_whitespace .skip(Self::ceil(split_whitespace_length / 2)) .map(|e| format!("{e} ")) .collect::() } ThemedComponent::Button => { let remove_dark_tags = Self::BUTTON_CLASSES.split("dark:").collect::(); let split_whitespace = remove_dark_tags.as_str().split(" "); let split_whitespace_length = split_whitespace.clone().count(); split_whitespace .skip(Self::ceil(split_whitespace_length / 2)) .map(|e| format!("{e} ")) .collect::() } }, ThemePref::Auto => match component { ThemedComponent::Page => Self::PAGE_CLASSES.to_string(), ThemedComponent::Card => Self::CARD_CLASSES.to_string(), ThemedComponent::Button => Self::BUTTON_CLASSES.to_string(), }, } } pub fn get_font_class(&self) -> String { match &self.font { FontPref::OpenDyslexic => "font-open".to_string(), FontPref::NerdFont => "font-nerd".to_string(), } } pub fn set_prefs(mut self, prefs: UserPrefs) { self.theme = prefs.theme; self.font = prefs.font; } pub fn set_theme(mut self, theme: ThemePref) { self.theme = theme; } pub fn set_font(mut self, font: FontPref) { self.font = font; } pub fn get_prefs(self) -> (ThemePref, FontPref) { let prefs = self.clone(); (prefs.theme, prefs.font) } pub fn get_theme(self) -> ThemePref { let prefs = self.clone(); prefs.theme.clone() } pub fn get_font(self) -> FontPref { let prefs = self.clone(); prefs.font.clone() } }