use gloo_net::http::Request;
use gloo_net::Error;
use gloo_storage::errors::StorageError;
use gloo_storage::{LocalStorage, Storage};
use patternfly_yew::{Toast, ToastDispatcher, ToastViewer, Type};
use serde::{Deserialize, Serialize};
use yew::prelude::*;
use yew_router::prelude::*;
#[derive(Clone, Deserialize, PartialEq, Serialize)]
struct User {
id: String,
banned: bool,
blacklisted: bool,
experience: u32,
level: u32,
money: u32,
moneylimit: u32,
steamid: String,
discordid: String,
discordname: String,
}
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/")]
Home,
#[at("/about")]
About,
#[at("/test")]
Test,
#[at("/404")]
NotFound,
}
#[function_component(About)]
fn about() -> Html {
let _history = use_history().unwrap();
let test: String = LocalStorage::get("test").unwrap_or(String::from("nop"));
html! {
<>
{ "À propos" }
{ test }
>
}
}
struct Home {
value: String,
user: Option,
}
#[derive(PartialEq)]
enum TestMessage {
Test,
Toast(ToastType),
ConnexionOk(User),
}
#[derive(PartialEq)]
struct ToastFields {
pub title: String,
pub body: String,
}
#[derive(PartialEq)]
enum ToastType {
Info(ToastFields),
Error(ToastFields),
}
impl Component for Home {
type Message = TestMessage;
type Properties = ();
fn create(_ctx: &Context) -> Self {
Self {
value: String::from("coucou"),
user: None,
}
}
fn view(&self, ctx: &Context) -> Html {
let user: Result = LocalStorage::get("auth");
if let Ok(user) = user {
if let None = self.user {
ctx.link().send_message(TestMessage::ConnexionOk(user));
}
} else {
ctx.link().send_future_batch(async {
match Request::get("/api/users/current").send().await {
Ok(resp) => {
if resp.ok() {
let json: Result = resp.json().await;
match json {
Ok(json) => {
let user = json.clone();
match LocalStorage::set("auth", json) {
Ok(_) => vec![
TestMessage::Toast(ToastType::Info(ToastFields {
title: String::from("Connexion réussie !"),
body: String::new(),
})),
TestMessage::ConnexionOk(user),
],
Err(err) => vec![TestMessage::Toast(ToastType::Error(
ToastFields {
title: String::from("Error from the promise"),
body: err.to_string(),
},
))],
}
}
Err(err) => {
LocalStorage::delete("auth");
vec![TestMessage::Toast(ToastType::Error(ToastFields {
title: String::from("Error from the promise"),
body: err.to_string(),
}))]
}
}
} else {
vec![TestMessage::Toast(ToastType::Error(ToastFields {
title: String::from("Error from the promise"),
body: String::from("L'API ne retourne pas un code 200."),
}))]
}
}
Err(err) => vec![TestMessage::Toast(ToastType::Error(ToastFields {
title: String::from("Error from the promise"),
body: err.to_string(),
}))],
}
});
}
//let onclick = ctx.link().callback(|_| TestMessage::Test);
html! {
<>
if let Some(user) = &self.user {
{ format!("Bienvenue {} !", user.discordname) }
if user.discordid.is_empty() {
{ "SE CONNECTER VIA DISCORD ICI" }
}
if user.steamid.is_empty() {
{ "SE CONNECTER VIA STEAM ICI" }
}
} else {
{ "SE CONNECTER VIA DISCORD ICI" }
{ "SE CONNECTER VIA STEAM ICI" }
}
//
>
}
}
fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool {
match msg {
TestMessage::ConnexionOk(user) => {
self.user = Some(user);
return true;
}
TestMessage::Toast(toast) => match toast {
ToastType::Info(infos) => ToastDispatcher::new().toast(Toast {
title: infos.title,
r#type: Type::Info,
..Default::default()
}),
ToastType::Error(infos) => ToastDispatcher::new().toast(Toast {
title: infos.title,
r#type: Type::Danger,
body: html! { { infos.body }
},
..Default::default()
}),
},
//_ => ToastDispatcher::new().toast(html! {}),
_ => ToastDispatcher::new().toast(Toast {
title: String::from("Un callback n'a pas été implémenté !"),
r#type: Type::Warning,
..Default::default()
}),
}
false
/*
if msg == TestMessage::Test {
self.value = String::from("nouveau");
true
} else if let TestMessage::StatusConnection(_) = msg {
self.value = String::from("yes ça marche");
true
} else {
false
}
*/
}
}
#[derive(Deserialize, Serialize)]
struct Game {
name: String,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
struct Group {
pub name: String,
pub game: String,
}
impl Group {
pub async fn get_game_name(&mut self) {
match Request::get(&format!("/api/games/{}", self.game))
.send()
.await
{
Ok(resp) => {
if resp.ok() {
let json: Result = resp.json().await;
match json {
Ok(json) => self.game = json.name,
Err(err) => log::info!("{}", err.to_string()),
}
}
}
Err(err) => (),
}
}
}
struct ListGroups {
idUser: String,
groups: Vec,
nb_show: usize,
}
#[derive(PartialEq, Properties)]
struct PropGroups {
id: String,
}
#[derive(PartialEq)]
enum MsgListGroups {
Done(Vec),
Info(String, String),
Error(String, String),
More,
}
impl Component for ListGroups {
type Message = MsgListGroups;
type Properties = PropGroups;
fn create(ctx: &Context) -> Self {
Self {
idUser: ctx.props().id.clone(),
groups: Vec::new(),
nb_show: 0,
}
}
fn view(&self, ctx: &Context) -> Html {
if self.groups.len() == 0 {
let id = self.idUser.clone();
ctx.link().send_future(async move {
match Request::get(&format!("/api/users/{}/groups", id))
.send()
.await
{
Ok(resp) => {
if resp.ok() {
let json: Result, Error> = resp.json().await;
match json {
Ok(mut json) => {
for item in json.iter_mut() {
item.get_game_name().await;
}
return MsgListGroups::Done(json);
}
Err(err) => {
log::info!("{}", err.to_string());
()
}
}
}
}
Err(err) => (),
};
MsgListGroups::Info(String::from("Ok"), String::new())
});
}
let onclick = ctx.link().callback(|_| MsgListGroups::More);
html! {
<>
if self.groups.len() > 0 {
{
self.groups[..self.nb_show].iter().map(|group| { html!{
{ group.name.clone() }
} }).collect::()
}
if self.nb_show < self.groups.len() {
}
} else {
{ "Vous n'êtes dans aucun groupe." }
}
//{ "coucou" }
>
}
}
fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool {
match msg {
MsgListGroups::Info(title, body) => {
if let Some(parent) = ctx.link().get_parent() {
(parent.clone())
.downcast::()
.send_message(TestMessage::Toast(ToastType::Info(ToastFields {
title,
body,
})))
}
}
MsgListGroups::Error(title, body) => {
if let Some(parent) = ctx.link().get_parent() {
(parent.clone())
.downcast::()
.send_message(TestMessage::Toast(ToastType::Error(ToastFields {
title,
body,
})))
}
}
MsgListGroups::Done(groups) => {
self.groups = groups;
return true;
}
MsgListGroups::More => {
self.nb_show += 3;
if self.nb_show > self.groups.len() {
self.nb_show -= self.nb_show - self.groups.len();
}
return true;
}
}
false
}
}
fn switch(route: &Route) -> Html {
match route {
Route::Home => html! { },
Route::About => html! { },
Route::NotFound => html! { {"404, déso"}
},
Route::Test => html! { },
}
}
#[function_component(App)]
fn app() -> Html {
html! {
render={Switch::render(switch)} />
}
}
fn main() {
wasm_logger::init(wasm_logger::Config::default());
yew::start_app::();
}
#[function_component(Test)]
fn test() -> Html {
let test = use_state(|| String::from(""));
{
let test = test.clone();
wasm_bindgen_futures::spawn_local(async move {
if let Ok(o) = Request::get("/test").send().await {
test.set(o.text().await.unwrap())
} else {
test.set(String::from("Pas de connexion !!"))
};
});
}
html! {
<>
{ "Moi !!!" }
{ (*test).clone() }
>
}
}