mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 08:51:09 +00:00
also resolve articles/instances on search page
This commit is contained in:
parent
1dc984025a
commit
862297638f
4 changed files with 50 additions and 25 deletions
|
@ -216,15 +216,9 @@ pub(in crate::backend::api) async fn fork_article(
|
||||||
pub(super) async fn resolve_article(
|
pub(super) async fn resolve_article(
|
||||||
Query(query): Query<ResolveObject>,
|
Query(query): Query<ResolveObject>,
|
||||||
data: Data<MyDataHandle>,
|
data: Data<MyDataHandle>,
|
||||||
) -> MyResult<Json<ArticleView>> {
|
) -> MyResult<Json<DbArticle>> {
|
||||||
let article: DbArticle = ObjectId::from(query.id).dereference(&data).await?;
|
let article = ObjectId::from(query.id).dereference(&data).await?;
|
||||||
let edits = DbEdit::read_for_article(&article, &data.db_connection)?;
|
Ok(Json(article))
|
||||||
let latest_version = edits.last().unwrap().hash.clone();
|
|
||||||
Ok(Json(ArticleView {
|
|
||||||
article,
|
|
||||||
edits,
|
|
||||||
latest_version,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search articles for matching title or body text.
|
/// Search articles for matching title or body text.
|
||||||
|
|
|
@ -42,7 +42,6 @@ pub(super) async fn resolve_instance(
|
||||||
Query(query): Query<ResolveObject>,
|
Query(query): Query<ResolveObject>,
|
||||||
data: Data<MyDataHandle>,
|
data: Data<MyDataHandle>,
|
||||||
) -> MyResult<Json<DbInstance>> {
|
) -> MyResult<Json<DbInstance>> {
|
||||||
// TODO: workaround because axum makes it hard to have multiple routes on /
|
|
||||||
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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ impl ApiClient {
|
||||||
Ok(handle_json_res(req).await.unwrap())
|
Ok(handle_json_res(req).await.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resolve_article(&self, id: Url) -> MyResult<ArticleView> {
|
pub async fn resolve_article(&self, id: Url) -> MyResult<DbArticle> {
|
||||||
let resolve_object = ResolveObject { id };
|
let resolve_object = ResolveObject { id };
|
||||||
self.get_query("article/resolve", Some(resolve_object))
|
self.get_query("article/resolve", Some(resolve_object))
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,34 +1,66 @@
|
||||||
use crate::common::SearchArticleData;
|
use crate::common::{DbArticle, DbInstance, SearchArticleData};
|
||||||
use crate::frontend::app::GlobalState;
|
use crate::frontend::app::GlobalState;
|
||||||
|
use futures::join;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_router::use_query_map;
|
use leptos_router::use_query_map;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Deserialize, Serialize)]
|
||||||
|
struct SearchResults {
|
||||||
|
articles: Vec<DbArticle>,
|
||||||
|
instance: Option<DbInstance>,
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Search() -> impl IntoView {
|
pub fn Search() -> impl IntoView {
|
||||||
let params = use_query_map();
|
let params = use_query_map();
|
||||||
let query = params.get_untracked().get("query").cloned().unwrap();
|
let query = move || params.get().get("query").cloned().unwrap();
|
||||||
let query_ = query.clone();
|
let search_results = create_resource(query, move |query| async move {
|
||||||
let search_results = create_resource(
|
let mut search_results = SearchResults::default();
|
||||||
move || query_.clone(),
|
let api_client = GlobalState::api_client();
|
||||||
move |query| async move {
|
let url = Url::parse(&query);
|
||||||
GlobalState::api_client()
|
let search_data = SearchArticleData { query };
|
||||||
.search(&SearchArticleData { query })
|
let search = api_client.search(&search_data);
|
||||||
.await
|
|
||||||
.unwrap()
|
// If its a valid url, also attempt to resolve as federation object
|
||||||
},
|
if let Ok(url) = url {
|
||||||
);
|
let resolve_article = api_client.resolve_article(url.clone());
|
||||||
|
let resolve_instance = api_client.resolve_instance(url);
|
||||||
|
let (search, resolve_article, resolve_instance) =
|
||||||
|
join!(search, resolve_article, resolve_instance);
|
||||||
|
search_results.instance = resolve_instance.ok();
|
||||||
|
if let Ok(article) = resolve_article {
|
||||||
|
search_results.articles.push(article);
|
||||||
|
}
|
||||||
|
search_results.articles.append(&mut search.unwrap())
|
||||||
|
} else {
|
||||||
|
search_results.articles.append(&mut search.await.unwrap())
|
||||||
|
}
|
||||||
|
search_results
|
||||||
|
});
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<h1>"Search results for "{query}</h1>
|
<h1>"Search results for "{query}</h1>
|
||||||
<Suspense fallback=|| view! { "Loading..." }> {
|
<Suspense fallback=|| view! { "Loading..." }> {
|
||||||
move || search_results.get().map(|search_results| {
|
move || search_results.get().map(|search_results| {
|
||||||
let is_empty = search_results.is_empty();
|
let is_empty = search_results.articles.is_empty() && search_results.instance.is_none();
|
||||||
view! {
|
view! {
|
||||||
<Show when=move || !is_empty
|
<Show when=move || !is_empty
|
||||||
fallback=|| view! { <p>No results found</p> }>
|
fallback=|| view! { <p>No results found</p> }>
|
||||||
<ul>
|
<ul>
|
||||||
{
|
{
|
||||||
search_results
|
// render resolved instance
|
||||||
|
if let Some(instance) = &search_results.instance {
|
||||||
|
let ap_id = instance.ap_id.to_string();
|
||||||
|
vec![view! { <li>
|
||||||
|
<a href={format!("/instance/{ap_id}")}>{ap_id}</a>
|
||||||
|
</li>}]
|
||||||
|
} else { vec![] }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// render articles from resolve/search
|
||||||
|
search_results.articles
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| view! { <li>
|
.map(|a| view! { <li>
|
||||||
<a href={format!("/article/{}", a.title)}>{a.title()}</a>
|
<a href={format!("/article/{}", a.title)}>{a.title()}</a>
|
||||||
|
|
Loading…
Reference in a new issue