mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-26 03:11:09 +00:00
Instance list
This commit is contained in:
parent
4ebd4600fc
commit
627b0067b5
11 changed files with 96 additions and 4 deletions
|
@ -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",
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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())?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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>
|
||||||
|
|
65
src/frontend/pages/instance/list.rs
Normal file
65
src/frontend/pages/instance/list.rs
Normal 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>
|
||||||
|
}
|
||||||
|
}
|
2
src/frontend/pages/instance/mod.rs
Normal file
2
src/frontend/pages/instance/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub(crate) mod details;
|
||||||
|
pub(crate) mod list;
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue