use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{Element, HtmlImageElement};
use crate::shared::{is_initialized, mark_initialized};
pub fn init(root: Element) {
if is_initialized(&root) { return; }
mark_initialized(&root);
let Ok(Some(img_node)) = root.query_selector("[data-rs-avatar-image]") else {
show_fallback(&root);
return;
};
let Ok(img) = img_node.dyn_into::<HtmlImageElement>() else { return };
if img.complete() && img.natural_width() > 0 {
root.set_attribute("data-rs-state", "loaded").ok();
return;
}
root.set_attribute("data-rs-state", "loading").ok();
{
let root_c = root.clone();
let cb = Closure::wrap(Box::new(move || {
root_c.set_attribute("data-rs-state", "loaded").ok();
hide_fallback(&root_c);
}) as Box<dyn Fn()>);
img.set_onload(Some(cb.as_ref().unchecked_ref()));
cb.forget();
}
{
let root_c = root.clone();
let cb = Closure::wrap(Box::new(move || {
root_c.set_attribute("data-rs-state", "error").ok();
show_fallback(&root_c);
}) as Box<dyn Fn()>);
img.set_onerror(Some(cb.as_ref().unchecked_ref()));
cb.forget();
}
}
fn show_fallback(root: &Element) {
if let Ok(Some(fb)) = root.query_selector("[data-rs-avatar-fallback]") {
fb.remove_attribute("hidden").ok();
fb.set_attribute("data-rs-state", "visible").ok();
}
if let Ok(Some(img)) = root.query_selector("[data-rs-avatar-image]") {
img.set_attribute("data-rs-state", "hidden").ok();
}
}
fn hide_fallback(root: &Element) {
if let Ok(Some(fb)) = root.query_selector("[data-rs-avatar-fallback]") {
fb.set_attribute("hidden", "").ok();
fb.set_attribute("data-rs-state", "hidden").ok();
}
}
pub fn init_all() {
let win = match web_sys::window() { Some(w) => w, None => return };
let doc = match win.document() { Some(d) => d, None => return };
let nodes = match doc.query_selector_all("[data-rs-avatar]") { Ok(n) => n, Err(_) => return };
for i in 0..nodes.length() {
if let Some(node) = nodes.item(i) {
if let Ok(el) = node.dyn_into::<Element>() { init(el); }
}
}
}