remove friend list stuff
parent
a291f1838a
commit
911ff5b750
|
@ -85,15 +85,12 @@ final class Api(
|
|||
def usersStatus = ApiRequest { req =>
|
||||
val ids = get("ids", req).??(_.split(',').take(50).toList map lila.user.User.normalize)
|
||||
env.user.lightUserApi asyncMany ids dmap (_.flatten) map { users =>
|
||||
val actualIds = users.map(_.id)
|
||||
val playingIds = env.relation.online.playing intersect actualIds
|
||||
val streamingIds = env.streamer.liveStreamApi.userIds
|
||||
toApiResult {
|
||||
users.map { u =>
|
||||
lila.common.LightUser.lightUserWrites
|
||||
.writes(u)
|
||||
.add("online" -> env.socket.isOnline(u.id))
|
||||
.add("playing" -> playingIds(u.id))
|
||||
.add("streaming" -> streamingIds(u.id))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ final class Dev(env: Env) extends LilaController(env) {
|
|||
env.streamer.alwaysFeaturedSetting,
|
||||
env.rating.ratingFactorsSetting,
|
||||
env.plan.donationGoalSetting,
|
||||
env.relation.friendListToggle,
|
||||
env.apiTimelineSetting,
|
||||
env.game.crosstableInit,
|
||||
env.game.playTimeInit
|
||||
|
|
|
@ -483,27 +483,24 @@ abstract private[controllers] class LilaController(val env: Env)
|
|||
val isPage = HTTPRequest isSynchronousHttp ctx.req
|
||||
val nonce = isPage option Nonce.random
|
||||
ctx.me.fold(fuccess(PageData.anon(ctx.req, nonce, blindMode(ctx)))) { me =>
|
||||
import lila.relation.actorApi.OnlineFriends
|
||||
env.pref.api.getPref(me, ctx.req) zip
|
||||
(if (isGranted(_.Teacher, me)) fuccess(true) else env.clas.api.student.isStudent(me.id)) zip {
|
||||
if (isPage) {
|
||||
env.user.lightUserApi preloadUser me
|
||||
env.relation.online.friendsOf(me.id) zip
|
||||
env.team.api.nbRequests(me.id) zip
|
||||
env.team.api.nbRequests(me.id) zip
|
||||
env.challenge.api.countInFor.get(me.id) zip
|
||||
env.notifyM.api.unreadCount(Notifies(me.id)).dmap(_.value) zip
|
||||
env.mod.inquiryApi.forMod(me)
|
||||
} else
|
||||
fuccess {
|
||||
((((OnlineFriends.empty, 0), 0), 0), none)
|
||||
(((0, 0), 0), none)
|
||||
}
|
||||
} map {
|
||||
case (
|
||||
(pref, hasClas),
|
||||
(onlineFriends ~ teamNbRequests ~ nbChallenges ~ nbNotifications ~ inquiry)
|
||||
(teamNbRequests ~ nbChallenges ~ nbNotifications ~ inquiry)
|
||||
) =>
|
||||
PageData(
|
||||
onlineFriends,
|
||||
teamNbRequests,
|
||||
nbChallenges,
|
||||
nbNotifications,
|
||||
|
|
|
@ -26,10 +26,9 @@ final class Streamer(
|
|||
|
||||
def live = apiC.ApiRequest { _ =>
|
||||
env.user.lightUserApi asyncMany env.streamer.liveStreamApi.userIds.toList dmap (_.flatten) map { users =>
|
||||
val playingIds = env.relation.online.playing intersect users.map(_.id)
|
||||
apiC.toApiResult {
|
||||
users.map { u =>
|
||||
lila.common.LightUser.lightUserWrites.writes(u).add("playing" -> playingIds(u.id))
|
||||
lila.common.LightUser.lightUserWrites.writes(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,8 +54,6 @@ object Environment
|
|||
|
||||
def blockingReportNbOpen: Int = env.report.api.nbOpen.awaitOrElse(10.millis, "nbReports", 0)
|
||||
|
||||
def friendListEnabled = env.relation.friendListEnabled()
|
||||
|
||||
val spinner: Frag = raw(
|
||||
"""<div class="spinner"><svg viewBox="0 0 40 40"><circle cx=20 cy=20 r=18 fill="none"></circle></svg></div>"""
|
||||
)
|
||||
|
|
|
@ -227,35 +227,13 @@ object layout {
|
|||
"is3d" -> ctx.pref.is3d
|
||||
)
|
||||
)(body),
|
||||
(ctx.isAuth && friendListEnabled) option div(
|
||||
ctx.isAuth option div(
|
||||
id := "friend_box",
|
||||
dataPreload := safeJsonValue(
|
||||
Json.obj(
|
||||
"users" -> ctx.onlineFriends.users.map(_.titleName),
|
||||
"playing" -> ctx.onlineFriends.playing,
|
||||
"patrons" -> ctx.onlineFriends.patrons,
|
||||
"studying" -> ctx.onlineFriends.studying,
|
||||
"i18n" -> i18nJsObject(i18nKeys)
|
||||
)
|
||||
)
|
||||
dataPreload := safeJsonValue(Json.obj("i18n" -> i18nJsObject(i18nKeys)))
|
||||
)(
|
||||
div(cls := "friend_box_title") {
|
||||
val count = ctx.onlineFriends.users.size
|
||||
trans.nbFriendsOnline.plural(count, strong(count))
|
||||
},
|
||||
div(cls := "friend_box_title"),
|
||||
div(cls := "content_wrap")(
|
||||
div(cls := "content list"),
|
||||
div(
|
||||
cls := List(
|
||||
"nobody" -> true,
|
||||
"none" -> ctx.onlineFriends.users.nonEmpty
|
||||
)
|
||||
)(
|
||||
span(trans.noFriendsOnline()),
|
||||
a(cls := "find button", href := routes.User.opponents)(
|
||||
span(cls := "is3 text", dataIcon := "h")(trans.findFriends())
|
||||
)
|
||||
)
|
||||
div(cls := "content list")
|
||||
)
|
||||
),
|
||||
a(id := "reconnecting", cls := "link text", dataIcon := "B")(trans.reconnecting()),
|
||||
|
|
|
@ -5,11 +5,9 @@ import play.api.i18n.Lang
|
|||
|
||||
import lila.common.{ HTTPRequest, Nonce }
|
||||
import lila.pref.Pref
|
||||
import lila.relation.actorApi.OnlineFriends
|
||||
import lila.user.{ BodyUserContext, HeaderUserContext, UserContext }
|
||||
|
||||
case class PageData(
|
||||
onlineFriends: OnlineFriends,
|
||||
teamNbRequests: Int,
|
||||
nbChallenges: Int,
|
||||
nbNotifications: Int,
|
||||
|
@ -25,7 +23,6 @@ case class PageData(
|
|||
object PageData {
|
||||
|
||||
def anon(req: RequestHeader, nonce: Option[Nonce], blindMode: Boolean = false) = PageData(
|
||||
OnlineFriends.empty,
|
||||
teamNbRequests = 0,
|
||||
nbChallenges = 0,
|
||||
nbNotifications = 0,
|
||||
|
@ -47,8 +44,6 @@ sealed trait Context extends lila.user.UserContextWrapper {
|
|||
|
||||
def lang = userContext.lang
|
||||
|
||||
def onlineFriends = pageData.onlineFriends
|
||||
|
||||
def teamNbRequests = pageData.teamNbRequests
|
||||
def nbChallenges = pageData.nbChallenges
|
||||
def nbNotifications = pageData.nbNotifications
|
||||
|
|
|
@ -16,7 +16,6 @@ final private[api] class UserApi(
|
|||
userRepo: lila.user.UserRepo,
|
||||
prefApi: lila.pref.PrefApi,
|
||||
liveStreamApi: lila.streamer.LiveStreamApi,
|
||||
onlineDoing: lila.relation.OnlineDoing,
|
||||
gameProxyRepo: lila.round.GameProxyRepo,
|
||||
net: NetConfig
|
||||
)(implicit ec: scala.concurrent.ExecutionContext) {
|
||||
|
@ -97,8 +96,7 @@ final private[api] class UserApi(
|
|||
}
|
||||
|
||||
private def addPlayingStreaming(js: JsObject, id: User.ID) =
|
||||
js.add("playing", onlineDoing.isPlaying(id))
|
||||
.add("streaming", liveStreamApi.isStreaming(id))
|
||||
js.add("streaming", liveStreamApi.isStreaming(id))
|
||||
|
||||
private def makeUrl(path: String): String = s"${net.baseUrl}/$path"
|
||||
}
|
||||
|
|
|
@ -271,10 +271,10 @@ package bookmark {
|
|||
}
|
||||
|
||||
package relation {
|
||||
case class ReloadOnlineFriends(userId: String)
|
||||
case class Block(u1: String, u2: String)
|
||||
case class UnBlock(u1: String, u2: String)
|
||||
case class Follow(u1: String, u2: String)
|
||||
case class UnFollow(u1: String, u2: String)
|
||||
}
|
||||
|
||||
package study {
|
||||
|
|
|
@ -16,10 +16,6 @@ private class RelationConfig(
|
|||
@ConfigName("limit.block") val maxBlock: Max
|
||||
)
|
||||
|
||||
final class FriendListEnabled(f: () => Boolean) extends (() => Boolean) {
|
||||
def apply() = f()
|
||||
}
|
||||
|
||||
@Module
|
||||
final class Env(
|
||||
appConfig: Configuration,
|
||||
|
@ -45,18 +41,4 @@ final class Env(
|
|||
lazy val api: RelationApi = wire[RelationApi]
|
||||
|
||||
lazy val stream = wire[RelationStream]
|
||||
|
||||
lazy val online: OnlineDoing = wire[OnlineDoing]
|
||||
|
||||
lazy val friendListToggle = settingStore[Boolean](
|
||||
"friendListToggle",
|
||||
default = true,
|
||||
text = "Enable the live friend list".some
|
||||
)
|
||||
|
||||
lazy val friendListEnabled = new FriendListEnabled(friendListToggle.get _)
|
||||
|
||||
def isPlaying(userId: lila.user.User.ID): Boolean = online.playing.get(userId)
|
||||
|
||||
system.actorOf(Props(wire[RelationActor]), name = config.actorName)
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package lila.relation
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import actorApi.OnlineFriends
|
||||
import lila.user.User
|
||||
import lila.memo.CacheApi
|
||||
|
||||
final class OnlineDoing(
|
||||
api: RelationApi,
|
||||
lightUser: lila.common.LightUser.GetterSync,
|
||||
enabled: FriendListEnabled,
|
||||
val userIds: () => Set[User.ID]
|
||||
)(implicit ec: scala.concurrent.ExecutionContext) {
|
||||
|
||||
private type StudyId = String
|
||||
|
||||
val playing = new lila.memo.ExpireSetMemo(4 hours)
|
||||
|
||||
def isPlaying(userId: User.ID) = playing get userId
|
||||
|
||||
// people with write access in public studies
|
||||
private[relation] val studying = CacheApi.scaffeineNoScheduler
|
||||
.expireAfterAccess(20 minutes)
|
||||
.build[ID, StudyId]
|
||||
|
||||
// people with write or read access in public and private studies
|
||||
private[relation] val studyingAll = CacheApi.scaffeineNoScheduler
|
||||
.expireAfterAccess(20 minutes)
|
||||
.build[ID, StudyId]
|
||||
|
||||
private[relation] def isStudying(userId: User.ID) = studying.getIfPresent(userId).isDefined
|
||||
|
||||
private[relation] def isStudying(userId: User.ID, studyId: StudyId) =
|
||||
studying.getIfPresent(userId) has studyId
|
||||
|
||||
private[relation] def isStudyingOrWatching(userId: User.ID, studyId: StudyId) =
|
||||
studyingAll.getIfPresent(userId) has studyId
|
||||
|
||||
def friendsOf(userId: User.ID): Fu[OnlineFriends] =
|
||||
if (enabled()) api fetchFollowing userId map userIds().intersect map { friends =>
|
||||
if (friends.isEmpty) OnlineFriends.empty
|
||||
else
|
||||
OnlineFriends(
|
||||
users = friends.view.flatMap { lightUser(_) }.toList,
|
||||
playing = playing intersect friends,
|
||||
studying = friends filter studying.getAllPresent(friends).contains
|
||||
)
|
||||
} else fuccess(OnlineFriends.empty)
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
package lila.relation
|
||||
|
||||
import akka.actor.Actor
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import actorApi._
|
||||
import lila.common.{ Bus, LightUser }
|
||||
import lila.hub.actorApi.relation._
|
||||
import lila.hub.actorApi.socket.{ SendTo, SendTos }
|
||||
import lila.user.User
|
||||
|
||||
final private[relation] class RelationActor(
|
||||
lightUser: LightUser.GetterSync,
|
||||
api: RelationApi,
|
||||
online: OnlineDoing,
|
||||
enabled: FriendListEnabled
|
||||
)(implicit ec: scala.concurrent.ExecutionContext)
|
||||
extends Actor {
|
||||
|
||||
private var previousOnlineIds = Set.empty[ID]
|
||||
|
||||
private val subs = List("startGame", "finishGame", "study", "reloadOnlineFriends")
|
||||
|
||||
override def preStart(): Unit = {
|
||||
Bus.subscribe(self, subs)
|
||||
context.system.scheduler.scheduleOnce(15 seconds, self, ComputeMovement)
|
||||
}
|
||||
|
||||
override def postStop(): Unit = {
|
||||
super.postStop()
|
||||
Bus.unsubscribe(self, subs)
|
||||
}
|
||||
|
||||
def scheduleNext =
|
||||
context.system.scheduler.scheduleOnce(1 seconds, self, ComputeMovement)
|
||||
|
||||
def receive = {
|
||||
|
||||
case ComputeMovement =>
|
||||
lila.common.Chronometer.syncMon(_.relation.actor.computeMovementSync) {
|
||||
|
||||
if (enabled()) {
|
||||
val curIds = online.userIds()
|
||||
|
||||
val leaveUsers: List[LightUser] =
|
||||
(previousOnlineIds diff curIds).view.flatMap { lightUser(_) }.to(List)
|
||||
val enterUsers: List[LightUser] =
|
||||
(curIds diff previousOnlineIds).view.flatMap { lightUser(_) }.to(List)
|
||||
|
||||
val friendsEntering = enterUsers map { u =>
|
||||
FriendEntering(u, online.playing get u.id, online isStudying u.id)
|
||||
}
|
||||
|
||||
previousOnlineIds = curIds
|
||||
|
||||
notifyFollowersFriendEnters(friendsEntering, curIds)
|
||||
.>>(notifyFollowersFriendLeaves(leaveUsers, curIds))
|
||||
.mon(_.relation.actor.computeMovement)
|
||||
.addEffectAnyway(scheduleNext)
|
||||
} else {
|
||||
previousOnlineIds = online.userIds()
|
||||
scheduleNext
|
||||
}
|
||||
}
|
||||
|
||||
// triggers following reloading for this user id
|
||||
case ReloadOnlineFriends(userId) if enabled() =>
|
||||
online friendsOf userId map { res =>
|
||||
// the mobile app requests this on every WS connection
|
||||
// we can skip it if empty
|
||||
if (!res.isEmpty) Bus.publish(SendTo(userId, JsonView writeOnlineFriends res), "socketUsers")
|
||||
} mon (_.relation.actor.reloadFriends)
|
||||
|
||||
case lila.game.actorApi.FinishGame(game, _, _) if game.hasClock =>
|
||||
game.userIds.some.filter(_.nonEmpty) foreach { usersPlaying =>
|
||||
online.playing removeAll usersPlaying
|
||||
if (enabled()) notifyFollowersGameStateChanged(usersPlaying, "following_stopped_playing")
|
||||
}
|
||||
|
||||
case lila.game.actorApi.StartGame(game) if game.hasClock =>
|
||||
game.userIds.some.filter(_.nonEmpty) foreach { usersPlaying =>
|
||||
online.playing putAll usersPlaying
|
||||
if (enabled()) notifyFollowersGameStateChanged(usersPlaying, "following_playing")
|
||||
}
|
||||
|
||||
case lila.hub.actorApi.study.StudyDoor(userId, studyId, contributor, public, true) =>
|
||||
online.studyingAll.put(userId, studyId)
|
||||
if (contributor && public) {
|
||||
val wasAlreadyInStudy = online isStudying userId
|
||||
online.studying.put(userId, studyId)
|
||||
if (!wasAlreadyInStudy && enabled())
|
||||
notifyFollowersFriendInStudyStateChanged(userId, "following_joined_study")
|
||||
}
|
||||
|
||||
case lila.hub.actorApi.study.StudyDoor(userId, _, contributor, public, false) =>
|
||||
online.studyingAll invalidate userId
|
||||
if (contributor && public) {
|
||||
online.studying invalidate userId
|
||||
if (enabled()) notifyFollowersFriendInStudyStateChanged(userId, "following_left_study")
|
||||
}
|
||||
|
||||
case lila.hub.actorApi.study.StudyBecamePrivate(studyId, contributors) =>
|
||||
studyBecamePrivateOrDeleted(studyId, contributors)
|
||||
|
||||
case lila.hub.actorApi.study.RemoveStudy(studyId, contributors) =>
|
||||
studyBecamePrivateOrDeleted(studyId, contributors)
|
||||
|
||||
case lila.hub.actorApi.study.StudyBecamePublic(studyId, contributors) =>
|
||||
contributorsIn(contributors, studyId) foreach { c =>
|
||||
online.studying.put(c, studyId)
|
||||
if (enabled()) notifyFollowersFriendInStudyStateChanged(c, "following_joined_study")
|
||||
}
|
||||
|
||||
case lila.hub.actorApi.study.StudyMemberGotWriteAccess(userId, studyId) =>
|
||||
if (online.isStudyingOrWatching(userId, studyId)) {
|
||||
online.studying.put(userId, studyId)
|
||||
if (enabled()) notifyFollowersFriendInStudyStateChanged(userId, "following_joined_study")
|
||||
}
|
||||
|
||||
case lila.hub.actorApi.study.StudyMemberLostWriteAccess(userId, studyId) =>
|
||||
if (online.isStudying(userId, studyId)) {
|
||||
online.studying invalidate userId
|
||||
if (enabled()) notifyFollowersFriendInStudyStateChanged(userId, "following_left_study")
|
||||
}
|
||||
}
|
||||
|
||||
private def studyBecamePrivateOrDeleted(studyId: String, contributors: Set[ID]) = {
|
||||
contributorsIn(contributors, studyId) foreach { c =>
|
||||
online.studying invalidate c
|
||||
if (enabled()) notifyFollowersFriendInStudyStateChanged(c, "following_left_study")
|
||||
}
|
||||
}
|
||||
|
||||
private def contributorsIn(contributors: Set[ID], studyId: String) = {
|
||||
val found = online.studying.getAllPresent(contributors).filter(_._2 == studyId)
|
||||
contributors filter found.contains
|
||||
}
|
||||
|
||||
private def notifyFollowersFriendEnters(
|
||||
friendsEntering: List[FriendEntering],
|
||||
onlineUserIds: Set[User.ID]
|
||||
): Funit =
|
||||
friendsEntering
|
||||
.map { entering =>
|
||||
api fetchFollowersFromSecondary entering.user.id map onlineUserIds.intersect map { ids =>
|
||||
if (ids.nonEmpty) Bus.publish(SendTos(ids, JsonView.writeFriendEntering(entering)), "socketUsers")
|
||||
}
|
||||
}
|
||||
.sequenceFu
|
||||
.void
|
||||
|
||||
private def notifyFollowersFriendLeaves(
|
||||
friendsLeaving: List[LightUser],
|
||||
onlineUserIds: Set[User.ID]
|
||||
): Funit =
|
||||
friendsLeaving
|
||||
.map { leaving =>
|
||||
api fetchFollowersFromSecondary leaving.id map onlineUserIds.intersect map { ids =>
|
||||
if (ids.nonEmpty) Bus.publish(SendTos(ids, "following_leaves", leaving.titleName), "socketUsers")
|
||||
}
|
||||
}
|
||||
.sequenceFu
|
||||
.void
|
||||
|
||||
private def notifyFollowersGameStateChanged(userIds: Iterable[ID], message: String) = {
|
||||
val onlineIds = online.userIds()
|
||||
userIds
|
||||
.map { userId =>
|
||||
api.fetchFollowersFromSecondary(userId) map onlineIds.intersect map { ids =>
|
||||
if (ids.nonEmpty) Bus.publish(SendTos(ids, message, userId), "socketUsers")
|
||||
}
|
||||
}
|
||||
.sequenceFu
|
||||
.mon(_.relation.actor.gameStateChanged)
|
||||
}
|
||||
|
||||
private def notifyFollowersFriendInStudyStateChanged(userId: ID, message: String) =
|
||||
api
|
||||
.fetchFollowersFromSecondary(userId)
|
||||
.map {
|
||||
online.userIds().intersect
|
||||
}
|
||||
.map { ids =>
|
||||
if (ids.nonEmpty) Bus.publish(SendTos(ids, message, userId), "socketUsers")
|
||||
}
|
||||
.mon(_.relation.actor.studyStateChanged)
|
||||
}
|
|
@ -17,7 +17,6 @@ import lila.user.User
|
|||
final class RelationApi(
|
||||
coll: Coll,
|
||||
repo: RelationRepo,
|
||||
actor: actors.Relation,
|
||||
timeline: actors.Timeline,
|
||||
prefApi: lila.pref.PrefApi,
|
||||
cacheApi: lila.memo.CacheApi,
|
||||
|
@ -144,7 +143,6 @@ final class RelationApi(
|
|||
repo.follow(u1, u2) >> limitFollow(u1) >>- {
|
||||
countFollowersCache.update(u2, 1 +)
|
||||
countFollowingCache.update(u1, prev => (prev + 1) atMost config.maxFollow.value)
|
||||
reloadOnlineFriends(u1, u2)
|
||||
timeline ! Propagate(FollowUser(u1, u2)).toFriendsOf(u1).toUsers(List(u2))
|
||||
Bus.publish(lila.hub.actorApi.relation.Follow(u1, u2), "relation")
|
||||
lila.mon.relation.follow.increment()
|
||||
|
@ -181,7 +179,6 @@ final class RelationApi(
|
|||
case true => funit
|
||||
case _ =>
|
||||
repo.block(u1, u2) >> limitBlock(u1) >> unfollow(u2, u1) >>- {
|
||||
reloadOnlineFriends(u1, u2)
|
||||
Bus.publish(lila.hub.actorApi.relation.Block(u1, u2), "relation")
|
||||
Bus.publish(
|
||||
lila.hub.actorApi.socket.SendTo(u2, lila.socket.Socket.makeMessage("blockedBy", u1)),
|
||||
|
@ -198,7 +195,7 @@ final class RelationApi(
|
|||
repo.unfollow(u1, u2) >>- {
|
||||
countFollowersCache.update(u2, _ - 1)
|
||||
countFollowingCache.update(u1, _ - 1)
|
||||
reloadOnlineFriends(u1, u2)
|
||||
Bus.publish(lila.hub.actorApi.relation.UnFollow(u1, u2), "relation")
|
||||
lila.mon.relation.unfollow.increment()
|
||||
}
|
||||
case _ => funit
|
||||
|
@ -211,7 +208,6 @@ final class RelationApi(
|
|||
fetchBlocks(u1, u2) flatMap {
|
||||
case true =>
|
||||
repo.unblock(u1, u2) >>- {
|
||||
reloadOnlineFriends(u1, u2)
|
||||
Bus.publish(lila.hub.actorApi.relation.UnBlock(u1, u2), "relation")
|
||||
Bus.publish(
|
||||
lila.hub.actorApi.socket.SendTo(u2, lila.socket.Socket.makeMessage("unblockedBy", u1)),
|
||||
|
@ -225,9 +221,4 @@ final class RelationApi(
|
|||
|
||||
def searchFollowedBy(u: User, term: String, max: Int): Fu[List[User.ID]] =
|
||||
repo.followingLike(u.id, term) map { _.sorted take max }
|
||||
|
||||
private def reloadOnlineFriends(u1: ID, u2: ID): Unit = {
|
||||
import lila.hub.actorApi.relation.ReloadOnlineFriends
|
||||
List(u1, u2).foreach(actor ! ReloadOnlineFriends(_))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,6 @@ package actorApi
|
|||
|
||||
import lila.common.LightUser
|
||||
|
||||
private[relation] case class AllOnlineFriends(onlines: Map[ID, LightUser])
|
||||
private[relation] case object ComputeMovement
|
||||
|
||||
case class OnlineFriends(users: List[LightUser], playing: Set[String], studying: Set[String]) {
|
||||
def isEmpty = users.isEmpty
|
||||
def patrons: List[String] = users collect {
|
||||
|
|
|
@ -12,11 +12,11 @@ import scala.concurrent.duration._
|
|||
|
||||
import lila.common.{ Bus, Lilakka }
|
||||
import lila.hub.actorApi.Announce
|
||||
import lila.hub.actorApi.relation.ReloadOnlineFriends
|
||||
import lila.hub.actorApi.round.Mlat
|
||||
import lila.hub.actorApi.security.CloseAccount
|
||||
import lila.hub.actorApi.socket.remote.{ TellSriIn, TellSriOut, TellUserIn }
|
||||
import lila.hub.actorApi.socket.{ BotIsOnline, SendTo, SendTos }
|
||||
import lila.hub.actorApi.relation.{ Follow, UnFollow }
|
||||
import Socket.Sri
|
||||
|
||||
final class RemoteSocket(
|
||||
|
@ -49,10 +49,6 @@ final class RemoteSocket(
|
|||
case In.DisconnectUsers(userIds) =>
|
||||
onlineUserIds.getAndUpdate((x: UserIds) => x -- userIds)
|
||||
case In.NotifiedBatch(userIds) => notification ! lila.hub.actorApi.notify.NotifiedBatch(userIds)
|
||||
case In.FriendsBatch(userIds) =>
|
||||
userIds foreach { userId =>
|
||||
Bus.publish(ReloadOnlineFriends(userId), "reloadOnlineFriends")
|
||||
}
|
||||
case In.Lags(lags) =>
|
||||
lags foreach (UserLagCache.put _).tupled
|
||||
// this shouldn't be necessary... ensure that users are known to be online
|
||||
|
@ -80,7 +76,8 @@ final class RemoteSocket(
|
|||
"accountClose",
|
||||
"shadowban",
|
||||
"impersonate",
|
||||
"botIsOnline"
|
||||
"botIsOnline",
|
||||
"relation"
|
||||
) {
|
||||
case SendTos(userIds, payload) =>
|
||||
val connectedUsers = userIds intersect onlineUserIds.get
|
||||
|
@ -103,6 +100,8 @@ final class RemoteSocket(
|
|||
send(Out.impersonate(userId, modId))
|
||||
case BotIsOnline(userId, value) =>
|
||||
onlineUserIds.getAndUpdate((x: UserIds) => { if (value) x + userId else x - userId })
|
||||
case Follow(u1, u2) => send(Out.follow(u1, u2))
|
||||
case UnFollow(u1, u2) => send(Out.unfollow(u1, u2))
|
||||
}
|
||||
|
||||
final class StoppableSender(conn: StatefulRedisPubSubConnection[String, String], channel: Channel)
|
||||
|
@ -182,7 +181,6 @@ object RemoteSocket {
|
|||
case class NotifiedBatch(userIds: Iterable[String]) extends In
|
||||
case class Lag(userId: String, lag: Centis) extends In
|
||||
case class Lags(lags: Map[String, Centis]) extends In
|
||||
case class FriendsBatch(userIds: Iterable[String]) extends In
|
||||
case class TellSri(sri: Sri, userId: Option[String], typ: String, msg: JsObject) extends In
|
||||
case class TellUser(userId: String, typ: String, msg: JsObject) extends In
|
||||
case class ReqResponse(reqId: Int, response: String) extends In
|
||||
|
@ -213,8 +211,7 @@ object RemoteSocket {
|
|||
case _ => None
|
||||
}
|
||||
}.toMap).some
|
||||
case "friends/batch" => FriendsBatch(commas(raw.args)).some
|
||||
case "tell/sri" => raw.get(3)(tellSriMapper)
|
||||
case "tell/sri" => raw.get(3)(tellSriMapper)
|
||||
case "tell/user" =>
|
||||
raw.get(2) {
|
||||
case Array(user, payload) =>
|
||||
|
@ -265,8 +262,10 @@ object RemoteSocket {
|
|||
s"mod/troll/set $userId ${boolean(v)}"
|
||||
def impersonate(userId: String, by: Option[String]) =
|
||||
s"mod/impersonate $userId ${optional(by)}"
|
||||
def boot = "boot"
|
||||
def stop(reqId: Int) = s"lila/stop $reqId"
|
||||
def follow(u1: String, u2: String) = s"rel/follow $u1 $u2"
|
||||
def unfollow(u1: String, u2: String) = s"rel/unfollow $u1 $u2"
|
||||
def boot = "boot"
|
||||
def stop(reqId: Int) = s"lila/stop $reqId"
|
||||
|
||||
def commas(strs: Iterable[Any]): String = if (strs.isEmpty) "-" else strs mkString ","
|
||||
def boolean(v: Boolean): String = if (v) "+" else "-"
|
||||
|
|
|
@ -729,7 +729,13 @@
|
|||
|
||||
self.$nobody = el.find(".nobody");
|
||||
|
||||
const data = el.data('preload');
|
||||
const data = {
|
||||
users: [],
|
||||
playing: [],
|
||||
patrons: [],
|
||||
studying: [],
|
||||
... el.data('preload')
|
||||
};
|
||||
self.trans = lichess.trans(data.i18n);
|
||||
self.set(data);
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue