diff --git a/Cargo.lock b/Cargo.lock index 0bb09ac..642cb19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -520,6 +520,18 @@ dependencies = [ "syn 2.0.95", ] +[[package]] +name = "derive_setters" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.95", +] + [[package]] name = "digest" version = "0.10.7" @@ -550,6 +562,7 @@ dependencies = [ "clap", "console-subscriber", "crossterm", + "derive_setters", "http-body-util", "hyper 1.6.0", "hyper-util", diff --git a/Cargo.toml b/Cargo.toml index 14a2a6c..040fd7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,3 +35,4 @@ crossterm = "0.28.1" tracing = "0.1.41" tracing-subscriber = "0.3.19" ratatui = "0.29.0" +derive_setters = "0.1.6" diff --git a/src/client.rs b/src/client.rs index 4ba93fd..0867450 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,14 +1,4 @@ -use ratatui::crossterm::{event::{self, Event, KeyCode, KeyEvent, KeyEventKind}}; -use ratatui::{ - buffer::Buffer, - layout::{Constraint, Flex, Layout, Rect}, - style::Stylize, - symbols::border, - text::{Line, Text}, - widgets::{Block, Borders, Clear, Paragraph, Widget, Wrap}, - DefaultTerminal, - Frame, -}; +use ratatui::DefaultTerminal; use crate::{message::{Message, MessageKind}, player::Player, ui::ui}; @@ -20,12 +10,14 @@ pub struct Client { pub name: String, pub exit: bool, pub popup: bool, + pub popup_title: String, + pub popup_content: String, pub response: String, } impl Client { pub async fn run(&mut self, terminal: &mut DefaultTerminal) -> anyhow::Result<()> { - self.addr = "http://120.0.0.1:8080".to_string(); + self.addr = "http://127.0.0.1:8080".to_string(); self.client = reqwest::Client::new(); while !self.exit { @@ -63,39 +55,3 @@ impl Client { Ok(()) } } - -impl Widget for &Client { - fn render(self, area: Rect, buf: &mut Buffer) { - let title = Line::from(" durak tui test fre ".bold()); - - let instructions = Line::from(vec![ - " create player ".into(), - "1".blue().bold(), - " create lobby ".into(), - "2".blue().bold(), - " quit ".into(), - "<Q>".blue().bold(), - ]); - - let block = Block::bordered() - .title(title.centered()) - .title_bottom(instructions.centered()) - .border_set(border::THICK); - - let infos = Text::from(vec![ - Line::from(vec![ - "connected to: ".into(), - self.addr.clone().yellow(), - ]), - Line::from(vec![ - "username: ".into(), - self.name.clone().yellow(), - ]), - ]); - - Paragraph::new(infos) - .left_aligned() - .block(block) - .render(area, buf); - } -} diff --git a/src/ui.rs b/src/ui.rs index ab45194..b8b33d4 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,3 +1,4 @@ +use derive_setters::Setters; use ratatui::{ layout::{ Constraint, @@ -14,29 +15,71 @@ use ratatui::crossterm::{event::{self, Event, KeyCode, KeyEvent, KeyEventKind}}; use crate::{client::Client, player::Player}; -async fn handle_key_event(mut client: &mut Client, key_event: KeyEvent) { - match key_event.code { - KeyCode::Char('q') => Client::exit(client), - KeyCode::Char('1') => { - if !client.name.is_empty() { - println!("user already created"); - return - } +#[derive(Debug, Default, Setters)] +struct Popup<'a> { + #[setters(into)] + title: Line<'a>, + #[setters(into)] + content: Text<'a>, + border_style: Style, + title_style: Style, + style: Style, +} - client.user = Some(Player::new().expect("toto")); - client.name = client.user.clone().unwrap().name; - }, - KeyCode::Char('2') => { - todo!() - }, - KeyCode::Char('3') => { - if let Some(player) = client.user.clone() { - let addr = client.addr.clone(); - Client::send_player(&mut client, &player, &addr).await.unwrap(); - return +impl Widget for Popup<'_> { + fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized { + Clear.render(area, buf); + + let block = Block::new() + .title(self.title) + .title_style(self.title_style) + .borders(Borders::ALL) + .border_style(self.border_style); + + Paragraph::new(self.content) + .wrap(Wrap { trim: true }) + .style(self.style) + .block(block) + .render(area, buf); + } +} + +async fn handle_key_event(mut client: &mut Client, key_event: KeyEvent) { + match &client.popup { + false => { + match key_event.code { + KeyCode::Char('q') => Client::exit(client), + KeyCode::Char('1') => { + if !client.name.is_empty() { + client.popup_title = "Error".to_string(); + client.popup_content = "user already_created".to_string(); + client.popup = true; + return + } + + client.user = Some(Player::new().expect("toto")); + client.name = client.user.clone().unwrap().name; + }, + KeyCode::Char('2') => { + todo!() + }, + KeyCode::Char('3') => { + if let Some(player) = client.user.clone() { + let addr = client.addr.clone(); + Client::send_player(&mut client, &player, &addr).await.unwrap(); + return + } + } + _ => (), + } + } + true => { + match key_event.code { + _ => client.popup = false, } } - _ => {} } } @@ -100,5 +143,30 @@ pub fn ui(frame: &mut Frame, app: &Client) { .title_bottom(instructions.centered()) .borders(Borders::ALL) .style(Style::default()); - frame.render_widget(Paragraph::new(server_message).block(btm_block), chunks[1]); + frame.render_widget( + Paragraph::new(server_message) + .wrap(Wrap { trim: true, }) + .block(btm_block), + chunks[1], + ); + + let popup_area = Rect { + x: frame.area().width / 4, + y: frame.area().height / 3, + width: frame.area().width / 2, + height: frame.area().height / 3, + }; + + match &app.popup { + true => { + let popup = Popup::default() + .title(app.popup_title.clone()) + .content(app.popup_content.clone()) + .style(Style::new().yellow()) + .title_style(Style::new().white().bold()) + .border_style(Style::new().red()); + frame.render_widget(popup, popup_area); + }, + _ => () + } }