diff options
author | 2025-06-01 16:10:26 +0100 | |
---|---|---|
committer | 2025-06-01 17:27:40 +0100 | |
commit | 6ee4190a26f32bfa953302ee363ad3bb6c384ebb (patch) | |
tree | 2c3182c29d5780a0ad9c9770b5e546312bea49b4 /src/components/chats_list.rs | |
parent | f76c80c1d23177ab00c81240ee3a75d3bcda0e3b (diff) | |
download | macaw-web-6ee4190a26f32bfa953302ee363ad3bb6c384ebb.tar.gz macaw-web-6ee4190a26f32bfa953302ee363ad3bb6c384ebb.tar.bz2 macaw-web-6ee4190a26f32bfa953302ee363ad3bb6c384ebb.zip |
refactor: reorganise code
Diffstat (limited to 'src/components/chats_list.rs')
-rw-r--r-- | src/components/chats_list.rs | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/components/chats_list.rs b/src/components/chats_list.rs new file mode 100644 index 0000000..b8cf34c --- /dev/null +++ b/src/components/chats_list.rs @@ -0,0 +1,109 @@ +use chats_list_item::ChatsListItem; +use indexmap::IndexMap; +use jid::BareJID; +use leptos::prelude::*; +use tracing::debug; + +use crate::{chat::MacawChat, client::Client, components::{icon::IconComponent, new_chat::NewChatWidget, overlay::Overlay}, icon::Icon, message::MacawMessage, message_subscriptions::MessageSubscriptions}; + +mod chats_list_item; + +#[component] +pub fn ChatsList() -> impl IntoView { + let (chats, set_chats) = signal(IndexMap::new()); + + let load_chats = LocalResource::new(move || async move { + let client = use_context::<Client>().expect("client not in context"); + let chats = client + .get_chats_ordered_with_latest_messages_and_users() + .await + .map_err(|e| e.to_string()); + match chats { + Ok(c) => { + let chats = c + .into_iter() + .map(|((chat, chat_user), (message, message_user))| { + ( + chat.correspondent.clone(), + ( + MacawChat::got_chat_and_user(chat, chat_user), + MacawMessage::got_message_and_user(message, message_user), + ), + ) + }) + .collect::<IndexMap<BareJID, _>>(); + set_chats.set(chats); + } + Err(_) => { + // TODO: show error message at top of chats list + } + } + }); + + let (open_new_chat, set_open_new_chat) = signal(false); + + // TODO: filter new messages signal + let new_messages_signal: RwSignal<MessageSubscriptions> = use_context().unwrap(); + let (sub_id, set_sub_id) = signal(None); + let _load_new_messages = LocalResource::new(move || async move { + load_chats.await; + let (sub_id, mut new_messages) = new_messages_signal.write().subscribe_all(); + set_sub_id.set(Some(sub_id)); + while let Some((to, new_message)) = new_messages.recv().await { + debug!("got new message in let"); + let mut chats = set_chats.write(); + if let Some((chat, _latest_message)) = chats.shift_remove(&to) { + // TODO: check if new message is actually latest message + debug!("chat existed"); + debug!("new message: {}", new_message.message.read().body.body); + chats.insert_before(0, to, (chat.clone(), new_message)); + debug!("done setting"); + } else { + debug!("the chat didn't exist"); + let client = use_context::<Client>().expect("client not in context"); + let chat = client.get_chat(to.clone()).await.unwrap(); + let user = client.get_user(to.clone()).await.unwrap(); + debug!("before got chat"); + let chat = MacawChat::got_chat_and_user(chat, user); + debug!("after got chat"); + chats.insert_before(0, to, (chat, new_message)); + debug!("done setting"); + } + } + debug!("set the new message"); + }); + on_cleanup(move || { + if let Some(sub_id) = sub_id.get() { + new_messages_signal.write().unsubscribe_all(sub_id); + } + }); + + view! { + <div class="chats-list panel"> + // TODO: update icon, tooltip on hover. + <div class="header"> + <h2>Chats</h2> + <div class="new-chat header-icon" class:open=open_new_chat > + <IconComponent icon=Icon::NewBubble24 on:click=move |_| set_open_new_chat.update(|state| *state = !*state)/> + {move || { + if *open_new_chat.read() { + view! { + <Overlay set_open=set_open_new_chat> + <NewChatWidget set_open_new_chat /> + </Overlay> + }.into_any() + } else { + view! {}.into_any() + } + }} + </div> + </div> + <div class="chats-list-chats"> + <For each=move || chats.get() key=|chat| chat.1.1.message.read().id let(chat)> + <ChatsListItem chat=chat.1.0 message=chat.1.1 /> + </For> + </div> + </div> + } +} + |