diff --git a/.gitignore b/.gitignore index ea8c4bf..96ef6c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 0ca441f..1a9add8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "xmpp-client" +name = "rino" version = "0.1.0" edition = "2021" @@ -13,3 +13,6 @@ nom = "7.1.3" html-escape = "0.2.13" hsluv = "0.3.1" sha1 = "0.10.6" +tokio = { version = "1", features = [ "rt" ] } +xmpp = { git = "https://gitlab.com/xmpp-rs/xmpp-rs" } +async-channel = "2.3.1" diff --git a/src/main.rs b/src/main.rs index 8ef038e..7fd8c27 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ mod message; mod poezio_logs; mod tab; mod window; +mod xmpp; use message::Message; use tab::Tab; @@ -63,6 +64,11 @@ fn xep_0392(input: &str) -> String { } fn main() { + let mut args = std::env::args(); + let _ = args.next().unwrap(); + let username = args.next().expect("Please give username argument 1"); + let password = args.next().expect("Please give password argument 2"); + let app = adw::Application::builder() .application_id("fr.linkmauve.XmppClient") .flags(gio::ApplicationFlags::HANDLES_COMMAND_LINE) @@ -70,29 +76,13 @@ fn main() { let tabs_store = gio::ListStore::new::(); - let tabs_store2 = tabs_store.clone(); - app.connect_command_line(move |app, command_line| { - let args = command_line.arguments(); - let mut iter = args.iter(); - iter.next().unwrap(); - let mut first_tab = None; - for os_arg in iter { - let jid = os_arg.to_str().unwrap(); - let tab = Tab::new(jid, "User"); - tabs_store2.append(&tab); - if first_tab.is_none() { - first_tab = Some(tab); - } + let xmpp_receiver = xmpp::client(&username, &password); + let tabs_store_copy = tabs_store.clone(); + glib::spawn_future_local(async move { + while let Ok(xmpp::ContactReceived(jid)) = xmpp_receiver.recv().await { + let tab = Tab::new(jid.as_str(), jid.as_str()); + tabs_store_copy.append(&tab); } - if let Some(tab) = first_tab { - let win = app.active_window().unwrap(); - let win: &window::MainWindow = win.downcast_ref().unwrap(); - let store = load_logs(&tab.jid()); - win.selection().set_model(Some(&store)); - win.messages() - .scroll_to(win.selection().n_items() - 1, gtk::ListScrollFlags::FOCUS, None); - } - 0 }); app.connect_startup(move |app| { @@ -196,8 +186,11 @@ fn main() { .scroll_to(selection.n_items() - 1, gtk::ListScrollFlags::FOCUS, None); }); - win.messages() - .scroll_to(win.selection().n_items() - 1, gtk::ListScrollFlags::FOCUS, None); + win.messages().scroll_to( + win.selection().n_items() - 1, + gtk::ListScrollFlags::FOCUS, + None, + ); win.present(); }); diff --git a/src/xmpp.rs b/src/xmpp.rs new file mode 100644 index 0000000..4eade70 --- /dev/null +++ b/src/xmpp.rs @@ -0,0 +1,45 @@ +use async_channel::Receiver; +use tokio::runtime::Runtime; +use xmpp::{BareJid, ClientBuilder, ClientFeature, Event}; + +use std::sync::OnceLock; + +#[derive(Clone, Debug)] +pub struct ContactReceived(pub BareJid); + +fn tokio_runtime() -> &'static Runtime { + static RUNTIME: OnceLock = OnceLock::new(); + RUNTIME.get_or_init(|| Runtime::new().expect("Setting up tokio runtime needs to succeed.")) +} + +pub(crate) fn client(jid: &str, password: &str) -> Receiver { + let (event_sender, event_receiver) = async_channel::bounded::(1); + + let jid = jid.to_string(); + let password = password.to_string(); + + tokio_runtime().spawn(async move { + let mut client = ClientBuilder::new(BareJid::new(&jid).unwrap(), &password) + .set_default_nick("xmpp-client") + .enable_feature(ClientFeature::ContactList) + .build(); + + while let Some(events) = client.wait_for_events().await { + for event in events { + match event { + Event::ContactAdded(contact) => { + event_sender + .send(ContactReceived(contact.jid)) + .await + .expect("BOOOOOOHOOOO"); + } + _ => { + continue; + } + } + } + } + }); + + event_receiver +}