Skip to main content

yggdrasil/bridges/
library.rs

1//! 按组件需求加载浏览器库,资源完成后才允许构造 wasm-bindgen Options/实例。
2
3use 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
16/// enabled 可订阅组件状态;卸载会取消 Resource,迟到的加载结果不会挂载旧组件。
17pub 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}