show many lists in users index page

pull/83/head
Thibault Duplessis 2013-07-25 00:59:45 +02:00
parent 404b6b3cf0
commit 582eed9c6d
9 changed files with 72 additions and 76 deletions

View File

@ -47,9 +47,21 @@ object User extends LilaController {
def list(page: Int) = Open { implicit ctx
Reasonable(page) {
UserRepo.topElo(10) map {
case topElo html.user.list(topElo)
}
val nb = 15
UserRepo.topElo(nb) zip
UserRepo.byIdsSortElo(env.onlineUserIdMemo.keys, nb) zip
UserRepo.topBullet(nb) zip
UserRepo.topBlitz(nb) zip
UserRepo.topSlow(nb) zip
UserRepo.topNbGame(nb) map {
case (((((elo, online), bullet), blitz), slow), nb) html.user.list(
elo = elo,
online = online,
bullet = bullet,
blitz = blitz,
slow = slow,
nb = nb)
}
}
}

View File

@ -1,19 +1,22 @@
@(topElo: List[User])(implicit ctx: Context)
@(elo: List[User], online: List[User], bullet: List[User], blitz: List[User], slow: List[User], nb: List[User])(implicit ctx: Context)
@user.layout(trans.chessPlayers.str()) {
@goodies = {
<div class="goodies">
<form class="search_user_form" action="@routes.User.show("")">
<input placeholder="@trans.search()" class="search_user autocomplete" data-provider="@routes.User.autocomplete" />
</form>
</div>
}
@user.layout(trans.chessPlayers.str(), goodies = goodies.some) {
<div class="content_box">
<!--
<form class="search_user_form" action="@routes.User.show("")">
<input placeholder="@trans.search()" class="search_user autocomplete" data-provider="@routes.User.autocomplete" />
</form>
-->
<div class="user_lists clearfix">
<div class="top_elo">
<h1 class="lichess_title">Best players ever</h1>
<div class="users">
@topElo.map { u => @userLink(u) }
</div>
</div>
@user.top(elo, "Best players ever")(_.elo)
@user.top(online, "Best players online")(_.elo)
@user.top(slow, "Active players")(_.count.game + " " + trans.games.str())
@user.top(bullet, "Best bullet players")(_.speedElos.bullet.elo)
@user.top(blitz, "Best blitz players")(_.speedElos.blitz.elo)
@user.top(slow, "Best slow players")(_.speedElos.slow.elo)
</div>
</div>
}

View File

@ -0,0 +1,12 @@
@(users: List[User], title: String)(f: User => Any)(implicit ctx: Context)
<div class="user_top">
<h2>@title</h2>
<table>
<tbody>
@users.map { u =>
<tr><td>@userLink(u, withElo = false, cssClass="revert-underline".some)</td><td>@f(u)</td></tr>
}
</tbody>
</table>
</div>

View File

@ -14,7 +14,7 @@ object $query {
def byId[A: InColl, B: Writes](id: B) = apply($select byId id)
def byIds[A: InColl, B: Writes](ids: Seq[B]) = apply($select byIds ids)
def byIds[A: InColl, B: Writes](ids: Iterable[B]) = apply($select byIds ids)
def builder[A: InColl] = implicitly[InColl[A]].coll.genericQueryBuilder
}

View File

@ -20,5 +20,5 @@ final class Cached(ttl: Duration) {
val count = AsyncCache((o: JsObject) $count(o), timeToLive = ttl)
def countEnabled: Fu[Int] = count(UserRepo.enabledQuery)
def countEnabled: Fu[Int] = count(UserRepo.enabledSelect)
}

View File

@ -17,7 +17,7 @@ final class Ranking(ttl: Duration) {
private def compute: Fu[Map[String, Int]] =
$primitive(
UserRepo.enabledQuery ++ Json.obj("elo" -> $gt(User.STARTING_ELO)),
UserRepo.enabledSelect ++ Json.obj("elo" -> $gt(User.STARTING_ELO)),
"_id",
_ sort UserRepo.sortEloDesc
)(_.asOpt[String]) map { _.zipWithIndex.map(x x._1 -> (x._2 + 1)).toMap }

View File

@ -20,7 +20,17 @@ object UserRepo {
def all: Fu[List[User]] = $find.all
def topElo(nb: Int): Fu[List[User]] = $find($query.all sort sortEloDesc, nb)
def topElo(nb: Int): Fu[List[User]] = $find(enabledQuery sort sortEloDesc, nb)
def topBullet = topSpeed("bullet") _
def topBlitz = topSpeed("blitz") _
def topSlow = topSpeed("slow") _
def topSpeed(speed: String)(nb: Int): Fu[List[User]] =
$find(enabledQuery sort ($sort desc "speedElos." + speed + ".elo"), nb)
def topNbGame(nb: Int): Fu[List[User]] =
$find(enabledQuery sort ($sort desc "count.game"), nb)
def byId(id: ID): Fu[Option[User]] = $find byId id
@ -29,19 +39,19 @@ object UserRepo {
def byOrderedIds(ids: Iterable[ID]): Fu[List[User]] = $find byOrderedIds ids
def enabledByIds(ids: Seq[ID]): Fu[List[User]] =
$find(enabledQuery ++ $select.byIds(ids))
$find(enabledSelect ++ $select.byIds(ids))
def named(username: String): Fu[Option[User]] = $find byId normalize(username)
def nameds(usernames: List[String]): Fu[List[User]] = $find byIds usernames.map(normalize)
def byIdsSortElo(ids: Seq[ID], max: Int) = $find($query byIds ids sort sortEloDesc, max)
def byIdsSortElo(ids: Iterable[ID], max: Int) = $find($query byIds ids sort sortEloDesc, max)
def allSortToints(nb: Int) = $find($query.all sort ($sort desc "toints"), nb)
def usernameById(id: ID) = $primitive.one($select(id), "username")(_.asOpt[String])
def rank(user: User) = $count(enabledQuery ++ Json.obj("elo" -> $gt(user.elo))) map (1+)
def rank(user: User) = $count(enabledSelect ++ Json.obj("elo" -> $gt(user.elo))) map (1+)
def setElo(id: ID, elo: Int, speedElo: (String, SubElo), variantElo: (String, SubElo)): Funit = (speedElo, variantElo) match {
case ((speed, sElo), (variant, vElo)) $update($select(id), $set(
@ -55,7 +65,8 @@ object UserRepo {
def setEloOnly(id: ID, elo: Int): Funit = $update($select(id), $set("elo" -> elo))
val enabledQuery = Json.obj("enabled" -> true)
val enabledSelect = Json.obj("enabled" -> true)
val enabledQuery = $query(enabledSelect)
val sortEloDesc = $sort desc "elo"

View File

@ -1,64 +1,24 @@
#lichess div.user_lists h1 {
display: block;
}
div.user_lists h2 {
font-size: 1.5em;
margin-bottom: 0.5em;
}
div.user_lists div.all_users {
div.user_lists div.user_top {
float: left;
width: 358px;
margin-right: 20px;
border: 1px solid #DADADA;
border-width: 0 1px 0 0;
width: 33.3%;
margin-bottom: 2em;
}
div.user_lists div.online_users {
float: left;
margin-left: 20px;
width: 342px;
div.user_lists div.user_top table {
width: 100%;
}
div.user_lists h1.lichess_title {
margin-bottom: 1em;
}
div.user_lists div.online_users ul {
margin-bottom: 1.5em;
}
div.user_lists ul.anonymous_users li {
background: url(/assets/images/s16.png) top left no-repeat;
background-position: 0 -208px;
width: 16px;
height: 16px;
div.user_lists div.user_top a {
display: block;
float: left;
margin: 0 8px 8px 0;
margin: 3px 0;
}
div.user_lists form.search_user_form {
margin: 0 0 2em 0;
form.search_user_form {
margin: 1em 0 0 0;
}
div.user_lists form.search_user_form input {
form.search_user_form input {
border: 1px solid #DADADA;
padding: 3px 5px;
}
div.user_lists .users li {
font-size: 1.2em;
padding: 5px 0;
}
div.user_lists ol.users li {
list-style: decimal-leading-zero inside;
}
div.user_lists .users a.send {
font-size: 0.8em;
margin-left: 1em;
color: #fff;
}
div.user_lists .users li:hover a.send {
color: #888;
}
table.best_opponents a.request {
opacity: 0;
}
table.best_opponents tr:hover a.request {
opacity: 1;
}

2
todo
View File

@ -57,5 +57,3 @@ customize sound notifications http://imgur.com/70WVyb5
opera issue http://en.lichess.org/forum/lichess-feedback/new-game-wont-show-on-games-list-opera#1
embedded games links http://2ls.ru/chessonline/
filter ranges http://en.lichess.org/forum/lichess-feedback/my-proposed-changes-with-filter-window#1
hooks resync (chrome does not remove them all)
casual games elo range