diff --git a/app/controllers/Bot.scala b/app/controllers/Bot.scala
index 51d609d1e9..9a8283e22d 100644
--- a/app/controllers/Bot.scala
+++ b/app/controllers/Bot.scala
@@ -39,14 +39,12 @@ object Bot extends LilaController {
}
private def WithMyBotGame(anyId: String, me: lila.user.User)(f: lila.game.Pov => Fu[Result]) =
- lila.user.UserRepo.isBot(me) flatMap {
- case false => BadRequest(jsonError("This endpoint only works for bot accounts. See https://lichess.org/api#operation/botAccountUpgrade")).fuccess
- case _ => Env.round.roundProxyGame(lila.game.Game takeGameId anyId) flatMap {
- case None => NotFound(jsonError("No such game")).fuccess
- case Some(game) => lila.game.Pov(game, me) match {
- case None => NotFound(jsonError("Not your game")).fuccess
- case Some(pov) => f(pov)
- }
+ if (!me.isBot) BadRequest(jsonError("This endpoint only works for bot accounts. See https://lichess.org/api#operation/botAccountUpgrade")).fuccess
+ else Env.round.roundProxyGame(lila.game.Game takeGameId anyId) flatMap {
+ case None => NotFound(jsonError("No such game")).fuccess
+ case Some(game) => lila.game.Pov(game, me) match {
+ case None => NotFound(jsonError("Not your game")).fuccess
+ case Some(pov) => f(pov)
}
}
}
diff --git a/app/templating/UserHelper.scala b/app/templating/UserHelper.scala
index 50be0b9367..01c528f84b 100644
--- a/app/templating/UserHelper.scala
+++ b/app/templating/UserHelper.scala
@@ -139,9 +139,8 @@ trait UserHelper { self: I18nHelper with StringHelper with NumberHelper =>
): Html = userIdLink(userId.some, cssClass)
def titleTag(title: Option[String]) = Html {
- title match {
- case None => ""
- case Some(t) => s"""$t """
+ title.fold("") { t =>
+ s"""$t """
}
}
diff --git a/modules/api/src/main/UserApi.scala b/modules/api/src/main/UserApi.scala
index f97d2db3f1..48486dac62 100644
--- a/modules/api/src/main/UserApi.scala
+++ b/modules/api/src/main/UserApi.scala
@@ -51,10 +51,9 @@ private[api] final class UserApi(
bookmarkApi.countByUser(u) zip
gameCache.nbPlaying(u.id) zip
gameCache.nbImportedBy(u.id) zip
- lila.user.UserRepo.isBot(u) zip
playBanApi.completionRate(u.id).map(_.map { cr => math.round(cr * 100) }) map {
case gameOption ~ nbGamesWithMe ~ following ~ followers ~ followable ~ relation ~
- isFollowed ~ nbBookmarks ~ nbPlaying ~ nbImported ~ isBot ~ completionRate =>
+ isFollowed ~ nbBookmarks ~ nbPlaying ~ nbImported ~ completionRate =>
jsonView(u) ++ {
Json.obj(
"url" -> makeUrl(s"@/${u.username}"), // for app BC
@@ -77,8 +76,7 @@ private[api] final class UserApi(
"import" -> nbImported,
"me" -> nbGamesWithMe
)
- ).add("streaming", isStreaming(u.id))
- .add("bot" -> isBot) ++
+ ).add("streaming", isStreaming(u.id)) ++
as.isDefined.??(Json.obj(
"followable" -> followable,
"following" -> relation.has(true),
diff --git a/modules/common/src/main/LightUser.scala b/modules/common/src/main/LightUser.scala
index 4d6758e5ff..1f9fa8990e 100644
--- a/modules/common/src/main/LightUser.scala
+++ b/modules/common/src/main/LightUser.scala
@@ -11,10 +11,14 @@ case class LightUser(
def titleName = title.fold(name)(_ + " " + name)
def titleNameHtml = title.fold(name)(_ + " " + name)
+
+ def isBot = title has LightUser.botTitle
}
object LightUser {
+ val botTitle = "BOT"
+
implicit val lightUserWrites = OWrites[LightUser] { u =>
Json.obj(
"id" -> u.id,
diff --git a/modules/game/src/main/Namer.scala b/modules/game/src/main/Namer.scala
index 6e71ff1fcb..d4f842c5c0 100644
--- a/modules/game/src/main/Namer.scala
+++ b/modules/game/src/main/Namer.scala
@@ -13,7 +13,7 @@ object Namer {
p.aiLevel.fold(
p.userId.flatMap(lightUser).fold(lila.user.User.anonymous) { user =>
val title = (user.title ifTrue withTitle) ?? { t =>
- s"""$t """
+ s"""$t """
}
if (withRating) s"$title${user.name} (${ratingString(p)})"
else s"$title${user.name}"
diff --git a/modules/user/src/main/User.scala b/modules/user/src/main/User.scala
index 44d67f3152..b7f408f06b 100644
--- a/modules/user/src/main/User.scala
+++ b/modules/user/src/main/User.scala
@@ -108,6 +108,8 @@ case class User(
def createdSinceDays(days: Int) = createdAt isBefore DateTime.now.minusDays(days)
def is(name: String) = id == User.normalize(name)
+
+ def isBot = title has User.botTitle
}
object User {
@@ -173,9 +175,12 @@ object User {
"CM" -> "Candidate Master",
"WCM" -> "Woman Candidate Master",
"WNM" -> "Woman National Master",
- "LM" -> "Lichess Master"
+ "LM" -> "Lichess Master",
+ "BOT" -> "Chess Robot"
)
+ val botTitle = LightUser.botTitle
+
val titlesMap = titles.toMap
def titleName(title: String) = titlesMap get title getOrElse title
@@ -197,7 +202,6 @@ object User {
val createdAt = "createdAt"
val seenAt = "seenAt"
val kid = "kid"
- val bot = "bot"
val createdWithApiVersion = "createdWithApiVersion"
val lang = "lang"
val title = "title"
diff --git a/modules/user/src/main/UserRepo.scala b/modules/user/src/main/UserRepo.scala
index 0b57fdd26a..7b87c65e41 100644
--- a/modules/user/src/main/UserRepo.scala
+++ b/modules/user/src/main/UserRepo.scala
@@ -326,10 +326,9 @@ object UserRepo {
def setBot(user: User): Funit =
if (user.count.game > 0) fufail("You already have games played. Make a new account.")
- else coll.updateField($id(user.id), F.bot, true).void
+ else coll.updateField($id(user.id), F.title, User.botTitle).void
- def isBot(user: User): Fu[Boolean] =
- coll.primitiveOne[Boolean]($id(user.id), F.bot) map (~_)
+ private def botSelector(v: Boolean) = $doc(F.title -> v)
def getTitle(id: ID): Fu[Option[String]] = coll.primitiveOne[String]($id(id), F.title)
diff --git a/public/stylesheets/common.css b/public/stylesheets/common.css
index 499f4a31ed..a3afdb9c45 100644
--- a/public/stylesheets/common.css
+++ b/public/stylesheets/common.css
@@ -1036,6 +1036,9 @@ span.progress > .negative {
color: #d59120;
font-weight: bold;
}
+.user_link span.title[data-title=BOT] {
+ color: #c320d5!important;
+}
div.warning {
padding: 5px;
background: #f2dede;
diff --git a/ui/round/src/view/user.ts b/ui/round/src/view/user.ts
index 5c36bba81f..749a9b27c5 100644
--- a/ui/round/src/view/user.ts
+++ b/ui/round/src/view/user.ts
@@ -40,7 +40,9 @@ export function userHtml(ctrl: RoundController, player: Player) {
href: '/@/' + user.username,
target: ctrl.isPlaying() ? '_blank' : '_self'
}
- }, user.title ? [h('span.title', user.title), ' ', user.username] : [user.username]),
+ }, user.title ? [h('span.title', {
+ attrs: { 'data-title': user.title }
+ }, user.title), ' ', user.username] : [user.username]),
rating ? h('rating', rating + (player.provisional ? '?' : '')) : null,
ratingDiff(player),
player.engine ? h('span', {