forked from alemi/upub
fix(web): only load tl after refresh
also improved tl.more()
This commit is contained in:
parent
eb3c647691
commit
6397647511
6 changed files with 50 additions and 96 deletions
|
@ -12,29 +12,6 @@ pub fn App() -> impl IntoView {
|
|||
let (userid, set_userid) = use_cookie::<String, FromToStringCodec>("user_id");
|
||||
let (config, set_config, _) = use_local_storage::<crate::Config, JsonCodec>("config");
|
||||
|
||||
if let Some(tok) = token.get_untracked() {
|
||||
spawn_local(async move {
|
||||
match reqwest::Client::new()
|
||||
.request(Method::PATCH, format!("{URL_BASE}/auth"))
|
||||
.json(&serde_json::json!({"token": tok}))
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Err(e) => tracing::error!("could not refresh token: {e}"),
|
||||
Ok(res) => match res.error_for_status() {
|
||||
Err(e) => tracing::error!("server rejected refresh: {e}"),
|
||||
Ok(doc) => match doc.json::<AuthResponse>().await {
|
||||
Err(e) => tracing::error!("failed parsing auth response: {e}"),
|
||||
Ok(auth) => {
|
||||
set_token.set(Some(auth.token));
|
||||
set_userid.set(Some(auth.user));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let auth = Auth { token, userid };
|
||||
provide_context(auth);
|
||||
provide_context(config);
|
||||
|
@ -55,26 +32,39 @@ pub fn App() -> impl IntoView {
|
|||
let (menu, set_menu) = create_signal(screen_width <= 786);
|
||||
let (advanced, set_advanced) = create_signal(false);
|
||||
|
||||
spawn_local(async move {
|
||||
if let Err(e) = server_tl.more(auth).await {
|
||||
tracing::error!("error populating timeline: {e}");
|
||||
}
|
||||
});
|
||||
|
||||
let auth_present = auth.token.get_untracked().is_some(); // skip helper to use get_untracked
|
||||
if auth_present {
|
||||
let title_target = move || if auth_present { "/web/home" } else { "/web/server" };
|
||||
|
||||
if let Some(tok) = token.get_untracked() {
|
||||
spawn_local(async move {
|
||||
if let Err(e) = home_tl.more(auth).await {
|
||||
tracing::error!("error populating timeline: {e}");
|
||||
// refresh token first, or verify that we're still authed
|
||||
match reqwest::Client::new()
|
||||
.request(Method::PATCH, format!("{URL_BASE}/auth"))
|
||||
.json(&serde_json::json!({"token": tok}))
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Err(e) => tracing::error!("could not refresh token: {e}"),
|
||||
Ok(res) => match res.error_for_status() {
|
||||
Err(e) => tracing::error!("server rejected refresh: {e}"),
|
||||
Ok(doc) => match doc.json::<AuthResponse>().await {
|
||||
Err(e) => tracing::error!("failed parsing auth response: {e}"),
|
||||
Ok(auth) => {
|
||||
set_token.set(Some(auth.token));
|
||||
set_userid.set(Some(auth.user));
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let title_target = if auth_present { "/web/home" } else { "/web/server" };
|
||||
server_tl.more(auth);
|
||||
if auth_present { home_tl.more(auth) };
|
||||
})
|
||||
};
|
||||
|
||||
view! {
|
||||
<nav class="w-100 mt-1 mb-1 pb-s">
|
||||
<code class="color ml-3" ><a class="upub-title" href={title_target} >μpub</a></code>
|
||||
<code class="color ml-3" ><a class="upub-title" href=title_target >μpub</a></code>
|
||||
<small class="ml-1 mr-1 hidden-on-tiny" ><a class="clean" href="/web/server" >micro social network, federated</a></small>
|
||||
/* TODO kinda jank with the float but whatever, will do for now */
|
||||
<input type="submit" class="mr-2 rev" on:click=move |_| set_menu.set(!menu.get()) value="menu" style="float: right" />
|
||||
|
|
|
@ -19,11 +19,7 @@ pub fn LoginBox(
|
|||
token_tx.set(None);
|
||||
home_tl.reset(format!("{URL_BASE}/outbox/page"));
|
||||
server_tl.reset(format!("{URL_BASE}/inbox/page"));
|
||||
spawn_local(async move {
|
||||
if let Err(e) = server_tl.more(auth).await {
|
||||
logging::error!("failed refreshing server timeline: {e}");
|
||||
}
|
||||
});
|
||||
server_tl.more(auth);
|
||||
} />
|
||||
</div>
|
||||
<div class:hidden=move || auth.present() >
|
||||
|
@ -50,18 +46,10 @@ pub fn LoginBox(
|
|||
token_tx.set(Some(auth_response.token));
|
||||
// reset home feed and point it to our user's inbox
|
||||
home_tl.reset(format!("{URL_BASE}/users/{}/inbox/page", username));
|
||||
spawn_local(async move {
|
||||
if let Err(e) = home_tl.more(auth).await {
|
||||
tracing::error!("failed refreshing home timeline: {e}");
|
||||
}
|
||||
});
|
||||
home_tl.more(auth);
|
||||
// reset server feed: there may be more content now that we're authed
|
||||
server_tl.reset(format!("{URL_BASE}/inbox/page"));
|
||||
spawn_local(async move {
|
||||
if let Err(e) = server_tl.more(auth).await {
|
||||
tracing::error!("failed refreshing server timeline: {e}");
|
||||
}
|
||||
});
|
||||
server_tl.more(auth);
|
||||
});
|
||||
} >
|
||||
<table class="w-100 align">
|
||||
|
|
|
@ -36,14 +36,20 @@ impl Timeline {
|
|||
self.over.set(false);
|
||||
}
|
||||
|
||||
pub async fn more(&self, auth: Auth) -> reqwest::Result<()> {
|
||||
self.loading.set(true);
|
||||
let res = self.more_inner(auth).await;
|
||||
self.loading.set(false);
|
||||
res
|
||||
pub fn more(&self, auth: Auth) {
|
||||
if self.loading.get() { return }
|
||||
let _self = *self;
|
||||
spawn_local(async move {
|
||||
_self.loading.set(true);
|
||||
let res = _self.load_more(auth).await;
|
||||
_self.loading.set(false);
|
||||
if let Err(e) = res {
|
||||
tracing::error!("failed loading posts for timeline: {e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn more_inner(&self, auth: Auth) -> reqwest::Result<()> {
|
||||
pub async fn load_more(&self, auth: Auth) -> reqwest::Result<()> {
|
||||
use apb::{Collection, CollectionPage};
|
||||
|
||||
let feed_url = self.next.get_untracked();
|
||||
|
@ -119,13 +125,7 @@ pub fn TimelineReplies(tl: Timeline, root: String) -> impl IntoView {
|
|||
<div class="center mt-1 mb-1" class:hidden=tl.over >
|
||||
<button type="button"
|
||||
prop:disabled=tl.loading
|
||||
on:click=move |_| {
|
||||
spawn_local(async move {
|
||||
if let Err(e) = tl.more(auth).await {
|
||||
tracing::error!("error fetching more items for timeline: {e}");
|
||||
}
|
||||
})
|
||||
}
|
||||
on:click=move |_| tl.more(auth)
|
||||
>
|
||||
{move || if tl.loading.get() {
|
||||
view! { "loading"<span class="dots"></span> }.into_view()
|
||||
|
@ -152,9 +152,7 @@ pub fn TimelineFeed(tl: Timeline) -> impl IntoView {
|
|||
move |(s, h)| async move {
|
||||
if !config.get().infinite_scroll { return }
|
||||
if s > 0.0 && h - s < view_height && !tl.loading.get() {
|
||||
if let Err(e) = tl.more(auth).await {
|
||||
tracing::error!("auto load failed: {e}");
|
||||
}
|
||||
tl.more(auth);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -179,7 +177,7 @@ pub fn TimelineFeed(tl: Timeline) -> impl IntoView {
|
|||
<div class="center mt-1 mb-1" class:hidden=tl.over >
|
||||
<button type="button"
|
||||
prop:disabled=tl.loading
|
||||
on:click=move |_| load_more(tl, auth)
|
||||
on:click=move |_| tl.more(auth)
|
||||
>
|
||||
{move || if tl.loading.get() {
|
||||
view! { "loading"<span class="dots"></span> }.into_view()
|
||||
|
@ -189,16 +187,6 @@ pub fn TimelineFeed(tl: Timeline) -> impl IntoView {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_more(tl: Timeline, auth: Auth) {
|
||||
if !tl.loading.get() {
|
||||
spawn_local(async move {
|
||||
if let Err(e) = tl.more(auth).await {
|
||||
tracing::error!("error fetching more items for timeline: {e}");
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth) -> Vec<String> {
|
||||
let mut sub_tasks : Vec<Pin<Box<dyn futures::Future<Output = ()>>>> = Vec::new();
|
||||
let mut gonna_fetch = BTreeSet::new();
|
||||
|
|
|
@ -41,11 +41,7 @@ pub fn ObjectPage(tl: Timeline) -> impl IntoView {
|
|||
class:hidden=move || tl.is_empty()
|
||||
on:click=move |_| {
|
||||
tl.reset(tl.next.get().split('?').next().unwrap_or_default().to_string());
|
||||
spawn_local(async move {
|
||||
if let Err(e) = tl.more(auth).await {
|
||||
tracing::error!("error fetching more items for timeline: {e}");
|
||||
}
|
||||
})
|
||||
tl.more(auth);
|
||||
}><span class="emoji">
|
||||
"\u{1f5d8}"
|
||||
</span></a>
|
||||
|
|
|
@ -10,11 +10,7 @@ pub fn TimelinePage(name: &'static str, tl: Timeline) -> impl IntoView {
|
|||
{name}
|
||||
<a class="clean ml-1" href="#" on:click=move |_| {
|
||||
tl.reset(tl.next.get().split('?').next().unwrap_or_default().to_string());
|
||||
spawn_local(async move {
|
||||
if let Err(e) = tl.more(auth).await {
|
||||
tracing::error!("error fetching more items for timeline: {e}");
|
||||
}
|
||||
})
|
||||
tl.more(auth);
|
||||
}><span class="emoji">
|
||||
"\u{1f5d8}"
|
||||
</span></a>
|
||||
|
|
|
@ -51,11 +51,7 @@ pub fn UserPage(tl: Timeline) -> impl IntoView {
|
|||
class:hidden=move || tl.is_empty()
|
||||
on:click=move |_| {
|
||||
tl.reset(tl.next.get().split('?').next().unwrap_or_default().to_string());
|
||||
spawn_local(async move {
|
||||
if let Err(e) = tl.more(auth).await {
|
||||
tracing::error!("error fetching more items for timeline: {e}");
|
||||
}
|
||||
})
|
||||
tl.more(auth);
|
||||
}><span class="emoji">
|
||||
"\u{1f5d8}"
|
||||
</span></a>
|
||||
|
|
Loading…
Reference in a new issue