post in the forum
parent
8d801171d5
commit
fbf469dbd2
|
@ -5,9 +5,24 @@ import views._
|
|||
|
||||
object ForumPost extends LilaController {
|
||||
|
||||
def topicApi = env.forum.topicApi
|
||||
def postApi = env.forum.postApi
|
||||
def forms = forum.DataForm
|
||||
|
||||
def create(categSlug: String, slug: String) = TODO
|
||||
def create(categSlug: String, slug: String, page: Int) = OpenBody { implicit ctx ⇒
|
||||
implicit val req = ctx.body
|
||||
IOptionResult(topicApi.show(categSlug, slug, page)) {
|
||||
case (categ, topic, posts) ⇒ forms.post.bindFromRequest.fold(
|
||||
err ⇒ BadRequest(html.forum.topic.show(categ, topic, posts, err.some)),
|
||||
data ⇒ (for {
|
||||
post ← postApi.makePost(categ, topic, data, ctx.me)
|
||||
} yield Redirect("%s#%d".format(
|
||||
routes.ForumTopic.show(categ.slug, topic.slug, postApi pageOf post),
|
||||
post.number)
|
||||
)).unsafePerformIO
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def delete(id: String) = TODO
|
||||
}
|
||||
|
|
|
@ -6,12 +6,16 @@ import views._
|
|||
object ForumTopic extends LilaController {
|
||||
|
||||
def topicApi = env.forum.topicApi
|
||||
def forms = forum.DataForm
|
||||
|
||||
def create(categ: String) = TODO
|
||||
def create(categ: String) = Open { implicit ctx =>
|
||||
BadRequest
|
||||
}
|
||||
|
||||
def show(categSlug: String, slug: String, page: Int) = Open { implicit ctx ⇒
|
||||
IOptionOk(topicApi.show(categSlug, slug, page)) {
|
||||
case (categ, topic, posts) ⇒ html.forum.topic.show(categ, topic, posts)
|
||||
case (categ, topic, posts) ⇒ html.forum.topic.show(categ, topic, posts,
|
||||
postForm = (!posts.hasNextPage) option forms.post)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ final class CoreEnv private (application: Application, val settings: Settings) {
|
|||
lazy val forum = new lila.forum.ForumEnv(
|
||||
settings = settings,
|
||||
mongodb = mongodb.apply _,
|
||||
userRepo = user.userRepo)
|
||||
userRepo = user.userRepo,
|
||||
userDbRef = user.userRepo.dbRef)
|
||||
|
||||
lazy val lobby = new lila.lobby.LobbyEnv(
|
||||
app = app,
|
||||
|
|
|
@ -9,8 +9,8 @@ final class CategApi(env: ForumEnv) {
|
|||
val list: IO[List[CategView]] = for {
|
||||
categs ← env.categRepo.all
|
||||
views ← (categs map { categ ⇒
|
||||
env.postRepo byId categ.lastPostId map { post ⇒
|
||||
CategView(categ, post)
|
||||
env.postApi get categ.lastPostId map { post ⇒
|
||||
CategView(categ, post, env.postApi.pageOf)
|
||||
}
|
||||
}).sequence
|
||||
} yield views
|
||||
|
|
|
@ -3,7 +3,8 @@ package forum
|
|||
|
||||
case class CategView(
|
||||
categ: Categ,
|
||||
lastPost: Option[Post]) {
|
||||
lastPost: Option[(Topic, Post)],
|
||||
pageOf: Post ⇒ Int) {
|
||||
|
||||
def slug = categ.slug
|
||||
def name = categ.name
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package lila
|
||||
package forum
|
||||
|
||||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
|
||||
object DataForm {
|
||||
|
||||
case class PostData(
|
||||
text: String,
|
||||
author: Option[String])
|
||||
|
||||
val post = Form(mapping(
|
||||
"text" -> text(minLength = 3),
|
||||
"author" -> optional(text)
|
||||
)(PostData.apply)(PostData.unapply))
|
||||
}
|
|
@ -1,15 +1,17 @@
|
|||
package lila
|
||||
package forum
|
||||
|
||||
import user.UserRepo
|
||||
import user.{ User, UserRepo }
|
||||
import core.Settings
|
||||
|
||||
import com.mongodb.casbah.MongoCollection
|
||||
import com.mongodb.DBRef
|
||||
|
||||
final class ForumEnv(
|
||||
settings: Settings,
|
||||
mongodb: String ⇒ MongoCollection,
|
||||
userRepo: UserRepo) {
|
||||
userRepo: UserRepo,
|
||||
val userDbRef: User ⇒ DBRef) {
|
||||
|
||||
import settings._
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@ package forum
|
|||
import org.joda.time.DateTime
|
||||
import com.novus.salat.annotations.Key
|
||||
import com.mongodb.DBRef
|
||||
import ornicar.scalalib.OrnicarRandom
|
||||
|
||||
case class Post(
|
||||
@Key("_id") id: String,
|
||||
topicId: String,
|
||||
author: String,
|
||||
author: Option[String],
|
||||
user: Option[DBRef],
|
||||
text: String,
|
||||
number: Int,
|
||||
|
@ -16,3 +17,22 @@ case class Post(
|
|||
|
||||
def userId: Option[String] = user map (_.getId.toString)
|
||||
}
|
||||
|
||||
object Post {
|
||||
|
||||
val idSize = 8
|
||||
|
||||
def apply(
|
||||
topicId: String,
|
||||
author: Option[String],
|
||||
user: Option[DBRef],
|
||||
text: String,
|
||||
number: Int): Post = Post(
|
||||
id = OrnicarRandom nextAsciiString idSize,
|
||||
topicId = topicId,
|
||||
author = author,
|
||||
user = user,
|
||||
text = text,
|
||||
number = number,
|
||||
createdAt = DateTime.now)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,52 @@
|
|||
package lila
|
||||
package forum
|
||||
|
||||
import user.User
|
||||
|
||||
import scalaz.effects._
|
||||
import com.github.ornicar.paginator._
|
||||
import scala.math.ceil
|
||||
|
||||
final class PostApi(env: ForumEnv, maxPerPage: Int) {
|
||||
|
||||
def create(categSlug: String, slug: String, page: Int): IO[Option[(Categ, Topic, Paginator[Post])]] =
|
||||
for {
|
||||
categOption ← env.categRepo bySlug categSlug
|
||||
topicOption ← env.topicRepo.byTree(categSlug, slug)
|
||||
} yield categOption |@| topicOption apply {
|
||||
case (categ, topic) ⇒ (categ, topic, env.postApi.paginator(topic, page))
|
||||
}
|
||||
|
||||
def makePost(
|
||||
categ: Categ,
|
||||
topic: Topic,
|
||||
data: DataForm.PostData,
|
||||
user: Option[User]): IO[Post] = for {
|
||||
number ← lastNumberOf(topic)
|
||||
post = Post(
|
||||
topicId = topic.id,
|
||||
author = data.author,
|
||||
user = user map env.userDbRef,
|
||||
text = data.text,
|
||||
number = number + 1)
|
||||
_ ← env.postRepo saveIO post
|
||||
_ ← env.topicApi denormalize topic
|
||||
_ ← env.categApi denormalize categ
|
||||
} yield post
|
||||
|
||||
def get(postId: String): IO[Option[(Topic, Post)]] = for {
|
||||
postOption ← env.postRepo byId postId
|
||||
topicOption ← postOption.fold(
|
||||
post ⇒ env.topicRepo byId post.topicId,
|
||||
io(none[Topic])
|
||||
)
|
||||
} yield (topicOption |@| postOption).tupled
|
||||
|
||||
def lastNumberOf(topic: Topic): IO[Int] =
|
||||
env.postRepo lastByTopics List(topic) map (_.number)
|
||||
|
||||
def pageOf(post: Post) = ceil(post.number / maxPerPage.toFloat).toInt
|
||||
|
||||
def paginator(topic: Topic, page: Int): Paginator[Post] =
|
||||
Paginator(
|
||||
SalatAdapter(
|
||||
|
|
|
@ -20,14 +20,23 @@ final class PostRepo(
|
|||
}
|
||||
|
||||
def lastByTopics(topics: List[Topic]): IO[Post] = io {
|
||||
find(byTopicsQuery(topics)).sort(sortQuery).limit(1).next
|
||||
find(byTopicsQuery(topics)).sort(sortQuery(-1)).limit(1).next
|
||||
}
|
||||
|
||||
val all: IO[List[Post]] = io {
|
||||
find(DBObject()).toList
|
||||
}
|
||||
|
||||
val sortQuery = DBObject("createdAt" -> -1)
|
||||
val sortQuery: DBObject = sortQuery(1)
|
||||
|
||||
def sortQuery(order: Int): DBObject = DBObject("createdAt" -> order)
|
||||
|
||||
def saveIO(post: Post): IO[Unit] = io {
|
||||
update(
|
||||
DBObject("_id" -> post.id),
|
||||
_grater asDBObject post,
|
||||
upsert = true)
|
||||
}
|
||||
|
||||
def byTopicQuery(topic: Topic) = DBObject("topicId" -> topic.id)
|
||||
|
||||
|
|
|
@ -7,13 +7,17 @@ import com.github.ornicar.paginator._
|
|||
final class TopicApi(env: ForumEnv, maxPerPage: Int) {
|
||||
|
||||
def show(categSlug: String, slug: String, page: Int): IO[Option[(Categ, Topic, Paginator[Post])]] =
|
||||
for {
|
||||
categOption ← env.categRepo bySlug categSlug
|
||||
topicOption ← env.topicRepo.byTree(categSlug, slug)
|
||||
} yield categOption |@| topicOption apply {
|
||||
case (categ, topic) ⇒ (categ, topic, env.postApi.paginator(topic, page))
|
||||
get(categSlug, slug) map {
|
||||
_ map {
|
||||
case (categ, topic) ⇒ (categ, topic, env.postApi.paginator(topic, page))
|
||||
}
|
||||
}
|
||||
|
||||
def get(categSlug: String, slug: String) = for {
|
||||
categOption ← env.categRepo bySlug categSlug
|
||||
topicOption ← env.topicRepo.byTree(categSlug, slug)
|
||||
} yield (categOption |@| topicOption).tupled
|
||||
|
||||
def paginator(categ: Categ, page: Int): Paginator[TopicView] =
|
||||
Paginator(
|
||||
SalatAdapter(
|
||||
|
@ -21,7 +25,7 @@ final class TopicApi(env: ForumEnv, maxPerPage: Int) {
|
|||
query = env.topicRepo byCategQuery categ,
|
||||
sort = env.topicRepo.sortQuery) map { topic ⇒
|
||||
env.postRepo byId topic.lastPostId map { post ⇒
|
||||
TopicView(categ, topic, post)
|
||||
TopicView(categ, topic, post, env.postApi.pageOf)
|
||||
} unsafePerformIO
|
||||
},
|
||||
currentPage = page,
|
||||
|
|
|
@ -12,6 +12,10 @@ final class TopicRepo(
|
|||
collection: MongoCollection
|
||||
) extends SalatDAO[Topic, String](collection) {
|
||||
|
||||
def byId(id: String): IO[Option[Topic]] = io {
|
||||
findOneByID(id)
|
||||
}
|
||||
|
||||
def byCateg(categ: Categ): IO[List[Topic]] = io {
|
||||
find(DBObject("categId" -> categ.slug)).toList
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ package forum
|
|||
case class TopicView(
|
||||
categ: Categ,
|
||||
topic: Topic,
|
||||
lastPost: Option[Post]) {
|
||||
lastPost: Option[Post],
|
||||
pageOf: Post ⇒ Int) {
|
||||
|
||||
def id = topic.id
|
||||
def slug = topic.slug
|
||||
|
|
|
@ -18,6 +18,7 @@ object Environment
|
|||
with DateHelper
|
||||
with JsonHelper
|
||||
with PaginatorHelper
|
||||
with FormHelper
|
||||
with round.RoundHelper
|
||||
with game.GameHelper
|
||||
with user.UserHelper
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package lila
|
||||
package templating
|
||||
|
||||
import play.api.data._
|
||||
import play.api.templates.Html
|
||||
|
||||
trait FormHelper {
|
||||
|
||||
private val errNames = Map(
|
||||
"error.minLength" -> "Text is too short."
|
||||
)
|
||||
|
||||
def errMsg(form: Field): Html = Html {
|
||||
form.errors map { e ⇒
|
||||
"""<p class="error">%s</p>""".format(
|
||||
(errNames get e.message) | e.message)
|
||||
} mkString
|
||||
}
|
||||
}
|
|
@ -4,36 +4,38 @@
|
|||
title = trans.forum.str()) {
|
||||
|
||||
<div class="forum forum_index">
|
||||
<h1>Lichess Forum</h1>
|
||||
<h1>Lichess Forum</h1>
|
||||
</div>
|
||||
<table class="categories">
|
||||
<thead>
|
||||
<tr class="thead">
|
||||
<th>Categories</th>
|
||||
<th class="right">Topics</th>
|
||||
<th class="right">Posts</th>
|
||||
<th>Last Post</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@categs.map { categ =>
|
||||
@if(categ.slug != "staff" || isGranted(Permission.StaffForum)) {
|
||||
<tr>
|
||||
<td class="subject">
|
||||
<a class="category_name" href="@routes.ForumCateg.show(categ.slug)">@categ.name</a>
|
||||
<h2 class="description">@categ.desc</h2>
|
||||
</td>
|
||||
<td class="right">@categ.nbTopics</td>
|
||||
<td class="right">@categ.nbPosts</td>
|
||||
<td class="last_post">
|
||||
@categ.lastPost.map { post =>
|
||||
<a href="#">@showDate(post.createdAt)</a><br />by @userIdToUsername(post.userId)
|
||||
}
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
<thead>
|
||||
<tr class="thead">
|
||||
<th>Categories</th>
|
||||
<th class="right">Topics</th>
|
||||
<th class="right">Posts</th>
|
||||
<th>Last Post</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@categs.map { categ =>
|
||||
@if(categ.slug != "staff" || isGranted(Permission.StaffForum)) {
|
||||
<tr>
|
||||
<td class="subject">
|
||||
<a class="category_name" href="@routes.ForumCateg.show(categ.slug)">@categ.name</a>
|
||||
<h2 class="description">@categ.desc</h2>
|
||||
</td>
|
||||
<td class="right">@categ.nbTopics</td>
|
||||
<td class="right">@categ.nbPosts</td>
|
||||
<td class="last_post">
|
||||
@categ.lastPost.map {
|
||||
case (topic, post) => {
|
||||
<a href="@routes.ForumTopic.show(categ.slug, topic.slug, categ pageOf post)#@post.number">@showDate(post.createdAt)</a><br />by @userIdToUsername(post.userId)
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ title = categ.name) {
|
|||
<tr>
|
||||
<td class="subject"><a href="@routes.ForumTopic.show(categ.slug, topic.slug)">@topic.name</a></td>
|
||||
<td class="right">@topic.views</td>
|
||||
<td class="right">@topic.nbPosts</td>
|
||||
<td class="right">@(topic.nbPosts - 1)</td>
|
||||
<td class="last_post">
|
||||
@topic.lastPost.map { post =>
|
||||
<a href="@routes.ForumTopic.show(categ.slug, topic.slug)#@post.number">@showDate(post.createdAt)</a><br />by @userIdToUsername(post.userId)
|
||||
<a href="@routes.ForumTopic.show(categ.slug, topic.slug, topic pageOf post)#@post.number">@showDate(post.createdAt)</a><br />by @userIdToUsername(post.userId)
|
||||
}
|
||||
</td>
|
||||
@if(isGranted(Permission.ModerateForum)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(categ: lila.forum.Categ, topic: lila.forum.Topic, posts: Paginator[lila.forum.Post])(implicit ctx: Context)
|
||||
@(categ: lila.forum.Categ, topic: lila.forum.Topic, posts: Paginator[lila.forum.Post], postForm: Option[Form[lila.forum.DataForm.PostData]])(implicit ctx: Context)
|
||||
|
||||
@forum.layout(
|
||||
title = topic.name) {
|
||||
|
@ -34,13 +34,34 @@ title = topic.name) {
|
|||
}
|
||||
</div>
|
||||
|
||||
<div class="bar bottom clearfix">
|
||||
@for(form <- postForm) {
|
||||
<div class="topicReply">
|
||||
<h2 class="postNewTitle" id="reply">Reply to this topic</h2>
|
||||
@form.globalError.map { error =>
|
||||
<p class="error">@error.message</p>
|
||||
}
|
||||
<form action="@routes.ForumPost.create(categ.slug, topic.slug, posts.currentPage)#bottom" method="POST" novalidate>
|
||||
<label>
|
||||
<span class="required">Message</span>
|
||||
<textarea name="@form("text").name" id="@form("text").id"></textarea>
|
||||
@errMsg(form("text"))
|
||||
</label>
|
||||
@if(!ctx.isAuth) {
|
||||
<label>
|
||||
<span>Author</span>
|
||||
<input type="text" name="@form("author").name" id="@form("author").id">
|
||||
</label>
|
||||
}
|
||||
<input type="submit" class="submit button" value="Reply" />
|
||||
<a href="@routes.ForumCateg.show(categ.slug)" style="margin-left:20px">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div id="bottom" class="bar bottom clearfix">
|
||||
<div class="pagination">
|
||||
@forum.pagination(routes.ForumTopic.show(categ.slug, topic.slug, 1), posts)
|
||||
</div>
|
||||
@if(posts.currentPage == posts.nbPages) {
|
||||
<a href="@routes.ForumPost.create(categ.slug, topic.slug)" class="action button">Reply to this topic</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
102
conf/routes
102
conf/routes
|
@ -1,11 +1,11 @@
|
|||
#Site
|
||||
GET /socket controllers.Main.websocket
|
||||
GET /socket controllers.Main.websocket
|
||||
|
||||
# Game
|
||||
GET /games controllers.Game.realtime
|
||||
GET /games/refresh/:ids controllers.Game.realtimeInner(ids: String)
|
||||
GET /games/all controllers.Game.all(page: Int ?= 1)
|
||||
GET /games/checkmate controllers.Game.checkmate(page: Int ?= 1)
|
||||
GET /games controllers.Game.realtime
|
||||
GET /games/refresh/:ids controllers.Game.realtimeInner(ids: String)
|
||||
GET /games/all controllers.Game.all(page: Int ?= 1)
|
||||
GET /games/checkmate controllers.Game.checkmate(page: Int ?= 1)
|
||||
|
||||
# Round
|
||||
GET /$gameId<[\w\-]{8}> controllers.Round.watcher(gameId: String, color: String = "white")
|
||||
|
@ -38,71 +38,71 @@ GET /analyse/$gameId<[\w\-]{8}>/$color<white|black> controllers.Analyse.replay
|
|||
GET /$gameId<[\w\-]{8}>/stats controllers.Analyse.stats(gameId: String)
|
||||
|
||||
# Setting
|
||||
POST /setting/color controllers.Setting.color
|
||||
POST /setting/sound controllers.Setting.sound
|
||||
POST /setting/color controllers.Setting.color
|
||||
POST /setting/sound controllers.Setting.sound
|
||||
|
||||
# Setup
|
||||
GET /setup/ai controllers.Setup.aiForm
|
||||
POST /setup/ai controllers.Setup.ai
|
||||
GET /setup/friend controllers.Setup.friendForm
|
||||
POST /setup/friend controllers.Setup.friend
|
||||
GET /$fullId<[\w\-]{12}>/await controllers.Setup.await(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/cancel controllers.Setup.cancel(fullId: String)
|
||||
GET /setup/hook controllers.Setup.hookForm
|
||||
POST /setup/hook controllers.Setup.hook
|
||||
GET /setup/ai controllers.Setup.aiForm
|
||||
POST /setup/ai controllers.Setup.ai
|
||||
GET /setup/friend controllers.Setup.friendForm
|
||||
POST /setup/friend controllers.Setup.friend
|
||||
GET /$fullId<[\w\-]{12}>/await controllers.Setup.await(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/cancel controllers.Setup.cancel(fullId: String)
|
||||
GET /setup/hook controllers.Setup.hookForm
|
||||
POST /setup/hook controllers.Setup.hook
|
||||
|
||||
# I18n
|
||||
GET /translation/contribute controllers.I18n.contribute
|
||||
GET /translation/contribute controllers.I18n.contribute
|
||||
|
||||
# Authentication
|
||||
GET /login controllers.Auth.login
|
||||
POST /login controllers.Auth.authenticate
|
||||
GET /logout controllers.Auth.logout
|
||||
GET /login controllers.Auth.login
|
||||
POST /login controllers.Auth.authenticate
|
||||
GET /logout controllers.Auth.logout
|
||||
|
||||
# User
|
||||
GET /@/:username/export controllers.User.export(username: String)
|
||||
GET /@/:username/:filterName controllers.User.showFilter(username: String, filterName: String, page: Int ?= 1)
|
||||
GET /@/:username controllers.User.show(username: String)
|
||||
POST /@/:username/engine controllers.User.engine(username: String)
|
||||
POST /@/:username/mute controllers.User.mute(username: String)
|
||||
GET /signup controllers.User.signUp
|
||||
GET /people controllers.User.list(page: Int ?= 1)
|
||||
GET /people/stats controllers.User.stats
|
||||
GET /people/autocomplete controllers.User.autocomplete
|
||||
GET /people/online controllers.User.online
|
||||
GET /@/:username/export controllers.User.export(username: String)
|
||||
GET /@/:username/:filterName controllers.User.showFilter(username: String, filterName: String, page: Int ?= 1)
|
||||
GET /@/:username controllers.User.show(username: String)
|
||||
POST /@/:username/engine controllers.User.engine(username: String)
|
||||
POST /@/:username/mute controllers.User.mute(username: String)
|
||||
GET /signup controllers.User.signUp
|
||||
GET /people controllers.User.list(page: Int ?= 1)
|
||||
GET /people/stats controllers.User.stats
|
||||
GET /people/autocomplete controllers.User.autocomplete
|
||||
GET /people/online controllers.User.online
|
||||
GET /account/bio controllers.User.getBio
|
||||
POST /account/bio controllers.User.setBio
|
||||
GET /account/close controllers.User.close
|
||||
POST /account/closeConfirm controllers.User.closeConfirm
|
||||
GET /account/close controllers.User.close
|
||||
POST /account/closeConfirm controllers.User.closeConfirm
|
||||
|
||||
# Wiki
|
||||
GET /wiki controllers.Wiki.home
|
||||
GET /wiki controllers.Wiki.home
|
||||
|
||||
# AI
|
||||
GET /ai controllers.Ai.run
|
||||
GET /ai controllers.Ai.run
|
||||
|
||||
# Lobby
|
||||
GET / controllers.Lobby.home
|
||||
GET /new/$ownerId<[\w\-]{12}> controllers.Lobby.hook(ownerId: String)
|
||||
GET /new/$ownerId<[\w\-]{12}>/cancel controllers.Lobby.cancel(ownerId: String)
|
||||
GET /new/$hookId<[\w\-]{8}>/join controllers.Lobby.join(hookId: String)
|
||||
GET /lobby/socket controllers.Lobby.socket
|
||||
# Lobby
|
||||
GET / controllers.Lobby.home
|
||||
GET /new/$ownerId<[\w\-]{12}> controllers.Lobby.hook(ownerId: String)
|
||||
GET /new/$ownerId<[\w\-]{12}>/cancel controllers.Lobby.cancel(ownerId: String)
|
||||
GET /new/$hookId<[\w\-]{8}>/join controllers.Lobby.join(hookId: String)
|
||||
GET /lobby/socket controllers.Lobby.socket
|
||||
|
||||
# Forum
|
||||
GET /forum controllers.ForumCateg.index
|
||||
GET /forum/:slug controllers.ForumCateg.show(slug: String, page: Int ?= 1)
|
||||
GET /forum/:categSlug/new controllers.ForumTopic.create(categSlug: String)
|
||||
GET /forum/:categSlug/:slug controllers.ForumTopic.show(categSlug: String, slug: String, page: Int ?= 1)
|
||||
GET /forum/:categSlug/:slug/new controllers.ForumPost.create(categSlug: String, slug: String)
|
||||
GET /forum/delete/topic/:id controllers.ForumTopic.delete(id: String)
|
||||
GET /forum controllers.ForumCateg.index
|
||||
GET /forum/:slug controllers.ForumCateg.show(slug: String, page: Int ?= 1)
|
||||
POST /forum/:categSlug/new controllers.ForumTopic.create(categSlug: String)
|
||||
GET /forum/:categSlug/:slug controllers.ForumTopic.show(categSlug: String, slug: String, page: Int ?= 1)
|
||||
POST /forum/:categSlug/:slug/new controllers.ForumPost.create(categSlug: String, slug: String, page: Int ?= 1)
|
||||
GET /forum/delete/topic/:id controllers.ForumTopic.delete(id: String)
|
||||
GET /forum/delete/post/:id controllers.ForumPost.delete(id: String)
|
||||
|
||||
# Monitor
|
||||
GET /monitor controllers.Monitor.index
|
||||
GET /monitor/stream controllers.Monitor.stream
|
||||
GET /nb-players controllers.Monitor.nbPlayers
|
||||
GET /nb-playing controllers.Monitor.nbPlaying
|
||||
GET /status controllers.Monitor.status
|
||||
GET /monitor controllers.Monitor.index
|
||||
GET /monitor/stream controllers.Monitor.stream
|
||||
GET /nb-players controllers.Monitor.nbPlayers
|
||||
GET /nb-playing controllers.Monitor.nbPlaying
|
||||
GET /status controllers.Monitor.status
|
||||
|
||||
# Assets
|
||||
GET /assets/*file controllers.Assets.at(path="/public", file)
|
||||
GET /assets/*file controllers.Assets.at(path="/public", file)
|
||||
|
|
|
@ -200,7 +200,7 @@ div.category .description {
|
|||
margin-left: 110px;
|
||||
}
|
||||
|
||||
#lichess_forum form ul {
|
||||
#lichess_forum form p.error {
|
||||
margin-left: 110px;
|
||||
margin-bottom: 10px;
|
||||
color: red;
|
||||
|
|
Loading…
Reference in New Issue