feat(web): hashtags timeline page

rather jank, literally hotglued on other feeds but eh it works for now
ig?
This commit is contained in:
əlemi 2024-07-04 03:14:26 +02:00
parent 2836ec2b37
commit 8ab39bfb2b
Signed by: alemi
GPG key ID: A4895B84D311642C
9 changed files with 38 additions and 11 deletions

1
Cargo.lock generated
View file

@ -4795,7 +4795,6 @@ dependencies = [
"chrono", "chrono",
"httpsign", "httpsign",
"jrd", "jrd",
"mdhtml",
"nodeinfo", "nodeinfo",
"openssl", "openssl",
"regex", "regex",

View file

@ -10,7 +10,7 @@ use apb::Collection;
pub fn FollowList(outgoing: bool) -> impl IntoView { pub fn FollowList(outgoing: bool) -> impl IntoView {
let follow___ = if outgoing { "following" } else { "followers" }; let follow___ = if outgoing { "following" } else { "followers" };
let symbol = if outgoing { "👥" } else { "📢" }; let symbol = if outgoing { "👥" } else { "📢" };
let params = use_params::<super::IdParam>(); let params = use_params::<IdParam>();
let auth = use_context::<Auth>().expect("missing auth context"); let auth = use_context::<Auth>().expect("missing auth context");
let resource = create_local_resource( let resource = create_local_resource(
move || params.get().ok().and_then(|x| x.id).unwrap_or_default(), move || params.get().ok().and_then(|x| x.id).unwrap_or_default(),

View file

@ -6,7 +6,7 @@ use apb::{field::OptionalString, ActivityMut, Actor, Base, Object, ObjectMut};
#[component] #[component]
pub fn ActorHeader() -> impl IntoView { pub fn ActorHeader() -> impl IntoView {
let params = use_params::<super::IdParam>(); let params = use_params::<IdParam>();
let auth = use_context::<Auth>().expect("missing auth context"); let auth = use_context::<Auth>().expect("missing auth context");
let actor = create_local_resource( let actor = create_local_resource(
move || params.get().ok().and_then(|x| x.id).unwrap_or_default(), move || params.get().ok().and_then(|x| x.id).unwrap_or_default(),

View file

@ -1,9 +1,3 @@
pub mod follow; pub mod follow;
pub mod posts; pub mod posts;
pub mod header; pub mod header;
use leptos_router::Params; // TODO can i remove this?
#[derive(Clone, leptos::Params, PartialEq)]
struct IdParam {
id: Option<String>,
}

View file

@ -5,7 +5,7 @@ use crate::prelude::*;
#[component] #[component]
pub fn ActorPosts() -> impl IntoView { pub fn ActorPosts() -> impl IntoView {
let feeds = use_context::<Feeds>().expect("missing feeds context"); let feeds = use_context::<Feeds>().expect("missing feeds context");
let params = use_params::<super::IdParam>(); let params = use_params::<IdParam>();
Signal::derive(move || { Signal::derive(move || {
let id = params.get_untracked().ok().and_then(|x| x.id).unwrap_or_default(); let id = params.get_untracked().ok().and_then(|x| x.id).unwrap_or_default();
let tl_url = format!("{}/outbox/page", Uri::api(U::Actor, &id, false)); let tl_url = format!("{}/outbox/page", Uri::api(U::Actor, &id, false));

View file

@ -14,6 +14,7 @@ pub struct Feeds {
pub user: Timeline, pub user: Timeline,
pub server: Timeline, pub server: Timeline,
pub context: Timeline, pub context: Timeline,
pub tag: Timeline,
} }
impl Feeds { impl Feeds {
@ -24,6 +25,7 @@ impl Feeds {
global: Timeline::new(format!("{URL_BASE}/inbox/page")), global: Timeline::new(format!("{URL_BASE}/inbox/page")),
user: Timeline::new(format!("{URL_BASE}/actors/{username}/outbox/page")), user: Timeline::new(format!("{URL_BASE}/actors/{username}/outbox/page")),
server: Timeline::new(format!("{URL_BASE}/outbox/page")), server: Timeline::new(format!("{URL_BASE}/outbox/page")),
tag: Timeline::new(format!("{URL_BASE}/tags/upub/page")),
context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
} }
} }
@ -35,6 +37,7 @@ impl Feeds {
self.user.reset(None); self.user.reset(None);
self.server.reset(None); self.server.reset(None);
self.context.reset(None); self.context.reset(None);
self.tag.reset(None);
} }
} }
@ -131,6 +134,8 @@ pub fn App() -> impl IntoView {
<Route path="followers" view=move || view! { <FollowList outgoing=false /> } /> <Route path="followers" view=move || view! { <FollowList outgoing=false /> } />
</Route> </Route>
<Route path="tags/:id" view=move || view! { <HashtagFeed tl=feeds.tag /> } />
<Route path="objects/:id" view=ObjectView /> <Route path="objects/:id" view=ObjectView />
// <Route path="/web/activities/:id" view=move || view! { <ActivityPage tl=context_tl /> } /> // <Route path="/web/activities/:id" view=move || view! { <ActivityPage tl=context_tl /> } />
@ -194,6 +199,7 @@ fn Scrollable() -> impl IntoView {
out out
}, },
}, },
Some("tags") => format!("tags :: {}", path_iter.next().unwrap_or_default()),
Some(p) => p.to_string(), Some(p) => p.to_string(),
None => "?".to_string(), None => "?".to_string(),
} }

View file

@ -157,6 +157,11 @@ impl DashmapCache<String> {
} }
} }
use leptos_router::Params; // TODO can i remove this?
#[derive(Clone, leptos::Params, PartialEq)]
pub struct IdParam {
id: Option<String>,
}
pub struct Http; pub struct Http;

View file

@ -1,6 +1,7 @@
pub use crate::{ pub use crate::{
URL_BASE, URL_BASE,
Http, Uri, Http, Uri,
IdParam,
Cache, cache, // TODO move Cache under cache Cache, cache, // TODO move Cache under cache
app::{Feeds, Loader}, app::{Feeds, Loader},
auth::Auth, auth::Auth,
@ -21,7 +22,7 @@ pub use crate::{
}, },
timeline::{ timeline::{
Timeline, Timeline,
feed::Feed, feed::{Feed, HashtagFeed},
thread::Thread, thread::Thread,
}, },
}; };

View file

@ -1,4 +1,5 @@
use leptos::*; use leptos::*;
use leptos_router::use_params;
use crate::prelude::*; use crate::prelude::*;
use super::Timeline; use super::Timeline;
@ -33,3 +34,24 @@ pub fn Feed(tl: Timeline) -> impl IntoView {
{move || if tl.loading.get() { Some(view! { <Loader /> }) } else { None }} {move || if tl.loading.get() { Some(view! { <Loader /> }) } else { None }}
} }
} }
#[component]
pub fn HashtagFeed(tl: Timeline) -> impl IntoView {
let params = use_params::<IdParam>();
Signal::derive(move || {
let current_tag = tl.next.get_untracked()
.split('/')
.last()
.unwrap_or_default()
.split('?')
.next()
.unwrap_or_default()
.to_string();
let new_tag = params.get().ok().and_then(|x| x.id).unwrap_or_default();
if new_tag != current_tag {
tl.reset(Some(Uri::api(U::Hashtag, &new_tag, false)));
}
}).track();
view! { <Feed tl=tl /> }
}