/* * This file is part of sdbclient * Copyright (C) 2022 Jonni Liljamo * * 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, user::ResponseToken}, cfg::{self, CfgDev, CfgDirs, CfgUser}, util, }; use super::MenuState; pub mod ui; pub struct AccountLoginPlugin; impl Plugin for AccountLoginPlugin { fn build(&self, app: &mut App) { app.add_state(LoginState::None) // UI system .insert_resource(ui::InputsUserLogin::new()) .add_system_set( SystemSet::on_update(LoginState::Input).with_system(ui::account_login_ui), ) // Login system, as in calling the API .add_system_set( SystemSet::on_enter(LoginState::LoggingIn).with_system(start_login_call), ) .add_system_set( SystemSet::on_update(LoginState::LoggingIn).with_system(handle_login_call), ); } } /// Login State #[derive(Clone, Eq, PartialEq, Debug, Hash)] pub enum LoginState { None, Input, LoggingIn, } #[derive(Component)] struct LoginCall(Task); fn start_login_call( mut commands: Commands, cfg_dev: Res, inputs: Res, ) { let api_address = cfg_dev.api_server.clone(); let i = inputs.clone(); let thread_pool = AsyncComputeTaskPool::get(); let task = thread_pool.spawn(async move { let token_response = api::user::token(api_address, i.email, i.password); token_response }); commands.spawn(LoginCall(task)); } fn handle_login_call( mut commands: Commands, mut login_call_tasks: Query<(Entity, &mut LoginCall)>, mut inputs: ResMut, mut login_state: ResMut>, mut menu_state: ResMut>, mut cfg_user: ResMut, cfg_dirs: Res, mut console: EventWriter, ) { let (entity, mut task) = login_call_tasks.single_mut(); if let Some(login_response) = future::block_on(future::poll_once(&mut task.0)) { match login_response { ResponseToken::Valid(res) => { console.send(PrintConsoleLine::new(format!( "Logged in with: {}", inputs.email ))); // TODO: We need to fetch the user details at some point. *cfg_user = CfgUser { logged_in: true, user_token: res.token, id: res.id, username: "NOT SET".to_string(), email: "NOT SET".to_string(), }; util::sl::save( cfg_dirs.0.config_dir().to_str().unwrap(), cfg::FILE_CFG_USER, &cfg_user.into_inner(), console, ); login_state.set(LoginState::None).unwrap(); menu_state.set(MenuState::AccountLoggedIn).unwrap(); } ResponseToken::Error { error } => { inputs.error = error; login_state.set(LoginState::Input).unwrap(); } } // Remove the task, since it's done now commands.entity(entity).remove::(); commands.entity(entity).despawn_recursive(); } }