2014-03-02 15:43:21 -05:00
|
|
|
CocoView = require 'views/kinds/CocoView'
|
|
|
|
Level = require 'models/Level'
|
|
|
|
LevelSession = require 'models/LevelSession'
|
|
|
|
CocoCollection = require 'models/CocoCollection'
|
|
|
|
LeaderboardCollection = require 'collections/LeaderboardCollection'
|
|
|
|
{teamDataFromLevel} = require './utils'
|
|
|
|
|
|
|
|
HIGHEST_SCORE = 1000000
|
|
|
|
|
|
|
|
class LevelSessionsCollection extends CocoCollection
|
|
|
|
url: ''
|
|
|
|
model: LevelSession
|
|
|
|
|
|
|
|
constructor: (levelID) ->
|
|
|
|
super()
|
|
|
|
@url = "/db/level/#{levelID}/all_sessions"
|
|
|
|
|
2014-03-03 16:21:05 -05:00
|
|
|
module.exports = class LadderTabView extends CocoView
|
2014-03-02 15:43:21 -05:00
|
|
|
id: 'ladder-tab-view'
|
|
|
|
template: require 'templates/play/ladder/ladder_tab'
|
|
|
|
startsLoading: true
|
2014-03-23 19:48:30 -04:00
|
|
|
|
2014-03-21 22:50:54 -04:00
|
|
|
events:
|
2014-03-22 00:11:51 -04:00
|
|
|
'click .connect-facebook': 'onConnectFacebook'
|
2014-03-26 17:19:05 -04:00
|
|
|
'click .connect-google-plus': 'onConnectGPlus'
|
2014-03-23 19:48:30 -04:00
|
|
|
|
2014-03-21 22:50:54 -04:00
|
|
|
subscriptions:
|
2014-03-26 16:50:01 -04:00
|
|
|
'fbapi-loaded': 'checkFriends'
|
|
|
|
'gapi-loaded': 'checkFriends'
|
2014-03-22 00:11:51 -04:00
|
|
|
'facebook-logged-in': 'onConnectedWithFacebook'
|
2014-03-26 17:19:05 -04:00
|
|
|
'gplus-logged-in': 'onConnectedWithGPlus'
|
2014-03-02 15:43:21 -05:00
|
|
|
|
|
|
|
constructor: (options, @level, @sessions) ->
|
|
|
|
super(options)
|
|
|
|
@teams = teamDataFromLevel @level
|
|
|
|
@leaderboards = {}
|
2014-03-03 15:21:59 -05:00
|
|
|
@refreshLadder()
|
2014-03-26 17:53:09 -04:00
|
|
|
@checkFriends()
|
2014-03-22 12:48:36 -04:00
|
|
|
|
2014-03-21 22:50:54 -04:00
|
|
|
checkFriends: ->
|
2014-03-26 17:53:09 -04:00
|
|
|
return if @checked or (not window.FB) or (not window.gapi)
|
2014-03-26 16:50:01 -04:00
|
|
|
@checked = true
|
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
@loadingFacebookFriends = true
|
2014-03-21 22:50:54 -04:00
|
|
|
FB.getLoginStatus (response) =>
|
|
|
|
@facebookStatus = response.status
|
2014-03-23 12:30:01 -04:00
|
|
|
if @facebookStatus is 'connected' then @loadFacebookFriendSessions() else @loadingFacebookFriends = false
|
|
|
|
|
|
|
|
if application.gplusHandler.loggedIn is undefined
|
|
|
|
@loadingGPlusFriends = true
|
|
|
|
@listenToOnce(application.gplusHandler, 'checked-state', @gplusSessionStateLoaded)
|
|
|
|
else
|
|
|
|
@gplusSessionStateLoaded()
|
2014-03-21 22:50:54 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
# FACEBOOK
|
|
|
|
|
|
|
|
onConnectFacebook: ->
|
|
|
|
@connecting = true
|
|
|
|
FB.login()
|
2014-03-23 19:48:30 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
onConnectedWithFacebook: -> location.reload() if @connecting
|
2014-03-23 19:48:30 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
loadFacebookFriendSessions: ->
|
2014-03-21 22:50:54 -04:00
|
|
|
FB.api '/me/friends', (response) =>
|
|
|
|
@facebookData = response.data
|
|
|
|
levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
|
2014-03-23 12:30:01 -04:00
|
|
|
url = "/db/level/#{levelFrag}/leaderboard_facebook_friends"
|
2014-03-21 22:50:54 -04:00
|
|
|
$.ajax url, {
|
|
|
|
data: { friendIDs: (f.id for f in @facebookData) }
|
|
|
|
method: 'POST'
|
2014-03-23 12:30:01 -04:00
|
|
|
success: @onFacebookFriendSessionsLoaded
|
2014-03-21 22:50:54 -04:00
|
|
|
}
|
2014-03-22 12:48:36 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
onFacebookFriendSessionsLoaded: (result) =>
|
2014-03-21 22:50:54 -04:00
|
|
|
friendsMap = {}
|
|
|
|
friendsMap[friend.id] = friend.name for friend in @facebookData
|
|
|
|
for friend in result
|
2014-03-26 16:50:01 -04:00
|
|
|
friend.name = friendsMap[friend.facebookID]
|
2014-03-21 22:50:54 -04:00
|
|
|
friend.otherTeam = if friend.team is 'humans' then 'ogres' else 'humans'
|
2014-03-26 16:50:01 -04:00
|
|
|
friend.imageSource = "http://graph.facebook.com/#{friend.facebookID}/picture"
|
|
|
|
@facebookFriendSessions = result
|
2014-03-23 12:30:01 -04:00
|
|
|
@loadingFacebookFriends = false
|
|
|
|
@renderMaybe()
|
|
|
|
|
|
|
|
# GOOGLE PLUS
|
|
|
|
|
2014-03-26 17:19:05 -04:00
|
|
|
onConnectGPlus: ->
|
|
|
|
@connecting = true
|
|
|
|
@listenToOnce application.gplusHandler, 'logged-in', @onConnectedWithGPlus
|
|
|
|
application.gplusHandler.reauthorize()
|
|
|
|
|
|
|
|
onConnectedWithGPlus: -> location.reload() if @connecting
|
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
gplusSessionStateLoaded: ->
|
|
|
|
if application.gplusHandler.loggedIn
|
|
|
|
@loadingGPlusFriends = true
|
|
|
|
application.gplusHandler.loadFriends @gplusFriendsLoaded
|
|
|
|
else
|
|
|
|
@loadingGPlusFriends = false
|
|
|
|
@renderMaybe()
|
|
|
|
|
|
|
|
gplusFriendsLoaded: (friends) =>
|
|
|
|
@gplusData = friends.items
|
|
|
|
levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
|
|
|
|
url = "/db/level/#{levelFrag}/leaderboard_gplus_friends"
|
|
|
|
$.ajax url, {
|
|
|
|
data: { friendIDs: (f.id for f in @gplusData) }
|
|
|
|
method: 'POST'
|
|
|
|
success: @onGPlusFriendSessionsLoaded
|
|
|
|
}
|
|
|
|
|
|
|
|
onGPlusFriendSessionsLoaded: (result) =>
|
2014-03-26 16:50:01 -04:00
|
|
|
friendsMap = {}
|
|
|
|
friendsMap[friend.id] = friend for friend in @gplusData
|
|
|
|
for friend in result
|
|
|
|
friend.name = friendsMap[friend.gplusID].displayName
|
|
|
|
friend.otherTeam = if friend.team is 'humans' then 'ogres' else 'humans'
|
|
|
|
friend.imageSource = friendsMap[friend.gplusID].image.url
|
|
|
|
@gplusFriendSessions = result
|
2014-03-23 12:30:01 -04:00
|
|
|
@loadingGPlusFriends = false
|
2014-03-21 22:50:54 -04:00
|
|
|
@renderMaybe()
|
2014-03-26 16:50:01 -04:00
|
|
|
|
2014-03-23 12:30:01 -04:00
|
|
|
# LADDER LOADING
|
2014-03-03 15:21:59 -05:00
|
|
|
|
|
|
|
refreshLadder: ->
|
2014-03-21 22:50:54 -04:00
|
|
|
promises = []
|
2014-03-02 15:43:21 -05:00
|
|
|
for team in @teams
|
2014-03-03 15:21:59 -05:00
|
|
|
@leaderboards[team.id]?.off 'sync'
|
2014-03-20 17:40:17 -04:00
|
|
|
teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
|
2014-03-02 15:43:21 -05:00
|
|
|
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession)
|
2014-03-21 22:50:54 -04:00
|
|
|
promises.push @leaderboards[team.id].promise
|
|
|
|
@loadingLeaderboards = true
|
|
|
|
$.when(promises...).then(@leaderboardsLoaded)
|
2014-03-02 15:43:21 -05:00
|
|
|
|
2014-03-21 22:50:54 -04:00
|
|
|
leaderboardsLoaded: =>
|
|
|
|
@loadingLeaderboards = false
|
|
|
|
@renderMaybe()
|
2014-03-23 19:48:30 -04:00
|
|
|
|
2014-03-02 15:43:21 -05:00
|
|
|
renderMaybe: ->
|
2014-03-26 16:50:01 -04:00
|
|
|
return if @loadingFacebookFriends or @loadingLeaderboards or @loadingGPlusFriends
|
2014-03-02 15:43:21 -05:00
|
|
|
@startsLoading = false
|
|
|
|
@render()
|
|
|
|
|
|
|
|
getRenderData: ->
|
|
|
|
ctx = super()
|
|
|
|
ctx.level = @level
|
|
|
|
ctx.link = "/play/level/#{@level.get('name')}"
|
|
|
|
ctx.teams = @teams
|
|
|
|
team.leaderboard = @leaderboards[team.id] for team in @teams
|
|
|
|
ctx.levelID = @levelID
|
2014-03-26 16:50:01 -04:00
|
|
|
ctx.friends = @consolidateFriends()
|
2014-03-21 22:50:54 -04:00
|
|
|
ctx.onFacebook = @facebookStatus is 'connected'
|
2014-03-23 12:30:01 -04:00
|
|
|
ctx.onGPlus = application.gplusHandler.loggedIn
|
2014-03-02 15:43:21 -05:00
|
|
|
ctx
|
2014-03-03 15:21:59 -05:00
|
|
|
|
2014-03-26 16:50:01 -04:00
|
|
|
consolidateFriends: ->
|
|
|
|
allFriendSessions = (@facebookFriendSessions or []).concat(@gplusFriendSessions or [])
|
2014-03-26 17:22:04 -04:00
|
|
|
sessions = _.uniq allFriendSessions, false, (session) -> session._id
|
|
|
|
sessions = _.sortBy sessions, 'totalScore'
|
|
|
|
sessions.reverse()
|
|
|
|
sessions
|
2014-03-26 16:50:01 -04:00
|
|
|
|
2014-03-02 15:43:21 -05:00
|
|
|
class LeaderboardData
|
|
|
|
constructor: (@level, @team, @session) ->
|
|
|
|
_.extend @, Backbone.Events
|
2014-03-20 17:40:17 -04:00
|
|
|
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: 20})
|
|
|
|
promises = []
|
|
|
|
promises.push @topPlayers.fetch()
|
2014-03-02 15:43:21 -05:00
|
|
|
|
2014-03-20 17:40:17 -04:00
|
|
|
if @session
|
|
|
|
score = @session.get('totalScore') or 10
|
|
|
|
@playersAbove = new LeaderboardCollection(@level, {order:1, scoreOffset: score, limit: 4, team: @team})
|
|
|
|
promises.push @playersAbove.fetch()
|
|
|
|
@playersBelow = new LeaderboardCollection(@level, {order:-1, scoreOffset: score, limit: 4, team: @team})
|
|
|
|
promises.push @playersBelow.fetch()
|
|
|
|
level = "#{level.get('original')}.#{level.get('version').major}"
|
|
|
|
success = (@myRank) =>
|
|
|
|
promises.push $.ajax "/db/level/#{level}/leaderboard_rank?scoreOffset=#{@session.get('totalScore')}&team=#{@team}", {success}
|
2014-03-21 22:50:54 -04:00
|
|
|
@promise = $.when(promises...)
|
|
|
|
@promise.then @onLoad
|
|
|
|
@promise
|
2014-03-20 17:40:17 -04:00
|
|
|
|
|
|
|
onLoad: =>
|
2014-03-09 16:22:22 -04:00
|
|
|
@loaded = true
|
|
|
|
@trigger 'sync'
|
2014-03-20 17:40:17 -04:00
|
|
|
# TODO: cache user ids -> names mapping, and load them here as needed,
|
|
|
|
# and apply them to sessions. Fetching each and every time is too costly.
|
2014-03-21 11:09:08 -04:00
|
|
|
|
2014-03-20 17:40:17 -04:00
|
|
|
inTopSessions: ->
|
|
|
|
return me.id in (session.attributes.creator for session in @topPlayers.models)
|
2014-03-21 11:09:08 -04:00
|
|
|
|
2014-03-20 17:40:17 -04:00
|
|
|
nearbySessions: ->
|
2014-03-24 17:38:18 -04:00
|
|
|
return [] unless @session?.get('totalScore')
|
2014-03-20 17:40:17 -04:00
|
|
|
l = []
|
|
|
|
above = @playersAbove.models
|
|
|
|
above.reverse()
|
|
|
|
l = l.concat(above)
|
|
|
|
l.push @session
|
|
|
|
l = l.concat(@playersBelow.models)
|
|
|
|
if @myRank
|
|
|
|
startRank = @myRank - 4
|
|
|
|
session.rank = startRank + i for session, i in l
|
2014-03-21 11:09:08 -04:00
|
|
|
l
|