feat(web): show unread notifications count

This commit is contained in:
əlemi 2024-08-15 04:48:39 +02:00
parent 97d3056133
commit 45392081c7
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 22 additions and 6 deletions

View file

@ -1,3 +1,4 @@
use apb::Collection;
use leptos::*; use leptos::*;
use leptos_router::*; use leptos_router::*;
use crate::prelude::*; use crate::prelude::*;
@ -84,9 +85,24 @@ pub fn App() -> impl IntoView {
let title_target = move || if auth.present() { "/web/home" } else { "/web/global" }; let title_target = move || if auth.present() { "/web/home" } else { "/web/global" };
// refresh token immediately and every hour // refresh token immediately and every hour
let refresh = move || spawn_local(async move { Auth::refresh(auth.token, set_token, set_userid).await; }); let refresh_token = move || spawn_local(async move { Auth::refresh(auth.token, set_token, set_userid).await; });
refresh(); refresh_token();
set_interval(refresh, std::time::Duration::from_secs(3600)); set_interval(refresh_token, std::time::Duration::from_secs(3600));
// refresh notifications
let (notifications, set_notifications) = create_signal(0);
let fetch_notifications = move || spawn_local(async move {
let actor_id = userid.get().unwrap_or_default();
let notif_url = format!("/actors/{actor_id}/notifications");
match Http::fetch::<serde_json::Value>(&notif_url, auth).await {
Err(e) => tracing::error!("failed fetching notifications: {e}"),
Ok(doc) => if let Ok(count) = doc.total_items() {
set_notifications.set(count);
},
}
});
fetch_notifications();
set_interval(fetch_notifications, std::time::Duration::from_secs(60));
view! { view! {
<nav class="w-100 mt-1 mb-1 pb-s"> <nav class="w-100 mt-1 mb-1 pb-s">
@ -99,7 +115,7 @@ pub fn App() -> impl IntoView {
<div class="container mt-2 pt-2" > <div class="container mt-2 pt-2" >
<div class="two-col" > <div class="two-col" >
<div class="col-side sticky pb-s" class:hidden=menu > <div class="col-side sticky pb-s" class:hidden=menu >
<Navigator /> <Navigator notifications=notifications />
<hr class="mt-1 mb-1" /> <hr class="mt-1 mb-1" />
<LoginBox <LoginBox
token_tx=set_token token_tx=set_token

View file

@ -18,7 +18,7 @@ pub fn Breadcrumb(
} }
#[component] #[component]
pub fn Navigator() -> impl IntoView { pub fn Navigator(notifications: ReadSignal<u64>) -> impl IntoView {
let auth = use_context::<Auth>().expect("missing auth context"); let auth = use_context::<Auth>().expect("missing auth context");
let (query, set_query) = create_signal("".to_string()); let (query, set_query) = create_signal("".to_string());
view! { view! {
@ -40,7 +40,7 @@ pub fn Navigator() -> impl IntoView {
<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/global"><input class="w-100" type="submit" value="global 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/notifications"><input class="w-100" type="submit" class:hidden=move || !auth.present() value=move || format!("notifications [{}]", notifications.get()) /></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>