summaryrefslogtreecommitdiffstats
path: root/src/components/roster_list
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-06-11 02:54:27 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-06-11 02:54:27 +0100
commit838e99fd1577c52121e148efabcd624114a8b9ad (patch)
treedaaa4e0d00e53a851bf967f668cbc121018d4a5f /src/components/roster_list
parent8bd186fe47eda25b36f945f926ce19093d16fe39 (diff)
downloadmacaw-web-838e99fd1577c52121e148efabcd624114a8b9ad.tar.gz
macaw-web-838e99fd1577c52121e148efabcd624114a8b9ad.tar.bz2
macaw-web-838e99fd1577c52121e148efabcd624114a8b9ad.zip
fmt: everything
Diffstat (limited to 'src/components/roster_list')
-rw-r--r--src/components/roster_list/contact_request_manager.rs221
-rw-r--r--src/components/roster_list/roster_list_item.rs48
2 files changed, 177 insertions, 92 deletions
diff --git a/src/components/roster_list/contact_request_manager.rs b/src/components/roster_list/contact_request_manager.rs
index 174e677..cfb5f28 100644
--- a/src/components/roster_list/contact_request_manager.rs
+++ b/src/components/roster_list/contact_request_manager.rs
@@ -1,12 +1,18 @@
use std::{collections::HashSet, str::FromStr};
-use filamento::{error::{CommandError, SubscribeError}, roster::ContactStoreFields};
+use filamento::{
+ error::{CommandError, SubscribeError},
+ roster::ContactStoreFields,
+};
use jid::{BareJID, JID};
use leptos::{html::Input, prelude::*};
use reactive_stores::Store;
use thiserror::Error;
-use crate::{client::Client, roster::{Roster, RosterStoreFields}};
+use crate::{
+ client::Client,
+ roster::{Roster, RosterStoreFields},
+};
#[derive(Clone, Debug, Error)]
pub enum AddContactError {
@@ -21,9 +27,11 @@ pub enum AddContactError {
#[component]
// TODO: rename
pub fn AddContact() -> impl IntoView {
- let requests: ReadSignal<HashSet<BareJID>> = use_context().expect("no pending subscriptions in context");
- let set_requests: WriteSignal<HashSet<BareJID>> = use_context().expect("no pending subscriptions write signal in context");
- let roster: Store<Roster> = use_context().expect("no roster in context");
+ let requests: ReadSignal<HashSet<BareJID>> =
+ use_context().expect("no pending subscriptions in context");
+ let set_requests: WriteSignal<HashSet<BareJID>> =
+ 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());
// TODO: compartmentalise into error component, form component...
@@ -44,7 +52,7 @@ pub fn AddContact() -> impl IntoView {
let client3 = client.clone();
let client4 = client.clone();
- let add_contact= Action::new_local(move |_| {
+ let add_contact = Action::new_local(move |_| {
let client = client.clone();
async move {
set_add_contact_pending.set(true);
@@ -71,8 +79,8 @@ pub fn AddContact() -> impl IntoView {
Err(e) => {
set_error.set(Some(e.into()));
set_add_contact_pending.set(false);
- return;
- },
+ return;
+ }
};
set_add_contact_pending.set(false);
@@ -90,19 +98,26 @@ pub fn AddContact() -> impl IntoView {
}
});
- let outgoing = move || roster.contacts().get().into_iter().filter(|(jid, contact)| {
- match *contact.contact.subscription().read() {
- filamento::roster::Subscription::None => false,
- filamento::roster::Subscription::PendingOut => true,
- filamento::roster::Subscription::PendingIn => false,
- filamento::roster::Subscription::PendingInPendingOut => true,
- filamento::roster::Subscription::OnlyOut => false,
- filamento::roster::Subscription::OnlyIn => false,
- filamento::roster::Subscription::OutPendingIn => false,
- filamento::roster::Subscription::InPendingOut => true,
- filamento::roster::Subscription::Buddy => false,
- }
- }).collect::<Vec<_>>();
+ let outgoing = move || {
+ roster
+ .contacts()
+ .get()
+ .into_iter()
+ .filter(
+ |(jid, contact)| match *contact.contact.subscription().read() {
+ filamento::roster::Subscription::None => false,
+ filamento::roster::Subscription::PendingOut => true,
+ filamento::roster::Subscription::PendingIn => false,
+ filamento::roster::Subscription::PendingInPendingOut => true,
+ filamento::roster::Subscription::OnlyOut => false,
+ filamento::roster::Subscription::OnlyIn => false,
+ filamento::roster::Subscription::OutPendingIn => false,
+ filamento::roster::Subscription::InPendingOut => true,
+ filamento::roster::Subscription::Buddy => false,
+ },
+ )
+ .collect::<Vec<_>>()
+ };
let accept_friend_request = Action::new_local(move |jid: &BareJID| {
let client = client2.clone();
@@ -129,70 +144,116 @@ pub fn AddContact() -> impl IntoView {
async move {
// TODO: error
client.unsubscribe_from_contact(jid).await;
-
}
});
view! {
<div class="add-contact-menu">
- <div>
- {error_message}
- <form on:submit=move |ev| {
- ev.prevent_default();
- add_contact.dispatch(());
- }>
- <input
- disabled=add_contact_pending
- placeholder="JID"
- type="text"
- node_ref=jid_input
- bind:value=jid
- name="jid"
- id="jid"
- autofocus="true"
- />
- <input disabled=add_contact_pending class="button" type="submit" value="Send Friend Request" />
- </form>
- </div>
- {move || if !requests.read().is_empty() {
- view! {
- <div>
- <h3>Incoming Subscription Requests</h3>
- <For each=move || requests.get() key=|request| request.clone() let(request)>
- {
- let request2 = request.clone();
- let request3 = request.clone();
- 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()); } >Reject</div></div></div>
- }
- }
- </For>
- </div>
- }.into_any()
- } else {
- view! {}.into_any()
- }}
- {move || if !outgoing().is_empty() {
- view! {
- <div>
- <h3>Pending Outgoing Subscription Requests</h3>
- <For each=move || outgoing() key=|(jid, _contact)| jid.clone() let((jid, contact))>
- {
- let jid2 = jid.clone();
- let jid_string = move || jid.to_string();
- view! {
- <div class="jid-with-button"><div class="jid">{jid_string}</div><div class="button" on:click=move |_| { cancel_subscription_request.dispatch(jid2.clone()); } >Cancel</div></div>
- }
- }
- </For>
- </div>
- }.into_any()
- } else {
- view! {}.into_any()
- }}
+ <div>
+ {error_message}
+ <form on:submit=move |ev| {
+ ev.prevent_default();
+ add_contact.dispatch(());
+ }>
+ <input
+ disabled=add_contact_pending
+ placeholder="JID"
+ type="text"
+ node_ref=jid_input
+ bind:value=jid
+ name="jid"
+ id="jid"
+ autofocus="true"
+ />
+ <input
+ disabled=add_contact_pending
+ class="button"
+ type="submit"
+ value="Send Friend Request"
+ />
+ </form>
+ </div>
+ {move || {
+ if !requests.read().is_empty() {
+ view! {
+ <div>
+ <h3>Incoming Subscription Requests</h3>
+ <For
+ each=move || requests.get()
+ key=|request| request.clone()
+ let(request)
+ >
+ {
+ let request2 = request.clone();
+ let request3 = request.clone();
+ 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());
+ }
+ >
+ Reject
+ </div>
+ </div>
+ </div>
+ }
+ }
+ </For>
+ </div>
+ }
+ .into_any()
+ } else {
+ view! {}.into_any()
+ }
+ }}
+ {move || {
+ if !outgoing().is_empty() {
+ view! {
+ <div>
+ <h3>Pending Outgoing Subscription Requests</h3>
+ <For
+ each=move || outgoing()
+ key=|(jid, _contact)| jid.clone()
+ let((jid, contact))
+ >
+ {
+ let jid2 = jid.clone();
+ let jid_string = move || jid.to_string();
+ view! {
+ <div class="jid-with-button">
+ <div class="jid">{jid_string}</div>
+ <div
+ class="button"
+ on:click=move |_| {
+ cancel_subscription_request.dispatch(jid2.clone());
+ }
+ >
+ Cancel
+ </div>
+ </div>
+ }
+ }
+ </For>
+ </div>
+ }
+ .into_any()
+ } else {
+ view! {}.into_any()
+ }
+ }}
</div>
}
}
-
diff --git a/src/components/roster_list/roster_list_item.rs b/src/components/roster_list/roster_list_item.rs
index 538e664..c90455c 100644
--- a/src/components/roster_list/roster_list_item.rs
+++ b/src/components/roster_list/roster_list_item.rs
@@ -1,12 +1,24 @@
use std::ops::Deref;
-use filamento::{chat::Chat, roster::{Contact, ContactStoreFields}, user::{User, UserStoreFields}};
+use filamento::{
+ chat::Chat,
+ roster::{Contact, ContactStoreFields},
+ user::{User, UserStoreFields},
+};
use jid::BareJID;
use leptos::prelude::*;
use reactive_stores::{ArcStore, Store};
use tracing::debug;
-use crate::{chat::{ArcMacawChat, MacawChat}, client::Client, components::{avatar::AvatarWithPresence, sidebar::Open}, contact::MacawContact, open_chats::{OpenChatsPanel, OpenChatsPanelStoreFields}, state_store::StateStore, user::{fetch_avatar, get_name, ArcMacawUser}};
+use crate::{
+ chat::{ArcMacawChat, MacawChat},
+ client::Client,
+ components::{avatar::AvatarWithPresence, sidebar::Open},
+ contact::MacawContact,
+ open_chats::{OpenChatsPanel, OpenChatsPanelStoreFields},
+ state_store::StateStore,
+ user::{ArcMacawUser, fetch_avatar, get_name},
+};
#[component]
pub fn RosterListItem(contact: MacawContact) -> impl IntoView {
@@ -23,7 +35,7 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {
use_context().expect("no user state store");
let open_chat = Action::new_local(move |_| {
- let client= client.clone();
+ let client = client.clone();
async move {
let to = contact.user.get().jid().get();
let (chat, user) = match client.get_chat_and_user(to).await {
@@ -33,7 +45,7 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {
// set_error.set(Some(e.into()));
// set_new_chat_pending.set(false);
return;
- },
+ }
};
let chat = {
@@ -41,7 +53,9 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {
// let user = user_state_store.store(user.jid.clone(), ArcStore::new(user));
let old_user = user_state_store.get_listener(user.jid.clone());
let user = if let Some(old_user) = old_user {
- old_user.update(|(old_user, _avatar)| { old_user.set(user); });
+ old_user.update(|(old_user, _avatar)| {
+ old_user.set(user);
+ });
old_user
} else {
let avatar = fetch_avatar(user.avatar.as_deref()).await;
@@ -56,7 +70,8 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {
}
});
- let current_open_chat: Memo<Option<BareJID>> = use_context().expect("no open chat memo in context");
+ let current_open_chat: Memo<Option<BareJID>> =
+ use_context().expect("no open chat memo in context");
let open = move || {
if let Some(open_chat) = &*current_open_chat.read() {
@@ -78,17 +93,26 @@ pub fn RosterListItem(contact: MacawContact) -> impl IntoView {
let open = move || open().is_open();
view! {
- <div class="roster-list-item" class:open=move || open() class:focused=move || focused() on:click=move |_| { open_chat.dispatch(()); }>
+ <div
+ class="roster-list-item"
+ class:open=move || open()
+ class:focused=move || focused()
+ on:click=move |_| {
+ open_chat.dispatch(());
+ }
+ >
{move || {
- view! {
- <AvatarWithPresence user=contact.user />
- }
+ view! { <AvatarWithPresence user=contact.user /> }
}}
<div class="item-info">
- <div class="main-info"><p class="name">{name}<span class="jid"> - {move || contact.user_jid().read().to_string()}</span></p></div>
+ <div class="main-info">
+ <p class="name">
+ {name}
+ <span class="jid">- {move || contact.user_jid().read().to_string()}</span>
+ </p>
+ </div>
<div class="sub-info">{move || contact.subscription().read().to_string()}</div>
</div>
</div>
}
}
-