diff --git a/web/Cargo.toml b/web/Cargo.toml index d8b5b02d..e207bff1 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -26,3 +26,4 @@ reqwest = { version = "0.12", features = ["json"] } apb = { path = "../apb", features = ["unstructured"] } futures = "0.3.30" dissolve = "0.2" # TODO strip html without this crate +lazy_static = "1.4" diff --git a/web/src/context.rs b/web/src/context.rs new file mode 100644 index 00000000..ff1ae075 --- /dev/null +++ b/web/src/context.rs @@ -0,0 +1,23 @@ +use std::sync::Arc; + +use dashmap::DashMap; +use lazy_static::lazy_static; + +lazy_static! { + pub static ref CTX: Context = Context::default(); +} + +#[derive(Debug, Default, Clone)] +pub struct Context { + pub cache: Arc, + pub timelines: Arc, +} + +#[derive(Debug, Default)] +pub struct Cache { + pub user: DashMap, +} + +#[derive(Debug, Default)] +pub struct Timelines { +} diff --git a/web/src/lib.rs b/web/src/lib.rs index 12297be9..596a61e1 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -1,10 +1,11 @@ -use std::sync::Arc; +pub mod context; use apb::{target::Addressed, Activity, ActivityMut, Actor, Base, Collection, Object, ObjectMut}; -use dashmap::DashMap; +use context::CTX; use leptos::{leptos_dom::logging::console_log, *}; use leptos_router::*; + pub const URL_BASE: &str = "https://feditest.alemi.dev"; pub const URL_PREFIX: &str = "/web"; @@ -145,12 +146,16 @@ pub fn Actor() -> impl IntoView { let params = use_params_map(); let actor = create_local_resource(move || params.get().get("id").cloned().unwrap_or_default(), |uid| { async move { - reqwest::get(format!("{URL_BASE}/users/{uid}")) + let uid = format!("{URL_BASE}/users/{uid}"); + match CTX.cache.user.get(&uid) { + Some(x) => x.clone(), + None => reqwest::get(uid) .await .unwrap() .json::() .await - .unwrap() + .unwrap(), + } } }); view! { @@ -231,11 +236,8 @@ pub fn Timeline( token: Signal>, ) -> impl IntoView { let (timeline, set_timeline) = create_signal(format!("{URL_BASE}/inbox/page")); - let users : Arc> = Arc::new(DashMap::new()); - let _users = users.clone(); // TODO i think there is syntactic sugar i forgot? - let items = create_local_resource(move || timeline.get(), move |feed_url| { - let __users = _users.clone(); // TODO lmao this is meme tier - async move { fetch_activities_with_users(&feed_url, token, __users).await } + let items = create_local_resource(move || timeline.get(), move |feed_url| async move { + fetch_activities_with_users(&feed_url, token).await }); view! {
@@ -275,7 +277,6 @@ pub fn Timeline( async fn fetch_activities_with_users( feed_url: &str, token: Signal>, - users: Arc>, ) -> reqwest::Result> { let mut req = reqwest::Client::new().get(feed_url); @@ -298,7 +299,7 @@ async fn fetch_activities_with_users( let mut out = Vec::new(); for x in activities { if let Some(uid) = x.actor().id() { - if let Some(actor) = users.get(&uid) { + if let Some(actor) = CTX.cache.user.get(&uid) { out.push(x.set_actor(apb::Node::object(actor.clone()))) } else { let mut req = reqwest::Client::new() @@ -310,7 +311,7 @@ async fn fetch_activities_with_users( // TODO don't fail whole timeline fetch when one user fails fetching... let actor = req.send().await?.json::().await?; - users.insert(uid, actor.clone()); + CTX.cache.user.insert(uid, actor.clone()); out.push(x.set_actor(apb::Node::object(actor))) }