diff --git a/src/backend/api/article.rs b/src/backend/api/article.rs index 124069d..7805a08 100644 --- a/src/backend/api/article.rs +++ b/src/backend/api/article.rs @@ -216,15 +216,9 @@ pub(in crate::backend::api) async fn fork_article( pub(super) async fn resolve_article( Query(query): Query, data: Data, -) -> MyResult> { - 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> { + let article = ObjectId::from(query.id).dereference(&data).await?; + Ok(Json(article)) } /// Search articles for matching title or body text. diff --git a/src/backend/api/instance.rs b/src/backend/api/instance.rs index bf1d8fb..0b5719d 100644 --- a/src/backend/api/instance.rs +++ b/src/backend/api/instance.rs @@ -42,7 +42,6 @@ pub(super) async fn resolve_instance( Query(query): Query, data: Data, ) -> MyResult> { - // 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)) } diff --git a/src/frontend/api.rs b/src/frontend/api.rs index 0f0ad15..f84e9b4 100644 --- a/src/frontend/api.rs +++ b/src/frontend/api.rs @@ -156,7 +156,7 @@ impl ApiClient { Ok(handle_json_res(req).await.unwrap()) } - pub async fn resolve_article(&self, id: Url) -> MyResult { + pub async fn resolve_article(&self, id: Url) -> MyResult { let resolve_object = ResolveObject { id }; self.get_query("article/resolve", Some(resolve_object)) .await diff --git a/src/frontend/pages/search.rs b/src/frontend/pages/search.rs index 44e5989..044c7ca 100644 --- a/src/frontend/pages/search.rs +++ b/src/frontend/pages/search.rs @@ -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, + instance: Option, +} #[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! {

"Search results for "{query}

{ 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! { No results found

}>
    { - search_results + // render resolved instance + if let Some(instance) = &search_results.instance { + let ap_id = instance.ap_id.to_string(); + vec![view! {
  • + {ap_id} +
  • }] + } else { vec![] } + } + { + // render articles from resolve/search + search_results.articles .iter() .map(|a| view! {
  • {a.title()}