From 8a45008a26ff08254e80bca9aaf7dc9a061157c5 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Wed, 13 Mar 2024 16:53:35 +0100 Subject: [PATCH] show federation flags in broadcast leaderboard --- modules/relay/src/main/RelayLeaderboard.scala | 10 +++++-- modules/relay/src/main/RelayTeams.scala | 5 ++-- ui/analyse/css/study/relay/_teams.scss | 4 ++- ui/analyse/css/study/relay/_tour.scss | 27 +++++++++++++------ ui/analyse/src/study/relay/interfaces.ts | 1 + ui/analyse/src/study/relay/relayTourView.ts | 17 ++++++------ 6 files changed, 41 insertions(+), 23 deletions(-) diff --git a/modules/relay/src/main/RelayLeaderboard.scala b/modules/relay/src/main/RelayLeaderboard.scala index 6ca36a311bf5..5e7a8af08758 100644 --- a/modules/relay/src/main/RelayLeaderboard.scala +++ b/modules/relay/src/main/RelayLeaderboard.scala @@ -4,6 +4,7 @@ import lila.db.dsl.{ *, given } import lila.memo.CacheApi import lila.study.ChapterRepo import chess.{ Outcome, FideId, PlayerName, PlayerTitle, Elo } +import lila.fide.{ Federation, FidePlayerApi } case class RelayLeaderboard(players: List[RelayLeaderboard.Player]) @@ -14,7 +15,8 @@ object RelayLeaderboard: played: Int, rating: Option[Elo], title: Option[PlayerTitle], - fideId: Option[FideId] + fideId: Option[FideId], + fed: Option[Federation.Id] ) import play.api.libs.json.* @@ -25,11 +27,13 @@ object RelayLeaderboard: .add("rating", p.rating) .add("title", p.title) .add("fideId", p.fideId) + .add("fed", p.fed) final class RelayLeaderboardApi( tourRepo: RelayTourRepo, roundRepo: RelayRoundRepo, chapterRepo: ChapterRepo, + playerApi: FidePlayerApi, cacheApi: CacheApi )(using Executor, Scheduler): @@ -73,9 +77,11 @@ final class RelayLeaderboardApi( prevFideId.orElse(game.fideIds(color)) ) ) + federations <- playerApi.federationsOf(players.values.flatMap(_._5).toList) yield RelayLeaderboard: players.toList .sortBy(-_._2._1) .map: case (name, (score, played, rating, title, fideId)) => - RelayLeaderboard.Player(name, score, played, rating, title, fideId) + val fed = fideId.flatMap(federations.get) + RelayLeaderboard.Player(name, score, played, rating, title, fideId, fed) diff --git a/modules/relay/src/main/RelayTeams.scala b/modules/relay/src/main/RelayTeams.scala index 64fae3abcf5b..7007bfddb9b9 100644 --- a/modules/relay/src/main/RelayTeams.scala +++ b/modules/relay/src/main/RelayTeams.scala @@ -4,7 +4,7 @@ import chess.format.pgn.* import chess.format.Fen import chess.{ FideId, PlayerName, PlayerTitle, Elo } -import lila.fide.{ FidePlayerApi, PlayerToken, FidePlayer, Federation } +import lila.fide.{ PlayerToken, FidePlayer } import lila.study.ChapterPreview type TeamName = String @@ -59,8 +59,7 @@ private class RelayTeamsTextarea(val text: String): final class RelayTeamTable( chapterPreviewApi: lila.study.ChapterPreviewApi, - cacheApi: lila.memo.CacheApi, - fidePlayerApi: FidePlayerApi + cacheApi: lila.memo.CacheApi )(using Executor): import play.api.libs.json.* diff --git a/ui/analyse/css/study/relay/_teams.scss b/ui/analyse/css/study/relay/_teams.scss index 7f33376b6e38..3ed31e945cec 100644 --- a/ui/analyse/css/study/relay/_teams.scss +++ b/ui/analyse/css/study/relay/_teams.scss @@ -46,8 +46,10 @@ background: $c-bg-zebra; } color: $c-font; + border: 1px solid transparent; &:hover { - background: mix($c-bg-box, $c-link, 90%); + background: mix($c-link, $c-bg-box, 12%); + border-color: mix($c-link, $c-bg-box, 50%); color: $c-font-clearer; .mini-game__flag { opacity: 1; diff --git a/ui/analyse/css/study/relay/_tour.scss b/ui/analyse/css/study/relay/_tour.scss index fc392a234d81..7aeeed4a1583 100644 --- a/ui/analyse/css/study/relay/_tour.scss +++ b/ui/analyse/css/study/relay/_tour.scss @@ -221,22 +221,33 @@ border: none; } } - th { - &:first-child { - width: 1px; + thead { + th { + text-align: $end-direction; + padding: 0 2rem 0.5rem 2rem; } - &:first-child, - &:nth-child(2) { + } + th { + &:nth-child(1) { text-align: $start-direction; - } - &:nth-child(2) { padding-right: 2rem; } + a { + @extend %flex-center-nowrap; + .mini-game__flag { + margin-#{$end-direction}: 1em; + opacity: 0.7; + } + color: $c-font; + &:hover { + color: $c-primary; + } + } } td { text-align: $end-direction; padding: 1rem 2rem; - &:nth-child(4) { + &:last-child { font-weight: bold; } } diff --git a/ui/analyse/src/study/relay/interfaces.ts b/ui/analyse/src/study/relay/interfaces.ts index c4fe008dc68f..328475038896 100644 --- a/ui/analyse/src/study/relay/interfaces.ts +++ b/ui/analyse/src/study/relay/interfaces.ts @@ -18,6 +18,7 @@ export interface RelayPlayer { rating?: number; title?: string; fideId?: number; + fed: string; } export interface RelayGamePlayer extends RelayPlayer {} diff --git a/ui/analyse/src/study/relay/relayTourView.ts b/ui/analyse/src/study/relay/relayTourView.ts index 9e695339302e..d6cfb0327919 100644 --- a/ui/analyse/src/study/relay/relayTourView.ts +++ b/ui/analyse/src/study/relay/relayTourView.ts @@ -14,6 +14,7 @@ import { teamsView } from './relayTeams'; import { userTitle } from 'common/userLink'; import { makeChat } from '../../view/view'; import { gamesList } from './relayGames'; +import { playerFed } from '../playerBars'; export default function (ctrl: AnalyseCtrl): VNode | undefined { const study = ctrl.study, @@ -53,6 +54,7 @@ export const tourSide = (ctrl: AnalyseCtrl, study: StudyCtrl, relay: RelayCtrl) }), }), ]); + const leaderboard = (relay: RelayCtrl, ctrl: AnalyseCtrl): MaybeVNodes => { const players = relay.data.leaderboard || []; const withRating = !!players.find(p => p.rating); @@ -61,23 +63,20 @@ const leaderboard = (relay: RelayCtrl, ctrl: AnalyseCtrl): MaybeVNodes => { h('table.relay-tour__leaderboard.slist.slist-invert.slist-pad', [ h( 'thead', - h('tr', [ - h('th'), - h('th'), - withRating ? h('th', 'Elo') : undefined, - h('th', 'Score'), - h('th', 'Games'), - ]), + h('tr', [h('th'), withRating ? h('th', 'Elo') : undefined, h('th', 'Score'), h('th', 'Games')]), ), h( 'tbody', players.map(player => h('tr', [ - h('th', userTitle(player)), h( 'th', player.fideId - ? h('a', { attrs: { href: `/fide/${player.fideId}/redirect` } }, player.name) + ? h('a', { attrs: { href: `/fide/${player.fideId}/redirect` } }, [ + player.fed && playerFed(player.fed), + userTitle(player), + player.name, + ]) : player.name, ), h('td', withRating && player.rating ? `${player.rating}` : undefined),