DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

f6c7f0a741fcfcf22ab948663026d812abe2e135 — Jonni Liljamo 1 year, 7 months ago ac88eb9
feat(client): enable the play menu in a crippled state
9 files changed, 136 insertions(+), 688 deletions(-)

M client/src/plugins/menu/mod.rs
M client/src/plugins/menu/ui/mod.rs
D client/src/plugins/menu/ui/play/allformingcall.rs
D client/src/plugins/menu/ui/play/creategamecall.rs
D client/src/plugins/menu/ui/play/joingamecall.rs
M client/src/plugins/menu/ui/play/mod.rs
D client/src/plugins/menu/ui/play/mygamescall.rs
D client/src/plugins/menu/ui/play/startgamecall.rs
M client/src/plugins/menu/ui/play/ui.rs
M client/src/plugins/menu/mod.rs => client/src/plugins/menu/mod.rs +3 -1
@@ 22,8 22,10 @@ impl Plugin for MenuPlugin {
            add_loopless_state(MenuState::None)
            .add_enter_system(GameState::MainMenu, menu_setup)
            .insert_resource(ui::connect::ConnectScreenData::default())
            .insert_resource(ui::play::PlayScreenData::default())
            .add_system(ui::connect::ui.run_in_state(MenuState::Connect))
            .add_system(ui::menu::ui.run_in_state(MenuState::Menu));
            .add_system(ui::menu::ui.run_in_state(MenuState::Menu))
            .add_system(ui::play::ui.run_in_state(MenuState::Play));
    }
}


M client/src/plugins/menu/ui/mod.rs => client/src/plugins/menu/ui/mod.rs +1 -0
@@ 9,3 9,4 @@
pub mod menu;

pub mod connect;
pub mod play;

D client/src/plugins/menu/ui/play/allformingcall.rs => client/src/plugins/menu/ui/play/allformingcall.rs +0 -82
@@ 1,82 0,0 @@
/*
 * This file is part of laurelin/client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;

use futures_lite::future;

use crate::{
    api::{self, game::ResponseAllForming},
    cfg::{CfgDev, CfgUser},
    runtime::menu::RTDMenu,
};

use super::AllFormingEvent;

struct AllFormingCallResponse {
    all_forming: ResponseAllForming,
}

#[derive(Component)]
pub(super) struct AllFormingCall(Task<AllFormingCallResponse>);

pub(super) fn start(
    mut events: EventReader<AllFormingEvent>,
    mut commands: Commands,
    cfg_dev: Res<CfgDev>,
    cfg_user: Res<CfgUser>,
    mut rtdmenu: ResMut<RTDMenu>,
) {
    for _event in events.iter() {
        let api_address = cfg_dev.api_server.clone();
        let token = cfg_user.user_token.clone();

        let thread_pool = AsyncComputeTaskPool::get();
        let task = thread_pool.spawn(async move {
            let all_forming_response = api::game::all_forming(api_address, token);

            AllFormingCallResponse {
                all_forming: all_forming_response,
            }
        });
        commands.spawn(AllFormingCall(task));
        rtdmenu.waiting_for_all_forming_call = true;
    }
}

pub(super) fn handle(
    mut commands: Commands,
    mut all_forming_call_tasks: Query<(Entity, &mut AllFormingCall)>,
    mut rtdmenu: ResMut<RTDMenu>,
    mut console: EventWriter<PrintConsoleLine>,
) {
    if all_forming_call_tasks.is_empty() {
        return;
    }

    let (entity, mut task) = all_forming_call_tasks.single_mut();
    if let Some(all_forming_call_response) = future::block_on(future::poll_once(&mut task.0)) {
        rtdmenu.waiting_for_all_forming_call = false;
        match all_forming_call_response.all_forming {
            ResponseAllForming::Valid(res) => rtdmenu.all_forming_games = res,
            ResponseAllForming::Error(error) => {
                console.send(PrintConsoleLine::new(
                    format!("Fetching all forming games failed, got error: '{}'", error).into(),
                ));
            }
        }

        // Remove the task, since it's done now
        commands.entity(entity).remove::<AllFormingCall>();
        commands.entity(entity).despawn_recursive();
    }
}

D client/src/plugins/menu/ui/play/creategamecall.rs => client/src/plugins/menu/ui/play/creategamecall.rs +0 -89
@@ 1,89 0,0 @@
/*
 * This file is part of laurelin/client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;

use futures_lite::future;

use crate::{
    api::{self, game::ResponseCreateGame},
    cfg::{CfgDev, CfgUser},
    runtime::menu::{PlayMenuUIState, RTDMenu},
};

use super::CreateGameEvent;

struct CreateGameCallResponse {
    game: ResponseCreateGame,
}

#[derive(Component)]
pub(super) struct CreateGameCall(Task<CreateGameCallResponse>);

pub(super) fn start(
    mut events: EventReader<CreateGameEvent>,
    mut commands: Commands,
    cfg_dev: Res<CfgDev>,
    cfg_user: Res<CfgUser>,
    mut rtdmenu: ResMut<RTDMenu>,
) {
    for _event in events.iter() {
        let api_address = cfg_dev.api_server.clone();
        let token = cfg_user.user_token.clone();

        let thread_pool = AsyncComputeTaskPool::get();
        let task = thread_pool.spawn(async move {
            let create_game_response = api::game::create(api_address, token);

            CreateGameCallResponse {
                game: create_game_response,
            }
        });
        commands.spawn(CreateGameCall(task));
        rtdmenu.waiting_for_create_game_call = true;
    }
}

pub(super) fn handle(
    mut commands: Commands,
    mut create_game_call_tasks: Query<(Entity, &mut CreateGameCall)>,
    mut rtdmenu: ResMut<RTDMenu>,
    mut console: EventWriter<PrintConsoleLine>,
) {
    if create_game_call_tasks.is_empty() {
        return;
    }

    let (entity, mut task) = create_game_call_tasks.single_mut();
    if let Some(create_game_call_response) = future::block_on(future::poll_once(&mut task.0)) {
        rtdmenu.waiting_for_create_game_call = false;
        match create_game_call_response.game {
            ResponseCreateGame::Valid(res) => {
                rtdmenu.cur_game = Some(res.clone());
                rtdmenu.play_menu_ui_state = PlayMenuUIState::InLobbyHost;

                console.send(PrintConsoleLine::new(
                    format!("Created game with id: '{}'", res.id).into(),
                ));
            }
            ResponseCreateGame::Error(error) => {
                console.send(PrintConsoleLine::new(
                    format!("Game creation failed, got error: '{}'", error).into(),
                ));
            }
        }

        // Remove the task, since it's done now
        commands.entity(entity).remove::<CreateGameCall>();
        commands.entity(entity).despawn_recursive();
    }
}

D client/src/plugins/menu/ui/play/joingamecall.rs => client/src/plugins/menu/ui/play/joingamecall.rs +0 -93
@@ 1,93 0,0 @@
/*
 * This file is part of laurelin/client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;

use futures_lite::future;

use crate::{
    api::{self, game::ResponseJoinGame},
    cfg::{CfgDev, CfgUser},
    runtime::menu::{PlayMenuUIState, RTDMenu},
};

use super::JoinGameEvent;

struct JoinGameCallResponse {
    res: ResponseJoinGame,
}

#[derive(Component)]
pub(super) struct JoinGameCall(Task<JoinGameCallResponse>);

pub(super) fn start(
    mut events: EventReader<JoinGameEvent>,
    mut commands: Commands,
    cfg_dev: Res<CfgDev>,
    cfg_user: Res<CfgUser>,
    mut rtdmenu: ResMut<RTDMenu>,
) {
    for _event in events.iter() {
        let api_address = cfg_dev.api_server.clone();
        let token = cfg_user.user_token.clone();
        let game_id = rtdmenu.cur_game.as_ref().unwrap().id.clone();

        let thread_pool = AsyncComputeTaskPool::get();
        let task = thread_pool.spawn(async move {
            let join_game_response = api::game::join(api_address, token, game_id);

            JoinGameCallResponse {
                res: join_game_response,
            }
        });
        commands.spawn(JoinGameCall(task));
        rtdmenu.waiting_for_join_game_call = true;
    }
}

pub(super) fn handle(
    mut commands: Commands,
    mut join_game_call_tasks: Query<(Entity, &mut JoinGameCall)>,
    mut rtdmenu: ResMut<RTDMenu>,
    mut console: EventWriter<PrintConsoleLine>,
) {
    if join_game_call_tasks.is_empty() {
        return;
    }

    let (entity, mut task) = join_game_call_tasks.single_mut();
    if let Some(join_game_call_response) = future::block_on(future::poll_once(&mut task.0)) {
        rtdmenu.waiting_for_join_game_call = false;
        match join_game_call_response.res {
            ResponseJoinGame::Valid(_res) => {
                rtdmenu.play_menu_ui_state = PlayMenuUIState::InLobbyGuest;

                console.send(PrintConsoleLine::new(
                    format!(
                        "Joined game with id: '{}'",
                        rtdmenu.cur_game.as_ref().unwrap().id
                    )
                    .into(),
                ));
            }
            ResponseJoinGame::Error(error) => {
                console.send(PrintConsoleLine::new(
                    format!("Join game failed, got error: '{}'", error).into(),
                ));
            }
        }

        // Remove the task, since it's done now
        commands.entity(entity).remove::<JoinGameCall>();
        commands.entity(entity).despawn_recursive();
    }
}

M client/src/plugins/menu/ui/play/mod.rs => client/src/plugins/menu/ui/play/mod.rs +19 -73
@@ 6,84 6,30 @@
 * See LICENSE for licensing information.
 */

use bevy::prelude::*;
use iyes_loopless::prelude::*;

use crate::runtime::menu::RTDMenu;

use super::MenuState;
use bevy::ecs::system::Resource;

mod ui;
pub use ui::*;

mod allformingcall;
mod creategamecall;
mod joingamecall;
mod mygamescall;
mod startgamecall;

struct CreateGameEvent;
struct AllFormingEvent;
struct JoinGameEvent;
struct MyGamesEvent;
struct StartGameEvent;

pub(super) struct PlayMenuPlugin;

impl Plugin for PlayMenuPlugin {
    fn build(&self, app: &mut App) {
        app.add_loopless_state(PlayMenuState::None)
            .add_event::<CreateGameEvent>()
            .add_event::<AllFormingEvent>()
            .add_event::<JoinGameEvent>()
            .add_event::<MyGamesEvent>()
            .add_event::<StartGameEvent>()
            .add_enter_system(MenuState::Play, play_menu_setup)
            .add_system_set(
                ConditionSet::new()
                    .run_in_state(PlayMenuState::Visible)
                    .with_system(ui::show)
                    .with_system(creategamecall::start.run_on_event::<CreateGameEvent>())
                    .with_system(creategamecall::handle.run_if(waiting_for_create_game_call))
                    .with_system(allformingcall::start.run_on_event::<AllFormingEvent>())
                    .with_system(allformingcall::handle.run_if(waiting_for_all_forming_call))
                    .with_system(joingamecall::start.run_on_event::<JoinGameEvent>())
                    .with_system(joingamecall::handle.run_if(waiting_for_join_game_call))
                    .with_system(mygamescall::start.run_on_event::<MyGamesEvent>())
                    .with_system(mygamescall::handle.run_if(waiting_for_my_games_call))
                    .with_system(startgamecall::start.run_on_event::<StartGameEvent>())
                    .with_system(startgamecall::handle.run_if(waiting_for_start_game_call))
                    .into(),
            );
    }
}

/// Play Menu State
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(super) enum PlayMenuState {
    None,
    Visible,
}

fn play_menu_setup(mut commands: Commands) {
    commands.insert_resource(NextState(PlayMenuState::Visible))
}

fn waiting_for_create_game_call(rtdmenu: Res<RTDMenu>) -> bool {
    rtdmenu.waiting_for_create_game_call
}

fn waiting_for_all_forming_call(rtdmenu: Res<RTDMenu>) -> bool {
    rtdmenu.waiting_for_all_forming_call
}

fn waiting_for_join_game_call(rtdmenu: Res<RTDMenu>) -> bool {
    rtdmenu.waiting_for_join_game_call
#[derive(Default, Resource)]
pub struct PlayScreenData {
    pub state: PlayScreenState,
    pub browse_state: PlayScreenBrowseState,
}

fn waiting_for_my_games_call(rtdmenu: Res<RTDMenu>) -> bool {
    rtdmenu.waiting_for_my_games_call
#[derive(Default, PartialEq)]
pub enum PlayScreenState {
    #[default]
    Main,
    CreateGame,
    InLobbyHost,
    InLobbyGuest,
}

fn waiting_for_start_game_call(rtdmenu: Res<RTDMenu>) -> bool {
    rtdmenu.waiting_for_start_game_call
#[derive(Default, PartialEq)]
pub enum PlayScreenBrowseState {
    #[default]
    Forming,
    InProgress,
    Finished,
}

D client/src/plugins/menu/ui/play/mygamescall.rs => client/src/plugins/menu/ui/play/mygamescall.rs +0 -82
@@ 1,82 0,0 @@
/*
 * This file is part of laurelin/client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;

use futures_lite::future;

use crate::{
    api::{self, game::ResponseMyGames},
    cfg::{CfgDev, CfgUser},
    runtime::menu::RTDMenu,
};

use super::MyGamesEvent;

struct MyGamesCallResponse {
    my_games: ResponseMyGames,
}

#[derive(Component)]
pub(super) struct MyGamesCall(Task<MyGamesCallResponse>);

pub(super) fn start(
    mut events: EventReader<MyGamesEvent>,
    mut commands: Commands,
    cfg_dev: Res<CfgDev>,
    cfg_user: Res<CfgUser>,
    mut rtdmenu: ResMut<RTDMenu>,
) {
    for _event in events.iter() {
        let api_address = cfg_dev.api_server.clone();
        let token = cfg_user.user_token.clone();

        let thread_pool = AsyncComputeTaskPool::get();
        let task = thread_pool.spawn(async move {
            let my_games_response = api::game::my_games(api_address, token);

            MyGamesCallResponse {
                my_games: my_games_response,
            }
        });
        commands.spawn(MyGamesCall(task));
        rtdmenu.waiting_for_my_games_call = true;
    }
}

pub(super) fn handle(
    mut commands: Commands,
    mut my_games_call_tasks: Query<(Entity, &mut MyGamesCall)>,
    mut rtdmenu: ResMut<RTDMenu>,
    mut console: EventWriter<PrintConsoleLine>,
) {
    if my_games_call_tasks.is_empty() {
        return;
    }

    let (entity, mut task) = my_games_call_tasks.single_mut();
    if let Some(my_games_call_response) = future::block_on(future::poll_once(&mut task.0)) {
        rtdmenu.waiting_for_my_games_call = false;
        match my_games_call_response.my_games {
            ResponseMyGames::Valid(res) => rtdmenu.my_games = res,
            ResponseMyGames::Error(error) => {
                console.send(PrintConsoleLine::new(
                    format!("Fetching own games failed, got error: '{}'", error).into(),
                ));
            }
        }

        // Remove the task, since it's done now
        commands.entity(entity).remove::<MyGamesCall>();
        commands.entity(entity).despawn_recursive();
    }
}

D client/src/plugins/menu/ui/play/startgamecall.rs => client/src/plugins/menu/ui/play/startgamecall.rs +0 -105
@@ 1,105 0,0 @@
/*
 * This file is part of laurelin/client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    tasks::{AsyncComputeTaskPool, Task},
};
use bevy_console::PrintConsoleLine;

use futures_lite::future;
use iyes_loopless::state::NextState;

use crate::{
    api::{
        self,
        game::{types::GameState, ResponsePatchGameState},
    },
    cfg::{CfgDev, CfgUser},
    runtime::{
        game::RTDGame,
        menu::{PlayMenuUIState, RTDMenu},
    },
};

use super::{PlayMenuState, StartGameEvent};

struct StartGameCallResponse {
    res: ResponsePatchGameState,
}

#[derive(Component)]
pub(super) struct StartGameCall(Task<StartGameCallResponse>);

pub(super) fn start(
    mut events: EventReader<StartGameEvent>,
    mut commands: Commands,
    cfg_dev: Res<CfgDev>,
    cfg_user: Res<CfgUser>,
    mut rtdmenu: ResMut<RTDMenu>,
) {
    for _event in events.iter() {
        let api_address = cfg_dev.api_server.clone();
        let token = cfg_user.user_token.clone();
        let game_id = rtdmenu.cur_game.as_ref().unwrap().id.clone();

        let thread_pool = AsyncComputeTaskPool::get();
        let task = thread_pool.spawn(async move {
            let patch_game_state_response =
                api::game::patch_state(api_address, token, game_id, GameState::InProgress);

            StartGameCallResponse {
                res: patch_game_state_response,
            }
        });
        commands.spawn(StartGameCall(task));
        rtdmenu.waiting_for_start_game_call = true;
    }
}

pub(super) fn handle(
    mut commands: Commands,
    mut start_game_call_tasks: Query<(Entity, &mut StartGameCall)>,
    mut rtdmenu: ResMut<RTDMenu>,
    mut rtdgame: ResMut<RTDGame>,
    mut console: EventWriter<PrintConsoleLine>,
) {
    if start_game_call_tasks.is_empty() {
        return;
    }

    let (entity, mut task) = start_game_call_tasks.single_mut();
    if let Some(start_game_call_response) = future::block_on(future::poll_once(&mut task.0)) {
        rtdmenu.waiting_for_start_game_call = false;
        match start_game_call_response.res {
            ResponsePatchGameState::Valid(res) => {
                rtdmenu.play_menu_ui_state = PlayMenuUIState::Main;
                rtdgame.cur_game = Some(res);
                commands.insert_resource(NextState(PlayMenuState::None));
                commands.insert_resource(NextState(crate::GameState::Game));

                console.send(PrintConsoleLine::new(
                    format!(
                        "Started game with id: '{}'",
                        rtdmenu.cur_game.as_ref().unwrap().id
                    )
                    .into(),
                ));
            }
            ResponsePatchGameState::Error(error) => {
                console.send(PrintConsoleLine::new(
                    format!("Starting game failed, got error: '{}'", error).into(),
                ));
            }
        }

        // Remove the task, since it's done now
        commands.entity(entity).remove::<StartGameCall>();
        commands.entity(entity).despawn_recursive();
    }
}

M client/src/plugins/menu/ui/play/ui.rs => client/src/plugins/menu/ui/play/ui.rs +113 -163
@@ 10,188 10,141 @@ use bevy::prelude::*;
use bevy_inspector_egui::bevy_egui::{egui, EguiContext};
use iyes_loopless::prelude::*;

use crate::{
    api::game::types::GameState,
    cfg::CfgUser,
    plugins::menu::MenuState,
    runtime::menu::{BrowseMenuTab, PlayMenuUIState, RTDMenu},
};
use crate::{cfg::CfgUser, plugins::menu::MenuState, util::egui::menuwindow};

use super::{
    AllFormingEvent, CreateGameEvent, JoinGameEvent, MyGamesEvent, PlayMenuState, StartGameEvent,
};
use super::{PlayScreenBrowseState, PlayScreenData, PlayScreenState};

pub(super) fn show(
pub fn ui(
    mut commands: Commands,
    mut egui_context: ResMut<EguiContext>,
    mut rtdmenu: ResMut<RTDMenu>,
    mut data: ResMut<PlayScreenData>,
    cfg_user: Res<CfgUser>,
    mut creategame_ev_w: EventWriter<CreateGameEvent>,
    mut allforming_ev_w: EventWriter<AllFormingEvent>,
    mut joingame_ev_w: EventWriter<JoinGameEvent>,
    mut mygames_ev_w: EventWriter<MyGamesEvent>,
    mut startgame_ev_w: EventWriter<StartGameEvent>,
) {
    egui::Window::new(egui::RichText::new(rtdmenu.play_menu_ui_state.display()).size(32.))
        .resizable(false)
        .collapsible(false)
        .anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO)
        .fixed_size(egui::Vec2::new(800., 600.))
        .show(egui_context.ctx_mut(), |ui| {
            // Override egui style for this scope.
            let mut egui_style = (*ui.style_mut()).clone();
            egui_style.text_styles = [
                (
                    egui::TextStyle::Heading,
                    egui::FontId::new(30.0, egui::FontFamily::Proportional),
                ),
                (
                    egui::TextStyle::Body,
                    egui::FontId::new(18.0, egui::FontFamily::Proportional),
                ),
                (
                    egui::TextStyle::Monospace,
                    egui::FontId::new(14.0, egui::FontFamily::Proportional),
                ),
                (
                    egui::TextStyle::Button,
                    egui::FontId::new(24.0, egui::FontFamily::Proportional),
                ),
                (
                    egui::TextStyle::Small,
                    egui::FontId::new(10.0, egui::FontFamily::Proportional),
                ),
            ]
            .into();
            ui.set_style(egui_style);

            match rtdmenu.play_menu_ui_state {
                PlayMenuUIState::Main => {
                    egui::SidePanel::left("play_side_panel")
                        .resizable(false)
                        .show_inside(ui, |ui| {
                            ui.vertical_centered(|ui| {
                                if ui.button("Create").clicked() {
                                    rtdmenu.play_menu_ui_state = PlayMenuUIState::CreateGame
                                }
    // TODO: title used to be: rtdmenu.play_menu_ui_state.display()).size(32.)
    menuwindow(
        egui_context.ctx_mut(),
        "TEMP",
        &egui::Vec2::new(800., 600.),
        |ui| match data.state {
            PlayScreenState::Main => {
                egui::SidePanel::left("play_side_panel")
                    .resizable(false)
                    .show_inside(ui, |ui| {
                        ui.vertical_centered(|ui| {
                            if ui.button("Create").clicked() {
                                data.state = PlayScreenState::CreateGame;
                            }

                                if ui.button("Back").clicked() {
                                    commands.insert_resource(NextState(PlayMenuState::None));
                                    commands.insert_resource(NextState(MenuState::Main));
                                }
                            });
                            if ui.button("Back").clicked() {
                                commands.insert_resource(NextState(MenuState::Menu));
                            }
                        });
                    });

                    egui::TopBottomPanel::top("play_top_panel")
                        .resizable(false)
                        .show_inside(ui, |ui| {
                            ui.horizontal(|ui| {
                                ui.label(egui::RichText::new("Browse: ").size(24.));
                egui::TopBottomPanel::top("play_top_panel")
                    .resizable(false)
                    .show_inside(ui, |ui| {
                        ui.horizontal(|ui| {
                            ui.label(egui::RichText::new("Browse: ").size(24.));

                                ui.selectable_value(
                                    &mut rtdmenu.browse_tab,
                                    BrowseMenuTab::Forming,
                                    "Forming",
                                );
                                ui.selectable_value(
                                    &mut rtdmenu.browse_tab,
                                    BrowseMenuTab::InProgress,
                                    "In Progress",
                                );
                                ui.selectable_value(
                                    &mut rtdmenu.browse_tab,
                                    BrowseMenuTab::Finished,
                                    "Finished",
                                );
                            ui.selectable_value(
                                &mut data.browse_state,
                                PlayScreenBrowseState::Forming,
                                "Forming",
                            );
                            ui.selectable_value(
                                &mut data.browse_state,
                                PlayScreenBrowseState::InProgress,
                                "In Progress",
                            );
                            ui.selectable_value(
                                &mut data.browse_state,
                                PlayScreenBrowseState::Finished,
                                "Finished",
                            );

                                ui.with_layout(
                                    egui::Layout::right_to_left(egui::Align::Center),
                                    |ui| {
                                        if ui.button("Refresh").clicked() {
                                            match rtdmenu.browse_tab {
                                                BrowseMenuTab::Forming => {
                                                    if !rtdmenu.waiting_for_all_forming_call {
                                                        allforming_ev_w.send(AllFormingEvent);
                                                    }
                                                }
                                                BrowseMenuTab::InProgress => {
                                                    if !rtdmenu.waiting_for_my_games_call {
                                                        mygames_ev_w.send(MyGamesEvent);
                                                    }
                                                }
                                                BrowseMenuTab::Finished => {
                                                    if !rtdmenu.waiting_for_my_games_call {
                                                        mygames_ev_w.send(MyGamesEvent);
                                                    }
                                                }
                            ui.with_layout(
                                egui::Layout::right_to_left(egui::Align::Center),
                                |ui| {
                                    if ui.button("Refresh").clicked() {
                                        match data.browse_state {
                                            PlayScreenBrowseState::Forming => {
                                                //if !rtdmenu.waiting_for_all_forming_call {
                                                //    allforming_ev_w.send(AllFormingEvent);
                                                //}
                                            }
                                            PlayScreenBrowseState::InProgress => {
                                                //if !rtdmenu.waiting_for_my_games_call {
                                                //    mygames_ev_w.send(MyGamesEvent);
                                                //}
                                            }
                                            PlayScreenBrowseState::Finished => {
                                                //if !rtdmenu.waiting_for_my_games_call {
                                                //    mygames_ev_w.send(MyGamesEvent);
                                                //}
                                            }
                                        }
                                    },
                                );
                            });
                                    }
                                },
                            );
                        });
                    });

                    ui.vertical_centered(|ui| {
                        egui::ScrollArea::vertical().show(ui, |mut ui| match rtdmenu.browse_tab {
                            BrowseMenuTab::Forming => {
                                browse_forming(
                                    &mut ui,
                                    &mut rtdmenu,
                                    &cfg_user,
                                    &mut joingame_ev_w,
                                );
                            }
                            BrowseMenuTab::InProgress => {
                                browse_inprogress(&mut ui, &mut rtdmenu);
                            }
                            BrowseMenuTab::Finished => {
                                browse_finished(&mut ui, &mut rtdmenu);
                            }
                        });
                ui.vertical_centered(|ui| {
                    egui::ScrollArea::vertical().show(ui, |mut ui| match data.browse_state {
                        PlayScreenBrowseState::Forming => {
                            browse_forming(&mut ui, &mut data, &cfg_user);
                        }
                        PlayScreenBrowseState::InProgress => {
                            browse_inprogress(&mut ui, &mut data);
                        }
                        PlayScreenBrowseState::Finished => {
                            browse_finished(&mut ui, &mut data);
                        }
                    });
                }
                PlayMenuUIState::CreateGame => {
                    ui.vertical_centered(|ui| {
                        ui.add_enabled_ui(!rtdmenu.waiting_for_create_game_call, |ui| {
                });
            }
            PlayScreenState::CreateGame => {
                ui.vertical_centered(|ui| {
                    ui.add_enabled_ui(
                        /* !rtdmenu.waiting_for_create_game_call */ false,
                        |ui| {
                            if ui.button("Confirm").clicked() {
                                creategame_ev_w.send(CreateGameEvent);
                                //creategame_ev_w.send(CreateGameEvent);
                            }

                            if ui.button("Cancel").clicked() {
                                rtdmenu.play_menu_ui_state = PlayMenuUIState::Main
                                data.state = PlayScreenState::Main;
                            }
                        });
                    });
                        },
                    );
                });
            }
            PlayScreenState::InLobbyHost => {
                if ui.button("Start").clicked() {
                    //startgame_ev_w.send(StartGameEvent);
                }
                PlayMenuUIState::InLobbyHost => {
                    if ui.button("Start").clicked() {
                        startgame_ev_w.send(StartGameEvent);
                    }

                    if ui.button("Back").clicked() {
                        rtdmenu.play_menu_ui_state = PlayMenuUIState::Main
                    }
                if ui.button("Back").clicked() {
                    data.state = PlayScreenState::Main;
                }
                PlayMenuUIState::InLobbyGuest => {
                    ui.label(egui::RichText::new(format!(
                        "Host: {}",
                        rtdmenu.cur_game.as_ref().unwrap().host.username
                    )));
            }
            PlayScreenState::InLobbyGuest => {
                //ui.label(egui::RichText::new(format!(
                //    "Host: {}",
                //    rtdmenu.cur_game.as_ref().unwrap().host.username
                //)));

                    if ui.button("Back").clicked() {
                        rtdmenu.play_menu_ui_state = PlayMenuUIState::Main
                    }
                if ui.button("Back").clicked() {
                    data.state = PlayScreenState::Main;
                }
            }
        });
        },
    );
}

fn browse_forming(
    ui: &mut egui::Ui,
    rtdmenu: &mut RTDMenu,
    cfg_user: &CfgUser,
    joingame_ev_w: &mut EventWriter<JoinGameEvent>,
) {
fn browse_forming(ui: &mut egui::Ui, rtdmenu: &mut PlayScreenData, cfg_user: &CfgUser) {
    /*
    if rtdmenu.waiting_for_all_forming_call {
        ui.horizontal(|ui| {
            ui.spinner();


@@ 240,13 193,11 @@ fn browse_forming(
            }
        }
    }
    */
}

fn browse_inprogress(
    ui: &mut egui::Ui,
    rtdmenu: &mut RTDMenu,
    /*resumegame_ev_w: &mut EventWriter<ResumeGameEvent>*/
) {
fn browse_inprogress(ui: &mut egui::Ui, rtdmenu: &mut PlayScreenData) {
    /*
    if rtdmenu.waiting_for_my_games_call {
        ui.horizontal(|ui| {
            ui.spinner();


@@ 282,13 233,11 @@ fn browse_inprogress(
            }
        }
    }
    */
}

fn browse_finished(
    ui: &mut egui::Ui,
    rtdmenu: &mut RTDMenu,
    /*resumegame_ev_w: &mut EventWriter<ResumeGameEvent>*/
) {
fn browse_finished(ui: &mut egui::Ui, rtdmenu: &mut PlayScreenData) {
    /*
    if rtdmenu.waiting_for_my_games_call {
        ui.horizontal(|ui| {
            ui.spinner();


@@ 315,4 264,5 @@ fn browse_finished(
            }
        }
    }
    */
}