lila/modules/study/src/main/JsonView.scala

212 lines
7.3 KiB
Scala
Raw Normal View History

2016-02-26 05:08:11 -07:00
package lila.study
2019-12-13 07:30:20 -07:00
import chess.format.{ FEN, Uci }
2016-04-21 20:53:16 -06:00
import chess.Pos
import play.api.libs.json._
import scala.util.chaining._
2016-02-26 05:08:11 -07:00
2019-12-07 17:43:22 -07:00
import lila.common.Json._
2019-07-13 12:02:50 -06:00
import lila.socket.Socket.Sri
2016-11-26 06:59:27 -07:00
import lila.tree.Node.Shape
import lila.user.User
2016-02-26 05:08:11 -07:00
final class JsonView(
2016-05-26 14:01:43 -06:00
studyRepo: StudyRepo,
2019-12-03 17:55:45 -07:00
lightUserApi: lila.user.LightUserApi
)(implicit ec: scala.concurrent.ExecutionContext) {
2016-05-11 03:20:19 -06:00
import JsonView._
2016-04-20 01:04:38 -06:00
def apply(
2019-12-13 07:30:20 -07:00
study: Study,
chapters: List[Chapter.Metadata],
currentChapter: Chapter,
me: Option[User]
) = {
2016-10-12 07:37:40 -06:00
def allowed(selection: Settings.UserSelection): Boolean =
Settings.UserSelection.allows(selection, study, me.map(_.id))
me.?? { studyRepo.liked(study, _) } map { liked =>
2019-12-13 07:30:20 -07:00
studyWrites.writes(study) ++ Json
.obj(
"liked" -> liked,
"features" -> Json.obj(
2019-12-13 07:30:20 -07:00
"cloneable" -> allowed(study.settings.cloneable),
"chat" -> allowed(study.settings.chat),
"sticky" -> study.settings.sticky,
"description" -> study.settings.description
),
2020-02-21 12:27:22 -07:00
"topics" -> study.topicsOrEmpty,
2019-12-13 07:30:20 -07:00
"chapters" -> chapters.map(chapterMetadataWrites.writes),
"chapter" -> Json
.obj(
"id" -> currentChapter.id,
"ownerId" -> currentChapter.ownerId,
"setup" -> currentChapter.setup,
"tags" -> currentChapter.tags,
"features" -> Json.obj(
"computer" -> allowed(study.settings.computer),
"explorer" -> allowed(study.settings.explorer)
)
)
.add("description", currentChapter.description)
.add("serverEval", currentChapter.serverEval)
.add("relay", currentChapter.relay)(relayWrites)
.pipe(addChapterMode(currentChapter))
2019-12-13 07:30:20 -07:00
)
.add("description", study.description)
}
2017-08-10 20:05:03 -06:00
}
2019-12-13 07:30:20 -07:00
def chapterConfig(c: Chapter) =
Json
.obj(
"id" -> c.id,
"name" -> c.name,
"orientation" -> c.setup.orientation
)
.add("description", c.description) pipe addChapterMode(c)
2017-08-15 14:28:16 -06:00
2020-05-05 22:11:15 -06:00
def pagerData(s: Study.WithChaptersAndLiked) =
Json.obj(
"id" -> s.study.id.value,
"name" -> s.study.name.value,
"liked" -> s.liked,
"likes" -> s.study.likes.value,
"updatedAt" -> s.study.updatedAt,
"owner" -> lightUserApi.sync(s.study.ownerId),
"chapters" -> s.chapters.take(4),
"members" -> s.study.members.members.values.take(4)
)
2017-08-15 14:28:16 -06:00
private def addChapterMode(c: Chapter)(js: JsObject): JsObject =
js.add("practice", c.isPractice)
.add("gamebook", c.isGamebook)
.add("conceal", c.conceal)
2019-12-13 07:30:20 -07:00
implicit private[study] val memberRoleWrites = Writes[StudyMember.Role] { r =>
2016-05-11 03:20:19 -06:00
JsString(r.id)
}
2019-12-13 07:30:20 -07:00
implicit private[study] val memberWrites: Writes[StudyMember] = Writes[StudyMember] { m =>
2020-06-06 18:09:18 -06:00
Json.obj("user" -> lightUserApi.syncFallback(m.id), "role" -> m.role)
2016-05-11 03:20:19 -06:00
}
2019-12-13 07:30:20 -07:00
implicit private[study] val membersWrites: Writes[StudyMembers] = Writes[StudyMembers] { m =>
2016-05-11 03:20:19 -06:00
Json toJson m.members
}
2019-12-13 07:30:20 -07:00
implicit private val studyWrites = OWrites[Study] { s =>
Json
.obj(
"id" -> s.id,
"name" -> s.name,
"members" -> s.members,
"position" -> s.position,
"ownerId" -> s.ownerId,
"settings" -> s.settings,
"visibility" -> s.visibility,
"createdAt" -> s.createdAt,
"secondsSinceUpdate" -> (nowSeconds - s.updatedAt.getSeconds).toInt,
"from" -> s.from,
"likes" -> s.likes
)
.add("isNew" -> s.isNew)
2016-05-11 03:20:19 -06:00
}
}
object JsonView {
2016-06-13 05:29:00 -06:00
case class JsData(study: JsObject, analysis: JsObject)
2016-04-16 07:26:01 -06:00
2019-12-13 07:30:20 -07:00
implicit val studyIdWrites: Writes[Study.Id] = stringIsoWriter(Study.idIso)
2017-01-20 06:14:47 -07:00
implicit val studyNameWrites: Writes[Study.Name] = stringIsoWriter(Study.nameIso)
implicit val studyIdNameWrites = OWrites[Study.IdName] { s =>
Json.obj("id" -> s._id, "name" -> s.name)
}
2019-12-13 07:30:20 -07:00
implicit val chapterIdWrites: Writes[Chapter.Id] = stringIsoWriter(Chapter.idIso)
2017-01-20 06:14:47 -07:00
implicit val chapterNameWrites: Writes[Chapter.Name] = stringIsoWriter(Chapter.nameIso)
2019-12-13 07:30:20 -07:00
implicit private val posReader: Reads[Pos] = Reads[Pos] { v =>
2020-09-21 03:31:16 -06:00
(v.asOpt[String] flatMap Pos.fromKey).fold[JsResult[Pos]](JsError(Nil))(JsSuccess(_))
2016-04-21 20:53:16 -06:00
}
2019-12-13 07:30:20 -07:00
implicit private[study] val pathWrites: Writes[Path] = Writes[Path] { p =>
2016-04-21 20:53:16 -06:00
JsString(p.toString)
}
2019-12-13 07:30:20 -07:00
implicit private[study] val sriWriter: Writes[Sri] = Writes[Sri] { sri =>
2019-07-13 12:02:50 -06:00
JsString(sri.value)
2016-04-23 21:01:58 -06:00
}
2019-12-13 07:30:20 -07:00
implicit private[study] val visibilityWriter: Writes[Study.Visibility] = Writes[Study.Visibility] { v =>
2016-04-26 21:12:53 -06:00
JsString(v.key)
}
2019-12-13 07:30:20 -07:00
implicit private[study] val fromWriter: Writes[Study.From] = Writes[Study.From] {
case Study.From.Scratch => JsString("scratch")
case Study.From.Game(id) => Json.obj("game" -> id)
2016-08-31 10:03:37 -06:00
case Study.From.Study(id) => Json.obj("study" -> id)
case Study.From.Relay(id) => Json.obj("relay" -> id)
2016-05-22 08:50:55 -06:00
}
2019-12-13 07:30:20 -07:00
implicit private[study] val userSelectionWriter = Writes[Settings.UserSelection] { v =>
JsString(v.key)
}
2019-12-13 07:30:20 -07:00
implicit private[study] val settingsWriter: Writes[Settings] = Json.writes[Settings]
implicit private[study] val shapeReader: Reads[Shape] = Reads[Shape] { js =>
js.asOpt[JsObject]
.flatMap { o =>
for {
brush <- o str "brush"
orig <- o.get[Pos]("orig")
} yield o.get[Pos]("dest") match {
case Some(dest) => Shape.Arrow(brush, orig, dest)
case _ => Shape.Circle(brush, orig)
}
2016-04-21 20:53:16 -06:00
}
2019-12-13 07:30:20 -07:00
.fold[JsResult[Shape]](JsError(Nil))(JsSuccess(_))
2016-04-16 07:26:01 -06:00
}
2019-12-13 07:30:20 -07:00
implicit private val plyWrites = Writes[Chapter.Ply] { p =>
2016-05-18 08:15:02 -06:00
JsNumber(p.value)
}
2016-04-16 07:26:01 -06:00
2019-12-13 07:30:20 -07:00
implicit private val variantWrites = OWrites[chess.variant.Variant] { v =>
2016-05-22 04:54:20 -06:00
Json.obj("key" -> v.key, "name" -> v.name)
}
2016-12-21 11:18:38 -07:00
implicit val pgnTagWrites: Writes[chess.format.pgn.Tag] = Writes[chess.format.pgn.Tag] { t =>
2016-12-21 17:37:14 -07:00
Json.arr(t.name.toString, t.value)
2016-05-17 09:35:04 -06:00
}
2017-09-20 11:22:06 -06:00
implicit val pgnTagsWrites = Writes[chess.format.pgn.Tags] { tags =>
JsArray(tags.value map pgnTagWrites.writes)
}
2019-12-13 07:30:20 -07:00
implicit private val chapterSetupWrites = Json.writes[Chapter.Setup]
implicit val chapterMetadataWrites = OWrites[Chapter.Metadata] { c =>
Json
.obj("id" -> c._id, "name" -> c.name)
.add("ongoing", c.looksOngoing)
.add("res" -> c.resultStr)
2016-04-24 03:15:18 -06:00
}
2016-04-20 01:04:38 -06:00
2019-12-13 07:30:20 -07:00
implicit private[study] val positionRefWrites: Writes[Position.Ref] = Json.writes[Position.Ref]
implicit private val likesWrites: Writes[Study.Likes] = Writes[Study.Likes] { p =>
2016-05-26 14:01:43 -06:00
JsNumber(p.value)
}
2019-12-13 07:30:20 -07:00
implicit private[study] val likingRefWrites: Writes[Study.Liking] = Json.writes[Study.Liking]
implicit val relayWrites = OWrites[Chapter.Relay] { r =>
Json.obj(
2019-12-13 07:30:20 -07:00
"path" -> r.path,
"secondsSinceLastMove" -> r.secondsSinceLastMove
)
}
2019-12-13 07:30:20 -07:00
implicit private[study] val serverEvalWrites: Writes[Chapter.ServerEval] = Json.writes[Chapter.ServerEval]
2019-10-23 09:31:31 -06:00
2019-12-13 07:30:20 -07:00
implicit private[study] val whoWriter: Writes[actorApi.Who] = Writes[actorApi.Who] { w =>
Json.obj("u" -> w.u, "s" -> w.sri)
}
2020-02-21 12:27:22 -07:00
2020-02-21 17:47:45 -07:00
implicit val topicWrites: Writes[StudyTopic] = stringIsoWriter(StudyTopic.topicIso)
implicit val topicsWrites: Writes[StudyTopics] = Writes[StudyTopics] { topics =>
2020-02-21 12:27:22 -07:00
JsArray(topics.value map topicWrites.writes)
}
2016-04-18 00:32:34 -06:00
}