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

pull/83/head
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,
rank: Option[(Int, Int)],
nbPlaying: Int,
nbWithMe: Option[Int],
confrontation: Option[(Int, Int, Int)],
nbBookmark: Int,
eloWithMe: Option[List[(String, Int)]],
eloChart: Option[EloChart],
@ -22,6 +22,10 @@ case class UserInfo(
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)
}
@ -41,18 +45,18 @@ object UserInfo {
GameRepo count (_ notFinished user.id) map (_.some)
}) zip
(ctx.me.filter(user!=) ?? { me
GameRepo count (_.opponents(user, me)) map (_.some)
GameRepo.confrontation(user, me) map (_.some)
}) zip
(bookmarkApi countByUser user) zip
EloChart(user) zip
relationApi.nbFollowing(user.id) zip
relationApi.nbFollowers(user.id) zip
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,
rank = rank,
nbPlaying = ~nbPlaying,
nbWithMe = nbWithMe,
confrontation = confrontation,
nbBookmark = nbBookmark,
eloWithMe = ctx.me.filter(user !=) map { me
List(

View File

@ -111,12 +111,23 @@ evenMoreCss = evenMoreCss) {
}
@bio
@info.eloWithMe.map { eloWithMe =>
<div class="elo_with_me">
<div class="elo_with_me boxed_data">
@trans.ratedGameResult()<br />
@eloWithMe.map { e =>
@e._1.capitalize: <strong>@showNumber(e._2)</strong>
}
</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">
<p>@trans.memberSince() @showDate(u.createdAt)</p>
@u.seenAt.map { seen =>

View File

@ -244,3 +244,4 @@ boardEditor=Board editor
startPosition=Start position
clearBoard=Clear board
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](
Json.obj(
"count.rated" -> $gt(0),
"_id" -> "legend"
"count.rated" -> $gt(0)
)) sort ($sort desc "seenAt")
private def gamesQuery(user: User) = $query.apply[Game](

View File

@ -2,18 +2,17 @@ package lila.game
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.{ Color, Variant, Status }
import lila.common.PimpedJson._
import lila.db.api._
import lila.db.Implicits._
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
object GameRepo {
@ -197,9 +196,9 @@ object GameRepo {
import reactivemongo.core.commands._
val command = Aggregate(gameTube.coll.name, Seq(
Match(BSONDocument("uids" -> userId)),
Match(BSONDocument("uids" -> BSONDocument("$size" -> BSONInteger(2)))),
Match(BSONDocument("uids" -> BSONDocument("$size" -> 2))),
Unwind("uids"),
Match(BSONDocument("uids" -> BSONDocument("$ne" -> BSONString(userId)))),
Match(BSONDocument("uids" -> BSONDocument("$ne" -> userId))),
GroupField("uids")("gs" -> SumValue(1)),
Sort(Seq(Descending("gs"))),
Limit(limit)
@ -214,4 +213,32 @@ object GameRepo {
}).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 clearBoard = new Key("clearBoard")
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.user_lists form.search_user_form input,
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 textarea,
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 #lichess_forum table.forum_table tr:nth-child(odd),
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 #GameText 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 .elo_with_me,
div.user_show .boxed_data,
div.user_show .stats,
div.user_show .tournament_points,
div.user_show .teams {
@ -91,7 +91,7 @@ div.user_show .teams a {
margin: 5px 0;
}
div.user_show div.elo_with_me {
div.user_show div.boxed_data {
width: 292px;
padding: 5px 8px;
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
show friend game results on timeline
opera issue http://en.lichess.org/forum/lichess-feedback/new-game-wont-show-on-games-list-opera#1
analyse must update search index
---