🎨 Put svg image generation in a dedicated datasource

This commit is contained in:
2024-04-01 19:32:35 +02:00
parent 9071b0073c
commit 014a0c2c57
7 changed files with 283 additions and 196 deletions

View File

@@ -5,12 +5,12 @@ use std::rc::Rc;
use const_format::formatcp;
use dioxus::prelude::*;
use rand::distributions::{Alphanumeric, DistString};
use tracing::{debug, error, warn};
use validator::{Validate, ValidateArgs, ValidateEmail, ValidationError, ValidationErrors};
use zxcvbn::zxcvbn;
use crate::base::{Session, SESSION};
use crate::data::datasources::random_svg_generators::{generate_random_svg_shape, ShapeConfig};
use super::button::{LoginButton, RegisterButton};
use super::modal::{Modal, Severity};
@@ -47,36 +47,6 @@ const SHAPE_2_COLORS_STR: &str = formatcp!(
const SHAPE_3_COLORS_STR: &str = formatcp!(
"{COLOR_TERNARY_120},{COLOR_TERNARY_110},{COLOR_TERNARY_100},{COLOR_TERNARY_90},{COLOR_TERNARY_80}");
async fn generate_random_avatar(url: String) -> Option<String> {
let seed = Alphanumeric.sample_string(&mut rand::thread_rng(), 16);
let req = format!(
"https://{url}/7.x/shapes/svg?\
seed={seed}&\
backgroundColor={BACKGROUND_COLORS_STR}&\
shape1Color={SHAPE_1_COLORS_STR}&\
shape2Color={SHAPE_2_COLORS_STR}&\
shape3Color={SHAPE_3_COLORS_STR}"
);
let mut res: Option<String> = None;
match reqwest::get(req).await {
Ok(result) => {
match result.text().await {
Ok(svg) => {
res = Some(svg);
}
Err(err) => {
error!("Error during placeholder loading: {}", err);
}
};
}
Err(err) => {
error!("Error during placeholder loading: {}", err);
}
};
res
}
const REQUIRED_ERROR_NAME: &str = "required";
const REQUIRED_ERROR_HELPER_TEXT: &str = "This field must be completed";
@@ -591,12 +561,7 @@ impl<'a> PasswordSuggestionsModalConfig<'a> {
}
}
#[derive(Props, Clone, PartialEq)]
pub struct LoginProps {
dicebear_hostname: Option<String>,
}
pub fn Login(props: LoginProps) -> Element {
pub fn Login() -> Element {
debug!("Login rendering");
let mut data = use_signal(Data::new);
@@ -632,31 +597,23 @@ pub fn Login(props: LoginProps) -> Element {
let mut spinner_animated = use_signal(|| false);
let mut id_placeholder = use_signal(|| LOGIN_ID_PLACEHOLDER);
let url = props
.dicebear_hostname
.unwrap_or("dicebear.tools.adrien.run".to_string());
let mut random_avatar_future = use_resource(move || {
to_owned![url];
async move { generate_random_avatar(url).await }
let mut random_avatar_future = use_resource(move || async move {
let shape_config = ShapeConfig::new(
BACKGROUND_COLORS_STR,
SHAPE_1_COLORS_STR,
SHAPE_2_COLORS_STR,
SHAPE_3_COLORS_STR,
);
generate_random_svg_shape(Some(&shape_config)).await
});
let avatar = match &*random_avatar_future.read_unchecked() {
Some(Some(svg)) => {
rsx!(div {
Some(svg) => Some(rsx! {
div {
class: ClassName::LOGIN_FORM_PHOTO_CONTENT,
dangerous_inner_html: svg.as_str(),
})
}
Some(None) => {
warn!("No profile image set or generated, display the placeholder");
rsx!(div {
class: ClassName::LOGIN_FORM_PHOTO_CONTENT,
img {
src: "./images/login-profile-placeholder.svg"
}
})
}
}
}),
None => None,
};