codecombat/app/views/play/ladder_view.coffee

215 lines
6.8 KiB
CoffeeScript
Raw Normal View History

2014-02-07 18:51:05 -05:00
RootView = require 'views/kinds/RootView'
Level = require 'models/Level'
Simulator = require 'lib/simulator/Simulator'
2014-02-07 18:51:05 -05:00
LevelSession = require 'models/LevelSession'
CocoCollection = require 'models/CocoCollection'
2014-03-02 15:43:21 -05:00
{teamDataFromLevel} = require './ladder/utils'
{me} = require 'lib/auth'
application = require 'application'
2014-03-02 15:43:21 -05:00
LadderTabView = require './ladder/ladder_tab'
MyMatchesTabView = require './ladder/my_matches_tab'
LadderPlayModal = require './ladder/play_modal'
2014-04-12 17:13:26 -04:00
SimulatorsLeaderboardCollection = require 'collections/SimulatorsLeaderboardCollection'
CocoClass = require 'lib/CocoClass'
2014-02-07 18:51:05 -05:00
HIGHEST_SCORE = 1000000
class LevelSessionsCollection extends CocoCollection
url: ''
model: LevelSession
2014-02-20 16:58:35 -05:00
2014-02-07 18:51:05 -05:00
constructor: (levelID) ->
super()
@url = "/db/level/#{levelID}/my_sessions"
2014-02-07 18:51:05 -05:00
module.exports = class LadderView extends RootView
id: 'ladder-view'
template: require 'templates/play/ladder'
2014-02-14 19:53:34 -05:00
subscriptions:
'application:idle-changed': 'onIdleChanged'
2014-02-14 19:53:34 -05:00
events:
'click #simulate-button': 'onSimulateButtonClick'
'click #simulate-all-button': 'onSimulateAllButtonClick'
'click .play-button': 'onClickPlayButton'
'click a': 'onClickedLink'
2014-02-14 19:53:34 -05:00
2014-03-02 15:43:21 -05:00
constructor: (options, @levelID) ->
super(options)
@level = new Level(_id:@levelID)
@level.fetch()
@sessions = new LevelSessionsCollection(levelID)
@sessions.fetch({})
@addResourceToLoad(@sessions, 'your_sessions')
@addResourceToLoad(@level, 'level')
2014-04-12 17:13:26 -04:00
@simulatorsLeaderboardData = new SimulatorsLeaderboardData(me)
@addResourceToLoad(@simulatorsLeaderboardData, 'top_simulators')
2014-03-02 15:43:21 -05:00
@simulator = new Simulator()
2014-03-24 12:58:34 -04:00
@listenTo(@simulator, 'statusUpdate', @updateSimulationStatus)
2014-03-02 15:43:21 -05:00
@teams = []
onLoaded: ->
2014-03-02 15:43:21 -05:00
@teams = teamDataFromLevel @level
super()
2014-03-02 15:43:21 -05:00
getRenderData: ->
ctx = super()
ctx.level = @level
ctx.link = "/play/level/#{@level.get('name')}"
ctx.simulationStatus = @simulationStatus
ctx.teams = @teams
ctx.levelID = @levelID
ctx.levelDescription = marked(@level.get('description')) if @level.get('description')
2014-04-12 17:13:26 -04:00
ctx.simulatorsLeaderboardData = @simulatorsLeaderboardData
2014-04-13 18:28:16 -04:00
ctx._ = _
2014-03-02 15:43:21 -05:00
ctx
afterRender: ->
super()
return if @loading()
@insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions))
@insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions))
@refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 10 * 1000)
hash = document.location.hash[1..] if document.location.hash
if hash and not (hash in ['my-matches', 'simulate', 'ladder'])
@showPlayModal(hash) if @sessions.loaded
2014-03-03 15:21:59 -05:00
2014-03-03 15:10:24 -05:00
fetchSessionsAndRefreshViews: ->
return if @destroyed or application.userIsIdle or @$el.find('#simulate.active').length or (new Date() - 2000 < @lastRefreshTime) or @loading()
2014-03-03 15:10:24 -05:00
@sessions.fetch({"success": @refreshViews})
2014-03-03 15:21:59 -05:00
2014-03-03 15:10:24 -05:00
refreshViews: =>
return if @destroyed or application.userIsIdle
2014-03-19 21:26:38 -04:00
@lastRefreshTime = new Date()
@ladderTab.refreshLadder()
@myMatchesTab.refreshMatches()
console.log "Refreshed sessions for ladder and matches."
onIdleChanged: (e) ->
2014-03-20 18:40:02 -04:00
@fetchSessionsAndRefreshViews() unless e.idle
2014-03-03 15:21:59 -05:00
2014-03-02 15:43:21 -05:00
# Simulations
onSimulateAllButtonClick: (e) ->
2014-03-02 15:43:21 -05:00
submitIDs = _.pluck @leaderboards[@teams[0].id].topPlayers.models, "id"
2014-02-14 19:53:34 -05:00
for ID in submitIDs
$.ajax
url: '/queue/scoring'
method: 'POST'
data:
session: ID
$("#simulate-all-button").prop "disabled", true
$("#simulate-all-button").text "Submitted all!"
2014-02-14 19:53:34 -05:00
onSimulateButtonClick: (e) ->
$("#simulate-button").prop "disabled",true
$("#simulate-button").text "Simulating..."
@simulator.fetchAndSimulateTask()
2014-03-24 12:58:34 -04:00
updateSimulationStatus: (simulationStatus, sessions) ->
@simulationStatus = simulationStatus
try
if sessions?
#TODO: Fetch names from Redis, the creatorName is denormalized
creatorNames = (session.creatorName for session in sessions)
@simulationStatus = "Simulating game between "
for index in [0...creatorNames.length]
unless creatorNames[index]
creatorNames[index] = "Anonymous"
@simulationStatus += (if index != 0 then " and " else "") + creatorNames[index]
@simulationStatus += "..."
catch e
console.log "There was a problem with the named simulation status: #{e}"
2014-02-20 16:58:35 -05:00
$("#simulation-status-text").text @simulationStatus
onClickPlayButton: (e) ->
@showPlayModal($(e.target).closest('.play-button').data('team'))
2014-04-13 18:28:16 -04:00
2014-03-22 12:07:01 -04:00
resimulateAllSessions: ->
postData =
originalLevelID: @level.get('original')
levelMajorVersion: @level.get('version').major
console.log postData
2014-04-13 18:28:16 -04:00
2014-03-22 12:07:01 -04:00
$.ajax
url: '/queue/scoring/resimulateAllSessions'
method: 'POST'
2014-04-13 18:28:16 -04:00
data: postData
2014-03-22 12:07:01 -04:00
complete: (jqxhr) ->
console.log jqxhr.responseText
showPlayModal: (teamID) ->
return @showApologeticSignupModal() if me.get('anonymous')
session = (s for s in @sessions.models when s.get('team') is teamID)[0]
modal = new LadderPlayModal({}, @level, session, teamID)
2014-03-03 15:21:59 -05:00
@openModalView modal
2014-03-17 01:17:56 -04:00
showApologeticSignupModal: ->
SignupModal = require 'views/modal/signup_modal'
@openModalView(new SignupModal({showRequiredError:true}))
onClickedLink: (e) ->
link = $(e.target).closest('a').attr('href')
2014-03-17 01:17:56 -04:00
if link?.startsWith('/play/level') and me.get('anonymous')
e.stopPropagation()
e.preventDefault()
@showApologeticSignupModal()
2014-03-17 01:17:56 -04:00
destroy: ->
clearInterval @refreshInterval
@simulator.destroy()
super()
2014-04-12 17:13:26 -04:00
class SimulatorsLeaderboardData extends CocoClass
###
Consolidates what you need to load for a leaderboard into a single Backbone Model-like object.
###
2014-04-13 18:28:16 -04:00
2014-04-12 17:13:26 -04:00
constructor: (@me) ->
super()
@fetch()
2014-04-13 18:28:16 -04:00
2014-04-12 17:13:26 -04:00
fetch: ->
@topSimulators = new SimulatorsLeaderboardCollection({order:-1, scoreOffset: -1, limit: 20})
promises = []
2014-04-13 18:28:16 -04:00
promises.push @topSimulators.fetch()
unless @me.get('anonymous')
score = @me.get('simulatedBy') or 0
2014-04-12 17:13:26 -04:00
@playersAbove = new SimulatorsLeaderboardCollection({order:1, scoreOffset: score, limit: 4})
promises.push @playersAbove.fetch()
2014-04-13 18:28:16 -04:00
if score
@playersBelow = new SimulatorsLeaderboardCollection({order:-1, scoreOffset: score, limit: 4})
promises.push @playersBelow.fetch()
2014-04-12 17:13:26 -04:00
@promise = $.when(promises...)
@promise.then @onLoad
@promise.fail @onFail
@promise
onLoad: =>
return if @destroyed
@loaded = true
@trigger 'sync', @
2014-04-13 18:28:16 -04:00
2014-04-12 17:13:26 -04:00
onFail: (resource, jqxhr) =>
return if @destroyed
@trigger 'error', @, jqxhr
inTopSimulators: ->
return me.id in (user.id for user in @topSimulators.models)
nearbySimulators: ->
l = []
above = @playersAbove.models
above.reverse()
l = l.concat(above)
l.push @me
2014-04-13 18:28:16 -04:00
l = l.concat(@playersBelow.models) if @playersBelow
2014-04-12 17:13:26 -04:00
l
allResources: ->
resources = [@topSimulators, @playersAbove, @playersBelow]
return (r for r in resources when r)