use iris::prelude::*; use len_fns::*; use crate::{ client::{Client, app::AppHandle}, net::{ ClientMsg, Msg, client::{ConnectInfo, NetSender, connect}, }, }; #[derive(Eq, PartialEq, Hash, Clone)] pub struct Submit; impl DefaultEvent for Submit { type Data = (); } pub fn ui(handle: AppHandle) -> Ui { let mut ui = Ui::new(); login_screen(&mut ui, handle).set_root(&mut ui); ui } pub fn main_view(client: &mut Client, network: NetSender) -> WidgetId { let msg_panel = msg_panel(client, network); let side_bar = rect(Color::BLACK.brighter(0.05)).width(80); (side_bar, msg_panel) .span(Dir::RIGHT) .add(&mut client.ui) .any() } fn login_screen(ui: &mut Ui, handle: AppHandle) -> WidgetId { let mut field = |name| text(name).editable().size(20).add(ui); let ip = field("localhost:16839"); let username = field("username"); // let password = field("password"); let fbx = |field: WidgetId| { field .clone() .pad(10) .background(rect(Color::BLACK.brighter(0.1)).radius(15)) .on(CursorSense::click(), focus(field)) }; let ip_ = ip.clone(); let username_ = username.clone(); let color = Color::GREEN; let submit = rect(color) .radius(15) .id_on(CursorSense::click(), move |id, client: &mut Client, _| { client.ui[id].color = color.darker(0.3); let ip = client.ui[&ip_].content(); let username = client.ui[&username_].content(); connect(handle.clone(), ConnectInfo { ip, username }); }) .height(40); ( text("login").size(30), fbx(ip), fbx(username), // fbx(password), submit, ) .span(Dir::DOWN) .gap(10) .pad(15) .background(rect(Color::BLACK.brighter(0.2)).radius(15)) .width(400) .align(Align::Center) .add(ui) .any() } pub fn msg_widget(msg: Msg) -> impl WidgetLike { let content = text(msg.content) .editable() .size(20) .text_align(Align::Left) .wrap(true) .id_on(CursorSense::click(), |id, client: &mut Client, ctx| { client.ui.text(id).select(ctx.cursor, ctx.size); client.focus = Some(id.clone()); }); let header = text(msg.user).size(20); ( image(include_bytes!("./assets/sungals.png")) .sized((70, 70)) .align(Align::TopLeft), (header.align(Align::TopLeft), content.align(Align::TopLeft)) .span(Dir::DOWN) .gap(10), ) .span(Dir::RIGHT) .gap(10) } pub fn focus(id: WidgetId) -> impl Fn(&mut Client, CursorData) { move |client: &mut Client, data: CursorData| { client.ui.text(&id).select(data.cursor, data.size); client.focus = Some(id.clone()); } } pub fn msg_panel(client: &mut Client, network: NetSender) -> impl WidgetFn + use<> { let Client { ui, channel, .. } = client; let msg_area = Span::empty(Dir::DOWN).gap(15).add(ui); *channel = Some(msg_area.clone()); let send_text = text("").editable().size(20).text_align(Align::Left).add(ui); ( msg_area .clone() .align(Align::BotLeft) .scroll() .pad(Padding::x(15)) .height(rest(1)), send_text .clone() .id_on(Submit, move |id, client: &mut Client, _| { let content = client.ui.text(id).take(); let msg = Msg { content: content.clone(), user: client.username.clone(), }; network.send(ClientMsg::SendMsg(msg.clone())); let msg = msg_widget(msg).add(&mut client.ui); client.ui[&msg_area].children.push(msg.any()); }) .pad(15) .on(CursorSense::click(), focus(send_text)) .background(rect(Color::BLACK.brighter(0.05)).radius(15)) .pad(15) .height(80) .z_offset(1), ) .span(Dir::DOWN) .width(rest(1)) .background(rect(Color::BLACK.brighter(0.1))) }