use leptos::prelude::*; use wasm_bindgen_futures::spawn_local; use crate::api::{self, Me}; use crate::router::{parse_location, Location}; #[derive(Clone, Copy, PartialEq, Debug)] pub enum AuthPhase { Loading, Setup, Login, Authed, } #[component] pub fn App() -> impl IntoView { let (phase, set_phase) = signal(AuthPhase::Loading); let (me, set_me) = signal(Option::::None); let (loc, set_loc) = signal(Location::root()); // The URL hash is the source of truth for the location. { let set_loc = set_loc; set_loc.set(parse_location()); let set_loc = set_loc; let _h = window_event_listener(leptos::ev::hashchange, move |_| { set_loc.set(parse_location()); }); } // Initial /me probe: first boot, signed in, or needs login. spawn_local(async move { match api::me().await { Ok(m) => { let first_boot = m.first_boot; set_me.set(Some(m)); set_phase.set(if first_boot { AuthPhase::Setup } else { AuthPhase::Authed }); } Err(_) => set_phase.set(AuthPhase::Login), } }); view! { {move || { // Public share links (`#/s/{token}/...`) bypass the auth flow. let loc_now = loc.get(); if let Some(token) = loc_now.share_token.clone() { return view! { } .into_view() .into_any(); } match phase.get() { AuthPhase::Loading => view! {

"Loading…"

} .into_view() .into_any(), AuthPhase::Setup => view! { } .into_view() .into_any(), AuthPhase::Login => view! { } .into_view() .into_any(), AuthPhase::Authed => view! { } .into_view() .into_any(), } }} } }