From 75a7d2364d9a43071ca3c118cf7214fb8cfb6f25 Mon Sep 17 00:00:00 2001 From: PenguinWithATie <166940857+PenguinWithATie@users.noreply.github.com> Date: Sat, 30 Nov 2024 08:12:22 -0600 Subject: [PATCH] sort challenges, use animated for (#391) --- apis/src/components/organisms/challenges.rs | 69 ++++++++++++++++----- apis/src/pages/profile_view.rs | 16 ++--- shared_types/src/game_speed.rs | 2 +- 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/apis/src/components/organisms/challenges.rs b/apis/src/components/organisms/challenges.rs index 8d4c4d57..f7b29daf 100644 --- a/apis/src/components/organisms/challenges.rs +++ b/apis/src/components/organisms/challenges.rs @@ -1,4 +1,6 @@ +use crate::common::UserStatus; use crate::i18n::*; +use crate::providers::online_users::{OnlineUsersSignal, OnlineUsersState}; use crate::{ components::molecules::challenge_row::ChallengeRow, providers::{challenges::ChallengeStateSignal, AuthContext}, @@ -6,12 +8,39 @@ use crate::{ }; use leptos::*; +fn challenge_order( + a: &ChallengeResponse, + b: &ChallengeResponse, + online_users: &OnlineUsersState, +) -> std::cmp::Ordering { + let online_a = online_users.username_status.get(&a.challenger.username); + let online_a = matches!(online_a, Some(UserStatus::Online)); + let online_b = online_users.username_status.get(&b.challenger.username); + let online_b = matches!(online_b, Some(UserStatus::Online)); + if a.challenge_id.0.cmp(&b.challenge_id.0) == std::cmp::Ordering::Equal { + std::cmp::Ordering::Equal + } else if online_a && !online_b { + std::cmp::Ordering::Less + } else if !online_a && online_b { + std::cmp::Ordering::Greater + } else if a.time_base == b.time_base { + let a_incr = a.time_increment.unwrap_or(i32::MAX); + let b_incr = b.time_increment.unwrap_or(i32::MAX); + a_incr.cmp(&b_incr) + } else { + let a_base = a.time_base.unwrap_or(i32::MAX); + let b_base = b.time_base.unwrap_or(i32::MAX); + a_base.cmp(&b_base) + } +} + #[component] pub fn Challenges() -> impl IntoView { let i18n = use_i18n(); let th_class = "py-1 px-1 md:py-2 md:px-2 lg:px-3 font-bold uppercase max-h-[80vh] max-w-screen"; let challenges = expect_context::(); + let online_users = expect_context::().signal; let auth_context = expect_context::(); let user = move || { if let Some(Ok(Some(user))) = (auth_context.user)() { @@ -20,8 +49,8 @@ pub fn Challenges() -> impl IntoView { None } }; - let direct = move || { - if let Some(user) = user() { + let direct = Signal::derive(move || { + let mut ret = if let Some(user) = user() { // Get the challenges direct at the current user challenges .signal @@ -39,11 +68,13 @@ pub fn Challenges() -> impl IntoView { .values() .cloned() .collect::>() - } - }; + }; + ret.sort_by(|a, b| challenge_order(a, b, &online_users.get())); + ret + }); - let own = move || { - if let Some(user) = user() { + let own = Signal::derive(move || { + let mut ret = if let Some(user) = user() { challenges .signal .get() @@ -54,11 +85,13 @@ pub fn Challenges() -> impl IntoView { .collect::>() } else { Vec::new() - } - }; + }; + ret.sort_by(|a, b| challenge_order(a, b, &online_users.get())); + ret + }); - let public = move || { - if let Some(user) = user() { + let public = Signal::derive(move || { + let mut ret = if let Some(user) = user() { challenges .signal .get() @@ -71,8 +104,10 @@ pub fn Challenges() -> impl IntoView { .collect::>() } else { Vec::new() - } - }; + }; + ret.sort_by(|a, b| challenge_order(a, b, &online_users.get())); + ret + }); let has_games = move |list: Vec| !list.is_empty(); let not_hidden = Memo::new(move |_| has_games(direct()) || has_games(own()) || has_games(public())); @@ -92,15 +127,15 @@ pub fn Challenges() -> impl IntoView { - - - + + + - + - + diff --git a/apis/src/pages/profile_view.rs b/apis/src/pages/profile_view.rs index 4af85314..1ccd7c21 100644 --- a/apis/src/pages/profile_view.rs +++ b/apis/src/pages/profile_view.rs @@ -1,4 +1,5 @@ use crate::common::UserAction; +use crate::components::atoms::rating::icon_for_speed; use crate::components::molecules::user_row::UserRow; use crate::i18n::*; use crate::{ @@ -10,13 +11,13 @@ use crate::{ ApiRequests, }, }; -use leptos_icons::*; use hive_lib::Color; use leptix_primitives::{ radio_group::{RadioGroupItem, RadioGroupRoot}, toggle_group::{ToggleGroupItem, ToggleGroupKind, ToggleGroupMultiple, ToggleGroupRoot}, }; use leptos::*; +use leptos_icons::*; use leptos_router::*; use leptos_use::{ core::ConnectionReadyState, signal_debounced, use_infinite_scroll_with_options, @@ -24,7 +25,6 @@ use leptos_use::{ }; use shared_types::{GameProgress, GameSpeed, GamesContextToUpdate, GamesQueryOptions, ResultType}; use std::str::FromStr; -use crate::components::atoms::rating::icon_for_speed; #[derive(Params, PartialEq, Eq)] struct UsernameParams { @@ -163,22 +163,22 @@ fn Controls(username: Signal) -> impl IntoView { > - + - + - + - + - + - + diff --git a/shared_types/src/game_speed.rs b/shared_types/src/game_speed.rs index 0a6700a6..26c0337c 100644 --- a/shared_types/src/game_speed.rs +++ b/shared_types/src/game_speed.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Debug, Serialize, PartialEq, Eq, Deserialize, Clone, Hash)] +#[derive(Debug, Serialize, PartialEq, Eq, Deserialize, Clone, Hash, PartialOrd, Ord)] pub enum GameSpeed { Bullet, Blitz,