Merge branch 'feature/Change-view-to-fit-new-supermodel' into feature/loading-views

Conflicts:
	app/views/play/ladder/ladder_tab.coffee
	app/views/play/ladder_view.coffee
This commit is contained in:
Ting-Kuan 2014-04-16 11:38:05 -04:00
commit 2e50d7b15d
19 changed files with 262 additions and 297 deletions

View file

@ -6,8 +6,14 @@ class NameLoader extends CocoClass
loadNames: (ids) ->
toLoad = (id for id in ids when not namesCache[id])
return false unless toLoad.length
jqxhr = $.ajax('/db/user/x/names', {type:'POST', data:{ids:toLoad}})
jqxhr.done @loadedNames
jqxhrOptions = {
url: '/db/user/x/names',
type:'POST',
data:{ids:toLoad},
success: @loadedNames
}
return jqxhrOptions
loadedNames: (newNames) =>
_.extend namesCache, newNames

View file

@ -397,6 +397,7 @@
hard: "Hard"
player: "Player"
about:
who_is_codecombat: "Who is CodeCombat?"
why_codecombat: "Why CodeCombat?"
@ -667,4 +668,9 @@
leaderboard: "Leaderboard"
user_schema: "User Schema"
user_profile: "User Profile"
patches: "Patches"
level_session: "LevelSession"
level_sessions_collection: 'LevelSessionsCollection'
opponent_session: "OpponentSession"
simulator: 'Simulator'
level_document: 'Level Document'
thang_document: 'Thang Document'

View file

@ -29,6 +29,7 @@ module.exports = class Level extends CocoModel
visit = (system) ->
return if system.original of originalsSeen
systemModel = _.find systemModels, {original: system.original}
console.error "Couldn't find model for original", system.original, "from", systemModels unless systemModel
for d in systemModel.dependencies or []
system2 = _.find levelSystems, {original: d.original}

View file

@ -1,5 +1,12 @@
module.exports = class SuperModel extends Backbone.Model
constructor: ->
@num = 0
@denom = 0
@showing = false
@progress = 0
@resources = {}
@rid = 0
@models = {}
@collections = {}
@schemas = {}
@ -8,14 +15,17 @@ module.exports = class SuperModel extends Backbone.Model
@mustPopulate = model
model.saveBackups = @shouldSaveBackups(model)
url = model.url()
@models[url] = model unless @models[url]?
@addModel(model)
@modelLoaded(model) if model.loaded
resName = url unless resName
modelRes = @addModelResource(model, url)
resName = model.url unless resName
modelRes = @addModelResource(model, model.url)
schema = model.schema()
@schemas[schema.urlRoot] = schema
modelRes.load()
return modelRes
# replace or overwrite
shouldLoadReference: (model) -> true
@ -32,8 +42,10 @@ module.exports = class SuperModel extends Backbone.Model
@removeEventsFromModel(model)
removeEventsFromModel: (model) ->
model.off 'sync', @modelLoaded, @
model.off 'error', @modelErrored, @
# "Request" resource may have no off()
# "Something" resource may have no model.
model?.off? 'sync', @modelLoaded, @
model?.off? 'error', @modelErrored, @
getModel: (ModelClass_or_url, id) ->
return @getModelByURL(ModelClass_or_url) if _.isString(ModelClass_or_url)
@ -55,9 +67,7 @@ module.exports = class SuperModel extends Backbone.Model
return _.values @models
addModel: (model) ->
url = model.url()
return console.warn "Tried to add Model '#{url}' to SuperModel, but it wasn't loaded." unless model.loaded
#return console.warn "Tried to add Model '#{url}' to SuperModel when we already had it." if @models[url]?
url = model.url
@models[url] = model
getCollection: (collection) ->
@ -82,44 +92,44 @@ module.exports = class SuperModel extends Backbone.Model
collection
finished: ->
return ResourceManager.progress is 1.0 or Object.keys(ResourceManager.resources).length is 0
return @progress is 1.0 or Object.keys(@resources).length is 0
addModelResource: (modelOrCollection, name, fetchOptions, value=1) ->
@checkName(name)
@addModel(modelOrCollection)
res = new ModelResource(modelOrCollection, name, fetchOptions, value)
@storeResource(name, res, value)
@storeResource(res, value)
return res
addRequestResource: (name, jqxhrOptions, value=1) ->
@checkName(name)
res = new RequestResource(name, jqxhrOptions, value)
@storeResource(name, res, value)
@storeResource(res, value)
return res
addSomethingResource: (name, value=1) ->
@checkName(name)
res = new SomethingResource(name, value)
@storeResource(name, res, value)
@storeResource(res, value)
return res
checkName: (name) ->
if not name
throw new Error('Resource name should not be empty.')
if name in ResourceManager.resources
throw new Error('Resource name has been used.')
storeResource: (name, resource, value)->
ResourceManager.resources[name] = resource
storeResource: (resource, value) ->
@rid++
resource.rid = @rid
@resources[@rid] = resource
@listenToOnce(resource, 'resource:loaded', @onResourceLoaded)
@listenToOnce(resource, 'resource:failed', @onResourceFailed)
ResourceManager.denom += value
@denom += value
loadResources: ()->
for name, res of ResourceManager.resources
loadResources: ->
for rid, res of @resources
res.load()
onResourceLoaded: (r)=>
onResourceLoaded: (r) ->
@modelLoaded(r.model)
# Check if the model has references
if r.constructor.name is 'ModelResource'
@ -129,8 +139,9 @@ module.exports = class SuperModel extends Backbone.Model
else
@updateProgress(r)
onResourceFailed: (r)=>
@modelErrored(r.model)
onResourceFailed: (source) ->
@trigger('resource:failed', source)
@modelErrored(source.resource.model)
addModelRefencesToLoad: (model) ->
schema = model.schema?()
@ -150,56 +161,47 @@ module.exports = class SuperModel extends Backbone.Model
res.load()
updateProgress: (r) =>
ResourceManager.num += r.value
ResourceManager.progress = ResourceManager.num / ResourceManager.denom
@num += r.value
@progress = @num / @denom
@trigger('superModel:updateProgress', ResourceManager.progress)
@trigger 'loaded-all' if @finished()
@trigger('superModel:updateProgress', @progress)
@trigger('loaded-all') if @finished()
getResource: (name)->
return ResourceManager.resources[name]
getResource: (rid)->
return @resources[rid]
getProgress: ()-> return ResourceManager.progress
getProgress: -> return @progress
# Both SuperModel and Resource access this class.
# Set resources as static so no need to load resources multiple times when more than one view is used.
class ResourceManager
@num = 0
@denom = 0
@showing = false
@progress = 0
@resources: {}
class Resource extends Backbone.Model
constructor: (name, value=1) ->
@name = name
@value = value
@dependencies = []
@rid = -1 # Used for checking state and reloading
@isLoading = false
@isLoaded = false
@model = null
@loadDeferred = null
@value = 1
addDependency: (name)->
depRes = ResourceManager.resources[name]
throw new Error('Resource not found') unless depRes
return if (depRes.isLoaded or name is @name)
@dependencies.push(name)
addDependency: (depRes) ->
return if depRes.isLoaded
@dependencies.push(depRes)
markLoaded: ()->
markLoaded: ->
@trigger('resource:loaded', @) if not @isLoaded
@isLoaded = true
@isLoading = false
markFailed: ()->
@trigger('resource:failed', @) if not @isLoaded
markFailed: (error) ->
@trigger('resource:failed', {resource: @, error: error}) if not @isLoaded
@isLoaded = false
@isLoading = false
load: ()->
isReadyForLoad: ()-> return not (@isloaded and @isLoading)
getModel: ()-> @model
load: ->
isReadyForLoad: -> return not (@isloaded and @isLoading)
getModel: -> @model
class ModelResource extends Resource
constructor: (modelOrCollection, name, fetchOptions, value)->
@ -207,28 +209,27 @@ class ModelResource extends Resource
@model = modelOrCollection
@fetchOptions = fetchOptions
load: ()->
load: ->
return @loadDeferred.promise() if @isLoading or @isLoaded
@isLoading = true
@loadDeferred = $.Deferred()
$.when.apply($, @loadDependencies())
.then(@onLoadDependenciesSuccess, @onLoadDependenciesFailed)
.always(()=> @isLoading = false)
.always(=> @isLoading = false)
return @loadDeferred.promise()
loadDependencies: ()->
loadDependencies: ->
promises = []
for resName in @dependencies
dep = ResourceManager.resources[resName]
for dep in @dependencies
continue if not dep.isReadyForLoad()
promises.push(dep.load())
return promises
onLoadDependenciesSuccess: ()=>
onLoadDependenciesSuccess: =>
@model.fetch(@fetchOptions)
@listenToOnce(@model, 'sync', ->
@ -237,12 +238,12 @@ class ModelResource extends Resource
)
@listenToOnce(@model, 'error', ->
@markFailed()
@markFailed('Failed to load resource.')
@loadDeferred.reject(@)
)
onLoadDependenciesFailed: ()=>
@markFailed()
onLoadDependenciesFailed: =>
@markFailed('Failed to load dependencies.')
@loadDeferred.reject(@)
@ -253,7 +254,7 @@ class RequestResource extends Resource
@jqxhrOptions = jqxhrOptions
@loadDeferred = @model
load: ()->
load: ->
return @loadDeferred.promise() if @isLoading or @isLoaded
@isLoading = true
@ -263,21 +264,26 @@ class RequestResource extends Resource
return @loadDeferred.promise()
loadDependencies: ()->
loadDependencies: ->
promises = []
for depName in @dependecies
dep = ResourceManager.resources[depName]
for dep in @dependencies
continue if not dep.isReadyForLoad()
promises.push(dep.load())
return promises
onLoadDependenciesSuccess: ()->
onLoadDependenciesSuccess: =>
@model = $.ajax(@jqxhrOptions)
@model.done(()=> @markLoaded()).failed(()=> @markFailed())
@model.done(
=> @markLoaded()
).fail(
(jqXHR, textStatus, errorThrown) =>
@markFailed(errorThrown)
)
onLoadDependenciesFailed: ()->
@markFailed()
onLoadDependenciesFailed: =>
@markFailed('Failed to load dependencies.')
class SomethingResource extends Resource
@ -286,13 +292,13 @@ class SomethingResource extends Resource
@name = name
@loadDeferred = $.Deferred()
load: ()->
load: ->
return @loadDeferred.promise()
markLoaded: ()->
markLoaded: ->
@loadDeferred.resolve()
super()
markFailed: ()->
markFailed: (error) ->
@loadDeferred.reject()
super()
super(error)

View file

@ -18,31 +18,26 @@ module.exports = class ThangComponentEditView extends CocoView
@level = options.level
@callback = options.callback
render: =>
return if @destroyed
if not @componentCollection
@componentCollection = @supermodel.getCollection new ComponentsCollection()
unless @componentCollection.loaded
@listenToOnce(@componentCollection, 'sync', @onComponentsSync)
@componentCollection.fetch()
super() # do afterRender at the end
@componentCollectionRes = @supermodel.addModelResource(@componentCollection, 'component_collection')
@listenToOnce(@componentCollectionRes, 'resource:loaded', @onComponentsSync)
@componentCollectionRes.load()
onLoaded: ->
afterRender: ->
super()
return @showLoading() unless @componentCollection?.loaded
@hideLoading()
@buildExtantComponentTreema()
@buildAddComponentTreema()
onComponentsSync: ->
onComponentsSync: (res) ->
return if @destroyed
@supermodel.addCollection @componentCollection
@render()
buildExtantComponentTreema: ->
level = new Level()
treemaOptions =
supermodel: @supermodel
schema: Level.schema.properties.thangs.items.properties.components
schema: level.schema().properties.thangs.items.properties.components
data: _.cloneDeep @components
callbacks: {select: @onSelectExtantComponent, change:@onChangeExtantComponents}
noSortable: true

View file

@ -22,13 +22,10 @@ module.exports = class AddThangsView extends View
constructor: (options) ->
super options
@world = options.world
@thangTypes = @supermodel.getCollection new ThangTypeSearchCollection() # should load depended-on Components, too
@listenToOnce(@thangTypes, 'sync', @onThangTypesLoaded)
@thangTypes.fetch()
onThangTypesLoaded: ->
return if @destroyed
@render() # do it again but without the loading screen
@thangTypes = @supermodel.getCollection new ThangTypeSearchCollection() # should load depended-on Components, too
@thangTypesRes = @supermodel.addModelResource(@thangTypes, 'add_thang_type_search_collection')
@thangTypesRes.load()
getRenderData: (context={}) ->
context = super(context)
@ -59,7 +56,6 @@ module.exports = class AddThangsView extends View
context
afterRender: ->
return if @startsLoading
super()
runSearch: (e) =>

View file

@ -22,6 +22,7 @@ module.exports = class ComponentsTabView extends View
events:
'click #create-new-component-button': 'createNewLevelComponent'
onLoaded: ->
onLevelThangsChanged: (e) ->
thangsData = e.thangsData
presentComponents = {}

View file

@ -20,7 +20,6 @@ ErrorView = require '../../error_view'
module.exports = class EditorLevelView extends View
id: "editor-level-view"
template: template
startsLoading: true
cache: false
events:
@ -28,7 +27,7 @@ module.exports = class EditorLevelView extends View
'click #commit-level-start-button': 'startCommittingLevel'
'click #fork-level-start-button': 'startForkingLevel'
'click #history-button': 'showVersionHistory'
'click #patches-tab': -> @patchesView.load()
'click #patches-tab': -> @patchesView?.load()
'click #commit-level-patch-button': 'startPatchingLevel'
constructor: (options, @levelID) ->
@ -46,33 +45,29 @@ module.exports = class EditorLevelView extends View
@supermodel.shouldSaveBackups = (model) ->
model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem']
@level = new Level _id: @levelID
@listenToOnce(@level, 'sync', @onLevelLoaded)
@worldRes = @supermodel.addSomethingResource('world')
@listenToOnce(@supermodel, 'error',
() =>
@level = new Level _id: @levelID
#@listenToOnce(@level, 'sync', @onLevelLoaded)
@listenToOnce(@supermodel, 'error', =>
@hideLoading()
@insertSubView(new ErrorView())
)
@supermodel.populateModel(@level, 'level')
@levelRes = @supermodel.addModelResource(@level, 'level')
@listenToOnce(@levelRes, 'resource:loaded', ->
@world = new World @level.name
@worldRes.markLoaded()
)
@levelRes.load()
@files = new DocumentFiles(@level)
@supermodel.addModelResource(@files, 'level_document').load()
showLoading: ($el) ->
$el ?= @$el.find('.tab-content')
super($el)
onLevelLoaded: ->
@files = new DocumentFiles(@level)
@supermodel.addModelResource(@files, @files.url).load()
onAllLoaded: ->
@level.unset('nextLevel') if _.isString(@level.get('nextLevel'))
@initWorld()
@startsLoading = false
@render() # do it again but without the loading screen
initWorld: ->
@world = new World @level.name
getRenderData: (context={}) ->
context = super(context)
context.level = @level
@ -81,9 +76,9 @@ module.exports = class EditorLevelView extends View
context
afterRender: ->
return if @startsLoading
super()
new LevelSystem # temp; trigger the LevelSystem schema to be loaded, if it isn't already
return unless @world and @level
console.debug 'gintau', 'edit-afterRender'
@$el.find('a[data-toggle="tab"]').on 'shown.bs.tab', (e) =>
Backbone.Mediator.publish 'level:view-switched', e
@thangsTab = @insertSubView new ThangsTabView world: @world, supermodel: @supermodel

View file

@ -17,6 +17,7 @@ module.exports = class ScriptsTabView extends View
@world = options.world
@files = options.files
onLoaded: ->
onLevelLoaded: (e) ->
@level = e.level
@dimensions = @level.dimensions()

View file

@ -22,6 +22,7 @@ module.exports = class SettingsTabView extends View
super options
@world = options.world
onLoaded: ->
onLevelLoaded: (e) ->
@level = e.level
data = _.pick @level.attributes, (value, key) => key in @editableSettings

View file

@ -31,15 +31,17 @@ module.exports = class SystemsTabView extends View
url = "/db/level.system/#{system.original}/version/#{system.majorVersion}"
ls = new LevelSystem()
ls.saveBackups = true
lsRes = @supermodel.addModelResource(ls, 'level_system_' + system.original);
do (url) -> ls.url = -> url
continue if @supermodel.getModelByURL ls.url
ls.fetch()
@listenToOnce ls, 'sync', @onSystemLoaded
lsRes.load()
@listenToOnce(lsRes, 'resource:loaded', @onSystemLoaded)
++@toLoad
@onDefaultSystemsLoaded() unless @toLoad
onSystemLoaded: (ls) ->
@supermodel.addModel ls
onSystemLoaded: (lsRes) ->
ls = lsRes.model
@supermodel.addModel(ls)
--@toLoad
@onDefaultSystemsLoaded() unless @toLoad
@ -48,9 +50,9 @@ module.exports = class SystemsTabView extends View
@render() # do it again but without the loading screen
@onLevelLoaded level: @level if @level
onLoaded: ->
onLevelLoaded: (e) ->
@level = e.level
return if @startsLoading
@buildSystemsTreema()
buildSystemsTreema: ->
@ -145,9 +147,7 @@ class LevelSystemNode extends TreemaObjectNode
grabDBComponent: ->
unless _.isString @data.original
return alert('Press the "Add System" button at the bottom instead of the "+". Sorry.')
@system = @settings.supermodel.getModelByOriginalAndMajorVersion LevelSystem, @data.original, @data.majorVersion
#@system = _.find @settings.supermodel.getModels(LevelSystem), (m) =>
# m.get('original') is @data.original and m.get('version').major is @data.majorVersion
@system = @settings.supermodel.getModelByOriginalAndMajorVersion(LevelSystem, @data.original, @data.majorVersion)
console.error "Couldn't find system for", @data.original, @data.majorVersion, "from models", @settings.supermodel.models unless @system
getChildSchema: (key) ->

View file

@ -50,6 +50,7 @@ module.exports = class LevelThangEditView extends View
input.val(thangTypeName)
@$el.find('#thang-type-link span').text(thangTypeName)
window.input = input
@hideLoading()
saveThang: (e) ->
# Make sure it validates first?

View file

@ -60,31 +60,34 @@ module.exports = class ThangsTabView extends View
constructor: (options) ->
super options
@world = options.world
@thangTypes = @supermodel.getCollection new ThangTypeSearchCollection() # should load depended-on Components, too
@listenToOnce(@thangTypes, 'sync', @onThangTypesLoaded)
@thangTypes.fetch()
@thangTypesRes = @supermodel.addModelResource(@thangTypes, 'thang_type_search_collection')
@listenToOnce(@thangTypesRes, 'resource:loaded', @onThangTypesLoaded)
@thangTypesRes.load()
$(document).bind 'contextmenu', @preventDefaultContextMenu
# just loading all Components for now: https://github.com/codecombat/codecombat/issues/405
@componentCollection = @supermodel.getCollection new ComponentsCollection()
@listenToOnce(@componentCollection, 'sync', @onComponentsLoaded)
@componentCollection.fetch()
@componentCollectionRes = @supermodel.addModelResource(@componentCollection, 'components_collection')
@listenToOnce(@componentCollectionRes, 'resource:loaded', @onComponentsLoaded)
@componentCollectionRes.load()
onThangTypesLoaded: ->
return if @destroyed
@supermodel.addCollection @thangTypes
for model in @thangTypes.models
@supermodel.populateModel(model, model.name)
@startsLoading = not @componentCollection.loaded
@render() # do it again but without the loading screen
@onLevelLoaded level: @level if @level and not @startsLoading
# @render() # do it again but without the loading screen
# @onLevelLoaded level: @level if @level and not @startsLoading
onComponentsLoaded: ->
return if @destroyed
@supermodel.addCollection @componentCollection
@startsLoading = not @thangTypes.loaded
@render() # do it again but without the loading screen
@onLevelLoaded level: @level if @level and not @startsLoading
# @render() # do it again but without the loading screen
# @onLevelLoaded level: @level if @level and not @startsLoading
getRenderData: (context={}) ->
context = super(context)
@ -115,8 +118,8 @@ module.exports = class ThangsTabView extends View
oldHeight = $('#thangs-list').height()
$('#thangs-list').height(oldHeight - thangsHeaderHeight - 80)
onLoaded: ->
afterRender: ->
return if @startsLoading
super()
$('.tab-content').click @selectAddThang
$('#thangs-list').bind 'mousewheel', @preventBodyScrollingInThangList
@ -138,7 +141,7 @@ module.exports = class ThangsTabView extends View
onLevelLoaded: (e) ->
@level = e.level
return if @startsLoading
data = $.extend(true, {}, @level.attributes)
treemaOptions =
schema: Level.schema.properties.thangs
@ -153,6 +156,7 @@ module.exports = class ThangsTabView extends View
thang: ThangNode
array: ThangsNode
world: @world
@thangsTreema = @$el.find('#thangs-treema').treema treemaOptions
@thangsTreema.build()
@thangsTreema.open()

View file

@ -20,18 +20,15 @@ module.exports = class PatchesView extends CocoView
initPatches: ->
@startedLoading = false
@patches = new PatchesCollection([], {}, @model, @status)
@listenToOnce @patches, 'sync', @gotPatches
@addResourceToLoad @patches, 'patches'
@patchesRes = @supermodel.addModelResource(@patches, 'patches')
gotPatches: ->
ids = (p.get('creator') for p in @patches.models)
jqxhr = nameLoader.loadNames ids
if jqxhr then @addRequestToLoad(jqxhr, 'user_names', 'gotPatches') else @render()
jqxhrOptions = nameLoader.loadNames ids
@nameLoaderRes = @supermodel.addRequestResource('name_loader', jqxhrOptions)
@nameLoaderRes.addDependency(@patchesRes)
load: ->
return if @startedLoading
@patches.fetch()
@startedLoading = true
@nameLoaderRes.load()
getRenderData: ->
c = super()

View file

@ -61,20 +61,13 @@ module.exports = class ThangTypeEditView extends View
)
thangRes = @supermodel.addModelResource(@thangType, 'thang_type')
@files = new DocumentFiles(@thangType)
thangDocRes = @supermodel.addModelResource(@files, 'thang_document')
thangRes.addDependency(thangDocRes)
thangRes.load()
@listenToOnce(@thangType.schema(), 'sync', @onThangTypeSync)
@listenToOnce(@thangType, 'sync', @onThangTypeSync)
@refreshAnimation = _.debounce @refreshAnimation, 500
onThangTypeSync: ->
return unless @thangType.loaded
@startsLoading = false
@files = new DocumentFiles(@thangType)
@supermodel.addModelResource(@files, @files.url).load()
@render()
getRenderData: (context={}) ->
context = super(context)
context.thangType = @thangType
@ -90,7 +83,6 @@ module.exports = class ThangTypeEditView extends View
afterRender: ->
super()
return unless @thangType.loaded
@initStage()
@buildTreema()
@initSliders()

View file

@ -43,8 +43,9 @@ module.exports = class CocoView extends Backbone.View
@updateProgressBar = _.debounce @updateProgressBar, 100
# Backbone.Mediator handles subscription setup/teardown automatically
@listenToOnce(@supermodel, 'loaded-all', ()=>@onLoaded)
@listenToOnce(@supermodel, 'loaded-all', @onLoaded)
@listenToOnce(@supermodel, 'superModel:updateProgress', @updateProgress)
@listenToOnce(@supermodel, 'resource:failed', @onResourceLoadFailed)
super options
@ -118,38 +119,20 @@ module.exports = class CocoView extends Backbone.View
@$el?.find('.loading-screen .progress-bar').css('width', prog)
onLoaded: ->
#@render()
@render?()
# Error handling for loading
onResourceLoadFailed: (resource, jqxhr) ->
for r, index in @loadProgress.resources
break if r.resource is resource
onResourceLoadFailed: (source) ->
@$el.find('.loading-screen .errors').append(loadingErrorTemplate({
status:jqxhr.status,
name: r.name
resourceIndex: index,
responseText: jqxhr.responseText
status: 'error',
name: source.resource.name
resourceIndex: source.resource.rid,
responseText: source.error
})).i18n()
onRetryResource: (e) ->
r = @loadProgress.resources[$(e.target).data('resource-index')]
r.resource.fetch()
$(e.target).closest('.loading-error-alert').remove()
onRequestLoadFailed: (jqxhr) =>
for r, index in @loadProgress.requests
break if r.request is jqxhr
@$el.find('.loading-screen .errors').append(loadingErrorTemplate({
status:jqxhr.status,
name: r.name
requestIndex: index,
responseText: jqxhr.responseText
}))
onRetryRequest: (e) ->
r = @loadProgress.requests[$(e.target).data('request-index')]
@[r.retryFunc]?()
res = @supermodel.getResource($(e.target).data('resource-index'))
res.load()
$(e.target).closest('.loading-error-alert').remove()
# Modals

View file

@ -32,7 +32,8 @@ module.exports = class LadderTabView extends CocoView
constructor: (options, @level, @sessions) ->
super(options)
@addSomethingToLoad("social_network_apis")
@socialNetworkRes = @supermodel.addSomethingResource("social_network_apis")
@teams = teamDataFromLevel @level
@leaderboards = {}
@refreshLadder()
@ -42,17 +43,22 @@ module.exports = class LadderTabView extends CocoView
return if @checked or (not window.FB) or (not window.gapi)
@checked = true
@addSomethingToLoad("facebook_status")
# @addSomethingToLoad("facebook_status")
@fbStatusRes = @supermodel.addSomethingResource("facebook_status")
@fbStatusRes.load()
FB.getLoginStatus (response) =>
@facebookStatus = response.status
@loadFacebookFriends() if @facebookStatus is 'connected'
@somethingLoaded("facebook_status")
@fbStatusRes.markLoaded()
if application.gplusHandler.loggedIn is undefined
@listenToOnce(application.gplusHandler, 'checked-state', @gplusSessionStateLoaded)
else
@gplusSessionStateLoaded()
@somethingLoaded("social_network_apis")
@socialNetworkRes.markLoaded()
# FACEBOOK
@ -63,23 +69,39 @@ module.exports = class LadderTabView extends CocoView
onConnectedWithFacebook: -> location.reload() if @connecting
loadFacebookFriends: ->
@addSomethingToLoad("facebook_friends")
# @addSomethingToLoad("facebook_friends")
@fbFriendRes = @supermodel.addSomethingResource("facebook_friends")
@fbFriendRes.load()
FB.api '/me/friends', @onFacebookFriendsLoaded
onFacebookFriendsLoaded: (response) =>
@facebookData = response.data
@loadFacebookFriendSessions()
@somethingLoaded("facebook_friends")
@fbFriendRes.markLoaded()
loadFacebookFriendSessions: ->
levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
url = "/db/level/#{levelFrag}/leaderboard_facebook_friends"
###
jqxhr = $.ajax url, {
data: { friendIDs: (f.id for f in @facebookData) }
method: 'POST'
success: @onFacebookFriendSessionsLoaded
}
@addRequestToLoad(jqxhr, 'facebook_friend_sessions', 'loadFacebookFriendSessions')
###
@fbFriendSessionRes = @supermodel.addRequestResource('facebook_friend_sessions', {
url: url
data: { friendIDs: (f.id for f in @facebookData) }
method: 'POST'
success: @onFacebookFriendSessionsLoaded
})
@fbFriendSessionRes.load()
onFacebookFriendSessionsLoaded: (result) =>
friendsMap = {}
@ -101,23 +123,34 @@ module.exports = class LadderTabView extends CocoView
gplusSessionStateLoaded: ->
if application.gplusHandler.loggedIn
@addSomethingToLoad("gplus_friends", 0) # this might not load ever, so we can't wait for it
#@addSomethingToLoad("gplus_friends")
@gpFriendRes = @supermodel.addSomethingResource("gplus_friends")
@gpFriendRes.load()
application.gplusHandler.loadFriends @gplusFriendsLoaded
gplusFriendsLoaded: (friends) =>
@gplusData = friends.items
@loadGPlusFriendSessions()
@somethingLoaded("gplus_friends")
@gpFriendRes.markLoaded()
loadGPlusFriendSessions: ->
levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
url = "/db/level/#{levelFrag}/leaderboard_gplus_friends"
###
jqxhr = $.ajax url, {
data: { friendIDs: (f.id for f in @gplusData) }
method: 'POST'
success: @onGPlusFriendSessionsLoaded
}
@addRequestToLoad(jqxhr, 'gplus_friend_sessions', 'loadGPlusFriendSessions')
###
@gpFriendSessionRes = @supermodel.addRequestResource('gplus_friend_sessions', {
url: url
data: { friendIDs: (f.id for f in @gplusData) }
method: 'POST'
success: @onGPlusFriendSessionsLoaded
})
@gpFriendSessionRes.load()
onGPlusFriendSessionsLoaded: (result) =>
friendsMap = {}
@ -135,8 +168,9 @@ module.exports = class LadderTabView extends CocoView
@leaderboards[team.id]?.destroy()
teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession)
@addResourceToLoad @leaderboards[team.id], 'leaderboard', 3
# @addResourceToLoad @leaderboards[team.id], 'leaderboard', 3
@leaderboardRes = @supermodel.addModelResource(@leaderboards[team.id], 'leaderboard', 3)
@leaderboardRes.load()
render: ->
super()
@ -205,8 +239,8 @@ module.exports = class LadderTabView extends CocoView
.attr("x",1)
.attr("width",width/20)
.attr("height", (d) -> height - y(d.y))
if playerScore = @leaderboards[teamName].session?.get('totalScore')
playerScore *= 100
if @leaderboards[teamName].session?
playerScore = @leaderboards[teamName].session.get('totalScore') * 100
scorebar = svg.selectAll(".specialbar")
.data([playerScore])
.enter().append("g")

View file

@ -10,8 +10,6 @@ application = require 'application'
LadderTabView = require './ladder/ladder_tab'
MyMatchesTabView = require './ladder/my_matches_tab'
LadderPlayModal = require './ladder/play_modal'
SimulatorsLeaderboardCollection = require 'collections/SimulatorsLeaderboardCollection'
CocoClass = require 'lib/CocoClass'
HIGHEST_SCORE = 1000000
@ -39,13 +37,13 @@ module.exports = class LadderView extends RootView
constructor: (options, @levelID) ->
super(options)
@level = new Level(_id:@levelID)
@level.fetch()
levelRes = @supermodel.addModelResource(@level, 'level')
levelRes.load()
@sessions = new LevelSessionsCollection(levelID)
@sessions.fetch({})
@addResourceToLoad(@sessions, 'your_sessions')
@addResourceToLoad(@level, 'level')
@simulatorsLeaderboardData = new SimulatorsLeaderboardData(me)
@addResourceToLoad(@simulatorsLeaderboardData, 'top_simulators')
sessionRes = @supermodel.addModelResource(@sessions, 'level_sessions_collection')
sessionRes.load()
@simulator = new Simulator()
@listenTo(@simulator, 'statusUpdate', @updateSimulationStatus)
@teams = []
@ -62,13 +60,11 @@ module.exports = class LadderView extends RootView
ctx.teams = @teams
ctx.levelID = @levelID
ctx.levelDescription = marked(@level.get('description')) if @level.get('description')
ctx.simulatorsLeaderboardData = @simulatorsLeaderboardData
ctx._ = _
ctx
afterRender: ->
super()
return if @loading()
return unless @supermodel.finished()
@insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions))
@insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions))
@refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 10 * 1000)
@ -77,7 +73,7 @@ module.exports = class LadderView extends RootView
@showPlayModal(hash) if @sessions.loaded
fetchSessionsAndRefreshViews: ->
return if @destroyed or application.userIsIdle or @$el.find('#simulate.active').length or (new Date() - 2000 < @lastRefreshTime) or @loading()
return if @destroyed or application.userIsIdle or @$el.find('#simulate.active').length or (new Date() - 2000 < @lastRefreshTime) or not @supermodel.finished()
@sessions.fetch({"success": @refreshViews})
refreshViews: =>
@ -162,53 +158,3 @@ module.exports = class LadderView extends RootView
clearInterval @refreshInterval
@simulator.destroy()
super()
class SimulatorsLeaderboardData extends CocoClass
###
Consolidates what you need to load for a leaderboard into a single Backbone Model-like object.
###
constructor: (@me) ->
super()
@fetch()
fetch: ->
@topSimulators = new SimulatorsLeaderboardCollection({order:-1, scoreOffset: -1, limit: 20})
promises = []
promises.push @topSimulators.fetch()
unless @me.get('anonymous')
score = @me.get('simulatedBy') or 0
@playersAbove = new SimulatorsLeaderboardCollection({order:1, scoreOffset: score, limit: 4})
promises.push @playersAbove.fetch()
if score
@playersBelow = new SimulatorsLeaderboardCollection({order:-1, scoreOffset: score, limit: 4})
promises.push @playersBelow.fetch()
@promise = $.when(promises...)
@promise.then @onLoad
@promise.fail @onFail
@promise
onLoad: =>
return if @destroyed
@loaded = true
@trigger 'sync', @
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
l = l.concat(@playersBelow.models) if @playersBelow
l
allResources: ->
resources = [@topSimulators, @playersAbove, @playersBelow]
return (r for r in resources when r)

View file

@ -23,7 +23,7 @@ module.exports = class LevelLoadingView extends View
@updateProgressBar()
updateProgressBar: ->
@$el.find('.progress-bar').css('width', (100 * @progress) + '%')
@$el?.find('.progress-bar').css('width', (100 * @progress) + '%')
showReady: ->
ready = $.i18n.t('play_level.loading_ready', defaultValue: 'Ready!')