From 51b392a845b827a42eeeba6abb7b978aa3b857ef Mon Sep 17 00:00:00 2001 From: reya Date: Thu, 2 Jan 2025 09:58:42 +0700 Subject: [PATCH] wip: refactor --- Cargo.lock | 108 +----------------- Cargo.toml | 6 - crates/app/Cargo.toml | 2 - crates/app/src/constants.rs | 2 +- crates/app/src/main.rs | 63 +++++++--- crates/app/src/states/account.rs | 10 +- crates/app/src/states/metadata.rs | 4 - crates/app/src/states/signal.rs | 10 +- crates/app/src/utils.rs | 26 ----- crates/app/src/views/app.rs | 15 ++- .../{onboarding.rs => onboarding/mod.rs} | 36 +++--- 11 files changed, 94 insertions(+), 188 deletions(-) rename crates/app/src/views/{onboarding.rs => onboarding/mod.rs} (66%) diff --git a/Cargo.lock b/Cargo.lock index 14e09cb..e1e9471 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1202,8 +1202,6 @@ dependencies = [ "dirs 5.0.1", "gpui", "itertools 0.13.0", - "keyring", - "keyring-search", "nostr-sdk", "random_name_generator", "reqwest_client", @@ -1415,30 +1413,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" -[[package]] -name = "dbus" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" -dependencies = [ - "libc", - "libdbus-sys", - "winapi", -] - -[[package]] -name = "dbus-secret-service" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42a16374481d92aed73ae45b1f120207d8e71d24fb89f357fadbd8f946fd84b" -dependencies = [ - "dbus", - "futures-util", - "num", - "once_cell", - "rand", -] - [[package]] name = "derive_more" version = "0.99.18" @@ -2887,35 +2861,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keyring" -version = "3.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8fe839464d4e4b37d756d7e910063696af79a7e877282cb1825e4ec5f10833" -dependencies = [ - "byteorder", - "dbus-secret-service", - "log", - "security-framework 2.11.1", - "security-framework 3.1.0", - "windows-sys 0.59.0", -] - -[[package]] -name = "keyring-search" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fba83ff0a0efb658afeaaa6de89c7abd3ccd34333f5a36d5dae417334fcd488" -dependencies = [ - "byteorder", - "lazy_static", - "linux-keyutils", - "regex", - "secret-service", - "security-framework 2.11.1", - "windows-sys 0.52.0", -] - [[package]] name = "khronos-egl" version = "6.0.0" @@ -2957,15 +2902,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "libdbus-sys" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" -dependencies = [ - "pkg-config", -] - [[package]] name = "libfuzzer-sys" version = "0.4.8" @@ -3022,16 +2958,6 @@ dependencies = [ "syn 2.0.93", ] -[[package]] -name = "linux-keyutils" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" -dependencies = [ - "bitflags 2.6.0", - "libc", -] - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -4711,7 +4637,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.1.0", + "security-framework", ] [[package]] @@ -4874,38 +4800,6 @@ dependencies = [ "cc", ] -[[package]] -name = "secret-service" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4d35ad99a181be0a60ffcbe85d680d98f87bdc4d7644ade319b87076b9dbfd4" -dependencies = [ - "aes", - "cbc", - "futures-util", - "generic-array", - "hkdf", - "num", - "once_cell", - "rand", - "serde", - "sha2", - "zbus 4.4.0", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - [[package]] name = "security-framework" version = "3.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7f18fbd..44bfabe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,12 +29,6 @@ tracing = "0.1.40" anyhow = "1.0.44" smallvec = "1.13.2" rust-embed = "8.5.0" -keyring-search = "1.2.0" -keyring = { version = "3", features = [ - "apple-native", - "windows-native", - "sync-secret-service", -] } [profile.release] codegen-units = 1 diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index 3bfab0f..bf921e4 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -16,8 +16,6 @@ reqwest_client.workspace = true tokio.workspace = true nostr-sdk.workspace = true -keyring-search.workspace = true -keyring.workspace = true anyhow.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/app/src/constants.rs b/crates/app/src/constants.rs index b018b44..02e003b 100644 --- a/crates/app/src/constants.rs +++ b/crates/app/src/constants.rs @@ -1,5 +1,5 @@ pub const KEYRING_SERVICE: &str = "Coop Safe Storage"; -pub const APP_NAME: &str = "coop"; +pub const APP_NAME: &str = "Coop"; pub const FAKE_SIG: &str = "f9e79d141c004977192d05a86f81ec7c585179c371f7350a5412d33575a2a356433f58e405c2296ed273e2fe0aafa25b641e39cc4e1f3f261ebf55bce0cbac83"; pub const NEW_MESSAGE_SUB_ID: &str = "listen_new_giftwrap"; pub const ALL_MESSAGES_SUB_ID: &str = "listen_all_giftwraps"; diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs index 03e0e7c..f819664 100644 --- a/crates/app/src/main.rs +++ b/crates/app/src/main.rs @@ -13,22 +13,25 @@ use tokio::{ sync::{mpsc, Mutex}, time::sleep, }; -use ui::Root; -use constants::{ALL_MESSAGES_SUB_ID, APP_NAME, FAKE_SIG, METADATA_DELAY, NEW_MESSAGE_SUB_ID}; +use constants::{ + ALL_MESSAGES_SUB_ID, APP_NAME, FAKE_SIG, KEYRING_SERVICE, METADATA_DELAY, NEW_MESSAGE_SUB_ID, +}; +use ui::Root; +use views::app::AppView; + use states::{ account::AccountRegistry, chat::ChatRegistry, metadata::MetadataRegistry, signal::{Signal, SignalRegistry}, }; -use views::app::AppView; -pub mod asset; -pub mod constants; -pub mod states; -pub mod utils; -pub mod views; +mod asset; +mod constants; +mod states; +mod utils; +mod views; actions!(main_menu, [Quit]); actions!(app, [ReloadMetadata]); @@ -128,8 +131,7 @@ async fn main() { // Send event back to channel if subscription_id == new_message { - if let Err(e) = signal_tx.send(Signal::RecvEvent(ev)).await - { + if let Err(e) = signal_tx.send(Signal::Event(ev)).await { println!("Send error: {}", e) } } @@ -138,13 +140,13 @@ async fn main() { Err(e) => println!("Unwrap error: {}", e), } } else if event.kind == Kind::Metadata { - if let Err(e) = signal_tx.send(Signal::RecvMetadata(event.pubkey)).await { + if let Err(e) = signal_tx.send(Signal::Metadata(event.pubkey)).await { println!("Send error: {}", e) } } } else if let RelayMessage::EndOfStoredEvents(subscription_id) = message { if subscription_id == all_messages { - if let Err(e) = signal_tx.send(Signal::RecvEose(subscription_id)).await { + if let Err(e) = signal_tx.send(Signal::Eose).await { println!("Send error: {}", e) } } @@ -211,6 +213,36 @@ async fn main() { // Set quit action cx.on_action(quit); + cx.spawn(|async_cx| { + let task = cx.read_credentials(KEYRING_SERVICE); + + async move { + if let Ok(res) = task.await { + if let Some((npub, secret)) = res { + let public_key = PublicKey::from_bech32(&npub).unwrap(); + let hex = String::from_utf8(secret).unwrap(); + let keys = Keys::parse(&hex).unwrap(); + + _ = client.set_signer(keys).await; + // Update global state + _ = async_cx.update_global::(|state, _cx| { + state.set_user(Some(public_key)); + state.set_loading(); + }); + } else { + _ = async_cx.update_global::(|state, _| { + state.set_loading(); + }); + } + } else { + _ = async_cx.update_global::(|state, _| { + state.set_loading(); + }); + } + } + }) + .detach(); + cx.spawn(|async_cx| async move { let (tx, rx) = smol::channel::unbounded::(); @@ -227,12 +259,12 @@ async fn main() { while let Ok(signal) = rx.recv().await { match signal { - Signal::RecvEose(_) => { + Signal::Eose => { _ = async_cx.update_global::(|state, _| { state.update(); }); } - Signal::RecvEvent(event) => { + Signal::Event(event) => { let metadata = async_cx .background_executor() .spawn(async move { @@ -248,7 +280,7 @@ async fn main() { state.push(event, metadata); }); } - Signal::RecvMetadata(public_key) => { + Signal::Metadata(public_key) => { let metadata = async_cx .background_executor() .spawn(async move { @@ -264,7 +296,6 @@ async fn main() { state.seen(public_key, metadata); }); } - _ => {} } } }) diff --git a/crates/app/src/states/account.rs b/crates/app/src/states/account.rs index 08862d0..f3a788d 100644 --- a/crates/app/src/states/account.rs +++ b/crates/app/src/states/account.rs @@ -10,6 +10,7 @@ use crate::{ pub struct AccountRegistry { public_key: Option, + pub(crate) is_loading: bool, } impl Global for AccountRegistry {} @@ -58,6 +59,10 @@ impl AccountRegistry { .detach(); } + pub fn set_loading(&mut self) { + self.is_loading = false + } + pub fn get(&self) -> Option { self.public_key } @@ -71,6 +76,9 @@ impl AccountRegistry { } fn new() -> Self { - Self { public_key: None } + Self { + public_key: None, + is_loading: true, + } } } diff --git a/crates/app/src/states/metadata.rs b/crates/app/src/states/metadata.rs index c81abfe..05c65cf 100644 --- a/crates/app/src/states/metadata.rs +++ b/crates/app/src/states/metadata.rs @@ -17,10 +17,6 @@ impl MetadataRegistry { cx.set_global(Self::new()); } - pub fn contains(&self, public_key: PublicKey) -> bool { - self.seens.lock().unwrap().contains(&public_key) - } - pub fn seen(&mut self, public_key: PublicKey, metadata: Option) { let mut seens = self.seens.lock().unwrap(); diff --git a/crates/app/src/states/signal.rs b/crates/app/src/states/signal.rs index 5afd612..6a5c7f3 100644 --- a/crates/app/src/states/signal.rs +++ b/crates/app/src/states/signal.rs @@ -5,14 +5,12 @@ use tokio::sync::mpsc::UnboundedSender; #[derive(Clone)] pub enum Signal { - /// Request metadata - ReqMetadata(PublicKey), /// Receive metadata - RecvMetadata(PublicKey), - /// Receive EOSE - RecvEose(SubscriptionId), + Metadata(PublicKey), /// Receive event - RecvEvent(Event), + Event(Event), + /// Receive EOSE + Eose, } pub struct SignalRegistry { diff --git a/crates/app/src/utils.rs b/crates/app/src/utils.rs index 7868e3d..f4a9bdb 100644 --- a/crates/app/src/utils.rs +++ b/crates/app/src/utils.rs @@ -1,32 +1,6 @@ use chrono::{Duration, Local, TimeZone}; -use keyring::Entry; -use keyring_search::{Limit, List, Search}; use nostr_sdk::prelude::*; -use crate::constants::KEYRING_SERVICE; - -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: Vec = list - .split_whitespace() - .filter(|v| v.starts_with("npub1") && !v.ends_with("coop")) - .filter_map(|i| PublicKey::from_bech32(i).ok()) - .collect(); - - accounts -} - -pub fn get_keys_by_account(public_key: PublicKey) -> Result { - let bech32 = public_key.to_bech32()?; - let entry = Entry::new(KEYRING_SERVICE, &bech32)?; - let password = entry.get_password()?; - let keys = Keys::parse(&password)?; - - Ok(keys) -} - pub fn get_room_id(owner: &PublicKey, public_keys: &[PublicKey]) -> String { let hex: Vec = public_keys .iter() diff --git a/crates/app/src/views/app.rs b/crates/app/src/views/app.rs index 67961ee..7079445 100644 --- a/crates/app/src/views/app.rs +++ b/crates/app/src/views/app.rs @@ -4,8 +4,9 @@ use serde::Deserialize; use std::sync::Arc; use ui::{ dock::{DockArea, DockItem, DockPlacement}, + indicator::Indicator, theme::Theme, - Root, TitleBar, + Root, Sizable, TitleBar, }; use super::{ @@ -143,10 +144,20 @@ impl Render for AppView { fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { let modal_layer = Root::render_modal_layer(cx); let notification_layer = Root::render_notification_layer(cx); + let state = cx.global::(); let mut content = div().size_full().flex().flex_col(); - if cx.global::().is_user_logged_in() { + if state.is_loading { + content = content.child(div()).child( + div() + .flex_1() + .flex() + .items_center() + .justify_center() + .child(Indicator::new().small()), + ) + } else if state.is_user_logged_in() { content = content .child( TitleBar::new() diff --git a/crates/app/src/views/onboarding.rs b/crates/app/src/views/onboarding/mod.rs similarity index 66% rename from crates/app/src/views/onboarding.rs rename to crates/app/src/views/onboarding/mod.rs index 29a2eeb..c39cc4a 100644 --- a/crates/app/src/views/onboarding.rs +++ b/crates/app/src/views/onboarding/mod.rs @@ -1,6 +1,4 @@ -use async_utility::task::spawn; use gpui::*; -use keyring::Entry; use nostr_sdk::prelude::*; use ui::{ input::{InputEvent, TextInput}, @@ -34,26 +32,30 @@ impl Onboarding { fn save_keys(content: &str, cx: &mut ViewContext) -> anyhow::Result<(), anyhow::Error> { let keys = Keys::parse(content)?; - let public_key = keys.public_key(); - let bech32 = public_key.to_bech32().unwrap(); + let bech32 = public_key.to_bech32()?; let secret = keys.secret_key().to_secret_hex(); - let entry = Entry::new(KEYRING_SERVICE, &bech32).unwrap(); + let mut async_cx = cx.to_async(); + let view_id = cx.entity_id(); - // Save secret key to keyring - entry.set_password(&secret)?; + cx.foreground_executor() + .spawn({ + let client = get_client(); + let task = cx.write_credentials(KEYRING_SERVICE, &bech32, secret.as_bytes()); - // Update signer - spawn(async move { - get_client().set_signer(keys).await; - }); - - // Update globals state - cx.update_global::(|state, cx| { - state.set_user(Some(public_key)); - cx.notify(); - }); + async move { + if task.await.is_ok() { + _ = client.set_signer(keys).await; + // Update global state + _ = async_cx.update_global::(|state, cx| { + state.set_user(Some(public_key)); + cx.notify(Some(view_id)); + }); + } + } + }) + .detach(); Ok(()) }