implement user-side report routing, controller and templating

pull/83/head
Thibault Duplessis 2013-07-27 17:39:19 +02:00
parent 9fac73aad7
commit d274266076
9 changed files with 177 additions and 6 deletions

View File

@ -104,4 +104,5 @@ object Env {
def importer = lila.importer.Env.current
def tournament = lila.tournament.Env.current
def relation = lila.relation.Env.current
def report = lila.report.Env.current
}

View File

@ -0,0 +1,45 @@
package controllers
import play.api.mvc._
import play.api.templates.Html
import views._
import lila.app._
import lila.security.Granter
import lila.user.{ User UserModel, UserRepo, Context }
object Report extends LilaController {
private def forms = Env.report.forms
private def api = Env.report.api
def form = Auth { implicit ctx
implicit me
get("username") ?? UserRepo.named flatMap { user
forms.createWithCaptcha map {
case (form, captcha) Ok(html.report.form(form, user, captcha))
}
}
}
def create = AuthBody { implicit ctx
implicit me
implicit val req = ctx.body
forms.create.bindFromRequest.fold(
err get("username") ?? UserRepo.named flatMap { user
forms.anyCaptcha map { captcha
BadRequest(html.report.form(err.pp, user, captcha))
}
},
data api.create(data, me) map { thread
Redirect(routes.Report.thanks)
})
}
def thanks = Auth { implicit ctx
implicit me
fuccess {
html.report.thanks()
}
}
}

View File

@ -0,0 +1,53 @@
@(form: Form[_], reqUser: Option[User] = None, captcha: lila.common.Captcha)(implicit ctx: Context)
@import lila.report.Reason
@site.layout(title = "Report a user", moreCss = cssTag("report.css")) {
<div class="content_box" id="report">
<h1>Report a user</h1>
<form class="create" action="@routes.Report.create()@reqUser.map(u => "?username=" + u.username)" method="post">
<div class="field_to">
<label for="@form("username").id">User</label>
@reqUser.map { user =>
@userLink(user, cssClass = "inline".some)
<input
type="hidden"
name="@form("username").name"
value="@user.id">
}.getOrElse {
<input
type="text"
data-provider="@routes.User.autocomplete"
class="autocomplete"
required="required"
name="@form("username").name"
id="@form("username").id"
value="@form("username").value">
@errMsg(form("username"))
}
</div>
<div class="field_reason">
<label for="@form("reason").id">Reason</label>
@base.select(form("reason"), Reason.all.map(r => r.name -> r.name.capitalize), "What's the matter?".some)
@errMsg(form("reason"))
</div>
<div class="field_body">
<label for="@form("text").id">Description</label>
<textarea
name="@form("text").name"
required="required"
id="@form("text").id">@form("text").value</textarea>
<p class="help">
Paste the link to the game(s) and explain what is wrong about this user behavior.
</p>
@errMsg(form("text"))
</div>
@base.captcha(form("move"), form("gameId"), captcha)
@errMsg(form)
<div class="actions">
<input class="send button" type="submit" value="@trans.send()" />
<a class="cancel" href="@routes.Lobby.home()">@trans.cancel()</a>
</div>
</form>
</div>
}

View File

@ -0,0 +1,12 @@
@()(implicit ctx: Context)
@site.layout(title = "Thanks for the report", moreCss = cssTag("report.css")) {
<div class="content_box small_box">
<h1 class="lichess_title">Thanks for the report</h1>
<p>The moderators will review it very soon, and take appropriate action</p>
<p>
<a href="@routes.Lobby.home">Back to lichess homepage</a>
</p>
</div>
}

View File

@ -131,6 +131,10 @@ evenMoreCss = evenMoreCss) {
<p>@trans.lastLogin() @timeago(seen)</p>
}
<a href="@routes.User.opponents(u.username)">@trans.favoriteOpponents()</a>
@if(ctx.isAuth && !(ctx is u)) {
<br />
<a href="@routes.Report.form?username=@u.username">Report @u.username to moderators</a>
}
<div class="teams">
@teamIds(u.id).sortBy(t => !myTeam(t)).map { teamId =>
@teamLink(teamId, ("s16 team revert-underline" + myTeam(teamId).fold(" mine", "")).some)

View File

@ -187,6 +187,11 @@ GET /monitor controllers.Monitor.index
GET /monitor/socket controllers.Monitor.websocket
GET /monitor/status controllers.Monitor.status
# Report
GET /report controllers.Report.form
POST /report controllers.Report.create
GET /report/thanks controllers.Report.thanks
# Misc
POST /cli controllers.Cli.command
GET /captcha/$id<[\w]{8}> controllers.Main.captchaCheck(id: String)

View File

@ -1,16 +1,16 @@
package lila.report
private[report] sealed trait Reason {
sealed trait Reason {
def name = toString.toLowerCase
}
private[report] object Reason {
object Reason {
object Cheat extends Reason
object Violence extends Reason
object Troll extends Reason
object Other extends Reason
case object Cheat extends Reason
case object Violence extends Reason
case object Troll extends Reason
case object Other extends Reason
val all = List(Cheat, Violence, Troll, Other)
val names = all map (_.name)

View File

@ -0,0 +1,47 @@
#report form.create {
font-size: 1.1em;
padding-top: 2em;
}
#report form.create div.actions,
#report div.answer div.actions {
padding: 0.5em 0;
font-size: 1.1em;
}
#report form.create .actions a,
#report div.answer div.actions a {
margin-left: 1em;
}
#report form.create >div >label {
float: left;
width: 100px;
text-align: right;
margin-right: 10px;
vertical-align: middle;
margin-top: 3px;
}
#report .field_to input,
#report .field_reason input {
width: 450px;
border: 1px solid #D4D4D4;
padding: 3px 5px;
}
#report .field_to,
#report .field_reason {
margin-bottom: 1em;
}
#report textarea {
width: 547px;
height: 150px;
padding: 10px;
border: 1px solid #D4D4D4;
}
#report .error {
color: red;
margin-left: 110px;
}
#report .help {
margin-left: 110px;
}
#report .checkmateCaptcha {
margin-top: 2em;
}

4
todo
View File

@ -51,3 +51,7 @@ customize piece images
opera bug http://postimg.org/image/zcv8hse8n/full/
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
deploy
------
db.report.ensureIndex({createdAt: -1, processedBy: 1})