1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2024-11-26 03:11:09 +00:00

Instance list

This commit is contained in:
Felix Ableitner 2024-11-11 11:20:28 +01:00
parent 4ebd4600fc
commit 627b0067b5
11 changed files with 96 additions and 4 deletions

View file

@ -20,7 +20,7 @@ ssr = [
"katex/duktape", "katex/duktape",
"leptos/ssr", "leptos/ssr",
"leptos-use/ssr", "leptos-use/ssr",
"leptos-use/axum" "leptos-use/axum",
] ]
hydrate = [ hydrate = [
"leptos/hydrate", "leptos/hydrate",

View file

@ -42,3 +42,11 @@ pub(super) async fn resolve_instance(
let instance: DbInstance = ObjectId::from(query.id).dereference(&data).await?; let instance: DbInstance = ObjectId::from(query.id).dereference(&data).await?;
Ok(Json(instance)) Ok(Json(instance))
} }
#[debug_handler]
pub(in crate::backend::api) async fn list_remote_instances(
data: Data<IbisData>,
) -> MyResult<Json<Vec<DbInstance>>> {
let instances = DbInstance::read_remote(&data)?;
Ok(Json(instances))
}

View file

@ -41,6 +41,7 @@ use axum::{
use axum_extra::extract::CookieJar; use axum_extra::extract::CookieJar;
use axum_macros::debug_handler; use axum_macros::debug_handler;
use futures::future::try_join_all; use futures::future::try_join_all;
use instance::list_remote_instances;
pub mod article; pub mod article;
pub mod instance; pub mod instance;
@ -60,6 +61,7 @@ pub fn api_routes() -> Router<()> {
.route("/instance", get(get_instance)) .route("/instance", get(get_instance))
.route("/instance/follow", post(follow_instance)) .route("/instance/follow", post(follow_instance))
.route("/instance/resolve", get(resolve_instance)) .route("/instance/resolve", get(resolve_instance))
.route("/instance/list", get(list_remote_instances))
.route("/search", get(search_article)) .route("/search", get(search_article))
.route("/user", get(get_user)) .route("/user", get(get_user))
.route("/account/register", post(register_user)) .route("/account/register", post(register_user))

View file

@ -119,4 +119,11 @@ impl DbInstance {
.select(person::all_columns) .select(person::all_columns)
.get_results(conn.deref_mut())?) .get_results(conn.deref_mut())?)
} }
pub fn read_remote(data: &Data<IbisData>) -> MyResult<Vec<DbInstance>> {
let mut conn = data.db_pool.get()?;
Ok(instance::table
.filter(instance::local.eq(false))
.get_results(conn.deref_mut())?)
}
} }

View file

@ -142,6 +142,10 @@ impl ApiClient {
self.get_query("/api/v1/instance", Some(get_form)).await self.get_query("/api/v1/instance", Some(get_form)).await
} }
pub async fn list_instances(&self) -> MyResult<Vec<DbInstance>> {
self.get_query("/api/v1/instance/list", None::<i32>).await
}
pub async fn follow_instance_with_resolve( pub async fn follow_instance_with_resolve(
&self, &self,
follow_instance: &str, follow_instance: &str,

View file

@ -15,7 +15,7 @@ use crate::{
}, },
conflicts::Conflicts, conflicts::Conflicts,
diff::EditDiff, diff::EditDiff,
instance_details::InstanceDetails, instance::{details::InstanceDetails, list::ListInstances},
login::Login, login::Login,
register::Register, register::Register,
search::Search, search::Search,
@ -120,6 +120,7 @@ pub fn App() -> impl IntoView {
<Route path="/article/create" view=CreateArticle /> <Route path="/article/create" view=CreateArticle />
<Route path="/article/list" view=ListArticles /> <Route path="/article/list" view=ListArticles />
<Route path="/instance/:hostname" view=InstanceDetails /> <Route path="/instance/:hostname" view=InstanceDetails />
<Route path="/instance/list" view=ListInstances />
<Route path="/user/:name" view=UserProfile /> <Route path="/user/:name" view=UserProfile />
<Route path="/login" view=Login /> <Route path="/login" view=Login />
<Route path="/register" view=Register /> <Route path="/register" view=Register />

View file

@ -47,7 +47,10 @@ pub fn Nav() -> impl IntoView {
<A href="/">"Main Page"</A> <A href="/">"Main Page"</A>
</li> </li>
<li> <li>
<A href="/article/list">"List Articles"</A> <A href="/instance/list">"Instances"</A>
</li>
<li>
<A href="/article/list">"Articles"</A>
</li> </li>
<Show when=move || global_state.with(|state| state.my_profile.is_some())> <Show when=move || global_state.with(|state| state.my_profile.is_some())>
<li> <li>

View file

@ -0,0 +1,65 @@
use crate::frontend::app::GlobalState;
use leptos::*;
use url::Url;
#[component]
pub fn ListInstances() -> impl IntoView {
let instances = create_resource(
move || (),
|_| async move { GlobalState::api_client().list_instances().await.unwrap() },
);
let connect_ibis_wiki = create_action(move |_: &()| async move {
GlobalState::api_client()
.resolve_instance(Url::parse("https://ibis.wiki").unwrap())
.await
.unwrap();
instances.refetch();
});
let fallback = move || {
view! {
<div class="flex justify-center h-screen">
<button
class="btn btn-primary place-self-center"
on:click=move |_| connect_ibis_wiki.dispatch(())
>
Connect with ibis.wiki
</button>
</div>
}
};
view! {
<h1 class="text-4xl font-bold font-serif my-4">Instances</h1>
<Suspense fallback=|| view! { "Loading..." }>
<Show
when=move || { !instances.get().unwrap_or_default().is_empty() }
fallback=fallback
>
<ul class="list-none my-4">
{move || {
instances
.get()
.map(|a| {
a.into_iter()
.map(|i| {
view! {
<li>
<a
class="link text-lg"
href=format!("/instance/{}", i.domain)
>
{i.domain}
</a>
</li>
}
})
.collect::<Vec<_>>()
})
}}
</ul>
</Show>
</Suspense>
}
}

View file

@ -0,0 +1,2 @@
pub(crate) mod details;
pub(crate) mod list;

View file

@ -8,7 +8,7 @@ use leptos_router::use_params_map;
pub(crate) mod article; pub(crate) mod article;
pub(crate) mod conflicts; pub(crate) mod conflicts;
pub(crate) mod diff; pub(crate) mod diff;
pub(crate) mod instance_details; pub(crate) mod instance;
pub(crate) mod login; pub(crate) mod login;
pub(crate) mod register; pub(crate) mod register;
pub(crate) mod search; pub(crate) mod search;