diff options
| author | 2025-05-23 16:00:54 +0100 | |
|---|---|---|
| committer | 2025-05-23 16:00:54 +0100 | |
| commit | eff7045e9f871c0ec6eb0401c77ab4209b36d636 (patch) | |
| tree | bb5d9007f37ec0e76cdc511c937062f7249a3215 /src | |
| parent | f14ac34129b05b7424fb0c002920c6bf40ad45ab (diff) | |
| download | macaw-web-eff7045e9f871c0ec6eb0401c77ab4209b36d636.tar.gz macaw-web-eff7045e9f871c0ec6eb0401c77ab4209b36d636.tar.bz2 macaw-web-eff7045e9f871c0ec6eb0401c77ab4209b36d636.zip  | |
feat: subscription request badges
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 36 | 
1 files changed, 33 insertions, 3 deletions
@@ -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>  | 
