mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 17:45:40 -05:00
Place error message over Surface next to line
This commit is contained in:
parent
f3e4906810
commit
b4dde5705b
8 changed files with 69 additions and 29 deletions
|
@ -126,3 +126,7 @@ module.exports =
|
|||
|
||||
'tome:winnability-updated': c.object {title: 'Winnability Updated', description: 'When we think we can now win (or can no longer win), we may want to emphasize the submit button versus the run button (or vice versa), so this fires when we get new goal states (even preloaded goal states) suggesting success or failure change.', required: ['winnable']},
|
||||
winnable: {type: 'boolean'}
|
||||
|
||||
'tome:show-problem-alert': c.object {title: 'Show Problem Alert', description: 'A problem alert needs to be shown.', required: ['problem']},
|
||||
problem: {type: 'object'}
|
||||
lineOffsetPx: {type: ['number', 'undefined']}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
@import "app/styles/mixins"
|
||||
@import "app/styles/bootstrap/variables"
|
||||
|
||||
.problem-alert
|
||||
|
||||
#problem-alert-view.problem-alert
|
||||
z-index: 10
|
||||
position: absolute
|
||||
// Position these at the end of the spell editor, right above the spell toolbar.
|
||||
bottom: -20px
|
||||
left: 10px
|
||||
right: 10px
|
||||
top: 45px
|
||||
right: 500px
|
||||
background: transparent
|
||||
border: 1px solid transparent
|
||||
padding: 0
|
||||
font-size: 18px
|
||||
text-shadow: none
|
||||
color: white
|
||||
word-wrap: break-word
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#gold-view
|
||||
|
||||
#problem-alert-view
|
||||
|
||||
#level-chat-view
|
||||
|
||||
#multiplayer-status-view
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
button.close(type="button", data-dismiss="alert") ×
|
||||
button.close(type="button") ×
|
||||
if hint
|
||||
span.problem-title!= hint
|
||||
br
|
||||
|
|
|
@ -23,6 +23,7 @@ RealTimeCollection = require 'collections/RealTimeCollection'
|
|||
|
||||
# subviews
|
||||
LevelLoadingView = require './LevelLoadingView'
|
||||
ProblemAlertView = require './tome/ProblemAlertView'
|
||||
TomeView = require './tome/TomeView'
|
||||
ChatView = require './LevelChatView'
|
||||
HUDView = require './LevelHUDView'
|
||||
|
@ -249,6 +250,7 @@ module.exports = class PlayLevelView extends RootView
|
|||
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
||||
if @level.get('type') in ['ladder', 'hero-ladder']
|
||||
@insertSubView new MultiplayerStatusView levelID: @levelID, session: @session, level: @level
|
||||
@insertSubView new ProblemAlertView {}
|
||||
worldName = utils.i18n @level.attributes, 'name'
|
||||
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel}
|
||||
#_.delay (=> Backbone.Mediator.publish('level:set-debug', debug: true)), 5000 if @isIPadApp() # if me.displayName() is 'Nick'
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
ProblemAlertView = require './ProblemAlertView'
|
||||
Range = ace.require('ace/range').Range
|
||||
|
||||
module.exports = class Problem
|
||||
annotation: null
|
||||
alertView: null
|
||||
markerRange: null
|
||||
constructor: (@aether, @aetherProblem, @ace, withAlert=false, isCast=false, @levelID) ->
|
||||
constructor: (@aether, @aetherProblem, @ace, isCast=false, @levelID) ->
|
||||
@buildAnnotation()
|
||||
@buildAlertView() if withAlert
|
||||
@buildMarkerRange() if isCast
|
||||
Backbone.Mediator.publish("problem:problem-created", line:@annotation.row, text: @annotation.text) if application.isIPadApp
|
||||
|
||||
destroy: ->
|
||||
unless @alertView?.destroyed
|
||||
@alertView?.$el?.remove()
|
||||
@alertView?.destroy()
|
||||
@removeMarkerRange()
|
||||
@userCodeProblem.off() if @userCodeProblem
|
||||
|
||||
|
@ -29,11 +23,6 @@ module.exports = class Problem
|
|||
text: text,
|
||||
type: @aetherProblem.level ? 'error'
|
||||
|
||||
buildAlertView: ->
|
||||
@alertView = new ProblemAlertView problem: @
|
||||
@alertView.render()
|
||||
$(@ace.container).append @alertView.el
|
||||
|
||||
buildMarkerRange: ->
|
||||
return unless @aetherProblem.range
|
||||
[start, end] = @aetherProblem.range
|
||||
|
|
|
@ -3,32 +3,68 @@ template = require 'templates/play/level/tome/problem_alert'
|
|||
{me} = require 'lib/auth'
|
||||
|
||||
module.exports = class ProblemAlertView extends CocoView
|
||||
id: 'problem-alert-view'
|
||||
className: 'problem-alert'
|
||||
template: template
|
||||
|
||||
subscriptions: {}
|
||||
subscriptions:
|
||||
'tome:show-problem-alert': 'onShowProblemAlert'
|
||||
'tome:manual-cast': 'onHideProblemAlert'
|
||||
'real-time-multiplayer:manual-cast': 'onHideProblemAlert'
|
||||
|
||||
events:
|
||||
'click .close': 'onRemoveClicked'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@problem = options.problem
|
||||
if options.problem?
|
||||
@problem = options.problem
|
||||
@onWindowResize()
|
||||
else
|
||||
@$el.hide()
|
||||
$(window).on 'resize', @onWindowResize
|
||||
|
||||
destroy: ->
|
||||
$(window).off 'resize', @onWindowResize
|
||||
super()
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
context = super context
|
||||
format = (s) -> s?.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br>')
|
||||
context.message = format @problem.aetherProblem.message
|
||||
context.hint = format @problem.aetherProblem.hint
|
||||
if @problem?
|
||||
format = (s) -> s?.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br>')
|
||||
context.message = format @problem.aetherProblem.message
|
||||
context.hint = format @problem.aetherProblem.hint
|
||||
context
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
@$el.addClass('alert').addClass("alert-#{@problem.aetherProblem.level}").hide().fadeIn('slow')
|
||||
@$el.addClass('no-hint') unless @problem.aetherProblem.hint
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'error_appear', volume: 1.0
|
||||
if @problem?
|
||||
@$el.addClass('alert').addClass("alert-#{@problem.aetherProblem.level}").hide().fadeIn('slow')
|
||||
@$el.addClass('no-hint') unless @problem.aetherProblem.hint
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'error_appear', volume: 1.0
|
||||
|
||||
onShowProblemAlert: (data) ->
|
||||
return if @problem? and data.problem.aetherProblem.message is @problem.aetherProblem.message and data.problem.aetherProblem.hint is @problem.aetherProblem.hint
|
||||
return unless $('#code-area').is(":visible")
|
||||
@problem = data.problem
|
||||
@lineOffsetPx = data.lineOffsetPx or 0
|
||||
@$el.show()
|
||||
@onWindowResize()
|
||||
@render()
|
||||
|
||||
onHideProblemAlert: ->
|
||||
@onRemoveClicked()
|
||||
|
||||
onRemoveClicked: ->
|
||||
@$el.remove()
|
||||
@destroy()
|
||||
#@problem.destroy() # let's try leaving the annotations / marker ranges alone
|
||||
@$el.hide()
|
||||
@problem = null
|
||||
|
||||
onWindowResize: (e) =>
|
||||
# TODO: This all seems a little hacky
|
||||
if @problem?
|
||||
@$el.css('left', $('#goals-view').outerWidth(true) + 'px')
|
||||
@$el.css('right', $('#code-area').outerWidth(true) + 'px')
|
||||
|
||||
# 45px 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', (45 + @lineOffsetPx) + 'px')
|
||||
|
|
|
@ -515,7 +515,13 @@ module.exports = class SpellView extends CocoView
|
|||
for aetherProblem, problemIndex in aether.getAllProblems()
|
||||
continue if key = aetherProblem.userInfo?.key and key of seenProblemKeys
|
||||
seenProblemKeys[key] = true if key
|
||||
@problems.push problem = new Problem aether, aetherProblem, @ace, isCast and problemIndex is 0, isCast, @spell.levelID
|
||||
@problems.push problem = new Problem aether, aetherProblem, @ace, isCast, @spell.levelID
|
||||
if isCast and problemIndex is 0
|
||||
if problem.aetherProblem.range?
|
||||
# Line height is 20px
|
||||
# TODO: Can we get line height dynamically from ace?
|
||||
lineOffsetPx = problem.aetherProblem.range[0].row * 20 - @ace.session.getScrollTop()
|
||||
Backbone.Mediator.publish 'tome:show-problem-alert', problem: problem, lineOffsetPx: lineOffsetPx
|
||||
@saveUserCodeProblem(aether, aetherProblem) if isCast
|
||||
annotations.push problem.annotation if problem.annotation
|
||||
@aceSession.setAnnotations annotations
|
||||
|
|
Loading…
Reference in a new issue