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

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