mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 09:31: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(
|
||||
Query(query): Query<ResolveObject>,
|
||||
data: Data<MyDataHandle>,
|
||||
) -> MyResult<Json<ArticleView>> {
|
||||
let article: DbArticle = ObjectId::from(query.id).dereference(&data).await?;
|
||||
let edits = DbEdit::read_for_article(&article, &data.db_connection)?;
|
||||
let latest_version = edits.last().unwrap().hash.clone();
|
||||
Ok(Json(ArticleView {
|
||||
article,
|
||||
edits,
|
||||
latest_version,
|
||||
}))
|
||||
) -> MyResult<Json<DbArticle>> {
|
||||
let article = ObjectId::from(query.id).dereference(&data).await?;
|
||||
Ok(Json(article))
|
||||
}
|
||||
|
||||
/// Search articles for matching title or body text.
|
||||
|
|
|
@ -42,7 +42,6 @@ pub(super) async fn resolve_instance(
|
|||
Query(query): Query<ResolveObject>,
|
||||
data: Data<MyDataHandle>,
|
||||
) -> 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?;
|
||||
Ok(Json(instance))
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ impl ApiClient {
|
|||
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 };
|
||||
self.get_query("article/resolve", Some(resolve_object))
|
||||
.await
|
||||
|
|
|
@ -1,34 +1,66 @@
|
|||
use crate::common::SearchArticleData;
|
||||
use crate::common::{DbArticle, DbInstance, SearchArticleData};
|
||||
use crate::frontend::app::GlobalState;
|
||||
use futures::join;
|
||||
use leptos::*;
|
||||
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]
|
||||
pub fn Search() -> impl IntoView {
|
||||
let params = use_query_map();
|
||||
let query = params.get_untracked().get("query").cloned().unwrap();
|
||||
let query_ = query.clone();
|
||||
let search_results = create_resource(
|
||||
move || query_.clone(),
|
||||
move |query| async move {
|
||||
GlobalState::api_client()
|
||||
.search(&SearchArticleData { query })
|
||||
.await
|
||||
.unwrap()
|
||||
},
|
||||
);
|
||||
let query = move || params.get().get("query").cloned().unwrap();
|
||||
let search_results = create_resource(query, move |query| async move {
|
||||
let mut search_results = SearchResults::default();
|
||||
let api_client = GlobalState::api_client();
|
||||
let url = Url::parse(&query);
|
||||
let search_data = SearchArticleData { query };
|
||||
let search = api_client.search(&search_data);
|
||||
|
||||
// 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! {
|
||||
<h1>"Search results for "{query}</h1>
|
||||
<Suspense fallback=|| view! { "Loading..." }> {
|
||||
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! {
|
||||
<Show when=move || !is_empty
|
||||
fallback=|| view! { <p>No results found</p> }>
|
||||
<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()
|
||||
.map(|a| view! { <li>
|
||||
<a href={format!("/article/{}", a.title)}>{a.title()}</a>
|
||||
|
|
Loading…
Reference in a new issue