forum router type safety

This commit is contained in:
Thibault Duplessis
2024-05-07 17:13:59 +02:00
parent 7209749646
commit fb543ed033
22 changed files with 73 additions and 84 deletions
+3 -3
View File
@@ -31,7 +31,7 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController
else if topic.isOld then BadRequest("This topic is archived")
else
for
canModCateg <- access.isGrantedMod(categ.slug)
canModCateg <- access.isGrantedMod(categ.id)
replyBlocked <- access.isReplyBlockedOnUBlog(topic, canModCateg)
res <-
if replyBlocked then BadRequest.snip(trans.ublog.youBlockedByBlogAuthor()).toFuccess
@@ -42,7 +42,7 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController
CategGrantWrite(categId, tryingToPostAsMod = true):
for
unsub <- env.timeline.status(s"forum:${topic.id}")
canModCateg <- access.isGrantedMod(categ.slug)
canModCateg <- access.isGrantedMod(categ.id)
page <- renderPage:
views.forum.topic
.show(
@@ -87,7 +87,7 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController
val post = view.post
if post.userId.exists(_.is(me)) && !post.erased then
if view.topic.nbPosts == 1 then
env.forum.delete.deleteTopic(view).inject(Redirect(routes.ForumCateg.show(view.categ.slug)))
env.forum.delete.deleteTopic(view).inject(Redirect(routes.ForumCateg.show(view.categ.id)))
else postApi.erasePost(post).inject(Redirect(routes.ForumPost.redirect(id)))
else
TopicGrantModById(post.categId, post.topicId):
+5 -5
View File
@@ -29,7 +29,7 @@ final class ForumTopic(env: Env) extends LilaController(env) with ForumControlle
data =>
limit.forumTopic(ctx.ip, rateLimited):
topicApi.makeTopic(categ, data).map { topic =>
Redirect(routes.ForumTopic.show(categ.slug, topic.slug, 1))
Redirect(routes.ForumTopic.show(categ.id, topic.slug, 1))
}
)
}
@@ -43,9 +43,9 @@ final class ForumTopic(env: Env) extends LilaController(env) with ForumControlle
else
for
unsub <- ctx.me.soUse(env.timeline.status(s"forum:${topic.id}"))
canRead <- access.isGrantedRead(categ.slug)
canWrite <- access.isGrantedWrite(categ.slug, tryingToPostAsMod = true)
canModCateg <- access.isGrantedMod(categ.slug)
canRead <- access.isGrantedRead(categ.id)
canWrite <- access.isGrantedWrite(categ.id, tryingToPostAsMod = true)
canModCateg <- access.isGrantedMod(categ.id)
replyBlocked <- ctx.me.soUse(access.isReplyBlockedOnUBlog(topic, canModCateg))
inOwnTeam <- ~(categ.team, ctx.me).mapN(env.team.api.isLeader(_, _))
form = ctx.me
@@ -57,7 +57,7 @@ final class ForumTopic(env: Env) extends LilaController(env) with ForumControlle
if canRead then
Ok.page(
views.forum.topic.show(categ, topic, posts, form, unsub, canModCateg, None, replyBlocked)
).map(_.withCanonical(routes.ForumTopic.show(categ.slug, topic.slug, page)))
).map(_.withCanonical(routes.ForumTopic.show(categ.id, topic.slug, page)))
else notFound
yield res
+1 -1
View File
@@ -68,7 +68,7 @@ final class Team(env: Env, apiC: => Api) extends LilaController(env):
members <- paginator.teamMembers(team.team, page)
log <- (asMod && isGrantedOpt(_.ManageTeam)).so(env.mod.logApi.teamLog(team.id))
hasChat = canHaveChat(info, asMod)
chat <- hasChat.soFu(env.chat.api.userChat.cached.findMine(ChatId(team.id)))
chat <- hasChat.soFu(env.chat.api.userChat.cached.findMine(team.id.into(ChatId)))
_ <- env.user.lightUserApi.preloadMany:
info.publicLeaders.map(_.user) ::: info.userIds
version <- hasChat.soFu(env.team.version(team.id))
+1 -1
View File
@@ -60,7 +60,7 @@ final class Ublog(env: Env) extends LilaController(env):
NotForKids:
import lila.forum.ForumCateg.ublogId
val topicSlug = s"ublog-${id}"
val redirect = Redirect(routes.ForumTopic.show(ublogId.value, topicSlug))
val redirect = Redirect(routes.ForumTopic.show(ublogId, topicSlug))
env.forum.topicRepo.existsByTree(ublogId, topicSlug).flatMap {
if _ then redirect
else
-6
View File
@@ -1,8 +1,6 @@
package router
import lila.app.*
import lila.appeal.Appeal
import lila.challenge.Challenge
import lila.puzzle.PuzzleTheme
import lila.report.Report
import lila.core.socket.Sri
@@ -11,11 +9,7 @@ import lila.core.id.*
// These are only meant for the play router,
// so that controllers can take richer types than routes allow
given Conversion[String, lila.study.Order] = lila.study.Order(_)
given Conversion[String, TeamId] = TeamId(_)
given Conversion[String, RelayRoundId] = RelayRoundId(_)
given Conversion[String, ForumCategId] = ForumCategId(_)
given Conversion[String, ForumTopicId] = ForumTopicId(_)
given Conversion[String, ForumPostId] = ForumPostId(_)
given Conversion[String, lila.cms.CmsPage.Id] = lila.cms.CmsPage.Id(_)
given Conversion[String, lila.cms.CmsPage.Key] = lila.cms.CmsPage.Key(_)
given Conversion[String, Sri] = Sri(_)
+1 -1
View File
@@ -21,7 +21,7 @@ object inquiry:
case "relay" => routes.RelayRound.show("-", "-", id).url
case "tournament" => routes.Tournament.show(TourId(id)).url
case "swiss" => routes.Swiss.show(SwissId(id)).url
case "forum" => routes.ForumPost.redirect(id).url
case "forum" => routes.ForumPost.redirect(ForumCategId(id)).url
case _ => s"/$tpe/$id"
a(href := path)(path).some -> text
case text => None -> text
+24 -24
View File
@@ -371,7 +371,7 @@ GET /tournament controllers.Tournament.home
GET /tournament/featured controllers.Tournament.featured
GET /tournament/new controllers.Tournament.form
POST /tournament/new controllers.Tournament.webCreate
GET /tournament/team-battle/new/:teamId controllers.Tournament.teamBattleForm(teamId)
GET /tournament/team-battle/new/:teamId controllers.Tournament.teamBattleForm(teamId: TeamId)
GET /tournament/team-battle/edit/:id controllers.Tournament.teamBattleEdit(id: TourId)
POST /tournament/team-battle/edit/:id controllers.Tournament.teamBattleUpdate(id: TourId)
GET /tournament/calendar controllers.Tournament.calendar
@@ -383,7 +383,7 @@ GET /tournament/$id<\w{8}>/page-of/:user controllers.Tournament.pageOf(id:
POST /tournament/$id<\w{8}>/join controllers.Tournament.join(id: TourId)
POST /tournament/$id<\w{8}>/withdraw controllers.Tournament.pause(id: TourId)
GET /tournament/$id<\w{8}>/player/:user controllers.Tournament.player(id: TourId, user: UserStr)
GET /tournament/$id<\w{8}>/team/:team controllers.Tournament.teamInfo(id: TourId, team)
GET /tournament/$id<\w{8}>/team/:team controllers.Tournament.teamInfo(id: TourId, team: TeamId)
POST /tournament/$id<\w{8}>/terminate controllers.Tournament.terminate(id: TourId)
GET /tournament/$id<\w{8}>/edit controllers.Tournament.edit(id: TourId)
POST /tournament/$id<\w{8}>/edit controllers.Tournament.update(id: TourId)
@@ -404,8 +404,8 @@ POST /tournament/manager controllers.TournamentCrud.create
# Swiss
GET /swiss controllers.Swiss.home
GET /swiss/new/:teamId controllers.Swiss.form(teamId)
POST /swiss/new/:teamId controllers.Swiss.create(teamId)
GET /swiss/new/:teamId controllers.Swiss.form(teamId: TeamId)
POST /swiss/new/:teamId controllers.Swiss.create(teamId: TeamId)
GET /swiss/$id<\w{8}> controllers.Swiss.show(id: SwissId)
GET /swiss/$id<\w{8}>/round/:round controllers.Swiss.round(id: SwissId, round: Int)
GET /swiss/$id<\w{8}>.trf controllers.Swiss.exportTrf(id: SwissId)
@@ -439,13 +439,13 @@ GET /$lang<\w\w\w?>/simul controllers.Simul.homeLang(lang)
GET /api/team/all controllers.TeamApi.all(page: Int ?= 1)
GET /api/team/search controllers.TeamApi.search(text ?= "", page: Int ?= 1)
GET /api/team/of/:username controllers.TeamApi.teamsOf(username: UserStr)
GET /api/team/:id controllers.TeamApi.show(id)
GET /api/team/:id/users controllers.TeamApi.users(id)
GET /api/team/:id/arena controllers.Tournament.byTeam(id)
GET /api/team/:id/swiss controllers.Swiss.byTeam(id)
GET /api/team/:id/requests controllers.TeamApi.requests(id)
POST /api/team/:id/request/:userId/:decision controllers.TeamApi.requestProcess(id, userId: UserStr, decision)
POST /api/team/:id/kick/:user controllers.TeamApi.kickUser(id, user: UserStr)
GET /api/team/:id controllers.TeamApi.show(id: TeamId)
GET /api/team/:id/users controllers.TeamApi.users(id: TeamId)
GET /api/team/:id/arena controllers.Tournament.byTeam(id: TeamId)
GET /api/team/:id/swiss controllers.Swiss.byTeam(id: TeamId)
GET /api/team/:id/requests controllers.TeamApi.requests(id: TeamId)
POST /api/team/:id/request/:userId/:decision controllers.TeamApi.requestProcess(id: TeamId, userId: UserStr, decision)
POST /api/team/:id/kick/:user controllers.TeamApi.kickUser(id: TeamId, user: UserStr)
# Analyse
POST /$gameId<\w{8}>/request-analysis controllers.Analyse.requestAnalysis(gameId: GameId)
@@ -593,18 +593,18 @@ GET /kaladin controllers.Irwin.kaladin
# Forum
GET /forum controllers.ForumCateg.index
GET /forum/search controllers.ForumPost.search(text ?= "", page: Int ?= 1)
GET /forum/:slug controllers.ForumCateg.show(slug, page: Int ?= 1)
GET /forum/:categSlug/form controllers.ForumTopic.form(categSlug)
POST /forum/:categSlug/new controllers.ForumTopic.create(categSlug)
GET /forum/participants/:topicId controllers.ForumTopic.participants(topicId)
GET /forum/:categSlug/:slug controllers.ForumTopic.show(categSlug, slug, page: Int ?= 1)
POST /forum/:categSlug/:slug/close controllers.ForumTopic.close(categSlug, slug)
POST /forum/:categSlug/:slug/sticky controllers.ForumTopic.sticky(categSlug, slug)
POST /forum/:categSlug/:slug/new controllers.ForumPost.create(categSlug, slug, page: Int ?= 1)
POST /forum/delete/:id controllers.ForumPost.delete(id)
POST /forum/:categSlug/react/:id/:reaction/:v controllers.ForumPost.react(categSlug, id, reaction, v: Boolean)
POST /forum/post/:id controllers.ForumPost.edit(id)
GET /forum/redirect/post/:id controllers.ForumPost.redirect(id)
GET /forum/:categId controllers.ForumCateg.show(categId: ForumCategId, page: Int ?= 1)
GET /forum/:categId/form controllers.ForumTopic.form(categId: ForumCategId)
POST /forum/:categId/new controllers.ForumTopic.create(categId: ForumCategId)
GET /forum/participants/:topicId controllers.ForumTopic.participants(topicId: ForumTopicId)
GET /forum/:categId/:slug controllers.ForumTopic.show(categId: ForumCategId, slug, page: Int ?= 1)
POST /forum/:categId/:slug/close controllers.ForumTopic.close(categId: ForumCategId, slug)
POST /forum/:categId/:slug/sticky controllers.ForumTopic.sticky(categId: ForumCategId, slug)
POST /forum/:categId/:slug/new controllers.ForumPost.create(categId: ForumCategId, slug, page: Int ?= 1)
POST /forum/delete/:id controllers.ForumPost.delete(id: ForumPostId)
POST /forum/:categId/react/:id/:reaction/:v controllers.ForumPost.react(categId: ForumCategId, id: ForumPostId, reaction, v: Boolean)
POST /forum/post/:id controllers.ForumPost.edit(id: ForumPostId)
GET /forum/redirect/post/:id controllers.ForumPost.redirect(id: ForumPostId)
POST /diagnostic controllers.ForumTopic.diagnostic
POST /diagnostic/clear/:slug controllers.ForumTopic.clearDiagnostic(slug)
@@ -677,7 +677,7 @@ POST /api/tournament/$id<\w{8}>/join controllers.Tournament.apiJoin(id: T
POST /api/tournament/$id<\w{8}>/withdraw controllers.Tournament.apiWithdraw(id: TourId)
POST /api/tournament/$id<\w{8}>/terminate controllers.Tournament.apiTerminate(id: TourId)
POST /api/tournament/team-battle/:id controllers.Tournament.apiTeamBattleUpdate(id: TourId)
POST /api/swiss/new/:teamId controllers.Swiss.apiCreate(teamId)
POST /api/swiss/new/:teamId controllers.Swiss.apiCreate(teamId: TeamId)
POST /api/swiss/$id<\w{8}>/edit controllers.Swiss.apiUpdate(id: SwissId)
POST /api/swiss/$id<\w{8}>/join controllers.Swiss.join(id: SwissId)
POST /api/swiss/$id<\w{8}>/withdraw controllers.Swiss.withdraw(id: SwissId)
+3 -3
View File
@@ -10,9 +10,9 @@ GET /team/autocomplete controllers.team.Team.autocomplete
GET /team/:id controllers.team.Team.show(id: TeamId, page: Int ?= 1, mod: Boolean ?= false)
POST /team/:id/join controllers.team.Team.join(id: TeamId)
POST /team/:id/quit controllers.team.Team.quit(id: TeamId)
GET /team/:id/request/new controllers.team.Team.requestForm(id: String)
POST /team/:id/request/new controllers.team.Team.requestCreate(id: String)
POST /team/:id/request/process controllers.team.Team.requestProcess(id: String)
GET /team/:id/request/new controllers.team.Team.requestForm(id: TeamId)
POST /team/:id/request/new controllers.team.Team.requestCreate(id: TeamId)
POST /team/-/request/process/:reqId controllers.team.Team.requestProcess(reqId)
GET /team/:id/declined-requests controllers.team.Team.declinedRequests(id: TeamId, page: Int ?=1)
GET /team/:id/edit controllers.team.Team.edit(id: TeamId)
POST /team/:id/edit controllers.team.Team.update(id: TeamId)
+1 -1
View File
@@ -446,7 +446,7 @@ object mon:
def post(verdict: String, isNew: Boolean, multi: Boolean) = counter("msg.post").withTags(
tags("verdict" -> verdict, "isNew" -> isNew, "multi" -> multi)
)
def teamBulk(teamId: String) = histogram("msg.bulk.team").withTag("id", teamId)
def teamBulk(teamId: TeamId) = histogram("msg.bulk.team").withTag("id", teamId.value)
def clasBulk(clasId: ClasId) = histogram("msg.bulk.clas").withTag("id", clasId.value)
object puzzle:
object selector:
-2
View File
@@ -46,8 +46,6 @@ case class ForumCateg(
lastPostIdTroll = lastPostIdTroll
)
def slug = id
object ForumCateg:
export lila.core.forum.ForumCateg.*
+3 -3
View File
@@ -108,7 +108,7 @@ final class ForumPostApi(
postRepo.coll.byId[ForumPost](postId)
def react(
categSlug: String,
categId: ForumCategId,
postId: ForumPostId,
reactionStr: String,
v: Boolean
@@ -117,7 +117,7 @@ final class ForumPostApi(
if v then lila.mon.forum.reaction(reaction.key).increment()
postRepo.coll
.findAndUpdateSimplified[ForumPost](
selector = $id(postId) ++ $doc("categId" -> categSlug, "userId".$ne(me.userId)),
selector = $id(postId) ++ $doc("categId" -> categId, "userId".$ne(me.userId)),
update =
if v then $addToSet(s"reactions.$reaction" -> me.userId)
else $pull(s"reactions.$reaction" -> me.userId),
@@ -126,7 +126,7 @@ final class ForumPostApi(
.andDo:
if me.marks.troll && reaction == ForumPost.Reaction.MinusOne && v then
scheduler.scheduleOnce(5 minutes):
react(categSlug, postId, reaction.key, false)
react(categId, postId, reaction.key, false)
}
def views(posts: List[ForumPost]): Fu[List[PostView]] =
+2 -2
View File
@@ -87,7 +87,7 @@ final private class ForumTopicApi(
)(using me: Me): Fu[ForumTopic] =
topicRepo.nextSlug(categ, data.name).zip(detectLanguage(data.post.text)).flatMap { (slug, lang) =>
val topic = ForumTopic.make(
categId = categ.slug,
categId = categ.id,
slug = slug,
name = noShouting(data.name),
userId = me,
@@ -137,7 +137,7 @@ final private class ForumTopicApi(
): Funit =
categRepo.byId(ForumCateg.ublogId).flatMapz { categ =>
val topic = ForumTopic.make(
categId = categ.slug,
categId = categ.id,
slug = slug,
name = name,
userId = authorId,
+1 -1
View File
@@ -64,5 +64,5 @@ final private class ForumTopicRepo(val coll: Coll, filter: Filter = Safe)(using
else fuccess(slug)
}
def byCategQuery(categ: ForumCateg) = $doc("categId" -> categ.slug) ++ trollFilter
def byCategQuery(categ: ForumCateg) = $doc("categId" -> categ.id) ++ trollFilter
def byCategNotStickyQuery(categ: ForumCateg) = byCategQuery(categ) ++ notStickyQuery
+1 -4
View File
@@ -5,16 +5,13 @@ case class CategView(
lastPost: Option[(ForumTopic, ForumPost, Int)],
forUser: Option[User]
):
export categ.{ id as slug, name, desc }
def nbTopics = categ.nbTopics(forUser)
def nbPosts = categ.nbPosts(forUser)
def lastPostId = categ.lastPostId(forUser)
def lastPostUserId = lastPost.map(_._2).flatMap(_.userId)
def slug = categ.slug
def name = categ.name
def desc = categ.desc
case class TopicView(
categ: ForumCateg,
topic: ForumTopic,
+5 -5
View File
@@ -42,7 +42,7 @@ final class CategUi(helpers: Helpers, bits: ForumBits):
val newTopicButton = canWrite.option(
a(
href := routes.ForumTopic.form(categ.slug),
href := routes.ForumTopic.form(categ.id),
cls := "button button-empty button-green text",
dataIcon := Icon.Pencil
):
@@ -52,13 +52,13 @@ final class CategUi(helpers: Helpers, bits: ForumBits):
def showTopic(sticky: Boolean)(topic: TopicView) =
tr(cls := List("sticky" -> sticky))(
td(cls := "subject")(
a(href := routes.ForumTopic.show(categ.slug, topic.slug))(topic.name)
a(href := routes.ForumTopic.show(categ.id, topic.slug))(topic.name)
),
td(cls := "right")(topic.nbReplies.localize),
td(
topic.lastPost.map: post =>
frag(
a(href := s"${routes.ForumTopic.show(categ.slug, topic.slug, topic.lastPage)}#${post.number}")(
a(href := s"${routes.ForumTopic.show(categ.id, topic.slug, topic.lastPage)}#${post.number}")(
momentFromNow(post.createdAt)
),
br,
@@ -73,7 +73,7 @@ final class CategUi(helpers: Helpers, bits: ForumBits):
.js(infiniteScrollEsmInit)
.graph(
title = s"Forum: ${categ.name}",
url = s"$netBaseUrl${routes.ForumCateg.show(categ.slug).url}",
url = s"$netBaseUrl${routes.ForumCateg.show(categ.id).url}",
description = categ.desc
):
main(cls := "forum forum-categ box")(
@@ -100,7 +100,7 @@ final class CategUi(helpers: Helpers, bits: ForumBits):
tbody(cls := "infinite-scroll")(
stickyPosts.map(showTopic(sticky = true)),
topics.currentPageResults.map(showTopic(sticky = false)),
pagerNextTable(topics, n => routes.ForumCateg.show(categ.slug, n).url)
pagerNextTable(topics, n => routes.ForumCateg.show(categ.id, n).url)
)
)
)
+12 -12
View File
@@ -23,7 +23,7 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
main(cls := "forum forum-topic topic-form page-small box box-pad")(
boxTop(
h1(
a(href := routes.ForumCateg.show(categ.slug), dataIcon := Icon.LessThan, cls := "text"),
a(href := routes.ForumCateg.show(categ.id), dataIcon := Icon.LessThan, cls := "text"),
categ.name
)
),
@@ -45,14 +45,14 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
trans.site.makeSureToRead:
strong(a(href := routes.Cms.lonePage("forum-etiquette"))(trans.site.theForumEtiquette()))
),
postForm(cls := "form3", action := routes.ForumTopic.create(categ.slug))(
postForm(cls := "form3", action := routes.ForumTopic.create(categ.id))(
form3.group(form("name"), trans.site.subject())(form3.input(_)(autofocus)),
form3.group(form("post")("text"), trans.site.message())(
form3.textarea(_, klass = "post-text-area")(rows := 10)
),
renderCaptcha(form("post"), captcha),
form3.actions(
a(href := routes.ForumCateg.show(categ.slug))(trans.site.cancel()),
a(href := routes.ForumCateg.show(categ.id))(trans.site.cancel()),
Granter
.opt(_.PublicMod)
.option(
@@ -82,11 +82,11 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
val backUrl =
if isDiagnostic && !canModCateg then routes.ForumCateg.index.url
else
topic.ublogId.fold(s"${routes.ForumCateg.show(categ.slug)}"): id =>
topic.ublogId.fold(s"${routes.ForumCateg.show(categ.id)}"): id =>
routes.Ublog.redirect(id).url
val teamOnly = categ.team.filterNot(isMyTeamSync)
val pager = paginationByQuery(routes.ForumTopic.show(categ.slug, topic.slug, 1), posts, showPost = true)
val pager = paginationByQuery(routes.ForumTopic.show(categ.id, topic.slug, 1), posts, showPost = true)
Page(s"${topic.name} • page ${posts.currentPage}/${posts.nbPages}${categ.name}")
.css("forum")
.csp(_.withInlineIconFont.withTwitter)
@@ -94,7 +94,7 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
.graph(
OpenGraph(
title = topic.name,
url = s"$netBaseUrl${routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage).url}",
url = s"$netBaseUrl${routes.ForumTopic.show(categ.id, topic.slug, posts.currentPage).url}",
description = shorten(posts.currentPageResults.headOption.so(_.post.text), 152)
)
):
@@ -114,7 +114,7 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
categ,
topic,
p,
s"${routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage)}#${p.post.number}",
s"${routes.ForumTopic.show(categ.id, topic.slug, posts.currentPage)}#${p.post.number}",
canReply = formWithCaptcha.isDefined,
canModCateg = canModCateg,
canReact = teamOnly.isEmpty
@@ -149,14 +149,14 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
trans.site.unsubscribe()
),
(canModCateg || (topic.isUblog && ctx.me.exists(topic.isAuthor))).option(
postForm(action := routes.ForumTopic.close(categ.slug, topic.slug))(
postForm(action := routes.ForumTopic.close(categ.id, topic.slug))(
button(cls := "button button-empty button-red")(
if topic.closed then "Reopen" else "Close"
)
)
),
canModCateg.option(
postForm(action := routes.ForumTopic.sticky(categ.slug, topic.slug))(
postForm(action := routes.ForumTopic.sticky(categ.id, topic.slug))(
button(cls := "button button-empty button-brag")(
if topic.isSticky then "Unsticky" else "Sticky"
)
@@ -168,7 +168,7 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
formWithCaptcha.map: (form, captcha) =>
postForm(
cls := "form3 reply",
action := s"${routes.ForumPost.create(categ.slug, topic.slug, posts.currentPage)}#reply",
action := s"${routes.ForumPost.create(categ.id, topic.slug, posts.currentPage)}#reply",
novalidate
)(
form3.group(
@@ -187,7 +187,7 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
),
renderCaptcha(form, captcha),
form3.actions(
a(href := routes.ForumCateg.show(categ.slug))(trans.site.cancel()),
a(href := routes.ForumCateg.show(categ.id))(trans.site.cancel()),
(Granter.opt(_.PublicMod) || Granter.opt(_.SeeReport)).option(
form3.submit(
frag(s"Reply as a mod ${(!Granter.opt(_.PublicMod)).so("(anonymously)")}"),
@@ -215,7 +215,7 @@ final class TopicUi(helpers: Helpers, bits: ForumBits, postUi: PostUi)(
p("Describe your issue above the report. Unsolicited diagnostics will be ignored."),
p("Only you and the Lichess moderators can see this forum.")
),
postForm(cls := "form3", action := routes.ForumTopic.create(categ.slug))(
postForm(cls := "form3", action := routes.ForumTopic.create(categ.id))(
form3.group(form("post")("text"), trans.site.message())(
form3.textarea(_, klass = "post-text-area")(rows := 10, autofocus := "")(
"\n\n\n" +
+2 -2
View File
@@ -129,14 +129,14 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi, pres
details = s"$categ/$topic id: $postId ${text.take(400)}".some
)
def deleteTeam(id: String, explain: String)(using MyId) = add:
def deleteTeam(id: TeamId, explain: String)(using MyId) = add:
Modlog(
none,
Modlog.deleteTeam,
details = s"$id: ${explain.take(200)}".some
).indexAs("team")
def toggleTeam(id: String, closing: Boolean, explain: String)(using MyId) = add:
def toggleTeam(id: TeamId, closing: Boolean, explain: String)(using MyId) = add:
Modlog(
none,
if closing then Modlog.disableTeam else Modlog.enableTeam,
+2 -1
View File
@@ -3,6 +3,7 @@ package lila.msg
import lila.core.LightUser
import lila.core.config.BaseUrl
import lila.core.team.LightTeam
import lila.core.id.ForumCategId
object MsgPreset:
@@ -29,7 +30,7 @@ Thank you for your understanding."""
def byModerator = compose("A moderator")
def byTeamLeader(teamSlug: String) = compose(s"A team leader of https://lichess.org/forum/$teamSlug")
def byTeamLeader(forumId: ForumCategId) = compose(s"A team leader of https://lichess.org/forum/$forumId")
def byBlogAuthor(user: UserName) = compose(by = s"The community blog author $user")
+2 -1
View File
@@ -2,6 +2,7 @@ package lila.ui
import lila.ui.ScalatagsTemplate.{ *, given }
import lila.core.team.LightTeam
import lila.core.id.ForumCategId
trait TeamHelper:
self: AssetHelper =>
@@ -30,4 +31,4 @@ trait TeamHelper:
def teamFlair(flair: Flair): Tag =
img(cls := "uflair", src := flairSrc(flair))
def teamForumUrl(id: TeamId) = routes.ForumCateg.show("team-" + id)
def teamForumUrl(id: TeamId) = routes.ForumCateg.show(ForumCategId("team-" + id))
@@ -57,13 +57,9 @@ object LilaRouter:
object conversions:
given reportIdConv: Conversion[ReportId, String] = _.value
given Conversion[lila.core.i18n.Language, String] = _.value
given Conversion[TeamId, String] = _.value
given Conversion[RelayRoundId, String] = _.value
given Conversion[chess.opening.OpeningKey, String] = _.value
given Conversion[chess.format.Uci, String] = _.uci
given postIdConv: Conversion[ForumPostId, String] = _.value
given Conversion[ForumCategId, String] = _.value
given Conversion[ForumTopicId, String] = _.value
given relayTourIdConv: Conversion[RelayTourId, String] = _.value
given Conversion[chess.FideId, Int] = _.value
given challengeIdConv: Conversion[ChallengeId, String] = _.value
+2 -1
View File
@@ -3,6 +3,7 @@ package ui
import lila.ui.*
import ScalatagsTemplate.{ *, given }
import lila.core.id.ForumCategId
final class SitePages(helpers: Helpers):
import helpers.{ *, given }
@@ -275,7 +276,7 @@ final class SitePages(helpers: Helpers):
// Contact email, because Slack requires a support channel without
// mandatory registration.
"Give us feedback or ask questions ",
a(href := routes.ForumCateg.show("lichess-feedback"))(
a(href := routes.ForumCateg.show(ForumCategId("lichess-feedback")))(
"in the forum"
),
". The source code is available at ",
+2 -1
View File
@@ -6,6 +6,7 @@ import scala.util.chaining.*
import lila.ui.*
import ScalatagsTemplate.{ *, given }
import lila.core.i18n.{ Translate, I18nKey as trans }
import lila.core.id.ForumCategId
object contact:
@@ -36,7 +37,7 @@ object contact:
frag(
ul(
li(
a(href := routes.ForumCateg.show("lichess-feedback"))(reportBugInForum())
a(href := routes.ForumCateg.show(ForumCategId("lichess-feedback")))(reportBugInForum())
),
li(
a(href := "https://github.com/lichess-org/lila/issues")(reportWebsiteIssue())