Merged big .executing arrow.

This commit is contained in:
Nick Winter 2014-11-07 16:06:14 -08:00
commit cfff09b01e
44 changed files with 398 additions and 240 deletions

View file

@ -193,6 +193,8 @@ module.exports = class CocoRouter extends Backbone.Router
onNavigate: (e) -> onNavigate: (e) ->
manualView = e.view or e.viewClass manualView = e.view or e.viewClass
if (e.route is document.location.pathname) and not manualView
return document.location.reload()
@navigate e.route, {trigger: not manualView} @navigate e.route, {trigger: not manualView}
return unless manualView return unless manualView
if e.viewClass if e.viewClass

Binary file not shown.

After

(image error) Size: 65 KiB

View file

Before

(image error) Size: 1.5 KiB

After

(image error) Size: 1.5 KiB

Before After
Before After

View file

@ -1,8 +1,6 @@
CocoClass = require 'lib/CocoClass' CocoClass = require 'lib/CocoClass'
PlayHeroesModal = require 'views/play/modal/PlayHeroesModal' PlayHeroesModal = require 'views/play/modal/PlayHeroesModal'
InventoryModal = require 'views/game-menu/InventoryModal' InventoryModal = require 'views/game-menu/InventoryModal'
PlayLevelView = require 'views/play/level/PlayLevelView'
LadderView = require 'views/play/ladder/LadderView'
LevelSession = require 'models/LevelSession' LevelSession = require 'models/LevelSession'
SuperModel = require 'models/SuperModel' SuperModel = require 'models/SuperModel'
@ -10,7 +8,6 @@ module.exports = class LevelSetupManager extends CocoClass
constructor: (@options) -> constructor: (@options) ->
super() super()
@options.showDevBits = true #?
@supermodel = new SuperModel() @supermodel = new SuperModel()
@session = @options.session @session = @options.session
if @session if @session
@ -71,6 +68,8 @@ module.exports = class LevelSetupManager extends CocoClass
onInventoryModalPlayClicked: -> onInventoryModalPlayClicked: ->
@navigatingToPlay = true @navigatingToPlay = true
PlayLevelView = require 'views/play/level/PlayLevelView'
LadderView = require 'views/play/ladder/LadderView'
viewClass = if @options.levelPath is 'ladder' then LadderView else PlayLevelView viewClass = if @options.levelPath is 'ladder' then LadderView else PlayLevelView
Backbone.Mediator.publish 'router:navigate', { Backbone.Mediator.publish 'router:navigate', {
route: "/play/#{@options.levelPath || 'level'}/#{@options.levelID}" route: "/play/#{@options.levelPath || 'level'}/#{@options.levelID}"

View file

@ -28,7 +28,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
about: "О нас" about: "О нас"
contact: "Контакты" contact: "Контакты"
twitter_follow: "Подписаться" twitter_follow: "Подписаться"
# teachers: "Teachers" teachers: "Учителям"
modal: modal:
close: "Закрыть" close: "Закрыть"
@ -51,11 +51,11 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
players: "игроки" # Hover over a level on /play players: "игроки" # Hover over a level on /play
hours_played: "часов сыграно" # Hover over a level on /play hours_played: "часов сыграно" # Hover over a level on /play
items: "Предметы" # Tooltip on item shop button from /play items: "Предметы" # Tooltip on item shop button from /play
# unlock: "Unlock" # For purchasing items and heroes unlock: "Разблокировать" # For purchasing items and heroes
# confirm: "Confirm" confirm: "Подтвердить"
# owned: "Owned" # For items you own # owned: "Owned" # For items you own
# locked: "Locked" # locked: "Locked"
# skills_granted: "Skills Granted" # Property documentation details skills_granted: "Умение получено" # Property documentation details
heroes: "Герои" # Tooltip on hero shop button from /play heroes: "Герои" # Tooltip on hero shop button from /play
achievements: "Достижения" # Tooltip on achievement list button from /play achievements: "Достижения" # Tooltip on achievement list button from /play
account: "Аккаунт" # Tooltip on account button from /play account: "Аккаунт" # Tooltip on account button from /play
@ -81,8 +81,8 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
campaign_player_created_description: "... в которых вы сражаетесь с креативностью ваших друзей <a href=\"/contribute#artisan\">Ремесленников</a>." campaign_player_created_description: "... в которых вы сражаетесь с креативностью ваших друзей <a href=\"/contribute#artisan\">Ремесленников</a>."
campaign_classic_algorithms: "Классические принципы" campaign_classic_algorithms: "Классические принципы"
campaign_classic_algorithms_description: "... которые чаще всего встречаются в копьютерных науках." campaign_classic_algorithms_description: "... которые чаще всего встречаются в копьютерных науках."
# campaign_forest: "Forest Campaign" campaign_forest: "Лесная кампания"
# campaign_dungeon: "Dungeon Campaign" campaign_dungeon: "Кампания в подземелье"
login: login:
sign_up: "Создать аккаунт" sign_up: "Создать аккаунт"
@ -109,12 +109,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
# recovery_sent: "Recovery email sent." # recovery_sent: "Recovery email sent."
items: items:
# primary: "Primary" primary: "Основное"
# secondary: "Secondary" secondary: "Второстепенное"
armor: "Броня" armor: "Броня"
accessories: "Аксессуары" accessories: "Аксессуары"
misc: "Разное" misc: "Разное"
# books: "Books" books: "Книги"
common: common:
loading: "Загрузка..." loading: "Загрузка..."
@ -183,7 +183,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
play_level: play_level:
done: "Готово" done: "Готово"
home: "На главную" # Not used any more, will be removed soon. home: "На главную" # Not used any more, will be removed soon.
# level: "Level" # Like "Level: Dungeons of Kithgard" level: "Уровень" # Like "Level: Dungeons of Kithgard"
skip: "Пропустить" skip: "Пропустить"
game_menu: "Меню игры" game_menu: "Меню игры"
guide: "Руководство" guide: "Руководство"
@ -206,13 +206,13 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
victory_rate_the_level: "Оцените уровень:" # Only in old-style levels. victory_rate_the_level: "Оцените уровень:" # Only in old-style levels.
victory_return_to_ladder: "Вернуться к ладдеру" victory_return_to_ladder: "Вернуться к ладдеру"
victory_play_continue: "Продолжить" victory_play_continue: "Продолжить"
# victory_play_skip: "Skip Ahead" victory_play_skip: "Пропустить"
victory_play_next_level: "Следующий уровень" victory_play_next_level: "Следующий уровень"
# victory_play_more_practice: "More Practice" victory_play_more_practice: "Попрактиковаться еще"
# victory_play_too_easy: "Too Easy" victory_play_too_easy: "Очень легко"
# victory_play_just_right: "Just Right" victory_play_just_right: "То, что надо"
# victory_play_too_hard: "Too Hard" victory_play_too_hard: "Очень сложно"
# victory_saving_progress: "Saving Progress" victory_saving_progress: "Процесс сохранения"
victory_go_home: "На главную" # Only in old-style levels. victory_go_home: "На главную" # Only in old-style levels.
victory_review: "Расскажите нам больше!" # Only in old-style levels. victory_review: "Расскажите нам больше!" # Only in old-style levels.
victory_hour_of_code_done: "Вы закончили?" victory_hour_of_code_done: "Вы закончили?"
@ -224,18 +224,18 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
tome_cast_button_castable: "Читать заклинание" # Temporary, if tome_cast_button_run isn't translated. tome_cast_button_castable: "Читать заклинание" # Temporary, if tome_cast_button_run isn't translated.
tome_cast_button_casting: "Заклинание читается" # Temporary, if tome_cast_button_running isn't translated. tome_cast_button_casting: "Заклинание читается" # Temporary, if tome_cast_button_running isn't translated.
tome_cast_button_cast: "Заклинание прочитано" # Temporary, if tome_cast_button_ran isn't translated. tome_cast_button_cast: "Заклинание прочитано" # Temporary, if tome_cast_button_ran isn't translated.
# tome_cast_button_run: "Run" tome_cast_button_run: "Запустить"
# tome_cast_button_running: "Running" tome_cast_button_running: "В процессе"
# tome_cast_button_ran: "Ran" tome_cast_button_ran: "Запущен"
# tome_submit_button: "Submit" tome_submit_button: "Отправить"
# tome_reload_method: "Reload original code for this method" # Title text for individual method reload button. tome_reload_method: "Загрузить оригинальный код для этого метода" # Title text for individual method reload button.
# tome_select_method: "Select a Method" tome_select_method: "Выбрать метод"
# tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methdos). tome_see_all_methods: "Показать все методы, доступные для редактирования" # Title text for method list selector (shown when there are multiple programmable methdos).
tome_select_a_thang: "Выбрать кого-нибудь для " tome_select_a_thang: "Выбрать кого-нибудь для "
tome_available_spells: "Доступные заклинания" tome_available_spells: "Доступные заклинания"
tome_your_skills: "Ваши навыки" tome_your_skills: "Ваши навыки"
hud_continue: "Продолжить (Shift+Пробел)" hud_continue: "Продолжить (Shift+Пробел)"
# hud_continue_short: "Continue" hud_continue_short: "Продолжить"
code_saved: "Код сохранен" code_saved: "Код сохранен"
skip_tutorial: "Пропуск (Esc)" skip_tutorial: "Пропуск (Esc)"
keyboard_shortcuts: "Горячие клавиши" keyboard_shortcuts: "Горячие клавиши"
@ -285,22 +285,22 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
options_tab: "Настройки" options_tab: "Настройки"
guide_tab: "Руководство" guide_tab: "Руководство"
multiplayer_tab: "Мультиплеер" multiplayer_tab: "Мультиплеер"
# auth_tab: "Sign Up" auth_tab: "Зарегистрироваться"
inventory_caption: "Оденьте своего героя" inventory_caption: "Оденьте своего героя"
choose_hero_caption: "Выбор героя, языка" choose_hero_caption: "Выбор героя, языка"
# save_load_caption: "... and view history" save_load_caption: "... и посмотреть историю"
options_caption: "Выбор настроек" options_caption: "Выбор настроек"
# guide_caption: "Docs and tips" # guide_caption: "Docs and tips"
multiplayer_caption: "Играй с друзьями!" multiplayer_caption: "Играй с друзьями!"
# auth_caption: "Save your progress." auth_caption: "Сохранить прогресс."
inventory: inventory:
choose_inventory: "Выбрать предметы" choose_inventory: "Выбрать предметы"
# equipped_item: "Equipped" equipped_item: "Выбранный"
# available_item: "Available" available_item: "Доступный"
# should_equip: "(double-click to equip)" should_equip: "(двойной клик чтобы одеть)"
# equipped: "(equipped)" equipped: "(выбранный)"
# locked: "(locked)" locked: "(заблокированный)"
choose_hero: choose_hero:
choose_hero: "Выберите героя" choose_hero: "Выберите героя"
@ -314,13 +314,13 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
io_blurb: "Простой, но непонятный." io_blurb: "Простой, но непонятный."
status: "Статус" status: "Статус"
weapons: "Оружие" weapons: "Оружие"
# attack: "Damage" # Can also translate as "Attack" attack: "Урон" # Can also translate as "Attack"
health: "Жизнь" health: "Жизнь"
speed: "Скорость" speed: "Скорость"
# regeneration: "Regeneration" regeneration: "Регенерация"
# range: "Range" # As in "attack or visual range" range: "Зона" # As in "attack or visual range"
# blocks: "Blocks" # As in "this shield blocks this much damage" blocks: "Блокирует" # As in "this shield blocks this much damage"
# skills: "Skills" skills: "Умения"
save_load: save_load:
granularity_saved_games: "Сохранено" granularity_saved_games: "Сохранено"

View file

@ -123,3 +123,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']}, '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'} 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']}

View file

@ -1,88 +1,66 @@
@import "app/styles/mixins" @import "app/styles/mixins"
#game-menu-modal #game-menu-modal
//- Clear modal defaults
.close
// We have to style this indendently because it's not in the header (we don't have a header).
position: absolute
top: -5px
right: 0
padding: 15px
font-size: 28px
background-color: transparent
z-index: 1
@include opacity(0.60)
&:hover
@include opacity(1)
// Make room for an overlaid close button in the lower right (we don't have a footer).
.overlaid-close-button
position: absolute
right: 35px
bottom: 20px
#inventory-modal #available-equipment
bottom: 60px
.modal-dialog .modal-dialog
margin-top: 0 width: 820px
width: 963px height: 570px
padding: 0
background: none
position: relative
top: 40px
.nav-tabs
h2 //- Background
margin: 0
#game-menu-background
position: absolute
top: -146px
left: -3px
//- Nav bar
#game-menu-nav
position: absolute
top: 53px
left: 42px
width: 178px
li
background: url(/images/pages/play/modal/menu-tab.png)
padding: 5px
margin: -5px 0
height: 80px
padding: 0
&.active
background: url(/images/pages/play/modal/menu-tab-selected.png)
width: 197px
.auth-tab
a a
h2, em font-size: 18px
pointer-events: none line-height: 50px
background: none
.tab-pane color: rgb(195,153,124)
h3:first-child font-weight: bold
margin-top: 0 padding: 14px 20px
font-family: Open Sans Condensed
// http://stackoverflow.com/questions/18432577/stacked-tabs-in-bootstrap-3 text-transform: uppercase
.tabs-left
> .nav-tabs .glyphicon
float: left margin-right: 6px
width: 185px
border-bottom: 0
> .tab-content
padding: 0px 15px
margin-left: 185px
.tab-content > .tab-pane, .pill-content > .pill-pane
display: none
.tab-content > .active, .pill-content > .active
display: block
.tabs-left
> .nav-tabs > li
float: none
> a
min-width: 74px
margin-right: 0
margin-bottom: 0
.tabs-left > .nav-tabs
border-right: 1px solid #ddd
> li > a
margin-right: -1px
-webkit-border-radius: 4px 0 0 4px
-moz-border-radius: 4px 0 0 4px
border-radius: 4px 0 0 4px
&:hover, &:focus
border-color: #eee #ddd #eee #eee
> .active a
&, &:hover, &:focus
border-color: #ddd transparent #ddd #ddd
*border-right-color: #fff
//- Tab panels
.game-menu-tab-content
position: absolute
left: 219px
top: 21px
width: 571px
height: 518px
padding: 50px
overflow: scroll

View file

@ -1,45 +1,137 @@
@import "app/styles/bootstrap/variables" @import "app/styles/bootstrap/variables"
#options-view #options-view
.select-group, .slider-group
display: block //- Volume slider
min-height: 20px
margin-top: 10px #volume-group
margin-bottom: 10px position: relative
padding-left: 20px width: 100%
vertical-align: middle height: 25px
margin: 15px 0
& > *
position: absolute
.ui-slider
left: 40px
right: 40px
top: 4px
background-color: rgb(248,169,67)
border: 4px solid rgb(26,21,18)
height: 18px
border-radius: 18px
.ui-slider-handle
background-color: rgb(26,21,18)
width: 28px
height: 28px
border-radius: 28px
top: -9px
outline: 0
.glyphicon
font-size: 30px
top: -2px
color: rgb(26,21,18)
.glyphicon-volume-down
position: absolute
left: 0
.glyphicon-volume-up
position: absolute
right: 0
//- header, horizontal rule
.hr
width: 100%
height: 10px
h3
margin-top: 5px
color: rgb(26,21,18)
//- All form groups
.form-group
font-size: 16px
color: rgb(51,51,51)
padding-top: 4px
padding-left: 40px
label
font-weight: normal
//- Check boxes
.form-group.checkbox
label label
font-weight: normal position: relative
margin-right: 20px
margin-bottom: 0
.slider
width: 200px
.form-group.radio-inline
input input
margin-left: 0px display: none
margin-right: 5px
& + .custom-checkbox
.radio-inline-parent-label .glyphicon
padding-left: 0 display: none
&:checked + .custom-checkbox .glyphicon
display: inline
color: rgb(248,169,67)
text-align: center
text-shadow: 0 0 3px black, 0 0 3px black, 0 0 3px black
font-size: 14px
position: relative
top: -1px
.custom-checkbox
border-radius: 2px
height: 27px
width: 27px
border: 4px solid rgb(26,21,18)
position: absolute
background: rgb(228,217,196)
text-align: center
// this undoes the padding of the form groups
left: -40px
top: -4px
//- Select boxes
select
border: 3px solid black
text-transform: uppercase
//.form-group.radio-inline
// input
// margin-left: 0px
// margin-right: 5px
//
// .radio-inline-parent-label
// padding-left: 0
//
//
#player-avatar-container #player-avatar-container
position: relative position: relative
margin: 0px 0px 15px 15px margin: 0 auto 40px
width: 230px width: 230px
max-height: 230px max-height: 230px
border-radius: 6px border-radius: 6px
img.profile-photo img.profile-photo
width: 100% width: 100%
border-radius: 6px border-radius: 6px
&.saving &.saving
opacity: 0.5 opacity: 0.5
.profile-caption .profile-caption
background-color: rgba(0, 0, 0, 0.5) background-color: rgba(0, 0, 0, 0.5)
color: white color: white
@ -52,7 +144,7 @@
text-align: center text-align: center
border: 0 border: 0
font-size: 18px font-size: 18px
.editable-icon .editable-icon
display: block display: block
position: absolute position: absolute
@ -61,11 +153,11 @@
font-size: 20px font-size: 20px
color: $blue color: $blue
opacity: 0.5 opacity: 0.5
&:hover &:hover
cursor: pointer cursor: pointer
box-shadow: 0px 0px 2px 1px $blue box-shadow: 0px 0px 2px 1px $blue
.editable-icon .editable-icon
opacity: 1.0 opacity: 1.0
cursor: pointer cursor: pointer

View file

@ -1,16 +1,17 @@
@import "app/styles/mixins" @import "app/styles/mixins"
@import "app/styles/bootstrap/variables" @import "app/styles/bootstrap/variables"
.problem-alert
#problem-alert-view.problem-alert
z-index: 10 z-index: 10
position: absolute position: absolute
// Position these at the end of the spell editor, right above the spell toolbar. // Position these at the end of the spell editor, right above the spell toolbar.
bottom: -20px top: 45px
left: 10px right: 500px
right: 10px
background: transparent background: transparent
border: 1px solid transparent border: 1px solid transparent
padding: 0 padding: 0
font-size: 18px
text-shadow: none text-shadow: none
color: white color: white
word-wrap: break-word word-wrap: break-word

View file

@ -74,6 +74,14 @@
//background-color: rgba(255, 255, 255, 0.25) //background-color: rgba(255, 255, 255, 0.25)
width: 47px width: 47px
margin-left: 4px margin-left: 4px
// override ace visible to get the experimental large current line executing arrow visible
.ace_gutter
overflow: visible
.ace_layer
overflow: visible
// End experiment....
.ace_scroller .ace_scroller
background-color: transparent background-color: transparent
@ -109,10 +117,29 @@
background-size: 40px 40px background-size: 40px 40px
@include animation(progress-bar-stripes 0.5s linear infinite) @include animation(progress-bar-stripes 0.5s linear infinite)
.ace_gutter-cell.executing:not(.ace_error):not(.ace_warning):not(.ace_info) .ace_gutter-cell.executing:not(.ace_error):not(.ace_warning):not(.ace_info):after
margin-left: 1px
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMjgwMTE3NDA3MjA2ODExOEE2REU4Q0M1MTM1MkIxRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBQjVEQUNDMzQ4RUIxMUUxOEVGRUUyNzFENDM3RDVFMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBQjVEQUNDMjQ4RUIxMUUxOEVGRUUyNzFENDM3RDVFMCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTU1MjE3RDIzMTIwNjgxMThEQkI4NTlBMjQ1QTEwOTUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4MDExNzQwNzIwNjgxMThBNkRFOENDNTEzNTJCMUYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7SazaGAAAAiElEQVR42mL8//8/AzUBEwOVweA3kAWboI2jCyhgDwBx4ZH9ey5Qy4UOQHweaHg/EAtQ08sFUIMDqBmGCkC8HmgoCCtQM1ICoK5toGYsg8KzHmjo+UGbDj8AcSMwORkSnQ7xgA3QtPmApISNBTyAGrSBGl6eAMSGxBhGyIVkZT3G0fKQYgAQYACL+C2ZM6PC7AAAAABJRU5ErkJggg==) // Experimenting with a larger executing-line-pointer
background-position: 0px center content: "\e072"
position: relative
top: -31px
left: -39px
display: inline-block
font-family: 'Glyphicons Halflings'
font-style: normal
font-weight: normal
line-height: 1
color: white
text-shadow: 0 0 5px black, 0 0 5px black, 0 0 5px black
font-size: 39px
-webkit-font-smoothing: antialiased
-moz-osx-font-smoothing: grayscale
//display: block
//margin-left: 1px
//background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMjgwMTE3NDA3MjA2ODExOEE2REU4Q0M1MTM1MkIxRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBQjVEQUNDMzQ4RUIxMUUxOEVGRUUyNzFENDM3RDVFMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBQjVEQUNDMjQ4RUIxMUUxOEVGRUUyNzFENDM3RDVFMCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTU1MjE3RDIzMTIwNjgxMThEQkI4NTlBMjQ1QTEwOTUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4MDExNzQwNzIwNjgxMThBNkRFOENDNTEzNTJCMUYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7SazaGAAAAiElEQVR42mL8//8/AzUBEwOVweA3kAWboI2jCyhgDwBx4ZH9ey5Qy4UOQHweaHg/EAtQ08sFUIMDqBmGCkC8HmgoCCtQM1ICoK5toGYsg8KzHmjo+UGbDj8AcSMwORkSnQ7xgA3QtPmApISNBTyAGrSBGl6eAMSGxBhGyIVkZT3G0fKQYgAQYACL+C2ZM6PC7AAAAABJRU5ErkJggg==)
//background-position: 0px center
.ace_gutter-cell.executed:not(.ace_error):not(.ace_warning):not(.ace_info) .ace_gutter-cell.executed:not(.ace_error):not(.ace_warning):not(.ace_info)
margin-left: 1px margin-left: 1px

View file

@ -77,10 +77,10 @@ $heroCanvasHeight: 265px
height: 98px height: 98px
margin: 0 -11px margin: 0 -11px
position: relative position: relative
background: url(/images/pages/play/modal/hero_portrait_picker_inactive.png) background: url(/images/pages/play/modal/hero-portrait.png)
border: none border: none
&.active &.active
background: url(/images/pages/play/modal/hero_portrait_picker_active.png) background: url(/images/pages/play/modal/hero-portrait-selected.png)
z-index: 5 z-index: 5
.hero-avatar .hero-avatar

View file

@ -12,6 +12,7 @@
overflow: hidden overflow: hidden
text-overflow: ellipsis text-overflow: ellipsis
//- Clear modal defaults //- Clear modal defaults
.modal-dialog .modal-dialog
padding: 0 padding: 0
@ -86,7 +87,7 @@
width: 178px width: 178px
li li
background: url(/images/pages/play/modal/play-items-modal-tab.png) background: url(/images/pages/play/modal/menu-tab.png)
padding: 5px padding: 5px
margin: -5px 0 margin: -5px 0
height: 80px height: 80px
@ -100,11 +101,9 @@
font-weight: bold font-weight: bold
padding: 10px 7px padding: 10px 7px
//img
li.active li.active
background: url(/images/pages/play/modal/play-items-modal-selected-tab.png) background: url(/images/pages/play/modal/menu-tab-selected.png)
width: 197px width: 197px
a a
@ -136,7 +135,7 @@
padding: 10px padding: 10px
height: 195px height: 195px
float: left float: left
background: url(/images/pages/play/modal/play-items-modal-item-background.png) background: url(/images/pages/play/modal/item-box-background.png)
margin: 4px margin: 4px
text-align: center text-align: center
position: relative position: relative
@ -220,7 +219,7 @@
font-size: 16px font-size: 16px
&.selected &.selected
background: url(/images/pages/play/modal/play-items-modal-selected-item-background.png) background: url(/images/pages/play/modal/item-box-background-selected.png)
//- Item list scrollbar //- Item list scrollbar

View file

@ -111,7 +111,7 @@ block content
li.row li.row
img(src="/images/pages/about/placeholder.png").img-thumbnail img(src="/images/pages/about/matt_small.png").img-thumbnail
.team_bio .team_bio

View file

@ -1,32 +1,28 @@
extends /templates/modal/modal_base .modal-dialog
.modal-content
img(src="/images/pages/play/modal/game-menu-background.png")#game-menu-background
block modal-header ul#game-menu-nav.nav.nav-pills.nav-stacked
li
a#change-hero-tab
span.glyphicon.glyphicon-user
span(data-i18n='play.change_hero')
block modal-body-content
.button.close(type="button", data-dismiss="modal", aria-hidden="true") &times;
.tabbable.tabs-left
- var submenus = ["save-load", "options", "guide", "multiplayer"]
- if (!showsGuide) {
- submenus.splice(2, 1);
- }
- if (!showDevBits) { // Not done yet.
- submenus.splice(0, 1);
- }
ul.nav.nav-tabs#game-menu-nav
for submenu, index in submenus for submenu, index in submenus
li(class=submenu === showTab || index === 0 && !showTab ? "active" : "") li(class=submenu === showTab ? "active" : "")
a(href='#' + submenu + '-view', data-toggle='tab') a(href='#' + submenu + '-view', data-toggle='tab')
h2(data-i18n='game_menu.' + submenu.replace('-', '_') + '_tab') span.glyphicon(class="glyphicon-"+iconMap[submenu])
em(data-i18n='game_menu.' + submenu.replace('-', '_') + '_caption') span(data-i18n='game_menu.' + submenu.replace('-', '_') + '_tab')
if me.get('anonymous') if me.get('anonymous')
li.auth-tab(data-toggle='coco-modal', data-target="modal/AuthModal") li.auth-tab(data-toggle='coco-modal', data-target="modal/AuthModal")
a(data-toggle='coco-modal', data-target="modal/AuthModal") a(data-toggle='coco-modal', data-target="modal/AuthModal")
h2(data-i18n='game_menu.auth_tab') span.glyphicon.glyphicon-pencil
em(data-i18n='game_menu.auth_caption') span(data-i18n='game_menu.auth_tab')
.tab-content
.tab-content.game-menu-tab-content
for submenu, index in submenus for submenu, index in submenus
.tab-pane(id=submenu + '-view') .tab-pane(id=submenu + '-view')
.clearfix // .clearfix
//
block modal-footer //block modal-footer
button.btn.btn-primary.btn-lg.overlaid-close-button(type="button", data-dismiss="modal", aria-hidden="true", data-i18n="modal.close") Close // button.btn.btn-primary.btn-lg.overlaid-close-button(type="button", data-dismiss="modal", aria-hidden="true", data-i18n="modal.close") Close

View file

@ -1,4 +1,4 @@
#player-avatar-container(title="Click to change your avatar").pull-right #player-avatar-container(title="Click to change your avatar")
if !me.get('photoURL') if !me.get('photoURL')
.editable-icon.glyphicon.glyphicon-pencil .editable-icon.glyphicon.glyphicon-pencil
img.profile-photo(src=me.getPhotoURL(230)) img.profile-photo(src=me.getPhotoURL(230))
@ -6,60 +6,72 @@
input#player-name.profile-caption(name="playerName", type="text", value=me.get('name', true)) input#player-name.profile-caption(name="playerName", type="text", value=me.get('name', true))
.form .form
h3(data-i18n="options.general_options") General Options
.form-group.slider-group h3(data-i18n="options.general_options") General Options
label(for="option-volume")
span(data-i18n="options.volume_label") Volume .form-group.slider-group#volume-group
span.spr : span.glyphicon.glyphicon-volume-down
span#option-volume-value= (me.get('volume') * 100).toFixed(0) + '%' #option-volume.slider.spr.spl
#option-volume.slider span.glyphicon.glyphicon-volume-up
.form-group.checkbox .form-group.checkbox
label(for="option-music") label(for="option-music").control-label
input#option-music(name="option-music", type="checkbox", checked=music) input#option-music(name="option-music", type="checkbox", checked=music)
span.custom-checkbox
.glyphicon.glyphicon-ok
span(data-i18n="options.music_label") Music span(data-i18n="options.music_label") Music
span.help-block(data-i18n="options.music_description") Turn background music on/off. span.help-block(data-i18n="options.music_description") Turn background music on/off.
.form-group.select-group .form-group.select-group
label.control-label(for="option-autorun-delay", data-i18n="options.autorun_label") Autorun label.control-label(for="option-autorun-delay", data-i18n="options.autorun_label") Autorun
select#option-autorun-delay(name="autorunDelay") select#option-autorun-delay.form-control(name="autorunDelay")
option(value=1000, selected=(autorunDelay === 1000), data-i18n="common.delay_1_sec") 1 second option(value=1000, selected=(autorunDelay === 1000), data-i18n="common.delay_1_sec") 1 second
option(value=3000, selected=(autorunDelay === 3000), data-i18n="common.delay_3_sec") 3 seconds option(value=3000, selected=(autorunDelay === 3000), data-i18n="common.delay_3_sec") 3 seconds
option(value=5000, selected=(autorunDelay === 5000), data-i18n="common.delay_5_sec") 5 seconds option(value=5000, selected=(autorunDelay === 5000), data-i18n="common.delay_5_sec") 5 seconds
option(value=90019001, selected=(autorunDelay === 90019001), data-i18n="common.manual") Manual option(value=90019001, selected=(autorunDelay === 90019001), data-i18n="common.manual") Manual
span.help-block(data-i18n="options.autorun_description") Control automatic code execution. span.help-block(data-i18n="options.autorun_description") Control automatic code execution.
img.hr(src="/images/pages/play/modal/hr.png")
h3(data-i18n="options.editor_config_title") Editor Configuration h3(data-i18n="options.editor_config_title") Editor Configuration
.form-group.select-group .form-group.select-group
label.control-label(for="option-key-bindings", data-i18n="options.editor_config_keybindings_label") Key Bindings label.control-label(for="option-key-bindings", data-i18n="options.editor_config_keybindings_label") Key Bindings
select#option-key-bindings(name="keyBindings") select#option-key-bindings.form-control(name="keyBindings")
option(value="default", selected=(aceConfig.keyBindings === "default"), data-i18n="options.editor_config_keybindings_default") Default (Ace) option(value="default", selected=(aceConfig.keyBindings === "default"), data-i18n="options.editor_config_keybindings_default") Default (Ace)
option(value="vim", selected=(aceConfig.keyBindings === "vim")) Vim option(value="vim", selected=(aceConfig.keyBindings === "vim")) Vim
option(value="emacs", selected=(aceConfig.keyBindings === "emacs")) Emacs option(value="emacs", selected=(aceConfig.keyBindings === "emacs")) Emacs
span.help-block(data-i18n="options.editor_config_keybindings_description") Adds additional shortcuts known from the common editors. span.help-block(data-i18n="options.editor_config_keybindings_description") Adds additional shortcuts known from the common editors.
.form-group.checkbox .form-group.checkbox
label(for="option-live-completion") label(for="option-live-completion")
input#option-live-completion(name="liveCompletion", type="checkbox", checked=aceConfig.liveCompletion) input#option-live-completion(name="liveCompletion", type="checkbox", checked=aceConfig.liveCompletion)
span.custom-checkbox
.glyphicon.glyphicon-ok
span(data-i18n="options.editor_config_livecompletion_label") Live Autocompletion span(data-i18n="options.editor_config_livecompletion_label") Live Autocompletion
span.help-block(data-i18n="options.editor_config_livecompletion_description") Displays autocomplete suggestions while typing. span.help-block(data-i18n="options.editor_config_livecompletion_description") Displays autocomplete suggestions while typing.
.form-group.checkbox .form-group.checkbox
label(for="option-invisibles") label(for="option-invisibles")
input#option-invisibles(name="invisibles", type="checkbox", checked=aceConfig.invisibles) input#option-invisibles(name="invisibles", type="checkbox", checked=aceConfig.invisibles)
span.custom-checkbox
.glyphicon.glyphicon-ok
span(data-i18n="options.editor_config_invisibles_label") Show Invisibles span(data-i18n="options.editor_config_invisibles_label") Show Invisibles
span.help-block(data-i18n="options.editor_config_invisibles_description") Displays invisibles such as spaces or tabs. span.help-block(data-i18n="options.editor_config_invisibles_description") Displays invisibles such as spaces or tabs.
.form-group.checkbox .form-group.checkbox
label(for="option-indent-guides") label(for="option-indent-guides")
input#option-indent-guides(name="indentGuides", type="checkbox", checked=aceConfig.indentGuides) input#option-indent-guides(name="indentGuides", type="checkbox", checked=aceConfig.indentGuides)
span.custom-checkbox
.glyphicon.glyphicon-ok
span(data-i18n="options.editor_config_indentguides_label") Show Indent Guides span(data-i18n="options.editor_config_indentguides_label") Show Indent Guides
span.help-block(data-i18n="options.editor_config_indentguides_description") Displays vertical lines to see indentation better. span.help-block(data-i18n="options.editor_config_indentguides_description") Displays vertical lines to see indentation better.
.form-group.checkbox .form-group.checkbox
label(for="option-behaviors") label(for="option-behaviors")
input#option-behaviors(name="behaviors", type="checkbox", checked=aceConfig.behaviors) input#option-behaviors(name="behaviors", type="checkbox", checked=aceConfig.behaviors)
span.custom-checkbox
.glyphicon.glyphicon-ok
span(data-i18n="options.editor_config_behaviors_label") Smart Behaviors span(data-i18n="options.editor_config_behaviors_label") Smart Behaviors
span.help-block(data-i18n="options.editor_config_behaviors_description") Autocompletes brackets, braces, and quotes. span.help-block(data-i18n="options.editor_config_behaviors_description") Autocompletes brackets, braces, and quotes.

View file

@ -20,6 +20,8 @@
#gold-view #gold-view
#problem-alert-view
#level-chat-view #level-chat-view
#multiplayer-status-view #multiplayer-status-view

View file

@ -1,4 +1,4 @@
button.close(type="button", data-dismiss="alert") &times; button.close(type="button") &times;
if hint if hint
span.problem-title!= hint span.problem-title!= hint
br br

View file

@ -8,13 +8,13 @@
img.item-img(src=item.getPortraitURL()) img.item-img(src=item.getPortraitURL())
img.item-shadow(src=item.getPortraitURL()) img.item-shadow(src=item.getPortraitURL())
img.hr(src="/images/pages/play/modal/play-items-modal-hr.png") img.hr(src="/images/pages/play/modal/hr.png")
for stat in stats for stat in stats
div.stat-row.big-font div.stat-row.big-font
div.stat-label= stat.name div.stat-label= stat.name
div.stat= stat.display div.stat= stat.display
img.hr(src="/images/pages/play/modal/play-items-modal-hr.png" class=stat.isLast ? "" : "faded") img.hr(src="/images/pages/play/modal/hr.png" class=stat.isLast ? "" : "faded")
if props.length if props.length
#skills #skills

View file

@ -1,7 +1,7 @@
.modal-dialog .modal-dialog
.modal-content .modal-content
img(src="/images/pages/play/modal/play-heroes-background.png")#play-heroes-background img(src="/images/pages/play/modal/heroes-background.png")#play-heroes-background
h1(data-i18n="choose_hero.choose_hero") h1(data-i18n="choose_hero.choose_hero")

View file

@ -1,7 +1,7 @@
.modal-dialog .modal-dialog
.modal-content .modal-content
img(src="/images/pages/play/modal/play-items-modal-background.png")#play-items-modal-bg img(src="/images/pages/play/modal/items-background.png")#play-items-modal-bg
img(src="/images/pages/play/modal/play-items-modal-background-narrow.png")#play-items-modal-narrow-bg img(src="/images/pages/play/modal/items-background-narrow.png")#play-items-modal-narrow-bg
h1.big-font(data-i18n="play.items") h1.big-font(data-i18n="play.items")
@ -15,7 +15,7 @@
for category, index in itemCategories for category, index in itemCategories
li(class=index ? "" : "active") li(class=index ? "" : "active")
a.one-line(href="#item-category-" + category, data-toggle="tab") a.one-line(href="#item-category-" + category, data-toggle="tab")
img.tab-icon(src="/images/pages/play/modal/play-items-modal-tab-icon-"+category+".png") img.tab-icon(src="/images/pages/play/modal/item-icon-"+category+".png")
span.big-font= itemCategoryNames[index] span.big-font= itemCategoryNames[index]

View file

@ -34,4 +34,4 @@ module.exports = class HomeView extends RootView
e.preventDefault() e.preventDefault()
e.stopImmediatePropagation() e.stopImmediatePropagation()
window.tracker?.trackEvent 'Homepage', Action: 'Play' window.tracker?.trackEvent 'Homepage', Action: 'Play'
window.open '/play', '_blank' window.open '/play', '_blank'

View file

@ -8,6 +8,7 @@ submenuViews = [
] ]
module.exports = class GameMenuModal extends ModalView module.exports = class GameMenuModal extends ModalView
className: 'modal fade play-modal'
template: template template: template
id: 'game-menu-modal' id: 'game-menu-modal'
instant: true instant: true
@ -15,10 +16,10 @@ module.exports = class GameMenuModal extends ModalView
events: events:
'change input.select': 'onSelectionChanged' 'change input.select': 'onSelectionChanged'
'shown.bs.tab #game-menu-nav a': 'onTabShown' 'shown.bs.tab #game-menu-nav a': 'onTabShown'
'click #change-hero-tab': -> @trigger 'change-hero'
constructor: (options) -> constructor: (options) ->
super options super options
@options.showDevBits = me.isAdmin() or /https?:\/\/localhost/.test(window.location.href)
@options.showTab = options.showTab @options.showTab = options.showTab
@options.levelID = @options.level.get('slug') @options.levelID = @options.level.get('slug')
@options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {}) @options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {})
@ -26,10 +27,17 @@ module.exports = class GameMenuModal extends ModalView
getRenderData: (context={}) -> getRenderData: (context={}) ->
context = super(context) context = super(context)
context.showDevBits = @options.showDevBits
context.showTab = @options.showTab
docs = @options.level.get('documentation') ? {} docs = @options.level.get('documentation') ? {}
context.showsGuide = docs.specificArticles?.length or docs.generalArticles?.length submenus = ["options", "save-load", "guide", "multiplayer"]
submenus = _.without submenus, 'guide' unless docs.specificArticles?.length or docs.generalArticles?.length
submenus = _.without submenus, 'save-load' unless me.isAdmin() or /https?:\/\/localhost/.test(window.location.href)
context.showTab = @options.showTab ? submenus[0]
context.submenus = submenus
context.iconMap =
'options': 'cog'
'guide': 'list'
'save-load': 'floppy-disk'
'multiplayer': 'globe'
context context
afterRender: -> afterRender: ->

View file

@ -72,6 +72,7 @@ module.exports = class OptionsView extends CocoView
@aceConfig.behaviors = @$el.find('#option-behaviors').prop('checked') @aceConfig.behaviors = @$el.find('#option-behaviors').prop('checked')
@aceConfig.liveCompletion = @$el.find('#option-live-completion').prop('checked') @aceConfig.liveCompletion = @$el.find('#option-live-completion').prop('checked')
me.set 'aceConfig', @aceConfig me.set 'aceConfig', @aceConfig
me.patch()
Backbone.Mediator.publish 'tome:change-config', {} Backbone.Mediator.publish 'tome:change-config', {}
updateMusic: -> updateMusic: ->

View file

@ -4,6 +4,7 @@ template = require 'templates/play/level/control_bar'
GameMenuModal = require 'views/game-menu/GameMenuModal' GameMenuModal = require 'views/game-menu/GameMenuModal'
RealTimeCollection = require 'collections/RealTimeCollection' RealTimeCollection = require 'collections/RealTimeCollection'
LevelSetupManager = require 'lib/LevelSetupManager'
module.exports = class ControlBarView extends CocoView module.exports = class ControlBarView extends CocoView
id: 'control-bar-view' id: 'control-bar-view'
@ -63,7 +64,11 @@ module.exports = class ControlBarView extends CocoView
c c
showGameMenuModal: -> showGameMenuModal: ->
@openModalView new GameMenuModal level: @level, session: @session, supermodel: @supermodel gameMenuModal = new GameMenuModal level: @level, session: @session, supermodel: @supermodel
@openModalView gameMenuModal
@listenToOnce gameMenuModal, 'change-hero', ->
setupManager = new LevelSetupManager({supermodel: @supermodel, levelID: @level.get('slug'), parent: @})
setupManager.open()
onClickHome: (e) -> onClickHome: (e) ->
e.preventDefault() e.preventDefault()

View file

@ -23,6 +23,7 @@ RealTimeCollection = require 'collections/RealTimeCollection'
# subviews # subviews
LevelLoadingView = require './LevelLoadingView' LevelLoadingView = require './LevelLoadingView'
ProblemAlertView = require './tome/ProblemAlertView'
TomeView = require './tome/TomeView' TomeView = require './tome/TomeView'
ChatView = require './LevelChatView' ChatView = require './LevelChatView'
HUDView = require './LevelHUDView' HUDView = require './LevelHUDView'
@ -34,7 +35,6 @@ GoldView = require './LevelGoldView'
VictoryModal = require './modal/VictoryModal' VictoryModal = require './modal/VictoryModal'
HeroVictoryModal = require './modal/HeroVictoryModal' HeroVictoryModal = require './modal/HeroVictoryModal'
InfiniteLoopModal = require './modal/InfiniteLoopModal' InfiniteLoopModal = require './modal/InfiniteLoopModal'
GameMenuModal = require 'views/game-menu/GameMenuModal'
MultiplayerStatusView = require './MultiplayerStatusView' MultiplayerStatusView = require './MultiplayerStatusView'
LevelSetupManager = require 'lib/LevelSetupManager' LevelSetupManager = require 'lib/LevelSetupManager'
@ -249,6 +249,7 @@ module.exports = class PlayLevelView extends RootView
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session @insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
if @level.get('type') in ['ladder', 'hero-ladder'] if @level.get('type') in ['ladder', 'hero-ladder']
@insertSubView new MultiplayerStatusView levelID: @levelID, session: @session, level: @level @insertSubView new MultiplayerStatusView levelID: @levelID, session: @session, level: @level
@insertSubView new ProblemAlertView {}
worldName = utils.i18n @level.attributes, 'name' worldName = utils.i18n @level.attributes, 'name'
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel} @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' #_.delay (=> Backbone.Mediator.publish('level:set-debug', debug: true)), 5000 if @isIPadApp() # if me.displayName() is 'Nick'

View file

@ -1,20 +1,14 @@
ProblemAlertView = require './ProblemAlertView'
Range = ace.require('ace/range').Range Range = ace.require('ace/range').Range
module.exports = class Problem module.exports = class Problem
annotation: null annotation: null
alertView: null
markerRange: null markerRange: null
constructor: (@aether, @aetherProblem, @ace, withAlert=false, isCast=false, @levelID) -> constructor: (@aether, @aetherProblem, @ace, isCast=false, @levelID) ->
@buildAnnotation() @buildAnnotation()
@buildAlertView() if withAlert
@buildMarkerRange() if isCast @buildMarkerRange() if isCast
Backbone.Mediator.publish("problem:problem-created", line:@annotation.row, text: @annotation.text) if application.isIPadApp Backbone.Mediator.publish("problem:problem-created", line:@annotation.row, text: @annotation.text) if application.isIPadApp
destroy: -> destroy: ->
unless @alertView?.destroyed
@alertView?.$el?.remove()
@alertView?.destroy()
@removeMarkerRange() @removeMarkerRange()
@userCodeProblem.off() if @userCodeProblem @userCodeProblem.off() if @userCodeProblem
@ -29,11 +23,6 @@ module.exports = class Problem
text: text, text: text,
type: @aetherProblem.level ? 'error' type: @aetherProblem.level ? 'error'
buildAlertView: ->
@alertView = new ProblemAlertView problem: @
@alertView.render()
$(@ace.container).append @alertView.el
buildMarkerRange: -> buildMarkerRange: ->
return unless @aetherProblem.range return unless @aetherProblem.range
[start, end] = @aetherProblem.range [start, end] = @aetherProblem.range

View file

@ -3,32 +3,68 @@ template = require 'templates/play/level/tome/problem_alert'
{me} = require 'lib/auth' {me} = require 'lib/auth'
module.exports = class ProblemAlertView extends CocoView module.exports = class ProblemAlertView extends CocoView
id: 'problem-alert-view'
className: 'problem-alert' className: 'problem-alert'
template: template template: template
subscriptions: {} subscriptions:
'tome:show-problem-alert': 'onShowProblemAlert'
'tome:manual-cast': 'onHideProblemAlert'
'real-time-multiplayer:manual-cast': 'onHideProblemAlert'
events: events:
'click .close': 'onRemoveClicked' 'click .close': 'onRemoveClicked'
constructor: (options) -> constructor: (options) ->
super 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={}) -> getRenderData: (context={}) ->
context = super context context = super context
format = (s) -> s?.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>') if @problem?
context.message = format @problem.aetherProblem.message format = (s) -> s?.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>')
context.hint = format @problem.aetherProblem.hint context.message = format @problem.aetherProblem.message
context.hint = format @problem.aetherProblem.hint
context context
afterRender: -> afterRender: ->
super() super()
@$el.addClass('alert').addClass("alert-#{@problem.aetherProblem.level}").hide().fadeIn('slow') if @problem?
@$el.addClass('no-hint') unless @problem.aetherProblem.hint @$el.addClass('alert').addClass("alert-#{@problem.aetherProblem.level}").hide().fadeIn('slow')
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'error_appear', volume: 1.0 @$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: -> onRemoveClicked: ->
@$el.remove() @$el.hide()
@destroy() @problem = null
#@problem.destroy() # let's try leaving the annotations / marker ranges alone
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')

View file

@ -515,7 +515,13 @@ module.exports = class SpellView extends CocoView
for aetherProblem, problemIndex in aether.getAllProblems() for aetherProblem, problemIndex in aether.getAllProblems()
continue if key = aetherProblem.userInfo?.key and key of seenProblemKeys continue if key = aetherProblem.userInfo?.key and key of seenProblemKeys
seenProblemKeys[key] = true if key 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 @saveUserCodeProblem(aether, aetherProblem) if isCast
annotations.push problem.annotation if problem.annotation annotations.push problem.annotation if problem.annotation
@aceSession.setAnnotations annotations @aceSession.setAnnotations annotations

View file

@ -188,7 +188,7 @@ module.exports = class PlayHeroesModal extends ModalView
me.patch() if changed me.patch() if changed
@hide() @hide()
@trigger 'confirm-click', hero: @selectedHero @trigger?('confirm-click', hero: @selectedHero)
updateHeroConfig: (model, hero) -> updateHeroConfig: (model, hero) ->
heroConfig = _.clone(model.get('heroConfig')) or {} heroConfig = _.clone(model.get('heroConfig')) or {}