improve user mod view - closes #494

This commit is contained in:
Thibault Duplessis 2015-07-08 18:04:51 +02:00
parent 1029d4b804
commit 4fe01bf0a8
6 changed files with 71 additions and 30 deletions

View file

@ -177,7 +177,7 @@ object User extends LilaController {
def mod(username: String) = Secure(_.UserSpy) { implicit ctx =>
me => OptionFuOk(UserRepo named username) { user =>
(Env.security userSpy user.id) zip
(Env.mod.assessApi.getPlayerAggregateAssessment(user.id)) flatMap {
(Env.mod.assessApi.getPlayerAggregateAssessmentWithGames(user.id)) flatMap {
case (spy, playerAggregateAssessment) =>
(Env.playban.api bans spy.otherUsers.map(_.id)) map { bans =>
html.user.mod(user, spy, playerAggregateAssessment, bans)

View file

@ -106,7 +106,8 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel
withDiff: Boolean = true,
engine: Boolean = false,
withStatus: Boolean = false,
mod: Boolean = false)(implicit ctx: UserContext) = Html {
mod: Boolean = false,
link: Boolean = true)(implicit ctx: UserContext) = Html {
val statusIcon = if (withStatus) """<span class="status"></span>""" else ""
player.userId.flatMap(lightUser) match {
case None =>
@ -121,7 +122,8 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel
val mark = engine ?? s"""<span class="engine_mark" title="${trans.thisPlayerUsesChessComputerAssistance()}"></span>"""
val dataIcon = withOnline ?? """data-icon="r""""
val space = if (withOnline) "&nbsp;" else ""
s"""<a $dataIcon $klass href="$href">$space$content$diff$mark</a>$statusIcon"""
val tag = if (link) "a" else "span"
s"""<$tag $dataIcon $klass href="$href">$space$content$diff$mark</$tag>$statusIcon"""
}
}

View file

@ -1,4 +1,4 @@
@(u: User, spy: lila.security.UserSpy, optionAggregateAssessment: Option[lila.evaluation.PlayerAggregateAssessment], bans: Map[String, Int])(implicit ctx: Context)
@(u: User, spy: lila.security.UserSpy, optionAggregateAssessment: Option[lila.evaluation.PlayerAggregateAssessment.WithGames], bans: Map[String, Int])(implicit ctx: Context)
@import lila.evaluation.Display
@ -57,28 +57,28 @@
<br />
</p>
</div>
}{ aggregateAssessment =>
}{ pag =>
<div class="evaluation results">
<table class="reportCard">
<thead>
<tr>
<th>
<span class="result_@aggregateAssessment.action.id">@aggregateAssessment.action.description</span>
<span class="result_@pag.pag.action.id">@pag.pag.action.description</span>
</th>
<th>
@aggregateAssessment.playerAssessments.size
@pag.pag.playerAssessments.size
</th>
<th>
@aggregateAssessment.cheatingSum
@pag.pag.cheatingSum
</th>
<th>
@aggregateAssessment.likelyCheatingSum
@pag.pag.likelyCheatingSum
</th>
<th>
@aggregateAssessment.relatedCheatersCount
@pag.pag.relatedCheatersCount
</th>
<th>
@aggregateAssessment.relatedUsersCount
@pag.pag.relatedUsersCount
</th>
</tr>
</thead>
@ -110,33 +110,33 @@
<tr>
<th>Blurs</th>
<td>
<strong>@aggregateAssessment.sfAvgBlurs</strong>
<strong>@pag.pag.sfAvgBlurs</strong>
<br/>high
</td>
<td>
<strong>@aggregateAssessment.sfAvgNoBlurs</strong>
<strong>@pag.pag.sfAvgNoBlurs</strong>
<br/>low
</td>
</tr>
<tr>
<th>Move Times</th>
<td>
<strong>@aggregateAssessment.sfAvgLowVar</strong>
<strong>@pag.pag.sfAvgLowVar</strong>
<br/>low variance
</td>
<td>
<strong>@aggregateAssessment.sfAvgHighVar</strong>
<strong>@pag.pag.sfAvgHighVar</strong>
<br/>high variance
</td>
</tr>
<tr>
<th>Hold Alert</th>
<td>
<strong>@aggregateAssessment.sfAvgHold</strong>
<strong>@pag.pag.sfAvgHold</strong>
<br/>alert
</td>
<td>
<strong>@aggregateAssessment.sfAvgNoHold</strong>
<strong>@pag.pag.sfAvgNoHold</strong>
<br/>no alert
</td>
</tr>
@ -144,7 +144,8 @@
<table class="slist">
<thead>
<tr>
<th>Assessed game</th>
<th>Opponent</th>
<th>Game</th>
<th>
Centi-Pawn
<br />(Avg ± SD)
@ -159,28 +160,49 @@
</tr>
</thead>
<tbody>
@aggregateAssessment.playerAssessments.sortBy(-_.assessment.id).take(15).map { result =>
@pag.pag.playerAssessments.sortBy(-_.assessment.id).take(15).map { result =>
<tr>
<td><a href="@routes.Round.watcher(result.gameId, result.color.name)">@routes.Round.watcher(result.gameId, result.color.name)</a></td>
<td>
<span class="sig_@(Display.stockfishSig(result))" data-icon="J"></span>
<a href="@routes.Round.watcher(result.gameId, result.color.name)">
@pag.pov(result).fold{
@result.gameId
} { p =>
@playerLink(p.opponent, withRating = true, withDiff = true, withOnline = false, link = false)
}
</a>
</td>
<td>
@pag.pov(result).map { p =>
<a href="@routes.Round.watcher(p.gameId, p.color.name)">
@if(p.game.isTournament) {
<span data-icon="g"></span>
}
@p.game.perfType.map { pt =>
<span data-icon="@pt.iconChar"></span>
}
@shortClockName(p.game.clock)
</a>
}
</td>
<td>
<span class="sig sig_@(Display.stockfishSig(result))" data-icon="J"></span>
@result.sfAvg ± @result.sfSd
</td>
<td>
<span class="sig_@(Display.moveTimeSig(result))" data-icon="J"></span>
<span class="sig sig_@(Display.moveTimeSig(result))" data-icon="J"></span>
@(result.mtAvg/10) ± @(result.mtSd/10)
</td>
<td>
<span class="sig_@(Display.blurSig(result))" data-icon="J"></span>
<span class="sig sig_@(Display.blurSig(result))" data-icon="J"></span>
@(result.blurs)%
</td>
<td>
<span class="sig_@(Display.holdSig(result))" data-icon="J"></span>
<span class="sig sig_@(Display.holdSig(result))" data-icon="J"></span>
@if(result.hold){Yes} else {No}
</td>
<td>
<div class="aggregate hint--top-left">
<span class="sig_@(result.assessment.id)">@result.assessment.emoticon</span>
<span class="sig sig_@(result.assessment.id)">@result.assessment.emoticon</span>
</div>
</td>
</tr>

View file

@ -131,6 +131,13 @@ case class PlayerAggregateAssessment(
}
}
object PlayerAggregateAssessment {
case class WithGames(pag: PlayerAggregateAssessment, games: List[lila.game.Game]) {
def pov(pa: PlayerAssessment) = games find (_.id == pa.gameId) map { lila.game.Pov(_, pa.color) }
}
}
case class PlayerFlags(
suspiciousErrorRate: Boolean,
alwaysHasAdvantage: Boolean,

View file

@ -66,6 +66,17 @@ final class AssessApi(
}
}
def withGames(pag: PlayerAggregateAssessment): Fu[PlayerAggregateAssessment.WithGames] =
GameRepo games pag.playerAssessments.map(_.gameId) map {
PlayerAggregateAssessment.WithGames(pag, _)
}
def getPlayerAggregateAssessmentWithGames(userId: String, nb: Int = 100): Fu[Option[PlayerAggregateAssessment.WithGames]] =
getPlayerAggregateAssessment(userId, nb) flatMap {
case None => fuccess(none)
case Some(pag) => withGames(pag).map(_.some)
}
def refreshAssessByUsername(username: String): Funit = withUser(username) { user =>
(GameRepo.gamesForAssessment(user.id, 100) flatMap { gs =>
(gs map { g =>

View file

@ -258,6 +258,9 @@ div.user_show .mod_zone .slist {
font-size: 0.9em;
margin-bottom: 1em;
}
div.user_show .mod_zone .slist a {
text-decoration: none;
}
div.user_show .mod_zone .same {
font-style: italic;
font-weight: bold;
@ -317,9 +320,6 @@ div.user_show .evaluation .legend {
div.user_show .evaluation .legend span {
padding: 10px;
}
div.user_show .evaluation [data-icon] {
text-shadow: 1px 1px 1px #000;
}
div.user_show .evaluation .sig_1 {
color: #2077C0;
/* dark blue */
@ -406,9 +406,8 @@ div.user_show .extra_stats td {
padding: 5px;
}
div.user_show .results .aggregate {
text-shadow: 1px -1px 1px #000;
font-weight: bold;
font-size: 2.2em;
font-size: 1.4em;
text-align: center;
margin-left: -20px;
width: 50px;