add swiss tournament result to user activity feed - closes #7708
parent
9ea1775ddc
commit
dc7c49f7b4
|
@ -8,6 +8,7 @@ import lila.api.Context
|
||||||
import lila.app.templating.Environment._
|
import lila.app.templating.Environment._
|
||||||
import lila.app.ui.ScalatagsTemplate._
|
import lila.app.ui.ScalatagsTemplate._
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
|
import lila.swiss.Swiss
|
||||||
|
|
||||||
object activity {
|
object activity {
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ object activity {
|
||||||
a.simuls map renderSimuls(u),
|
a.simuls map renderSimuls(u),
|
||||||
a.studies map renderStudies,
|
a.studies map renderStudies,
|
||||||
a.tours map renderTours,
|
a.tours map renderTours,
|
||||||
|
a.swisses map renderSwisses,
|
||||||
a.teams map renderTeams,
|
a.teams map renderTeams,
|
||||||
a.stream option renderStream(u),
|
a.stream option renderStream(u),
|
||||||
a.signup option renderSignup
|
a.signup option renderSignup
|
||||||
|
@ -245,7 +247,6 @@ object activity {
|
||||||
trans.activity.competedInNbTournaments.pluralSame(tours.nb),
|
trans.activity.competedInNbTournaments.pluralSame(tours.nb),
|
||||||
subTag(
|
subTag(
|
||||||
tours.best.map { t =>
|
tours.best.map { t =>
|
||||||
val link = a(href := routes.Tournament.show(t.tourId))(tournamentIdToName(t.tourId))
|
|
||||||
div(
|
div(
|
||||||
cls := List(
|
cls := List(
|
||||||
"is-gold" -> (t.rank == 1),
|
"is-gold" -> (t.rank == 1),
|
||||||
|
@ -258,7 +259,32 @@ object activity {
|
||||||
strong(t.rank),
|
strong(t.rank),
|
||||||
t.rankRatio.percent,
|
t.rankRatio.percent,
|
||||||
t.nbGames,
|
t.nbGames,
|
||||||
link
|
a(href := routes.Tournament.show(t.tourId))(tournamentIdToName(t.tourId))
|
||||||
|
),
|
||||||
|
br
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private def renderSwisses(swisses: List[(Swiss.IdName, Int)])(implicit ctx: Context) =
|
||||||
|
entryTag(
|
||||||
|
iconTag("g"),
|
||||||
|
div(
|
||||||
|
trans.activity.competedInNbSwissTournaments.pluralSame(swisses.size),
|
||||||
|
subTag(
|
||||||
|
swisses.map { case (swiss, rank) =>
|
||||||
|
div(
|
||||||
|
cls := List(
|
||||||
|
"is-gold" -> (rank == 1),
|
||||||
|
"text" -> (rank <= 3)
|
||||||
|
),
|
||||||
|
dataIcon := (rank <= 3).option("g")
|
||||||
|
)(
|
||||||
|
trans.activity.rankedInSwissTournament(
|
||||||
|
strong(rank),
|
||||||
|
a(href := routes.Swiss.show(swiss.id.value))(swiss.name)
|
||||||
),
|
),
|
||||||
br
|
br
|
||||||
)
|
)
|
||||||
|
|
|
@ -215,7 +215,7 @@ lazy val pool = module("pool",
|
||||||
)
|
)
|
||||||
|
|
||||||
lazy val activity = module("activity",
|
lazy val activity = module("activity",
|
||||||
Seq(common, game, analyse, user, forum, study, pool, puzzle, tournament, practice, team),
|
Seq(common, game, analyse, user, forum, study, pool, puzzle, tournament, swiss, practice, team),
|
||||||
reactivemongo.bundle
|
reactivemongo.bundle
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.joda.time.Interval
|
||||||
|
|
||||||
import lila.common.Day
|
import lila.common.Day
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
|
import lila.swiss.Swiss
|
||||||
|
|
||||||
case class Activity(
|
case class Activity(
|
||||||
id: Activity.Id,
|
id: Activity.Id,
|
||||||
|
@ -20,6 +21,7 @@ case class Activity(
|
||||||
follows: Option[Follows] = None,
|
follows: Option[Follows] = None,
|
||||||
studies: Option[Studies] = None,
|
studies: Option[Studies] = None,
|
||||||
teams: Option[Teams] = None,
|
teams: Option[Teams] = None,
|
||||||
|
swisses: Option[Swisses] = None,
|
||||||
stream: Boolean = false
|
stream: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -40,7 +42,8 @@ case class Activity(
|
||||||
patron,
|
patron,
|
||||||
follows,
|
follows,
|
||||||
studies,
|
studies,
|
||||||
teams
|
teams,
|
||||||
|
swisses
|
||||||
)
|
)
|
||||||
.forall(_.isEmpty)
|
.forall(_.isEmpty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ final class ActivityReadApi(
|
||||||
postApi: lila.forum.PostApi,
|
postApi: lila.forum.PostApi,
|
||||||
simulApi: lila.simul.SimulApi,
|
simulApi: lila.simul.SimulApi,
|
||||||
studyApi: lila.study.StudyApi,
|
studyApi: lila.study.StudyApi,
|
||||||
tourLeaderApi: lila.tournament.LeaderboardApi
|
tourLeaderApi: lila.tournament.LeaderboardApi,
|
||||||
|
swissApi: lila.swiss.SwissApi
|
||||||
)(implicit ec: scala.concurrent.ExecutionContext) {
|
)(implicit ec: scala.concurrent.ExecutionContext) {
|
||||||
|
|
||||||
import BSONHandlers._
|
import BSONHandlers._
|
||||||
|
@ -83,13 +84,13 @@ final class ActivityReadApi(
|
||||||
.?? { simuls =>
|
.?? { simuls =>
|
||||||
simulApi byIds simuls.value.map(_.value) dmap some
|
simulApi byIds simuls.value.map(_.value) dmap some
|
||||||
}
|
}
|
||||||
.map(_ filter (_.nonEmpty))
|
.dmap(_.filter(_.nonEmpty))
|
||||||
studies <-
|
studies <-
|
||||||
a.studies
|
a.studies
|
||||||
.?? { studies =>
|
.?? { studies =>
|
||||||
studyApi publicIdNames studies.value dmap some
|
studyApi publicIdNames studies.value dmap some
|
||||||
}
|
}
|
||||||
.map(_ filter (_.nonEmpty))
|
.dmap(_.filter(_.nonEmpty))
|
||||||
tours <- a.games.exists(_.hasNonCorres) ?? {
|
tours <- a.games.exists(_.hasNonCorres) ?? {
|
||||||
val dateRange = a.date -> a.date.plusDays(1)
|
val dateRange = a.date -> a.date.plusDays(1)
|
||||||
tourLeaderApi
|
tourLeaderApi
|
||||||
|
@ -106,6 +107,21 @@ final class ActivityReadApi(
|
||||||
}
|
}
|
||||||
.mon(_.user segment "activity.tours")
|
.mon(_.user segment "activity.tours")
|
||||||
}
|
}
|
||||||
|
swisses <-
|
||||||
|
a.swisses
|
||||||
|
.?? { swisses =>
|
||||||
|
swissApi
|
||||||
|
.idNames(swisses.value.map(_.id))
|
||||||
|
.map {
|
||||||
|
_.flatMap { idName =>
|
||||||
|
swisses.value.find(_.id == idName.id) map { s =>
|
||||||
|
(idName, s.rank)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dmap(_.some.filter(_.nonEmpty))
|
||||||
|
}
|
||||||
|
|
||||||
} yield ActivityView(
|
} yield ActivityView(
|
||||||
interval = a.interval,
|
interval = a.interval,
|
||||||
games = a.games,
|
games = a.games,
|
||||||
|
@ -121,6 +137,7 @@ final class ActivityReadApi(
|
||||||
studies = studies,
|
studies = studies,
|
||||||
teams = a.teams,
|
teams = a.teams,
|
||||||
tours = tours,
|
tours = tours,
|
||||||
|
swisses = swisses,
|
||||||
stream = a.stream
|
stream = a.stream
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import lila.tournament.LeaderboardApi.{ Entry => TourEntry }
|
||||||
|
|
||||||
import activities._
|
import activities._
|
||||||
import model._
|
import model._
|
||||||
|
import lila.swiss.Swiss
|
||||||
|
|
||||||
case class ActivityView(
|
case class ActivityView(
|
||||||
interval: Interval,
|
interval: Interval,
|
||||||
|
@ -26,6 +27,7 @@ case class ActivityView(
|
||||||
studies: Option[List[Study.IdName]] = None,
|
studies: Option[List[Study.IdName]] = None,
|
||||||
teams: Option[Teams] = None,
|
teams: Option[Teams] = None,
|
||||||
tours: Option[ActivityView.Tours] = None,
|
tours: Option[ActivityView.Tours] = None,
|
||||||
|
swisses: Option[List[(Swiss.IdName, Int)]] = None,
|
||||||
stream: Boolean = false,
|
stream: Boolean = false,
|
||||||
signup: Boolean = false
|
signup: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
|
@ -150,6 +150,11 @@ final class ActivityWriteApi(
|
||||||
def streamStart(userId: User.ID) =
|
def streamStart(userId: User.ID) =
|
||||||
update(userId) { _.copy(stream = true).some }
|
update(userId) { _.copy(stream = true).some }
|
||||||
|
|
||||||
|
def swiss(id: lila.swiss.Swiss.Id, ranking: lila.swiss.Ranking) =
|
||||||
|
ranking.map { case (userId, rank) =>
|
||||||
|
update(userId) { a => a.copy(swisses = Some(~a.swisses + SwissRank(id, rank))).some }
|
||||||
|
}.sequenceFu
|
||||||
|
|
||||||
def erase(user: User) = coll.delete.one(regexId(user.id))
|
def erase(user: User) = coll.delete.one(regexId(user.id))
|
||||||
|
|
||||||
private def simulParticipant(simul: lila.simul.Simul, userId: String) =
|
private def simulParticipant(simul: lila.simul.Simul, userId: String) =
|
||||||
|
|
|
@ -7,8 +7,10 @@ import lila.common.{ Day, Iso }
|
||||||
import lila.db.dsl._
|
import lila.db.dsl._
|
||||||
import lila.rating.BSONHandlers.perfTypeKeyIso
|
import lila.rating.BSONHandlers.perfTypeKeyIso
|
||||||
import lila.rating.PerfType
|
import lila.rating.PerfType
|
||||||
import lila.study.BSONHandlers._
|
import lila.study.BSONHandlers.StudyIdBSONHandler
|
||||||
import lila.study.Study
|
import lila.study.Study
|
||||||
|
import lila.swiss.BsonHandlers.swissIdHandler
|
||||||
|
import lila.swiss.Swiss
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
|
|
||||||
private object BSONHandlers {
|
private object BSONHandlers {
|
||||||
|
@ -117,6 +119,13 @@ private object BSONHandlers {
|
||||||
implicit private lazy val teamsHandler =
|
implicit private lazy val teamsHandler =
|
||||||
isoHandler[Teams, List[String]]((s: Teams) => s.value, Teams.apply _)
|
isoHandler[Teams, List[String]]((s: Teams) => s.value, Teams.apply _)
|
||||||
|
|
||||||
|
implicit lazy val swissRankHandler = new lila.db.BSON[SwissRank] {
|
||||||
|
def reads(r: lila.db.BSON.Reader) = SwissRank(Swiss.Id(r.str("i")), r.intD("r"))
|
||||||
|
def writes(w: lila.db.BSON.Writer, s: SwissRank) = BSONDocument("i" -> s.id, "r" -> s.rank)
|
||||||
|
}
|
||||||
|
implicit private lazy val swissesHandler =
|
||||||
|
isoHandler[Swisses, List[SwissRank]]((s: Swisses) => s.value, Swisses.apply _)
|
||||||
|
|
||||||
object ActivityFields {
|
object ActivityFields {
|
||||||
val id = "_id"
|
val id = "_id"
|
||||||
val games = "g"
|
val games = "g"
|
||||||
|
@ -131,6 +140,7 @@ private object BSONHandlers {
|
||||||
val follows = "f"
|
val follows = "f"
|
||||||
val studies = "t"
|
val studies = "t"
|
||||||
val teams = "e"
|
val teams = "e"
|
||||||
|
val swisses = "w"
|
||||||
val stream = "st"
|
val stream = "st"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +163,7 @@ private object BSONHandlers {
|
||||||
follows = r.getO[Follows](follows).filterNot(_.isEmpty),
|
follows = r.getO[Follows](follows).filterNot(_.isEmpty),
|
||||||
studies = r.getO[Studies](studies),
|
studies = r.getO[Studies](studies),
|
||||||
teams = r.getO[Teams](teams),
|
teams = r.getO[Teams](teams),
|
||||||
|
swisses = r.getO[Swisses](swisses),
|
||||||
stream = r.getD[Boolean](stream)
|
stream = r.getD[Boolean](stream)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -171,6 +182,7 @@ private object BSONHandlers {
|
||||||
follows -> o.follows,
|
follows -> o.follows,
|
||||||
studies -> o.studies,
|
studies -> o.studies,
|
||||||
teams -> o.teams,
|
teams -> o.teams,
|
||||||
|
swisses -> o.swisses,
|
||||||
stream -> o.stream.option(true)
|
stream -> o.stream.option(true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ final class Env(
|
||||||
studyApi: lila.study.StudyApi,
|
studyApi: lila.study.StudyApi,
|
||||||
tourLeaderApi: lila.tournament.LeaderboardApi,
|
tourLeaderApi: lila.tournament.LeaderboardApi,
|
||||||
getTourName: lila.tournament.GetTourName,
|
getTourName: lila.tournament.GetTourName,
|
||||||
getTeamName: lila.team.GetTeamName
|
getTeamName: lila.team.GetTeamName,
|
||||||
|
swissApi: lila.swiss.SwissApi
|
||||||
)(implicit
|
)(implicit
|
||||||
ec: scala.concurrent.ExecutionContext,
|
ec: scala.concurrent.ExecutionContext,
|
||||||
system: ActorSystem
|
system: ActorSystem
|
||||||
|
@ -52,7 +53,8 @@ final class Env(
|
||||||
"relation",
|
"relation",
|
||||||
"startStudy",
|
"startStudy",
|
||||||
"streamStart",
|
"streamStart",
|
||||||
"gdprErase"
|
"gdprErase",
|
||||||
|
"swissFinish"
|
||||||
) {
|
) {
|
||||||
case lila.forum.actorApi.CreatePost(post) => write.forumPost(post).unit
|
case lila.forum.actorApi.CreatePost(post) => write.forumPost(post).unit
|
||||||
case prog: lila.practice.PracticeProgress.OnComplete => write.practice(prog).unit
|
case prog: lila.practice.PracticeProgress.OnComplete => write.practice(prog).unit
|
||||||
|
@ -67,5 +69,6 @@ final class Env(
|
||||||
case lila.hub.actorApi.team.JoinTeam(id, userId) => write.team(id, userId).unit
|
case lila.hub.actorApi.team.JoinTeam(id, userId) => write.team(id, userId).unit
|
||||||
case lila.hub.actorApi.streamer.StreamStart(userId) => write.streamStart(userId).unit
|
case lila.hub.actorApi.streamer.StreamStart(userId) => write.streamStart(userId).unit
|
||||||
case lila.user.User.GDPRErase(user) => write.erase(user).unit
|
case lila.user.User.GDPRErase(user) => write.erase(user).unit
|
||||||
|
case lila.swiss.SwissFinish(swissId, ranking) => write.swiss(swissId, ranking)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package lila.activity
|
package lila.activity
|
||||||
|
|
||||||
|
import model._
|
||||||
import ornicar.scalalib.Zero
|
import ornicar.scalalib.Zero
|
||||||
|
|
||||||
import lila.rating.PerfType
|
import lila.rating.PerfType
|
||||||
import lila.study.Study
|
import lila.study.Study
|
||||||
|
import lila.swiss.Swiss
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
import model._
|
|
||||||
|
|
||||||
object activities {
|
object activities {
|
||||||
|
|
||||||
|
@ -103,4 +104,10 @@ object activities {
|
||||||
def +(s: String) = copy(value = (s :: value).distinct take maxSubEntries)
|
def +(s: String) = copy(value = (s :: value).distinct take maxSubEntries)
|
||||||
}
|
}
|
||||||
implicit val TeamsZero = Zero.instance(Teams(Nil))
|
implicit val TeamsZero = Zero.instance(Teams(Nil))
|
||||||
|
|
||||||
|
case class SwissRank(id: Swiss.Id, rank: Int)
|
||||||
|
case class Swisses(value: List[SwissRank]) extends AnyVal {
|
||||||
|
def +(s: SwissRank) = copy(value = (s :: value) take maxSubEntries)
|
||||||
|
}
|
||||||
|
implicit val SwissesZero = Zero.instance(Swisses(Nil))
|
||||||
}
|
}
|
||||||
|
|
|
@ -966,6 +966,8 @@ val `joinedNbSimuls` = new I18nKey("activity:joinedNbSimuls")
|
||||||
val `createdNbStudies` = new I18nKey("activity:createdNbStudies")
|
val `createdNbStudies` = new I18nKey("activity:createdNbStudies")
|
||||||
val `competedInNbTournaments` = new I18nKey("activity:competedInNbTournaments")
|
val `competedInNbTournaments` = new I18nKey("activity:competedInNbTournaments")
|
||||||
val `rankedInTournament` = new I18nKey("activity:rankedInTournament")
|
val `rankedInTournament` = new I18nKey("activity:rankedInTournament")
|
||||||
|
val `competedInNbSwissTournaments` = new I18nKey("activity:competedInNbSwissTournaments")
|
||||||
|
val `rankedInSwissTournament` = new I18nKey("activity:rankedInSwissTournament")
|
||||||
val `joinedNbTeams` = new I18nKey("activity:joinedNbTeams")
|
val `joinedNbTeams` = new I18nKey("activity:joinedNbTeams")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,6 @@ object Study {
|
||||||
implicit val nameIso = lila.common.Iso.string[Name](Name.apply, _.value)
|
implicit val nameIso = lila.common.Iso.string[Name](Name.apply, _.value)
|
||||||
|
|
||||||
case class IdName(_id: Id, name: Name) {
|
case class IdName(_id: Id, name: Name) {
|
||||||
|
|
||||||
def id = _id
|
def id = _id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import lila.db.BSON
|
||||||
import lila.db.dsl._
|
import lila.db.dsl._
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
|
|
||||||
private object BsonHandlers {
|
object BsonHandlers {
|
||||||
|
|
||||||
implicit val variantHandler = variantByKeyHandler
|
implicit val variantHandler = variantByKeyHandler
|
||||||
implicit val clockHandler = clockConfigHandler
|
implicit val clockHandler = clockConfigHandler
|
||||||
|
@ -130,4 +130,7 @@ private object BsonHandlers {
|
||||||
"garbage" -> s.unrealisticSettings.option(true)
|
"garbage" -> s.unrealisticSettings.option(true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import Swiss.IdName
|
||||||
|
implicit val SwissIdNameBSONHandler = Macros.handler[IdName]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package lila.swiss
|
package lila.swiss
|
||||||
|
|
||||||
import chess.Clock.{ Config => ClockConfig }
|
import chess.Clock.{ Config => ClockConfig }
|
||||||
|
import chess.format.FEN
|
||||||
import chess.Speed
|
import chess.Speed
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
@ -8,7 +9,6 @@ import scala.concurrent.duration._
|
||||||
import lila.hub.LightTeam.TeamID
|
import lila.hub.LightTeam.TeamID
|
||||||
import lila.rating.PerfType
|
import lila.rating.PerfType
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
import chess.format.FEN
|
|
||||||
|
|
||||||
case class Swiss(
|
case class Swiss(
|
||||||
_id: Swiss.Id,
|
_id: Swiss.Id,
|
||||||
|
@ -93,6 +93,10 @@ object Swiss {
|
||||||
case class Performance(value: Float) extends AnyVal
|
case class Performance(value: Float) extends AnyVal
|
||||||
case class Score(value: Int) extends AnyVal
|
case class Score(value: Int) extends AnyVal
|
||||||
|
|
||||||
|
case class IdName(_id: Id, name: String) {
|
||||||
|
def id = _id
|
||||||
|
}
|
||||||
|
|
||||||
case class Settings(
|
case class Settings(
|
||||||
nbRounds: Int,
|
nbRounds: Int,
|
||||||
rated: Boolean,
|
rated: Boolean,
|
||||||
|
|
|
@ -430,9 +430,9 @@ final class SwissApi(
|
||||||
|
|
||||||
private[swiss] def finish(oldSwiss: Swiss): Funit =
|
private[swiss] def finish(oldSwiss: Swiss): Funit =
|
||||||
Sequencing(oldSwiss.id)(startedById) { swiss =>
|
Sequencing(oldSwiss.id)(startedById) { swiss =>
|
||||||
colls.pairing.countSel($doc(SwissPairing.Fields.swissId -> swiss.id)) flatMap {
|
colls.pairing.exists($doc(SwissPairing.Fields.swissId -> swiss.id)) flatMap {
|
||||||
case 0 => destroy(swiss)
|
if (_) doFinish(swiss)
|
||||||
case _ => doFinish(swiss)
|
else destroy(swiss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private def doFinish(swiss: Swiss): Funit =
|
private def doFinish(swiss: Swiss): Funit =
|
||||||
|
@ -459,6 +459,15 @@ final class SwissApi(
|
||||||
} >>- {
|
} >>- {
|
||||||
systemChat(swiss.id, s"Tournament completed!")
|
systemChat(swiss.id, s"Tournament completed!")
|
||||||
socket.reload(swiss.id)
|
socket.reload(swiss.id)
|
||||||
|
system.scheduler
|
||||||
|
.scheduleOnce(10 seconds) {
|
||||||
|
// we're delaying this to make sure the ranking has been recomputed
|
||||||
|
// since doFinish is called by finishGame before that
|
||||||
|
rankingApi(swiss) foreach { ranking =>
|
||||||
|
Bus.publish(SwissFinish(swiss.id, ranking), "swissFinish")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.unit
|
||||||
}
|
}
|
||||||
|
|
||||||
def kill(swiss: Swiss): Funit = {
|
def kill(swiss: Swiss): Funit = {
|
||||||
|
@ -639,6 +648,11 @@ final class SwissApi(
|
||||||
.zipWithIndex
|
.zipWithIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val idNameProjection = $doc("name" -> true)
|
||||||
|
|
||||||
|
def idNames(ids: List[Swiss.Id]): Fu[List[Swiss.IdName]] =
|
||||||
|
colls.swiss.find($inIds(ids), idNameProjection.some).cursor[Swiss.IdName]().list()
|
||||||
|
|
||||||
private def Sequencing[A: Zero](
|
private def Sequencing[A: Zero](
|
||||||
id: Swiss.Id
|
id: Swiss.Id
|
||||||
)(fetch: Swiss.Id => Fu[Option[Swiss]])(run: Swiss => Fu[A]): Fu[A] =
|
)(fetch: Swiss.Id => Fu[Option[Swiss]])(run: Swiss => Fu[A]): Fu[A] =
|
||||||
|
|
|
@ -26,3 +26,5 @@ case class FeaturedSwisses(
|
||||||
created: List[Swiss],
|
created: List[Swiss],
|
||||||
started: List[Swiss]
|
started: List[Swiss]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
case class SwissFinish(id: Swiss.Id, ranking: Ranking)
|
||||||
|
|
|
@ -4,9 +4,9 @@ import lila.user.User
|
||||||
|
|
||||||
package object swiss extends PackageObject {
|
package object swiss extends PackageObject {
|
||||||
|
|
||||||
private[swiss] val logger = lila.log("swiss")
|
type Ranking = Map[lila.user.User.ID, Int]
|
||||||
|
|
||||||
private[swiss] type Ranking = Map[lila.user.User.ID, Int]
|
private[swiss] val logger = lila.log("swiss")
|
||||||
|
|
||||||
// FIDE TRF player IDs
|
// FIDE TRF player IDs
|
||||||
private[swiss] type PlayerIds = Map[User.ID, Int]
|
private[swiss] type PlayerIds = Map[User.ID, Int]
|
||||||
|
|
|
@ -55,13 +55,21 @@
|
||||||
<item quantity="other">Created %s new studies</item>
|
<item quantity="other">Created %s new studies</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="competedInNbTournaments">
|
<plurals name="competedInNbTournaments">
|
||||||
<item quantity="one">Competed in %s tournament</item>
|
<item quantity="one">Competed in %s Arena tournament</item>
|
||||||
<item quantity="other">Competed in %s tournaments</item>
|
<item quantity="other">Competed in %s Arena tournaments</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="rankedInTournament">
|
<plurals name="rankedInTournament">
|
||||||
<item quantity="one">Ranked #%1$s (top %2$s%%) with %3$s game in %4$s</item>
|
<item quantity="one">Ranked #%1$s (top %2$s%%) with %3$s game in %4$s</item>
|
||||||
<item quantity="other">Ranked #%1$s (top %2$s%%) with %3$s games in %4$s</item>
|
<item quantity="other">Ranked #%1$s (top %2$s%%) with %3$s games in %4$s</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="competedInNbSwissTournaments">
|
||||||
|
<item quantity="one">Competed in %s swiss tournament</item>
|
||||||
|
<item quantity="other">Competed in %s swiss tournaments</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="rankedInSwissTournament">
|
||||||
|
<item quantity="one">Ranked #%1$s in %2$s</item>
|
||||||
|
<item quantity="other">Ranked #%1$s in %2$s</item>
|
||||||
|
</plurals>
|
||||||
<string name="signedUp">Signed up to lichess.org</string>
|
<string name="signedUp">Signed up to lichess.org</string>
|
||||||
<plurals name="joinedNbTeams">
|
<plurals name="joinedNbTeams">
|
||||||
<item quantity="one">Joined %s team</item>
|
<item quantity="one">Joined %s team</item>
|
||||||
|
|
Loading…
Reference in New Issue