1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2024-11-22 11:31:08 +00:00

Move api client into static

This commit is contained in:
Felix Ableitner 2024-11-14 11:15:02 +01:00
parent 226c3facaa
commit d9020a15d4
18 changed files with 55 additions and 73 deletions

View file

@ -1,3 +1,5 @@
use std::sync::LazyLock;
use crate::{
common::{
newtypes::ArticleId,
@ -32,6 +34,10 @@ use reqwest::{Client, RequestBuilder, StatusCode};
use serde::{Deserialize, Serialize};
use url::Url;
pub static CLIENT: LazyLock<ApiClient> = LazyLock::new(|| {
ApiClient::new(Client::new(), None)
});
#[derive(Clone)]
pub struct ApiClient {
client: Client,

View file

@ -1,7 +1,6 @@
use crate::{
common::LocalUserView,
frontend::{
api::ApiClient,
components::nav::Nav,
dark_mode::DarkMode,
pages::{
@ -35,40 +34,25 @@ use leptos::{
IntoView,
RwSignal,
SignalGet,
SignalGetUntracked,
SignalUpdate,
};
use leptos_meta::{provide_meta_context, *};
use leptos_router::{Route, Router, Routes};
use reqwest::Client;
use std::{thread::sleep, time::Duration};
use crate::frontend::api::CLIENT;
// https://book.leptos.dev/15_global_state.html
#[derive(Clone)]
pub struct GlobalState {
api_client: ApiClient,
pub(crate) my_profile: Option<LocalUserView>,
}
impl GlobalState {
pub fn api_client() -> ApiClient {
let mut global_state = use_context::<RwSignal<GlobalState>>();
// Wait for global state to be populated (only needed on instance_details for some reason)
while global_state.is_none() {
sleep(Duration::from_millis(10));
global_state = use_context::<RwSignal<GlobalState>>();
}
global_state
.expect("global state is provided")
.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();
let my_profile = CLIENT.my_profile().await.ok();
expect_context::<RwSignal<GlobalState>>()
.update(|state| state.my_profile = my_profile.clone());
},
@ -91,7 +75,6 @@ impl GlobalState {
pub fn App() -> impl IntoView {
provide_meta_context();
let global_state = GlobalState {
api_client: ApiClient::new(Client::new(), None),
my_profile: None,
};
// Load user profile in case we are already logged in

View file

@ -6,7 +6,7 @@ use crate::{
article_title,
components::instance_follow_button::InstanceFollowButton,
},
};
};use crate::frontend::api::CLIENT;
use leptos::*;
use leptos_router::*;
@ -37,7 +37,7 @@ pub fn ArticleNav(
let form = GetInstance {
id: Some(instance_id),
};
GlobalState::api_client().get_instance(&form).await.unwrap()
CLIENT.get_instance(&form).await.unwrap()
},
);
let global_state = use_context::<RwSignal<GlobalState>>().unwrap();

View file

@ -1,11 +1,10 @@
use crate::frontend::app::GlobalState;
use leptos::{component, *};
use url::Url;
use url::Url;use crate::frontend::api::CLIENT;
#[component]
pub fn ConnectView<T: Clone + 'static, R: 'static>(res: Resource<T, R>) -> impl IntoView {
let connect_ibis_wiki = create_action(move |_: &()| async move {
GlobalState::api_client()
CLIENT
.resolve_instance(Url::parse("https://ibis.wiki").unwrap())
.await
.unwrap();

View file

@ -1,7 +1,7 @@
use crate::{
common::{newtypes::InstanceId, DbInstance, FollowInstance},
frontend::app::GlobalState,
};
};use crate::frontend::api::CLIENT;
use leptos::{component, *};
#[component]
@ -11,7 +11,7 @@ pub fn InstanceFollowButton(instance: DbInstance) -> impl IntoView {
let instance_id = *instance_id;
async move {
let form = FollowInstance { id: instance_id };
GlobalState::api_client()
CLIENT
.follow_instance(form)
.await
.unwrap();

View file

@ -1,18 +1,18 @@
use crate::frontend::{app::GlobalState, dark_mode::DarkMode};
use leptos::{component, use_context, view, IntoView, RwSignal, SignalWith, *};
use leptos_router::*;
use leptos_router::*;use crate::frontend::api::CLIENT;
#[component]
pub fn Nav() -> impl IntoView {
let global_state = use_context::<RwSignal<GlobalState>>().unwrap();
let logout_action = create_action(move |_| async move {
GlobalState::api_client().logout().await.unwrap();
CLIENT.logout().await.unwrap();
GlobalState::update_my_profile();
});
let registration_open = create_local_resource(
|| (),
move |_| async move {
GlobalState::api_client()
CLIENT
.get_local_instance()
.await
.map(|i| i.registration_open)
@ -22,7 +22,7 @@ pub fn Nav() -> impl IntoView {
let notification_count = create_resource(
|| (),
move |_| async move {
GlobalState::api_client()
CLIENT
.notifications_count()
.await
.unwrap_or_default()
@ -39,7 +39,7 @@ pub fn Nav() -> impl IntoView {
>
<img src="/logo.png" class="m-auto" />
<h1 class="w-min md:hidden text-3xl font-bold font-serif">
{GlobalState::api_client().hostname}
{CLIENT.hostname.clone()}
</h1>
<div class="flex-grow md:hidden"></div>
<button tabindex="0" class="btn btn-outline lg:hidden">
@ -50,7 +50,7 @@ pub fn Nav() -> impl IntoView {
class="menu dropdown-content p-2 max-sm:rounded-box max-sm:z-[1] max-sm:shadow md:h-full"
>
<h1 class="px-4 py-2 text-3xl font-bold font-serif sm:hidden">
{GlobalState::api_client().hostname}
{CLIENT.hostname.clone()}
</h1>
<li>
<A href="/">"Main Page"</A>

View file

@ -7,7 +7,7 @@ use crate::{
pages::article_resource,
DbArticle,
},
};
};use crate::frontend::api::CLIENT;
use leptos::*;
use leptos_router::Redirect;
@ -25,7 +25,7 @@ pub fn ArticleActions() -> impl IntoView {
};
async move {
set_error.update(|e| *e = None);
let result = GlobalState::api_client().fork_article(&params).await;
let result = CLIENT.fork_article(&params).await;
match result {
Ok(res) => set_fork_response.set(Some(res.article)),
Err(err) => {
@ -41,7 +41,7 @@ pub fn ArticleActions() -> impl IntoView {
};
async move {
set_error.update(|e| *e = None);
let result = GlobalState::api_client().protect_article(&params).await;
let result = CLIENT.protect_article(&params).await;
match result {
Ok(_res) => article.refetch(),
Err(err) => {

View file

@ -1,7 +1,7 @@
use crate::{
common::CreateArticleForm,
frontend::{app::GlobalState, components::editor::EditorView},
};
frontend::components::editor::EditorView,
};use crate::frontend::api::CLIENT;
use html::Textarea;
use leptos::*;
use leptos_router::Redirect;
@ -33,7 +33,7 @@ pub fn CreateArticle() -> impl IntoView {
summary,
};
set_wait_for_response.update(|w| *w = true);
let res = GlobalState::api_client().create_article(&form).await;
let res = CLIENT.create_article(&form).await;
set_wait_for_response.update(|w| *w = false);
match res {
Ok(_res) => {

View file

@ -1,14 +1,13 @@
use crate::{
common::{newtypes::ConflictId, ApiConflict, ArticleView, EditArticleForm, Notification},
frontend::{
app::GlobalState,
components::{
article_nav::{ActiveTab, ArticleNav},
editor::EditorView,
},
pages::article_resource,
},
};
};use crate::frontend::api::CLIENT;
use html::Textarea;
use leptos::*;
use leptos_router::use_params_map;
@ -34,7 +33,7 @@ pub fn EditArticle() -> impl IntoView {
create_action(move |conflict_id: &String| {
let conflict_id = ConflictId(conflict_id.parse().unwrap());
async move {
let conflict = GlobalState::api_client()
let conflict = CLIENT
.notifications_list()
.await
.unwrap()
@ -90,7 +89,7 @@ pub fn EditArticle() -> impl IntoView {
resolve_conflict_id,
};
set_wait_for_response.update(|w| *w = true);
let res = GlobalState::api_client()
let res = CLIENT
.edit_article_with_conflict(&form)
.await;
set_wait_for_response.update(|w| *w = false);

View file

@ -1,7 +1,7 @@
use crate::{
common::ListArticlesForm,
frontend::{app::GlobalState, article_link, article_title, components::connect::ConnectView},
};
frontend::{article_link, article_title, components::connect::ConnectView},
};use crate::frontend::api::CLIENT;
use html::Input;
use leptos::*;
@ -13,7 +13,7 @@ pub fn ListArticles() -> impl IntoView {
let articles = create_resource(
move || only_local.get(),
|only_local| async move {
GlobalState::api_client()
CLIENT
.list_articles(ListArticlesForm {
only_local: Some(only_local),
instance_id: None,

View file

@ -1,12 +1,11 @@
use crate::{
common::{utils::http_protocol_str, DbInstance, ListArticlesForm},
frontend::{
app::GlobalState,
article_link,
article_title,
components::instance_follow_button::InstanceFollowButton,
},
};
};use crate::frontend::api::CLIENT;
use leptos::*;
use leptos_router::use_params_map;
use url::Url;
@ -17,7 +16,7 @@ pub fn InstanceDetails() -> impl IntoView {
let hostname = move || params.get().get("hostname").cloned().unwrap();
let instance_profile = create_resource(hostname, move |hostname| async move {
let url = Url::parse(&format!("{}://{hostname}", http_protocol_str())).unwrap();
GlobalState::api_client()
CLIENT
.resolve_instance(url)
.await
.unwrap()
@ -34,7 +33,7 @@ pub fn InstanceDetails() -> impl IntoView {
let articles = create_resource(
move || instance.id,
|instance_id| async move {
GlobalState::api_client()
CLIENT
.list_articles(ListArticlesForm {
only_local: None,
instance_id: Some(instance_id),

View file

@ -1,11 +1,11 @@
use crate::frontend::{app::GlobalState, components::connect::ConnectView};
use leptos::*;
use crate::frontend::components::connect::ConnectView;
use leptos::*;use crate::frontend::api::CLIENT;
#[component]
pub fn ListInstances() -> impl IntoView {
let instances = create_resource(
move || (),
|_| async move { GlobalState::api_client().list_instances().await.unwrap() },
|_| async move { CLIENT.list_instances().await.unwrap() },
);
view! {

View file

@ -2,7 +2,7 @@ use crate::{
common::LoginUserForm,
frontend::{app::GlobalState, components::credentials::*},
};
use leptos::*;
use leptos::*;use crate::frontend::api::CLIENT;
use leptos_router::Redirect;
#[component]
@ -17,7 +17,7 @@ pub fn Login() -> impl IntoView {
let credentials = LoginUserForm { username, password };
async move {
set_wait_for_response.update(|w| *w = true);
let result = GlobalState::api_client().login(credentials).await;
let result = CLIENT.login(credentials).await;
set_wait_for_response.update(|w| *w = false);
match result {
Ok(res) => {

View file

@ -1,9 +1,6 @@
use crate::{
common::{ArticleView, GetArticleForm, MAIN_PAGE_NAME},
frontend::app::GlobalState,
};
use crate::common::{ArticleView, GetArticleForm, MAIN_PAGE_NAME};
use leptos::{create_resource, Resource, SignalGet};
use leptos_router::use_params_map;
use leptos_router::use_params_map;use crate::frontend::api::CLIENT;
pub(crate) mod article;
pub(crate) mod diff;
@ -24,7 +21,7 @@ fn article_resource() -> Resource<Option<String>, ArticleView> {
title = title_.to_string();
domain = Some(domain_.to_string());
}
GlobalState::api_client()
CLIENT
.get_article(GetArticleForm {
title: Some(title),
domain,

View file

@ -1,6 +1,6 @@
use crate::{
common::Notification,
frontend::{app::GlobalState, article_link, article_title},
frontend::{api::CLIENT, article_link, article_title},
};
use leptos::*;
@ -9,7 +9,7 @@ pub fn Notifications() -> impl IntoView {
let notifications = create_local_resource(
move || {},
|_| async move {
GlobalState::api_client()
CLIENT
.notifications_list()
.await
.unwrap()

View file

@ -2,7 +2,7 @@ use crate::{
common::{LocalUserView, RegisterUserForm},
frontend::{app::GlobalState, components::credentials::*, error::MyResult},
};
use leptos::{logging::log, *};
use leptos::{logging::log, *};use crate::frontend::api::CLIENT;
#[component]
pub fn Register() -> impl IntoView {
@ -18,7 +18,7 @@ pub fn Register() -> impl IntoView {
async move {
set_wait_for_response.update(|w| *w = true);
let result: MyResult<LocalUserView> =
GlobalState::api_client().register(credentials).await;
CLIENT.register(credentials).await;
set_wait_for_response.update(|w| *w = false);
match result {
Ok(res) => {

View file

@ -1,11 +1,11 @@
use crate::{
common::{DbArticle, DbInstance, SearchArticleForm},
frontend::{app::GlobalState, article_link, article_title},
frontend::{article_link, article_title},
};
use leptos::*;
use leptos_router::use_query_map;
use serde::{Deserialize, Serialize};
use url::Url;
use url::Url;use crate::frontend::api::CLIENT;
#[derive(Default, Clone, Deserialize, Serialize, Debug)]
struct SearchResults {
@ -27,10 +27,9 @@ pub fn Search() -> impl IntoView {
let search_results = create_resource(query, move |query| async move {
set_error.set(None);
let mut search_results = SearchResults::default();
let api_client = GlobalState::api_client();
let url = Url::parse(&query);
let search_data = SearchArticleForm { query };
let search = api_client.search(&search_data);
let search = CLIENT.search(&search_data);
match search.await {
Ok(mut a) => search_results.articles.append(&mut a),
@ -39,11 +38,11 @@ pub fn Search() -> impl IntoView {
// If its a valid url, also attempt to resolve as federation object
if let Ok(url) = url {
match api_client.resolve_article(url.clone()).await {
match CLIENT.resolve_article(url.clone()).await {
Ok(a) => search_results.articles.push(a.article),
Err(e) => set_error.set(Some(e.0.to_string())),
}
match api_client.resolve_instance(url).await {
match CLIENT.resolve_instance(url).await {
Ok(a) => search_results.instance = Some(a),
Err(e) => set_error.set(Some(e.0.to_string())),
}

View file

@ -1,9 +1,9 @@
use crate::{
common::{DbPerson, GetUserForm},
frontend::{app::GlobalState, user_title},
frontend::user_title,
};
use leptos::*;
use leptos_router::use_params_map;
use leptos_router::use_params_map;use crate::frontend::api::CLIENT;
#[component]
pub fn UserProfile() -> impl IntoView {
@ -18,7 +18,7 @@ pub fn UserProfile() -> impl IntoView {
domain = Some(domain_.to_string());
}
let params = GetUserForm { name, domain };
GlobalState::api_client().get_user(params).await.unwrap()
CLIENT.get_user(params).await.unwrap()
});
view! {