Compare commits

...

2 commits

Author SHA1 Message Date
clizia
e6968b6c8d player gets added to lobby upon lobby creation 2025-05-13 19:51:53 +02:00
clizia
789e3912d3 reverted the idea of getting a lobby list from the server 2025-05-13 19:21:53 +02:00
5 changed files with 132 additions and 127 deletions

View file

@ -1,13 +1,12 @@
use anyhow::Result; use anyhow::Result;
use ratatui::DefaultTerminal; use ratatui::{widgets::ListState, DefaultTerminal};
use crate::{message::{Message, MessageKind}, player::Player, ui::{ui, CurrentScreen}}; use crate::{lobby::Lobby, message::{Message, MessageKind}, player::Player, ui::{ui, CurrentScreen}};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Client { pub struct Client {
pub addr: String, pub addr: String,
pub client: reqwest::Client, pub client: reqwest::Client,
pub current_screen: CurrentScreen,
pub user: Option<String>, pub user: Option<String>,
pub user_name: String, pub user_name: String,
pub exit: bool, pub exit: bool,

View file

@ -23,7 +23,7 @@ impl Lobby {
} }
} }
pub fn join_lobby(mut self, player: Player) { pub fn join_lobby(&mut self, player: Player) {
self.players.push(player); self.players.push(player);
} }

View file

@ -19,6 +19,7 @@ pub enum MessageKind {
DeleteLobby, DeleteLobby,
JoinLobby, JoinLobby,
QuitLobby, QuitLobby,
GetLobbies,
} }
impl Message { impl Message {

View file

@ -34,7 +34,7 @@ impl App {
pub async fn create_player( pub async fn create_player(
State(db): State<AppState>, State(db): State<AppState>,
json_body: Result<Json<Message>, JsonRejection>, json_body: Result<Json<Message>, JsonRejection>,
) -> Result<axum::Json<Message>, StatusCode> { ) -> Result<axum::Json<Message>, String> {
match json_body { match json_body {
Ok(Json(message)) => { Ok(Json(message)) => {
println!("{:?}", message); println!("{:?}", message);
@ -44,7 +44,7 @@ impl App {
.lock().expect("ciao"); .lock().expect("ciao");
if players.contains_key(&player.name) { if players.contains_key(&player.name) {
return Err(StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS) return Err(String::from("player already in db"))
} }
players.insert( players.insert(
@ -55,42 +55,57 @@ impl App {
Ok(Json(Message::new("server", MessageKind::CreatePlayer, &player.name).expect("failed creating message"))) Ok(Json(Message::new("server", MessageKind::CreatePlayer, &player.name).expect("failed creating message")))
} }
Err(_) => Err(StatusCode::UNPROCESSABLE_ENTITY) Err(_) => Err(String::from("failed parsing json message"))
} }
} }
pub async fn create_lobby( pub async fn create_lobby(
State(db): State<AppState>, State(db): State<AppState>,
json_body: Result<Json<Message>, JsonRejection>, json_body: Result<Json<Message>, JsonRejection>,
) -> Result<axum::Json<Message>, StatusCode> { ) -> Result<axum::Json<Message>, String> {
match json_body { match json_body {
Ok(Json(message)) => { Ok(Json(message)) => {
println!("{:?}", message); println!("{:?}", message);
let lobby: Lobby = Lobby::new(); let mut lobby: Lobby = Lobby::new();
let mut lobbies = db.lobbies let mut lobbies = db.lobbies
.lock().expect("ciao"); .lock()
.expect("failed to lock lobbies db");
if lobbies.contains_key(&lobby.id) { if lobbies.contains_key(&lobby.id) {
return Err(StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS) return Err(String::from("lobby already in db"))
} }
let players = db.players
.lock()
.expect("failed to lock player db");
let player_bytes = players.get(&message.content);
let player: Player = if let None = player_bytes {
return Err(String::from("player not found or not yet created"));
} else {
Player::from(serde_json::from_slice(player_bytes.unwrap()).expect("failed"))
};
lobby.join_lobby(player);
lobbies.insert( lobbies.insert(
lobby.get_id(), lobby.get_id(),
Bytes::copy_from_slice(lobby.encode().expect(&StatusCode::EXPECTATION_FAILED.to_string()).as_ref()) Bytes::copy_from_slice(lobby.encode().expect("failed copying lobby from bytes slice").as_ref())
); );
println!("{:?}", lobbies); println!("{:?}", lobbies);
Ok(Json(Message::new("server", MessageKind::CreateLobby, &lobby.id).expect("failed creating message"))) Ok(Json(Message::new("server", MessageKind::CreateLobby, &lobby.id).expect("failed creating message")))
}, },
Err(_) => Err(StatusCode::UNPROCESSABLE_ENTITY), Err(_) => Err(String::from("failed to parse json message")),
} }
} }
pub async fn delete_player( pub async fn delete_player(
State(db): State<AppState>, State(db): State<AppState>,
Path(player_id): Path<String> Path(player_id): Path<String>
) -> Result<axum::response::Json<Message>, StatusCode> { ) -> Result<axum::response::Json<Message>, String> {
{ {
let mut players = db.players let mut players = db.players
.lock().expect("ciao"); .lock().expect("ciao");
@ -101,7 +116,7 @@ impl App {
println!("{:?}", players); println!("{:?}", players);
Ok(Json(Message::new("server", MessageKind::DeletePlayer, "user deleted").expect("a"))) Ok(Json(Message::new("server", MessageKind::DeletePlayer, "user deleted").expect("a")))
}, },
false => Err(StatusCode::NOT_FOUND), false => Err(String::from("player not found")),
} }
} }
@ -110,7 +125,7 @@ impl App {
pub async fn delete_lobby( pub async fn delete_lobby(
State(db): State<AppState>, State(db): State<AppState>,
Path(lobby_id): Path<String> Path(lobby_id): Path<String>
) -> Result<axum::response::Json<Message>, StatusCode> { ) -> Result<axum::response::Json<Message>, String> {
{ {
let mut lobbies = db.lobbies let mut lobbies = db.lobbies
.lock().expect("ciao"); .lock().expect("ciao");
@ -121,7 +136,7 @@ impl App {
println!("{:?}", lobbies); println!("{:?}", lobbies);
Ok(Json(Message::new("server", MessageKind::DeleteLobby, "lobby deleted").expect("a"))) Ok(Json(Message::new("server", MessageKind::DeleteLobby, "lobby deleted").expect("a")))
}, },
false => Err(StatusCode::NOT_FOUND), false => Err(String::from("lobby not found in db")),
} }
} }
@ -130,7 +145,8 @@ impl App {
pub async fn join_lobby( pub async fn join_lobby(
State(db): State<AppState>, State(db): State<AppState>,
Path(lobby_id): Path<String> Path(lobby_id): Path<String>
) -> Result<axum::response::Json<Message>, StatusCode> { ) -> Result<axum::response::Json<Message>, String> {
todo!() todo!()
} }
} }

205
src/ui.rs
View file

@ -8,7 +8,7 @@ use ratatui::{
}, },
style::{Color, Style, Stylize}, style::{Color, Style, Stylize},
text::{Line, Span, Text}, text::{Line, Span, Text},
widgets::{Block, Borders, Clear, List, ListItem, Paragraph, Widget, Wrap}, widgets::{Block, Borders, Clear, List, ListItem, ListState, Paragraph, Widget, Wrap},
Frame, Frame,
}; };
use ratatui::crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; use ratatui::crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
@ -57,61 +57,56 @@ impl Widget for Popup<'_> {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub enum CurrentScreen { pub enum CurrentScreen {
#[default] Menu, #[default] Menu,
LobbyList, Lobbies,
} }
async fn handle_key_event(mut client: &mut Client, key_event: KeyEvent) { async fn handle_key_event(mut client: &mut Client, key_event: KeyEvent) {
match &client.popup { match &client.popup {
false => { false => {
match client.current_screen { match key_event.code {
CurrentScreen::Menu => { KeyCode::Char('q') => Client::exit(client),
match key_event.code { KeyCode::Char('h') => {
KeyCode::Char('q') => Client::exit(client), client.popup_title = "help".to_string();
KeyCode::Char('h') => { client.popup_content = HELP.to_string();
client.popup_title = "help".to_string(); client.popup = true;
client.popup_content = HELP.to_string(); },
client.popup = true; KeyCode::Char('1') => {
}, if client.user != None {
KeyCode::Char('1') => { client.popup_title = "Error".to_string();
if client.user != None { client.popup_content = "user already_created".to_string();
client.popup_title = "Error".to_string(); client.popup = true;
client.popup_content = "user already_created".to_string(); } else {
client.popup = true; let addr = client.addr.clone();
} else { let path = "/create/player";
let addr = client.addr.clone(); let message = Message::new(
let path = "/create/player"; "",
let message = Message::new( MessageKind::CreatePlayer,
"", ""
MessageKind::CreatePlayer, ).unwrap();
""
).unwrap();
Client::send(&mut client, message, &addr, &path).await.unwrap(); Client::send(&mut client, message, &addr, &path).await.unwrap();
client.user_name = client.user.clone().unwrap(); client.user_name = client.user.clone().unwrap();
}
},
KeyCode::Char('2') => {
if client.lobby != None {
client.popup_title = "Error".to_string();
client.popup_content = "lobby already_created".to_string();
client.popup = true;
} else {
let addr = client.addr.clone();
let path = "/create/lobby";
let message = Message::new(
"",
MessageKind::CreateLobby,
""
).unwrap();
Client::send(&mut client, message, &addr, &path).await.unwrap();
client.lobby_id = client.lobby.clone().unwrap();
}
},
_ => (),
} }
} },
CurrentScreen::LobbyList => todo!(), KeyCode::Char('2') => {
if client.lobby != None || client.user == None {
client.popup_title = "Error".to_string();
client.popup_content = "lobby already_created or player not yet created".to_string();
client.popup = true;
} else {
let addr = client.addr.clone();
let path = "/create/lobby";
let message = Message::new(
"",
MessageKind::CreateLobby,
&client.user_name,
).unwrap();
Client::send(&mut client, message, &addr, &path).await.unwrap();
client.lobby_id = client.lobby.clone().unwrap();
}
},
_ => (),
} }
} }
true => { true => {
@ -134,70 +129,64 @@ pub async fn handle_events(client: &mut Client) -> anyhow::Result<()> {
} }
pub fn ui(frame: &mut Frame, app: &Client) { pub fn ui(frame: &mut Frame, app: &Client) {
match app.current_screen { let chunks = Layout::default()
CurrentScreen::Menu => { .direction(Direction::Vertical)
.constraints([
let chunks = Layout::default() Constraint::Min(3),
.direction(Direction::Vertical) Constraint::Min(1),
.constraints([ ])
Constraint::Min(3), .split(frame.area());
Constraint::Min(1),
])
.split(frame.area());
let instructions = Line::from(vec![ let instructions = Line::from(vec![
" 1".blue().bold(), " 1".blue().bold(),
" create player ".into(), " create player ".into(),
"2".blue().bold(), "2".blue().bold(),
" create lobby ".into(), " create lobby ".into(),
"<Q>".blue().bold(), "<Q>".blue().bold(),
" quit ".into(), " quit ".into(),
]); ]);
let infos = Text::from(vec![ let infos = Text::from(vec![
Line::from(vec![ Line::from(vec![
"connected to: ".into(), "connected to: ".into(),
app.addr.clone().yellow(), app.addr.clone().yellow(),
]), ]),
Line::from(vec![ Line::from(vec![
"username: ".into(), "username: ".into(),
app.user_name.clone().yellow(), app.user_name.clone().yellow(),
]), ]),
Line::from(vec![ Line::from(vec![
"lobby: ".into(), "lobby: ".into(),
app.lobby_id.clone().yellow(), app.lobby_id.clone().yellow(),
]), ]),
]); ]);
let top_block_title = Line::from(" durak tui test fre ".bold()); let top_block_title = Line::from(" durak tui test fre ".bold());
let top_block = Block::default() let top_block = Block::default()
.title(top_block_title.centered()) .title(top_block_title.centered())
.borders(Borders::ALL) .borders(Borders::ALL)
.style(Style::default()); .style(Style::default());
frame.render_widget(Paragraph::new(infos).block(top_block), chunks[0]); frame.render_widget(Paragraph::new(infos).block(top_block), chunks[0]);
let server_message = Text::from(vec![ let server_message = Text::from(vec![
Line::from(vec![ Line::from(vec![
"message: ".into(), "message: ".into(),
app.response.clone().blue(), app.response.clone().blue(),
]) ])
]); ]);
let btm_block_title = Line::from(" messaggini carini :3 ".bold()); let btm_block_title = Line::from(" messaggini carini :3 ".bold());
let btm_block = Block::default() let btm_block = Block::default()
.title(btm_block_title.centered()) .title(btm_block_title.centered())
.title_bottom(instructions.centered()) .title_bottom(instructions.centered())
.borders(Borders::ALL) .borders(Borders::ALL)
.style(Style::default()); .style(Style::default());
frame.render_widget( frame.render_widget(
Paragraph::new(server_message) Paragraph::new(server_message)
.wrap(Wrap { trim: true, }) .wrap(Wrap { trim: true, })
.block(btm_block), .block(btm_block),
chunks[1], chunks[1],
); );
}
CurrentScreen::LobbyList => todo!(),
}
let popup_area = Rect { let popup_area = Rect {
x: frame.area().width / 4, x: frame.area().width / 4,