diff --git a/Cargo.toml b/Cargo.toml index 9d9c6fb..00f3635 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ axum-extra = { version = "0.9.4", features = ["cookie"], optional = true } leptos = "0.6.15" leptos_meta = "0.6.15" leptos_router = "0.6.15" -leptos_axum = { version = "0.6.15", features = ["wasm"], optional = true } +leptos_axum = { version = "0.6.15", optional = true } bcrypt = "0.15.1" chrono = { version = "0.4.38", features = ["serde"] } diesel = { version = "2.2.4", features = [ diff --git a/src/common/mod.rs b/src/common/mod.rs index f6f2fdf..543d1c8 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -151,7 +151,7 @@ pub struct SharedConfig { pub article_approval: bool, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)] #[cfg_attr(feature = "ssr", derive(Queryable))] #[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))] pub struct SiteView { diff --git a/src/frontend/api.rs b/src/frontend/api.rs index 73ad047..70c7661 100644 --- a/src/frontend/api.rs +++ b/src/frontend/api.rs @@ -23,11 +23,12 @@ use crate::{ ProtectArticleForm, RegisterUserForm, ResolveObject, - SearchArticleForm, + SearchArticleForm, SiteView, }, frontend::error::MyResult, }; use anyhow::anyhow; +use once_cell::sync::OnceCell; use reqwest::{Client, RequestBuilder, StatusCode}; use serde::{Deserialize, Serialize}; use url::Url; @@ -40,7 +41,12 @@ pub struct ApiClient { } impl ApiClient { - pub fn new(client: Client, hostname_: Option) -> Self { + pub fn get() -> &'static ApiClient { + static CELL: OnceCell = OnceCell::::new(); + CELL.get_or_init(|| Self::build(Client::new(), None)) + } + + pub fn build(client: Client, hostname_: Option) -> Self { let mut hostname; let ssl; #[cfg(not(feature = "ssr"))] @@ -207,10 +213,10 @@ impl ApiClient { } } - pub async fn my_profile(&self) -> MyResult { + pub async fn site(&self) -> MyResult { let req = self .client - .get(self.request_endpoint("/api/v1/account/my_profile")); + .get(self.request_endpoint("/api/v1/site")); handle_json_res(req).await } diff --git a/src/frontend/app.rs b/src/frontend/app.rs index 62d4ce5..7d2659e 100644 --- a/src/frontend/app.rs +++ b/src/frontend/app.rs @@ -1,5 +1,5 @@ use crate::{ - common::LocalUserView, + common::{LocalUserView, SiteView}, frontend::{ api::ApiClient, components::nav::Nav, @@ -24,22 +24,9 @@ use crate::{ }, }; use leptos::{ - component, - create_local_resource, - create_rw_signal, - expect_context, - provide_context, - use_context, - view, - DynAttrs, - IntoView, - RwSignal, - SignalGetUntracked, - SignalUpdate, -}; +*}; use leptos_meta::{provide_meta_context, *}; use leptos_router::{Route, Router, Routes}; -use reqwest::Client; use std::{thread::sleep, time::Duration}; // https://book.leptos.dev/15_global_state.html @@ -62,28 +49,23 @@ impl GlobalState { .get_untracked() .api_client } +} - pub fn update_my_profile() { - create_local_resource( - move || (), - |_| async move { - let my_profile = GlobalState::api_client().my_profile().await.ok(); - expect_context::>() - .update(|state| state.my_profile = my_profile.clone()); - }, - ); - } +pub fn site() -> Resource<(), SiteView>{ + use_context::>().unwrap() } #[component] pub fn App() -> impl IntoView { provide_meta_context(); let global_state = GlobalState { - api_client: ApiClient::new(Client::new(), None), + api_client: ApiClient::get().clone(), my_profile: None, }; - // Load user profile in case we are already logged in - GlobalState::update_my_profile(); + let site = create_resource(|| (), |_| async move { + ApiClient::get().site().await.unwrap() + }); + provide_context(site); provide_context(create_rw_signal(global_state)); let darkmode = DarkMode::init(); diff --git a/src/frontend/components/instance_follow_button.rs b/src/frontend/components/instance_follow_button.rs index 504f107..52123c3 100644 --- a/src/frontend/components/instance_follow_button.rs +++ b/src/frontend/components/instance_follow_button.rs @@ -1,6 +1,6 @@ use crate::{ common::{newtypes::InstanceId, DbInstance, FollowInstance}, - frontend::app::GlobalState, + frontend::app::{site, GlobalState}, }; use leptos::{component, *}; @@ -15,7 +15,7 @@ pub fn InstanceFollowButton(instance: DbInstance) -> impl IntoView { .follow_instance(form) .await .unwrap(); - GlobalState::update_my_profile(); + site().refetch(); } }); let is_following = global_state diff --git a/src/frontend/components/nav.rs b/src/frontend/components/nav.rs index ee69596..4a10615 100644 --- a/src/frontend/components/nav.rs +++ b/src/frontend/components/nav.rs @@ -1,4 +1,4 @@ -use crate::frontend::{app::GlobalState, dark_mode::DarkMode}; +use crate::frontend::{api::ApiClient, app::{site, GlobalState}, dark_mode::DarkMode}; use leptos::{component, use_context, view, IntoView, RwSignal, SignalWith, *}; use leptos_router::*; @@ -6,23 +6,13 @@ use leptos_router::*; pub fn Nav() -> impl IntoView { let global_state = use_context::>().unwrap(); let logout_action = create_action(move |_| async move { - GlobalState::api_client().logout().await.unwrap(); - GlobalState::update_my_profile(); + ApiClient::get().logout().await.unwrap(); + site().refetch(); }); - let registration_open = create_local_resource( - || (), - move |_| async move { - GlobalState::api_client() - .get_local_instance() - .await - .map(|i| i.registration_open) - .unwrap_or_default() - }, - ); let notification_count = create_resource( || (), move |_| async move { - GlobalState::api_client() + ApiClient::get() .notifications_count() .await .unwrap_or_default() @@ -108,11 +98,12 @@ pub fn Nav() -> impl IntoView {
  • "Login"
  • - + +
  • "Register"
  • -
    +
    } } >