notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 98adb82e5689c4e803d8b01f8295568299e7af7d
parent 5619ae60ad42c974d87ed0b6afe2557078fbe98d
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 11 Dec 2022 18:34:43 -0800

receiving initial messages!

Diffstat:
Menostr/src/client/message.rs | 16+++++++---------
Menostr/src/client/mod.rs | 2++
Menostr/src/filter.rs | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Menostr/src/lib.rs | 5++++-
Menostr/src/relay/mod.rs | 10++++++++--
Menostr/src/relay/pool.rs | 12++++++------
Msrc/app.rs | 39+++++++++++++++++++++++++++++++++++----
7 files changed, 117 insertions(+), 22 deletions(-)

diff --git a/enostr/src/client/message.rs b/enostr/src/client/message.rs @@ -1,4 +1,5 @@ -use crate::{Event, Filter} +use crate::{Event, Filter}; +use serde_json::json; /// Messages sent by clients, received by relays #[derive(Debug, Eq, PartialEq)] @@ -16,8 +17,8 @@ pub enum ClientMessage { } impl ClientMessage { - pub fn event(ev: Event) -> Self { - ClientMessage::Event {ev} + pub fn event(event: Event) -> Self { + ClientMessage::Event { event } } pub fn req(sub_id: String, filters: Vec<Filter>) -> Self { @@ -31,11 +32,8 @@ impl ClientMessage { pub fn to_json(&self) -> String { match self { Self::Event { event } => json!(["EVENT", event]).to_string(), - Self::Req { - subscription_id, - filters, - } => { - let mut json = json!(["REQ", subscription_id]); + Self::Req { sub_id, filters } => { + let mut json = json!(["REQ", sub_id]); let mut filters = json!(filters); if let Some(json) = json.as_array_mut() { @@ -46,7 +44,7 @@ impl ClientMessage { json.to_string() } - Self::Close { subscription_id } => json!(["CLOSE", subscription_id]).to_string(), + Self::Close { sub_id } => json!(["CLOSE", sub_id]).to_string(), } } } diff --git a/enostr/src/client/mod.rs b/enostr/src/client/mod.rs @@ -1 +1,3 @@ mod message; + +pub use message::ClientMessage; diff --git a/enostr/src/filter.rs b/enostr/src/filter.rs @@ -21,3 +21,58 @@ pub struct Filter { #[serde(skip_serializing_if = "Option::is_none")] limit: Option<u16>, } + +impl Filter { + pub fn new() -> Filter { + Filter { + ids: None, + authors: None, + kinds: None, + events: None, + pubkeys: None, + since: None, + until: None, + limit: None, + } + } + + pub fn ids(mut self, ids: Vec<String>) -> Self { + self.ids = Some(ids); + self + } + + pub fn authors(mut self, authors: Vec<String>) -> Self { + self.authors = Some(authors); + self + } + + pub fn kinds(mut self, kinds: Vec<u64>) -> Self { + self.kinds = Some(kinds); + self + } + + pub fn events(mut self, events: Vec<String>) -> Self { + self.events = Some(events); + self + } + + pub fn pubkeys(mut self, pubkeys: Vec<String>) -> Self { + self.pubkeys = Some(pubkeys); + self + } + + pub fn since(mut self, since: u64) -> Self { + self.since = Some(since); + self + } + + pub fn until(mut self, until: u64) -> Self { + self.until = Some(until); + self + } + + pub fn limit(mut self, limit: u16) -> Self { + self.limit = Some(limit); + self + } +} diff --git a/enostr/src/lib.rs b/enostr/src/lib.rs @@ -1,12 +1,15 @@ +mod client; mod error; mod event; mod filter; mod relay; +pub use client::ClientMessage; pub use error::Error; pub use event::Event; pub use filter::Filter; -pub use relay::pool::RelayPool; +pub use relay::message::{RelayEvent, RelayMessage}; +pub use relay::pool::{PoolEvent, RelayPool}; pub use relay::Relay; pub type Result<T> = std::result::Result<T, error::Error>; diff --git a/enostr/src/relay/mod.rs b/enostr/src/relay/mod.rs @@ -1,6 +1,6 @@ -use ewebsock::{WsReceiver, WsSender}; +use ewebsock::{WsMessage, WsReceiver, WsSender}; -use crate::Result; +use crate::{ClientMessage, Filter, Result}; use std::fmt; use std::hash::{Hash, Hasher}; @@ -57,4 +57,10 @@ impl Relay { status, }) } + + pub fn subscribe(&mut self, subid: String, filters: Vec<Filter>) { + let cmd = ClientMessage::req(subid, filters); + let txt = WsMessage::Text(cmd.to_json()); + self.sender.send(txt); + } } diff --git a/enostr/src/relay/pool.rs b/enostr/src/relay/pool.rs @@ -4,13 +4,13 @@ use crate::Result; use tracing::error; #[derive(Debug)] -pub struct PoolMessage<'a> { - relay: &'a str, - event: RelayEvent, +pub struct PoolEvent<'a> { + pub relay: &'a str, + pub event: RelayEvent, } pub struct RelayPool { - relays: Vec<Relay>, + pub relays: Vec<Relay>, } impl Default for RelayPool { @@ -47,12 +47,12 @@ impl RelayPool { Ok(()) } - pub fn try_recv(&self) -> Option<PoolMessage<'_>> { + pub fn try_recv(&self) -> Option<PoolEvent<'_>> { for relay in &self.relays { if let Some(msg) = relay.receiver.try_recv() { match msg.try_into() { Ok(event) => { - return Some(PoolMessage { + return Some(PoolEvent { event, relay: &relay.url, }); diff --git a/src/app.rs b/src/app.rs @@ -2,6 +2,7 @@ //use egui_android::SimpleApp; use egui_extras::RetainedImage; +use enostr::{Filter, RelayEvent, RelayMessage}; //use nostr_rust::events::Event; use poll_promise::Promise; //use std::borrow::{Borrow, Cow}; @@ -9,7 +10,7 @@ use egui::Context; //use log::error; use std::collections::HashMap; use std::hash::Hash; -use tracing::{debug, error, info}; +use tracing::{debug, error, info, warn}; use enostr::{Event, RelayPool}; @@ -73,6 +74,34 @@ fn relay_setup(pool: &mut RelayPool, ctx: &egui::Context) { } } +fn send_initial_filters(pool: &mut RelayPool, relay_url: &str) { + let filter = Filter::new().limit(20).kinds(vec![1, 42]); + let subid = "initial"; + for relay in &mut pool.relays { + if relay.url == relay_url { + relay.subscribe(subid.to_string(), vec![filter]); + return; + } + } +} + +fn try_process_event(damus: &mut Damus) { + let m_ev = damus.pool.try_recv(); + if m_ev.is_none() { + return; + } + let ev = m_ev.unwrap(); + let relay = ev.relay.to_owned(); + + match &ev.event { + RelayEvent::Opened => send_initial_filters(&mut damus.pool, &relay), + RelayEvent::Closed => warn!("{} connection closed", &relay), /* TODO: handle reconnects */ + RelayEvent::Other(msg) => debug!("Other ws message: {:?}", msg), + RelayEvent::Message(msg) => process_message(damus, &msg), + } + //info!("recv {:?}", ev) +} + fn update_damus(damus: &mut Damus, ctx: &egui::Context) { if damus.state == DamusState::Initializing { damus.pool = RelayPool::new(); @@ -80,9 +109,11 @@ fn update_damus(damus: &mut Damus, ctx: &egui::Context) { damus.state = DamusState::Initialized; } - if let Some(ev) = damus.pool.try_recv() { - info!("recv {:?}", ev) - } + try_process_event(damus); +} + +fn process_message(damus: &mut Damus, msg: &RelayMessage) { + info!("process message {:?}", msg); } fn render_damus(damus: &mut Damus, ctx: &Context) {