more team pages

This commit is contained in:
Thibault Duplessis 2012-12-11 10:29:50 +01:00
parent d663aa8a83
commit 481fef4408
11 changed files with 101 additions and 27 deletions

View file

@ -46,10 +46,12 @@ object Team extends LilaController {
}
def mine = Auth { implicit ctx
me
IOk(api mine me map { html.team.mine(_) })
me IOk(repo byUser me map { html.team.mine(_) })
}
def join(id: String) = TODO
def leave(id: String) = TODO
private def OnePerWeek[A <: Result](me: UserModel)(a: A)(implicit ctx: Context): Result = {
!Granter.superAdmin(me) &&
api.hasCreatedRecently(me).unsafePerformIO

View file

@ -169,6 +169,9 @@ final class I18nKeys(translator: Translator) {
val allTeams = new Key("allTeams")
val newTeam = new Key("newTeam")
val myTeams = new Key("myTeams")
val noTeamFound = new Key("noTeamFound")
val joinTeam = new Key("joinTeam")
val leaveTeam = new Key("leaveTeam")
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, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, signUp, people, games, forum, chessPlayers, minutesPerSide, variant, timeControl, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, searchAPlayer, whoIsOnline, allPlayers, namedPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, advancedSearch, tournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents, teams, nbMembers, allTeams, newTeam, myTeams)
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, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, signUp, people, games, forum, chessPlayers, minutesPerSide, variant, timeControl, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, searchAPlayer, whoIsOnline, allPlayers, namedPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, advancedSearch, tournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents, teams, nbMembers, allTeams, newTeam, myTeams, noTeamFound, joinTeam, leaveTeam)
}

View file

@ -8,8 +8,8 @@ import play.api.data.Forms._
import play.api.data.validation.Constraints._
final class DataForm(
repo: TeamRepo,
captcher: Captcha) {
repo: TeamRepo,
captcher: Captcha) {
import lila.core.Form._
@ -32,7 +32,7 @@ final class DataForm(
def captchaCreate: Captcha.Challenge = captcher.create
private def teamExists(setup: TeamSetup) =
repo.exists(Team nameToId setup.name).unsafePerformIO
repo.exists(Team nameToId setup.trim.name).unsafePerformIO
}
private[team] case class TeamSetup(
@ -40,4 +40,10 @@ private[team] case class TeamSetup(
location: Option[String],
description: String,
gameId: String,
move: String)
move: String) {
def trim = copy(
name = name.trim,
location = location map (_.trim),
description = description.trim)
}

View file

@ -14,10 +14,18 @@ case class Team(
description: String,
members: List[Member],
nbMembers: Int,
enabled: Boolean,
createdAt: DateTime,
createdBy: String) {
def slug = id
def contains(userId: String): Boolean = members exists (_ is userId)
def contains(user: User): Boolean = contains(user.id)
def canJoin(user: User) = true
def disabled = !enabled
}
object Team {
@ -33,6 +41,7 @@ object Team {
description = description,
members = Member(createdBy) :: Nil,
nbMembers = 1,
enabled = true,
createdAt = DateTime.now,
createdBy = createdBy.id)

View file

@ -16,22 +16,22 @@ final class TeamApi(
def popular(page: Int): Paginator[Team] = Paginator(
SalatAdapter(
dao = repo,
query = repo.queryAll,
query = repo.enabledQuery,
sort = repo.sortPopular),
currentPage = page,
maxPerPage = maxPerPage
) | popular(1)
def mine(me: User): List[Team] = repo byUser user.id
def create(setup: TeamSetup, me: User): IO[Team] = setup.trim |> { s
Team(
name = s.name,
location = s.location,
description = s.description,
createdBy = me) |> { team
repo saveIO team inject team
}
}
def create(setup: TeamSetup, me: User): IO[Team] = Team(
name = setup.name,
location = setup.location,
description = setup.description,
createdBy = me) |> { team
repo saveIO team inject team
}
def hasCreatedRecently(me: User): IO[Boolean] =
def hasCreatedRecently(me: User): IO[Boolean] =
repo.userHasCreatedSince(me.id, creationPeriod)
}

View file

@ -46,7 +46,7 @@ final class TeamRepo(collection: MongoCollection)
def selectId(id: String) = DBObject("_id" -> id)
val queryAll = DBObject()
val enabledQuery = DBObject("enabled" -> true)
val sortPopular = DBObject("nbMembers" -> -1)
}

View file

@ -37,7 +37,7 @@ moreJs = moreJs) {
<tr>
<td colspan="2">
<br />
No team found
@trans.noTeamFound()
</td>
</tr>
</tbody>

View file

@ -1,7 +1,35 @@
@(teams: Paginator[lila.team.Team])(implicit ctx: Context)
@(teams: List[lila.team.Team])(implicit ctx: Context)
@team.list(
name = trans.teams.str(),
teams = teams,
next = teams.nextPage map { n => routes.Team.home(n) },
tab = "all")
@team.layout(
title = trans.myTeams.str(),
currentTab = "mine".some) {
<div id="team" class="content_box team_box no_padding">
<h1>@trans.myTeams()</h1>
<table class="slist">
@if(teams.size > 0) {
<tbody>
@teams.map { team =>
<tr class="paginated_element">
<td class="subject">
<a class="team-name" href="@routes.Team.show(team.id)">@team.name</a>
@shorten(team.description, 200)
</td>
<td class="info">
<p>@trans.nbMembers(team.nbMembers)</p>
</td>
</tr>
}
</tbody>
} else {
<tbody>
<tr>
<td colspan="2">
<br />
@trans.noTeamFound()
</td>
</tr>
</tbody>
}
</table>
</div>
}

View file

@ -2,4 +2,25 @@
@team.layout(
title = t.name) {
<div class="content_box no_padding team_show">
<div class="content_box_top">
@if(~ctx.me.map(t.contains)) {
<a href="@routes.Team.leave(t.id)" class="send_message">@trans.leaveTeam()</a>
} else {
if (~ctx.me.map(t.canJoin)) {
<a href="@routes.Team.join(t.id)" class="send_message">@trans.joinTeam()</a>
}
}
<h1 class="lichess_title">@t.name</h1>
<span class="rank">
@trans.nbMembers(t.nbMembers)
</span>
@if(t.disabled) {
<span class="staff">CLOSED</span>
}
</div>
<div class="content_box_content clearfix">
@autoLink(t.description)
</div>
</div>
}

View file

@ -145,3 +145,6 @@ nbMembers=%s members
allTeams=All teams
newTeam=New team
myTeams=My teams
noTeamFound=No team found
joinTeam=Join team
leaveTeam=Leave team

View file

@ -54,8 +54,10 @@ GET /tournament/faq controllers.Tournament.faq
GET /team controllers.Team.home(page: Int ?= 1)
GET /team/new controllers.Team.form
POST /team/new controllers.Team.create
POST /team/me controllers.Team.mine
GET /team/me controllers.Team.mine
GET /team/:id controllers.Team.show(id: String)
POST /team/:id/join controllers.Team.join(id: String)
POST /team/:id/leave controllers.Team.leave(id: String)
# Analyse
GET /analyse/$gameId<[\w\-]{8}> controllers.Analyse.replay(gameId: String, color: String = "white")