appeal nav tree WIP - for lichess-org/tavern#37
parent
d2002257d2
commit
9207c35137
|
@ -6,26 +6,32 @@ import views._
|
|||
import lila.api.Context
|
||||
import lila.app._
|
||||
import lila.report.Suspect
|
||||
import play.api.data.Form
|
||||
|
||||
final class Appeal(env: Env, reportC: => Report) extends LilaController(env) {
|
||||
|
||||
import lila.appeal.Appeal.form
|
||||
|
||||
def home =
|
||||
Auth { implicit ctx => me =>
|
||||
env.appeal.api.mine(me) map { appeal =>
|
||||
Ok(html.appeal.discussion(appeal, env.appeal.forms.text))
|
||||
}
|
||||
renderAppealOrTree(me) map { Ok(_) }
|
||||
}
|
||||
|
||||
private def renderAppealOrTree(
|
||||
me: lila.user.User,
|
||||
err: Option[Form[String]] = None
|
||||
)(implicit ctx: Context) = env.appeal.api.mine(me) map {
|
||||
case None => html.appeal.tree(me)
|
||||
case Some(a) => html.appeal.discussion(a, err | form)
|
||||
}
|
||||
|
||||
def post =
|
||||
AuthBody { implicit ctx => me =>
|
||||
implicit val req = ctx.body
|
||||
env.appeal.forms.text
|
||||
form
|
||||
.bindFromRequest()
|
||||
.fold(
|
||||
err =>
|
||||
env.appeal.api.mine(me) map { appeal =>
|
||||
BadRequest(html.appeal.discussion(appeal, err))
|
||||
},
|
||||
err => renderAppealOrTree(me, err.some) map { BadRequest(_) },
|
||||
text => env.appeal.api.post(text, me) inject Redirect(routes.Appeal.home).flashSuccess
|
||||
)
|
||||
}
|
||||
|
@ -43,7 +49,7 @@ final class Appeal(env: Env, reportC: => Report) extends LilaController(env) {
|
|||
Secure(_.Appeals) { implicit ctx => me =>
|
||||
asMod(username) { (appeal, suspect) =>
|
||||
env.report.api.inquiries.ofSuspectId(suspect.user.id) map { inquiry =>
|
||||
Ok(html.appeal.discussion.show(appeal, suspect, inquiry, env.appeal.forms.text, getPresets))
|
||||
Ok(html.appeal.discussion.show(appeal, suspect, inquiry, form, getPresets))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +58,7 @@ final class Appeal(env: Env, reportC: => Report) extends LilaController(env) {
|
|||
SecureBody(_.Appeals) { implicit ctx => me =>
|
||||
asMod(username) { (appeal, suspect) =>
|
||||
implicit val req = ctx.body
|
||||
env.appeal.forms.text
|
||||
form
|
||||
.bindFromRequest()
|
||||
.fold(
|
||||
err =>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package views.html
|
||||
package appeal
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app.templating.Environment._
|
||||
import lila.app.ui.ScalatagsTemplate._
|
||||
|
||||
object bits {
|
||||
|
||||
def layout(title: String)(body: Frag)(implicit ctx: Context) =
|
||||
views.html.base.layout(
|
||||
title = title,
|
||||
moreCss = frag(
|
||||
cssTag("form3"),
|
||||
cssTag("appeal")
|
||||
),
|
||||
moreJs = jsModule("appeal")
|
||||
)(body)
|
||||
}
|
|
@ -16,35 +16,21 @@ import lila.user.User
|
|||
|
||||
object discussion {
|
||||
|
||||
def apply(appeal: Option[Appeal], textForm: Form[_])(implicit ctx: Context) =
|
||||
layout("Appeal") {
|
||||
def apply(appeal: Appeal, textForm: Form[String])(implicit ctx: Context) =
|
||||
bits.layout("Appeal") {
|
||||
main(cls := "page-small box box-pad page appeal")(
|
||||
appeal match {
|
||||
case Some(a) => renderAppeal(a, textForm, asMod = false, presets = none)
|
||||
case None => newAppeal(textForm)
|
||||
}
|
||||
renderAppeal(appeal, textForm, asMod = false, presets = none)
|
||||
)
|
||||
}
|
||||
|
||||
private def newAppeal(textForm: Form[_])(implicit ctx: Context) =
|
||||
frag(
|
||||
h1("Appeal a moderation decision"),
|
||||
renderHelp,
|
||||
div(cls := "body")(
|
||||
renderForm(textForm, action = routes.Appeal.post.url, isNew = true, presets = none)
|
||||
)
|
||||
)
|
||||
|
||||
def show(
|
||||
appeal: Appeal,
|
||||
suspect: Suspect,
|
||||
inquiry: Option[Inquiry],
|
||||
textForm: Form[_],
|
||||
textForm: Form[String],
|
||||
presets: ModPresets
|
||||
)(implicit
|
||||
ctx: Context
|
||||
) =
|
||||
layout(s"Appeal by ${suspect.user.username}") {
|
||||
)(implicit ctx: Context) =
|
||||
bits.layout(s"Appeal by ${suspect.user.username}") {
|
||||
main(cls := "page-small box box-pad page appeal")(
|
||||
renderAppeal(
|
||||
appeal,
|
||||
|
@ -81,19 +67,9 @@ object discussion {
|
|||
)
|
||||
}
|
||||
|
||||
private def layout(title: String)(body: Frag)(implicit ctx: Context) =
|
||||
views.html.base.layout(
|
||||
title = title,
|
||||
moreCss = frag(
|
||||
cssTag("form3"),
|
||||
cssTag("appeal")
|
||||
),
|
||||
moreJs = jsModule("appeal")
|
||||
)(body)
|
||||
|
||||
private def renderAppeal(
|
||||
appeal: Appeal,
|
||||
textForm: Form[_],
|
||||
textForm: Form[String],
|
||||
asMod: Boolean,
|
||||
inquiry: Boolean = false,
|
||||
presets: Option[ModPresets]
|
||||
|
@ -125,19 +101,6 @@ object discussion {
|
|||
)
|
||||
)
|
||||
|
||||
private def renderHelp =
|
||||
div(cls := "appeal__help")(
|
||||
p(
|
||||
"If your account has been restricted for violation of ",
|
||||
a(href := routes.Page.tos)("the Lichess rules"),
|
||||
" you may file an appeal here."
|
||||
),
|
||||
p(
|
||||
"You can read more about the appeal process ",
|
||||
a(href := routes.Page.loneBookmark("appeal"))("here.")
|
||||
)
|
||||
)
|
||||
|
||||
private def renderUser(appeal: Appeal, userId: User.ID, asMod: Boolean)(implicit ctx: Context) =
|
||||
if (appeal isAbout userId) userIdLink(userId.some)
|
||||
else
|
||||
|
@ -150,7 +113,7 @@ object discussion {
|
|||
)
|
||||
)
|
||||
|
||||
private def renderForm(form: Form[_], action: String, isNew: Boolean, presets: Option[ModPresets])(implicit
|
||||
def renderForm(form: Form[String], action: String, isNew: Boolean, presets: Option[ModPresets])(implicit
|
||||
ctx: Context
|
||||
) =
|
||||
postForm(st.action := action)(
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package views.html
|
||||
package appeal
|
||||
|
||||
import controllers.routes
|
||||
import play.api.data.Form
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app.templating.Environment._
|
||||
import lila.app.ui.ScalatagsTemplate._
|
||||
import lila.report.Report.Inquiry
|
||||
import lila.user.User
|
||||
|
||||
object tree {
|
||||
|
||||
import trans.contact.doNotMessageModerators
|
||||
import views.html.base.navTree._
|
||||
|
||||
private def cleanMenu(implicit ctx: Context): Branch =
|
||||
Branch(
|
||||
"root",
|
||||
"Your account is not marked or restricted. You're all good!",
|
||||
List(
|
||||
Leaf(
|
||||
"clean-other-account",
|
||||
"I want to appeal for another account",
|
||||
frag(
|
||||
p(
|
||||
"Sorry we don't take appeals from other accounts. The appeal should come from nowhere else, but the concerned account."
|
||||
)
|
||||
)
|
||||
),
|
||||
Leaf(
|
||||
"clean-warning",
|
||||
"I want to discuss a warning I received",
|
||||
frag(
|
||||
p(
|
||||
"Please note that warnings are only warnings, and that your account has not been restricted currently.",
|
||||
br,
|
||||
"If you still want to file an appeal, use the following form:"
|
||||
),
|
||||
newAppeal
|
||||
)
|
||||
),
|
||||
Leaf(
|
||||
"clean-other-issue",
|
||||
"I have another issue to discuss",
|
||||
p(
|
||||
"This channel of communication is for appealing moderation related issues.",
|
||||
br,
|
||||
"Please use ",
|
||||
a(href := routes.Main.contact)("the contact page"),
|
||||
" or ",
|
||||
a(href := "https://discordapp.com/invite/pvHanhg")("our discord server"),
|
||||
" to contact us about other issues.",
|
||||
br,
|
||||
"You can also ",
|
||||
a(href := routes.Page.loneBookmark("appeal"))("find here more information about appeals.")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def apply(me: User)(implicit ctx: Context) =
|
||||
bits.layout("Appeal a moderation decision") {
|
||||
main(cls := "page page-small box box-pad appeal")(
|
||||
h1("Appeal"),
|
||||
div(cls := "nav-tree")(
|
||||
renderNode(
|
||||
{
|
||||
if (me.marks.clean) cleanMenu
|
||||
else ???
|
||||
},
|
||||
none
|
||||
)
|
||||
),
|
||||
p(cls := "appeal__moderators text", dataIcon := "")(doNotMessageModerators())
|
||||
)
|
||||
}
|
||||
|
||||
private def newAppeal(implicit ctx: Context) =
|
||||
discussion.renderForm(
|
||||
lila.appeal.Appeal.form,
|
||||
action = routes.Appeal.post.url,
|
||||
isNew = true,
|
||||
presets = none
|
||||
)
|
||||
|
||||
private def renderHelp =
|
||||
div(cls := "appeal__help")(
|
||||
p(
|
||||
"If your account has been restricted for violation of ",
|
||||
a(href := routes.Page.tos)("the Lichess rules"),
|
||||
" you may file an appeal here."
|
||||
),
|
||||
p(
|
||||
"You can read more about the appeal process ",
|
||||
a(href := routes.Page.loneBookmark("appeal"))("here.")
|
||||
)
|
||||
)
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package views.html
|
||||
package base
|
||||
|
||||
import lila.api.Context
|
||||
import lila.app.templating.Environment._
|
||||
import lila.app.ui.ScalatagsTemplate._
|
||||
|
||||
object navTree {
|
||||
|
||||
sealed trait Node {
|
||||
val id: String
|
||||
val name: Frag
|
||||
}
|
||||
case class Branch(id: String, name: Frag, children: List[Node]) extends Node
|
||||
case class Leaf(id: String, name: Frag, content: Frag) extends Node
|
||||
|
||||
def renderNode(node: Node, parent: Option[Node])(implicit ctx: Context): Frag =
|
||||
node match {
|
||||
case Leaf(_, _, content) =>
|
||||
List(
|
||||
div(makeId(node.id), cls := "node leaf")(
|
||||
h2(parent map goBack, node.name),
|
||||
div(cls := "content")(content)
|
||||
)
|
||||
)
|
||||
case b @ Branch(id, _, children) =>
|
||||
frag(
|
||||
div(makeId(node.id), cls := s"node branch $id")(
|
||||
h2(parent map goBack, node.name),
|
||||
div(cls := "links")(
|
||||
children map { child =>
|
||||
a(makeLink(child.id))(child.name)
|
||||
}
|
||||
)
|
||||
),
|
||||
children map { renderNode(_, b.some) }
|
||||
)
|
||||
}
|
||||
|
||||
private def makeId(id: String) = st.id := s"help-$id"
|
||||
|
||||
private def makeLink(id: String) = href := s"#help-$id"
|
||||
|
||||
private def goBack(parent: Node): Frag =
|
||||
a(makeLink(parent.id), cls := "back", dataIcon := "I", title := "Go back")
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package views
|
||||
package html.site
|
||||
package views.html
|
||||
package site
|
||||
|
||||
import controllers.routes
|
||||
import scala.util.chaining._
|
||||
|
@ -11,13 +11,7 @@ import lila.app.ui.ScalatagsTemplate._
|
|||
object contact {
|
||||
|
||||
import trans.contact._
|
||||
|
||||
sealed private trait Node {
|
||||
val id: String
|
||||
val name: Frag
|
||||
}
|
||||
private case class Branch(id: String, name: Frag, children: List[Node]) extends Node
|
||||
private case class Leaf(id: String, name: Frag, content: Frag) extends Node
|
||||
import views.html.base.navTree._
|
||||
|
||||
private def reopenLeaf(prefix: String)(implicit ctx: Context) =
|
||||
Leaf(
|
||||
|
@ -347,35 +341,6 @@ object contact {
|
|||
)
|
||||
)
|
||||
|
||||
private def renderNode(node: Node, parent: Option[Node])(implicit ctx: Context): Frag =
|
||||
node match {
|
||||
case Leaf(_, _, content) =>
|
||||
List(
|
||||
div(makeId(node.id), cls := "node leaf")(
|
||||
h2(parent map goBack, node.name),
|
||||
div(cls := "content")(content)
|
||||
)
|
||||
)
|
||||
case b @ Branch(id, _, children) =>
|
||||
frag(
|
||||
div(makeId(node.id), cls := s"node branch $id")(
|
||||
h2(parent map goBack, node.name),
|
||||
div(cls := "links")(
|
||||
children map { child =>
|
||||
a(makeLink(child.id))(child.name)
|
||||
}
|
||||
)
|
||||
),
|
||||
children map { renderNode(_, b.some) }
|
||||
)
|
||||
}
|
||||
|
||||
private def makeId(id: String) = st.id := s"help-$id"
|
||||
private def makeLink(id: String) = href := s"#help-$id"
|
||||
|
||||
private def goBack(parent: Node): Frag =
|
||||
a(makeLink(parent.id), cls := "back", dataIcon := "I", title := "Go back")
|
||||
|
||||
def apply()(implicit ctx: Context) =
|
||||
page.layout(
|
||||
title = trans.contact.contact.txt(),
|
||||
|
|
|
@ -59,6 +59,13 @@ object Appeal {
|
|||
def apply(key: String) = all.find(_.key == key)
|
||||
}
|
||||
|
||||
val form = {
|
||||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
Form[String](
|
||||
single("text" -> nonEmptyText)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
case class AppealMsg(
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package lila.appeal
|
||||
|
||||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
|
||||
final class AppealForm {
|
||||
|
||||
val text = Form(
|
||||
single("text" -> nonEmptyText)
|
||||
)
|
||||
}
|
|
@ -12,7 +12,5 @@ final class Env(
|
|||
|
||||
private val coll = db(CollName("appeal"))
|
||||
|
||||
lazy val forms = wire[AppealForm]
|
||||
|
||||
lazy val api: AppealApi = wire[AppealApi]
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<string name="youCanAlsoReachReportPage">You can also reach that page by clicking the %s report button on a profile page.</string>
|
||||
<string name="doNotReportInForum">Do not report players in the forum.</string>
|
||||
<string name="doNotSendReportEmails">Do not send us report emails.</string>
|
||||
<string name="doNotMessageModerators">Do not send direct messages to moderators.</string>
|
||||
<string name="doNotMessageModerators">Please do not send direct messages to moderators.</string>
|
||||
<string name="onlyReports">Only reporting players through the report form is effective.</string>
|
||||
<string name="wantReportBug">I want to report a bug</string>
|
||||
<string name="reportBugInForum">In the Lichess Feedback section of the forum</string>
|
||||
|
|
|
@ -52,4 +52,11 @@
|
|||
.appeal-presets {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
&__moderators {
|
||||
@extend %box-radius;
|
||||
margin-top: 3em;
|
||||
padding: 2em 3em;
|
||||
background: $c-bg-zebra;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { formToXhr } from 'common/xhr';
|
||||
|
||||
lichess.load.then(() => {
|
||||
if ($('.nav-tree').length) location.hash = location.hash || '#help-root';
|
||||
|
||||
$('select.appeal-presets').on('change', (e: Event) => $('#form3-text').val((e.target as HTMLTextAreaElement).value));
|
||||
|
||||
$('form.appeal__actions__slack').on('submit', (e: Event) => {
|
||||
|
|
Loading…
Reference in New Issue