diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index 319d660..8f49902 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs @@ -1,9 +1,9 @@ #![feature(async_fn_traits)] #![windows_subsystem = "windows"] -use crate::data::ClientData; +use crate::{data::ClientData, session::Session}; use iris::prelude::*; -use openworm::net::{ServerMsg, install_crypto_provider}; +use openworm::net::install_crypto_provider; use winit::{ event::{ElementState, MouseButton, WindowEvent}, window::WindowAttributes, @@ -26,14 +26,13 @@ pub struct Client { data: ClientData, main_ui: WeakWidget, notif: WeakWidget, + sessions: Vec, } pub type Rsc = DefaultRsc; pub type ClientSender = EventSender; pub enum ClientEvent { - CacheUpdate, - ServerMsg(ServerMsg), Err(String), } @@ -62,6 +61,7 @@ impl DefaultAppState for Client { ui::start(rsc, &data).set_ptr(main_ui, rsc); Self { + sessions: Default::default(), ui_state, data, main_ui, @@ -76,11 +76,9 @@ impl DefaultAppState for Client { _render: &mut UiRenderState, ) { match event { - ClientEvent::ServerMsg(_) => {} ClientEvent::Err(msg) => { rsc[self.notif].inner = Some(ui::werror(&msg, rsc)); } - ClientEvent::CacheUpdate => {} } } diff --git a/src/bin/client/net.rs b/src/bin/client/net.rs index dddb698..77faf18 100644 --- a/src/bin/client/net.rs +++ b/src/bin/client/net.rs @@ -1,4 +1,4 @@ -use crate::{Client, ClientSender, Rsc}; +use crate::{Client, ClientEvent, ClientSender, Rsc, session::Session}; use dashmap::DashMap; use iris::prelude::DefaultRsc; use openworm::net::{ @@ -166,7 +166,7 @@ async fn connection_no_cert(addr: SocketAddr) -> NetResult<(Endpoint, Connection impl NetHandle { pub async fn connect( - msg: impl MsgHandler, + id: usize, info: ConnectInfo, event_sender: ClientSender, ) -> Result { @@ -184,7 +184,7 @@ impl NetHandle { let mut req_id = RequestId::first(); let recv = Arc::new(ServerRecv { - msg, + id, requests_sync: DashMap::default(), requests: DashMap::default(), event_sender: event_sender.clone(), @@ -251,14 +251,14 @@ where } } -struct ServerRecv { +struct ServerRecv { requests: DashMap>, requests_sync: DashMap, event_sender: ClientSender, - msg: F, + id: usize, } -impl RecvHandler for ServerRecv { +impl RecvHandler for ServerRecv { async fn msg(&self, resp: ServerMsgInst) { if let Some(id) = resp.id { if let Some((_, send)) = self.requests.remove(&id) { @@ -267,7 +267,7 @@ impl RecvHandler for ServerRecv { self.event_sender.run(|rsc| f(resp.msg, rsc)); } } else { - self.msg.run(resp.msg).await; + Session::handle(&self.event_sender, self.id, resp); } } } diff --git a/src/bin/client/session.rs b/src/bin/client/session.rs index fe5ca50..65679b1 100644 --- a/src/bin/client/session.rs +++ b/src/bin/client/session.rs @@ -1,9 +1,9 @@ use std::sync::{Arc, Mutex, MutexGuard}; use iris::prelude::*; -use openworm::net::UserId; +use openworm::net::{ServerMsgInst, UserId}; -use crate::{Rsc, net::NetHandle, ui::UserCache}; +use crate::{ClientSender, Rsc, net::NetHandle, ui::UserCache}; // TODO: this really should not be async... // I mean it could be used async but all widgets @@ -38,4 +38,12 @@ impl Session { let span = Span::empty(Dir::DOWN).add(rsc); span } + + pub fn handle(sender: &ClientSender, id: usize, inst: ServerMsgInst) { + match inst.msg { + _ => { + println!("Unknown server message recieved"); + } + } + } } diff --git a/src/bin/client/ui/channel.rs b/src/bin/client/ui/channel.rs index 64154e6..fceca04 100644 --- a/src/bin/client/ui/channel.rs +++ b/src/bin/client/ui/channel.rs @@ -1,12 +1,28 @@ +use openworm::net::CreateChannel; + use super::*; -pub fn view(rsc: &mut Rsc) -> StrongWidget { +pub fn view(rsc: &mut Rsc, session: &Session) -> StrongWidget { let msg_panel = msg_panel(rsc); - let side_bar = rect(Color::BLACK.alpha(150)).width(260); + let side_bar = side_bar(rsc, session); (side_bar, msg_panel).span(Dir::RIGHT).add_strong(rsc) } +pub fn side_bar(rsc: &mut Rsc, session: &Session) -> WeakWidget { + let add = Button::new("create channel", color::DARK, rsc); + let session = session.clone(); + rsc.events.register(add, CursorSense::click(), move |_, _| { + session.con().send(CreateChannel { + name: "new channel".to_string(), + }); + }); + rect(Color::BLACK.alpha(150)) + .width(260) + .foreground((add,).span(Dir::DOWN)) + .add(rsc) +} + pub fn msg_widget(username: &str, content: &str) -> impl WidgetIdFn { let content = wtext(content) .editable(EditMode::MultiLine) diff --git a/src/bin/client/ui/connect.rs b/src/bin/client/ui/connect.rs index de02a87..94a02c3 100644 --- a/src/bin/client/ui/connect.rs +++ b/src/bin/client/ui/connect.rs @@ -62,10 +62,9 @@ pub fn start(rsc: &mut Rsc, data: &ClientData) -> WeakWidget { ctx.error(&reason, rsc); }) }; + let id = 0; let con = match NetHandle::connect( - async |msg| { - println!("msg recv :joy:"); - }, + id, ConnectInfo { url: account.url.clone(), cert, @@ -100,6 +99,7 @@ pub fn start(rsc: &mut Rsc, data: &ClientData) -> WeakWidget { }; ctx.update(move |ctx, rsc| { let session = Session::new(con, user_id); + ctx.sessions.push(session.clone()); main_view(rsc, session).set_ptr(ctx.main_ui, rsc); }); }); @@ -160,10 +160,9 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget { }) }; keyring::use_native_store(true).unwrap(); + let id = 0; let con = match NetHandle::connect( - async |msg| { - println!("msg recv :joy:"); - }, + id, ConnectInfo { url: url.clone(), cert, @@ -199,6 +198,7 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget { }; ctx.update(move |ctx, rsc| { let session = Session::new(con, user_id); + ctx.sessions.push(session.clone()); main_view(rsc, session).set_ptr(ctx.main_ui, rsc); ctx.data.create_account( ServerInfo { cert_hex }, diff --git a/src/bin/client/ui/main.rs b/src/bin/client/ui/main.rs index 745d5ee..303c4da 100644 --- a/src/bin/client/ui/main.rs +++ b/src/bin/client/ui/main.rs @@ -12,7 +12,7 @@ pub enum MainView { } pub fn main_view(rsc: &mut Rsc, session: Session) -> WeakWidget { - let mut view = WidgetSelector::new(MainView::Channel, channel::view(rsc)); + let mut view = WidgetSelector::new(MainView::Channel, channel::view(rsc, &session)); view.set(MainView::Server, server::view(rsc, &session)); view.set(MainView::Friends, friends::view(rsc, &session)); let view = view.add(rsc); diff --git a/src/bin/server/db/data.rs b/src/bin/server/db/data.rs index b8e3be0..653fa03 100644 --- a/src/bin/server/db/data.rs +++ b/src/bin/server/db/data.rs @@ -42,6 +42,7 @@ pub struct Msg { pub author: UserId, } +#[derive(bitcode::Encode, bitcode::Decode)] pub struct Channel { pub name: String, pub desc: String, diff --git a/src/bin/server/db/mod.rs b/src/bin/server/db/mod.rs index d57bdfa..bd054d1 100644 --- a/src/bin/server/db/mod.rs +++ b/src/bin/server/db/mod.rs @@ -15,6 +15,7 @@ pub struct Db { pub msgs: DbMap, pub users: DbMap, pub usernames: DbMap, + pub channels: DbMap, } impl Db { @@ -35,6 +36,7 @@ impl Db { msgs: DbMap::open("msg", &db), users: DbMap::open("user", &db), usernames: DbMap::open("username", &db), + channels: DbMap::open("channel", &db), db, } } diff --git a/src/bin/server/handle.rs b/src/bin/server/handle.rs index b737c35..ca8a578 100644 --- a/src/bin/server/handle.rs +++ b/src/bin/server/handle.rs @@ -1,7 +1,7 @@ use super::net::ClientSender; use crate::{ ClientId, account_token, - db::{Db, ServerPerms, User, UserId}, + db::{Channel, ChannelId, Db, ServerPerms, User, UserId}, net::ClientReplier, }; use openworm::net::*; @@ -70,6 +70,22 @@ impl ClientHandler { }; let db = &self.db; match msg { + ClientMsg::CreateChannel(info) => { + let mut id: ChannelId; + let channel = Channel { + name: info.name, + desc: String::new(), + }; + loop { + let mut tx = db.write_tx(); + id = rand::random(); + tx.insert(&db.channels, &id, &channel); + if tx.commit() { + break; + } + } + reply!(CreateChannelResp::Ok); + } ClientMsg::GenerateToken(info) => { let check = if info.perms == ServerPerms::NONE { ServerPerms::ACCOUNT_TOKENS @@ -274,55 +290,3 @@ impl RecvHandler for ClientHandler { } } } - -// ClientMsg::SendMsg(msg) => { -// let uid = check_login().await?; -// let msg = Msg { -// author: uid, -// content: msg.content, -// }; -// // TODO: it is technically possible to send 2 messages at the exact same time... -// // should probably append a number if one already exists at that time, -// // but also I can't see this ever happening...? -// // should be an easy fix later (write tx) -// let timestamp = time::OffsetDateTime::now_utc().unix_timestamp_nanos(); -// self.db.msgs.insert(×tamp, &msg); -// let mut handles = Vec::new(); -// let msg = LoadMsg { -// content: msg.content, -// author: uid, -// }; -// for (&id, send) in self.senders.read().await.iter() { -// if id == self.id { -// continue; -// } -// let send = send.clone(); -// let msg = msg.clone(); -// let fut = async move { -// let _ = send -// .send(LoadMsg { -// content: msg.content, -// author: msg.author, -// }) -// .await; -// }; -// handles.push(tokio::spawn(fut)); -// } -// for h in handles { -// h.await.unwrap(); -// } -// None -// } -// ClientMsg::RequestMsgs => { -// check_login().await?; -// let msgs = self -// .db -// .msgs -// .values() -// .map(|msg| LoadMsg { -// content: msg.content, -// author: msg.author, -// }) -// .collect(); -// replier.send(ServerMsg::LoadMsgs(msgs)).await; -// } diff --git a/src/net/data.rs b/src/net/data.rs index b601e88..1320e9e 100644 --- a/src/net/data.rs +++ b/src/net/data.rs @@ -1,5 +1,15 @@ use iris::core::util::HashSet; +#[derive(Debug, bitcode::Encode, bitcode::Decode)] +pub struct CreateChannel { + pub name: String, +} + +#[derive(Debug, bitcode::Encode, bitcode::Decode)] +pub enum CreateChannelResp { + Ok, +} + #[derive(Debug, bitcode::Encode, bitcode::Decode)] pub struct RequestUserInfo { pub id: UserId, diff --git a/src/net/msg.rs b/src/net/msg.rs index 00102c9..55175e6 100644 --- a/src/net/msg.rs +++ b/src/net/msg.rs @@ -10,6 +10,7 @@ msg_type!(ClientMsg: { 6: AnswerFriendRequest, 7: GenerateToken => GenerateTokenResp, 8: RequestUserInfo => RequestUserInfoResp, + 9: CreateChannel => CreateChannelResp, }); msg_type!(ServerMsg: { 0: NotLoggedIn, @@ -22,6 +23,7 @@ msg_type!(ServerMsg: { 7: AddFriendResp, 8: GenerateTokenResp, 9: RequestUserInfoResp, + 10: CreateChannelResp, }); macro_rules! msg_type {