Skip to content

Commit

Permalink
Merge branch 'lichess-org:master' into patch-12
Browse files Browse the repository at this point in the history
  • Loading branch information
Carbrex authored Feb 14, 2024
2 parents b446cf6 + aea0cd7 commit 8dd3480
Show file tree
Hide file tree
Showing 223 changed files with 848 additions and 1,110 deletions.
1 change: 0 additions & 1 deletion COPYING.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ public/images/staunton/piece/Staunton | [Eden Murs](https://userstyles.org/style
Lichess as deployed on https://lichess.org/ also uses these external services:

- [Cloudflare](https://www.cloudflare.com/) to serve static assets, DNS lookups for email validation
- [prismic.io](https://prismic.io/) for help/documentation pages and the blog
- [twitch](https://www.twitch.tv/) for featured livestreams
- [YouTube](https://www.youtube.com) for featured livestreams and the [Video library](https://lichess.org/video)
- [stripe](https://stripe.com/) and [PayPal](https://www.paypal.com) for [Patron donations](https://lichess.org/patron)
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Lichess talks to [Stockfish](https://stockfishchess.org/) deployed in an [AI clu
It uses [MongoDB](https://www.mongodb.com) to store more than 4.7 billion games, which are indexed by [elasticsearch](https://github.com/elastic/elasticsearch).
HTTP requests and WebSocket connections can be proxied by [nginx](https://nginx.org).
The web client is written in [TypeScript](https://www.typescriptlang.org/) and [snabbdom](https://github.com/snabbdom/snabbdom), using [Sass](https://sass-lang.com/) to generate CSS.
The [blog](https://lichess.org/blog) uses a free open content plan from [prismic.io](https://prismic.io).
All rated games are published in a [free PGN database](https://database.lichess.org).
Browser testing done with [Browserstack](https://www.browserstack.com).
Proxy detection done with [IP2Proxy database](https://www.ip2location.com/database/ip2proxy).
Expand Down
4 changes: 2 additions & 2 deletions app/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class Env(
val puzzle: lila.puzzle.Env,
val coordinate: lila.coordinate.Env,
val tv: lila.tv.Env,
val blog: lila.blog.Env,
val feed: lila.feed.Env,
val history: lila.history.Env,
val video: lila.video.Env,
val playban: lila.playban.Env,
Expand Down Expand Up @@ -211,7 +211,7 @@ final class EnvBoot(
lazy val puzzle: lila.puzzle.Env = wire[lila.puzzle.Env]
lazy val coordinate: lila.coordinate.Env = wire[lila.coordinate.Env]
lazy val tv: lila.tv.Env = wire[lila.tv.Env]
lazy val blog: lila.blog.Env = wire[lila.blog.Env]
lazy val feed: lila.feed.Env = wire[lila.feed.Env]
lazy val history: lila.history.Env = wire[lila.history.Env]
lazy val video: lila.video.Env = wire[lila.video.Env]
lazy val playban: lila.playban.Env = wire[lila.playban.Env]
Expand Down
2 changes: 1 addition & 1 deletion app/LilaComponents.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ final class LilaComponents(
lazy val api: Api = wire[Api]
lazy val appealC: appeal.Appeal = wire[appeal.Appeal]
lazy val auth: Auth = wire[Auth]
lazy val dailyFeed: DailyFeed = wire[DailyFeed]
lazy val feed: Feed = wire[Feed]
lazy val playApi: PlayApi = wire[PlayApi]
lazy val challenge: Challenge = wire[Challenge]
lazy val coach: Coach = wire[Coach]
Expand Down
63 changes: 0 additions & 63 deletions app/controllers/DailyFeed.scala

This file was deleted.

61 changes: 61 additions & 0 deletions app/controllers/Feed.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package controllers

import play.api.mvc.*
import views.*
import java.time.LocalDate

import lila.app.{ given, * }
import lila.common.config.Max
import lila.feed.Feed.Update

final class Feed(env: Env) extends LilaController(env):

def api = env.feed.api

def index(page: Int) = Open: ctx ?=>
Reasonable(page):
for
updates <- env.feed.paginator.recent(isGrantedOpt(_.Feed), page)
renderedPage <- renderPage(html.feed.index(updates))
yield Ok(renderedPage)

def createForm = Secure(_.Feed) { _ ?=> _ ?=>
Ok.pageAsync(html.feed.create(api.form(none)))
}

def create = SecureBody(_.Feed) { _ ?=> _ ?=>
api
.form(none)
.bindFromRequest()
.fold(
err => BadRequest.pageAsync(html.feed.create(err)),
data =>
val up = data toUpdate none
api.set(up) inject Redirect(routes.Feed.edit(up.id)).flashSuccess
)
}

def edit(id: String) = Secure(_.Feed) { _ ?=> _ ?=>
Found(api.get(id)): up =>
Ok.pageAsync(html.feed.edit(api.form(up.some), up))
}

def update(id: String) = SecureBody(_.Feed) { _ ?=> _ ?=>
Found(api.get(id)): from =>
api
.form(from.some)
.bindFromRequest()
.fold(
err => BadRequest.pageAsync(html.feed.edit(err, from)),
data => api.set(data toUpdate from.id.some) inject Redirect(routes.Feed.edit(from.id)).flashSuccess
)
}

def delete(id: String) = Secure(_.Feed) { _ ?=> _ ?=>
Found(api.get(id)): up =>
api.delete(up.id) inject Redirect(routes.Feed.index(1)).flashSuccess
}

def atom = Anon:
api.recentPublished map: ups =>
Ok(html.feed.atom(ups)) as XML
9 changes: 6 additions & 3 deletions app/controllers/Team.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class Team(env: Env, apiC: => Api) extends LilaController(env):

def show(id: TeamId, page: Int, mod: Boolean) = Open:
Reasonable(page):
Found(api team id) { renderTeam(_, page, mod && isGrantedOpt(_.ManageTeam)) }
Found(api team id) { renderTeam(_, page, mod && canEnterModView) }

def members(id: TeamId, page: Int) = Open:
Reasonable(page, config.Max(50)):
Expand Down Expand Up @@ -61,7 +61,7 @@ final class Team(env: Env, apiC: => Api) extends LilaController(env):
team <- api.withLeaders(team)
info <- env.teamInfo(team, ctx.me, withForum = canHaveForum(team.team, asMod))
members <- paginator.teamMembers(team.team, page)
log <- asMod.so(env.mod.logApi.teamLog(team.id))
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))
_ <- env.user.lightUserApi.preloadMany:
Expand All @@ -70,14 +70,17 @@ final class Team(env: Env, apiC: => Api) extends LilaController(env):
page <- renderPage(html.team.show(team, members, info, chat, version, asMod, log))
yield Ok(page).withCanonical(routes.Team.show(team.id))

private def canEnterModView(using Context) =
isGrantedOpt(_.Shusher) || isGrantedOpt(_.ManageTeam)

private def canHaveChat(info: lila.app.mashup.TeamInfo, requestModView: Boolean)(using
ctx: Context
): Boolean =
import info.*
team.enabled && !team.isChatFor(_.NONE) && ctx.kid.no && HTTPRequest.isHuman(ctx.req) && {
(team.isChatFor(_.LEADERS) && info.ledByMe) ||
(team.isChatFor(_.MEMBERS) && info.mine) ||
(isGrantedOpt(_.Shusher) && requestModView)
(canEnterModView && requestModView)
}

private def canHaveForum(team: TeamModel, asMod: Boolean)(member: Option[TeamMember])(using
Expand Down
15 changes: 5 additions & 10 deletions app/controllers/User.scala
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,10 @@ final class User(
relateds <-
ops
.zip(followables)
.map { case ((u, nb), followable) =>
relationApi.fetchRelation(user.id, u.id) map {
.traverse { case ((u, nb), followable) =>
relationApi.fetchRelation(user.id, u.id) map:
lila.relation.Related(u, nb.some, followable, _)
}
}
.parallel
page <- renderPage(html.relation.bits.opponents(user, relateds))
yield Ok(page)
}
Expand All @@ -524,9 +522,8 @@ final class User(
Found(env.perfStat.api.data(username, perfKey)): data =>
negotiate(
Ok.pageAsync:
env.history.ratingChartApi(data.user.user) map {
env.history.ratingChartApi(data.user.user) map:
html.user.perfStat(data, _)
}
,
JsonOk:
getBool("graph")
Expand Down Expand Up @@ -597,8 +594,6 @@ final class User(
}

def tryRedirect(username: UserStr)(using Context): Fu[Option[Result]] =
env.user.repo byId username map {
_.filter(_.enabled.yes || isGrantedOpt(_.SeeReport)) map { user =>
env.user.repo byId username map:
_.filter(_.enabled.yes || isGrantedOpt(_.SeeReport)) map: user =>
Redirect(routes.User.show(user.username))
}
}
4 changes: 2 additions & 2 deletions app/mashup/Preload.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class Preload(
lightUserApi: LightUserApi,
roundProxy: lila.round.GameProxyRepo,
simulIsFeaturable: SimulIsFeaturable,
getLastUpdates: lila.blog.DailyFeed.GetLastUpdates,
getLastUpdates: lila.feed.Feed.GetLastUpdates,
lastPostsCache: AsyncLoadingCache[Unit, List[UblogPost.PreviewPost]],
msgApi: lila.msg.MsgApi,
relayListing: lila.relay.RelayListing,
Expand Down Expand Up @@ -148,7 +148,7 @@ object Preload:
currentGame: Option[Preload.CurrentGame],
isFeaturable: Simul => Boolean,
blindGames: List[Pov],
lastUpdates: List[lila.blog.DailyFeed.Update],
lastUpdates: List[lila.feed.Feed.Update],
ublogPosts: List[UblogPost.PreviewPost],
me: Option[User.WithPerfs],
hasUnreadLichessMessage: Boolean
Expand Down
2 changes: 1 addition & 1 deletion app/templating/FormHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,6 @@ trait FormHelper:

object file:
def image(name: String): Frag =
st.input(tpe := "file", st.name := name, accept := "image/png, image/jpeg")
st.input(tpe := "file", st.name := name, accept := "image/png, image/jpeg, image/webp")
def pgn(name: String): Frag = st.input(tpe := "file", st.name := name, accept := ".pgn")
def selectImage = button(cls := "button select-image")("select image")
2 changes: 1 addition & 1 deletion app/views/base/layout.scala
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ object layout:
private def spaceless(html: String) = raw(spaceRegex.replaceAllIn(html.replace("\\n", ""), ""))

private val dailyNewsAtom = link(
href := routes.DailyFeed.atom,
href := routes.Feed.atom,
st.title := "Lichess Updates Feed",
tpe := "application/atom+xml",
rel := "alternate"
Expand Down
2 changes: 1 addition & 1 deletion app/views/cms.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ object cms:
rawHtml(page.html)
)

def editButton(p: CmsPage.Render)(using Context) =
private def editButton(p: CmsPage.Render)(using Context) =
isGranted(_.Pages) option a(
href := routes.Cms.edit(p.id),
cls := "button button-empty text",
Expand Down
32 changes: 16 additions & 16 deletions app/views/dailyFeed.scala → app/views/feed.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import controllers.routes

import lila.app.templating.Environment.{ given, * }
import lila.app.ui.ScalatagsTemplate.{ *, given }
import lila.blog.DailyFeed.Update
import lila.feed.Feed.Update
import play.api.data.Form
import play.api.i18n.Lang
import lila.common.paginator.Paginator

object dailyFeed:
object feed:

private def layout(title: String, edit: Boolean = false)(using PageContext) =
views.html.site.page.layout(
Expand All @@ -25,16 +25,16 @@ object dailyFeed:
boxTop(
h1("Lichess updates"),
div(cls := "box__top__actions")(
isGranted(_.DailyFeed) option a(
href := routes.DailyFeed.createForm,
isGranted(_.Feed) option a(
href := routes.Feed.createForm,
cls := "button button-green",
dataIcon := licon.PlusButton
),
views.html.site.bits.atomLink(routes.DailyFeed.atom)
views.html.site.bits.atomLink(routes.Feed.atom)
)
),
standardFlash,
updates(ups, editor = isGranted(_.DailyFeed))
updates(ups, editor = isGranted(_.Feed))
)

def updates(ups: Paginator[Update], editor: Boolean)(using Context) =
Expand All @@ -49,7 +49,7 @@ object dailyFeed:
h2(a(href := s"#${update.id}")(absClientInstant(update.at))),
editor option frag(
a(
href := routes.DailyFeed.edit(update.id),
href := routes.Feed.edit(update.id),
cls := "button button-green button-empty button-thin text",
dataIcon := licon.Pencil
),
Expand All @@ -60,7 +60,7 @@ object dailyFeed:
div(cls := "daily-feed__update__markup")(rawHtml(update.rendered))
)
),
pagerNext(ups, np => routes.DailyFeed.index(np).url)
pagerNext(ups, np => routes.Feed.index(np).url)
)

val lobbyUpdates = renderCache[List[Update]](1 minute): ups =>
Expand Down Expand Up @@ -88,12 +88,12 @@ object dailyFeed:
main(cls := "daily-feed page-small box box-pad")(
boxTop(
h1(
a(href := routes.DailyFeed.index(1))("Daily Feed"),
a(href := routes.Feed.index(1))("Daily Feed"),
"",
"New update!"
)
),
postForm(cls := "content_box_content form3", action := routes.DailyFeed.create):
postForm(cls := "content_box_content form3", action := routes.Feed.create):
inForm(form)
)

Expand All @@ -103,16 +103,16 @@ object dailyFeed:
div(cls := "box box-pad")(
boxTop(
h1(
a(href := routes.DailyFeed.index(1))("Lichess update"),
a(href := routes.Feed.index(1))("Lichess update"),
"",
semanticDate(update.at)
)
),
standardFlash,
postForm(cls := "content_box_content form3", action := routes.DailyFeed.update(update.id)):
postForm(cls := "content_box_content form3", action := routes.Feed.update(update.id)):
inForm(form)
,
postForm(action := routes.DailyFeed.delete(update.id))(cls := "daily-feed__delete"):
postForm(action := routes.Feed.delete(update.id))(cls := "daily-feed__delete"):
submitButton(cls := "button button-red button-empty confirm")("Delete")
)
)
Expand Down Expand Up @@ -152,8 +152,8 @@ object dailyFeed:
import views.html.base.atom.{ atomDate, category }
views.html.base.atom(
elems = ups,
htmlCall = routes.DailyFeed.index(1),
atomCall = routes.DailyFeed.atom,
htmlCall = routes.Feed.index(1),
atomCall = routes.Feed.atom,
title = "Lichess updates feed",
updated = ups.headOption.map(_.at)
): up =>
Expand All @@ -163,7 +163,7 @@ object dailyFeed:
link(
rel := "alternate",
tpe := "text/html",
href := s"$netBaseUrl${routes.DailyFeed.index(1)}#${up.id}"
href := s"$netBaseUrl${routes.Feed.index(1)}#${up.id}"
),
tag("title")(up.title),
tag("content")(tpe := "html")(convertToAbsoluteHrefs(up.rendered))
Expand Down
Loading

0 comments on commit 8dd3480

Please sign in to comment.