use std::str::FromStr; use filamento::{chat::Chat, error::{CommandError, DatabaseError}, user::User}; use jid::{BareJID, JID}; use leptos::{html::Input, prelude::*}; use reactive_stores::{ArcStore, Store}; use thiserror::Error; use crate::{chat::{ArcMacawChat, MacawChat}, client::Client, open_chats::OpenChatsPanel, state_store::StateStore, user::{ArcMacawUser, MacawUser}}; #[derive(Clone, Debug, Error)] pub enum NewChatError { #[error("Missing JID")] MissingJID, #[error("Invalid JID: {0}")] InvalidJID(#[from] jid::ParseError), #[error("Database: {0}")] Db(#[from] CommandError), } #[component] pub fn NewChatWidget(set_open_new_chat: WriteSignal) -> impl IntoView { let jid = RwSignal::new("".to_string()); // TODO: compartmentalise into error component, form component... let (error, set_error) = signal(None::); let error_message = move || { error.with(|error| { if let Some(error) = error { view! {
{error.to_string()}
}.into_any() } else { view! {}.into_any() } }) }; let (new_chat_pending, set_new_chat_pending) = signal(false); let open_chats: Store = use_context().expect("no open chats panel store in context"); let client = use_context::().expect("client not in context"); let chat_state_store: StateStore> = use_context().expect("no chat state store"); let user_state_store: StateStore> = use_context().expect("no user state store"); let open_chat = Action::new_local(move |_| { let client = client.clone(); async move { set_new_chat_pending.set(true); if jid.read_untracked().is_empty() { set_error.set(Some(NewChatError::MissingJID)); set_new_chat_pending.set(false); return; } let jid = match JID::from_str(&jid.read_untracked()) { // TODO: ability to direct address a resource? Ok(j) => j.to_bare(), Err(e) => { set_error.set(Some(e.into())); set_new_chat_pending.set(false); return; } }; let chat_jid = jid; let (chat, user) = match client.get_chat_and_user(chat_jid).await { Ok(c) => c, Err(e) => { set_error.set(Some(e.into())); set_new_chat_pending.set(false); return; }, }; let chat = { // let user = MacawUser::got_user(user); let user = user_state_store.store(user.jid.clone(), ArcStore::new(user)); let user = ArcMacawUser { user }; let chat = chat_state_store.store(chat.correspondent.clone(), ArcStore::new(chat)); ArcMacawChat { chat, user } }; open_chats.update(|open_chats| open_chats.open(chat.clone())); set_open_new_chat.set(false); } }); let jid_input = NodeRef::::new(); let _focus = Effect::new(move |_| { if let Some(input) = jid_input.get() { let _ = input.focus(); input.set_text_content(Some("")); // input.style("height: 0"); // let height = input.scroll_height(); // input.style(format!("height: {}px", height)); } }); view! {
{error_message}
} }