channel work
This commit is contained in:
@@ -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 => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
@@ -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(×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;
|
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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user