1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2024-11-22 18:31:10 +00:00
This commit is contained in:
Felix Ableitner 2024-11-13 15:04:20 +01:00
parent 72d123aab1
commit 541a973b7c
6 changed files with 31 additions and 52 deletions

View file

@ -64,7 +64,7 @@ axum-extra = { version = "0.9.4", features = ["cookie"], optional = true }
leptos = "0.6.15" leptos = "0.6.15"
leptos_meta = "0.6.15" leptos_meta = "0.6.15"
leptos_router = "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" bcrypt = "0.15.1"
chrono = { version = "0.4.38", features = ["serde"] } chrono = { version = "0.4.38", features = ["serde"] }
diesel = { version = "2.2.4", features = [ diesel = { version = "2.2.4", features = [

View file

@ -151,7 +151,7 @@ pub struct SharedConfig {
pub article_approval: bool, 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", derive(Queryable))]
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))] #[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
pub struct SiteView { pub struct SiteView {

View file

@ -23,11 +23,12 @@ use crate::{
ProtectArticleForm, ProtectArticleForm,
RegisterUserForm, RegisterUserForm,
ResolveObject, ResolveObject,
SearchArticleForm, SearchArticleForm, SiteView,
}, },
frontend::error::MyResult, frontend::error::MyResult,
}; };
use anyhow::anyhow; use anyhow::anyhow;
use once_cell::sync::OnceCell;
use reqwest::{Client, RequestBuilder, StatusCode}; use reqwest::{Client, RequestBuilder, StatusCode};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use url::Url; use url::Url;
@ -40,7 +41,12 @@ pub struct ApiClient {
} }
impl ApiClient { impl ApiClient {
pub fn new(client: Client, hostname_: Option<String>) -> Self { pub fn get() -> &'static ApiClient {
static CELL: OnceCell<ApiClient> = OnceCell::<ApiClient>::new();
CELL.get_or_init(|| Self::build(Client::new(), None))
}
pub fn build(client: Client, hostname_: Option<String>) -> Self {
let mut hostname; let mut hostname;
let ssl; let ssl;
#[cfg(not(feature = "ssr"))] #[cfg(not(feature = "ssr"))]
@ -207,10 +213,10 @@ impl ApiClient {
} }
} }
pub async fn my_profile(&self) -> MyResult<LocalUserView> { pub async fn site(&self) -> MyResult<SiteView> {
let req = self let req = self
.client .client
.get(self.request_endpoint("/api/v1/account/my_profile")); .get(self.request_endpoint("/api/v1/site"));
handle_json_res(req).await handle_json_res(req).await
} }

View file

@ -1,5 +1,5 @@
use crate::{ use crate::{
common::LocalUserView, common::{LocalUserView, SiteView},
frontend::{ frontend::{
api::ApiClient, api::ApiClient,
components::nav::Nav, components::nav::Nav,
@ -24,22 +24,9 @@ use crate::{
}, },
}; };
use leptos::{ 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_meta::{provide_meta_context, *};
use leptos_router::{Route, Router, Routes}; use leptos_router::{Route, Router, Routes};
use reqwest::Client;
use std::{thread::sleep, time::Duration}; use std::{thread::sleep, time::Duration};
// https://book.leptos.dev/15_global_state.html // https://book.leptos.dev/15_global_state.html
@ -62,28 +49,23 @@ impl GlobalState {
.get_untracked() .get_untracked()
.api_client .api_client
} }
}
pub fn update_my_profile() { pub fn site() -> Resource<(), SiteView>{
create_local_resource( use_context::<Resource<(), SiteView>>().unwrap()
move || (),
|_| async move {
let my_profile = GlobalState::api_client().my_profile().await.ok();
expect_context::<RwSignal<GlobalState>>()
.update(|state| state.my_profile = my_profile.clone());
},
);
}
} }
#[component] #[component]
pub fn App() -> impl IntoView { pub fn App() -> impl IntoView {
provide_meta_context(); provide_meta_context();
let global_state = GlobalState { let global_state = GlobalState {
api_client: ApiClient::new(Client::new(), None), api_client: ApiClient::get().clone(),
my_profile: None, my_profile: None,
}; };
// Load user profile in case we are already logged in let site = create_resource(|| (), |_| async move {
GlobalState::update_my_profile(); ApiClient::get().site().await.unwrap()
});
provide_context(site);
provide_context(create_rw_signal(global_state)); provide_context(create_rw_signal(global_state));
let darkmode = DarkMode::init(); let darkmode = DarkMode::init();

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
common::{newtypes::InstanceId, DbInstance, FollowInstance}, common::{newtypes::InstanceId, DbInstance, FollowInstance},
frontend::app::GlobalState, frontend::app::{site, GlobalState},
}; };
use leptos::{component, *}; use leptos::{component, *};
@ -15,7 +15,7 @@ pub fn InstanceFollowButton(instance: DbInstance) -> impl IntoView {
.follow_instance(form) .follow_instance(form)
.await .await
.unwrap(); .unwrap();
GlobalState::update_my_profile(); site().refetch();
} }
}); });
let is_following = global_state let is_following = global_state

View file

@ -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::{component, use_context, view, IntoView, RwSignal, SignalWith, *};
use leptos_router::*; use leptos_router::*;
@ -6,23 +6,13 @@ use leptos_router::*;
pub fn Nav() -> impl IntoView { pub fn Nav() -> impl IntoView {
let global_state = use_context::<RwSignal<GlobalState>>().unwrap(); let global_state = use_context::<RwSignal<GlobalState>>().unwrap();
let logout_action = create_action(move |_| async move { let logout_action = create_action(move |_| async move {
GlobalState::api_client().logout().await.unwrap(); ApiClient::get().logout().await.unwrap();
GlobalState::update_my_profile(); 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( let notification_count = create_resource(
|| (), || (),
move |_| async move { move |_| async move {
GlobalState::api_client() ApiClient::get()
.notifications_count() .notifications_count()
.await .await
.unwrap_or_default() .unwrap_or_default()
@ -108,11 +98,12 @@ pub fn Nav() -> impl IntoView {
<li> <li>
<A href="/login">"Login"</A> <A href="/login">"Login"</A>
</li> </li>
<Show when=move || registration_open.get().unwrap_or_default()> <Transition>
<Show when=move || site().get().map(|s| s.config.registration_open).unwrap_or_default()>
<li> <li>
<A href="/register">"Register"</A> <A href="/register">"Register"</A>
</li> </li>
</Show> </Show></Transition>
} }
} }
> >