From 862297638fbcaaa44299d5f9ce64b0b94b7023f3 Mon Sep 17 00:00:00 2001
From: Felix Ableitner
Date: Thu, 1 Feb 2024 12:52:55 +0100
Subject: [PATCH] also resolve articles/instances on search page
---
src/backend/api/article.rs | 12 ++------
src/backend/api/instance.rs | 1 -
src/frontend/api.rs | 2 +-
src/frontend/pages/search.rs | 60 +++++++++++++++++++++++++++---------
4 files changed, 50 insertions(+), 25 deletions(-)
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()}