channel work
This commit is contained in:
@@ -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<WidgetPtr>,
|
||||
notif: WeakWidget<WidgetPtr>,
|
||||
sessions: Vec<Session>,
|
||||
}
|
||||
|
||||
pub type Rsc = DefaultRsc<Client>;
|
||||
pub type ClientSender = EventSender<Client>;
|
||||
|
||||
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 => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Self, String> {
|
||||
@@ -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<F: MsgHandler> {
|
||||
struct ServerRecv {
|
||||
requests: DashMap<RequestId, oneshot::Sender<ServerMsg>>,
|
||||
requests_sync: DashMap<RequestId, SyncReqFn>,
|
||||
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) {
|
||||
if let Some(id) = resp.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));
|
||||
}
|
||||
} else {
|
||||
self.msg.run(resp.msg).await;
|
||||
Session::handle(&self.event_sender, self.id, resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Rsc> {
|
||||
let content = wtext(content)
|
||||
.editable(EditMode::MultiLine)
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -42,6 +42,7 @@ pub struct Msg {
|
||||
pub author: UserId,
|
||||
}
|
||||
|
||||
#[derive(bitcode::Encode, bitcode::Decode)]
|
||||
pub struct Channel {
|
||||
pub name: String,
|
||||
pub desc: String,
|
||||
|
||||
@@ -15,6 +15,7 @@ pub struct Db {
|
||||
pub msgs: DbMap<MsgId, Msg>,
|
||||
pub users: DbMap<UserId, User>,
|
||||
pub usernames: DbMap<String, UserId>,
|
||||
pub channels: DbMap<ChannelId, Channel>,
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
+17
-53
@@ -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<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(×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;
|
||||
// }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user