yggdrasil/bridges/
library.rs1use dioxus::prelude::*;
4
5#[cfg(target_arch = "wasm32")]
6#[wasm_bindgen::prelude::wasm_bindgen]
7extern "C" {
8 #[wasm_bindgen(js_namespace = window, js_name = __loadBrowserLibrary, catch)]
9 async fn load_browser_library(
10 name: &str,
11 ) -> Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>;
12}
13
14pub type LibraryResource = Resource<Result<bool, String>>;
15
16pub fn use_browser_library(
18 name: &'static str,
19 mut enabled: impl FnMut() -> bool + 'static,
20) -> LibraryResource {
21 use_resource(move || {
22 let enabled = enabled();
23 async move {
24 #[cfg(target_arch = "wasm32")]
25 {
26 if !enabled {
27 return Ok(false);
28 }
29 load_browser_library(name).await.map_err(|error| {
30 web_sys::console::error_1(&error);
31 "加载失败,请检查网络后重试。".to_string()
32 })?;
33 Ok(true)
34 }
35 #[cfg(not(target_arch = "wasm32"))]
36 {
37 let _ = (name, enabled);
38 Ok(false)
39 }
40 }
41 })
42}
43
44pub fn library_ready(library: LibraryResource) -> bool {
45 matches!(&*library.read(), Some(Ok(true)))
46}
47
48#[component]
49pub fn LibraryLoadError(mut library: LibraryResource) -> Element {
50 let message = library
51 .read()
52 .as_ref()
53 .and_then(|result| result.as_ref().err())
54 .cloned();
55 rsx! {
56 if let Some(message) = message {
57 div { role: "alert", class: "flex items-center gap-3 p-3 text-sm text-red-500 dark:text-red-400",
58 span { "{message}" }
59 button { r#type: "button", class: "underline underline-offset-4", onclick: move |_| library.restart(), "重新加载" }
60 }
61 }
62 }
63}