Implements leaving on the client side

This commit is contained in:
2025-06-24 16:49:21 +02:00
parent d11e31149b
commit fbe456a0f5
43 changed files with 1730 additions and 10 deletions

View File

@@ -0,0 +1,34 @@
use std::fmt::Display;
use async_trait::async_trait;
use gamenight_api_client_rs::{apis::default_api::leave_post, models::GamenightId};
use uuid::Uuid;
use super::{Flow, FlowOutcome, FlowResult, GamenightState};
#[derive(Clone)]
pub struct Leave {
gamenight_id: Uuid
}
impl Leave {
pub fn new(gamenight_id: Uuid) -> Self {
Self {
gamenight_id
}
}
}
#[async_trait]
impl<'a> Flow<'a> for Leave {
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
let _ = leave_post(&state.configuration, Some(GamenightId{gamenight_id: self.gamenight_id.to_string()})).await?;
Ok((FlowOutcome::Successful, state))
}
}
impl Display for Leave {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Leave")
}
}

View File

@@ -14,6 +14,7 @@ mod list_gamenights;
mod add_gamenight;
mod view_gamenight;
mod join;
mod leave;
pub struct GamenightState {
configuration: Configuration,

View File

@@ -1,9 +1,11 @@
use gamenight_api_client_rs::{apis::default_api::{participants_get, user_get}, models::{GamenightId, UserId}};
use inquire::Select;
use jsonwebtoken::{decode, DecodingKey, Validation};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::{domain::{gamenight::Gamenight, user::User}, flows::{exit::Exit, join::Join}};
use crate::{domain::{gamenight::Gamenight, user::User}, flows::{exit::Exit, join::Join, leave::Leave}};
use super::*;
@@ -21,12 +23,26 @@ impl ViewGamenight {
}
fn vec_user_to_usernames_string(users: Vec<User>) -> String {
fn vec_user_to_usernames_string(users: &Vec<User>) -> String {
let string_list: Vec<String> = users.iter().map(|x| {format!("{}", x)}).collect();
string_list.join(", ")
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
exp: i64,
uid: Uuid
}
impl From<jsonwebtoken::errors::Error> for FlowError {
fn from(value: jsonwebtoken::errors::Error) -> Self {
Self {
error: value.to_string()
}
}
}
#[async_trait]
impl<'a> Flow<'a> for ViewGamenight {
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
@@ -41,9 +57,25 @@ impl<'a> Flow<'a> for ViewGamenight {
});
}
println!("{}\nwho: {}", self.gamenight, vec_user_to_usernames_string(users));
println!("{}\nwho: {}", self.gamenight, vec_user_to_usernames_string(&users));
let decoding_key = DecodingKey::from_secret(b"");
let mut validation = Validation::default();
validation.insecure_disable_signature_validation();
let claims = decode::<Claims>(
&state.configuration.bearer_access_token.as_ref().unwrap(),
&decoding_key,
&validation)?.claims;
let join_or_leave: Box<dyn Flow<'a> + Send> =
if users.iter().map(|x| {x.id}).find(|x| *x == claims.uid) != None {
Box::new(Leave::new(claims.uid))
}
else {
Box::new(Join::new(claims.uid))
};
let options: Vec<Box<dyn Flow<'a> + Send>> = vec![
Box::new(Join::new(self.gamenight.id)),
join_or_leave,
Box::new(Exit::new())
];
let choice = Select::new("What do you want to do:", options)