mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-12 08:41:46 -05:00
Merge hero selector and misc fixes
This commit is contained in:
commit
79de50126d
29 changed files with 503 additions and 146 deletions
|
@ -3,4 +3,9 @@ ThangType = require 'models/ThangType'
|
||||||
|
|
||||||
module.exports = class ThangTypeCollection extends CocoCollection
|
module.exports = class ThangTypeCollection extends CocoCollection
|
||||||
url: '/db/thang.type'
|
url: '/db/thang.type'
|
||||||
model: ThangType
|
model: ThangType
|
||||||
|
|
||||||
|
fetchHeroes: ->
|
||||||
|
@fetch {
|
||||||
|
url: '/db/thang.type?view=heroes'
|
||||||
|
}
|
||||||
|
|
|
@ -168,6 +168,13 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
@consolidateFlagHistory() if @opponentSession?.loaded
|
@consolidateFlagHistory() if @opponentSession?.loaded
|
||||||
else if session is @opponentSession
|
else if session is @opponentSession
|
||||||
@consolidateFlagHistory() if @session.loaded
|
@consolidateFlagHistory() if @session.loaded
|
||||||
|
if @level.get('type', true) in ['course'] # course-ladder is hard to handle because there's 2 sessions
|
||||||
|
heroConfig = me.get('heroConfig')
|
||||||
|
return if not heroConfig
|
||||||
|
url = "/db/thang.type/#{heroConfig.thangType}/version"
|
||||||
|
if heroResource = @maybeLoadURL(url, ThangType, 'thang')
|
||||||
|
@worldNecessities.push heroResource
|
||||||
|
return
|
||||||
return unless @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
return unless @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
heroConfig = session.get('heroConfig')
|
heroConfig = session.get('heroConfig')
|
||||||
heroConfig ?= me.get('heroConfig') if session is @session and not @headless
|
heroConfig ?= me.get('heroConfig') if session is @session and not @headless
|
||||||
|
|
|
@ -156,6 +156,8 @@ module.exports =
|
||||||
courseProgress[levelID][userID] = { completed: true, started: false } # These don't matter, will always be set
|
courseProgress[levelID][userID] = { completed: true, started: false } # These don't matter, will always be set
|
||||||
session = _.find classroom.sessions.models, (session) ->
|
session = _.find classroom.sessions.models, (session) ->
|
||||||
session.get('creator') is userID and session.get('level').original is levelID
|
session.get('creator') is userID and session.get('level').original is levelID
|
||||||
|
|
||||||
|
courseProgress[levelID][userID].session = session
|
||||||
|
|
||||||
if not session # haven't gotten to this level yet, but might have completed others before
|
if not session # haven't gotten to this level yet, but might have completed others before
|
||||||
courseProgress.started ||= false #no-op
|
courseProgress.started ||= false #no-op
|
||||||
|
|
|
@ -1314,6 +1314,9 @@
|
||||||
sent_verification: "We've sent a verification email to:"
|
sent_verification: "We've sent a verification email to:"
|
||||||
you_can_edit: "You can edit your email address in "
|
you_can_edit: "You can edit your email address in "
|
||||||
account_settings: "Account Settings"
|
account_settings: "Account Settings"
|
||||||
|
select_your_hero: "Select Your Hero"
|
||||||
|
select_your_hero_description: "You can always change your hero by going to your Courses page and clicking \"Select Hero\""
|
||||||
|
select_this_hero: "Select this Hero"
|
||||||
|
|
||||||
teacher:
|
teacher:
|
||||||
teacher_dashboard: "Teacher Dashboard" # Navbar
|
teacher_dashboard: "Teacher Dashboard" # Navbar
|
||||||
|
|
|
@ -5,8 +5,8 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
no_mobile: "CodeCombat is niet gemaakt voor mobiele apparaten en werkt misschien niet!" # Warning that shows up on mobile devices
|
no_mobile: "CodeCombat is niet gemaakt voor mobiele apparaten en werkt misschien niet!" # Warning that shows up on mobile devices
|
||||||
play: "Speel" # The big play button that opens up the campaign view.
|
play: "Speel" # The big play button that opens up the campaign view.
|
||||||
play_campaign_version: "Speel de Verhaallijn" # Shows up under big play button if you only play /courses
|
play_campaign_version: "Speel de Verhaallijn" # Shows up under big play button if you only play /courses
|
||||||
old_browser: "Oh oh, jouw browser is te oud om CodeCombat te kunnen spelen, Sorry!" # Warning that shows up on really old Firefox/Chrome/Safari
|
old_browser: "uh-oh, jouw browser is te oud om CodeCombat te kunnen spelen, Sorry!" # Warning that shows up on really old Firefox/Chrome/Safari
|
||||||
old_browser_suffix: "Je kan toch proberen, maar het zal waarschijnlijk niet werken!"
|
old_browser_suffix: "Je kan alsnog proberen, maar het zal waarschijnlijk niet werken!"
|
||||||
ipad_browser: "Slecht nieuws: CodeCombat draait niet in je browser op de iPad. Goed nieuws: onze iPad-app wordt op het moment beoordeeld door Apple."
|
ipad_browser: "Slecht nieuws: CodeCombat draait niet in je browser op de iPad. Goed nieuws: onze iPad-app wordt op het moment beoordeeld door Apple."
|
||||||
campaign: "Verhaallijn"
|
campaign: "Verhaallijn"
|
||||||
for_beginners: "Voor Beginners"
|
for_beginners: "Voor Beginners"
|
||||||
|
@ -24,25 +24,25 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
im_a_teacher: "Ik ben een leraar"
|
im_a_teacher: "Ik ben een leraar"
|
||||||
im_a_student: "Ik ben een leerling"
|
im_a_student: "Ik ben een leerling"
|
||||||
learn_more: "Lees verder"
|
learn_more: "Lees verder"
|
||||||
classroom_in_a_box: "Een kant-en-klare digitale klas voor programmeerlessen."
|
classroom_in_a_box: "Kant-en-klare programmeerlessen."
|
||||||
codecombat_is: "CodeCombat is een platform waarmee leerlingen leren programmeren door het spelen van een spel." # {change}
|
codecombat_is: "CodeCombat is een platform waarmee leerlingen leren programmeren door het spelen van een spel." # {change}
|
||||||
our_courses: "Onze lessen zijn specifiek ontwikkeld voor een klasomgeving, zelfs voor leraren zonder programmeerervaring." # {change}
|
our_courses: "Onze lessen zijn specifiek ontwikkeld voor een klasomgeving, zelfs voor leraren zonder programmeerervaring." # {change}
|
||||||
top_screenshots_hint: "Leerlingen schrijven code en zien direct het resultaat van de verandering."
|
top_screenshots_hint: "Leerlingen schrijven code en zien direct resultaat."
|
||||||
designed_with: "Gemaakt voor leraren"
|
designed_with: "Gemaakt voor leraren"
|
||||||
real_code: "Echte, getypte code"
|
real_code: "Echte, getypte code"
|
||||||
from_the_first_level: "vanaf het eerste level"
|
from_the_first_level: "vanaf het eerste level"
|
||||||
getting_students: "Leerlingen zo snel mogelijk echte code laten schrijven is noodzakelijk voor het leren van programmeer syntax en correcte structuur."
|
getting_students: "Doordat leerlingen code schrijven in 'echte programmeertaal', leren ze niet alleen hoe computers denken, maar kunnen ze het ook echt toepassen."
|
||||||
educator_resources: "Lesbrieven voor docenten"
|
educator_resources: "Lesbrieven voor docenten"
|
||||||
course_guides: "en ondersteuningsmateriaal"
|
course_guides: "en ondersteuningsmateriaal"
|
||||||
teaching_computer_science: "Je hebt geen informatica diploma nodig om te kunnen programmeren, wij verschaffen de materialen waarmee elke docent programmeerles kan geven."
|
teaching_computer_science: "Je hebt geen informatica diploma nodig om te kunnen programmeren, wij verschaffen de materialen waarmee elke docent programmeerles kan geven."
|
||||||
accessible_to: "Bereikbaar voor"
|
accessible_to: "Toegankelijk voor"
|
||||||
everyone: "iedereen"
|
everyone: "iedereen"
|
||||||
democratizing: "Programmeerles toegankelijk maken is onze filosofie. Iedereen moet de kans krijgen om te leren programmeren."
|
democratizing: "Programmeerles toegankelijk maken is onze filosofie. Iedereen moet de kans krijgen om te leren programmeren."
|
||||||
forgot_learning: "Volgens mij hadden ze niet meer door dat ze eigenlijk bezig waren met leren."
|
forgot_learning: "Volgens mij hadden ze niet meer door dat ze eigenlijk bezig waren met leren."
|
||||||
wanted_to_do: " Ik wilde altijd al leren programmeren, maar op school was hier nooit aandacht voor."
|
wanted_to_do: " Ik wilde altijd al leren programmeren, maar op school was hier nooit aandacht voor."
|
||||||
why_games: "Waarom is spelenderwijs leren belangrijk?"
|
why_games: "Waarom is spelenderwijs leren belangrijk?"
|
||||||
games_reward: "Games vergroten de productiviteit."
|
games_reward: "Games vergroten de productiviteit."
|
||||||
encourage: "Gaming is een middel dat interactie, nieuwschierigheid, en trial-and-error aanmoedigt. Een goed spel daagt de speler uit zijn vaardigheden te perfectioneren, wat hetzelfde noodzakelijke proces is waar leerlingen doorheen gaan wanneer zij iets leren."
|
encourage: "Iedereen wordt geboren als klein onderzoekertje dat de wereld ontdekt door vallen en opstaan. Deze intrinsieke motivatie om te leren ziet men ook terug in een spelomgeving. Voor de speler wordt 'leren' een middel om het spel te winnen, in plaats van een doel op zich."
|
||||||
excel: "Games helpen bij de"
|
excel: "Games helpen bij de"
|
||||||
struggle: "productiviteit-strijd"
|
struggle: "productiviteit-strijd"
|
||||||
kind_of_struggle: "het soort worsteling dat uitmondt in een leerproces dat uitdagend is en "
|
kind_of_struggle: "het soort worsteling dat uitmondt in een leerproces dat uitdagend is en "
|
||||||
|
@ -58,7 +58,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
great_game: "Een goed spel is meer dan alleen medailles en prestaties - het gaat om een reis, nauwkeurig ontworpen puzzels, en de mogelijkheid om uitdagingen vol zelfvertrouwen aan te pakken."
|
great_game: "Een goed spel is meer dan alleen medailles en prestaties - het gaat om een reis, nauwkeurig ontworpen puzzels, en de mogelijkheid om uitdagingen vol zelfvertrouwen aan te pakken."
|
||||||
agency: "CodeCombat is een game die de mogelijkheid en het zelfvertrouwen geeft om met echte code te werken, wat zowel beginners als gevorderde helpt bij het schrijven van goede, valide code."
|
agency: "CodeCombat is een game die de mogelijkheid en het zelfvertrouwen geeft om met echte code te werken, wat zowel beginners als gevorderde helpt bij het schrijven van goede, valide code."
|
||||||
request_demo_title: "Laat je leerlingen vandaag nog starten!"
|
request_demo_title: "Laat je leerlingen vandaag nog starten!"
|
||||||
request_demo_subtitle: "Vraag een demo aan en start binnen een uur met programmeerlessen."
|
request_demo_subtitle: "Vraag een demo aan en start met programmeerlessen."
|
||||||
get_started_title: "Maak vandaag nog een klas aan!"
|
get_started_title: "Maak vandaag nog een klas aan!"
|
||||||
get_started_subtitle: "Maak een klas aan, voeg je leerlingen toe, en monitor hun vooruitgang."
|
get_started_subtitle: "Maak een klas aan, voeg je leerlingen toe, en monitor hun vooruitgang."
|
||||||
request_demo: "Vraag een demo aan"
|
request_demo: "Vraag een demo aan"
|
||||||
|
@ -74,7 +74,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
coming_soon: "Binnenkort beschikbaar!"
|
coming_soon: "Binnenkort beschikbaar!"
|
||||||
courses_available_in: "Lessen zijn beschikbaar in JavaScript, Python, en Java (Java is binnenkort beschikbaar!)"
|
courses_available_in: "Lessen zijn beschikbaar in JavaScript, Python, en Java (Java is binnenkort beschikbaar!)"
|
||||||
boast: "Uitdagende raadsels die zowel gamers als fanatieke programmeurs weten te prikkelen."
|
boast: "Uitdagende raadsels die zowel gamers als fanatieke programmeurs weten te prikkelen."
|
||||||
winning: "Een gouden combinatie van spel-elementen en programmeerhuiswerk, dat samen zorgt voor kind-vriendelijk en oprecht aangenaam onderwijs."
|
winning: "Een gouden combinatie van spel-elementen en programmeerhuiswerk, dat samen zorgt voor kindvriendelijk en oprecht aangenaam onderwijs."
|
||||||
run_class: "Alles wat je nodig hebt om vandaag nog programmeerlessen in jouw klas te geven, geen voorkennis vereist."
|
run_class: "Alles wat je nodig hebt om vandaag nog programmeerlessen in jouw klas te geven, geen voorkennis vereist."
|
||||||
teachers: "Docenten!"
|
teachers: "Docenten!"
|
||||||
teachers_and_educators: "Docenten & Mentoren"
|
teachers_and_educators: "Docenten & Mentoren"
|
||||||
|
@ -92,7 +92,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
check_out_wiki: "Bekijk onze nieuwe leraren Wiki"
|
check_out_wiki: "Bekijk onze nieuwe leraren Wiki"
|
||||||
want_coco: "Wil je CodeCombat op jouw school?"
|
want_coco: "Wil je CodeCombat op jouw school?"
|
||||||
form_select_role: "Selecteer je rol"
|
form_select_role: "Selecteer je rol"
|
||||||
form_select_range: "Selecteer klassengrootte"
|
form_select_range: "Selecteer klasomvang"
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
play: "Levels" # The top nav bar entry where players choose which levels to play
|
play: "Levels" # The top nav bar entry where players choose which levels to play
|
||||||
|
@ -221,19 +221,19 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
"/": "gedeeld door"
|
"/": "gedeeld door"
|
||||||
"+": "plus"
|
"+": "plus"
|
||||||
"-": "min"
|
"-": "min"
|
||||||
# "+=": "add and assign"
|
"+=": "tel op en wijs toe"
|
||||||
# "-=": "subtract and assign"
|
"-=": "trek af en wijs toe"
|
||||||
True: "Waar"
|
True: "Waar"
|
||||||
true: "waar"
|
true: "waar"
|
||||||
False: "onwaar"
|
False: "onwaar"
|
||||||
false: "onwaar"
|
false: "onwaar"
|
||||||
undefined: "ongedefinieerd"
|
undefined: "ongedefinieerd"
|
||||||
# null: "null"
|
null: "nul"
|
||||||
# nil: "nil"
|
nil: "nihil"
|
||||||
None: "Geen"
|
None: "Geen"
|
||||||
|
|
||||||
share_progress_modal:
|
share_progress_modal:
|
||||||
blurb: "Je gaat snel vooruit! Vertel aan je ouders hoeveel je geleerd hebt van CodeCombat."
|
blurb: "Je gaat snel vooruit! Vertel je ouders hoeveel je geleerd hebt van CodeCombat."
|
||||||
email_invalid: "E-mailadres klopt niet."
|
email_invalid: "E-mailadres klopt niet."
|
||||||
form_blurb: "Vul het e-mailadres van je ouders hieronder in en we zullen het ze laten zien!"
|
form_blurb: "Vul het e-mailadres van je ouders hieronder in en we zullen het ze laten zien!"
|
||||||
form_label: "E-mailadres"
|
form_label: "E-mailadres"
|
||||||
|
@ -472,19 +472,19 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
tip_reticulating: "Paden aan het verknopen."
|
tip_reticulating: "Paden aan het verknopen."
|
||||||
tip_harry: "Je bent een tovenaar, "
|
tip_harry: "Je bent een tovenaar, "
|
||||||
tip_great_responsibility: "Met een groots talent voor programmeren komt een grootse debug verantwoordelijkheid."
|
tip_great_responsibility: "Met een groots talent voor programmeren komt een grootse debug verantwoordelijkheid."
|
||||||
tip_munchkin: "Als je je groentjes niet opeet zal een munchkin je ontvoeren terwijl je slaapt."
|
tip_munchkin: "Als je je groenten niet opeet zal een munchkin je ontvoeren terwijl je slaapt."
|
||||||
tip_binary: "Er zijn 10 soorten mensen in de wereld: Mensen die binair kunnen tellen en mensen die dat niet kunnen."
|
tip_binary: "Er zijn 10 soorten mensen in de wereld: Mensen die binair kunnen tellen en mensen die dat niet kunnen."
|
||||||
tip_commitment_yoda: "Een programmeur moet de grootste inzet hebben, een meest serieuze geest. ~ Yoda"
|
tip_commitment_yoda: "Een programmeur moet de grootste inzet hebben, een meest serieuze geest. ~ Yoda"
|
||||||
tip_no_try: "Doe het. Of doe het niet. Je kunt niet proberen. - Yoda"
|
tip_no_try: "Doe het. Of doe het niet. Je kunt niet proberen. - Yoda"
|
||||||
tip_patience: "Geduld moet je hebben, jonge Padawan. - Yoda"
|
tip_patience: "Geduld moet je hebben, jonge Padawan. - Yoda"
|
||||||
tip_documented_bug: "Een gedocumenteerde fout is geen fout; het is deel van het programma."
|
tip_documented_bug: "Een gedocumenteerde fout is geen fout; het is deel van het programma."
|
||||||
tip_impossible: "Het lijkt altijd onmogelijk tot het gedaan wordt. - Nelson Mandela"
|
tip_impossible: "Het lijkt altijd onmogelijk totdat iemand het doet. - Nelson Mandela"
|
||||||
tip_talk_is_cheap: "Je kunt het goed uitleggen, maar toon me de code. - Linus Torvalds"
|
tip_talk_is_cheap: "Je kunt het goed uitleggen, maar toon me de code. - Linus Torvalds"
|
||||||
tip_first_language: "Het ergste dat je kan leren is je eerste programmeertaal. - Alan Kay"
|
tip_first_language: "Het ergste dat je kan leren is je eerste programmeertaal. - Alan Kay"
|
||||||
tip_hardware_problem: "Q: Hoeveel programmeurs heb je nodig om een lampje te vervangen? A: Nul, het is een a hardware probleem."
|
tip_hardware_problem: "Q: Hoeveel programmeurs heb je nodig om een lampje te vervangen? A: Nul, het is een a hardware probleem."
|
||||||
tip_hofstadters_law: "De Wet van Hofstadter: Het duurt altijd langer dan je verwacht, zelfs wanneer je rekening houdt met de Wet van Hofstadter."
|
tip_hofstadters_law: "De Wet van Hofstadter: Het duurt altijd langer dan je verwacht, zelfs wanneer je rekening houdt met de Wet van Hofstadter."
|
||||||
tip_premature_optimization: "vroegtijdig optimaliseren is de wortel van al het kwaad. - Donald Knuth"
|
tip_premature_optimization: "vroegtijdig optimaliseren is de wortel van al het kwaad. - Donald Knuth"
|
||||||
tip_brute_force: "Wanneer je twijfelt, gebruik brute force. - Ken Thompson"
|
tip_brute_force: "Wanneer je twijfelt, gebruik dan brute force. - Ken Thompson"
|
||||||
tip_extrapolation: "Er zijn twee soorten mensen: Zij die iets kunnen afleiden van onvolledige gegevens..."
|
tip_extrapolation: "Er zijn twee soorten mensen: Zij die iets kunnen afleiden van onvolledige gegevens..."
|
||||||
tip_superpower: "Van alle dingen komt programmeren het dichtst in de buurt van een superkracht."
|
tip_superpower: "Van alle dingen komt programmeren het dichtst in de buurt van een superkracht."
|
||||||
tip_control_destiny: "In echte open source, hebt je het recht om je eigen toekomst te bepalen. - Linus Torvalds"
|
tip_control_destiny: "In echte open source, hebt je het recht om je eigen toekomst te bepalen. - Linus Torvalds"
|
||||||
|
@ -820,8 +820,8 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
|
||||||
teachers_quote:
|
teachers_quote:
|
||||||
name: "Demo Formulier"
|
name: "Demo Formulier"
|
||||||
title: "Demo aanvragen"
|
title: "Demo aanvragen"
|
||||||
subtitle: "Haal CodeCombat jouw klaslokaal of club!"
|
subtitle: "Gebruik CodeCombat voor jouw klas of programmeerclub!"
|
||||||
email_exists: "Er bestaat al een gebruiker met dit email adres."
|
email_exists: "Er bestaat al een gebruiker met dit emailadres."
|
||||||
phone_number: "Telefoonnummer"
|
phone_number: "Telefoonnummer"
|
||||||
phone_number_help: "Waarop kunnen we je bereiken tijdens kantooruren?"
|
phone_number_help: "Waarop kunnen we je bereiken tijdens kantooruren?"
|
||||||
primary_role_label: "Uw primaire rol"
|
primary_role_label: "Uw primaire rol"
|
||||||
|
|
|
@ -686,21 +686,21 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# writable: "writable" # Hover over "attack" in Your Skills while playing a level to see most of this
|
# writable: "writable" # Hover over "attack" in Your Skills while playing a level to see most of this
|
||||||
# read_only: "read-only"
|
# read_only: "read-only"
|
||||||
action: "Aкција"
|
action: "Aкција"
|
||||||
# spell: "Spell"
|
spell: "Магија"
|
||||||
# action_name: "name"
|
action_name: "име"
|
||||||
# action_cooldown: "Takes"
|
action_cooldown: "Потребно"
|
||||||
# action_specific_cooldown: "Cooldown"
|
action_specific_cooldown: "Хлађење"
|
||||||
# action_damage: "Damage"
|
action_damage: "Штета"
|
||||||
# action_range: "Range"
|
action_range: "Домет"
|
||||||
# action_radius: "Radius"
|
action_radius: "Опсег"
|
||||||
# action_duration: "Duration"
|
action_duration: "Трајање"
|
||||||
# example: "Example"
|
example: "Пример"
|
||||||
# ex: "ex" # Abbreviation of "example"
|
ex: "нпр." # Abbreviation of "example"
|
||||||
# current_value: "Current Value"
|
current_value: "Тренутна вредност"
|
||||||
# default_value: "Default value"
|
default_value: "Подразумевана вредност"
|
||||||
# parameters: "Parameters"
|
parameters: "Параметри"
|
||||||
# returns: "Returns"
|
returns: "Враћа"
|
||||||
# granted_by: "Granted by"
|
granted_by: "Додељено од"
|
||||||
|
|
||||||
save_load:
|
save_load:
|
||||||
granularity_saved_games: "Сачувано"
|
granularity_saved_games: "Сачувано"
|
||||||
|
@ -860,12 +860,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
finish_signup_p: "Направи налог да оснујеш разред, додаш своје ученике и пратиш њихов напредак док уче компјутерске науке."
|
finish_signup_p: "Направи налог да оснујеш разред, додаш своје ученике и пратиш њихов напредак док уче компјутерске науке."
|
||||||
signup_with: "Пријави се са:"
|
signup_with: "Пријави се са:"
|
||||||
connect_with: "Повежи се са:"
|
connect_with: "Повежи се са:"
|
||||||
# conversion_warning: "WARNING: Your current account is a <em>Student Account</em>. Once you submit this form, your account will be updated to a Teacher Account."
|
conversion_warning: "УПОЗОРЕЊЕ: Твој тренутни налог је <em>Студентски Налог</em>. Након што пошаљеш овај формулар, твој налог ће бити надограђен у Учитељски Налог."
|
||||||
# learn_more_modal: "Teacher accounts on CodeCombat have the ability to monitor student progress, assign enrollments and manage classrooms. Teacher accounts cannot be a part of a classroom - if you are currently enrolled in a class using this account, you will no longer be able to access it once you update to a Teacher Account."
|
learn_more_modal: "Учитељски налози на CodeCombat-у имају могућност посматрања напретка ученика, додељивања уписа и управљања учионицама. Учитељски налози не могу бити део учионице - ако си тренутно уписан у разред преко овог налога, нећеш више моћи да му приступиш кад ажурираш у Учитељски Налог."
|
||||||
create_account: "Направи учитељски налог"
|
create_account: "Направи учитељски налог"
|
||||||
# create_account_subtitle: "Get access to teacher-only tools for using CodeCombat in the classroom. <strong>Set up a class</strong>, add your students, and <strong>monitor their progress</strong>!"
|
create_account_subtitle: "Добиј приступ алатима само за учитеље за коришћење CodeCombat-а у учионици. <strong>Подеси разред</strong>, додај своје ученике, и <strong>посматрај њихов напредак</strong>!"
|
||||||
# convert_account_title: "Update to Teacher Account"
|
convert_account_title: "Ажурирај у Учитељски Налог"
|
||||||
# not: "Not"
|
not: "Није"
|
||||||
setup_a_class: "Подеси разред"
|
setup_a_class: "Подеси разред"
|
||||||
|
|
||||||
versions:
|
versions:
|
||||||
|
@ -880,18 +880,18 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
|
|
||||||
contact:
|
contact:
|
||||||
contact_us: "Контактирај CodeCombat"
|
contact_us: "Контактирај CodeCombat"
|
||||||
welcome: "Драго нам је што нас контактираш! Искористи ову форму да нам пошаљеш мејл. "
|
welcome: "Драго нам је што нас контактираш! Искористи овај формулар да нам пошаљеш мејл. "
|
||||||
forum_prefix: "За било шта јавно, посети "
|
forum_prefix: "За било шта јавно, посети "
|
||||||
forum_page: "наш форум."
|
forum_page: "наш форум"
|
||||||
# forum_suffix: " instead."
|
forum_suffix: " уместо тога."
|
||||||
# faq_prefix: "There's also a"
|
faq_prefix: "Такође, ту је"
|
||||||
# faq: "FAQ"
|
faq: "FAQ"
|
||||||
# subscribe_prefix: "If you need help figuring out a level, please"
|
subscribe_prefix: "Ако ти треба помоћ да разумеш ниво, молимо да"
|
||||||
# subscribe: "buy a CodeCombat subscription"
|
subscribe: "купиш CodeCombat претплату"
|
||||||
# subscribe_suffix: "and we'll be happy to help you with your code."
|
subscribe_suffix: "и радо ћемо ти помоћи у твом коду."
|
||||||
# subscriber_support: "Since you're a CodeCombat subscriber, your email will get our priority support."
|
subscriber_support: "Пошто си CodeCombat претплатник, твој мејл ће имати приоритет у нашој подршци."
|
||||||
# screenshot_included: "Screenshot included."
|
screenshot_included: "Снимак екрана укључен."
|
||||||
# where_reply: "Where should we reply?"
|
where_reply: "Где треба да одговоримо?"
|
||||||
send: "Пошаљи повратну информацију"
|
send: "Пошаљи повратну информацију"
|
||||||
|
|
||||||
account_settings:
|
account_settings:
|
||||||
|
@ -910,24 +910,24 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# god_mode: "God Mode"
|
# god_mode: "God Mode"
|
||||||
password_tab: "Шифра"
|
password_tab: "Шифра"
|
||||||
emails_tab: "Мејлови"
|
emails_tab: "Мејлови"
|
||||||
# admin: "Admin"
|
admin: "Администратор"
|
||||||
manage_subscription: "Кликни овде да би управљао својом претплатом."
|
manage_subscription: "Кликни овде да би управљао својом претплатом."
|
||||||
new_password: "Нова Шифра"
|
new_password: "Нова Шифра"
|
||||||
new_password_verify: "Потврди"
|
new_password_verify: "Потврди"
|
||||||
# type_in_email: "Type in your email to confirm account deletion."
|
type_in_email: "Упиши свој мејл да потврдиш брисање налога."
|
||||||
# type_in_email_progress: "Type in your email to confirm deleting your progress."
|
type_in_email_progress: "Упиши свој мејл да потврдиш брисање свог напретка."
|
||||||
# type_in_password: "Also, type in your password."
|
type_in_password: "Такође, упиши своју шифру."
|
||||||
email_subscriptions: "Мејл претплате"
|
email_subscriptions: "Мејл претплате"
|
||||||
# email_subscriptions_none: "No Email Subscriptions."
|
email_subscriptions_none: "Без мејл претплата."
|
||||||
email_announcements: "Обавештења"
|
email_announcements: "Обавештења"
|
||||||
email_announcements_description: "Прими мејл за најновије вести и достигнућа на CodeCombat-у"
|
email_announcements_description: "Прими мејл за најновије вести и достигнућа на CodeCombat-у"
|
||||||
# email_notifications: "Notifications"
|
email_notifications: "Обавештења"
|
||||||
# email_notifications_summary: "Controls for personalized, automatic email notifications related to your CodeCombat activity."
|
email_notifications_summary: "Контроле за персонализована, аутоматска мејл обавештења вазана за твоју CodeCombat активност."
|
||||||
# email_any_notes: "Any Notifications"
|
email_any_notes: "Сва обавештења"
|
||||||
# email_any_notes_description: "Disable to stop all activity notification emails."
|
email_any_notes_description: "Онемогући да би прекинуо сва мејл обавештења о активности."
|
||||||
email_news: "Вести"
|
email_news: "Вести"
|
||||||
email_recruit_notes: "Пословне могућности"
|
email_recruit_notes: "Пословне могућности"
|
||||||
# email_recruit_notes_description: "If you play really well, we may contact you about getting you a (better) job."
|
email_recruit_notes_description: "Ако играш јако добро, можда ћемо те контактирати о томе да добијеш (бољи) посао."
|
||||||
contributor_emails: "Мејлови реда сарадника"
|
contributor_emails: "Мејлови реда сарадника"
|
||||||
contribute_prefix: "Тражимо људе који би нам се придружили! Погледај "
|
contribute_prefix: "Тражимо људе који би нам се придружили! Погледај "
|
||||||
contribute_page: "страницу за сарадњу"
|
contribute_page: "страницу за сарадњу"
|
||||||
|
@ -961,13 +961,13 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
|
|
||||||
community:
|
community:
|
||||||
main_title: "CodeCombat Заједница"
|
main_title: "CodeCombat Заједница"
|
||||||
# introduction: "Check out the ways you can get involved below and decide what sounds the most fun. We look forward to working with you!"
|
introduction: "Погледај испод како можеш да се укључиш и одлучи шта звучи најзанимљивије. Радујемо се прилици да радимо са тобом!"
|
||||||
# level_editor_prefix: "Use the CodeCombat"
|
level_editor_prefix: "Користи CodeCombat"
|
||||||
# level_editor_suffix: "to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!"
|
level_editor_suffix: "да правиш и уређујеш нивое. Корисници су направили нивое за њихове разреде, пријатеље, хакатоне, ученике и браћу и сестре. Ако прављење новог нивоа звучи застрашујуће, можеш да почнеш форковањем једног од наших!"
|
||||||
# thang_editor_prefix: "We call units within the game 'thangs'. Use the"
|
thang_editor_prefix: "Ми зовемо јединице у игри 'thangs'. Користи"
|
||||||
# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites."
|
thang_editor_suffix: "да модификујеш CodeCombat изворне илустрације. Дозволи јединицама да бацају пројектиле, измени дирекцију анимације, промени хит поене јединице или отпреми сопствене векторске спрајтове."
|
||||||
# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the"
|
article_editor_prefix: "Видиш грешку у неком од наших докумената? Желиш да направиш инструкције за сопствене креације? Погледај"
|
||||||
# article_editor_suffix: "and help CodeCombat players get the most out of their playtime."
|
article_editor_suffix: "и помози CodeCombat играчима да добију највише од свог играња."
|
||||||
find_us: "Нађи нас на овим сајтовима"
|
find_us: "Нађи нас на овим сајтовима"
|
||||||
social_github: "Погледај цео наш код на GitHub-у"
|
social_github: "Погледај цео наш код на GitHub-у"
|
||||||
social_blog: "Читај CodeCombat блог на Sett-у"
|
social_blog: "Читај CodeCombat блог на Sett-у"
|
||||||
|
@ -986,57 +986,57 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
make_private: "Направи клан приватним"
|
make_private: "Направи клан приватним"
|
||||||
subs_only: "само за претплатнике"
|
subs_only: "само за претплатнике"
|
||||||
create_clan: "Направи нови клан"
|
create_clan: "Направи нови клан"
|
||||||
private_preview: "Preview"
|
private_preview: "Приказ"
|
||||||
private_clans: "Приватни кланови"
|
private_clans: "Приватни кланови"
|
||||||
public_clans: "Јавни кланови"
|
public_clans: "Јавни кланови"
|
||||||
my_clans: "Моји кланови"
|
my_clans: "Моји кланови"
|
||||||
clan_name: "Име клана"
|
clan_name: "Име клана"
|
||||||
name: "Име"
|
name: "Име"
|
||||||
# chieftain: "Chieftain"
|
chieftain: "Поглавица"
|
||||||
# type: "Type"
|
type: "Врста"
|
||||||
edit_clan_name: "Измени име клана"
|
edit_clan_name: "Измени име клана"
|
||||||
edit_clan_description: "Измени опис клана"
|
edit_clan_description: "Измени опис клана"
|
||||||
edit_name: "измени име"
|
edit_name: "измени име"
|
||||||
edit_description: "измени опис"
|
edit_description: "измени опис"
|
||||||
private: "(приватан)"
|
private: "(приватан)"
|
||||||
# summary: "Summary"
|
summary: "Преглед"
|
||||||
# average_level: "Average Level"
|
average_level: "Просечни ниво"
|
||||||
# average_achievements: "Average Achievements"
|
average_achievements: "Просечна достигнућа"
|
||||||
delete_clan: "Избриши клан"
|
delete_clan: "Избриши клан"
|
||||||
leave_clan: "Напусти клан"
|
leave_clan: "Напусти клан"
|
||||||
join_clan: "Придружи се клану"
|
join_clan: "Придружи се клану"
|
||||||
invite_1: "Позови:"
|
invite_1: "Позови:"
|
||||||
# invite_2: "*Invite players to this Clan by sending them this link."
|
invite_2: "*Позови играче у овај Клан тако што ћеш им послати овај линк."
|
||||||
members: "Чланови"
|
members: "Чланови"
|
||||||
progress: "Напредак"
|
progress: "Напредак"
|
||||||
# not_started_1: "not started"
|
not_started_1: "није започето"
|
||||||
# started_1: "started"
|
started_1: "започето"
|
||||||
# complete_1: "complete"
|
complete_1: "заврши"
|
||||||
# exp_levels: "Expand levels"
|
exp_levels: "Прошири нивое"
|
||||||
# rem_hero: "Remove Hero"
|
rem_hero: "Уклони Хероја"
|
||||||
status: "Статус"
|
status: "Статус"
|
||||||
# complete_2: "Complete"
|
complete_2: "Заврши"
|
||||||
# started_2: "Started"
|
started_2: "Започето"
|
||||||
# not_started_2: "Not Started"
|
not_started_2: "Није започето"
|
||||||
# view_solution: "Click to view solution."
|
view_solution: "Кликни да видиш решење."
|
||||||
# view_attempt: "Click to view attempt."
|
view_attempt: "Кликни да видиш покушај."
|
||||||
# latest_achievement: "Latest Achievement"
|
latest_achievement: "Последње достигнуће"
|
||||||
# playtime: "Playtime"
|
playtime: "Време игања"
|
||||||
# last_played: "Last played"
|
last_played: "Последњи пут играно"
|
||||||
# leagues_explanation: "Play in a league against other clan members in these multiplayer arena instances."
|
leagues_explanation: "Играј у лиги против других чланова клана у овим мултиплејер инстанцама арене."
|
||||||
# track_concepts1: "Track concepts"
|
track_concepts1: "Прати концепте"
|
||||||
# track_concepts2a: "learned by each student"
|
track_concepts2a: "научене од сваког ученика"
|
||||||
# track_concepts2b: "learned by each member"
|
track_concepts2b: "научене од сваког члана"
|
||||||
# track_concepts3a: "Track levels completed for each student"
|
track_concepts3a: "Прати завршене нивое за сваког ученика"
|
||||||
# track_concepts3b: "Track levels completed for each member"
|
track_concepts3b: "Прати завршене нивое за сваког члана"
|
||||||
# track_concepts4a: "See your students'"
|
track_concepts4a: "Види од својих ученика"
|
||||||
# track_concepts4b: "See your members'"
|
track_concepts4b: "Види од својих чланова"
|
||||||
# track_concepts5: "solutions"
|
track_concepts5: "решења"
|
||||||
# track_concepts6a: "Sort students by name or progress"
|
track_concepts6a: "Сортирај ученике према имену или напретку"
|
||||||
# track_concepts6b: "Sort members by name or progress"
|
track_concepts6b: "Сортирај чланове према имену или напретку"
|
||||||
# track_concepts7: "Requires invitation"
|
track_concepts7: "Захтева позив"
|
||||||
# track_concepts8: "to join"
|
track_concepts8: "за придруживање"
|
||||||
# private_require_sub: "Private clans require a subscription to create or join."
|
private_require_sub: "Приватни кланови захтевају претплату да би могао да их направиш или да им се придружиш."
|
||||||
|
|
||||||
# courses:
|
# courses:
|
||||||
# course: "Course"
|
# course: "Course"
|
||||||
|
@ -1488,12 +1488,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# add_system_title: "Add Systems to Level"
|
# add_system_title: "Add Systems to Level"
|
||||||
# done_adding: "Done Adding"
|
# done_adding: "Done Adding"
|
||||||
|
|
||||||
# article:
|
article:
|
||||||
# edit_btn_preview: "Preview"
|
edit_btn_preview: "Приказ"
|
||||||
# edit_article_title: "Edit Article"
|
edit_article_title: "Измени Чланак"
|
||||||
|
|
||||||
# polls:
|
polls:
|
||||||
# priority: "Priority"
|
priority: "Приоритет"
|
||||||
|
|
||||||
# contribute:
|
# contribute:
|
||||||
# page_title: "Contributing"
|
# page_title: "Contributing"
|
||||||
|
@ -1645,17 +1645,17 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# favorite_postfix: "."
|
# favorite_postfix: "."
|
||||||
# not_member_of_clans: "Not a member of any clans yet."
|
# not_member_of_clans: "Not a member of any clans yet."
|
||||||
|
|
||||||
# achievements:
|
achievements:
|
||||||
# last_earned: "Last Earned"
|
last_earned: "Последње стечено"
|
||||||
# amount_achieved: "Amount"
|
amount_achieved: "Количина"
|
||||||
# achievement: "Achievement"
|
achievement: "Достигнуће"
|
||||||
# current_xp_prefix: ""
|
current_xp_prefix: ""
|
||||||
# current_xp_postfix: " in total"
|
current_xp_postfix: " укупно"
|
||||||
# new_xp_prefix: ""
|
new_xp_prefix: ""
|
||||||
# new_xp_postfix: " earned"
|
new_xp_postfix: " стечено"
|
||||||
# left_xp_prefix: ""
|
left_xp_prefix: ""
|
||||||
# left_xp_infix: " until level "
|
left_xp_infix: " до нивоа "
|
||||||
# left_xp_postfix: ""
|
left_xp_postfix: ""
|
||||||
|
|
||||||
account:
|
account:
|
||||||
payments: "Уплате"
|
payments: "Уплате"
|
||||||
|
|
|
@ -368,6 +368,7 @@ class CocoModel extends Backbone.Model
|
||||||
return if _.isString @url then @url else @url()
|
return if _.isString @url then @url else @url()
|
||||||
|
|
||||||
@pollAchievements: ->
|
@pollAchievements: ->
|
||||||
|
return if application.testing
|
||||||
|
|
||||||
CocoCollection = require 'collections/CocoCollection'
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
EarnedAchievement = require 'models/EarnedAchievement'
|
EarnedAchievement = require 'models/EarnedAchievement'
|
||||||
|
|
|
@ -145,6 +145,11 @@ module.exports = class Level extends CocoModel
|
||||||
for original, placeholderComponent of placeholders when not placeholdersUsed[original]
|
for original, placeholderComponent of placeholders when not placeholdersUsed[original]
|
||||||
levelThang.components.push placeholderComponent
|
levelThang.components.push placeholderComponent
|
||||||
|
|
||||||
|
# Load the user's chosen hero AFTER getting stats from default char
|
||||||
|
if /Hero Placeholder/.test(levelThang.id) and @get('type', true) in ['course', 'course-ladder']
|
||||||
|
heroThangType = me.get('heroConfig')?.thangType
|
||||||
|
levelThang.thangType = heroThangType if heroThangType
|
||||||
|
|
||||||
sortSystems: (levelSystems, systemModels) ->
|
sortSystems: (levelSystems, systemModels) ->
|
||||||
[sorted, originalsSeen] = [[], {}]
|
[sorted, originalsSeen] = [[], {}]
|
||||||
visit = (system) ->
|
visit = (system) ->
|
||||||
|
|
|
@ -239,6 +239,25 @@ module.exports = class ThangType extends CocoModel
|
||||||
portraitOnly = !!options.portraitOnly
|
portraitOnly = !!options.portraitOnly
|
||||||
"#{@get('name')} - #{options.resolutionFactor} - #{colorConfigs} - #{portraitOnly}"
|
"#{@get('name')} - #{options.resolutionFactor} - #{colorConfigs} - #{portraitOnly}"
|
||||||
|
|
||||||
|
getHeroShortName: ->
|
||||||
|
map = {
|
||||||
|
"Assassin": "Ritic"
|
||||||
|
"Captain": "Anya"
|
||||||
|
"Forest Archer": "Naria"
|
||||||
|
"Goliath": "Okar"
|
||||||
|
"Guardian": "Illia"
|
||||||
|
"Knight": "Tharin"
|
||||||
|
"Librarian": "Hushbaum"
|
||||||
|
"Necromancer": "Nalfar"
|
||||||
|
"Ninja": "Amara"
|
||||||
|
"Potion Master": "Omarn"
|
||||||
|
"Raider": "Arryn"
|
||||||
|
"Samurai": "Hattori"
|
||||||
|
"Sorcerer": "Pender"
|
||||||
|
"Trapper": "Senick"
|
||||||
|
}
|
||||||
|
map[@get('name')]
|
||||||
|
|
||||||
getPortraitImage: (spriteOptionsOrKey, size=100) ->
|
getPortraitImage: (spriteOptionsOrKey, size=100) ->
|
||||||
src = @getPortraitSource(spriteOptionsOrKey, size)
|
src = @getPortraitSource(spriteOptionsOrKey, size)
|
||||||
return null unless src
|
return null unless src
|
||||||
|
|
|
@ -41,3 +41,22 @@
|
||||||
#join-class-form
|
#join-class-form
|
||||||
.alert, .progress
|
.alert, .progress
|
||||||
margin-top: 20px
|
margin-top: 20px
|
||||||
|
|
||||||
|
// Hero display
|
||||||
|
.current-hero-container
|
||||||
|
display: flex
|
||||||
|
justify-content: center
|
||||||
|
|
||||||
|
.current-hero-text
|
||||||
|
font-size: 16pt
|
||||||
|
|
||||||
|
.hero-avatar
|
||||||
|
background-color: #f8f8f8
|
||||||
|
box-shadow: 0 0 0 1px gray
|
||||||
|
margin-right: 25px
|
||||||
|
|
||||||
|
.current-hero-right-col
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
justify-content: space-between
|
||||||
|
align-items: flex-start
|
||||||
|
|
40
app/styles/courses/hero-select-modal.sass
Normal file
40
app/styles/courses/hero-select-modal.sass
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
@import "app/styles/style-flat-variables"
|
||||||
|
|
||||||
|
#hero-select-modal
|
||||||
|
.modal-dialog
|
||||||
|
width: auto
|
||||||
|
max-width: 900px
|
||||||
|
|
||||||
|
.modal-header, .modal-body:not(.secret), .modal-footer
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
align-items: center
|
||||||
|
|
||||||
|
.modal-footer
|
||||||
|
margin: 30px
|
||||||
|
|
||||||
|
h4
|
||||||
|
max-width: 500px
|
||||||
|
|
||||||
|
.hero-list
|
||||||
|
display: flex
|
||||||
|
flex-wrap: wrap
|
||||||
|
justify-content: center
|
||||||
|
margin-bottom: -50px
|
||||||
|
|
||||||
|
.hero-option
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
align-items: center
|
||||||
|
margin: 0 50px 50px
|
||||||
|
|
||||||
|
.hero-avatar
|
||||||
|
margin: 6px
|
||||||
|
background-color: #f8f8f8
|
||||||
|
box-shadow: 0 0 0 1px gray
|
||||||
|
|
||||||
|
.current .hero-avatar
|
||||||
|
box-shadow: 0 0 0 6px gray
|
||||||
|
|
||||||
|
.selected .hero-avatar
|
||||||
|
box-shadow: 0 0 0 6px $gold
|
|
@ -7,3 +7,7 @@
|
||||||
font-family: Arial, Geneva, sans-serif
|
font-family: Arial, Geneva, sans-serif
|
||||||
padding: 20px
|
padding: 20px
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
|
|
||||||
|
.alert-report
|
||||||
|
font-size: 20px
|
||||||
|
|
|
@ -39,6 +39,18 @@ block content
|
||||||
|
|
||||||
.text-center
|
.text-center
|
||||||
h1(data-i18n="courses.welcome_to_page") Welcome to your Courses page!
|
h1(data-i18n="courses.welcome_to_page") Welcome to your Courses page!
|
||||||
|
|
||||||
|
.current-hero-container.text-center.row
|
||||||
|
.hero-avatar
|
||||||
|
img(src=view.hero.getPortraitURL())
|
||||||
|
.current-hero-right-col
|
||||||
|
.semibold.current-hero-text
|
||||||
|
span.spr(data-i18n="TODO")
|
||||||
|
| Current Hero:
|
||||||
|
span.current-hero-name= view.hero.getHeroShortName()
|
||||||
|
button.change-hero-btn.btn.btn-lg.btn-forest
|
||||||
|
span(data-i18n="TODO")
|
||||||
|
| Change Hero
|
||||||
|
|
||||||
if view.classrooms.size()
|
if view.classrooms.size()
|
||||||
h3.text-uppercase(data-i18n="courses.my_classes")
|
h3.text-uppercase(data-i18n="courses.my_classes")
|
||||||
|
|
27
app/templates/courses/hero-select-modal.jade
Normal file
27
app/templates/courses/hero-select-modal.jade
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
extends /templates/core/modal-base-flat
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
.text-center
|
||||||
|
h3(data-i18n="courses.select_your_hero")
|
||||||
|
h4(data-i18n="courses.select_your_hero_description")
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
.hero-list
|
||||||
|
if view.heroes.loaded
|
||||||
|
each hero in view.heroes.models
|
||||||
|
if hero.get('heroClass') === 'Warrior'
|
||||||
|
+heroOption(hero)
|
||||||
|
|
||||||
|
mixin heroOption(hero)
|
||||||
|
- var heroID = hero.id
|
||||||
|
- var selectedState = (state.get('selectedHeroID') === heroID ? 'selected' : (state.get('currentHeroID') === heroID ? 'current' : ''))
|
||||||
|
.hero-option(data-hero-id=heroID class=selectedState)
|
||||||
|
.hero-avatar
|
||||||
|
img(src=hero.getPortraitURL())
|
||||||
|
.text-h5.hero-name
|
||||||
|
span= hero.getHeroShortName()
|
||||||
|
|
||||||
|
block modal-footer-content
|
||||||
|
.select-hero-btn.btn.btn-lg.btn-forest
|
||||||
|
span(data-i18n="courses.select_this_hero")
|
||||||
|
|
|
@ -321,7 +321,7 @@ mixin studentLevelsRow(student)
|
||||||
- var levels = view.classroom.getLevels({courseID: course.id, withoutLadderLevels: true}).models
|
- var levels = view.classroom.getLevels({courseID: course.id, withoutLadderLevels: true}).models
|
||||||
each level, index in levels
|
each level, index in levels
|
||||||
- var progress = state.get('progressData').get({ classroom: view.classroom, course: course, level: level, user: student })
|
- var progress = state.get('progressData').get({ classroom: view.classroom, course: course, level: level, user: student })
|
||||||
+studentLevelProgressDot(progress, level, index+1)
|
+studentLevelProgressDot(progress, level, index+1, session)
|
||||||
|
|
||||||
mixin studentCourseProgressDot(progress, levelsTotal, level, label)
|
mixin studentCourseProgressDot(progress, levelsTotal, level, label)
|
||||||
//- TODO: Refactor with TeacherClassesView jade
|
//- TODO: Refactor with TeacherClassesView jade
|
||||||
|
@ -342,7 +342,7 @@ mixin studentLevelProgressDot(progress, level, levelNumber)
|
||||||
//- TODO: Refactor with TeacherClassesView jade
|
//- TODO: Refactor with TeacherClassesView jade
|
||||||
- dotClass = progress.completed ? 'forest' : (progress.started ? 'gold' : '');
|
- dotClass = progress.completed ? 'forest' : (progress.started ? 'gold' : '');
|
||||||
- levelName = level.get('name')
|
- levelName = level.get('name')
|
||||||
- context = _.merge(progress, { levelName: levelName, levelNumber: levelNumber })
|
- context = _.merge(progress, { levelName: levelName, levelNumber: levelNumber, moment: moment })
|
||||||
.progress-dot.level-progress-dot(class=dotClass, data-html='true', data-title=view.singleStudentLevelProgressDotTemplate(context))
|
.progress-dot.level-progress-dot(class=dotClass, data-html='true', data-title=view.singleStudentLevelProgressDotTemplate(context))
|
||||||
+progressDotLabel(levelNumber)
|
+progressDotLabel(levelNumber)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
mixin timePlayed()
|
||||||
|
if session.get('playtime') > 0
|
||||||
|
.small-details.nowrap
|
||||||
|
span.spr(data-i18n='teacher.time_played')
|
||||||
|
| Played for
|
||||||
|
span= moment.duration({ seconds: session.get('playtime') }).humanize()
|
||||||
|
|
||||||
if completed
|
if completed
|
||||||
.small-details.nowrap
|
.small-details.nowrap
|
||||||
span= levelNumber
|
span= levelNumber
|
||||||
|
@ -7,6 +14,7 @@ if completed
|
||||||
span.spr(data-i18n='teacher.completed')
|
span.spr(data-i18n='teacher.completed')
|
||||||
| Completed
|
| Completed
|
||||||
span= new Date(dateFirstCompleted).toLocaleString()
|
span= new Date(dateFirstCompleted).toLocaleString()
|
||||||
|
+timePlayed
|
||||||
//- .small-details
|
//- .small-details
|
||||||
//- i(data-i18n='teacher.click_to_view_solution')
|
//- i(data-i18n='teacher.click_to_view_solution')
|
||||||
//- | click to view solution
|
//- | click to view solution
|
||||||
|
@ -19,6 +27,7 @@ else if started
|
||||||
span.spr(data-i18n='teacher.last_played')
|
span.spr(data-i18n='teacher.last_played')
|
||||||
| Last played
|
| Last played
|
||||||
span= new Date(lastPlayed).toLocaleString()
|
span= new Date(lastPlayed).toLocaleString()
|
||||||
|
+timePlayed
|
||||||
//- .small-details
|
//- .small-details
|
||||||
//- i(data-i18n='teacher.click_to_view_progress')
|
//- i(data-i18n='teacher.click_to_view_progress')
|
||||||
//- | click to view progress
|
//- | click to view progress
|
||||||
|
|
|
@ -11,6 +11,20 @@ ol.breadcrumb
|
||||||
.container-fluid
|
.container-fluid
|
||||||
.row
|
.row
|
||||||
.col-md-8
|
.col-md-8
|
||||||
|
#failure-reports
|
||||||
|
for report in view.failureReports
|
||||||
|
.alert.alert-danger.alert-report
|
||||||
|
ul.suite-list
|
||||||
|
for description in report.suiteDescriptions
|
||||||
|
li= description
|
||||||
|
li
|
||||||
|
strong ... #{report.testDescription}
|
||||||
|
hr
|
||||||
|
ol.error-list
|
||||||
|
for message in report.failMessages
|
||||||
|
li
|
||||||
|
strong= message
|
||||||
|
|
||||||
#test-wrapper.well
|
#test-wrapper.well
|
||||||
#testing-area
|
#testing-area
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ module.exports = TestView = class TestView extends RootView
|
||||||
id: 'test-view'
|
id: 'test-view'
|
||||||
template: template
|
template: template
|
||||||
reloadOnClose: true
|
reloadOnClose: true
|
||||||
loadedFileIDs: []
|
className: 'style-flat'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click #show-demos-btn': 'onClickShowDemosButton'
|
'click #show-demos-btn': 'onClickShowDemosButton'
|
||||||
|
@ -24,11 +24,13 @@ module.exports = TestView = class TestView extends RootView
|
||||||
initialize: (options, @subPath='') ->
|
initialize: (options, @subPath='') ->
|
||||||
@subPath = @subPath[1..] if @subPath[0] is '/'
|
@subPath = @subPath[1..] if @subPath[0] is '/'
|
||||||
@demosOn = storage.load('demos-on')
|
@demosOn = storage.load('demos-on')
|
||||||
|
@failureReports = []
|
||||||
|
@loadedFileIDs = []
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
@initSpecFiles()
|
@initSpecFiles()
|
||||||
@render()
|
@render()
|
||||||
TestView.runTests(@specFiles, @demosOn)
|
TestView.runTests(@specFiles, @demosOn, @)
|
||||||
window.runJasmine()
|
window.runJasmine()
|
||||||
|
|
||||||
# EVENTS
|
# EVENTS
|
||||||
|
@ -59,7 +61,30 @@ module.exports = TestView = class TestView extends RootView
|
||||||
prefix = TEST_REQUIRE_PREFIX + @subPath
|
prefix = TEST_REQUIRE_PREFIX + @subPath
|
||||||
@specFiles = (f for f in @specFiles when _.string.startsWith f, prefix)
|
@specFiles = (f for f in @specFiles when _.string.startsWith f, prefix)
|
||||||
|
|
||||||
@runTests: (specFiles, demosOn=false) ->
|
@runTests: (specFiles, demosOn=false, view) ->
|
||||||
|
|
||||||
|
jasmine.getEnv().addReporter({
|
||||||
|
suiteStack: []
|
||||||
|
|
||||||
|
specDone: (result) ->
|
||||||
|
if result.status is 'failed'
|
||||||
|
console.log 'result', result
|
||||||
|
report = {
|
||||||
|
suiteDescriptions: _.clone(@suiteStack)
|
||||||
|
failMessages: (fe.message for fe in result.failedExpectations)
|
||||||
|
testDescription: result.description
|
||||||
|
}
|
||||||
|
view.failureReports.push(report)
|
||||||
|
view.renderSelectors('#failure-reports')
|
||||||
|
|
||||||
|
suiteStarted: (result) ->
|
||||||
|
@suiteStack.push(result.description)
|
||||||
|
|
||||||
|
suiteDone: (result) ->
|
||||||
|
@suiteStack.pop()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
application.testing = true
|
application.testing = true
|
||||||
specFiles ?= @getAllSpecFiles()
|
specFiles ?= @getAllSpecFiles()
|
||||||
if demosOn
|
if demosOn
|
||||||
|
@ -71,23 +96,22 @@ module.exports = TestView = class TestView extends RootView
|
||||||
jasmine.demoEl = _.noop
|
jasmine.demoEl = _.noop
|
||||||
jasmine.demoModal = _.noop
|
jasmine.demoModal = _.noop
|
||||||
|
|
||||||
describe 'CodeCombat Client', =>
|
jasmine.Ajax.install()
|
||||||
jasmine.Ajax.install()
|
beforeEach ->
|
||||||
beforeEach ->
|
jasmine.Ajax.requests.reset()
|
||||||
jasmine.Ajax.requests.reset()
|
Backbone.Mediator.init()
|
||||||
Backbone.Mediator.init()
|
Backbone.Mediator.setValidationEnabled false
|
||||||
Backbone.Mediator.setValidationEnabled false
|
spyOn(application.tracker, 'trackEvent')
|
||||||
spyOn(application.tracker, 'trackEvent')
|
# TODO Stubbify more things
|
||||||
# TODO Stubbify more things
|
# * document.location
|
||||||
# * document.location
|
# * firebase
|
||||||
# * firebase
|
# * all the services that load in main.html
|
||||||
# * all the services that load in main.html
|
|
||||||
|
|
||||||
afterEach ->
|
afterEach ->
|
||||||
# TODO Clean up more things
|
# TODO Clean up more things
|
||||||
# * Events
|
# * Events
|
||||||
|
|
||||||
require f for f in specFiles # runs the tests
|
require f for f in specFiles # runs the tests
|
||||||
|
|
||||||
@getAllSpecFiles = ->
|
@getAllSpecFiles = ->
|
||||||
allFiles = window.require.list()
|
allFiles = window.require.list()
|
||||||
|
|
|
@ -4,6 +4,7 @@ template = require 'templates/courses/courses-view'
|
||||||
AuthModal = require 'views/core/AuthModal'
|
AuthModal = require 'views/core/AuthModal'
|
||||||
CreateAccountModal = require 'views/core/CreateAccountModal'
|
CreateAccountModal = require 'views/core/CreateAccountModal'
|
||||||
ChangeCourseLanguageModal = require 'views/courses/ChangeCourseLanguageModal'
|
ChangeCourseLanguageModal = require 'views/courses/ChangeCourseLanguageModal'
|
||||||
|
HeroSelectModal = require 'views/courses/HeroSelectModal'
|
||||||
ChooseLanguageModal = require 'views/courses/ChooseLanguageModal'
|
ChooseLanguageModal = require 'views/courses/ChooseLanguageModal'
|
||||||
JoinClassModal = require 'views/courses/JoinClassModal'
|
JoinClassModal = require 'views/courses/JoinClassModal'
|
||||||
CourseInstance = require 'models/CourseInstance'
|
CourseInstance = require 'models/CourseInstance'
|
||||||
|
@ -13,6 +14,7 @@ Classroom = require 'models/Classroom'
|
||||||
Classrooms = require 'collections/Classrooms'
|
Classrooms = require 'collections/Classrooms'
|
||||||
LevelSession = require 'models/LevelSession'
|
LevelSession = require 'models/LevelSession'
|
||||||
Campaign = require 'models/Campaign'
|
Campaign = require 'models/Campaign'
|
||||||
|
ThangType = require 'models/ThangType'
|
||||||
utils = require 'core/utils'
|
utils = require 'core/utils'
|
||||||
|
|
||||||
# TODO: Test everything
|
# TODO: Test everything
|
||||||
|
@ -24,6 +26,7 @@ module.exports = class CoursesView extends RootView
|
||||||
events:
|
events:
|
||||||
'click #log-in-btn': 'onClickLogInButton'
|
'click #log-in-btn': 'onClickLogInButton'
|
||||||
'click #start-new-game-btn': 'openSignUpModal'
|
'click #start-new-game-btn': 'openSignUpModal'
|
||||||
|
'click .change-hero-btn': 'onClickChangeHeroButton'
|
||||||
'click #join-class-btn': 'onClickJoinClassButton'
|
'click #join-class-btn': 'onClickJoinClassButton'
|
||||||
'submit #join-class-form': 'onSubmitJoinClassForm'
|
'submit #join-class-form': 'onSubmitJoinClassForm'
|
||||||
'click #change-language-link': 'onClickChangeLanguageLink'
|
'click #change-language-link': 'onClickChangeLanguageLink'
|
||||||
|
@ -43,6 +46,16 @@ module.exports = class CoursesView extends RootView
|
||||||
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
||||||
@supermodel.loadCollection(@courses)
|
@supermodel.loadCollection(@courses)
|
||||||
|
|
||||||
|
# TODO: Trim this section for only what's necessary
|
||||||
|
@hero = new ThangType
|
||||||
|
defaultHeroOriginal = ThangType.heroes.captain
|
||||||
|
heroOriginal = me.get('heroConfig')?.thangType or defaultHeroOriginal
|
||||||
|
@hero.url = "/db/thang.type/#{heroOriginal}/version"
|
||||||
|
# @hero.setProjection ['name','slug','soundTriggers','featureImages','gems','heroClass','description','components','extendedName','unlockLevelName','i18n']
|
||||||
|
@supermodel.loadModel(@hero, 'hero')
|
||||||
|
@listenTo @hero, 'all', ->
|
||||||
|
@render()
|
||||||
|
|
||||||
onCourseInstancesLoaded: ->
|
onCourseInstancesLoaded: ->
|
||||||
map = {}
|
map = {}
|
||||||
for courseInstance in @courseInstances.models
|
for courseInstance in @courseInstances.models
|
||||||
|
@ -76,6 +89,16 @@ module.exports = class CoursesView extends RootView
|
||||||
@openModalView(modal)
|
@openModalView(modal)
|
||||||
application.tracker?.trackEvent 'Started Student Signup', category: 'Courses'
|
application.tracker?.trackEvent 'Started Student Signup', category: 'Courses'
|
||||||
|
|
||||||
|
onClickChangeHeroButton: ->
|
||||||
|
modal = new HeroSelectModal({ currentHeroID: @hero.id })
|
||||||
|
@openModalView(modal)
|
||||||
|
@listenTo modal, 'hero-select:success', (newHero) =>
|
||||||
|
# @hero.url = "/db/thang.type/#{me.get('heroConfig').thangType}/version"
|
||||||
|
# @hero.fetch()
|
||||||
|
@hero.set(newHero.attributes)
|
||||||
|
@listenTo modal, 'hide', ->
|
||||||
|
@stopListening modal
|
||||||
|
|
||||||
onSubmitJoinClassForm: (e) ->
|
onSubmitJoinClassForm: (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@joinClass()
|
@joinClass()
|
||||||
|
@ -136,7 +159,7 @@ module.exports = class CoursesView extends RootView
|
||||||
classroomCourseInstances.fetch({ data: {classroomID: newClassroom.id} })
|
classroomCourseInstances.fetch({ data: {classroomID: newClassroom.id} })
|
||||||
@listenToOnce classroomCourseInstances, 'sync', ->
|
@listenToOnce classroomCourseInstances, 'sync', ->
|
||||||
# TODO: Smoother system for joining a classroom and course instances, without requiring page reload,
|
# TODO: Smoother system for joining a classroom and course instances, without requiring page reload,
|
||||||
# and showing which class was just joined.
|
# and showing which class was just joined.
|
||||||
document.location.search = '' # Using document.location.reload() causes an infinite loop of reloading
|
document.location.search = '' # Using document.location.reload() causes an infinite loop of reloading
|
||||||
|
|
||||||
onClickChangeLanguageLink: ->
|
onClickChangeLanguageLink: ->
|
||||||
|
|
42
app/views/courses/HeroSelectModal.coffee
Normal file
42
app/views/courses/HeroSelectModal.coffee
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
ModalView = require 'views/core/ModalView'
|
||||||
|
template = require 'templates/courses/hero-select-modal'
|
||||||
|
Classroom = require 'models/Classroom'
|
||||||
|
ThangTypes = require 'collections/ThangTypes'
|
||||||
|
State = require 'models/State'
|
||||||
|
ThangType = require 'models/ThangType'
|
||||||
|
User = require 'models/User'
|
||||||
|
|
||||||
|
module.exports = class HeroSelectModal extends ModalView
|
||||||
|
id: 'hero-select-modal'
|
||||||
|
template: template
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .select-hero-btn': 'onClickSelectHeroButton'
|
||||||
|
'click .hero-option': 'onClickHeroOption'
|
||||||
|
|
||||||
|
initialize: ({ currentHeroID }) ->
|
||||||
|
@debouncedRender = _.debounce @render, 0
|
||||||
|
|
||||||
|
@state = new State({
|
||||||
|
currentHeroID
|
||||||
|
selectedHeroID: currentHeroID
|
||||||
|
})
|
||||||
|
|
||||||
|
@heroes = new ThangTypes({}, { project: ['original', 'name', 'heroClass'] })
|
||||||
|
@supermodel.trackRequest @heroes.fetchHeroes()
|
||||||
|
|
||||||
|
@listenTo @state, 'all', -> @debouncedRender()
|
||||||
|
@listenTo @heroes, 'all', -> @debouncedRender()
|
||||||
|
|
||||||
|
onClickHeroOption: (e) ->
|
||||||
|
heroID = $(e.currentTarget).data('hero-id')
|
||||||
|
@state.set selectedHeroID: heroID
|
||||||
|
hero = @heroes.get(heroID)
|
||||||
|
me.set(heroConfig: {}) unless me.get('heroConfig')
|
||||||
|
heroConfig = _.assign me.get('heroConfig'), { thangType: hero.get('original') }
|
||||||
|
me.set({ heroConfig })
|
||||||
|
me.save().then =>
|
||||||
|
@trigger 'hero-select:success', hero
|
||||||
|
|
||||||
|
onClickSelectHeroButton: () ->
|
||||||
|
@hide()
|
|
@ -316,7 +316,7 @@ module.exports = class SpellView extends CocoView
|
||||||
|
|
||||||
xstart = startOfRow(row)
|
xstart = startOfRow(row)
|
||||||
if language is 'python'
|
if language is 'python'
|
||||||
requiredIndent = new RegExp '^' + new Array(xstart / 4 + 2).join '( |\t)' + '(\\S|\\s*$)'
|
requiredIndent = new RegExp '^' + new Array(xstart / 4 + 1).join('( |\t)') + '( |\t)+(\\S|\\s*$)'
|
||||||
for crow in [docRange.start.row+1..docRange.end.row]
|
for crow in [docRange.start.row+1..docRange.end.row]
|
||||||
unless requiredIndent.test lines[crow]
|
unless requiredIndent.test lines[crow]
|
||||||
docRange.end.row = crow - 1
|
docRange.end.row = crow - 1
|
||||||
|
|
|
@ -52,7 +52,8 @@
|
||||||
"esper.js": "http://files.codecombat.com/esper.tar.gz",
|
"esper.js": "http://files.codecombat.com/esper.tar.gz",
|
||||||
"algoliasearch": "^3.13.1",
|
"algoliasearch": "^3.13.1",
|
||||||
"algolia-autocomplete.js": "^0.17.0",
|
"algolia-autocomplete.js": "^0.17.0",
|
||||||
"algolia-autocomplete-no-conflict": "1.0.0"
|
"algolia-autocomplete-no-conflict": "1.0.0",
|
||||||
|
"bluebird": "^3.4.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"algolia-autocomplete.js": {
|
"algolia-autocomplete.js": {
|
||||||
|
|
|
@ -84,7 +84,7 @@ ClassroomHandler = class ClassroomHandler extends Handler
|
||||||
return @sendDatabaseError(res, err) if err
|
return @sendDatabaseError(res, err) if err
|
||||||
return @sendSuccess(res, (@formatEntity(req, classroom) for classroom in classrooms))
|
return @sendSuccess(res, (@formatEntity(req, classroom) for classroom in classrooms))
|
||||||
else if code = req.query.code
|
else if code = req.query.code
|
||||||
code = code.toLowerCase()
|
code = code.toLowerCase().replace(/ /g, '')
|
||||||
Classroom.findOne {code: code}, (err, classroom) =>
|
Classroom.findOne {code: code}, (err, classroom) =>
|
||||||
return @sendDatabaseError(res, err) if err
|
return @sendDatabaseError(res, err) if err
|
||||||
return @sendNotFoundError(res) unless classroom
|
return @sendNotFoundError(res) unless classroom
|
||||||
|
|
|
@ -65,7 +65,7 @@ module.exports =
|
||||||
activities = JSON.parse(body)
|
activities = JSON.parse(body)
|
||||||
return done("Unexpected activities format: " + body) unless activities.data?
|
return done("Unexpected activities format: " + body) unless activities.data?
|
||||||
for activity in activities.data when activity._type is 'Email'
|
for activity in activities.data when activity._type is 'Email'
|
||||||
if /@codecombat\.com/ig.test(activity.sender) and not activity.sender?.indexOf(config.mail.username) >= 0
|
if /@codecombat\.(?:com)|(?:nl)$/ig.test(activity.sender) and not activity.sender?.indexOf(config.mail.username) >= 0
|
||||||
return done(null, activity.sender, lead.id)
|
return done(null, activity.sender, lead.id)
|
||||||
return done(null, config.mail.supportSchools, lead.id)
|
return done(null, config.mail.supportSchools, lead.id)
|
||||||
catch error
|
catch error
|
||||||
|
|
|
@ -22,7 +22,7 @@ module.exports =
|
||||||
fetchByCode: wrap (req, res, next) ->
|
fetchByCode: wrap (req, res, next) ->
|
||||||
code = req.query.code
|
code = req.query.code
|
||||||
return next() unless code
|
return next() unless code
|
||||||
classroom = yield Classroom.findOne({ code: code.toLowerCase() }).select('name ownerID aceConfig')
|
classroom = yield Classroom.findOne({ code: code.toLowerCase().replace(/ /g, '') }).select('name ownerID aceConfig')
|
||||||
if not classroom
|
if not classroom
|
||||||
log.debug("classrooms.fetchByCode: Couldn't find Classroom with code: #{code}")
|
log.debug("classrooms.fetchByCode: Couldn't find Classroom with code: #{code}")
|
||||||
throw new errors.NotFound('Classroom not found.')
|
throw new errors.NotFound('Classroom not found.')
|
||||||
|
@ -170,7 +170,7 @@ module.exports =
|
||||||
if req.user.isTeacher()
|
if req.user.isTeacher()
|
||||||
log.debug("classrooms.join: Cannot join a classroom as a teacher: #{req.user.id}")
|
log.debug("classrooms.join: Cannot join a classroom as a teacher: #{req.user.id}")
|
||||||
throw new errors.Forbidden('Cannot join a classroom as a teacher')
|
throw new errors.Forbidden('Cannot join a classroom as a teacher')
|
||||||
code = req.body.code.toLowerCase()
|
code = req.body.code.toLowerCase().replace(/ /g, '')
|
||||||
classroom = yield Classroom.findOne({code: code})
|
classroom = yield Classroom.findOne({code: code})
|
||||||
if not classroom
|
if not classroom
|
||||||
log.debug("classrooms.join: Classroom not found with code #{code}")
|
log.debug("classrooms.join: Classroom not found with code #{code}")
|
||||||
|
|
|
@ -60,6 +60,18 @@ describe 'GET /db/classroom/:id', ->
|
||||||
expect(body._id).toBe(classroomID = body._id)
|
expect(body._id).toBe(classroomID = body._id)
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
describe 'GET /db/classroom by classCode', ->
|
||||||
|
it 'Returns the class if you include spaces', utils.wrap (done) ->
|
||||||
|
user = yield utils.initUser()
|
||||||
|
yield utils.loginUser(user)
|
||||||
|
teacher = yield utils.initUser()
|
||||||
|
classroom = new Classroom({ name: "some class", ownerID: teacher.id, camelCode: "FooBarBaz", code: "foobarbaz" })
|
||||||
|
yield classroom.save()
|
||||||
|
[res, body] = yield request.getAsync(getURL('/db/classroom?code=foo bar baz'), { json: true })
|
||||||
|
expect(res.statusCode).toBe(200)
|
||||||
|
expect(res.body.data?.name).toBe(classroom.get('name'))
|
||||||
|
done()
|
||||||
|
|
||||||
describe 'POST /db/classroom', ->
|
describe 'POST /db/classroom', ->
|
||||||
|
|
||||||
beforeEach utils.wrap (done) ->
|
beforeEach utils.wrap (done) ->
|
||||||
|
@ -295,6 +307,18 @@ describe 'POST /db/classroom/-/members', ->
|
||||||
fail('student should be added to the free course instance.')
|
fail('student should be added to the free course instance.')
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
it 'joins the class even with spaces in the classcode', utils.wrap (done) ->
|
||||||
|
yield utils.loginUser(@student)
|
||||||
|
url = getURL("/db/classroom/anything-here/members")
|
||||||
|
code = @classroom.get('code')
|
||||||
|
codeWithSpaces = code.split("").join(" ")
|
||||||
|
[res, body] = yield request.postAsync { uri: url, json: { code: codeWithSpaces } }
|
||||||
|
expect(res.statusCode).toBe(200)
|
||||||
|
classroom = yield Classroom.findById(@classroom.id)
|
||||||
|
if classroom.get('members').length isnt 1
|
||||||
|
fail 'expected classCode with spaces to work too'
|
||||||
|
done()
|
||||||
|
|
||||||
it 'returns 403 if the user is a teacher', utils.wrap (done) ->
|
it 'returns 403 if the user is a teacher', utils.wrap (done) ->
|
||||||
yield utils.loginUser(@teacher)
|
yield utils.loginUser(@teacher)
|
||||||
url = getURL("/db/classroom/~/members")
|
url = getURL("/db/classroom/~/members")
|
||||||
|
|
32
test/app/views/courses/CoursesView.spec.coffee
Normal file
32
test/app/views/courses/CoursesView.spec.coffee
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
CoursesView = require 'views/courses/CoursesView'
|
||||||
|
HeroSelectModal = require 'views/courses/HeroSelectModal'
|
||||||
|
Classrooms = require 'collections/Classrooms'
|
||||||
|
CourseInstances = require 'collections/CourseInstances'
|
||||||
|
Courses = require 'collections/Courses'
|
||||||
|
auth = require 'core/auth'
|
||||||
|
factories = require 'test/app/factories'
|
||||||
|
|
||||||
|
describe 'CoursesView', ->
|
||||||
|
|
||||||
|
modal = null
|
||||||
|
view = null
|
||||||
|
|
||||||
|
describe 'Change Hero button', ->
|
||||||
|
beforeEach (done) ->
|
||||||
|
view = new CoursesView()
|
||||||
|
classrooms = new Classrooms([factories.makeClassroom()])
|
||||||
|
courseInstances = new CourseInstances([factories.makeCourseInstance()])
|
||||||
|
courses = new Courses([factories.makeCourse()])
|
||||||
|
view.classrooms.fakeRequests[0].respondWith({ status: 200, responseText: classrooms.stringify() })
|
||||||
|
view.ownedClassrooms.fakeRequests[0].respondWith({ status: 200, responseText: classrooms.stringify() })
|
||||||
|
view.courseInstances.fakeRequests[0].respondWith({ status: 200, responseText: courseInstances.stringify() })
|
||||||
|
view.render()
|
||||||
|
jasmine.demoEl(view.$el)
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'opens the modal when you click Change Hero', ->
|
||||||
|
spyOn(view, 'openModalView')
|
||||||
|
view.$('.change-hero-btn').click()
|
||||||
|
expect(view.openModalView).toHaveBeenCalled()
|
||||||
|
args = view.openModalView.calls.argsFor(0)
|
||||||
|
expect(args[0] instanceof HeroSelectModal).toBe(true)
|
38
test/app/views/courses/HeroSelectModal.spec.coffee
Normal file
38
test/app/views/courses/HeroSelectModal.spec.coffee
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
HeroSelectModal = require 'views/courses/HeroSelectModal'
|
||||||
|
auth = require 'core/auth'
|
||||||
|
factories = require 'test/app/factories'
|
||||||
|
|
||||||
|
describe 'HeroSelectModal', ->
|
||||||
|
|
||||||
|
modal = null
|
||||||
|
coursesView = null
|
||||||
|
user = null
|
||||||
|
|
||||||
|
hero1 = factories.makeThangType({ original: "hero1original", _id: "hero1id", heroClass: "Warrior", name: "Hero 1" })
|
||||||
|
hero2 = factories.makeThangType({ original: "hero2original", _id: "hero2id", heroClass: "Warrior", name: "Hero 2" })
|
||||||
|
heroesResponse = JSON.stringify([hero1, hero2])
|
||||||
|
|
||||||
|
beforeEach (done) ->
|
||||||
|
window.me = user = factories.makeUser({ heroConfig: { thangType: hero1.get('original') } })
|
||||||
|
auth.loginUser(user.attributes)
|
||||||
|
modal = new HeroSelectModal({ currentHeroID: hero1.id })
|
||||||
|
modal.heroes.fakeRequests[0].respondWith({ status: 200, responseText: heroesResponse })
|
||||||
|
jasmine.demoModal(modal)
|
||||||
|
_.defer ->
|
||||||
|
modal.render()
|
||||||
|
done()
|
||||||
|
|
||||||
|
afterEach ->
|
||||||
|
modal.stopListening()
|
||||||
|
|
||||||
|
it 'highlights the current hero', ->
|
||||||
|
expect(modal.$(".hero-option[data-hero-id='#{hero1.id}']")[0].className.split(" ")).toContain('selected')
|
||||||
|
|
||||||
|
it 'saves when you change heroes', (done) ->
|
||||||
|
modal.$(".hero-option[data-hero-id='#{hero2.id}']").click()
|
||||||
|
_.defer ->
|
||||||
|
expect(user.fakeRequests.length).toBe(1)
|
||||||
|
request = user.fakeRequests[0]
|
||||||
|
expect(request.method).toBe("PUT")
|
||||||
|
expect(JSON.parse(request.params).heroConfig?.thangType).toBe(hero2.get('original'))
|
||||||
|
done()
|
|
@ -40,6 +40,12 @@ describe 'CourseVictoryModal', ->
|
||||||
modal.classroom.fakeRequests[0].respondWith({
|
modal.classroom.fakeRequests[0].respondWith({
|
||||||
status: 200, responseText: factories.makeClassroom().stringify()
|
status: 200, responseText: factories.makeClassroom().stringify()
|
||||||
})
|
})
|
||||||
|
if me.fakeRequests
|
||||||
|
lastRequest = _.last(me.fakeRequests)
|
||||||
|
if not lastRequest.response
|
||||||
|
lastRequest.respondWith({
|
||||||
|
status: 200, responseText: factories.makeUser().stringify()
|
||||||
|
})
|
||||||
nextLevelRequest = modal.nextLevel.fakeRequests[0]
|
nextLevelRequest = modal.nextLevel.fakeRequests[0]
|
||||||
|
|
||||||
describe 'given a course level with a next level and no item or hero rewards', ->
|
describe 'given a course level with a next level and no item or hero rewards', ->
|
||||||
|
|
Loading…
Reference in a new issue