relay connected!
This commit is contained in:
53
Cargo.lock
generated
53
Cargo.lock
generated
@@ -646,12 +646,12 @@ dependencies = [
|
||||
"egui_extras",
|
||||
"ehttp",
|
||||
"enostr",
|
||||
"ewebsock 0.2.0 (git+https://github.com/jb55/ewebsock.git?rev=93420aa96a990e7513647db775751a2dc9d4a1ba)",
|
||||
"image",
|
||||
"log",
|
||||
"poll-promise",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-wasm",
|
||||
@@ -918,10 +918,11 @@ dependencies = [
|
||||
name = "enostr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ewebsock 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ewebsock",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1000,24 +1001,6 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ewebsock"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/jb55/ewebsock.git?rev=93420aa96a990e7513647db775751a2dc9d4a1ba#93420aa96a990e7513647db775751a2dc9d4a1ba"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"tracing",
|
||||
"tungstenite",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "expat-sys"
|
||||
version = "2.1.6"
|
||||
@@ -2797,11 +2780,35 @@ dependencies = [
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.17.2"
|
||||
@@ -2810,8 +2817,12 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tungstenite",
|
||||
"webpki",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2917,10 +2928,12 @@ dependencies = [
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"rustls",
|
||||
"sha-1",
|
||||
"thiserror",
|
||||
"url",
|
||||
"utf-8",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -23,8 +23,6 @@ poll-promise = "0.2.0"
|
||||
serde_derive = "1"
|
||||
serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = "0.3"
|
||||
ewebsock = { git = "https://github.com/jb55/ewebsock.git", rev = "93420aa96a990e7513647db775751a2dc9d4a1ba" }
|
||||
#wasm-bindgen = "0.2.83"
|
||||
#wasm-bindgen-futures = "0.4"
|
||||
enostr = { path = "enostr" }
|
||||
@@ -35,6 +33,11 @@ enostr = { path = "enostr" }
|
||||
console_error_panic_hook = "0.1.6"
|
||||
tracing-wasm = "0.2"
|
||||
|
||||
# native:
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
tokio = { version = "1.16", features = ["macros", "rt-multi-thread"] }
|
||||
tracing-subscriber = "0.3"
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android_logger = "0.11.1"
|
||||
#android-activity = "0.4.0"
|
||||
|
||||
92
enostr/Cargo.lock
generated
92
enostr/Cargo.lock
generated
@@ -62,6 +62,12 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@@ -105,6 +111,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -404,12 +411,49 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.149"
|
||||
@@ -471,6 +515,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.105"
|
||||
@@ -533,6 +583,17 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.23.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.17.2"
|
||||
@@ -541,8 +602,12 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tungstenite",
|
||||
"webpki",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -590,10 +655,12 @@ dependencies = [
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"rustls",
|
||||
"sha-1",
|
||||
"thiserror",
|
||||
"url",
|
||||
"utf-8",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -623,6 +690,12 @@ dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
@@ -728,6 +801,25 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
||||
@@ -6,7 +6,8 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ewebsock = "0.2.0"
|
||||
ewebsock = { version = "0.2.0", features = ["tls"] }
|
||||
serde_derive = "1"
|
||||
serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence
|
||||
serde_json = "1.0.89"
|
||||
tracing = "0.1.37"
|
||||
|
||||
52
enostr/src/client/message.rs
Normal file
52
enostr/src/client/message.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use crate::{Event, Filter}
|
||||
|
||||
/// Messages sent by clients, received by relays
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum ClientMessage {
|
||||
Event {
|
||||
event: Event,
|
||||
},
|
||||
Req {
|
||||
sub_id: String,
|
||||
filters: Vec<Filter>,
|
||||
},
|
||||
Close {
|
||||
sub_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl ClientMessage {
|
||||
pub fn event(ev: Event) -> Self {
|
||||
ClientMessage::Event {ev}
|
||||
}
|
||||
|
||||
pub fn req(sub_id: String, filters: Vec<Filter>) -> Self {
|
||||
ClientMessage::Req { sub_id, filters }
|
||||
}
|
||||
|
||||
pub fn close(sub_id: String) -> Self {
|
||||
ClientMessage::Close { sub_id }
|
||||
}
|
||||
|
||||
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]);
|
||||
let mut filters = json!(filters);
|
||||
|
||||
if let Some(json) = json.as_array_mut() {
|
||||
if let Some(filters) = filters.as_array_mut() {
|
||||
json.append(filters);
|
||||
}
|
||||
}
|
||||
|
||||
json.to_string()
|
||||
}
|
||||
Self::Close { subscription_id } => json!(["CLOSE", subscription_id]).to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
1
enostr/src/client/mod.rs
Normal file
1
enostr/src/client/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
mod message;
|
||||
23
enostr/src/filter.rs
Normal file
23
enostr/src/filter.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Filter {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
ids: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
authors: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
kinds: Option<Vec<u64>>,
|
||||
#[serde(rename = "#e")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
events: Option<Vec<String>>,
|
||||
#[serde(rename = "#p")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pubkeys: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
since: Option<u64>, // unix timestamp seconds
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
until: Option<u64>, // unix timestamp seconds
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
limit: Option<u16>,
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
mod error;
|
||||
mod event;
|
||||
mod filter;
|
||||
mod relay;
|
||||
|
||||
pub use error::Error;
|
||||
pub use event::Event;
|
||||
pub use filter::Filter;
|
||||
pub use relay::pool::RelayPool;
|
||||
pub use relay::Relay;
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ impl PartialEq for Relay {
|
||||
impl Eq for Relay {}
|
||||
|
||||
impl Relay {
|
||||
pub fn new(url: String) -> Result<Self> {
|
||||
pub fn new(url: String, wakeup: impl Fn() + Send + Sync + 'static) -> Result<Self> {
|
||||
let status = RelayStatus::Connecting;
|
||||
let (sender, receiver) = ewebsock::connect(&url)?;
|
||||
let (sender, receiver) = ewebsock::connect_with_wakeup(&url, wakeup)?;
|
||||
|
||||
Ok(Self {
|
||||
url,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::relay::message::RelayEvent;
|
||||
use crate::relay::Relay;
|
||||
use crate::Result;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PoolMessage<'a> {
|
||||
@@ -20,8 +21,8 @@ impl Default for RelayPool {
|
||||
|
||||
impl RelayPool {
|
||||
// Constructs a new, empty RelayPool.
|
||||
pub fn new(relays: Vec<Relay>) -> RelayPool {
|
||||
RelayPool { relays: relays }
|
||||
pub fn new() -> RelayPool {
|
||||
RelayPool { relays: vec![] }
|
||||
}
|
||||
|
||||
pub fn has(&self, url: &str) -> bool {
|
||||
@@ -34,8 +35,12 @@ impl RelayPool {
|
||||
}
|
||||
|
||||
// Adds a websocket url to the RelayPool.
|
||||
pub fn add_url(&mut self, url: String) -> Result<()> {
|
||||
let relay = Relay::new(url)?;
|
||||
pub fn add_url(
|
||||
&mut self,
|
||||
url: String,
|
||||
wakeup: impl Fn() + Send + Sync + 'static,
|
||||
) -> Result<()> {
|
||||
let relay = Relay::new(url, wakeup)?;
|
||||
|
||||
self.relays.push(relay);
|
||||
|
||||
@@ -45,12 +50,18 @@ impl RelayPool {
|
||||
pub fn try_recv(&self) -> Option<PoolMessage<'_>> {
|
||||
for relay in &self.relays {
|
||||
if let Some(msg) = relay.receiver.try_recv() {
|
||||
if let Ok(event) = msg.try_into() {
|
||||
let pmsg = PoolMessage {
|
||||
event,
|
||||
relay: &relay.url,
|
||||
};
|
||||
return Some(pmsg);
|
||||
match msg.try_into() {
|
||||
Ok(event) => {
|
||||
return Some(PoolMessage {
|
||||
event,
|
||||
relay: &relay.url,
|
||||
});
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
error!("{:?}", e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
48
src/app.rs
48
src/app.rs
@@ -6,10 +6,10 @@ use egui_extras::RetainedImage;
|
||||
use poll_promise::Promise;
|
||||
//use std::borrow::{Borrow, Cow};
|
||||
use egui::Context;
|
||||
use log::error;
|
||||
//use log::error;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
use tracing::debug;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
use enostr::{Event, RelayPool};
|
||||
|
||||
@@ -21,28 +21,26 @@ enum UrlKey<'a> {
|
||||
|
||||
type ImageCache<'a> = HashMap<UrlKey<'a>, Promise<ehttp::Result<RetainedImage>>>;
|
||||
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
pub enum DamusState {
|
||||
Initializing,
|
||||
Initialized,
|
||||
}
|
||||
|
||||
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
#[serde(default)] // if we add new fields, give them default values when deserializing old state
|
||||
pub struct Damus<'a> {
|
||||
// Example stuff:
|
||||
label: String,
|
||||
|
||||
state: DamusState,
|
||||
composing: bool,
|
||||
|
||||
n_panels: u32,
|
||||
|
||||
#[serde(skip)]
|
||||
pool: RelayPool,
|
||||
|
||||
#[serde(skip)]
|
||||
events: Vec<Event>,
|
||||
|
||||
#[serde(skip)]
|
||||
img_cache: ImageCache<'a>,
|
||||
|
||||
// this how you opt-out of serialization of a member
|
||||
#[serde(skip)]
|
||||
value: f32,
|
||||
}
|
||||
|
||||
@@ -51,6 +49,7 @@ impl Default for Damus<'_> {
|
||||
Self {
|
||||
// Example stuff:
|
||||
label: "Hello World!".to_owned(),
|
||||
state: DamusState::Initializing,
|
||||
composing: false,
|
||||
pool: RelayPool::default(),
|
||||
events: vec![],
|
||||
@@ -66,8 +65,24 @@ pub fn is_mobile(ctx: &egui::Context) -> bool {
|
||||
screen_size.x < 550.0
|
||||
}
|
||||
|
||||
fn damus_update(damus: &mut Damus, ctx: &Context) {
|
||||
render_damus(damus, ctx);
|
||||
fn relay_setup(pool: &mut RelayPool, ctx: &egui::Context) {
|
||||
let ctx = ctx.clone();
|
||||
let wakeup = move || ctx.request_repaint();
|
||||
if let Err(e) = pool.add_url("wss://relay.damus.io".to_string(), wakeup) {
|
||||
error!("{:?}", e)
|
||||
}
|
||||
}
|
||||
|
||||
fn update_damus(damus: &mut Damus, ctx: &egui::Context) {
|
||||
if damus.state == DamusState::Initializing {
|
||||
damus.pool = RelayPool::new();
|
||||
relay_setup(&mut damus.pool, ctx);
|
||||
damus.state = DamusState::Initialized;
|
||||
}
|
||||
|
||||
if let Some(ev) = damus.pool.try_recv() {
|
||||
info!("recv {:?}", ev)
|
||||
}
|
||||
}
|
||||
|
||||
fn render_damus(damus: &mut Damus, ctx: &Context) {
|
||||
@@ -94,9 +109,7 @@ impl Damus<'_> {
|
||||
//return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
|
||||
//}
|
||||
|
||||
let mut d: Self = Default::default();
|
||||
d.add_test_events();
|
||||
d
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +361,8 @@ impl eframe::App for Damus<'_> {
|
||||
/// Called each time the UI needs repainting, which may be many times per second.
|
||||
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
damus_update(self, ctx);
|
||||
update_damus(self, ctx);
|
||||
render_damus(self, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ use eframe;
|
||||
|
||||
// Desktop
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn main() {
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Log to stdout (if you run with `RUST_LOG=debug`).
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user