codecombat/app/views/play/ladder/ladder_tab.coffee

149 lines
4.7 KiB
CoffeeScript
Raw Normal View History

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"
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
events:
2014-03-22 00:11:51 -04:00
'click .connect-facebook': 'onConnectFacebook'
subscriptions:
2014-03-22 00:11:51 -04:00
'facebook-logged-in': 'onConnectedWithFacebook'
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()
@checkFriends()
2014-03-22 00:11:51 -04:00
onConnectFacebook: ->
@connecting = true
FB.login()
onConnectedWithFacebook: ->
location.reload() if @connecting
checkFriends: ->
@loadingFriends = true
FB.getLoginStatus (response) =>
@facebookStatus = response.status
if @facebookStatus is 'connected'
@loadFriendSessions()
else
@loadingFriends = false
@renderMaybe()
loadFriendSessions: ->
FB.api '/me/friends', (response) =>
@facebookData = response.data
console.log 'got facebookData', @facebookData
levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
url = "/db/level/#{levelFrag}/leaderboard_friends"
$.ajax url, {
data: { friendIDs: (f.id for f in @facebookData) }
method: 'POST'
success: @facebookFriendsLoaded
}
facebookFriendsLoaded: (result) =>
friendsMap = {}
friendsMap[friend.id] = friend.name for friend in @facebookData
for friend in result
friend.facebookName = friendsMap[friend.facebookID]
friend.otherTeam = if friend.team is 'humans' then 'ogres' else 'humans'
@friends = result
@loadingFriends = false
@renderMaybe()
2014-03-03 15:21:59 -05:00
refreshLadder: ->
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'
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)
promises.push @leaderboards[team.id].promise
@loadingLeaderboards = true
$.when(promises...).then(@leaderboardsLoaded)
2014-03-02 15:43:21 -05:00
leaderboardsLoaded: =>
@loadingLeaderboards = false
@renderMaybe()
2014-03-02 15:43:21 -05:00
renderMaybe: ->
return if @loadingFriends or @loadingLeaderboards
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
ctx.friends = @friends
ctx.onFacebook = @facebookStatus is 'connected'
2014-03-02 15:43:21 -05:00
ctx
2014-03-03 15:21:59 -05:00
2014-03-02 15:43:21 -05:00
class LeaderboardData
constructor: (@level, @team, @session) ->
_.extend @, Backbone.Events
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: 20})
promises = []
promises.push @topPlayers.fetch()
@topPlayers.once 'sync', @onceLeaderboardPartLoaded, @
2014-03-02 15:43:21 -05: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()
@playersAbove.once 'sync', @onceLeaderboardPartLoaded, @
@playersBelow = new LeaderboardCollection(@level, {order:-1, scoreOffset: score, limit: 4, team: @team})
promises.push @playersBelow.fetch()
@playersBelow.once 'sync', @onceLeaderboardPartLoaded, @
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}
@promise = $.when(promises...)
@promise.then @onLoad
@promise
onLoad: =>
2014-03-09 16:22:22 -04:00
@loaded = true
@trigger 'sync'
# 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
inTopSessions: ->
return me.id in (session.attributes.creator for session in @topPlayers.models)
2014-03-21 11:09:08 -04:00
nearbySessions: ->
return [] unless @session
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