diff --git a/src/util/mod.rs b/src/util/mod.rs index cf7196e..d7ad020 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -5,3 +5,5 @@ cfg_if! { pub mod audio; } } + +pub mod state; diff --git a/src/util/state.rs b/src/util/state.rs new file mode 100644 index 0000000..b2fa59c --- /dev/null +++ b/src/util/state.rs @@ -0,0 +1,49 @@ +use leptos::*; +use leptos::logging::*; + +use crate::playstatus::PlayStatus; +use crate::models::User; +use crate::auth::get_logged_in_user; + +/// Global front-end state +/// Contains anything frequently needed across multiple components +/// Behaves like a singleton, in that provide/expect_context will +/// always return the same instance +#[derive(Clone)] +pub struct GlobalState { + /// A resource that fetches the logged in user + /// This will not automatically refetch, so any login/logout related code + /// should call `refetch` on this resource + pub logged_in_user: Resource<(), Option>, + + /// The current play status + pub play_status: RwSignal, +} + +impl GlobalState { + pub fn new() -> Self { + let play_status = create_rw_signal(PlayStatus::default()); + + let logged_in_user = create_resource(|| (), |_| async { + get_logged_in_user().await + .inspect_err(|e| { + error!("Error getting logged in user: {:?}", e); + }) + .ok() + .flatten() + }); + + Self { + logged_in_user, + play_status, + } + } + + pub fn logged_in_user() -> Resource<(), Option> { + expect_context::().logged_in_user + } + + pub fn play_status() -> RwSignal { + expect_context::().play_status + } +}