feat(web): add resolve directly to cache
should slim down code more down the line
This commit is contained in:
parent
12073bfed4
commit
bae7aab3df
3 changed files with 38 additions and 43 deletions
|
@ -13,18 +13,13 @@ pub fn ActorHeader() -> impl IntoView {
|
||||||
move |id| {
|
move |id| {
|
||||||
async move {
|
async move {
|
||||||
match cache::OBJECTS.get(&Uri::full(U::Actor, &id)) {
|
match cache::OBJECTS.get(&Uri::full(U::Actor, &id)) {
|
||||||
Some(x) => Ok::<_, String>(x.clone()),
|
Some(x) => Some(x.clone()),
|
||||||
None => {
|
None => {
|
||||||
let user : serde_json::Value = Http::fetch(&Uri::api(U::Actor, &id, true), auth)
|
let user = cache::OBJECTS.resolve(&id, U::Actor, auth).await?;
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
let user = std::sync::Arc::new(user);
|
|
||||||
let uid = Uri::full(U::Actor, &id);
|
|
||||||
cache::OBJECTS.store(&uid, user.clone());
|
|
||||||
if let Some(url) = user.url().id().str() {
|
if let Some(url) = user.url().id().str() {
|
||||||
cache::WEBFINGER.store(&url, uid);
|
cache::WEBFINGER.store(&url, user.id().unwrap_or_default().to_string());
|
||||||
}
|
}
|
||||||
Ok(user)
|
Some(user)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +27,8 @@ pub fn ActorHeader() -> impl IntoView {
|
||||||
);
|
);
|
||||||
move || match actor.get() {
|
move || match actor.get() {
|
||||||
None => view! { <Loader /> }.into_view(),
|
None => view! { <Loader /> }.into_view(),
|
||||||
Some(Err(e)) => view! { <code class="center cw color">"could not resolve user: "{e}</code> }.into_view(),
|
Some(None) => view! { <code class="center cw color">"could not resolve user"</code> }.into_view(),
|
||||||
Some(Ok(actor)) => {
|
Some(Some(actor)) => {
|
||||||
let avatar_url = actor.icon().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
|
let avatar_url = actor.icon().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
|
||||||
let background_url = actor.image().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
|
let background_url = actor.image().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
|
||||||
let username = actor.preferred_username().unwrap_or_default().to_string();
|
let username = actor.preferred_username().unwrap_or_default().to_string();
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub mod cache {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LookupStatus<T> {
|
pub enum LookupStatus<T> {
|
||||||
Resolving,
|
Resolving, // TODO use this to avoid fetching twice!
|
||||||
Found(T),
|
Found(T),
|
||||||
NotFound,
|
NotFound,
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,26 @@ impl<T> Cache for DashmapCache<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DashmapCache<Object> {
|
||||||
|
pub async fn resolve(&self, key: &str, kind: UriClass, auth: Auth) -> Option<Object> {
|
||||||
|
let full_key = Uri::full(kind, key);
|
||||||
|
match self.get(&full_key) {
|
||||||
|
Some(x) => Some(x),
|
||||||
|
None => {
|
||||||
|
let obj = match Http::fetch::<serde_json::Value>(&Uri::api(kind, key, true), auth).await {
|
||||||
|
Ok(obj) => Arc::new(obj),
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("failed loading object from backend: {e}");
|
||||||
|
return None;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cache::OBJECTS.store(&full_key, obj.clone());
|
||||||
|
Some(obj)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO would be cool unifying a bit the fetch code too
|
// TODO would be cool unifying a bit the fetch code too
|
||||||
|
|
||||||
impl DashmapCache<Object> {
|
impl DashmapCache<Object> {
|
||||||
|
|
|
@ -1,48 +1,28 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_router::*;
|
use leptos_router::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use apb::{Base, Object};
|
use apb::{Object};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ObjectView() -> impl IntoView {
|
pub fn ObjectView() -> impl IntoView {
|
||||||
let params = use_params_map();
|
let params = use_params_map();
|
||||||
let auth = use_context::<Auth>().expect("missing auth context");
|
let auth = use_context::<Auth>().expect("missing auth context");
|
||||||
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
|
||||||
let object = create_local_resource(
|
let object = create_local_resource(
|
||||||
move || params.get().get("id").cloned().unwrap_or_default(),
|
move || params.get().get("id").cloned().unwrap_or_default(),
|
||||||
move |oid| async move {
|
move |oid| async move {
|
||||||
let obj = match cache::OBJECTS.get(&Uri::full(U::Object, &oid)) {
|
let obj = cache::OBJECTS.resolve(&oid, U::Object, auth).await?;
|
||||||
Some(x) => x.clone(),
|
if let Ok(author) = obj.attributed_to().id() {
|
||||||
None => {
|
cache::OBJECTS.resolve(&author, U::Actor, auth).await;
|
||||||
let obj = match Http::fetch::<serde_json::Value>(&Uri::api(U::Object, &oid, true), auth).await {
|
|
||||||
Ok(obj) => Arc::new(obj),
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("failed loading object from backend: {e}");
|
|
||||||
return None;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if let Ok(author) = obj.attributed_to().id() {
|
|
||||||
if let Ok(user) = Http::fetch::<serde_json::Value>(
|
|
||||||
&Uri::api(U::Actor, author, true), auth
|
|
||||||
).await {
|
|
||||||
cache::OBJECTS.store(&Uri::full(U::Actor, author), Arc::new(user));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cache::OBJECTS.store(&Uri::full(U::Object, &oid), obj.clone());
|
|
||||||
obj
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Ok(ctx) = obj.context().id() {
|
|
||||||
let tl_url = format!("{}/context/page", Uri::api(U::Object, ctx, false));
|
|
||||||
if !feeds.context.next.get_untracked().starts_with(&tl_url) {
|
|
||||||
feeds.context.reset(Some(tl_url));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(obj)
|
Some(obj)
|
||||||
|
|
||||||
|
// if let Ok(ctx) = obj.context().id() {
|
||||||
|
// let tl_url = format!("{}/context/page", Uri::api(U::Object, ctx, false));
|
||||||
|
// if !feeds.context.next.get_untracked().starts_with(&tl_url) {
|
||||||
|
// feeds.context.reset(Some(tl_url));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue