channel work

This commit is contained in:
2026-05-25 21:50:14 -04:00
parent e7a50cbdbc
commit 03df4470fd
11 changed files with 78 additions and 77 deletions
+4 -6
View File
@@ -1,9 +1,9 @@
#![feature(async_fn_traits)] #![feature(async_fn_traits)]
#![windows_subsystem = "windows"] #![windows_subsystem = "windows"]
use crate::data::ClientData; use crate::{data::ClientData, session::Session};
use iris::prelude::*; use iris::prelude::*;
use openworm::net::{ServerMsg, install_crypto_provider}; use openworm::net::install_crypto_provider;
use winit::{ use winit::{
event::{ElementState, MouseButton, WindowEvent}, event::{ElementState, MouseButton, WindowEvent},
window::WindowAttributes, window::WindowAttributes,
@@ -26,14 +26,13 @@ pub struct Client {
data: ClientData, data: ClientData,
main_ui: WeakWidget<WidgetPtr>, main_ui: WeakWidget<WidgetPtr>,
notif: WeakWidget<WidgetPtr>, notif: WeakWidget<WidgetPtr>,
sessions: Vec<Session>,
} }
pub type Rsc = DefaultRsc<Client>; pub type Rsc = DefaultRsc<Client>;
pub type ClientSender = EventSender<Client>; pub type ClientSender = EventSender<Client>;
pub enum ClientEvent { pub enum ClientEvent {
CacheUpdate,
ServerMsg(ServerMsg),
Err(String), Err(String),
} }
@@ -62,6 +61,7 @@ impl DefaultAppState for Client {
ui::start(rsc, &data).set_ptr(main_ui, rsc); ui::start(rsc, &data).set_ptr(main_ui, rsc);
Self { Self {
sessions: Default::default(),
ui_state, ui_state,
data, data,
main_ui, main_ui,
@@ -76,11 +76,9 @@ impl DefaultAppState for Client {
_render: &mut UiRenderState, _render: &mut UiRenderState,
) { ) {
match event { match event {
ClientEvent::ServerMsg(_) => {}
ClientEvent::Err(msg) => { ClientEvent::Err(msg) => {
rsc[self.notif].inner = Some(ui::werror(&msg, rsc)); rsc[self.notif].inner = Some(ui::werror(&msg, rsc));
} }
ClientEvent::CacheUpdate => {}
} }
} }
+7 -7
View File
@@ -1,4 +1,4 @@
use crate::{Client, ClientSender, Rsc}; use crate::{Client, ClientEvent, ClientSender, Rsc, session::Session};
use dashmap::DashMap; use dashmap::DashMap;
use iris::prelude::DefaultRsc; use iris::prelude::DefaultRsc;
use openworm::net::{ use openworm::net::{
@@ -166,7 +166,7 @@ async fn connection_no_cert(addr: SocketAddr) -> NetResult<(Endpoint, Connection
impl NetHandle { impl NetHandle {
pub async fn connect( pub async fn connect(
msg: impl MsgHandler, id: usize,
info: ConnectInfo, info: ConnectInfo,
event_sender: ClientSender, event_sender: ClientSender,
) -> Result<Self, String> { ) -> Result<Self, String> {
@@ -184,7 +184,7 @@ impl NetHandle {
let mut req_id = RequestId::first(); let mut req_id = RequestId::first();
let recv = Arc::new(ServerRecv { let recv = Arc::new(ServerRecv {
msg, id,
requests_sync: DashMap::default(), requests_sync: DashMap::default(),
requests: DashMap::default(), requests: DashMap::default(),
event_sender: event_sender.clone(), event_sender: event_sender.clone(),
@@ -251,14 +251,14 @@ where
} }
} }
struct ServerRecv<F: MsgHandler> { struct ServerRecv {
requests: DashMap<RequestId, oneshot::Sender<ServerMsg>>, requests: DashMap<RequestId, oneshot::Sender<ServerMsg>>,
requests_sync: DashMap<RequestId, SyncReqFn>, requests_sync: DashMap<RequestId, SyncReqFn>,
event_sender: ClientSender, event_sender: ClientSender,
msg: F, id: usize,
} }
impl<F: MsgHandler> RecvHandler<ServerMsgInst> for ServerRecv<F> { impl RecvHandler<ServerMsgInst> for ServerRecv {
async fn msg(&self, resp: ServerMsgInst) { async fn msg(&self, resp: ServerMsgInst) {
if let Some(id) = resp.id { if let Some(id) = resp.id {
if let Some((_, send)) = self.requests.remove(&id) { if let Some((_, send)) = self.requests.remove(&id) {
@@ -267,7 +267,7 @@ impl<F: MsgHandler> RecvHandler<ServerMsgInst> for ServerRecv<F> {
self.event_sender.run(|rsc| f(resp.msg, rsc)); self.event_sender.run(|rsc| f(resp.msg, rsc));
} }
} else { } else {
self.msg.run(resp.msg).await; Session::handle(&self.event_sender, self.id, resp);
} }
} }
} }
+10 -2
View File
@@ -1,9 +1,9 @@
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
use iris::prelude::*; 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... // TODO: this really should not be async...
// I mean it could be used async but all widgets // I mean it could be used async but all widgets
@@ -38,4 +38,12 @@ impl Session {
let span = Span::empty(Dir::DOWN).add(rsc); let span = Span::empty(Dir::DOWN).add(rsc);
span span
} }
pub fn handle(sender: &ClientSender, id: usize, inst: ServerMsgInst) {
match inst.msg {
_ => {
println!("Unknown server message recieved");
}
}
}
} }
+18 -2
View File
@@ -1,12 +1,28 @@
use openworm::net::CreateChannel;
use super::*; 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 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) (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<Rsc> { pub fn msg_widget(username: &str, content: &str) -> impl WidgetIdFn<Rsc> {
let content = wtext(content) let content = wtext(content)
.editable(EditMode::MultiLine) .editable(EditMode::MultiLine)
+6 -6
View File
@@ -62,10 +62,9 @@ pub fn start(rsc: &mut Rsc, data: &ClientData) -> WeakWidget {
ctx.error(&reason, rsc); ctx.error(&reason, rsc);
}) })
}; };
let id = 0;
let con = match NetHandle::connect( let con = match NetHandle::connect(
async |msg| { id,
println!("msg recv :joy:");
},
ConnectInfo { ConnectInfo {
url: account.url.clone(), url: account.url.clone(),
cert, cert,
@@ -100,6 +99,7 @@ pub fn start(rsc: &mut Rsc, data: &ClientData) -> WeakWidget {
}; };
ctx.update(move |ctx, rsc| { ctx.update(move |ctx, rsc| {
let session = Session::new(con, user_id); let session = Session::new(con, user_id);
ctx.sessions.push(session.clone());
main_view(rsc, session).set_ptr(ctx.main_ui, rsc); 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(); keyring::use_native_store(true).unwrap();
let id = 0;
let con = match NetHandle::connect( let con = match NetHandle::connect(
async |msg| { id,
println!("msg recv :joy:");
},
ConnectInfo { ConnectInfo {
url: url.clone(), url: url.clone(),
cert, cert,
@@ -199,6 +198,7 @@ pub fn create_account(rsc: &mut Rsc) -> WeakWidget {
}; };
ctx.update(move |ctx, rsc| { ctx.update(move |ctx, rsc| {
let session = Session::new(con, user_id); let session = Session::new(con, user_id);
ctx.sessions.push(session.clone());
main_view(rsc, session).set_ptr(ctx.main_ui, rsc); main_view(rsc, session).set_ptr(ctx.main_ui, rsc);
ctx.data.create_account( ctx.data.create_account(
ServerInfo { cert_hex }, ServerInfo { cert_hex },
+1 -1
View File
@@ -12,7 +12,7 @@ pub enum MainView {
} }
pub fn main_view(rsc: &mut Rsc, session: Session) -> WeakWidget { 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::Server, server::view(rsc, &session));
view.set(MainView::Friends, friends::view(rsc, &session)); view.set(MainView::Friends, friends::view(rsc, &session));
let view = view.add(rsc); let view = view.add(rsc);
+1
View File
@@ -42,6 +42,7 @@ pub struct Msg {
pub author: UserId, pub author: UserId,
} }
#[derive(bitcode::Encode, bitcode::Decode)]
pub struct Channel { pub struct Channel {
pub name: String, pub name: String,
pub desc: String, pub desc: String,
+2
View File
@@ -15,6 +15,7 @@ pub struct Db {
pub msgs: DbMap<MsgId, Msg>, pub msgs: DbMap<MsgId, Msg>,
pub users: DbMap<UserId, User>, pub users: DbMap<UserId, User>,
pub usernames: DbMap<String, UserId>, pub usernames: DbMap<String, UserId>,
pub channels: DbMap<ChannelId, Channel>,
} }
impl Db { impl Db {
@@ -35,6 +36,7 @@ impl Db {
msgs: DbMap::open("msg", &db), msgs: DbMap::open("msg", &db),
users: DbMap::open("user", &db), users: DbMap::open("user", &db),
usernames: DbMap::open("username", &db), usernames: DbMap::open("username", &db),
channels: DbMap::open("channel", &db),
db, db,
} }
} }
+17 -53
View File
@@ -1,7 +1,7 @@
use super::net::ClientSender; use super::net::ClientSender;
use crate::{ use crate::{
ClientId, account_token, ClientId, account_token,
db::{Db, ServerPerms, User, UserId}, db::{Channel, ChannelId, Db, ServerPerms, User, UserId},
net::ClientReplier, net::ClientReplier,
}; };
use openworm::net::*; use openworm::net::*;
@@ -70,6 +70,22 @@ impl ClientHandler {
}; };
let db = &self.db; let db = &self.db;
match msg { 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) => { ClientMsg::GenerateToken(info) => {
let check = if info.perms == ServerPerms::NONE { let check = if info.perms == ServerPerms::NONE {
ServerPerms::ACCOUNT_TOKENS ServerPerms::ACCOUNT_TOKENS
@@ -274,55 +290,3 @@ impl RecvHandler<ClientMsgInst> 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(&timestamp, &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;
// }
+10
View File
@@ -1,5 +1,15 @@
use iris::core::util::HashSet; 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)] #[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub struct RequestUserInfo { pub struct RequestUserInfo {
pub id: UserId, pub id: UserId,
+2
View File
@@ -10,6 +10,7 @@ msg_type!(ClientMsg: {
6: AnswerFriendRequest, 6: AnswerFriendRequest,
7: GenerateToken => GenerateTokenResp, 7: GenerateToken => GenerateTokenResp,
8: RequestUserInfo => RequestUserInfoResp, 8: RequestUserInfo => RequestUserInfoResp,
9: CreateChannel => CreateChannelResp,
}); });
msg_type!(ServerMsg: { msg_type!(ServerMsg: {
0: NotLoggedIn, 0: NotLoggedIn,
@@ -22,6 +23,7 @@ msg_type!(ServerMsg: {
7: AddFriendResp, 7: AddFriendResp,
8: GenerateTokenResp, 8: GenerateTokenResp,
9: RequestUserInfoResp, 9: RequestUserInfoResp,
10: CreateChannelResp,
}); });
macro_rules! msg_type { macro_rules! msg_type {