From d275ce7f044e557f312e26899dd878778acac8cc Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 8 Jun 2024 03:39:38 +0200 Subject: [PATCH] feat(web): better timelines, add use obj, add notifs --- web/src/app.rs | 70 ++++++++++++++++++++++++-------- web/src/components/login.rs | 21 ++++++---- web/src/components/navigation.rs | 1 + web/src/components/timeline.rs | 6 ++- web/src/page/object.rs | 15 +++---- web/src/page/timeline.rs | 2 +- web/src/page/user.rs | 15 +++---- web/src/prelude.rs | 1 + 8 files changed, 88 insertions(+), 43 deletions(-) diff --git a/web/src/app.rs b/web/src/app.rs index 6bd52daf..ff5eb898 100644 --- a/web/src/app.rs +++ b/web/src/app.rs @@ -4,6 +4,44 @@ use crate::prelude::*; use leptos_use::{storage::use_local_storage, use_cookie, utils::{FromToStringCodec, JsonCodec}}; +#[derive(Clone, Copy)] +pub struct Feeds { + // object feeds + pub home: Timeline, + pub global: Timeline, + // notification feeds + pub private: Timeline, + pub public: Timeline, + // exploration feeds + pub user: Timeline, + pub server: Timeline, + pub context: Timeline, +} + +impl Feeds { + pub fn new(username: &str) -> Self { + Feeds { + home: Timeline::new(format!("{URL_BASE}/actors/{username}/feed/page")), + global: Timeline::new(format!("{URL_BASE}/feed/page")), + private: Timeline::new(format!("{URL_BASE}/actors/{username}/inbox/page")), + public: Timeline::new(format!("{URL_BASE}/inbox/page")), + user: Timeline::new(format!("{URL_BASE}/actors/{username}/outbox/page")), + server: Timeline::new(format!("{URL_BASE}/outbox/page")), + context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh + } + } + + pub fn reset(&self) { + self.home.reset(None); + self.global.reset(None); + self.private.reset(None); + self.public.reset(None); + self.user.reset(None); + self.server.reset(None); + self.context.reset(None); + } +} + #[component] pub fn App() -> impl IntoView { @@ -12,18 +50,16 @@ pub fn App() -> impl IntoView { let (config, set_config, _) = use_local_storage::("config"); let auth = Auth { token, userid }; - provide_context(auth); - provide_context(config); let username = auth.userid.get_untracked() .map(|x| x.split('/').last().unwrap_or_default().to_string()) .unwrap_or_default(); - let home_tl = Timeline::new(format!("{URL_BASE}/actors/{username}/inbox/page")); - let user_tl = Timeline::new(format!("{URL_BASE}/actors/{username}/outbox/page")); - let server_tl = Timeline::new(format!("{URL_BASE}/inbox/page")); - let local_tl = Timeline::new(format!("{URL_BASE}/outbox/page")); - let context_tl = Timeline::new(format!("{URL_BASE}/outbox/page")); // TODO ehhh + let feeds = Feeds::new(&username); + + provide_context(auth); + provide_context(config); + provide_context(feeds); let reply_controls = ReplyControls::default(); provide_context(reply_controls); @@ -35,13 +71,14 @@ pub fn App() -> impl IntoView { let title_target = move || if auth.present() { "/web/home" } else { "/web/server" }; - local_tl.more(auth); // public outbox never contains private posts spawn_local(async move { // refresh token first, or verify that we're still authed if Auth::refresh(auth.token, set_token, set_userid).await { - home_tl.more(auth); // home inbox requires auth to be read + feeds.home.more(auth); // home inbox requires auth to be read + feeds.private.more(auth); } - server_tl.more(auth); // server inbox may contain private posts + feeds.global.more(auth); + feeds.public.more(auth); // server inbox may contain private posts }); @@ -67,8 +104,6 @@ pub fn App() -> impl IntoView {
@@ -105,16 +140,17 @@ pub fn App() -> impl IntoView { } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> } /> - } /> - } /> + + // } /> diff --git a/web/src/components/login.rs b/web/src/components/login.rs index 50e18d6a..ce2a6d10 100644 --- a/web/src/components/login.rs +++ b/web/src/components/login.rs @@ -5,21 +5,20 @@ use crate::prelude::*; pub fn LoginBox( token_tx: WriteSignal>, userid_tx: WriteSignal>, - home_tl: Timeline, - server_tl: Timeline, ) -> impl IntoView { let auth = use_context::().expect("missing auth context"); let username_ref: NodeRef = create_node_ref(); let password_ref: NodeRef = create_node_ref(); + let feeds = use_context::().expect("missing feeds context"); view! {
@@ -45,11 +44,15 @@ pub fn LoginBox( userid_tx.set(Some(auth_response.user)); token_tx.set(Some(auth_response.token)); // reset home feed and point it to our user's inbox - home_tl.reset(format!("{URL_BASE}/actors/{}/inbox/page", username)); - home_tl.more(auth); + feeds.home.reset(Some(format!("{URL_BASE}/actors/{username}/feed/page"))); + feeds.home.more(auth); + feeds.private.reset(Some(format!("{URL_BASE}/actors/{username}/inbox/page"))); + feeds.private.more(auth); // reset server feed: there may be more content now that we're authed - server_tl.reset(format!("{URL_BASE}/inbox/page")); - server_tl.more(auth); + feeds.global.reset(Some(format!("{URL_BASE}/feed/page"))); + feeds.global.more(auth); + feeds.server.reset(Some(format!("{URL_BASE}/inbox/page"))); + feeds.server.more(auth); }); } > diff --git a/web/src/components/navigation.rs b/web/src/components/navigation.rs index 7b9b8f32..10f6d8c2 100644 --- a/web/src/components/navigation.rs +++ b/web/src/components/navigation.rs @@ -40,6 +40,7 @@ pub fn Navigator() -> impl IntoView { + diff --git a/web/src/components/timeline.rs b/web/src/components/timeline.rs index 0530ba34..05dafc21 100644 --- a/web/src/components/timeline.rs +++ b/web/src/components/timeline.rs @@ -30,10 +30,12 @@ impl Timeline { self.feed.get().is_empty() } - pub fn reset(&self, url: String) { + pub fn reset(&self, url: Option) { self.feed.set(vec![]); - self.next.set(url); self.over.set(false); + if let Some(url) = url { + self.next.set(url); + } } pub fn more(&self, auth: Auth) { diff --git a/web/src/page/object.rs b/web/src/page/object.rs index 8a362a9b..ea000efd 100644 --- a/web/src/page/object.rs +++ b/web/src/page/object.rs @@ -7,9 +7,10 @@ use crate::prelude::*; use apb::{Base, Object}; #[component] -pub fn ObjectPage(tl: Timeline) -> impl IntoView { +pub fn ObjectPage() -> impl IntoView { let params = use_params_map(); let auth = use_context::().expect("missing auth context"); + let feeds = use_context::().expect("missing feeds context"); let object = create_local_resource( move || params.get().get("id").cloned().unwrap_or_default(), move |oid| async move { @@ -36,8 +37,8 @@ pub fn ObjectPage(tl: Timeline) -> impl IntoView { }; if let Ok(ctx) = obj.context().id() { let tl_url = format!("{}/context/page", Uri::api(U::Object, ctx, false)); - if !tl.next.get_untracked().starts_with(&tl_url) { - tl.reset(tl_url); + if !feeds.context.next.get_untracked().starts_with(&tl_url) { + feeds.context.reset(Some(tl_url)); } } @@ -50,10 +51,10 @@ pub fn ObjectPage(tl: Timeline) -> impl IntoView { objects::view "\u{1f5d8}" @@ -71,7 +72,7 @@ pub fn ObjectPage(tl: Timeline) -> impl IntoView { view!{
- +
}.into_view() }, diff --git a/web/src/page/timeline.rs b/web/src/page/timeline.rs index fb7b5420..7934251e 100644 --- a/web/src/page/timeline.rs +++ b/web/src/page/timeline.rs @@ -9,7 +9,7 @@ pub fn TimelinePage(name: &'static str, tl: Timeline) -> impl IntoView { {name} "\u{1f5d8}" diff --git a/web/src/page/user.rs b/web/src/page/user.rs index 32316abd..916fe0e7 100644 --- a/web/src/page/user.rs +++ b/web/src/page/user.rs @@ -20,8 +20,9 @@ fn send_follow_request(target: String) { } #[component] -pub fn UserPage(tl: Timeline) -> impl IntoView { +pub fn UserPage() -> impl IntoView { let params = use_params_map(); + let feeds = use_context::().expect("missing feeds context"); let auth = use_context::().expect("missing auth context"); let id = params.get() .get("id") @@ -33,8 +34,8 @@ pub fn UserPage(tl: Timeline) -> impl IntoView { move |id| { async move { let tl_url = format!("{}/outbox/page", Uri::api(U::Actor, &id, false)); - if !tl.next.get_untracked().starts_with(&tl_url) { - tl.reset(tl_url); + if !feeds.user.next.get_untracked().starts_with(&tl_url) { + feeds.user.reset(Some(tl_url)); } match CACHE.get(&Uri::full(U::Actor, &id)) { Some(x) => Some(x.clone()), @@ -54,10 +55,10 @@ pub fn UserPage(tl: Timeline) -> impl IntoView { users::view "\u{1f5d8}" @@ -138,7 +139,7 @@ pub fn UserPage(tl: Timeline) -> impl IntoView {

- + }.into_view() }, } diff --git a/web/src/prelude.rs b/web/src/prelude.rs index 7601d0f0..d2c6ef67 100644 --- a/web/src/prelude.rs +++ b/web/src/prelude.rs @@ -1,6 +1,7 @@ pub use crate::{ Http, Uri, CACHE, URL_BASE, + app::Feeds, auth::Auth, page::*, components::*,