refactor app state

This commit is contained in:
2024-11-24 15:17:35 +07:00
parent 17e7766401
commit db7e28a78a
12 changed files with 49 additions and 65 deletions

View File

@@ -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",
] }

View File

@@ -8,5 +8,3 @@ gpui.workspace = true
nostr-sdk.workspace = true
dirs.workspace = true
tokio.workspace = true
keyring-search.workspace = true
keyring.workspace = true

View File

@@ -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(())
}
}

View File

@@ -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<Client> = 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;

View File

@@ -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"] }

View File

@@ -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

View File

@@ -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<PublicKey>,
pub signer: Option<PublicKey>,
}
impl Global for AppState {}
impl AppState {
pub fn new() -> Self {
let accounts = get_all_accounts_from_keyring();
Self { accounts }
Self { signer: None }
}
}

View File

@@ -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<PublicKey> {
pub fn get_all_accounts_from_keyring() -> Vec<PublicKey> {
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<PublicKey> = list
let accounts: Vec<PublicKey> = list
.split_whitespace()
.filter(|v| v.starts_with("npub1") && !v.ends_with("coop"))
.filter_map(|i| PublicKey::from_bech32(i).ok())

View File

@@ -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<Self>) -> impl IntoElement {
let mut content = div().size_full().flex().items_center().justify_center();
if cx.global::<AppState>().accounts.is_empty() {
if cx.global::<AppState>().signer.is_none() {
content = content.child(self.onboarding.clone())
} else {
content = content.child(self.chat_space.clone())

View File

@@ -74,27 +74,11 @@ impl RenderOnce for Account {
}
}
pub struct BottomBar {
accounts: Vec<Account>,
}
pub struct BottomBar {}
impl BottomBar {
pub fn new(cx: &mut ViewContext<'_, Self>) -> BottomBar {
let state: Vec<PublicKey> = cx
.global::<AppState>()
.accounts
.clone()
.into_iter()
.collect();
let win_cx = cx.window_context();
let accounts = state
.into_iter()
.map(|pk| Account::new(pk, win_cx))
.collect::<Vec<_>>();
BottomBar { accounts }
BottomBar {}
}
}
@@ -108,6 +92,5 @@ impl Render for BottomBar {
.items_center()
.justify_center()
.gap_1()
.children(self.accounts.clone())
}
}

View File

@@ -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,

View File

@@ -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::<NostrClient>().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::<NostrClient>().add_account(keys).is_ok() {
cx.global_mut::<AppState>().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();