codecombat/app/views/play/level/modal/HeroVictoryModal.coffee

146 lines
5.6 KiB
CoffeeScript

ModalView = require 'views/kinds/ModalView'
template = require 'templates/play/level/modal/hero-victory-modal'
Achievement = require 'models/Achievement'
EarnedAchievement = require 'models/EarnedAchievement'
CocoCollection = require 'collections/CocoCollection'
LocalMongo = require 'lib/LocalMongo'
utils = require 'lib/utils'
ThangType = require 'models/ThangType'
module.exports = class HeroVictoryModal extends ModalView
id: 'hero-victory-modal'
template: template
closeButton: false
closesOnClickOutside: false
constructor: (options) ->
super(options)
@session = options.session
@level = options.level
achievements = new CocoCollection([], {
url: "/db/achievement?related=#{@session.get('level').original}"
model: Achievement
})
@thangTypes = {}
@achievements = @supermodel.loadCollection(achievements, 'achievements').model
@listenToOnce @achievements, 'sync', @onAchievementsLoaded
@readyToContinue = false
onAchievementsLoaded: ->
thangTypeOriginals = []
achievementIDs = []
for achievement in @achievements.models
rewards = achievement.get('rewards')
thangTypeOriginals.push rewards.heroes or []
thangTypeOriginals.push rewards.items or []
achievement.completed = LocalMongo.matchesQuery(@session.attributes, achievement.get('query'))
achievementIDs.push(achievement.id) if achievement.completed
thangTypeOriginals = _.uniq _.flatten thangTypeOriginals
for thangTypeOriginal in thangTypeOriginals
thangType = new ThangType()
thangType.url = "/db/thang.type/#{thangTypeOriginal}/version"
thangType.project = ['original', 'rasterIcon', 'name']
@thangTypes[thangTypeOriginal] = @supermodel.loadModel(thangType, 'thang').model
if achievementIDs.length
url = "/db/earned_achievement?view=get-by-achievement-ids&achievementIDs=#{achievementIDs.join(',')}"
earnedAchievements = new CocoCollection([], {
url: url
model: EarnedAchievement
})
earnedAchievements.sizeShouldBe = achievementIDs.length
res = @supermodel.loadCollection(earnedAchievements, 'earned_achievements')
@earnedAchievements = res.model
@listenTo @earnedAchievements, 'sync', ->
if @earnedAchievements.models.length < @earnedAchievements.sizeShouldBe
@earnedAchievements.fetch()
else
@listenToOnce me, 'sync', ->
@readyToContinue = true
@updateSavingProgressStatus()
me.fetch() unless me.loading
else
@readyToContinue = true
getRenderData: ->
c = super()
c.levelName = utils.i18n @level.attributes, 'name'
earnedAchievementMap = _.indexBy(@earnedAchievements?.models or [], (ea) -> ea.get('achievement'))
for achievement in @achievements.models
earnedAchievement = earnedAchievementMap[achievement.id]
if earnedAchievement
achievement.completedAWhileAgo = new Date() - Date.parse(earnedAchievement.get('created')) > 30 * 1000
c.achievements = @achievements.models
# for testing the three states
# if c.achievements.length
# c.achievements = [c.achievements[0].clone(), c.achievements[0].clone(), c.achievements[0].clone()]
# for achievement, index in c.achievements
# achievement.completed = index > 0
# achievement.completedAWhileAgo = index > 1
c.thangTypes = @thangTypes
return c
afterRender: ->
super()
return unless @supermodel.finished()
@updateSavingProgressStatus()
complete = _.once(_.bind(@beginAnimateNumbers, @))
@animatedPanels = $()
panels = @$el.find('.achievement-panel')
for panel in panels
panel = $(panel)
continue unless panel.data('animate')
@animatedPanels = @animatedPanels.add(panel)
panel.delay(500)
panel.queue(->
$(this).addClass('earned') # animate out the grayscale
$(this).dequeue()
)
panel.delay(500)
panel.queue(->
$(this).find('.reward-image-container').addClass('show')
$(this).dequeue()
)
panel.delay(500)
panel.queue(-> complete())
@animationComplete = not @animatedPanels.length
beginAnimateNumbers: ->
@numericalItemPanels = _.map(@animatedPanels.find('.numerical'), (panel) -> {
number: $(panel).data('number')
textEl: $(panel).find('.reward-text')
rootEl: $(panel)
unit: $(panel).data('number-unit')
})
# TODO: mess with this more later. Doesn't seem to work, often times will pulse background red rather than animate
# itemPanel.rootEl.find('.reward-image-container img').addClass('pulse') for itemPanel in @numericalItemPanels
@numberAnimationStart = new Date()
@totalXP = 0
@totalXP += panel.number for panel in @numericalItemPanels when panel.unit is 'xp'
@totalGems = 0
@totalGems += panel.number for panel in @numericalItemPanels when panel.unit is 'gem'
@gemEl = $('#gem-total')
@XPEl = $('#xp-total')
@numberAnimationInterval = setInterval(@tickNumberAnimation, 15 / 1000)
tickNumberAnimation: =>
pct = Math.min(1, (new Date() - @numberAnimationStart) / 1500)
panel.textEl.text('+'+parseInt(panel.number*pct)) for panel in @numericalItemPanels
@XPEl.text('+'+parseInt(@totalXP * pct))
@gemEl.text('+'+parseInt(@totalGems * pct))
@endAnimateNumbers() if pct is 1
endAnimateNumbers: ->
@$el.find('.pulse').removeClass('pulse')
clearInterval(@numberAnimationInterval)
@animationComplete = true
@updateSavingProgressStatus()
updateSavingProgressStatus: ->
return unless @animationComplete
@$el.find('#saving-progress-label').toggleClass('hide', @readyToContinue)
@$el.find('#continue-button').toggleClass('hide', not @readyToContinue)