Skip to content

Commit

Permalink
update friends box
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed May 24, 2013
1 parent c5a6128 commit 2fc42d8
Show file tree
Hide file tree
Showing 23 changed files with 88 additions and 76 deletions.
2 changes: 1 addition & 1 deletion app/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object Global extends GlobalSettings {
}
else {
Env.monitor.reporting ! AddRequest
Env.security.wiretap(req.pp)
Env.security.wiretap(req)
Env.security.firewall.requestHandler(req).await orElse
Env.i18n.requestHandler(req) orElse
super.onRouteRequest(req)
Expand Down
14 changes: 7 additions & 7 deletions app/controllers/Relation.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package controllers

import play.api.mvc._
import play.api.templates.Html

import lila.app._
import lila.user.{ User UserModel, UserRepo, Context }
import views._

import play.api.mvc._
import play.api.templates.Html

object Relation extends LilaController {

private def env = Env.relation
Expand Down Expand Up @@ -35,16 +35,16 @@ object Relation extends LilaController {

def following(userId: String) = Open { implicit ctx
OptionFuOk(UserRepo named userId) { user
env.api.following(user.id) map { userIds
html.relation.following(user, userIds.toList.sorted)
env.api.following(user.id) flatMap UserRepo.byIds map { users
html.relation.following(user, users.sorted)
}
}
}

def followers(userId: String) = Open { implicit ctx
OptionFuOk(UserRepo named userId) { user
env.api.followers(user.id) map { userIds
html.relation.followers(user, userIds.toList.sorted)
env.api.followers(user.id) flatMap UserRepo.byIds map { users
html.relation.followers(user, users.sorted)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions app/templating/DateHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ trait DateHelper { self: I18nHelper ⇒
def timeagoLocale(implicit ctx: Context): Option[String] =
lang(ctx).language match {
case "en" none
case "fr" "fr-short".some
case "pt" "pt-br".some
case "zh" "zh-CN".some
case l timeagoLocales(l) option l
Expand Down
2 changes: 1 addition & 1 deletion app/templating/UserHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ trait UserHelper { self: I18nHelper with StringHelper ⇒

def userGameFilterTitle(info: UserInfo, filter: GameFilter)(implicit ctx: Context) = Html((filter match {
case GameFilter.All info.user.nbGames + " " + trans.gamesPlayed()
case GameFilter.Me ctx.me.fold("-")(me "%d vs me" format ~info.nbWithMe)
case GameFilter.Me ctx.me.fold("-")(me trans.nbGamesWithYou(~info.nbWithMe).body)
case GameFilter.Rated info.nbRated + " " + trans.rated()
case GameFilter.Win trans.nbWins(info.user.nbWins)
case GameFilter.Loss trans.nbLosses(info.user.nbLosses)
Expand Down
8 changes: 4 additions & 4 deletions app/views/relation/followers.scala.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@(u: User, userIds: List[String])(implicit ctx: Context)
@(u: User, users: List[User])(implicit ctx: Context)

@user.layout(title = u.username + " - " + trans.nbFollowers(userIds.size)) {
@user.layout(title = u.username + " - " + trans.nbFollowers(users.size)) {
<div class="content_box no_padding">
<h1>@userLink(u, withOnline = false) @trans.nbFollowers(userIds.size)</h1>
@relation.userTable(userIds)
<h1>@userLink(u, withOnline = false) @trans.nbFollowers(users.size)</h1>
@user.simpleTable(users)
</div>
}
8 changes: 4 additions & 4 deletions app/views/relation/following.scala.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@(u: User, userIds: List[String])(implicit ctx: Context)
@(u: User, users: List[User])(implicit ctx: Context)

@user.layout(title = u.username + " - " + trans.nbFollowing(userIds.size)) {
@user.layout(title = u.username + " - " + trans.nbFollowing(users.size)) {
<div class="content_box no_padding">
<h1>@userLink(u, withOnline = false) @trans.nbFollowing(userIds.size)</h1>
@relation.userTable(userIds)
<h1>@userLink(u, withOnline = false) @trans.nbFollowing(users.size)</h1>
@user.simpleTable(users)
</div>
}
18 changes: 0 additions & 18 deletions app/views/relation/userTable.scala.html

This file was deleted.

7 changes: 4 additions & 3 deletions app/views/user/opponents.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
<h1>@userLink(u, withOnline = false) @trans.favoriteOpponents()</h1>
<table class="slist best_opponents">
@if(sugs.size > 0) {
<tbody class="infinitescroll">
<tbody>
@sugs.map { sug =>
<tr>
<td>@userLink(sug._1)</td>
<td>@sug._1.elo ELO</td>
<td>
<a href="@routes.Game.search()[email protected]&players.b=@sug._1.username">
@sug._2 @trans.games()
@trans.nbGamesWithYou(sug._2)
</a>
</td>
<td>@relation.actions(sug._1.id)</td>
<td><div class="relation_actions">@relation.actions(sug._1.id)</div></td>
</tr>
}
</tbody>
Expand Down
20 changes: 20 additions & 0 deletions app/views/user/simpleTable.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@(users: List[User])(implicit ctx: Context)

<table class="slist">
@if(users.size > 0) {
<tbody class="infinitescroll">
@users.map { u =>
<tr>
<td>@userLink(u)</td>
<td>@u.elo ELO</td>
<td>@u.nbGames @trans.games()</td>
<td><div class="relation_actions">@relation.actions(u.id)</div></td>
</tr>
}
</tbody>
} else {
<tbody>
<tr><td colspan="2">None found.<br /></td></tr>
</tbody>
}
</table>
1 change: 1 addition & 0 deletions conf/messages
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ allYouNeedIsAUsernameAndAPassword=All you need is a username and a password.
learnMoreAboutLichess=Learn more about Lichess
rank=Rank
gamesPlayed=Games played
nbGamesWithYou=%s games with you
declineInvitation=Decline invitation
cancel=Cancel
timeOut=Time out
Expand Down
3 changes: 1 addition & 2 deletions modules/hub/src/main/actorApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,5 @@ package bookmark {
}

package relation {
case class GetFriends(userId: String)
case class FriendsOf(userId: String, friends: List[String])
case class ReloadFriends(userId: String)
}
9 changes: 5 additions & 4 deletions modules/i18n/src/main/I18nKeys.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Generated with bin/trans-dump
package lila.i18n

import play.api.i18n.Lang
import play.api.templates.Html

import lila.user.Context

import play.api.templates.Html
import play.api.i18n.Lang

final class I18nKeys(translator: Translator) {

final class Key(val key: String) extends I18nKey {
Expand Down Expand Up @@ -115,6 +115,7 @@ final class I18nKeys(translator: Translator) {
val learnMoreAboutLichess = new Key("learnMoreAboutLichess")
val rank = new Key("rank")
val gamesPlayed = new Key("gamesPlayed")
val nbGamesWithYou = new Key("nbGamesWithYou")
val declineInvitation = new Key("declineInvitation")
val cancel = new Key("cancel")
val timeOut = new Key("timeOut")
Expand Down Expand Up @@ -232,5 +233,5 @@ final class I18nKeys(translator: Translator) {
val nbFollowers = new Key("nbFollowers")
val nbFollowing = new Key("nbFollowing")

def keys = List(playWithAFriend, inviteAFriendToPlayWithYou, playWithTheMachine, challengeTheArtificialIntelligence, toInviteSomeoneToPlayGiveThisUrl, gameOver, waitingForOpponent, waiting, yourTurn, aiNameLevelAiLevel, level, toggleTheChat, toggleSound, chat, resign, checkmate, stalemate, white, black, createAGame, noGameAvailableRightNowCreateOne, whiteIsVictorious, blackIsVictorious, playWithTheSameOpponentAgain, newOpponent, playWithAnotherOpponent, yourOpponentWantsToPlayANewGameWithYou, joinTheGame, whitePlays, blackPlays, theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim, makeYourOpponentResign, forceResignation, talkInChat, theFirstPersonToComeOnThisUrlWillPlayWithYou, whiteCreatesTheGame, blackCreatesTheGame, whiteJoinsTheGame, blackJoinsTheGame, whiteResigned, blackResigned, whiteLeftTheGame, blackLeftTheGame, shareThisUrlToLetSpectatorsSeeTheGame, youAreViewingThisGameAsASpectator, replayAndAnalyse, computerAnalysisInProgress, theComputerAnalysisYouRequestedIsNowAvailable, theComputerAnalysisHasFailed, viewTheComputerAnalysis, requestAComputerAnalysis, blunders, mistakes, inaccuracies, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, newToLichess, youNeedAUsernameToDoThat, signUp, people, games, forum, searchInForum, xPostedInForumY, chessPlayers, minutesPerSide, variant, timeControl, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, noMessageHereYet, subject, recipient, send, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, searchAPlayer, whoIsOnline, allPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, advancedSearch, tournament, tournamentPoints, viewTournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents, teams, nbMembers, allTeams, newTeam, myTeams, noTeamFound, joinTeam, quitTeam, anyoneCanJoin, aConfirmationIsRequiredToJoin, joiningPolicy, teamLeader, teamBestPlayers, teamRecentMembers, searchATeam, xJoinedTeamY, xCreatedTeamY, averageElo, location, settings, filterGames, reset, apply, leaderboard, pasteTheFenStringHere, pasteThePgnStringHere, fromPosition, continueFromHere, importGame, nbImportedGames, thisIsAChessCaptcha, clickOnTheBoardToMakeYourMove, notACheckmate, colorPlaysCheckmateInOne, retry, reconnecting, friends, noFriendsOnline, findFriends, favoriteOpponents, follow, following, unfollow, block, blocked, unblock, followsYou, xStartedFollowingY, nbFollowers, nbFollowing)
def keys = List(playWithAFriend, inviteAFriendToPlayWithYou, playWithTheMachine, challengeTheArtificialIntelligence, toInviteSomeoneToPlayGiveThisUrl, gameOver, waitingForOpponent, waiting, yourTurn, aiNameLevelAiLevel, level, toggleTheChat, toggleSound, chat, resign, checkmate, stalemate, white, black, createAGame, noGameAvailableRightNowCreateOne, whiteIsVictorious, blackIsVictorious, playWithTheSameOpponentAgain, newOpponent, playWithAnotherOpponent, yourOpponentWantsToPlayANewGameWithYou, joinTheGame, whitePlays, blackPlays, theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim, makeYourOpponentResign, forceResignation, talkInChat, theFirstPersonToComeOnThisUrlWillPlayWithYou, whiteCreatesTheGame, blackCreatesTheGame, whiteJoinsTheGame, blackJoinsTheGame, whiteResigned, blackResigned, whiteLeftTheGame, blackLeftTheGame, shareThisUrlToLetSpectatorsSeeTheGame, youAreViewingThisGameAsASpectator, replayAndAnalyse, computerAnalysisInProgress, theComputerAnalysisYouRequestedIsNowAvailable, theComputerAnalysisHasFailed, viewTheComputerAnalysis, requestAComputerAnalysis, blunders, mistakes, inaccuracies, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, newToLichess, youNeedAUsernameToDoThat, signUp, people, games, forum, searchInForum, xPostedInForumY, chessPlayers, minutesPerSide, variant, timeControl, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, nbGamesWithYou, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, noMessageHereYet, subject, recipient, send, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, searchAPlayer, whoIsOnline, allPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, advancedSearch, tournament, tournamentPoints, viewTournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents, teams, nbMembers, allTeams, newTeam, myTeams, noTeamFound, joinTeam, quitTeam, anyoneCanJoin, aConfirmationIsRequiredToJoin, joiningPolicy, teamLeader, teamBestPlayers, teamRecentMembers, searchATeam, xJoinedTeamY, xCreatedTeamY, averageElo, location, settings, filterGames, reset, apply, leaderboard, pasteTheFenStringHere, pasteThePgnStringHere, fromPosition, continueFromHere, importGame, nbImportedGames, thisIsAChessCaptcha, clickOnTheBoardToMakeYourMove, notACheckmate, colorPlaysCheckmateInOne, retry, reconnecting, friends, noFriendsOnline, findFriends, favoriteOpponents, follow, following, unfollow, block, blocked, unblock, followsYou, xStartedFollowingY, nbFollowers, nbFollowing)
}
2 changes: 1 addition & 1 deletion modules/relation/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class Env(

lazy val api = new RelationApi(
cached = cached,
timelinePush = hub.actor.timeline,
actor = hub.actor.relation,
timeline = hub.actor.timeline)

private lazy val cached = new Cached
Expand Down
19 changes: 10 additions & 9 deletions modules/relation/src/main/RelationActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@ import akka.pattern.{ ask, pipe }

import actorApi._
import lila.hub.actorApi.relation._
import lila.hub.actorApi.SendTos
import lila.hub.actorApi.{ SendTo, SendTos }
import lila.hub.ActorLazyRef
import makeTimeout.short

private[relation] final class RelationActor(
socketHub: ActorLazyRef,
getOnlineUserIds: () Set[String],
getUsername: String Fu[String],
getFriendIds: String Fu[Set[String]]) extends Actor {

private type ID = String
private type Username = String
private type User = (ID, Username)

def receive = {

// sends back a list of usernames, followers, following and online
case GetFriends(userId) getFriendIds(userId) flatMap { ids
// triggers friends reloading for this user id
case ReloadFriends(userId) getFriendIds(userId) flatMap { ids
((ids intersect onlineIds).toList map getUsername).sequenceFu
} pipeTo sender
} map { SendTo(userId, "friends", _) } pipeTo socketHub.ref

case NotifyMovement {
val prevIds = onlineIds
Expand All @@ -42,16 +47,12 @@ private[relation] final class RelationActor(
}
}

private type ID = String
private type Username = String
private type User = (ID, Username)

private var onlines = Map[ID, Username]()
private def onlineIds: Set[ID] = onlines.keySet

private def notifyFriends(users: List[User], message: String) {
users foreach {
case (id, name) getFriendIds(id.pp).thenPp foreach { ids
case (id, name) getFriendIds(id) foreach { ids
val notify = ids filter onlines.contains
if (notify.nonEmpty) socketHub ! SendTos(notify.toSet, message, name)
}
Expand Down
16 changes: 11 additions & 5 deletions modules/relation/src/main/RelationApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package lila.relation
import lila.db.api._
import lila.db.Implicits._
import lila.game.GameRepo
import lila.hub.actorApi.relation.ReloadFriends
import lila.hub.actorApi.timeline.{ Propagate, Follow FollowUser }
import lila.hub.ActorLazyRef
import lila.user.tube.userTube
Expand All @@ -11,7 +12,7 @@ import tube.relationTube

final class RelationApi(
cached: Cached,
timelinePush: ActorLazyRef,
actor: ActorLazyRef,
timeline: ActorLazyRef) {

def followers(userId: ID) = cached followers userId
Expand All @@ -23,6 +24,7 @@ final class RelationApi(
def nbFollowing(userId: ID) = following(userId) map (_.size)

def friends(userId: ID) = cached friends userId
def areFriends(u1: ID, u2: ID) = friends(u1) map (_ contains u2)

def follows(u1: ID, u2: ID) = following(u1) map (_ contains u2)
def blocks(u1: ID, u2: ID) = blocking(u1) map (_ contains u2)
Expand All @@ -34,7 +36,7 @@ final class RelationApi(
else relation(u1, u2) flatMap {
case Some(Follow) fufail("Already following")
case _ RelationRepo.follow(u1, u2) >>
cached.invalidate(u1, u2) >>-
refresh(u1, u2) >>-
(timeline ! Propagate(
FollowUser(u1, u2)
).toFriendsOf(u1).toUsers(List(u2)))
Expand All @@ -44,20 +46,24 @@ final class RelationApi(
if (u1 == u2) fufail("Cannot block yourself")
else relation(u1, u2) flatMap {
case Some(Block) fufail("Already blocking")
case _ RelationRepo.block(u1, u2) >> cached.invalidate(u1, u2)
case _ RelationRepo.block(u1, u2) >> refresh(u1, u2)
}

def unfollow(u1: ID, u2: ID): Funit =
if (u1 == u2) fufail("Cannot unfollow yourself")
else relation(u1, u2) flatMap {
case Some(Follow) RelationRepo.unfollow(u1, u2) >> cached.invalidate(u1, u2)
case Some(Follow) RelationRepo.unfollow(u1, u2) >> refresh(u1, u2)
case _ fufail("Not following")
}

def unblock(u1: ID, u2: ID): Funit =
if (u1 == u2) fufail("Cannot unblock yourself")
else relation(u1, u2) flatMap {
case Some(Block) RelationRepo.unblock(u1, u2) >> cached.invalidate(u1, u2)
case Some(Block) RelationRepo.unblock(u1, u2) >> refresh(u1, u2)
case _ fufail("Not blocking")
}

private def refresh(u1: ID, u2: ID): Funit =
cached.invalidate(u1, u2) >>-
List(u1, u2).foreach(actor ! ReloadFriends(_))
}
6 changes: 2 additions & 4 deletions modules/socket/src/main/Handler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import play.api.libs.json._

import actorApi._
import lila.common.PimpedJson._
import lila.hub.actorApi.relation.{ GetFriends, FriendsOf }
import lila.hub.actorApi.relation.ReloadFriends
import makeTimeout.large

object Handler {
Expand All @@ -25,9 +25,7 @@ object Handler {
val baseController: Controller = {
case ("p", _) socket ! Ping(uid)
case ("friends", _) userId foreach { u
hub.actor.relation ? GetFriends(u) mapTo manifest[List[String]] map { friends
FriendsOf(uid, friends)
} pipeTo socket
hub.actor.relation ! ReloadFriends(u)
}
case msg logwarn("Unhandled msg: " + msg)
}
Expand Down
3 changes: 0 additions & 3 deletions modules/socket/src/main/SocketActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import akka.actor._
import play.api.libs.json._

import actorApi._
import lila.hub.actorApi.relation.FriendsOf
import lila.hub.actorApi.{ GetUids, WithUserIds, GetNbMembers, NbMembers, SendTo, SendTos }
import lila.memo.ExpireSetMemo

Expand Down Expand Up @@ -46,8 +45,6 @@ abstract class SocketActor[M <: SocketMember](uidTtl: Duration) extends Actor {

case SendTos(userIds, msg) sendTos(userIds, msg)

case FriendsOf(uid, friends) withMember(uid)(notifyMember("friends", friends))

case Resync(uid) resync(uid)
}

Expand Down
4 changes: 3 additions & 1 deletion modules/timeline/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ final class Env(
config: Config,
db: lila.db.Env,
hub: lila.hub.Env,
getFriendIds: String => Fu[Set[String]],
getUsername: String Fu[String],
lobbySocket: lila.hub.ActorLazyRef,
renderer: lila.hub.ActorLazyRef,
Expand All @@ -32,7 +33,7 @@ final class Env(
system.actorOf(Props(new Push(
lobbySocket = lobbySocket,
renderer = renderer,
relationActor = hub.actor.relation
getFriendIds = getFriendIds
)), name = UserActorName)

private[timeline] lazy val gameEntryColl = db(GameCollectionEntry)
Expand All @@ -46,6 +47,7 @@ object Env {
config = lila.common.PlayApp loadConfig "timeline",
db = lila.db.Env.current,
hub = lila.hub.Env.current,
getFriendIds = lila.relation.Env.current.api.friends _,
getUsername = lila.user.Env.current.usernameOrAnonymous _,
lobbySocket = lila.hub.Env.current.socket.lobby,
renderer = lila.hub.Env.current.actor.renderer,
Expand Down
Loading

0 comments on commit 2fc42d8

Please sign in to comment.