use chats_list_item::ChatsListItem; use indexmap::IndexMap; use jid::BareJID; use js_sys::{wasm_bindgen::UnwrapThrowExt, Object, Reflect, JSON}; use leptos::{html::Div, prelude::*}; use overlay_scrollbars::OverlayScrollbars; use tracing::debug; use crate::{ chat::{ArcMacawChat, MacawChat}, client::Client, components::{icon::IconComponent, new_chat::NewChatWidget, overlay::Overlay}, icon::Icon, message::{ArcMacawMessage, 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::().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 mut chats = IndexMap::new(); for ((chat, chat_user), (message, message_user)) in c { chats.insert( chat.correspondent.clone(), ( ArcMacawChat::got_chat_and_user(chat, chat_user).await, ArcMacawMessage::got_message_and_user(message, message_user).await, ), ); } 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 = 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.get().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::().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 = ArcMacawChat::got_chat_and_user(chat, user).await; 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_untracked() { new_messages_signal.write().unsubscribe_all(sub_id); } }); let chats_list: NodeRef
= NodeRef::new(); let chats_list_viewport: NodeRef
= NodeRef::new(); let _scrollbars = Effect::new(move |_| { if let Some(buffer) = chats_list.get() { if let Some(viewport) = chats_list_viewport.get() { let scrollbars_obj = Object::new(); // Reflect::set(&scrollbars_obj, &"theme".into(), &"os-macaw".into()).unwrap_throw(); // Reflect::set(&scrollbars_obj, &"autoHide".into(), &"leave".into()).unwrap_throw(); let options_obj = Object::new(); // Reflect::set(&options_obj, &"scrollbars".into(), &scrollbars_obj).unwrap_throw(); let elements_obj = Object::new(); Reflect::set(&elements_obj, &"viewport".into(), &viewport.into()).unwrap_throw(); let element_obj = Object::new(); Reflect::set(&elements_obj, &"elements".into(), &elements_obj).unwrap_throw(); Reflect::set(&element_obj, &"target".into(), &buffer.into()).unwrap_throw(); // let element = Object::define_property(&Object::define_property(&Object::new(), &"target".into(), &buffer.into()), &"elements".into(), &Object::define_property(&Object::new(), &"viewport".into(), &viewport.into())); debug!("scrollable element: {}", JSON::stringify(&element_obj.clone().into()).unwrap_throw()); OverlayScrollbars(element_obj, options_obj); } } }); view! {
// TODO: update icon, tooltip on hover.

Chats

{move || { if *open_new_chat.read() { view! { } .into_any() } else { view! {}.into_any() } }}
} }