diff --git a/iris b/iris index 796bc41..a592318 160000 --- a/iris +++ b/iris @@ -1 +1 @@ -Subproject commit 796bc41752c97254231adf6692cec7c9d42953aa +Subproject commit a592318a6f6034995bb70bcdd37d508bc98bfaff diff --git a/src/bin/client/data.rs b/src/bin/client/data.rs new file mode 100644 index 0000000..56d9349 --- /dev/null +++ b/src/bin/client/data.rs @@ -0,0 +1,39 @@ +use openworm::rsc::{DataDir, DataRsc}; + +pub struct ClientData { + pub dir: DataDir, + pub cache: Cache, +} + +impl ClientData { + pub fn load() -> Self { + let dir = DataDir::default(); + Self { + cache: dir.load(), + dir, + } + } + + pub fn save(&self) { + self.dir.save(&self.cache); + } + + pub fn device_key(&self) -> { + } +} + +#[derive(Debug, Default, bincode::Encode, bincode::Decode)] +pub struct Cache { + pub ip: String, + pub username: String, + /// TODO: not store this as plain string? + /// need to figure out crypto stuff + /// or store session token + pub password: String, +} + +impl DataRsc for Cache { + fn path() -> &'static str { + "client_data" + } +} diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index 868ec73..a082f23 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs @@ -1,25 +1,21 @@ #![windows_subsystem = "windows"] use crate::{ + data::ClientData, net::{NetHandle, NetSender}, - rsc::{CLIENT_DATA, ClientData}, state::{ClientState, LoggedIn, Login}, - ui::*, }; use iris::prelude::*; -use openworm::{ - net::{ClientMsg, ServerMsg, install_crypto_provider}, - rsc::DataDir, -}; +use openworm::net::{ClientMsg, ServerMsg, install_crypto_provider}; use winit::{ event::{ElementState, MouseButton, WindowEvent}, window::WindowAttributes, }; mod account; +mod data; mod debug; mod net; -mod rsc; mod state; mod ui; @@ -31,7 +27,6 @@ fn main() { #[derive(DefaultUiState)] pub struct Client { ui_state: DefaultUiState, - dir: DataDir, data: ClientData, state: ClientState, main_ui: WeakWidget, @@ -55,7 +50,6 @@ impl DefaultAppState for Client { rsc: &mut DefaultRsc, proxy: Proxy, ) -> Self { - let dir = DataDir::default(); let notif = WidgetPtr::default().add(rsc); let main_ui = WidgetPtr::default().add(rsc); let bg = ( @@ -72,13 +66,12 @@ impl DefaultAppState for Client { .stack() .set_root(rsc, &mut ui_state); - start_ui(rsc).set_ptr(main_ui, rsc); + ui::start(rsc).set_ptr(main_ui, rsc); Self { ui_state, - data: dir.load(CLIENT_DATA), + data: ClientData::load(), state: Default::default(), - dir, main_ui, notif, proxy, @@ -110,7 +103,7 @@ impl DefaultAppState for Client { if let ClientState::LoggedIn(state) = &mut self.state && let Some(msg_area) = state.channel { - let msg = msg_widget(&msg.user, &msg.content).add_strong(rsc); + let msg = ui::msg_widget(&msg.user, &msg.content).add_strong(rsc); rsc[msg_area].children.push(msg); } } @@ -120,7 +113,7 @@ impl DefaultAppState for Client { { for msg in msgs { state.msgs.push(msg.clone()); - let msg = msg_widget(&msg.user, &msg.content).add_strong(rsc); + let msg = ui::msg_widget(&msg.user, &msg.content).add_strong(rsc); rsc[msg_area].children.push(msg); } } @@ -136,22 +129,22 @@ impl DefaultAppState for Client { msgs: Vec::new(), username, }); - main_view(rsc).set_ptr(self.main_ui, rsc); + ui::main_view(rsc).set_ptr(self.main_ui, rsc); } ServerMsg::Error(error) => { let msg = format!("{error:?}"); - rsc[self.notif].inner = Some(werror(&msg, rsc)); + rsc[self.notif].inner = Some(ui::werror(&msg, rsc)); } }, ClientEvent::Err(msg) => { - rsc[self.notif].inner = Some(werror(&msg, rsc)); + rsc[self.notif].inner = Some(ui::werror(&msg, rsc)); } } } fn exit(&mut self, _rsc: &mut DefaultRsc, _render: &mut UiRenderState) { self.state.exit(); - self.dir.save(CLIENT_DATA, &self.data); + self.data.save(); } fn window_event( diff --git a/src/bin/client/rsc.rs b/src/bin/client/rsc.rs deleted file mode 100644 index 531d3fc..0000000 --- a/src/bin/client/rsc.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub const CLIENT_DATA: &str = "client_data"; - -#[derive(Debug, Default, bincode::Encode, bincode::Decode)] -pub struct ClientData { - pub ip: String, - pub username: String, - /// TODO: not store this as plain string? - /// need to figure out crypto stuff - /// or store session token - pub password: String, -} diff --git a/src/bin/client/ui/connect.rs b/src/bin/client/ui/connect.rs index bf73a77..0c909e9 100644 --- a/src/bin/client/ui/connect.rs +++ b/src/bin/client/ui/connect.rs @@ -1,6 +1,6 @@ use super::*; -pub fn start_ui(rsc: &mut Rsc) -> WeakWidget { +pub fn start(rsc: &mut Rsc) -> WeakWidget { let mut accounts = Span::empty(Dir::DOWN); accounts.push( @@ -14,15 +14,13 @@ pub fn start_ui(rsc: &mut Rsc) -> WeakWidget { let connect = Button::submit("connect", rsc); let create = Button::submit("create", rsc); - rsc.events.register(connect.root(), Submit, move |_, rsc| { + rsc.events.register(connect, Submit, move |_, rsc| { connect.disable(rsc); create.disable(rsc); }); - rsc.events.register(create.root(), Submit, move |ctx, rsc| { - connect.disable(rsc); - create.disable(rsc); - create_ui(rsc).set_ptr(ctx.state.main_ui, rsc); + rsc.events.register(create, Submit, move |ctx, rsc| { + create_account(rsc).set_ptr(ctx.state.main_ui, rsc); }); ( @@ -36,8 +34,27 @@ pub fn start_ui(rsc: &mut Rsc) -> WeakWidget { .add(rsc) } -pub fn create_ui(rsc: &mut Rsc) -> WeakWidget { - wtext("hi").add(rsc) +pub fn create_account(rsc: &mut Rsc) -> WeakWidget { + let url = field("", "server", rsc); + let username = field("", "username", rsc); + let password = field("", "password", rsc); + + let create = Button::submit("create", rsc); + rsc.events.register(create, Submit, move |ctx, rsc| { + ctx.state.data + }); + + ( + wtext("Create Account").text_align(Align::CENTER).size(30), + field_box(url, rsc), + field_box(username, rsc), + field_box(password, rsc), + create, + ) + .span(Dir::DOWN) + .gap(15) + .modal(400) + .add(rsc) } // pub fn connect_screen(client: &mut Client, ui: &mut Ui, state: &UiState) -> WeakWidget { diff --git a/src/bin/client/ui/main.rs b/src/bin/client/ui/main.rs index d421c3b..be016df 100644 --- a/src/bin/client/ui/main.rs +++ b/src/bin/client/ui/main.rs @@ -40,7 +40,7 @@ pub fn msg_panel(rsc: &mut Rsc) -> WeakWidget { .editable(EditMode::MultiLine) .size(SIZE) .wrap(true) - .hint(hint("send message")) + .hint(hint_text("send message")) .add(rsc); let msg_area = msg_area.add(rsc); diff --git a/src/bin/client/ui/misc.rs b/src/bin/client/ui/misc.rs index ab87886..ed66009 100644 --- a/src/bin/client/ui/misc.rs +++ b/src/bin/client/ui/misc.rs @@ -8,15 +8,15 @@ pub fn werror(msg: &str, rsc: &mut Rsc) -> StrongWidget { .add_strong(rsc) } -pub fn hint(msg: impl Into) -> TextBuilder { +pub fn hint_text(msg: impl Into) -> TextBuilder { wtext(msg).size(20).color(Color::GRAY) } -pub fn field_widget(name: &str, hint_text: &str, rsc: &mut Rsc) -> WeakWidget { - wtext(name) +pub fn field(default: &str, hint: &str, rsc: &mut Rsc) -> WeakWidget { + wtext(default) .editable(EditMode::SingleLine) .size(20) - .hint(hint(hint_text)) + .hint(hint_text(hint)) .add(rsc) } diff --git a/src/rsc.rs b/src/rsc.rs index 9f3954d..c0dcaa0 100644 --- a/src/rsc.rs +++ b/src/rsc.rs @@ -20,13 +20,17 @@ impl Default for DataDir { } } +pub trait DataRsc: bincode::Encode + bincode::Decode<()> + Default { + fn path() -> &'static str; +} + impl DataDir { pub fn get(&self) -> &Path { self.dirs.data_local_dir() } - pub fn load + Default>(&self, path: &str) -> T { - let path = self.get().join(path); + pub fn load(&self) -> T { + let path = self.get().join(T::path()); match fs::read(path) { Ok(bytes) => match bincode::decode_from_slice(&bytes, BINCODE_CONFIG) { Ok((data, _)) => data, @@ -36,10 +40,10 @@ impl DataDir { } } - pub fn save(&self, path: &str, data: &T) { + pub fn save(&self, data: &T) { let dir = self.get(); fs::create_dir_all(dir).unwrap(); - let mut file = File::create(dir.join(path)).unwrap(); + let mut file = File::create(dir.join(T::path())).unwrap(); bincode::encode_into_std_write(data, &mut file, BINCODE_CONFIG).unwrap(); } }