Skip to main content

flams_router_vscode/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![allow(clippy::must_use_candidate)]
3
4#[cfg(any(
5    all(feature = "ssr", feature = "hydrate", not(feature = "docs-only")),
6    not(any(feature = "ssr", feature = "hydrate"))
7))]
8compile_error!("exactly one of the features \"ssr\" or \"hydrate\" must be enabled");
9
10pub mod checks;
11pub mod components;
12
13use flams_router_base::maybe_lazy;
14use flams_utils::unwrap;
15use ftml_component_utils::Spinner;
16use ftml_dom::utils::css::inject_css;
17pub use leptos::prelude::*;
18
19#[server]
20#[allow(clippy::unused_async)]
21async fn is_lsp() -> Result<bool, ServerFnError> {
22    Ok(flams_system::settings::Settings::get().lsp)
23}
24
25#[derive(Clone)]
26pub struct VSCode {
27    origin: String,
28}
29impl VSCode {
30    #[must_use]
31    pub fn get() -> Option<Self> {
32        use_context()
33    }
34    /// # Errors
35    pub fn post_message<T: leptos::server_fn::serde::Serialize + std::fmt::Debug>(
36        &self,
37        t: T,
38    ) -> Result<(), String> {
39        #[cfg(feature = "hydrate")]
40        {
41            let e = serde_wasm_bindgen::to_value(&t).map_err(|e| e.to_string())?;
42            let parent = unwrap!(unwrap!(unwrap!(leptos::web_sys::window()).parent().ok()));
43            unwrap!(parent.post_message(&e, &self.origin).ok());
44        }
45        Ok(())
46    }
47}
48
49maybe_lazy!(
50    VSCWrap = {
51        use flams_router_login::components::LoginProvider;
52        use leptos::either::EitherOf3;
53        ftml_dom::global_setup(|| {
54            flams_router_content::Views::top_safe(|| {
55                inject_css("flams-vscode", include_str!("vscode.css"));
56                let lsp = Resource::new(|| (), |()| is_lsp());
57                if let Some(origin) =
58                    leptos_router::hooks::use_query_map().with_untracked(|q| q.get("origin"))
59                {
60                    provide_context(VSCode { origin });
61                }
62                view!(
63                    <LoginProvider><Suspense>{move ||
64                        match lsp.get() {
65                            Some(Ok(true)) => EitherOf3::A(view!(
66                                <div class="flams-vscode">
67                                    <leptos_router::components::Outlet/>
68                                </div>
69                            )),
70                            Some(_) => EitherOf3::B("ERROR"),
71                            None => EitherOf3::C(view!(<Spinner/>)),
72                        }
73                    }
74                    </Suspense></LoginProvider>
75                )
76            })
77        })
78        .into_any()
79    }
80);
81
82#[component(transparent)]
83pub fn VSCodeWrap() -> impl IntoView {
84    use flams_router_login::components::LoginProvider;
85    use leptos::either::EitherOf3;
86    ftml_dom::global_setup(|| {
87        flams_router_content::Views::top_safe(|| {
88            inject_css("flams-vscode", include_str!("vscode.css"));
89            let lsp = Resource::new(|| (), |()| is_lsp());
90            if let Some(origin) =
91                leptos_router::hooks::use_query_map().with_untracked(|q| q.get("origin"))
92            {
93                provide_context(VSCode { origin });
94            }
95            view!(
96                <LoginProvider><Suspense>{move ||
97                    match lsp.get() {
98                        Some(Ok(true)) => EitherOf3::A(view!(
99                            <div class="flams-vscode">
100                                <leptos_router::components::Outlet/>
101                            </div>
102                        )),
103                        Some(_) => EitherOf3::B("ERROR"),
104                        None => EitherOf3::C(view!(<Spinner/>)),
105                    }
106                }
107                </Suspense></LoginProvider>
108            )
109        })
110    })
111}