refactor: sync based on interval not window event

This commit is contained in:
reya 2024-11-04 09:40:33 +07:00
parent efd3c83193
commit bd1f2b899d
5 changed files with 111 additions and 112 deletions

16
src-tauri/Cargo.lock generated
View File

@ -3480,7 +3480,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]] [[package]]
name = "nostr" name = "nostr"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"aes", "aes",
"async-trait", "async-trait",
@ -3511,7 +3511,7 @@ dependencies = [
[[package]] [[package]]
name = "nostr-connect" name = "nostr-connect"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"async-utility", "async-utility",
@ -3525,7 +3525,7 @@ dependencies = [
[[package]] [[package]]
name = "nostr-database" name = "nostr-database"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"flatbuffers", "flatbuffers",
@ -3539,7 +3539,7 @@ dependencies = [
[[package]] [[package]]
name = "nostr-lmdb" name = "nostr-lmdb"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"heed", "heed",
"nostr", "nostr",
@ -3552,7 +3552,7 @@ dependencies = [
[[package]] [[package]]
name = "nostr-relay-pool" name = "nostr-relay-pool"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"async-utility", "async-utility",
"async-wsocket", "async-wsocket",
@ -3570,7 +3570,7 @@ dependencies = [
[[package]] [[package]]
name = "nostr-sdk" name = "nostr-sdk"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"async-utility", "async-utility",
"atomic-destructor", "atomic-destructor",
@ -3589,7 +3589,7 @@ dependencies = [
[[package]] [[package]]
name = "nostr-zapper" name = "nostr-zapper"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"nostr", "nostr",
@ -3733,7 +3733,7 @@ dependencies = [
[[package]] [[package]]
name = "nwc" name = "nwc"
version = "0.35.0" version = "0.35.0"
source = "git+https://github.com/rust-nostr/nostr#497c72f5a255c3d0cdf2a837e85c24be3d162fc0" source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"async-utility", "async-utility",

BIN
src-tauri/icons/tray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

View File

@ -30,7 +30,6 @@ pub mod common;
pub struct Nostr { pub struct Nostr {
client: Client, client: Client,
queue: RwLock<HashSet<PublicKey>>, queue: RwLock<HashSet<PublicKey>>,
is_syncing: RwLock<bool>,
settings: RwLock<Settings>, settings: RwLock<Settings>,
} }
@ -68,7 +67,7 @@ pub const QUEUE_DELAY: u64 = 300;
pub const NOTIFICATION_SUB_ID: &str = "lume_notification"; pub const NOTIFICATION_SUB_ID: &str = "lume_notification";
fn main() { fn main() {
tracing_subscriber::fmt::init(); // tracing_subscriber::fmt::init();
let builder = Builder::<tauri::Wry>::new().commands(collect_commands![ let builder = Builder::<tauri::Wry>::new().commands(collect_commands![
get_relays, get_relays,
@ -231,110 +230,9 @@ fn main() {
app.manage(Nostr { app.manage(Nostr {
client, client,
queue: RwLock::new(HashSet::new()), queue: RwLock::new(HashSet::new()),
is_syncing: RwLock::new(false),
settings: RwLock::new(Settings::default()), 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::<Nostr>();
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<PublicKey> = 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<PublicKey> = events
.iter()
.flat_map(|ev| ev.tags.public_keys().copied())
.collect();
let pk_vec: Vec<PublicKey> = 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 // Listen for request metadata
app.listen_any("request_metadata", move |event| { app.listen_any("request_metadata", move |event| {
let payload = event.payload(); 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::<Nostr>();
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<PublicKey> = 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<PublicKey> = events
.iter()
.flat_map(|ev| ev.tags.public_keys().copied())
.collect();
// Convert to vector
let public_keys: Vec<PublicKey> = 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 { tauri::async_runtime::spawn(async move {
let state = handle_clone.state::<Nostr>(); let state = handle_clone.state::<Nostr>();
let client = &state.client; let client = &state.client;

View File

@ -30,6 +30,13 @@
"$RESOURCE/*" "$RESOURCE/*"
] ]
} }
},
"trayIcon": {
"id": "main",
"iconAsTemplate": true,
"menuOnLeftClick": true,
"tooltip": "Lume",
"iconPath": "./icons/tray.png"
} }
}, },
"bundle": { "bundle": {

BIN
tray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB