From db7e28a78a1e67198b9d8f652f4318a279c7b82f Mon Sep 17 00:00:00 2001 From: reya Date: Sun, 24 Nov 2024 15:17:35 +0700 Subject: [PATCH] refactor app state --- Cargo.toml | 4 +-- crates/client/Cargo.toml | 2 -- crates/client/src/lib.rs | 12 ------- crates/client/src/state.rs | 10 +++--- crates/ui/Cargo.toml | 2 +- crates/ui/src/main.rs | 9 +++--- crates/ui/src/state.rs | 8 ++--- crates/ui/src/utils.rs | 5 ++- crates/ui/src/views/app.rs | 6 ++-- crates/ui/src/views/chat_space/bottom_bar.rs | 21 ++----------- crates/ui/src/views/chat_space/mod.rs | 2 -- crates/ui/src/views/onboarding.rs | 33 ++++++++++++++++---- 12 files changed, 49 insertions(+), 65 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b154767..3939159 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,8 @@ components = { package = "ui", git = "https://github.com/longbridgeapp/gpui-comp reqwest_client = { git = "https://github.com/huacnlee/zed.git", branch = "export-platform-window" } # Nostr -nostr-relay-builder = { git = "https://github.com/rust-nostr/nostr" } -nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = [ +nostr-relay-builder = { git = "https://github.com/rust-nostr/nostr", branch = "nip17" } +nostr-sdk = { git = "https://github.com/rust-nostr/nostr", branch = "nip17", features = [ "lmdb", "all-nips", ] } diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 43485f3..cdbc61d 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -8,5 +8,3 @@ gpui.workspace = true nostr-sdk.workspace = true dirs.workspace = true tokio.workspace = true -keyring-search.workspace = true -keyring.workspace = true diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index 86ff30c..f4e4a72 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -1,5 +1,4 @@ use gpui::Global; -use keyring::Entry; use nostr_sdk::prelude::*; use state::get_client; @@ -18,15 +17,4 @@ impl NostrClient { Self { client } } - - pub fn add_account(&self, keys: Keys) -> Result<()> { - let public_key = keys.public_key().to_bech32()?; - let secret = keys.secret_key().to_secret_hex(); - let entry = Entry::new("Coop Safe Storage", &public_key)?; - - // Add secret to keyring - entry.set_password(&secret)?; - - Ok(()) - } } diff --git a/crates/client/src/state.rs b/crates/client/src/state.rs index 19dd857..d5fbd88 100644 --- a/crates/client/src/state.rs +++ b/crates/client/src/state.rs @@ -1,6 +1,6 @@ use dirs::config_dir; use nostr_sdk::prelude::*; -use std::fs; +use std::{fs, time::Duration}; use tokio::sync::OnceCell; pub static CLIENT: OnceCell = OnceCell::const_new(); @@ -17,15 +17,17 @@ pub async fn get_client() -> &'static Client { .expect("Database is NOT initialized"); // Setup Nostr Client - let client = ClientBuilder::default().database(lmdb).build(); + let opts = Options::new().gossip(true).timeout(Duration::from_secs(5)); + let client = ClientBuilder::default().database(lmdb).opts(opts).build(); // Add some bootstrap relays let _ = client.add_relay("wss://relay.damus.io").await; let _ = client.add_relay("wss://relay.primal.net").await; let _ = client.add_relay("wss://nostr.fmt.wiz.biz").await; let _ = client.add_relay("wss://directory.yabu.me").await; - let _ = client.add_relay("wss://purplepag.es").await; - let _ = client.add_relay("wss://user.kindpag.es/").await; + + let _ = client.add_discovery_relay("wss://user.kindpag.es/").await; + let _ = client.add_discovery_relay("wss://purplepag.es").await; // Connect to all relays client.connect().await; diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index 7f8d2aa..f23ba3a 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -22,4 +22,4 @@ reqwest_client.workspace = true client = { version = "0.1.0", path = "../client" } rust-embed = "8.5.0" -env_logger = "0.11.5" +tracing-subscriber = { version = "0.3.18", features = ["fmt"] } diff --git a/crates/ui/src/main.rs b/crates/ui/src/main.rs index 297fb22..ad47ab2 100644 --- a/crates/ui/src/main.rs +++ b/crates/ui/src/main.rs @@ -15,11 +15,11 @@ actions!(main_menu, [Quit]); #[tokio::main] async fn main() { - env_logger::init(); + tracing_subscriber::fmt::init(); // Initialize nostr client let nostr = NostrClient::init().await; - // Initializ app state + // Initialize app state let app_state = AppState::new(); App::new() @@ -31,9 +31,8 @@ async fn main() { // Set custom theme let mut theme = Theme::from(ThemeColor::dark()); - // TODO: support light mode + // Set dark mode by default theme.mode = ThemeMode::Dark; - // TODO: adjust color set // Set app state cx.set_global(theme); @@ -43,7 +42,7 @@ async fn main() { // Set quit action cx.on_action(quit); - // Rerender + // Refresh cx.refresh(); // Set window size diff --git a/crates/ui/src/state.rs b/crates/ui/src/state.rs index 96f03c1..db72c9e 100644 --- a/crates/ui/src/state.rs +++ b/crates/ui/src/state.rs @@ -1,19 +1,15 @@ use gpui::Global; use nostr_sdk::prelude::*; -use std::collections::HashSet; - -use crate::utils::get_all_accounts_from_keyring; pub struct AppState { - pub accounts: HashSet, + pub signer: Option, } impl Global for AppState {} impl AppState { pub fn new() -> Self { - let accounts = get_all_accounts_from_keyring(); - Self { accounts } + Self { signer: None } } } diff --git a/crates/ui/src/utils.rs b/crates/ui/src/utils.rs index 2fbcc0c..cff89f4 100644 --- a/crates/ui/src/utils.rs +++ b/crates/ui/src/utils.rs @@ -1,12 +1,11 @@ use keyring_search::{Limit, List, Search}; use nostr_sdk::prelude::*; -use std::collections::HashSet; -pub fn get_all_accounts_from_keyring() -> HashSet { +pub fn get_all_accounts_from_keyring() -> Vec { let search = Search::new().expect("Keyring not working."); let results = search.by_service("Coop Safe Storage"); let list = List::list_credentials(&results, Limit::All); - let accounts: HashSet = list + let accounts: Vec = list .split_whitespace() .filter(|v| v.starts_with("npub1") && !v.ends_with("coop")) .filter_map(|i| PublicKey::from_bech32(i).ok()) diff --git a/crates/ui/src/views/app.rs b/crates/ui/src/views/app.rs index 0422688..d8897bc 100644 --- a/crates/ui/src/views/app.rs +++ b/crates/ui/src/views/app.rs @@ -11,9 +11,9 @@ pub struct AppView { impl AppView { pub fn new(cx: &mut ViewContext<'_, Self>) -> AppView { - // Onboarding model + // Onboarding let onboarding = cx.new_view(Onboarding::new); - // Chat Space view + // Chat Space let chat_space = cx.new_view(ChatSpace::new); AppView { @@ -27,7 +27,7 @@ impl Render for AppView { fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { let mut content = div().size_full().flex().items_center().justify_center(); - if cx.global::().accounts.is_empty() { + if cx.global::().signer.is_none() { content = content.child(self.onboarding.clone()) } else { content = content.child(self.chat_space.clone()) diff --git a/crates/ui/src/views/chat_space/bottom_bar.rs b/crates/ui/src/views/chat_space/bottom_bar.rs index 1a54da6..adf44ba 100644 --- a/crates/ui/src/views/chat_space/bottom_bar.rs +++ b/crates/ui/src/views/chat_space/bottom_bar.rs @@ -74,27 +74,11 @@ impl RenderOnce for Account { } } -pub struct BottomBar { - accounts: Vec, -} +pub struct BottomBar {} impl BottomBar { pub fn new(cx: &mut ViewContext<'_, Self>) -> BottomBar { - let state: Vec = cx - .global::() - .accounts - .clone() - .into_iter() - .collect(); - - let win_cx = cx.window_context(); - - let accounts = state - .into_iter() - .map(|pk| Account::new(pk, win_cx)) - .collect::>(); - - BottomBar { accounts } + BottomBar {} } } @@ -108,6 +92,5 @@ impl Render for BottomBar { .items_center() .justify_center() .gap_1() - .children(self.accounts.clone()) } } diff --git a/crates/ui/src/views/chat_space/mod.rs b/crates/ui/src/views/chat_space/mod.rs index 3d36288..b322101 100644 --- a/crates/ui/src/views/chat_space/mod.rs +++ b/crates/ui/src/views/chat_space/mod.rs @@ -16,7 +16,6 @@ pub struct ChatSpace { impl ChatSpace { pub fn new(cx: &mut ViewContext<'_, Self>) -> Self { let navigation = cx.new_view(Navigation::new); - let bottom_bar = cx.new_view(BottomBar::new); let layout = cx.new_view(|cx| { h_resizable(cx) @@ -28,7 +27,6 @@ impl ChatSpace { .flex() .flex_col() .child(navigation.clone()) - .child(bottom_bar.clone()) .into_any_element() }), cx, diff --git a/crates/ui/src/views/onboarding.rs b/crates/ui/src/views/onboarding.rs index 3828cc9..d019e6e 100644 --- a/crates/ui/src/views/onboarding.rs +++ b/crates/ui/src/views/onboarding.rs @@ -4,6 +4,7 @@ use components::{ label::Label, }; use gpui::*; +use keyring::Entry; use nostr_sdk::prelude::*; use crate::state::AppState; @@ -21,17 +22,37 @@ impl Onboarding { }); cx.subscribe(&input, move |_, text_input, input_event, cx| { + let mut async_cx = cx.to_async(); + let client = cx.global::().client; + let view_id = cx.parent_view_id(); + if let InputEvent::PressEnter = input_event { let content = text_input.read(cx).text().to_string(); if let Ok(keys) = Keys::parse(content) { - let public_key = keys.public_key(); + cx.foreground_executor() + .spawn(async move { + let public_key = keys.public_key(); + let secret = keys.secret_key().to_secret_hex(); - if cx.global::().add_account(keys).is_ok() { - cx.global_mut::().accounts.insert(public_key); - cx.notify(); - } - }; + let entry = + Entry::new("Coop Safe Storage", &public_key.to_bech32().unwrap()) + .unwrap(); + + // Store private key to OS Keyring + let _ = entry.set_password(&secret); + + // Update signer + client.set_signer(keys).await; + + // Update view + async_cx.update_global(|app_state: &mut AppState, cx| { + app_state.signer = Some(public_key); + cx.notify(view_id); + }) + }) + .detach(); + } } }) .detach();