Compare commits
No commits in common. "48768b0e1a4f8a148523ac83ca39157fdc234987" and "baaaa55e9dfceee162f972b053156459bf36a259" have entirely different histories.
48768b0e1a
...
baaaa55e9d
11 changed files with 27 additions and 49 deletions
|
@ -119,7 +119,6 @@ pub async fn page<const OUTGOING: bool>(
|
||||||
crate::builders::collection_page(
|
crate::builders::collection_page(
|
||||||
&upub::url!(ctx, "/actors/{id}/{follow___}/page"),
|
&upub::url!(ctx, "/actors/{id}/{follow___}/page"),
|
||||||
offset, limit,
|
offset, limit,
|
||||||
following.into_iter().map(serde_json::Value::String).collect(),
|
following.into_iter().map(serde_json::Value::String).collect()
|
||||||
true
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,6 @@ pub async fn page(
|
||||||
.map(|x| x.ap())
|
.map(|x| x.ap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
crate::builders::collection_page(&upub::url!(ctx, "/actors/{id}/notifications/page"), offset, limit, activities, true)
|
crate::builders::collection_page(&upub::url!(ctx, "/actors/{id}/notifications/page"), offset, limit, activities)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,5 +51,5 @@ pub async fn page(
|
||||||
.map(|item| item.ap())
|
.map(|item| item.ap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
crate::builders::collection_page(&id, offset, limit, items, true)
|
crate::builders::collection_page(&id, offset, limit, items)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@ pub async fn page(
|
||||||
offset,
|
offset,
|
||||||
limit,
|
limit,
|
||||||
objects,
|
objects,
|
||||||
true,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,7 @@ pub async fn paginate_feed(
|
||||||
.add(filter);
|
.add(filter);
|
||||||
|
|
||||||
// by default we want replies because servers don't know about our api and want everything
|
// by default we want replies because servers don't know about our api and want everything
|
||||||
let replies = page.replies.unwrap_or(true);
|
if !page.replies.unwrap_or(true) {
|
||||||
|
|
||||||
if !replies {
|
|
||||||
conditions = conditions.add(upub::model::object::Column::InReplyTo.is_null());
|
conditions = conditions.add(upub::model::object::Column::InReplyTo.is_null());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,19 +52,18 @@ pub async fn paginate_feed(
|
||||||
.map(|item| item.ap())
|
.map(|item| item.ap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
collection_page(&id, offset, limit, items, replies)
|
collection_page(&id, offset, limit, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collection_page(id: &str, offset: u64, limit: u64, items: Vec<serde_json::Value>, replies: bool) -> crate::ApiResult<JsonLD<serde_json::Value>> {
|
pub fn collection_page(id: &str, offset: u64, limit: u64, items: Vec<serde_json::Value>) -> crate::ApiResult<JsonLD<serde_json::Value>> {
|
||||||
let replies = if replies { "" } else { "&replies=false" };
|
|
||||||
let next = if items.len() < limit as usize {
|
let next = if items.len() < limit as usize {
|
||||||
apb::Node::Empty
|
apb::Node::Empty
|
||||||
} else {
|
} else {
|
||||||
apb::Node::link(format!("{id}?offset={}{replies}", offset+limit))
|
apb::Node::link(format!("{id}?offset={}", offset+limit))
|
||||||
};
|
};
|
||||||
Ok(JsonLD(
|
Ok(JsonLD(
|
||||||
apb::new()
|
apb::new()
|
||||||
.set_id(Some(&format!("{id}?offset={offset}{replies}")))
|
.set_id(Some(&format!("{id}?offset={offset}")))
|
||||||
.set_collection_type(Some(apb::CollectionType::OrderedCollectionPage))
|
.set_collection_type(Some(apb::CollectionType::OrderedCollectionPage))
|
||||||
.set_part_of(apb::Node::link(id.replace("/page", "")))
|
.set_part_of(apb::Node::link(id.replace("/page", "")))
|
||||||
.set_ordered_items(apb::Node::array(items))
|
.set_ordered_items(apb::Node::array(items))
|
||||||
|
|
|
@ -193,7 +193,6 @@ fn Scrollable() -> impl IntoView {
|
||||||
let location = use_location();
|
let location = use_location();
|
||||||
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
||||||
let auth = use_context::<Auth>().expect("missing auth context");
|
let auth = use_context::<Auth>().expect("missing auth context");
|
||||||
let config = use_context::<Signal<crate::Config>>().expect("missing config context");
|
|
||||||
let relevant_timeline = Signal::derive(move || {
|
let relevant_timeline = Signal::derive(move || {
|
||||||
let path = location.pathname.get();
|
let path = location.pathname.get();
|
||||||
if path.contains("/web/home") {
|
if path.contains("/web/home") {
|
||||||
|
@ -247,7 +246,7 @@ fn Scrollable() -> impl IntoView {
|
||||||
<a class="breadcrumb mr-1" href="javascript:history.back()" ><b>"<<"</b></a>
|
<a class="breadcrumb mr-1" href="javascript:history.back()" ><b>"<<"</b></a>
|
||||||
<b>{crate::NAME}</b>" :: "{breadcrumb}
|
<b>{crate::NAME}</b>" :: "{breadcrumb}
|
||||||
{move || relevant_timeline.get().map(|tl| view! {
|
{move || relevant_timeline.get().map(|tl| view! {
|
||||||
<a class="breadcrumb ml-1" href="#" on:click=move|_| tl.refresh(auth, config) ><b>"↺"</b></a>
|
<a class="breadcrumb ml-1" href="#" on:click=move|_| tl.refresh(auth) ><b>"↺"</b></a>
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
|
|
@ -7,7 +7,6 @@ pub fn LoginBox(
|
||||||
userid_tx: WriteSignal<Option<String>>,
|
userid_tx: WriteSignal<Option<String>>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let auth = use_context::<Auth>().expect("missing auth context");
|
let auth = use_context::<Auth>().expect("missing auth context");
|
||||||
let config = use_context::<Signal<crate::Config>>().expect("missing config context");
|
|
||||||
let username_ref: NodeRef<html::Input> = create_node_ref();
|
let username_ref: NodeRef<html::Input> = create_node_ref();
|
||||||
let password_ref: NodeRef<html::Input> = create_node_ref();
|
let password_ref: NodeRef<html::Input> = create_node_ref();
|
||||||
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
||||||
|
@ -18,8 +17,8 @@ pub fn LoginBox(
|
||||||
<input style="float:right" type="submit" value="logout" on:click=move |_| {
|
<input style="float:right" type="submit" value="logout" on:click=move |_| {
|
||||||
token_tx.set(None);
|
token_tx.set(None);
|
||||||
feeds.reset();
|
feeds.reset();
|
||||||
feeds.global.spawn_more(auth, config);
|
feeds.global.spawn_more(auth);
|
||||||
feeds.server.spawn_more(auth, config);
|
feeds.server.spawn_more(auth);
|
||||||
} />
|
} />
|
||||||
</div>
|
</div>
|
||||||
<div class:hidden=move || auth.present() >
|
<div class:hidden=move || auth.present() >
|
||||||
|
@ -46,14 +45,14 @@ pub fn LoginBox(
|
||||||
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}/inbox/page")));
|
||||||
feeds.home.spawn_more(auth, config);
|
feeds.home.spawn_more(auth);
|
||||||
feeds.notifications.reset(Some(format!("{URL_BASE}/actors/{username}/notifications/page")));
|
feeds.notifications.reset(Some(format!("{URL_BASE}/actors/{username}/notifications/page")));
|
||||||
feeds.notifications.spawn_more(auth, config);
|
feeds.notifications.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}/inbox/page")));
|
||||||
feeds.global.spawn_more(auth, config);
|
feeds.global.spawn_more(auth);
|
||||||
feeds.server.reset(Some(format!("{URL_BASE}/outbox/page")));
|
feeds.server.reset(Some(format!("{URL_BASE}/outbox/page")));
|
||||||
feeds.server.spawn_more(auth, config);
|
feeds.server.spawn_more(auth);
|
||||||
});
|
});
|
||||||
} >
|
} >
|
||||||
<table class="w-100 align">
|
<table class="w-100 align">
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::{prelude::*, DEFAULT_COLOR};
|
||||||
pub fn ConfigPage(setter: WriteSignal<crate::Config>) -> impl IntoView {
|
pub fn ConfigPage(setter: WriteSignal<crate::Config>) -> impl IntoView {
|
||||||
let config = use_context::<Signal<crate::Config>>().expect("missing config context");
|
let config = use_context::<Signal<crate::Config>>().expect("missing config context");
|
||||||
let auth = use_context::<Auth>().expect("missing auth context");
|
let auth = use_context::<Auth>().expect("missing auth context");
|
||||||
let feeds = use_context::<Feeds>().expect("missing feeds context");
|
|
||||||
let (color, set_color) = leptos_use::use_css_var("--accent");
|
let (color, set_color) = leptos_use::use_css_var("--accent");
|
||||||
let (_color_rgb, set_color_rgb) = leptos_use::use_css_var("--accent-rgb");
|
let (_color_rgb, set_color_rgb) = leptos_use::use_css_var("--accent-rgb");
|
||||||
|
|
||||||
|
@ -98,12 +97,7 @@ pub fn ConfigPage(setter: WriteSignal<crate::Config>) -> impl IntoView {
|
||||||
<hr />
|
<hr />
|
||||||
<p><code title="unchecked elements won't show in timelines">filters</code></p>
|
<p><code title="unchecked elements won't show in timelines">filters</code></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><span title="replies to other posts"><input type="checkbox" prop:checked=get_cfg!(filter replies) on:input=move |ev| {
|
<li><span title="replies to other posts"><input type="checkbox" prop:checked=get_cfg!(filter replies) on:input=set_cfg!(filter replies) />" replies"</span></li>
|
||||||
let mut mock = config.get();
|
|
||||||
mock.filters.replies = event_target_checked(&ev);
|
|
||||||
setter.set(mock);
|
|
||||||
feeds.reset();
|
|
||||||
}/>" replies"</span></li>
|
|
||||||
<li><span title="like activities"><input type="checkbox" prop:checked=get_cfg!(filter likes) on:input=set_cfg!(filter likes) />" likes"</span></li>
|
<li><span title="like activities"><input type="checkbox" prop:checked=get_cfg!(filter likes) on:input=set_cfg!(filter likes) />" likes"</span></li>
|
||||||
<li><span title="create activities with object"><input type="checkbox" prop:checked=get_cfg!(filter creates) on:input=set_cfg!(filter creates)/>" creates"</span></li>
|
<li><span title="create activities with object"><input type="checkbox" prop:checked=get_cfg!(filter creates) on:input=set_cfg!(filter creates)/>" creates"</span></li>
|
||||||
<li><span title="update activities, to objects or actors"><input type="checkbox" prop:checked=get_cfg!(filter updates) on:input=set_cfg!(filter updates)/>" updates"</span></li>
|
<li><span title="update activities, to objects or actors"><input type="checkbox" prop:checked=get_cfg!(filter updates) on:input=set_cfg!(filter updates)/>" updates"</span></li>
|
||||||
|
|
|
@ -10,11 +10,10 @@ pub fn Feed(
|
||||||
ignore_filters: bool,
|
ignore_filters: bool,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let auth = use_context::<Auth>().expect("missing auth context");
|
let auth = use_context::<Auth>().expect("missing auth context");
|
||||||
let config = use_context::<Signal<crate::Config>>().expect("missing config context");
|
|
||||||
if let Some(auto_scroll) = use_context::<Signal<bool>>() {
|
if let Some(auto_scroll) = use_context::<Signal<bool>>() {
|
||||||
let _ = leptos::watch(
|
let _ = leptos::watch(
|
||||||
move || auto_scroll.get(),
|
move || auto_scroll.get(),
|
||||||
move |at_end, _, _| if *at_end { tl.spawn_more(auth, config) },
|
move |at_end, _, _| if *at_end { tl.spawn_more(auth) },
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl Timeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refresh(&self, auth: Auth, config: Signal<crate::Config>) {
|
pub fn refresh(&self, auth: Auth) {
|
||||||
self.reset(
|
self.reset(
|
||||||
self.next
|
self.next
|
||||||
.get_untracked()
|
.get_untracked()
|
||||||
|
@ -48,13 +48,13 @@ impl Timeline {
|
||||||
.next()
|
.next()
|
||||||
.map(|x| x.to_string())
|
.map(|x| x.to_string())
|
||||||
);
|
);
|
||||||
self.spawn_more(auth, config);
|
self.spawn_more(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_more(&self, auth: Auth, config: Signal<crate::Config>) {
|
pub fn spawn_more(&self, auth: Auth) {
|
||||||
let _self = *self;
|
let _self = *self;
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
_self.more(auth, config).await
|
_self.more(auth).await
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,28 +62,21 @@ impl Timeline {
|
||||||
self.loading.get_untracked()
|
self.loading.get_untracked()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn more(&self, auth: Auth, config: Signal<crate::Config>) {
|
pub async fn more(&self, auth: Auth) {
|
||||||
if self.loading.get_untracked() { return }
|
if self.loading.get_untracked() { return }
|
||||||
if self.over.get_untracked() { return }
|
if self.over.get_untracked() { return }
|
||||||
self.loading.set(true);
|
self.loading.set(true);
|
||||||
let res = self.load_more(auth, config).await;
|
let res = self.load_more(auth).await;
|
||||||
self.loading.set(false);
|
self.loading.set(false);
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
tracing::error!("failed loading posts for timeline: {e}");
|
tracing::error!("failed loading posts for timeline: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn load_more(&self, auth: Auth, config: Signal<crate::Config>) -> reqwest::Result<()> {
|
pub async fn load_more(&self, auth: Auth) -> reqwest::Result<()> {
|
||||||
use apb::{Collection, CollectionPage};
|
use apb::{Collection, CollectionPage};
|
||||||
|
|
||||||
let mut feed_url = self.next.get_untracked();
|
let feed_url = self.next.get_untracked();
|
||||||
if !config.get_untracked().filters.replies {
|
|
||||||
feed_url = if feed_url.contains('?') {
|
|
||||||
feed_url + "&replies=false"
|
|
||||||
} else {
|
|
||||||
feed_url + "?replies=false"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
let collection : serde_json::Value = Http::fetch(&feed_url, auth).await?;
|
let collection : serde_json::Value = Http::fetch(&feed_url, auth).await?;
|
||||||
let activities : Vec<serde_json::Value> = collection
|
let activities : Vec<serde_json::Value> = collection
|
||||||
.ordered_items()
|
.ordered_items()
|
||||||
|
|
|
@ -6,15 +6,14 @@ use super::Timeline;
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Thread(tl: Timeline, root: String) -> impl IntoView {
|
pub fn Thread(tl: Timeline, root: String) -> impl IntoView {
|
||||||
let auth = use_context::<Auth>().expect("missing auth context");
|
let auth = use_context::<Auth>().expect("missing auth context");
|
||||||
let config = use_context::<Signal<crate::Config>>().expect("missing config context");
|
|
||||||
if let Some(auto_scroll) = use_context::<Signal<bool>>() {
|
if let Some(auto_scroll) = use_context::<Signal<bool>>() {
|
||||||
let _ = leptos::watch(
|
let _ = leptos::watch(
|
||||||
move || auto_scroll.get(),
|
move || auto_scroll.get(),
|
||||||
move |new, old, _| {
|
move |new, old, _| {
|
||||||
match old {
|
match old {
|
||||||
None => tl.spawn_more(auth, config), // always do it first time
|
None => tl.spawn_more(auth), // always do it first time
|
||||||
Some(old) => if *new && new != old {
|
Some(old) => if *new && new != old {
|
||||||
tl.spawn_more(auth, config);
|
tl.spawn_more(auth);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue