Compare commits
No commits in common. "8b5e6d805d8af86cdd4d4f755fd19b5ee0aa47af" and "37a812f3c6c33eb9adf285331cb829611a787437" have entirely different histories.
8b5e6d805d
...
37a812f3c6
9 changed files with 72 additions and 41 deletions
|
@ -80,9 +80,6 @@
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
border-left: solid 3px var(--background-secondary);
|
border-left: solid 3px var(--background-secondary);
|
||||||
}
|
}
|
||||||
article {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
article.tl {
|
article.tl {
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
border-left: solid 3px var(--accent);
|
border-left: solid 3px var(--accent);
|
||||||
|
@ -90,6 +87,7 @@
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
article p {
|
article p {
|
||||||
margin: 0 0 0 .5em;
|
margin: 0 0 0 .5em;
|
||||||
|
|
25
web/src/actors/activity.rs
Normal file
25
web/src/actors/activity.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_router::*;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn ActorActivity() -> impl IntoView {
|
||||||
|
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
||||||
|
let params = use_params::<super::IdParam>();
|
||||||
|
let id = Signal::derive(move || {
|
||||||
|
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));
|
||||||
|
if !feeds.user.next.get_untracked().starts_with(&tl_url) {
|
||||||
|
feeds.user.reset(Some(tl_url));
|
||||||
|
}
|
||||||
|
id
|
||||||
|
});
|
||||||
|
view! {
|
||||||
|
<code class="cw color center mt-1 mb-1 ml-3 mr-3">
|
||||||
|
<a class="clean" href={format!("/web/actors/{}", id.get())}><span class="emoji">"🖂"</span>" posts"</a>
|
||||||
|
" | "
|
||||||
|
<b>activity</b>" "<span class="emoji">"@"</span>
|
||||||
|
</code>
|
||||||
|
<Feed tl=feeds.user />
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod follow;
|
pub mod follow;
|
||||||
pub mod posts;
|
pub mod posts;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
|
pub mod activity;
|
||||||
|
|
||||||
use leptos_router::Params; // TODO can i remove this?
|
use leptos_router::Params; // TODO can i remove this?
|
||||||
#[derive(Clone, leptos::Params, PartialEq)]
|
#[derive(Clone, leptos::Params, PartialEq)]
|
||||||
|
|
|
@ -6,17 +6,19 @@ use crate::prelude::*;
|
||||||
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::<super::IdParam>();
|
||||||
Signal::derive(move || {
|
let id = 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!("{}/streams/page", Uri::api(U::Actor, &id, false));
|
||||||
if !feeds.user.next.get_untracked().starts_with(&tl_url) {
|
if !feeds.user.next.get_untracked().starts_with(&tl_url) {
|
||||||
feeds.user.reset(Some(tl_url));
|
feeds.user.reset(Some(tl_url));
|
||||||
}
|
}
|
||||||
id
|
id
|
||||||
}).track();
|
});
|
||||||
view! {
|
view! {
|
||||||
<code class="cw color center mt-1 mb-1 ml-3 mr-3">
|
<code class="cw color center mt-1 mb-1 ml-3 mr-3">
|
||||||
<span class="emoji">"🖂"</span>" "<b>posts</b>
|
<span class="emoji">"🖂"</span>" "<b>posts</b>
|
||||||
|
" | "
|
||||||
|
<a class="clean" href={format!("/web/actors/{}/activity", id.get())}>"activity "<span class="emoji">"@"</span></a>
|
||||||
</code>
|
</code>
|
||||||
<Feed tl=feeds.user />
|
<Feed tl=feeds.user />
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,12 @@ use leptos_use::{signal_debounced, storage::use_local_storage, use_cookie, use_e
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Feeds {
|
pub struct Feeds {
|
||||||
|
// object feeds
|
||||||
pub home: Timeline,
|
pub home: Timeline,
|
||||||
pub global: Timeline,
|
pub global: Timeline,
|
||||||
pub notifications: Timeline,
|
// notification feeds
|
||||||
|
pub private: Timeline,
|
||||||
|
pub public: Timeline,
|
||||||
// exploration feeds
|
// exploration feeds
|
||||||
pub user: Timeline,
|
pub user: Timeline,
|
||||||
pub server: Timeline,
|
pub server: Timeline,
|
||||||
|
@ -19,9 +22,10 @@ pub struct Feeds {
|
||||||
impl Feeds {
|
impl Feeds {
|
||||||
pub fn new(username: &str) -> Self {
|
pub fn new(username: &str) -> Self {
|
||||||
Feeds {
|
Feeds {
|
||||||
home: Timeline::new(format!("{URL_BASE}/actors/{username}/inbox/page")),
|
home: Timeline::new(format!("{URL_BASE}/actors/{username}/feed/page")),
|
||||||
notifications: Timeline::new(format!("{URL_BASE}/actors/{username}/notifications/page")),
|
global: Timeline::new(format!("{URL_BASE}/feed/page")),
|
||||||
global: Timeline::new(format!("{URL_BASE}/inbox/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")),
|
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")),
|
||||||
context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
|
context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
|
||||||
|
@ -30,8 +34,9 @@ impl Feeds {
|
||||||
|
|
||||||
pub fn reset(&self) {
|
pub fn reset(&self) {
|
||||||
self.home.reset(None);
|
self.home.reset(None);
|
||||||
self.notifications.reset(None);
|
|
||||||
self.global.reset(None);
|
self.global.reset(None);
|
||||||
|
self.private.reset(None);
|
||||||
|
self.public.reset(None);
|
||||||
self.user.reset(None);
|
self.user.reset(None);
|
||||||
self.server.reset(None);
|
self.server.reset(None);
|
||||||
self.context.reset(None);
|
self.context.reset(None);
|
||||||
|
@ -117,9 +122,9 @@ pub fn App() -> impl IntoView {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route path="home" view=move || view! { <Feed tl=feeds.home /> } />
|
<Route path="home" view=move || view! { <Feed tl=feeds.home /> } />
|
||||||
<Route path="global" view=move || view! { <Feed tl=feeds.global /> } />
|
<Route path="server" 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 /> } />
|
<Route path="inbox" view=move || view! { <Feed tl=feeds.private /> } />
|
||||||
|
|
||||||
<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 /> } />
|
||||||
|
@ -129,6 +134,7 @@ pub fn App() -> impl IntoView {
|
||||||
<Route path="" view=ActorPosts />
|
<Route path="" view=ActorPosts />
|
||||||
<Route path="following" view=move || view! { <FollowList outgoing=true /> } />
|
<Route path="following" view=move || view! { <FollowList outgoing=true /> } />
|
||||||
<Route path="followers" view=move || view! { <FollowList outgoing=false /> } />
|
<Route path="followers" view=move || view! { <FollowList outgoing=false /> } />
|
||||||
|
<Route path="activity" view=ActorActivity />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="objects/:id" view=ObjectView />
|
<Route path="objects/:id" view=ObjectView />
|
||||||
|
@ -159,12 +165,12 @@ fn Scrollable() -> impl IntoView {
|
||||||
let path = location.pathname.get();
|
let path = location.pathname.get();
|
||||||
if path.contains("/web/home") {
|
if path.contains("/web/home") {
|
||||||
Some(feeds.home)
|
Some(feeds.home)
|
||||||
} else if path.contains("/web/global") {
|
} else if path.contains("/web/server") {
|
||||||
Some(feeds.global)
|
Some(feeds.global)
|
||||||
} else if path.contains("/web/local") {
|
} else if path.starts_with("/web/local") {
|
||||||
Some(feeds.server)
|
Some(feeds.server)
|
||||||
} else if path.starts_with("/web/notifications") {
|
} else if path.starts_with("/web/inbox") {
|
||||||
Some(feeds.notifications)
|
Some(feeds.private)
|
||||||
} else if path.starts_with("/web/actors") {
|
} else if path.starts_with("/web/actors") {
|
||||||
Some(feeds.user)
|
Some(feeds.user)
|
||||||
} else if path.starts_with("/web/objects") {
|
} else if path.starts_with("/web/objects") {
|
||||||
|
|
|
@ -19,12 +19,11 @@ pub fn ActivityLine(activity: crate::Object) -> impl IntoView {
|
||||||
_ => Uri::web(U::Object, &object_id),
|
_ => Uri::web(U::Object, &object_id),
|
||||||
};
|
};
|
||||||
view! {
|
view! {
|
||||||
<table class="align w-100">
|
<div>
|
||||||
<tr>
|
<span class="ml-1-l">
|
||||||
<td class="ml-1-r">
|
|
||||||
<ActorStrip object=actor />
|
<ActorStrip object=actor />
|
||||||
</td>
|
</span>
|
||||||
<td class="rev">
|
<span style="float:right">
|
||||||
<code class="color moreinfo" title={activity.published().ok().map(|x| x.to_rfc2822())} >
|
<code class="color moreinfo" title={activity.published().ok().map(|x| x.to_rfc2822())} >
|
||||||
<a class="upub-title clean" title={object_id} href={href} >
|
<a class="upub-title clean" title={object_id} href={href} >
|
||||||
{kind.as_ref().to_string()}
|
{kind.as_ref().to_string()}
|
||||||
|
@ -32,9 +31,8 @@ pub fn ActivityLine(activity: crate::Object) -> impl IntoView {
|
||||||
{activity_url}
|
{activity_url}
|
||||||
<PrivacyMarker addressed=activity.addressed() />
|
<PrivacyMarker addressed=activity.addressed() />
|
||||||
</code>
|
</code>
|
||||||
</td>
|
</span>
|
||||||
</tr>
|
</div>
|
||||||
</table>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn LoginBox(
|
||||||
token_tx.set(None);
|
token_tx.set(None);
|
||||||
feeds.reset();
|
feeds.reset();
|
||||||
feeds.global.spawn_more(auth);
|
feeds.global.spawn_more(auth);
|
||||||
feeds.server.spawn_more(auth);
|
feeds.public.spawn_more(auth);
|
||||||
} />
|
} />
|
||||||
</div>
|
</div>
|
||||||
<div class:hidden=move || auth.present() >
|
<div class:hidden=move || auth.present() >
|
||||||
|
@ -44,14 +44,14 @@ pub fn LoginBox(
|
||||||
userid_tx.set(Some(auth_response.user));
|
userid_tx.set(Some(auth_response.user));
|
||||||
token_tx.set(Some(auth_response.token));
|
token_tx.set(Some(auth_response.token));
|
||||||
// reset home feed and point it to our user's inbox
|
// reset home feed and point it to our user's inbox
|
||||||
feeds.home.reset(Some(format!("{URL_BASE}/actors/{username}/inbox/page")));
|
feeds.home.reset(Some(format!("{URL_BASE}/actors/{username}/feed/page")));
|
||||||
feeds.home.spawn_more(auth);
|
feeds.home.spawn_more(auth);
|
||||||
feeds.notifications.reset(Some(format!("{URL_BASE}/actors/{username}/notifications/page")));
|
feeds.private.reset(Some(format!("{URL_BASE}/actors/{username}/inbox/page")));
|
||||||
feeds.notifications.spawn_more(auth);
|
feeds.private.spawn_more(auth);
|
||||||
// reset server feed: there may be more content now that we're authed
|
// reset server feed: there may be more content now that we're authed
|
||||||
feeds.global.reset(Some(format!("{URL_BASE}/inbox/page")));
|
feeds.global.reset(Some(format!("{URL_BASE}/feed/page")));
|
||||||
feeds.global.spawn_more(auth);
|
feeds.global.spawn_more(auth);
|
||||||
feeds.server.reset(Some(format!("{URL_BASE}/outbox/page")));
|
feeds.server.reset(Some(format!("{URL_BASE}/inbox/page")));
|
||||||
feeds.server.spawn_more(auth);
|
feeds.server.spawn_more(auth);
|
||||||
});
|
});
|
||||||
} >
|
} >
|
||||||
|
|
|
@ -38,9 +38,9 @@ pub fn Navigator() -> impl IntoView {
|
||||||
</form>
|
</form>
|
||||||
<table class="align w-100">
|
<table class="align w-100">
|
||||||
<tr><td colspan="2"><a href="/web/home"><input class="w-100" type="submit" class:hidden=move || !auth.present() value="home timeline" /></a></td></tr>
|
<tr><td colspan="2"><a href="/web/home"><input class="w-100" type="submit" class:hidden=move || !auth.present() value="home timeline" /></a></td></tr>
|
||||||
<tr><td colspan="2"><a href="/web/global"><input class="w-100" type="submit" value="global timeline" /></a></td></tr>
|
<tr><td colspan="2"><a href="/web/server"><input class="w-100" type="submit" value="server timeline" /></a></td></tr>
|
||||||
<tr><td colspan="2"><a href="/web/local"><input class="w-100" type="submit" value="local timeline" /></a></td></tr>
|
<tr><td colspan="2"><a href="/web/local"><input class="w-100" type="submit" value="local timeline" /></a></td></tr>
|
||||||
<tr><td colspan="2"><a href="/web/notifications"><input class="w-100" type="submit" class:hidden=move || !auth.present() value="notifications" /></a></td></tr>
|
<tr><td colspan="2"><a href="/web/inbox"><input class="w-100" type="submit" class:hidden=move || !auth.present() value="notifications" /></a></td></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="w-50"><a href="/web/about"><input class="w-100" type="submit" value="about" /></a></td>
|
<td class="w-50"><a href="/web/about"><input class="w-100" type="submit" value="about" /></a></td>
|
||||||
<td class="w-50"><a href="/web/config"><input class="w-100" type="submit" value="config" /></a></td>
|
<td class="w-50"><a href="/web/config"><input class="w-100" type="submit" value="config" /></a></td>
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub use crate::{
|
||||||
header::ActorHeader,
|
header::ActorHeader,
|
||||||
follow::FollowList,
|
follow::FollowList,
|
||||||
posts::ActorPosts,
|
posts::ActorPosts,
|
||||||
|
activity::ActorActivity,
|
||||||
},
|
},
|
||||||
timeline::{
|
timeline::{
|
||||||
Timeline,
|
Timeline,
|
||||||
|
|
Loading…
Reference in a new issue