From 6ee4190a26f32bfa953302ee363ad3bb6c384ebb Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Sun, 1 Jun 2025 16:10:26 +0100 Subject: refactor: reorganise code --- src/views/login_page.rs | 189 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/views/login_page.rs (limited to 'src/views/login_page.rs') diff --git a/src/views/login_page.rs b/src/views/login_page.rs new file mode 100644 index 0000000..2edd4b5 --- /dev/null +++ b/src/views/login_page.rs @@ -0,0 +1,189 @@ +use std::{str::FromStr, sync::Arc}; + +use filamento::{db::Db, error::{CommandError, ConnectionError}, files::{opfs::OPFSError, FilesMem, FilesOPFS}, UpdateMessage}; +use jid::JID; +use thiserror::Error; +use leptos::prelude::*; +use tokio::sync::mpsc::Receiver; +use tracing::debug; + +use crate::{client::Client, files::Files}; + +use super::AppState; + +#[derive(Clone, Debug, Error)] +pub enum LoginError { + #[error("Missing Password")] + MissingPassword, + #[error("Missing JID")] + MissingJID, + #[error("Invalid JID: {0}")] + InvalidJID(#[from] jid::ParseError), + #[error("Connection Error: {0}")] + ConnectionError(#[from] CommandError), + #[error("OPFS: {0}")] + OPFS(#[from] OPFSError), +} + +#[component] +pub fn LoginPage( + set_app: WriteSignal, + set_client: WriteSignal)>>, +) -> impl IntoView { + let jid = RwSignal::new("".to_string()); + let password = RwSignal::new("".to_string()); + let remember_me = RwSignal::new(false); + let connect_on_login = RwSignal::new(true); + + 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 (login_pending, set_login_pending) = signal(false); + + let login = Action::new_local(move |_| { + async move { + set_login_pending.set(true); + + if jid.read_untracked().is_empty() { + set_error.set(Some(LoginError::MissingJID)); + set_login_pending.set(false); + return; + } + + if password.read_untracked().is_empty() { + set_error.set(Some(LoginError::MissingPassword)); + set_login_pending.set(false); + return; + } + + let jid = match JID::from_str(&jid.read_untracked()) { + Ok(j) => j, + Err(e) => { + set_error.set(Some(e.into())); + set_login_pending.set(false); + return; + } + }; + + let remember_me = remember_me.get_untracked(); + // initialise the client + let db = if remember_me { + debug!("creating db in opfs"); + Db::create_connect_and_migrate(jid.as_bare().to_string()) + .await + .unwrap() + } else { + debug!("creating db in memory"); + Db::create_connect_and_migrate_memory().await.unwrap() + }; + let files = if remember_me { + let opfs = FilesOPFS::new(jid.as_bare().to_string()).await; + match opfs { + Ok(f) => Files::Opfs(f), + Err(e) => { + set_error.set(Some(e.into())); + set_login_pending.set(false); + return; + } + } + } else { + Files::Mem(FilesMem::new()) + }; + let (client, updates) = filamento::Client::new( + jid.clone(), + password.read_untracked().clone(), + db, + files.clone(), + ); + let resource = ArcRwSignal::new(None::); + let client = Client { + client, + resource: resource.clone(), + jid: Arc::new(jid.to_bare()), + file_store: files, + }; + + if *connect_on_login.read_untracked() { + match client.connect().await { + Ok(r) => { + resource.set(Some(r)) + } + Err(e) => { + set_error.set(Some(e.into())); + set_login_pending.set(false); + return; + } + } + } + + // debug!("before setting app state"); + set_client.set(Some((client, updates))); + set_app.set(AppState::LoggedIn); + } + }); + + view! { +
+
+
+ +

Macaw Instant Messenger

+
+ {error_message} +
+ + + + +
+ + +
+
+ + +
+ +
+
+
+ } +} -- cgit