mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-12 08:41:46 -05:00
663c220eaf
This heavily refactors SpellView and adds infrastructure for receiving and reporting Errors raised by the web-dev iFrame. The web-dev error system, the Aether error system, and the Ace html-worker avoid disturbing each others' errors/annotations (though currently Aether+web-dev errors won't coexist), and they clear/update their own asynchronously. Show web-dev iFrame errors as Ace annotations Add functional error banners (with poor messages) Improve error banners, don't allow duplicate Problems Refactor setAnnotations override Convert all constructor calls for Problems Add comments, clean up Clean up Don't clear things unnecessarily Clean up error message sending from iFrame Add web-dev:error schema Clarify error message attributes Refactor displaying AetherProblems Refactor displaying user problem banners Refactor onWebDevError Set ace styles on updating @problems Clean up, fix off-by-1 error Add comment Show stale web-dev errors differently Some web-dev errors are generated by "stale" code — code that's still running in the iFrame but doesn't have the player's recent changes. This shows those errors differently than if they weren't "stale", and suggests they re-run their code. Hook up web-dev event schema Destroy ignored duplicate problems Functionalize a bit of stuff Fix ProblemAlertView never loading
107 lines
3.6 KiB
CoffeeScript
107 lines
3.6 KiB
CoffeeScript
CocoView = require 'views/core/CocoView'
|
|
GameMenuModal = require 'views/play/menu/GameMenuModal'
|
|
template = require 'templates/play/level/tome/problem_alert'
|
|
{me} = require 'core/auth'
|
|
|
|
module.exports = class ProblemAlertView extends CocoView
|
|
id: 'problem-alert-view'
|
|
className: 'problem-alert'
|
|
template: template
|
|
|
|
subscriptions:
|
|
'tome:show-problem-alert': 'onShowProblemAlert'
|
|
'tome:hide-problem-alert': 'onHideProblemAlert'
|
|
'level:restart': 'onHideProblemAlert'
|
|
'tome:jiggle-problem-alert': 'onJiggleProblemAlert'
|
|
'tome:manual-cast': 'onHideProblemAlert'
|
|
|
|
events:
|
|
'click .close': 'onRemoveClicked'
|
|
'click': -> Backbone.Mediator.publish 'tome:focus-editor', {}
|
|
|
|
constructor: (options) ->
|
|
@supermodel = options.supermodel # Has to go before super so events are hooked up
|
|
super options
|
|
@level = options.level
|
|
@session = options.session
|
|
if options.problem?
|
|
@problem = options.problem
|
|
@onWindowResize()
|
|
else
|
|
@$el.hide()
|
|
$(window).on 'resize', @onWindowResize
|
|
|
|
destroy: ->
|
|
$(window).off 'resize', @onWindowResize
|
|
super()
|
|
|
|
afterRender: ->
|
|
super()
|
|
if @problem?
|
|
@$el.addClass('alert').addClass("alert-#{@problem.level}").hide().fadeIn('slow')
|
|
@$el.addClass('no-hint') unless @problem.hint
|
|
@playSound 'error_appear'
|
|
|
|
setProblemMessage: ->
|
|
if @problem?
|
|
format = (s) -> marked(s.replace(/</g, '<').replace(/>/g, '>')) if s?
|
|
message = @problem.message
|
|
# Add time to problem message if hint is for a missing null check
|
|
# NOTE: This may need to be updated with Aether error hint changes
|
|
if @problem.hint? and /(?:null|undefined)/.test @problem.hint
|
|
age = @problem.userInfo?.age
|
|
if age?
|
|
if /^Line \d+:/.test message
|
|
message = message.replace /^(Line \d+)/, "$1, time #{age.toFixed(1)}"
|
|
else
|
|
message = "Time #{age.toFixed(1)}: #{message}"
|
|
@message = format message
|
|
@hint = format @problem.hint
|
|
|
|
onShowProblemAlert: (data) ->
|
|
return unless $('#code-area').is(":visible")
|
|
if @problem?
|
|
if @$el.hasClass "alert-#{@problem.level}"
|
|
@$el.removeClass "alert-#{@problem.level}"
|
|
if @$el.hasClass "no-hint"
|
|
@$el.removeClass "no-hint"
|
|
@problem = data.problem
|
|
@lineOffsetPx = data.lineOffsetPx or 0
|
|
@$el.show()
|
|
@onWindowResize()
|
|
@setProblemMessage()
|
|
@render()
|
|
@onJiggleProblemAlert()
|
|
application.tracker?.trackEvent 'Show problem alert', {levelID: @level.get('slug'), ls: @session?.get('_id')}
|
|
|
|
onJiggleProblemAlert: ->
|
|
return unless @problem?
|
|
@$el.show() unless @$el.is(":visible")
|
|
@$el.addClass 'jiggling'
|
|
@playSound 'error_appear'
|
|
pauseJiggle = =>
|
|
@$el?.removeClass 'jiggling'
|
|
_.delay pauseJiggle, 1000
|
|
|
|
onHideProblemAlert: ->
|
|
return unless @$el.is(':visible')
|
|
@onRemoveClicked()
|
|
|
|
onRemoveClicked: ->
|
|
@playSound 'menu-button-click'
|
|
@$el.hide()
|
|
Backbone.Mediator.publish 'tome:focus-editor', {}
|
|
|
|
onWindowResize: (e) =>
|
|
# TODO: This all seems a little hacky
|
|
if @problem?
|
|
levelContentWidth = $('.level-content').outerWidth(true)
|
|
goalsViewWidth = $('#goals-view').outerWidth(true)
|
|
codeAreaWidth = $('#code-area').outerWidth(true)
|
|
# problem alert view has 20px padding
|
|
@$el.css('max-width', levelContentWidth - codeAreaWidth - goalsViewWidth + 40 + 'px')
|
|
@$el.css('right', codeAreaWidth + 'px')
|
|
|
|
# 110px from top roughly aligns top of alert with top of first code line
|
|
# TODO: calculate this in a more dynamic, less sketchy way
|
|
@$el.css('top', (110 + @lineOffsetPx) + 'px')
|