wip: refactor
This commit is contained in:
108
Cargo.lock
generated
108
Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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::<AccountRegistry, _>(|state, _cx| {
|
||||
state.set_user(Some(public_key));
|
||||
state.set_loading();
|
||||
});
|
||||
} else {
|
||||
_ = async_cx.update_global::<AccountRegistry, _>(|state, _| {
|
||||
state.set_loading();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
_ = async_cx.update_global::<AccountRegistry, _>(|state, _| {
|
||||
state.set_loading();
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
cx.spawn(|async_cx| async move {
|
||||
let (tx, rx) = smol::channel::unbounded::<Signal>();
|
||||
|
||||
@@ -227,12 +259,12 @@ async fn main() {
|
||||
|
||||
while let Ok(signal) = rx.recv().await {
|
||||
match signal {
|
||||
Signal::RecvEose(_) => {
|
||||
Signal::Eose => {
|
||||
_ = async_cx.update_global::<ChatRegistry, _>(|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);
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::{
|
||||
|
||||
pub struct AccountRegistry {
|
||||
public_key: Option<PublicKey>,
|
||||
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<PublicKey> {
|
||||
self.public_key
|
||||
}
|
||||
@@ -71,6 +76,9 @@ impl AccountRegistry {
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
Self { public_key: None }
|
||||
Self {
|
||||
public_key: None,
|
||||
is_loading: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Metadata>) {
|
||||
let mut seens = self.seens.lock().unwrap();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<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: Vec<PublicKey> = 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<Keys, anyhow::Error> {
|
||||
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<String> = public_keys
|
||||
.iter()
|
||||
|
||||
@@ -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<Self>) -> impl IntoElement {
|
||||
let modal_layer = Root::render_modal_layer(cx);
|
||||
let notification_layer = Root::render_notification_layer(cx);
|
||||
let state = cx.global::<AccountRegistry>();
|
||||
|
||||
let mut content = div().size_full().flex().flex_col();
|
||||
|
||||
if cx.global::<AccountRegistry>().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()
|
||||
|
||||
@@ -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<Self>) -> 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::<AccountRegistry, _>(|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::<AccountRegistry, _>(|state, cx| {
|
||||
state.set_user(Some(public_key));
|
||||
cx.notify(Some(view_id));
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user