summaryrefslogtreecommitdiffstats
path: root/src/lib.rs
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-05-23 16:00:54 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-05-23 16:00:54 +0100
commiteff7045e9f871c0ec6eb0401c77ab4209b36d636 (patch)
treebb5d9007f37ec0e76cdc511c937062f7249a3215 /src/lib.rs
parentf14ac34129b05b7424fb0c002920c6bf40ad45ab (diff)
downloadmacaw-web-eff7045e9f871c0ec6eb0401c77ab4209b36d636.tar.gz
macaw-web-eff7045e9f871c0ec6eb0401c77ab4209b36d636.tar.bz2
macaw-web-eff7045e9f871c0ec6eb0401c77ab4209b36d636.zip
feat: subscription request badges
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 90cae4e..570d2f6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -649,6 +649,7 @@ fn Macaw(
// TODO: timestamp incoming/outgoing subscription requests
let (subscription_requests, set_subscription_requests)= signal(HashSet::<JID>::new());
provide_context(subscription_requests);
+ provide_context(set_subscription_requests);
// TODO: get cached contacts on login before getting the updated contacts
@@ -769,6 +770,8 @@ pub fn toggle_open(state: &mut Option<SidebarOpen>, open: SidebarOpen) -> bool {
#[component]
pub fn Sidebar() -> impl IntoView {
+ let requests: ReadSignal<HashSet<JID>> = use_context().expect("no pending subscriptions in context");
+
// for what has been clicked open (in the background)
let (open, set_open) = signal(None::<SidebarOpen>);
// for what is just in the hovered state (not clicked to be pinned open yet necessarily)
@@ -795,7 +798,21 @@ pub fn Sidebar() -> impl IntoView {
})
}>
<div class="dock-pill"></div>
- <img src="/assets/caw.png" />
+ <div class="dock-icon">
+ <div class="icon-with-badge">
+ <img src="/assets/caw.png" />
+ {move || {
+ let len = requests.read().len();
+ if len > 0 {
+ view! {
+ <div class="badge">{len}</div>
+ }.into_any()
+ } else {
+ view! {}.into_any()
+ }
+ }}
+ </div>
+ </div>
</div>
<div class="chats-tab dock-item" class:focused=move || *open.read() == Some(SidebarOpen::Chats) class:hovering=move || *hovered.read() == Some(SidebarOpen::Chats)
on:mouseenter=move |_| {
@@ -2166,6 +2183,8 @@ fn NewChatWidget(set_open_new_chat: WriteSignal<bool>) -> impl IntoView {
#[component]
fn RosterList() -> impl IntoView {
+ let requests: ReadSignal<HashSet<JID>> = use_context().expect("no pending subscriptions in context");
+
let roster: Store<Roster> = use_context().expect("no roster in context");
let (open_add_contact, set_open_add_contact) = signal(false);
@@ -2176,6 +2195,15 @@ fn RosterList() -> impl IntoView {
<h2>Roster</h2>
<div class="add-contact header-icon" class:open=open_add_contact>
<IconComponent icon=Icon::AddContact24 on:click=move |_| set_open_add_contact.update(|state| *state = !*state)/>
+ {move || {
+ if !requests.read().is_empty() {
+ view! {
+ <div class="badge"></div>
+ }.into_any()
+ } else {
+ view! {}.into_any()
+ }
+ }}
</div>
</div>
{move || {
@@ -2211,6 +2239,7 @@ pub enum AddContactError {
#[component]
fn AddContact() -> impl IntoView {
let requests: ReadSignal<HashSet<JID>> = use_context().expect("no pending subscriptions in context");
+ let set_requests: WriteSignal<HashSet<JID>> = use_context().expect("no pending subscriptions write signal in context");
let roster: Store<Roster> = use_context().expect("no roster in context");
let jid = RwSignal::new("".to_string());
@@ -2306,7 +2335,8 @@ fn AddContact() -> impl IntoView {
let jid = jid.clone();
async move {
// TODO: error
- client.unsubscribe_contact(jid).await;
+ client.unsubscribe_contact(jid.clone()).await;
+ set_requests.write().remove(&jid);
}
});
@@ -2352,7 +2382,7 @@ fn AddContact() -> impl IntoView {
let jid_string = move || request.to_string();
view! {
<div class="jid-with-button"><div class="jid">{jid_string}</div>
- <div><div class="button" on:click=move |_| { accept_friend_request.dispatch(request2.clone()); } >Accept</div><div class="button" on:click=move |_| { reject_friend_request.dispatch(request3.clone()); } >Accept</div></div></div>
+ <div><div class="button" on:click=move |_| { accept_friend_request.dispatch(request2.clone()); } >Accept</div><div class="button" on:click=move |_| { reject_friend_request.dispatch(request3.clone()); } >Reject</div></div></div>
}
}
</For>