sakgjiodfkg
This commit is contained in:
parent
d0e802d77c
commit
e50b31fc3f
12 changed files with 182 additions and 78 deletions
|
@ -159,11 +159,11 @@ impl WengLinRating {
|
|||
log::debug!("Getting human score for: {rating:?}±{uncertainty:?}");
|
||||
let uncertain = self.0.rating - self.0.uncertainty;
|
||||
log::trace!("Minimum score is: {uncertain:?}");
|
||||
let multiplied = uncertain * 100.0;
|
||||
let multiplied = uncertain * 300.0 / 5.0;
|
||||
log::trace!("Multiplied score is: {multiplied:?}");
|
||||
let floored: f64 = multiplied.floor();
|
||||
log::trace!("Floored score is: {floored:?}");
|
||||
let converted: i64 = floored as i64;
|
||||
let ceiled: f64 = multiplied.ceil();
|
||||
log::trace!("Ceiled score is: {ceiled:?}");
|
||||
let converted: i64 = ceiled as i64;
|
||||
log::debug!("Human score for {rating:?}±{uncertainty:?} is {converted:?}");
|
||||
converted
|
||||
}
|
||||
|
@ -231,6 +231,15 @@ impl Match {
|
|||
.get_results::<Self>(conn)
|
||||
}
|
||||
|
||||
pub fn played_by(conn: &mut PgConnection, player_id: i32) -> QueryResult<Vec<Self>> {
|
||||
schema::matches::table
|
||||
.select(Self::as_select())
|
||||
.or_filter(schema::matches::player_a_id.eq(player_id))
|
||||
.or_filter(schema::matches::player_b_id.eq(player_id))
|
||||
.order_by(schema::matches::instant.desc())
|
||||
.get_results::<Self>(conn)
|
||||
}
|
||||
|
||||
pub fn played_by_count(conn: &mut PgConnection, player_id: i32) -> QueryResult<i64> {
|
||||
schema::matches::table
|
||||
.select(diesel::dsl::count_star())
|
||||
|
|
|
@ -75,6 +75,9 @@ async fn main() -> anyhow::Result<Infallible> {
|
|||
.route("/api/matches/",
|
||||
axum::routing::post(routes::matches::post_match)
|
||||
)
|
||||
.route("/api/matches/holycow/:player_id",
|
||||
axum::routing::post(routes::matches::get_played_by_id)
|
||||
)
|
||||
.nest("/telegram/webhook",
|
||||
telegram_router
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use axum::http::StatusCode;
|
||||
use axum::{Extension, Json};
|
||||
use axum::extract::Path;
|
||||
use diesel::{Connection, PgConnection};
|
||||
use serde::Deserialize;
|
||||
use skillratings::weng_lin::WengLinConfig;
|
||||
|
@ -9,6 +10,14 @@ use teloxide::types::{ChatId, MessageId, ParseMode, ThreadId};
|
|||
use crate::config;
|
||||
use crate::database::model::{Match, MatchI, Outcome, Player, WengLinRating};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct MatchII {
|
||||
name: Option<String>,
|
||||
player_a: i32,
|
||||
player_b: i32,
|
||||
outcome: Outcome,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn get_all()
|
||||
-> Result<Json<Vec<Match>>, StatusCode>
|
||||
|
@ -22,29 +31,46 @@ pub async fn get_all()
|
|||
Ok(Json(matches))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct MatchII {
|
||||
name: Option<String>,
|
||||
player_a: i32,
|
||||
player_b: i32,
|
||||
outcome: Outcome,
|
||||
#[axum::debug_handler]
|
||||
pub async fn get_played_by_id(
|
||||
Path(player_id): Path<i32>,
|
||||
)
|
||||
-> Result<Json<Vec<Match>>, StatusCode>
|
||||
{
|
||||
let mut conn = PgConnection::establish(config::DATABASE_URL())
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
let matches = Match::played_by(&mut conn, player_id)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
Ok(Json(matches))
|
||||
}
|
||||
|
||||
fn player_to_text(player: &Player, before: &WengLinRating, after: &WengLinRating) -> String {
|
||||
let name = &player.username;
|
||||
let competitive = &player.competitive;
|
||||
let telegram_id = &player.telegram_id;
|
||||
let telegram_id = &player.telegram_id.clone().map(|t| t.0);
|
||||
|
||||
match competitive {
|
||||
false => {
|
||||
format!("{name}")
|
||||
match telegram_id {
|
||||
None =>
|
||||
format!(r#"<b>{name}</b>"#),
|
||||
Some(telegram_id) =>
|
||||
format!(r#"<b><a href="tg://user?id={telegram_id}">{name}</a></b>"#),
|
||||
}
|
||||
},
|
||||
true => {
|
||||
let before = before.human_score();
|
||||
let after = after.human_score();
|
||||
let change = after - before;
|
||||
|
||||
format!(r#"<b><a href="tg://user?id={telegram_id}">{name}</a></b> <i>({change:+})</i>"#)
|
||||
match telegram_id {
|
||||
None =>
|
||||
format!(r#"<b>{name}</b> ({change:+} ★)"#),
|
||||
Some(telegram_id) =>
|
||||
format!(r#"<b><a href="tg://user?id={telegram_id}">{name}</a></b> ({change:+} ★)"#),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,11 +43,22 @@ pub async fn get_all()
|
|||
Ok(Json(players.into_iter().map(Into::into).collect()))
|
||||
}
|
||||
|
||||
// this is an awful hack but idc i'm out of time
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PlayerOO {
|
||||
id: i32,
|
||||
telegram_id: Option<TelegramId>,
|
||||
username: String,
|
||||
human_score: Option<i64>,
|
||||
played: i64,
|
||||
wins: i64,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn get_by_id(
|
||||
Path(player_id): Path<i32>,
|
||||
)
|
||||
-> Result<Json<PlayerO>, StatusCode>
|
||||
-> Result<Json<PlayerOO>, StatusCode>
|
||||
{
|
||||
let mut conn = PgConnection::establish(config::DATABASE_URL())
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
@ -56,14 +67,29 @@ pub async fn get_by_id(
|
|||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
.ok_or(StatusCode::NOT_FOUND)?;
|
||||
|
||||
Ok(Json(player.into()))
|
||||
let played = player.played_count(&mut conn)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
let wins = player.won_count(&mut conn)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
let player_o = PlayerO::from(player);
|
||||
|
||||
Ok(Json(PlayerOO {
|
||||
id: player_o.id,
|
||||
telegram_id: player_o.telegram_id,
|
||||
username: player_o.username,
|
||||
human_score: player_o.human_score,
|
||||
played,
|
||||
wins,
|
||||
}))
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn get_by_telegram_id(
|
||||
Path(telegram_id): Path<TelegramId>,
|
||||
)
|
||||
-> Result<Json<PlayerO>, StatusCode>
|
||||
-> Result<Json<PlayerOO>, StatusCode>
|
||||
{
|
||||
let mut conn = PgConnection::establish(config::DATABASE_URL())
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
@ -72,5 +98,20 @@ pub async fn get_by_telegram_id(
|
|||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
.ok_or(StatusCode::NOT_FOUND)?;
|
||||
|
||||
Ok(Json(player.into()))
|
||||
let played = player.played_count(&mut conn)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
let wins = player.won_count(&mut conn)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
let player_o = PlayerO::from(player);
|
||||
|
||||
Ok(Json(PlayerOO {
|
||||
id: player_o.id,
|
||||
telegram_id: player_o.telegram_id,
|
||||
username: player_o.username,
|
||||
human_score: player_o.human_score,
|
||||
played,
|
||||
wins,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
export default async function Page() {
|
||||
import {ProfileBox} from "@/components/ProfileBox"
|
||||
import {PlayerOO} from "@/holycow"
|
||||
|
||||
|
||||
export default async function Page({params: {telegramId}}) {
|
||||
const playerResponse = await fetch(`${process.env.BASE_URL}/api/results/telegram/${telegramId}`)
|
||||
const player: PlayerOO = await playerResponse.json()
|
||||
|
||||
return (
|
||||
<ProfileBox
|
||||
player={player}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -18,3 +18,7 @@ hr {
|
|||
/* TODO: Fix in bluelib */
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fof {
|
||||
text-align: center;
|
||||
}
|
|
@ -28,7 +28,13 @@ export default function RootLayout({ children }) {
|
|||
<body>
|
||||
<header>
|
||||
<h2>
|
||||
Stagione 1
|
||||
<span>
|
||||
Stagione 1:
|
||||
</span>
|
||||
<br/>
|
||||
<small>
|
||||
Standard Brawl
|
||||
</small>
|
||||
</h2>
|
||||
</header>
|
||||
<TelegramContext.Provider value={telegram}>
|
||||
|
@ -38,7 +44,9 @@ export default function RootLayout({ children }) {
|
|||
<p>
|
||||
© Stefano Pigozzi
|
||||
-
|
||||
che cursata, non ha senso, che cursata
|
||||
Star Shard
|
||||
-
|
||||
che cursata le miniapp di telegram
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
|
|
19
holycow_frontend/src/app/none/page.tsx
Normal file
19
holycow_frontend/src/app/none/page.tsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import {ProfileBox} from "@/components/ProfileBox"
|
||||
import {PlayerOO} from "@/holycow"
|
||||
|
||||
|
||||
export default async function Page() {
|
||||
return (
|
||||
<div className={"panel box fof"}>
|
||||
<h3>
|
||||
👍
|
||||
</h3>
|
||||
<p>
|
||||
hai scoperto la pagina di tutti i tempi
|
||||
</p>
|
||||
<p>
|
||||
congrats!!
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -14,8 +14,6 @@ export default function Page() {
|
|||
useEffect(
|
||||
() => {
|
||||
switch(startParam) {
|
||||
case undefined:
|
||||
return
|
||||
case "profile":
|
||||
router.replace(`/${data.user.id}/profile`)
|
||||
return
|
||||
|
@ -23,7 +21,7 @@ export default function Page() {
|
|||
router.replace(`/${data.user.id}/report`)
|
||||
return
|
||||
default:
|
||||
router.replace(`/error404`)
|
||||
router.replace(`/none`)
|
||||
return
|
||||
}
|
||||
},
|
||||
|
@ -32,7 +30,7 @@ export default function Page() {
|
|||
|
||||
return (
|
||||
<LoadingBox>
|
||||
Connecting to Telegram...
|
||||
Connessione a Telegram in corso...
|
||||
</LoadingBox>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,81 +1,57 @@
|
|||
import {StatPanel} from "@/components/StatPanel"
|
||||
import {PlayerOO} from "@/holycow"
|
||||
import classNames from "classnames"
|
||||
|
||||
|
||||
export type ProfileBoxProps = {
|
||||
userName: string,
|
||||
played: number,
|
||||
won: number,
|
||||
rating: number,
|
||||
uncertainty: number,
|
||||
player: PlayerOO
|
||||
}
|
||||
|
||||
|
||||
export function ProfileBox({userName, played, won, rating, uncertainty}: ProfileBoxProps) {
|
||||
export function ProfileBox({player}: ProfileBoxProps) {
|
||||
return (
|
||||
<div className={"chapter-1"}>
|
||||
<div className={"panel box"}>
|
||||
<h3>
|
||||
{userName}
|
||||
{player.username}
|
||||
</h3>
|
||||
<div className={"chapter-4"}>
|
||||
<StatPanel
|
||||
name={"Giocate"}
|
||||
className={classNames({
|
||||
"fade": player.played === 0
|
||||
})}
|
||||
value={(
|
||||
<data
|
||||
className={classNames({
|
||||
"fade": played === 0
|
||||
})}
|
||||
value={played}
|
||||
>
|
||||
{played}
|
||||
<data value={player.played}>
|
||||
{player.played}
|
||||
</data>
|
||||
)}
|
||||
/>
|
||||
<StatPanel
|
||||
name={"Vinte"}
|
||||
className={classNames({
|
||||
"fade": player.wins === 0,
|
||||
"green": player.wins !== 0,
|
||||
})}
|
||||
value={(
|
||||
<data
|
||||
className={classNames({
|
||||
"fade": won === 0
|
||||
})}
|
||||
value={won}
|
||||
>
|
||||
{won}
|
||||
<data value={player.wins}>
|
||||
{player.wins}
|
||||
</data>
|
||||
)}
|
||||
/>
|
||||
<StatPanel
|
||||
name={"Punteggio"}
|
||||
value={(
|
||||
<span
|
||||
className={classNames({
|
||||
"fade": rating === 0
|
||||
})}
|
||||
>
|
||||
{rating === 0
|
||||
?
|
||||
<>
|
||||
<data value={rating}>
|
||||
-
|
||||
</data>
|
||||
</>
|
||||
:
|
||||
<>
|
||||
<data value={rating}>
|
||||
{rating}
|
||||
</data>
|
||||
<span>
|
||||
±
|
||||
</span>
|
||||
<data value={uncertainty}>
|
||||
{uncertainty}
|
||||
</data>
|
||||
</>
|
||||
}
|
||||
</span>
|
||||
)}
|
||||
/>
|
||||
{player.human_score !== null &&
|
||||
<StatPanel
|
||||
name={"★"}
|
||||
className={"yellow"}
|
||||
value={(
|
||||
<span>
|
||||
<data value={player.human_score}>
|
||||
{player.human_score}
|
||||
</data>
|
||||
</span>
|
||||
)}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import classNames from "classnames";
|
||||
import style from "./StatPanel.module.css"
|
||||
|
||||
export function StatPanel({name, value, display = value}) {
|
||||
export function StatPanel({className, name, value, display = value}) {
|
||||
return (
|
||||
<div className={classNames("panel", style.panel)}>
|
||||
<div className={classNames("panel", style.panel, className)}>
|
||||
<h4 className={style.name}>
|
||||
{name}
|
||||
</h4>
|
||||
|
|
|
@ -10,3 +10,12 @@ export type PlayerO = {
|
|||
username: string,
|
||||
human_score: null | number,
|
||||
}
|
||||
|
||||
export type PlayerOO = {
|
||||
id: number,
|
||||
telegram_id: number,
|
||||
username: string,
|
||||
human_score: null | number,
|
||||
played: number,
|
||||
wins: number,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue