show wins/draws/losses between 2 players, improve profile

This commit is contained in:
Thibault Duplessis 2013-07-21 23:13:36 +02:00
parent c8d5345d0e
commit 64b352433d
9 changed files with 64 additions and 20 deletions

View file

@ -12,7 +12,7 @@ case class UserInfo(
user: User, user: User,
rank: Option[(Int, Int)], rank: Option[(Int, Int)],
nbPlaying: Int, nbPlaying: Int,
nbWithMe: Option[Int], confrontation: Option[(Int, Int, Int)],
nbBookmark: Int, nbBookmark: Int,
eloWithMe: Option[List[(String, Int)]], eloWithMe: Option[List[(String, Int)]],
eloChart: Option[EloChart], eloChart: Option[EloChart],
@ -22,6 +22,10 @@ case class UserInfo(
def nbRated = user.count.rated def nbRated = user.count.rated
def nbWithMe = confrontation map {
case (w, d, l) w + d + l
}
def percentRated: Int = math.round(nbRated / user.count.game.toFloat * 100) def percentRated: Int = math.round(nbRated / user.count.game.toFloat * 100)
} }
@ -41,18 +45,18 @@ object UserInfo {
GameRepo count (_ notFinished user.id) map (_.some) GameRepo count (_ notFinished user.id) map (_.some)
}) zip }) zip
(ctx.me.filter(user!=) ?? { me (ctx.me.filter(user!=) ?? { me
GameRepo count (_.opponents(user, me)) map (_.some) GameRepo.confrontation(user, me) map (_.some)
}) zip }) zip
(bookmarkApi countByUser user) zip (bookmarkApi countByUser user) zip
EloChart(user) zip EloChart(user) zip
relationApi.nbFollowing(user.id) zip relationApi.nbFollowing(user.id) zip
relationApi.nbFollowers(user.id) zip relationApi.nbFollowers(user.id) zip
postApi.nbByUser(user.id) map { postApi.nbByUser(user.id) map {
case (((((((rank, nbPlaying), nbWithMe), nbBookmark), eloChart), nbFollowing), nbFollowers), nbPosts) new UserInfo( case (((((((rank, nbPlaying), confrontation), nbBookmark), eloChart), nbFollowing), nbFollowers), nbPosts) new UserInfo(
user = user, user = user,
rank = rank, rank = rank,
nbPlaying = ~nbPlaying, nbPlaying = ~nbPlaying,
nbWithMe = nbWithMe, confrontation = confrontation,
nbBookmark = nbBookmark, nbBookmark = nbBookmark,
eloWithMe = ctx.me.filter(user !=) map { me eloWithMe = ctx.me.filter(user !=) map { me
List( List(

View file

@ -111,12 +111,23 @@ evenMoreCss = evenMoreCss) {
} }
@bio @bio
@info.eloWithMe.map { eloWithMe => @info.eloWithMe.map { eloWithMe =>
<div class="elo_with_me"> <div class="elo_with_me boxed_data">
@trans.ratedGameResult()<br />
@eloWithMe.map { e => @eloWithMe.map { e =>
@e._1.capitalize: <strong>@showNumber(e._2)</strong> @e._1.capitalize: <strong>@showNumber(e._2)</strong>
} }
</div> </div>
} }
@info.confrontation.map {
case (w, d, l) => {
<div class="confrontation boxed_data">
@ctx.me.map(_.username) vs @u.username<br />
@trans.nbWins("<strong>"+w+"</strong>"),
@trans.nbDraws("<strong>"+d+"</strong>"),
@trans.nbLosses("<strong>"+l+"</strong>")
</div>
}
}
<div class="stats"> <div class="stats">
<p>@trans.memberSince() @showDate(u.createdAt)</p> <p>@trans.memberSince() @showDate(u.createdAt)</p>
@u.seenAt.map { seen => @u.seenAt.map { seen =>

View file

@ -244,3 +244,4 @@ boardEditor=Board editor
startPosition=Start position startPosition=Start position
clearBoard=Clear board clearBoard=Clear board
savePosition=Save position savePosition=Save position
ratedGameResult=Rated game result

View file

@ -68,8 +68,7 @@ private[game] final class ComputeElos(system: ActorSystem) {
private def usersQuery = $query.apply[User]( private def usersQuery = $query.apply[User](
Json.obj( Json.obj(
"count.rated" -> $gt(0), "count.rated" -> $gt(0)
"_id" -> "legend"
)) sort ($sort desc "seenAt") )) sort ($sort desc "seenAt")
private def gamesQuery(user: User) = $query.apply[Game]( private def gamesQuery(user: User) = $query.apply[Game](

View file

@ -2,18 +2,17 @@ package lila.game
import scala.util.Random import scala.util.Random
import org.joda.time.DateTime
import org.scala_tools.time.Imports._
import play.api.libs.json._
import play.modules.reactivemongo.json.BSONFormats.toJSON
import play.modules.reactivemongo.json.ImplicitBSONHandlers.JsObjectWriter
import chess.format.Forsyth import chess.format.Forsyth
import chess.{ Color, Variant, Status } import chess.{ Color, Variant, Status }
import lila.common.PimpedJson._ import lila.common.PimpedJson._
import lila.db.api._ import lila.db.api._
import lila.db.Implicits._ import lila.db.Implicits._
import lila.user.User import lila.user.User
import org.joda.time.DateTime
import org.scala_tools.time.Imports._
import play.api.libs.json._
import play.modules.reactivemongo.json.BSONFormats.toJSON
import play.modules.reactivemongo.json.ImplicitBSONHandlers.JsObjectWriter
import tube.gameTube import tube.gameTube
object GameRepo { object GameRepo {
@ -197,9 +196,9 @@ object GameRepo {
import reactivemongo.core.commands._ import reactivemongo.core.commands._
val command = Aggregate(gameTube.coll.name, Seq( val command = Aggregate(gameTube.coll.name, Seq(
Match(BSONDocument("uids" -> userId)), Match(BSONDocument("uids" -> userId)),
Match(BSONDocument("uids" -> BSONDocument("$size" -> BSONInteger(2)))), Match(BSONDocument("uids" -> BSONDocument("$size" -> 2))),
Unwind("uids"), Unwind("uids"),
Match(BSONDocument("uids" -> BSONDocument("$ne" -> BSONString(userId)))), Match(BSONDocument("uids" -> BSONDocument("$ne" -> userId))),
GroupField("uids")("gs" -> SumValue(1)), GroupField("uids")("gs" -> SumValue(1)),
Sort(Seq(Descending("gs"))), Sort(Seq(Descending("gs"))),
Limit(limit) Limit(limit)
@ -214,4 +213,32 @@ object GameRepo {
}).flatten }).flatten
} }
} }
// user1 wins, draws, losses
def confrontation(user1: User, user2: User): Fu[(Int, Int, Int)] = {
import reactivemongo.bson._
import reactivemongo.core.commands._
val userIds = List(user1, user2).sortBy(_.count.game).map(_.id)
val command = Aggregate(gameTube.coll.name, Seq(
Match(BSONDocument(
"uids" -> BSONDocument("$all" -> userIds),
"s" -> BSONDocument("$gte" -> chess.Status.Mate.id)
)),
GroupField("wid")("nb" -> SumValue(1))
))
gameTube.coll.db.command(command) map { stream
val res = (stream.toList map { obj
toJSON(obj).asOpt[JsObject] flatMap { o
o int "nb" map { nb
~(o str "_id") -> nb
}
}
}).flatten.toMap
(
~(res get user1.id),
~(res get ""),
~(res get user2.id)
)
}
}
} }

View file

@ -268,6 +268,7 @@ final class I18nKeys(translator: Translator) {
val startPosition = new Key("startPosition") val startPosition = new Key("startPosition")
val clearBoard = new Key("clearBoard") val clearBoard = new Key("clearBoard")
val savePosition = new Key("savePosition") val savePosition = new Key("savePosition")
val ratedGameResult = new Key("ratedGameResult")
def keys = List(playWithAFriend, inviteAFriendToPlayWithYou, playWithTheMachine, challengeTheArtificialIntelligence, toInviteSomeoneToPlayGiveThisUrl, gameOver, waitingForOpponent, waiting, yourTurn, aiNameLevelAiLevel, level, toggleTheChat, toggleSound, chat, resign, checkmate, stalemate, white, black, createAGame, noGameAvailableRightNowCreateOne, whiteIsVictorious, blackIsVictorious, playWithTheSameOpponentAgain, newOpponent, playWithAnotherOpponent, yourOpponentWantsToPlayANewGameWithYou, joinTheGame, whitePlays, blackPlays, theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim, makeYourOpponentResign, forceResignation, talkInChat, theFirstPersonToComeOnThisUrlWillPlayWithYou, whiteCreatesTheGame, blackCreatesTheGame, whiteJoinsTheGame, blackJoinsTheGame, whiteResigned, blackResigned, whiteLeftTheGame, blackLeftTheGame, shareThisUrlToLetSpectatorsSeeTheGame, youAreViewingThisGameAsASpectator, replayAndAnalyse, computerAnalysisInProgress, theComputerAnalysisYouRequestedIsNowAvailable, theComputerAnalysisHasFailed, viewTheComputerAnalysis, requestAComputerAnalysis, blunders, mistakes, inaccuracies, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, newToLichess, youNeedAnAccountToDoThat, signUp, people, games, forum, xPostedInForumY, chessPlayers, minutesPerSide, variant, timeControl, time, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, nbGamesWithYou, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, finished, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, noNewMessages, subject, recipient, send, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, whoIsOnline, allPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, search, advancedSearch, tournament, tournaments, tournamentPoints, viewTournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents, teams, nbMembers, allTeams, newTeam, myTeams, noTeamFound, joinTeam, quitTeam, anyoneCanJoin, aConfirmationIsRequiredToJoin, joiningPolicy, teamLeader, teamBestPlayers, teamRecentMembers, xJoinedTeamY, xCreatedTeamY, averageElo, location, settings, filterGames, reset, apply, leaderboard, pasteTheFenStringHere, pasteThePgnStringHere, fromPosition, continueFromHere, importGame, nbImportedGames, thisIsAChessCaptcha, clickOnTheBoardToMakeYourMove, notACheckmate, colorPlaysCheckmateInOne, retry, reconnecting, onlineFriends, noFriendsOnline, findFriends, favoriteOpponents, follow, following, unfollow, block, blocked, unblock, followsYou, xStartedFollowingY, nbFollowers, nbFollowing, profile, more, memberSince, lastLogin, challengeToPlay, player, list, graph, all, lessThanNbMinutes, xToYMinutes, textIsTooShort, textIsTooLong, required, addToChrome, openTournaments, duration, winner, standing, createANewTournament, join, withdraw, points, wins, losses, winStreak, createdBy, waitingForNbPlayers, tournamentIsStarting, nbMinutesPerSidePlusNbSecondsPerMove, anonymousCanJoin, boardEditor, startPosition, clearBoard, savePosition) def keys = List(playWithAFriend, inviteAFriendToPlayWithYou, playWithTheMachine, challengeTheArtificialIntelligence, toInviteSomeoneToPlayGiveThisUrl, gameOver, waitingForOpponent, waiting, yourTurn, aiNameLevelAiLevel, level, toggleTheChat, toggleSound, chat, resign, checkmate, stalemate, white, black, createAGame, noGameAvailableRightNowCreateOne, whiteIsVictorious, blackIsVictorious, playWithTheSameOpponentAgain, newOpponent, playWithAnotherOpponent, yourOpponentWantsToPlayANewGameWithYou, joinTheGame, whitePlays, blackPlays, theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim, makeYourOpponentResign, forceResignation, talkInChat, theFirstPersonToComeOnThisUrlWillPlayWithYou, whiteCreatesTheGame, blackCreatesTheGame, whiteJoinsTheGame, blackJoinsTheGame, whiteResigned, blackResigned, whiteLeftTheGame, blackLeftTheGame, shareThisUrlToLetSpectatorsSeeTheGame, youAreViewingThisGameAsASpectator, replayAndAnalyse, computerAnalysisInProgress, theComputerAnalysisYouRequestedIsNowAvailable, theComputerAnalysisHasFailed, viewTheComputerAnalysis, requestAComputerAnalysis, blunders, mistakes, inaccuracies, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, newToLichess, youNeedAnAccountToDoThat, signUp, people, games, forum, xPostedInForumY, chessPlayers, minutesPerSide, variant, timeControl, time, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, nbGamesWithYou, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, finished, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, noNewMessages, subject, recipient, send, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, whoIsOnline, allPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, search, advancedSearch, tournament, tournaments, tournamentPoints, viewTournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents, teams, nbMembers, allTeams, newTeam, myTeams, noTeamFound, joinTeam, quitTeam, anyoneCanJoin, aConfirmationIsRequiredToJoin, joiningPolicy, teamLeader, teamBestPlayers, teamRecentMembers, xJoinedTeamY, xCreatedTeamY, averageElo, location, settings, filterGames, reset, apply, leaderboard, pasteTheFenStringHere, pasteThePgnStringHere, fromPosition, continueFromHere, importGame, nbImportedGames, thisIsAChessCaptcha, clickOnTheBoardToMakeYourMove, notACheckmate, colorPlaysCheckmateInOne, retry, reconnecting, onlineFriends, noFriendsOnline, findFriends, favoriteOpponents, follow, following, unfollow, block, blocked, unblock, followsYou, xStartedFollowingY, nbFollowers, nbFollowing, profile, more, memberSince, lastLogin, challengeToPlay, player, list, graph, all, lessThanNbMinutes, xToYMinutes, textIsTooShort, textIsTooLong, required, addToChrome, openTournaments, duration, winner, standing, createANewTournament, join, withdraw, points, wins, losses, winStreak, createdBy, waitingForNbPlayers, tournamentIsStarting, nbMinutesPerSidePlusNbSecondsPerMove, anonymousCanJoin, boardEditor, startPosition, clearBoard, savePosition, ratedGameResult)
} }

View file

@ -73,7 +73,7 @@ body.dark #site_header div.side_menu a.active,
body.dark div.game_row, body.dark div.game_row,
body.dark div.user_lists form.search_user_form input, body.dark div.user_lists form.search_user_form input,
body.dark div.user_lists div.all_users, body.dark div.user_lists div.all_users,
body.dark div.user_show div.elo_with_me, body.dark div.user_show div.boxed_data,
body.dark #lichess_forum div.post, body.dark #lichess_forum div.post,
body.dark #lichess_forum textarea, body.dark #lichess_forum textarea,
body.dark #lichess_forum form.wide input, body.dark #lichess_forum form.wide input,
@ -251,7 +251,7 @@ body.dark .mini_board {
body.dark div.game_row:nth-child(odd), body.dark div.game_row:nth-child(odd),
body.dark #lichess_forum table.forum_table tr:nth-child(odd), body.dark #lichess_forum table.forum_table tr:nth-child(odd),
body.dark #lichess_message tr:nth-child(even), body.dark #lichess_message tr:nth-child(even),
body.dark div.user_show .elo_with_me, body.dark div.user_show div.boxed_data,
body.dark div.content_box_inter, body.dark div.content_box_inter,
body.dark #GameText tr:nth-child(even), body.dark #GameText tr:nth-child(even),
body.dark table.slist tbody tr:nth-child(even), body.dark table.slist tbody tr:nth-child(even),

View file

@ -76,7 +76,7 @@ div.user_show .user-infos {
} }
div.user_show .user_bio, div.user_show .user_bio,
div.user_show .elo_with_me, div.user_show .boxed_data,
div.user_show .stats, div.user_show .stats,
div.user_show .tournament_points, div.user_show .tournament_points,
div.user_show .teams { div.user_show .teams {
@ -91,7 +91,7 @@ div.user_show .teams a {
margin: 5px 0; margin: 5px 0;
} }
div.user_show div.elo_with_me { div.user_show div.boxed_data {
width: 292px; width: 292px;
padding: 5px 8px; padding: 5px 8px;
border: 1px solid #eaeaea; border: 1px solid #eaeaea;

1
todo
View file

@ -71,6 +71,7 @@ opera bug http://postimg.org/image/zcv8hse8n/full/
customize sound notifications http://imgur.com/70WVyb5 customize sound notifications http://imgur.com/70WVyb5
show friend game results on timeline show friend game results on timeline
opera issue http://en.lichess.org/forum/lichess-feedback/new-game-wont-show-on-games-list-opera#1 opera issue http://en.lichess.org/forum/lichess-feedback/new-game-wont-show-on-games-list-opera#1
analyse must update search index
--- ---