ada-judge-app 0.2.12

Native desktop app for ada-judge
use crate::{AJContestState, AJLeaderboardRow, AJMainWindow, app_state::AppState};
use ada_judge_public_models::{contests::LeaderboardRow, users::PublicUserData};
use futures::future::try_join_all;
use reqwest::StatusCode;
use slint::{ComponentHandle, ModelRc, VecModel, Weak};
use std::sync::Arc;
use tokio::sync::Mutex;

pub async fn load_contest_leaderboard(
    id: i64,
    state: Arc<Mutex<AppState>>,
    weak: Weak<AJMainWindow>,
) -> Result<(), anyhow::Error> {
    let client = reqwest::Client::new();
    let token = state.lock().await.token.clone();
    let base_url = state.lock().await.base_url.clone();
    let res = client
        .get(format!("{base_url}/contests/{id}/leaderboard"))
        .bearer_auth(token.clone())
        .send()
        .await?;
    if res.status() != StatusCode::OK {
        return Ok(());
    }
    let rows = res.json::<Vec<LeaderboardRow>>().await?;
    let rows: Vec<(String, LeaderboardRow)> = try_join_all(rows.iter().map(|row| {
        let client = client.clone();
        let token = token.clone();
        let base_url = base_url.clone();

        async move {
            let user = client
                .get(format!("{base_url}/users/{}", row.user_id))
                .bearer_auth(token.clone())
                .send()
                .await?
                .json::<PublicUserData>()
                .await?;
            Ok::<_, anyhow::Error>((user.login, row.clone()))
        }
    }))
    .await?;
    slint::invoke_from_event_loop(move || {
        let rows: Vec<AJLeaderboardRow> = rows
            .iter()
            .map(|(username, row)| (username.clone(), row).into())
            .collect();

        if let Some(ui) = weak.upgrade() {
            ui.global::<AJContestState>()
                .set_leaderboard_rows(ModelRc::new(VecModel::from(rows)));
        }
    })
    .unwrap();

    Ok(())
}