activity: study creations

pull/3317/merge
Thibault Duplessis 2017-07-21 12:49:54 +02:00
parent 652e74e574
commit 021c75b6c4
11 changed files with 82 additions and 18 deletions

View File

@ -24,10 +24,10 @@
@p.toList.sortBy(-_._2).zipWithIndex.map {
case ((study, nb), i) => {
@if(i == 1) {<div class="sub">}
Practiced @nb positions on <a href="@routes.Practice.show("-", study.slug, study.id.value)">@study.name</a><br />
}
}
</div>
Practiced @nb positions on <a href="@routes.Practice.show("-", study.slug, study.id.value)">@study.name</a><br />
}
}
</div>
</div>
</div>
}
@ -173,6 +173,20 @@ case (pt, score) => {
</div>
}
@renderStudies(studies: List[lila.study.Study.IdName]) = {
<div class="entry studies">
<i data-icon=""></i>
<div>
Created @studies.size new studies
<div class="sub">
@studies.map { s =>
<a href="@routes.Study.show(s.id.value)">@s.name</a><br />
}
</div>
</div>
</div>
}
@user.layout(
title = s"${u.username} activity",
evenMoreCss = moreCss) {
@ -201,6 +215,7 @@ evenMoreCss = moreCss) {
}
@a.follows.map(renderFollows)
@a.simuls.map(renderSimuls)
@a.studies.map(renderStudies)
</div>
</section>
}

View File

@ -16,7 +16,8 @@ case class Activity(
simuls: Option[Simuls] = None,
corres: Option[Corres] = None,
patron: Option[Patron] = None,
follows: Option[Follows] = None
follows: Option[Follows] = None,
studies: Option[Studies] = None
) {
def date = Activity.Day.genesis plusDays id.day.value

View File

@ -11,7 +11,8 @@ final class ActivityReadApi(
coll: Coll,
practiceApi: lila.practice.PracticeApi,
postApi: lila.forum.PostApi,
simulApi: lila.simul.SimulApi
simulApi: lila.simul.SimulApi,
studyApi: lila.study.StudyApi
) {
import Activity._
@ -57,6 +58,9 @@ final class ActivityReadApi(
simuls <- a.simuls ?? { simuls =>
simulApi byIds simuls.value.map(_.value) dmap some
}
studies <- a.studies ?? { studies =>
studyApi idNames studies.value map some
}
view = ActivityView(
games = a.games,
puzzles = a.puzzles,
@ -66,7 +70,8 @@ final class ActivityReadApi(
patron = a.patron,
corresMoves = corresMoves,
corresEnds = corresEnds,
follows = a.follows
follows = a.follows,
studies = studies
)
} yield ActivityView.AsTo(a.date, view)

View File

@ -6,6 +6,7 @@ import lila.study.Study
import lila.practice.PracticeStudy
import lila.game.Pov
import lila.simul.Simul
import lila.study.Study
import activities._
import model._
@ -19,7 +20,8 @@ case class ActivityView(
posts: Option[Map[lila.forum.Topic, List[lila.forum.Post]]],
corresMoves: Option[(Int, List[Pov])],
corresEnds: Option[(Score, List[Pov])],
follows: Option[Follows]
follows: Option[Follows],
studies: Option[List[Study.IdName]]
) {
}

View File

@ -5,8 +5,12 @@ import lila.db.dsl._
import lila.game.Game
import lila.user.User
import lila.user.UserRepo.lichessId
import lila.study.Study
final class ActivityWriteApi(coll: Coll) {
final class ActivityWriteApi(
coll: Coll,
studyApi: lila.study.StudyApi
) {
import Activity._
import BSONHandlers._
@ -52,6 +56,14 @@ final class ActivityWriteApi(coll: Coll) {
a.copy(follows = Some(~a.follows addIn from)).some
}
def study(id: Study.Id) = studyApi byId id flatMap {
_.filter(_.isPublic) ?? { s =>
update(s.ownerId) { a =>
a.copy(studies = Some(~a.studies + s.id)).some
}
}
}
private def simulParticipant(simul: lila.simul.Simul, userId: String, host: Boolean) =
update(userId) { a => a.copy(simuls = Some(~a.simuls + SimulId(simul.id))).some }

View File

@ -97,6 +97,10 @@ private object BSONHandlers {
)
}
private implicit val studyIdHandler = isoHandler(studyIdIso)
private implicit val studyIdsHandler = bsonArrayToListHandler[Study.Id]
private implicit val studiesHandler = isoHandler[Studies, List[Study.Id], Barr]((s: Studies) => s.value, Studies.apply _)
implicit val activityHandler = new lila.db.BSON[Activity] {
private val id = "_id"
@ -109,6 +113,7 @@ private object BSONHandlers {
private val corres = "o"
private val patron = "a"
private val follows = "f"
private val studies = "t"
def reads(r: lila.db.BSON.Reader) = Activity(
id = r.get[Id](id),
@ -120,7 +125,8 @@ private object BSONHandlers {
simuls = r.getO[Simuls](simuls),
corres = r.getO[Corres](corres),
patron = r.getO[Patron](patron),
follows = r.getO[Follows](follows)
follows = r.getO[Follows](follows),
studies = r.getO[Studies](studies)
)
def writes(w: lila.db.BSON.Writer, o: Activity) = BSONDocument(
@ -133,7 +139,8 @@ private object BSONHandlers {
simuls -> o.simuls,
corres -> o.corres,
patron -> o.patron,
follows -> o.follows
follows -> o.follows,
studies -> o.studies
)
}
}

View File

@ -12,20 +12,23 @@ final class Env(
system: akka.actor.ActorSystem,
practiceApi: lila.practice.PracticeApi,
postApi: lila.forum.PostApi,
simulApi: lila.simul.SimulApi
simulApi: lila.simul.SimulApi,
studyApi: lila.study.StudyApi
) {
private val activityColl = db(config getString "collection.activity")
val write = new ActivityWriteApi(
coll = activityColl
coll = activityColl,
studyApi = studyApi
)
val read = new ActivityReadApi(
coll = activityColl,
practiceApi = practiceApi,
postApi = postApi,
simulApi = simulApi
simulApi = simulApi,
studyApi = studyApi
)
system.lilaBus.subscribe(
@ -39,10 +42,13 @@ final class Env(
case CorresMoveEvent(move, Some(userId), _, _, false) => write.corresMove(move.gameId, userId)
case lila.hub.actorApi.plan.MonthInc(userId, months) => write.plan(userId, months)
case lila.hub.actorApi.relation.Follow(from, to) => write.follow(from, to)
case lila.study.actorApi.StartStudy(id) =>
// wait 5 minutes in case the study turns private
system.scheduler.scheduleOnce(5 seconds) { write study id }
}
})),
'finishGame, 'forumPost, 'finishPuzzle, 'finishPractice,
'startSimul, 'moveEventCorres, 'plan, 'relation
'startSimul, 'moveEventCorres, 'plan, 'relation, 'startStudy
)
}
@ -54,6 +60,7 @@ object Env {
system = lila.common.PlayApp.system,
practiceApi = lila.practice.Env.current.api,
postApi = lila.forum.Env.current.postApi,
simulApi = lila.simul.Env.current.api
simulApi = lila.simul.Env.current.api,
studyApi = lila.study.Env.current.api
)
}

View File

@ -85,4 +85,9 @@ object activities {
}
implicit val FollowListZero = Zero.instance(FollowList(Nil, None))
implicit val FollowsZero = Zero.instance(Follows(None, None))
case class Studies(value: List[Study.Id]) extends AnyVal {
def +(s: Study.Id) = copy(value = s :: value)
}
implicit val StudiesZero = Zero.instance(Studies(Nil))
}

View File

@ -3,8 +3,8 @@ package lila.study
import akka.actor.{ ActorRef, ActorSelection }
import scala.concurrent.duration._
import chess.format.pgn.Glyph
import chess.Centis
import chess.format.pgn.Glyph
import lila.hub.actorApi.map.Tell
import lila.hub.actorApi.timeline.{ Propagate, StudyCreate, StudyLike }
import lila.hub.Sequencer
@ -33,6 +33,8 @@ final class StudyApi(
def byIds = studyRepo byOrderedIds _
def idNames = studyRepo idNames _
def publicByIds(ids: Seq[Study.Id]) = byIds(ids) map { _.filter(_.isPublic) }
def byIdAndOwner(id: Study.Id, owner: User) = byId(id) map {
@ -79,7 +81,7 @@ final class StudyApi(
def studyIdOf = chapterRepo.studyIdOf _
def create(data: DataForm.Data, user: User): Fu[Option[Study.WithChapter]] = data.as match {
def create(data: DataForm.Data, user: User): Fu[Option[Study.WithChapter]] = (data.as match {
case DataForm.AsNewStudy =>
studyMaker(data, user) flatMap { res =>
studyRepo.insert(res.study) >>
@ -105,6 +107,10 @@ final class StudyApi(
} yield made
case _ => fuccess(none)
} orElse create(data.copy(asStr = none), user)
}) addEffect {
_ ?? { sc =>
bus.publish(actorApi.StartStudy(sc.study.id), 'startStudy)
}
}
def clone(me: User, prev: Study): Fu[Option[Study]] =

View File

@ -110,6 +110,9 @@ final class StudyRepo(private[study] val coll: Coll) {
private val idNameProjection = $doc("name" -> true)
def idNames(ids: List[Study.Id]): Fu[List[Study.IdName]] =
coll.find($inIds(ids), idNameProjection).list[Study.IdName]()
def recentByOwner(userId: User.ID, nb: Int) =
coll.find(
selectOwnerId(userId),

View File

@ -1,6 +1,7 @@
package lila.study
package actorApi
case class StartStudy(studyId: Study.Id)
case class SaveStudy(study: Study)
case class SetTag(chapterId: Chapter.Id, name: String, value: String) {
def tag = chess.format.pgn.Tag(name, value take 140)