feat(web): object replies and context tabs

This commit is contained in:
əlemi 2024-11-10 21:38:39 +01:00
parent bae7aab3df
commit 7d14bccdee
Signed by: alemi
GPG key ID: A4895B84D311642C
5 changed files with 31 additions and 8 deletions

View file

@ -10,6 +10,12 @@ use leptos_use::{
UseCookieOptions, UseElementSizeReturn UseCookieOptions, UseElementSizeReturn
}; };
// TODO this is getting out of hand
// when we will add lists there will have to potentially be multiple timelines (one per list)
// per user, which doesn't scale with this model. we should either take the "go back to where
// you were" into our own hands (maybe with timeline "segments"? would also solve slow load,
// but infinite-scroll upwards too may be hard to do) or understand how it works (with page
// stacks?) and keep timelines local to views.
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Feeds { pub struct Feeds {
pub home: Timeline, pub home: Timeline,
@ -19,6 +25,7 @@ pub struct Feeds {
pub user: Timeline, pub user: Timeline,
pub server: Timeline, pub server: Timeline,
pub context: Timeline, pub context: Timeline,
pub replies: Timeline,
pub tag: Timeline, pub tag: Timeline,
} }
@ -32,6 +39,7 @@ impl Feeds {
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")), 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
replies: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
} }
} }
@ -42,6 +50,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.replies.reset(None);
self.tag.reset(None); self.tag.reset(None);
} }
} }
@ -155,6 +164,7 @@ pub fn App() -> impl IntoView {
<Route path="global" view=move || view! { <Feed tl=feeds.global /> } /> <Route path="global" view=move || view! { <Feed tl=feeds.global /> } />
<Route path="local" view=move || view! { <Feed tl=feeds.server /> } /> <Route path="local" view=move || view! { <Feed tl=feeds.server /> } />
<Route path="notifications" view=move || view! { <Feed tl=feeds.notifications ignore_filters=true /> } /> <Route path="notifications" view=move || view! { <Feed tl=feeds.notifications ignore_filters=true /> } />
<Route path="tags/:id" view=move || view! { <HashtagFeed tl=feeds.tag /> } />
<Route path="about" view=AboutPage /> <Route path="about" view=AboutPage />
<Route path="config" view=move || view! { <ConfigPage setter=set_config /> } /> <Route path="config" view=move || view! { <ConfigPage setter=set_config /> } />
@ -166,9 +176,14 @@ 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="" view=ObjectContext />
<Route path="replies" view=ObjectReplies />
// <Route path="liked" view=ObjectLiked />
// <Route path="announced" view=ObjectAnnounced />
</Route>
// <Route path="/web/activities/:id" view=move || view! { <ActivityPage tl=context_tl /> } /> // <Route path="/web/activities/:id" view=move || view! { <ActivityPage tl=context_tl /> } />
<Route path="search" view=SearchPage /> <Route path="search" view=SearchPage />

View file

@ -109,6 +109,8 @@ pub fn PostBox(advanced: WriteSignal<bool>) -> impl IntoView {
on:input=move |ev| set_content.set(event_target_value(&ev)) on:input=move |ev| set_content.set(event_target_value(&ev))
></textarea> ></textarea>
<table class="align rev w-100"> <table class="align rev w-100">
<tr> <tr>
<td><input id="priv-public" type="radio" name="privacy" value="public" title="public" node_ref=public_ref /></td> <td><input id="priv-public" type="radio" name="privacy" value="public" title="public" node_ref=public_ref /></td>

View file

@ -1,4 +1,6 @@
pub mod view; pub mod view;
pub mod item; pub mod context;
pub mod replies;
pub mod item;
pub mod attachment; pub mod attachment;

View file

@ -2,7 +2,7 @@ use leptos::*;
use leptos_router::*; use leptos_router::*;
use crate::prelude::*; use crate::prelude::*;
use apb::{Object}; use apb::{Base, Object};
#[component] #[component]
pub fn ObjectView() -> impl IntoView { pub fn ObjectView() -> impl IntoView {
@ -13,7 +13,7 @@ pub fn ObjectView() -> impl IntoView {
move |oid| async move { move |oid| async move {
let obj = cache::OBJECTS.resolve(&oid, U::Object, auth).await?; let obj = cache::OBJECTS.resolve(&oid, U::Object, auth).await?;
if let Ok(author) = obj.attributed_to().id() { if let Ok(author) = obj.attributed_to().id() {
cache::OBJECTS.resolve(&author, U::Actor, auth).await; cache::OBJECTS.resolve(author, U::Actor, auth).await;
} }
Some(obj) Some(obj)
@ -35,12 +35,14 @@ pub fn ObjectView() -> impl IntoView {
}, },
Some(Some(o)) => { Some(Some(o)) => {
let object = o.clone(); let object = o.clone();
let base = Uri::web(U::Object, o.id().unwrap_or_default());
view!{ view!{
<Object object=object /> <Object object=object />
<hr class="color ma-2" /> <hr class="color ma-2" />
<div class="mr-1-r ml-1-r"> <code class="cw color center mt-1 mb-1 ml-3 mr-3">
<Thread tl=feeds.context root=o.id().unwrap_or_default().to_string() /> <a href=format!("{base}/context")><b>context</b></a> | <a href=format!("{base}/replies")><b>replies</b></a>
</div> </code>
<Outlet />
}.into_view() }.into_view()
}, },
}} }}

View file

@ -19,6 +19,8 @@ pub use crate::{
view::ObjectView, view::ObjectView,
attachment::Attachment, attachment::Attachment,
item::{Object, Summary, LikeButton, RepostButton, ReplyButton}, item::{Object, Summary, LikeButton, RepostButton, ReplyButton},
context::ObjectContext,
replies::ObjectReplies,
}, },
timeline::{ timeline::{
Timeline, Timeline,