diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 69904299..9014722a 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3480,7 +3480,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "nostr" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "aes", "async-trait", @@ -3511,7 +3511,7 @@ dependencies = [ [[package]] name = "nostr-connect" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "async-trait", "async-utility", @@ -3525,7 +3525,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "async-trait", "flatbuffers", @@ -3539,7 +3539,7 @@ dependencies = [ [[package]] name = "nostr-lmdb" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "heed", "nostr", @@ -3552,7 +3552,7 @@ dependencies = [ [[package]] name = "nostr-relay-pool" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "async-utility", "async-wsocket", @@ -3570,7 +3570,7 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "async-utility", "atomic-destructor", @@ -3589,7 +3589,7 @@ dependencies = [ [[package]] name = "nostr-zapper" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "async-trait", "nostr", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "nwc" version = "0.35.0" -source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" +source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b" dependencies = [ "async-trait", "async-utility", diff --git a/src-tauri/icons/tray.png b/src-tauri/icons/tray.png new file mode 100644 index 00000000..a96645bf Binary files /dev/null and b/src-tauri/icons/tray.png differ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index e9187331..348227e6 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -30,7 +30,6 @@ pub mod common; pub struct Nostr { client: Client, queue: RwLock>, - is_syncing: RwLock, settings: RwLock, } @@ -68,7 +67,7 @@ pub const QUEUE_DELAY: u64 = 300; pub const NOTIFICATION_SUB_ID: &str = "lume_notification"; fn main() { - tracing_subscriber::fmt::init(); + // tracing_subscriber::fmt::init(); let builder = Builder::::new().commands(collect_commands![ get_relays, @@ -231,110 +230,9 @@ fn main() { app.manage(Nostr { client, queue: RwLock::new(HashSet::new()), - is_syncing: RwLock::new(false), settings: RwLock::new(Settings::default()), }); - // Trigger some actions for window events - main_window.on_window_event(move |event| match event { - tauri::WindowEvent::Focused(focused) => { - if !focused { - let handle = handle_clone_event.clone(); - - tauri::async_runtime::spawn(async move { - let state = handle.state::(); - let client = &state.client; - - if *state.is_syncing.read().await { - return; - } - - let mut is_syncing = state.is_syncing.write().await; - - // Mark sync in progress - *is_syncing = true; - - let opts = SyncOptions::default(); - let accounts = get_all_accounts(); - - if !accounts.is_empty() { - let public_keys: Vec = accounts - .iter() - .filter_map(|acc| PublicKey::from_str(acc).ok()) - .collect(); - - let filter = Filter::new().pubkeys(public_keys).kinds(vec![ - Kind::TextNote, - Kind::Repost, - Kind::Reaction, - Kind::ZapReceipt, - ]); - - if let Ok(output) = client.sync(filter, &opts).await { - println!("Received: {}", output.received.len()) - } - } - - let filter = Filter::new().kinds(vec![ - Kind::TextNote, - Kind::Repost, - Kind::ContactList, - Kind::FollowSet, - ]); - - // Get all public keys in database - if let Ok(events) = client.database().query(vec![filter]).await { - let public_keys: HashSet = events - .iter() - .flat_map(|ev| ev.tags.public_keys().copied()) - .collect(); - let pk_vec: Vec = public_keys.into_iter().collect(); - - for chunk in pk_vec.chunks(500) { - if chunk.is_empty() { - return; - } - - let authors = chunk.to_owned(); - - let filter = Filter::new() - .authors(authors.clone()) - .kinds(vec![ - Kind::Metadata, - Kind::FollowSet, - Kind::Interests, - Kind::InterestSet, - ]) - .limit(1000); - - if let Ok(output) = client.sync(filter, &opts).await { - println!("Received: {}", output.received.len()) - } - - let filter = Filter::new() - .authors(authors) - .kinds(vec![ - Kind::TextNote, - Kind::Repost, - Kind::EventDeletion, - ]) - .limit(500); - - if let Ok(output) = client.sync(filter, &opts).await { - println!("Received: {}", output.received.len()) - } - } - } - - // Mark sync is done - *is_syncing = false; - }); - } - } - tauri::WindowEvent::Moved(_size) => {} - _ => {} - }); - // Listen for request metadata app.listen_any("request_metadata", move |event| { let payload = event.payload(); @@ -379,7 +277,101 @@ fn main() { }); }); - // Run notification thread + // Run a thread for negentropy + tauri::async_runtime::spawn(async move { + let state = handle_clone_event.state::(); + let client = &state.client; + + // Use default sync options + let opts = SyncOptions::default(); + + // Set interval + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(600)); + + loop { + interval.tick().await; + + let accounts = get_all_accounts(); + let public_keys: Vec = accounts + .iter() + .filter_map(|acc| PublicKey::from_str(acc).ok()) + .collect(); + + if !public_keys.is_empty() { + // Create filter for notification + // + let filter = Filter::new().pubkeys(public_keys.clone()).kinds(vec![ + Kind::TextNote, + Kind::Repost, + Kind::Reaction, + Kind::ZapReceipt, + ]); + + // Sync notification + // + if let Ok(output) = client.sync(filter, &opts).await { + println!("Received: {}", output.received.len()) + } + + // Create filter for contact list + // + let filter = Filter::new() + .authors(public_keys) + .kinds(vec![Kind::ContactList, Kind::FollowSet]); + + // Sync events for contact list + // + if let Ok(events) = client.database().query(vec![filter]).await { + // Get unique public keys + let public_keys: HashSet = events + .iter() + .flat_map(|ev| ev.tags.public_keys().copied()) + .collect(); + + // Convert to vector + let public_keys: Vec = public_keys.into_iter().collect(); + + for chunk in public_keys.chunks(1000) { + if chunk.is_empty() { + return; + } + + let authors = chunk.to_owned(); + + // Create filter for metadata + // + let filter = Filter::new().authors(authors.clone()).kinds(vec![ + Kind::Metadata, + Kind::FollowSet, + Kind::Interests, + Kind::InterestSet, + ]); + + // Sync metadata + // + if let Ok(output) = client.sync(filter, &opts).await { + println!("Received: {}", output.received.len()) + } + + // Create filter for text note + // + let filter = Filter::new() + .authors(authors) + .kinds(vec![Kind::TextNote, Kind::Repost, Kind::EventDeletion]) + .limit(100); + + // Sync text note + // + if let Ok(output) = client.sync(filter, &opts).await { + println!("Received: {}", output.received.len()) + } + } + } + } + } + }); + + // Run a thread for handle notification tauri::async_runtime::spawn(async move { let state = handle_clone.state::(); let client = &state.client; diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 59db9e07..f2f0aecf 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -30,6 +30,13 @@ "$RESOURCE/*" ] } + }, + "trayIcon": { + "id": "main", + "iconAsTemplate": true, + "menuOnLeftClick": true, + "tooltip": "Lume", + "iconPath": "./icons/tray.png" } }, "bundle": { diff --git a/tray.png b/tray.png new file mode 100644 index 00000000..b9102bbe Binary files /dev/null and b/tray.png differ