basic relay connections.

This commit is contained in:
Jack Chakany 2024-06-27 21:22:08 -04:00
parent f284f86b5b
commit 18458f99eb
6 changed files with 340 additions and 112 deletions

210
Cargo.lock generated
View file

@ -542,6 +542,9 @@ name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
dependencies = [
"serde",
]
[[package]]
name = "bitstream-io"
@ -961,6 +964,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
[[package]]
name = "data-encoding"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]]
name = "data-url"
version = "0.3.1"
@ -997,6 +1006,27 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "directories-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "dispatch"
version = "0.2.0"
@ -1045,6 +1075,7 @@ checksum = "020e2ccef6bbcec71dbc542f7eed64a5846fc3076727f5746da8fd307c91bab2"
dependencies = [
"bytemuck",
"cocoa",
"directories-next",
"document-features",
"egui",
"egui-wgpu",
@ -1062,6 +1093,8 @@ dependencies = [
"puffin",
"raw-window-handle 0.5.2",
"raw-window-handle 0.6.1",
"ron",
"serde",
"static_assertions",
"thiserror",
"wasm-bindgen",
@ -1084,6 +1117,7 @@ dependencies = [
"log",
"nohash-hasher",
"puffin",
"ron",
"serde",
]
@ -1118,6 +1152,7 @@ dependencies = [
"log",
"puffin",
"raw-window-handle 0.6.1",
"serde",
"smithay-clipboard",
"web-time",
"webbrowser",
@ -1326,6 +1361,21 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "ewebsock"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bbed098b2bf9abcfe50eeaa01ae77a2a1da931bdcd83d23fcd7b8f941cd52c9"
dependencies = [
"document-features",
"js-sys",
"log",
"tungstenite",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "exr"
version = "1.72.0"
@ -1391,6 +1441,12 @@ dependencies = [
"spin",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.5.0"
@ -1750,6 +1806,7 @@ version = "0.1.0"
dependencies = [
"eframe",
"egui_extras",
"ewebsock",
"image 0.25.1",
"puffin",
"puffin_http",
@ -1758,6 +1815,23 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "httparse"
version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]]
name = "icrate"
version = "0.0.4"
@ -2025,6 +2099,16 @@ dependencies = [
"redox_syscall 0.4.1",
]
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.5.0",
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
@ -2452,7 +2536,7 @@ version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
dependencies = [
"libredox",
"libredox 0.0.2",
]
[[package]]
@ -2863,6 +2947,17 @@ dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_users"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
dependencies = [
"getrandom",
"libredox 0.1.3",
"thiserror",
]
[[package]]
name = "regex"
version = "1.10.4"
@ -2921,6 +3016,33 @@ dependencies = [
"bytemuck",
]
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "ron"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
"base64",
"bitflags 2.5.0",
"serde",
"serde_derive",
]
[[package]]
name = "roxmltree"
version = "0.19.0"
@ -2960,6 +3082,37 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
dependencies = [
"log",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.102.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "same-file"
version = "1.0.6"
@ -3205,6 +3358,12 @@ dependencies = [
"float-cmp",
]
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "svgtypes"
version = "0.13.0"
@ -3521,6 +3680,28 @@ version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
[[package]]
name = "tungstenite"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http",
"httparse",
"log",
"rand",
"rustls",
"rustls-pki-types",
"sha1",
"thiserror",
"url",
"utf-8",
"webpki-roots",
]
[[package]]
name = "type-map"
version = "0.5.0"
@ -3595,6 +3776,12 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.0"
@ -3650,6 +3837,12 @@ dependencies = [
"tiny-skia-path",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "v_frame"
version = "0.3.8"
@ -3913,6 +4106,15 @@ dependencies = [
"web-sys",
]
[[package]]
name = "webpki-roots"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "weezl"
version = "0.1.8"
@ -4547,6 +4749,12 @@ dependencies = [
"syn 2.0.60",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]]
name = "zune-core"
version = "0.4.12"

View file

@ -5,17 +5,20 @@ authors = ["Jack Chakany <jack@chakany.systems>"]
edition = "2021"
publish = false
[features]
profiling = ["dep:puffin", "dep:puffin_http", "eframe/puffin", "egui_extras/puffin"]
[dependencies]
eframe = { version = "0.27.2", features = ["default", "puffin"] }
eframe = { version = "0.27.2", features = ["default", "persistence"] }
egui_extras = { version = "0.27.2", features = [
"file",
"image",
"svg",
"puffin",
] }
image = { version = "0.25.1", features = ["jpeg", "png"] }
tracing = "0.1.40"
tracing-appender = "0.2.3"
tracing-subscriber = "0.3.18"
puffin = "0.19.0"
puffin_http = "0.16.0"
puffin = { version = "0.19.0", optional = true }
puffin_http = { version = "0.16.0", optional = true }
ewebsock = { version = "0.6.0", features = ["tls"] }

2
Makefile Normal file
View file

@ -0,0 +1,2 @@
dev:
cargo run --features profiling

View file

@ -7,6 +7,9 @@ use egui::{Align, FontId, Layout};
use egui_extras::{Column, TableBuilder};
use tracing::{debug, error, info, Level};
mod relay;
mod pool;
fn main() -> Result<(), eframe::Error> {
let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout()); // add log files in prod one day
tracing_subscriber::fmt()
@ -14,6 +17,7 @@ fn main() -> Result<(), eframe::Error> {
.with_max_level(Level::DEBUG)
.init();
#[cfg(feature = "profiling")]
start_puffin_server();
let options = eframe::NativeOptions {
@ -40,7 +44,7 @@ fn main() -> Result<(), eframe::Error> {
let _ = &cc
.egui_ctx
.style_mut(|style| style.visuals.dark_mode = false);
Box::<Hoot>::default()
Box::new(Hoot::new(cc))
}),
)
}
@ -59,6 +63,7 @@ struct Hoot {
current_page: Page,
focused_post: String,
status: HootStatus,
relays: pool::RelayPool,
}
#[derive(Debug, PartialEq)]
@ -67,18 +72,45 @@ enum HootStatus {
Ready,
}
impl Default for Hoot {
fn default() -> Self {
Self::new()
fn update_app(app: &mut Hoot, ctx: &egui::Context) {
#[cfg(feature = "profiling")]
puffin::profile_function!();
if app.status == HootStatus::Initalizing {
let ctx = ctx.clone();
let wake_up = move || {
ctx.request_repaint();
};
app.relays.add_url("wss://relay.damus.io".to_string(), wake_up);
app.status = HootStatus::Ready;
}
app.relays.try_recv();
}
fn render_app(ctx: &egui::Context) {
#[cfg(feature = "profiling")]
puffin::profile_function!();
egui::SidePanel::left("Side Navbar").show(ctx, |ui| {
ui.heading("Hoot");
});
egui::TopBottomPanel::top("Search").show(ctx, |ui| {
ui.heading("Search");
});
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("hello there!");
});
}
impl Hoot {
fn new() -> Self {
fn new(cc: &eframe::CreationContext<'_>) -> Self {
Self {
current_page: Page::Inbox,
focused_post: "".into(),
status: HootStatus::Initalizing,
relays: pool::RelayPool::new(),
}
}
}
@ -93,110 +125,12 @@ impl eframe::App for Hoot {
HootStatus::Ready => {},
}
egui::SidePanel::left("sidebar").show(ctx, |ui| {
ui.heading("Hoot");
ui.vertical(|ui| {
ui.style_mut()
.text_styles
.insert(Button, FontId::new(20.0, Proportional));
ui.selectable_value(&mut self.current_page, Page::Inbox, "Inbox");
ui.selectable_value(&mut self.current_page, Page::Drafts, "Drafts");
ui.selectable_value(&mut self.current_page, Page::Starred, "Starred");
ui.selectable_value(&mut self.current_page, Page::Archived, "Archived");
ui.selectable_value(&mut self.current_page, Page::Trash, "Trash");
ui.with_layout(Layout::bottom_up(Align::LEFT), |ui| {
ui.label("Loading...");
ui.label("Loading...");
ui.separator();
});
});
});
egui::TopBottomPanel::top("search").show(ctx, |ui| {
ui.heading("Search");
});
egui::CentralPanel::default().show(ctx, |ui| match self.current_page {
Page::Inbox => {
ui.horizontal(|ui| {
ui.checkbox(&mut false, "");
ui.heading("Inbox");
});
TableBuilder::new(ui)
.column(Column::auto())
.column(Column::auto())
.column(Column::remainder())
.column(Column::remainder())
.column(Column::remainder())
.striped(true)
.auto_shrink(Vec2b { x: false, y: false })
.sense(Sense::click())
.header(20.0, |_header| {})
.body(|mut body| {
puffin::profile_scope!("table rendering");
body.row(30.0, |mut row| {
row.col(|ui| {
ui.checkbox(&mut false, "");
});
row.col(|ui| {
ui.checkbox(&mut false, "");
});
row.col(|ui| {
ui.label("Jack Chakany");
});
row.col(|ui| {
ui.label("Hello! Just checking in...");
});
row.col(|ui| {
ui.label("5 min ago");
});
if row.response().clicked() {
self.current_page = Page::Post;
}
});
body.row(30.0, |mut row| {
row.col(|ui| {
ui.checkbox(&mut false, "");
});
row.col(|ui| {
ui.checkbox(&mut false, "");
});
row.col(|ui| {
ui.label("Karnage");
});
row.col(|ui| {
ui.label("New designs!");
});
row.col(|ui| {
ui.label("10 min ago");
});
if row.response().clicked() {
self.current_page = Page::Post;
}
});
});
}
Page::Drafts => {
ui.heading("Drafts");
}
Page::Starred => {
ui.heading("Starred");
}
Page::Archived => {
ui.heading("Archived");
}
Page::Trash => {
ui.heading("Trash");
}
Page::Post => {
// used for viewing messages duh
ui.heading("Message");
ui.label(format!("{}", self.focused_post));
}
});
update_app(self, ctx);
render_app(ctx);
}
}
#[cfg(feature = "profiling")]
fn start_puffin_server() {
puffin::set_scopes_on(true); // tell puffin to collect data

30
src/pool.rs Normal file
View file

@ -0,0 +1,30 @@
use std::collections::HashMap;
use crate::relay::{Relay, RelayStatus};
pub struct RelayPool {
relays: HashMap<String, Relay>
}
impl RelayPool {
pub fn new() -> Self {
Self {
relays: HashMap::new(),
}
}
pub fn add_url(&mut self, url: String, wake_up: impl Fn() + Send + Sync + 'static) {
let relay = Relay::new_with_wakeup(url.clone(), wake_up);
self.relays.insert(url, relay);
}
pub fn try_recv(&mut self) -> Option<ewebsock::WsMessage> {
for relay in &mut self.relays {
if let Some(message) = relay.1.try_recv() {
return Some(message);
}
}
return None;
}
}

51
src/relay.rs Normal file
View file

@ -0,0 +1,51 @@
use ewebsock::{WsEvent};
use tracing::{error, info};
pub enum RelayStatus {
Connecting,
Connected,
Disconnected,
}
pub struct Relay {
url: String,
reader: ewebsock::WsReceiver,
writer: ewebsock::WsSender,
status: RelayStatus,
}
impl Relay {
pub fn new_with_wakeup(url: impl Into<String>, wake_up: impl Fn() + Send + Sync + 'static) -> Self {
let new_url: String = url.into();
let (mut sender, reciever) = ewebsock::connect_with_wakeup(new_url.clone(), ewebsock::Options::default(), wake_up).unwrap();
Self {
url: new_url,
reader: reciever,
writer: sender,
status: RelayStatus::Connected,
}
}
pub fn try_recv(&mut self) -> Option<ewebsock::WsMessage> {
if let Some(event) = self.reader.try_recv() {
match event {
WsEvent::Message(message) => {
return Some(message);
},
WsEvent::Opened => {
self.status = RelayStatus::Connected;
},
WsEvent::Error(error) => {
error!("error in websocket connection to {}: {}", self.url, error);
},
WsEvent::Closed => {
info!("connection to {} closed", self.url);
self.status = RelayStatus::Disconnected;
}
}
}
return None;
}
}