Merge branch 'master' into production

This commit is contained in:
Matt Lott 2016-08-17 14:26:17 -07:00
commit 713ad8115a
8 changed files with 59 additions and 27 deletions

View file

@ -18,6 +18,9 @@ class NameLoader extends CocoClass
loadedNames: (newNames) => loadedNames: (newNames) =>
_.extend namesCache, newNames _.extend namesCache, newNames
getName: (id) -> namesCache[id]?.name or id getName: (id) ->
if namesCache[id]?.firstName and namesCache[id]?.lastName
return "#{namesCache[id]?.firstName} #{namesCache[id]?.lastName}"
namesCache[id]?.firstName or namesCache[id]?.name or id
module.exports = new NameLoader() module.exports = new NameLoader()

View file

@ -1235,7 +1235,7 @@
play_now_learn_2: "while loops to solve pesky puzzles" play_now_learn_2: "while loops to solve pesky puzzles"
play_now_learn_3: "strings & variables to customize actions" play_now_learn_3: "strings & variables to customize actions"
play_now_learn_4: "how to defeat an ogre (important life skills!)" play_now_learn_4: "how to defeat an ogre (important life skills!)"
welcome_to_page: "Welcome to your Courses page!" welcome_to_page: "My Student Dashboard" # {change}
completed_hoc: "Amazing! You've completed the Hour of Code course!" completed_hoc: "Amazing! You've completed the Hour of Code course!"
ready_for_more_header: "Ready for more? Play the campaign mode!" ready_for_more_header: "Ready for more? Play the campaign mode!"
ready_for_more_1: "Use gems to unlock new items!" ready_for_more_1: "Use gems to unlock new items!"
@ -1243,10 +1243,9 @@
ready_for_more_3: "Learn even more programming!" ready_for_more_3: "Learn even more programming!"
saved_games: "Saved Games" saved_games: "Saved Games"
hoc: "Hour of Code" hoc: "Hour of Code"
my_classes: "My Classes" my_classes: "Current Classes" # {change}
class_added: "Class successfully added!" class_added: "Class successfully added!"
view_class: "view class" view_levels: "view all levels in course" # {change}
view_levels: "view levels"
join_class: "Join A Class" join_class: "Join A Class"
join_class_2: "Join class" join_class_2: "Join class"
ask_teacher_for_code: "Ask your teacher if you have a CodeCombat class code! If so, enter it below:" ask_teacher_for_code: "Ask your teacher if you have a CodeCombat class code! If so, enter it below:"
@ -1257,7 +1256,7 @@
play_arena: "Play Arena" play_arena: "Play Arena"
view_project: "View Project" view_project: "View Project"
start: "Start" start: "Start"
last_level: "Last Level" last_level: "Last level played" # {change}
welcome_to_hoc: "Adventurers, welcome to our Hour of Code!" welcome_to_hoc: "Adventurers, welcome to our Hour of Code!"
logged_in_as: "Logged in as:" logged_in_as: "Logged in as:"
not_you: "Not you?" not_you: "Not you?"

View file

@ -132,6 +132,7 @@ module.exports = class Classroom extends CocoModel
complete = session.get('state').complete ? false complete = session.get('state').complete ? false
playtime += session.get('playtime') ? 0 playtime += session.get('playtime') ? 0
lastPlayed = level lastPlayed = level
lastPlayedNumber = index + 1
if complete if complete
currentIndex = index currentIndex = index
else else
@ -161,6 +162,7 @@ module.exports = class Classroom extends CocoModel
numDone: levelsTotal - levelsLeft numDone: levelsTotal - levelsLeft
pctDone: (100 * (levelsTotal - levelsLeft) / levelsTotal).toFixed(1) + '%' pctDone: (100 * (levelsTotal - levelsLeft) / levelsTotal).toFixed(1) + '%'
lastPlayed: lastPlayed lastPlayed: lastPlayed
lastPlayedNumber: lastPlayedNumber ? 1
next: nextLevel next: nextLevel
first: courseLevels.first() first: courseLevels.first()
arena: arena arena: arena

View file

@ -16,6 +16,12 @@
hr hr
border-top: 1px solid grey border-top: 1px solid grey
margin: 5px 0 margin: 5px 0
padding-bottom: 20px
opacity: 0.5
.view-levels-btn
font-size: 13px
padding-left: 10px
.text-uppercase .text-uppercase
margin-top: 40px margin-top: 40px
@ -29,7 +35,7 @@
padding: 0 20px padding: 0 20px
.course-instance-entry .course-instance-entry
padding-left: 40px padding-bottom: 10px
.progress-bar .progress-bar
min-width: 15% min-width: 15%

View file

@ -38,7 +38,7 @@ block content
else else
.text-center .text-center
h1(data-i18n="courses.welcome_to_page") Welcome to your Courses page! h1(data-i18n="courses.welcome_to_page")
.current-hero-container.text-center.row .current-hero-container.text-center.row
.hero-avatar .hero-avatar
@ -51,10 +51,11 @@ block content
span(data-i18n="courses.change_hero") span(data-i18n="courses.change_hero")
if view.classrooms.size() if view.classrooms.size()
h3.text-uppercase(data-i18n="courses.my_classes") br
hr h3(data-i18n="courses.my_classes")
for classroom in view.classrooms.models for classroom in view.classrooms.models
hr.class-break
- var justAdded = classroom.id === view.classroomJustAdded; - var justAdded = classroom.id === view.classroomJustAdded;
- var classroomClass = justAdded ? 'just-added' : ''; - var classroomClass = justAdded ? 'just-added' : '';
if justAdded if justAdded
@ -65,7 +66,11 @@ block content
h5 h5
span.spr= classroom.get('name') span.spr= classroom.get('name')
span.spr (#{(classroom.get('aceConfig') || {}).language === 'javascript' ? 'JavaScript' : 'Python'}) span.spr (#{(classroom.get('aceConfig') || {}).language === 'javascript' ? 'JavaScript' : 'Python'})
a.view-class-btn(data-classroom-id=classroom.id, data-i18n="courses.view_class") p
span(data-i18n="courses.teacher")
span :
if view.ownerNameMap && view.ownerNameMap[classroom.get('ownerID')]
span.spl= view.ownerNameMap[classroom.get('ownerID')]
- var courseInstances = view.courseInstances.where({classroomID: classroom.id}); - var courseInstances = view.courseInstances.where({classroomID: classroom.id});
for courseInstance in courseInstances for courseInstance in courseInstances
@ -111,11 +116,11 @@ mixin course-instance-body(courseInstance, classroom)
- var projectLevel = stats.levels.project; - var projectLevel = stats.levels.project;
if arenaLevel if arenaLevel
- var arenaURL = "/play/ladder/"+arenaLevel.get('slug')+"/course/"+courseInstance.id; - var arenaURL = "/play/ladder/"+arenaLevel.get('slug')+"/course/"+courseInstance.id;
a.play-btn.btn.btn-burgandy.btn-lg.m-b-1(data-href=arenaURL, data-level-slug=arenaLevel.get('slug'), data-event-action="Students Play Arena") a.play-btn.btn.btn-forest-alt.btn-lg.m-b-1(data-href=arenaURL, data-level-slug=arenaLevel.get('slug'), data-event-action="Students Play Arena")
span(data-i18n="courses.play_arena") span(data-i18n="courses.play_arena")
else if projectLevel else if projectLevel
- var projectURL = "/play/level/"+projectLevel.get('slug')+"?course="+course.id+"&course-instance="+courseInstance.id; - var projectURL = "/play/level/"+projectLevel.get('slug')+"?course="+course.id+"&course-instance="+courseInstance.id;
a.play-btn.btn.btn-burgandy.btn-lg.m-b-1(data-href=projectURL, data-level-slug=projectLevel.get('slug'), data-event-action="Students Play Project") a.play-btn.btn.btn-forest-alt.btn-lg.m-b-1(data-href=projectURL, data-level-slug=projectLevel.get('slug'), data-event-action="Students Play Project")
span(data-i18n="courses.view_project") span(data-i18n="courses.view_project")
else else
a.btn.btn-default.btn-lg.m-b-1(disabled=true, data-i18n="courses.course_complete") a.btn.btn-default.btn-lg.m-b-1(disabled=true, data-i18n="courses.course_complete")
@ -130,16 +135,12 @@ mixin course-instance-body(courseInstance, classroom)
a.play-btn.btn.btn-navy.btn-lg.m-b-1(data-href=levelURL, data-level-slug=firstLevel.get('slug'), data-event-action="Students Start Course") a.play-btn.btn.btn-navy.btn-lg.m-b-1(data-href=levelURL, data-level-slug=firstLevel.get('slug'), data-event-action="Students Start Course")
span(data-i18n="courses.start") span(data-i18n="courses.start")
div
span(data-i18n="clans.playtime")
span.spr :
span= moment.duration(stats.playtime, 'seconds').humanize()
if stats.levels.lastPlayed if stats.levels.lastPlayed
div div
span(data-i18n="courses.last_level") span(data-i18n="courses.last_level")
span.spr : span : #{stats.levels.lastPlayedNumber}.
span= stats.levels.lastPlayed.get('name') span.spl= stats.levels.lastPlayed.get('name')
.clearfix .clearfix
.progress .progress

View file

@ -51,7 +51,7 @@ module.exports = class AuthModal extends ModalView
return forms.applyErrorsToForm(@$el, res.errors) unless res.valid return forms.applyErrorsToForm(@$el, res.errors) unless res.valid
new Promise(me.loginPasswordUser(userObject.emailOrUsername, userObject.password).then) new Promise(me.loginPasswordUser(userObject.emailOrUsername, userObject.password).then)
.then(-> .then(->
if window.nextURL then window.location.href = window.nextURL else window.location.reload() if window.nextURL then window.location.href = window.nextURL else loginNavigate()
) )
.catch((jqxhr) => .catch((jqxhr) =>
showingError = false showingError = false
@ -85,7 +85,7 @@ module.exports = class AuthModal extends ModalView
existingUser.fetchGPlusUser(gplusAttrs.gplusID, { existingUser.fetchGPlusUser(gplusAttrs.gplusID, {
success: => success: =>
me.loginGPlusUser(gplusAttrs.gplusID, { me.loginGPlusUser(gplusAttrs.gplusID, {
success: -> window.location.reload() success: -> loginNavigate()
error: @onGPlusLoginError error: @onGPlusLoginError
}) })
error: @onGPlusLoginError error: @onGPlusLoginError
@ -116,7 +116,7 @@ module.exports = class AuthModal extends ModalView
existingUser.fetchFacebookUser(facebookAttrs.facebookID, { existingUser.fetchFacebookUser(facebookAttrs.facebookID, {
success: => success: =>
me.loginFacebookUser(facebookAttrs.facebookID, { me.loginFacebookUser(facebookAttrs.facebookID, {
success: -> window.location.reload() success: -> loginNavigate()
error: @onFacebookLoginError error: @onFacebookLoginError
}) })
error: @onFacebookLoginError error: @onFacebookLoginError
@ -148,3 +148,11 @@ formSchema = {
} }
required: ['emailOrUsername', 'password'] required: ['emailOrUsername', 'password']
} }
loginNavigate = ->
if me.isStudent()
application.router.navigate('/courses', {trigger: true})
else if me.isTeacher()
application.router.navigate('/teachers/classes', {trigger: true})
window.location.reload()

View file

@ -123,7 +123,11 @@ module.exports = class CreateAccountModal extends ModalView
@once 'hidden', -> @once 'hidden', ->
if @signupState.get('accountCreated') and not application.testing if @signupState.get('accountCreated') and not application.testing
# ensure logged in state propagates through the entire app # ensure logged in state propagates through the entire app
document.location.reload() if me.isStudent()
application.router.navigate('/courses', {trigger: true})
else if me.isTeacher()
application.router.navigate('/teachers/classes', {trigger: true})
window.location.reload()
onClickLoginLink: -> onClickLoginLink: ->
@openModalView(new AuthModal({ initialValues: @signupState.get('authModalInitialValues') })) @openModalView(new AuthModal({ initialValues: @signupState.get('authModalInitialValues') }))

View file

@ -13,6 +13,7 @@ Course = require 'models/Course'
Classroom = require 'models/Classroom' Classroom = require 'models/Classroom'
Classrooms = require 'collections/Classrooms' Classrooms = require 'collections/Classrooms'
LevelSession = require 'models/LevelSession' LevelSession = require 'models/LevelSession'
NameLoader = require 'core/NameLoader'
Campaign = require 'models/Campaign' Campaign = require 'models/Campaign'
ThangType = require 'models/ThangType' ThangType = require 'models/ThangType'
utils = require 'core/utils' utils = require 'core/utils'
@ -90,6 +91,14 @@ module.exports = class CoursesView extends RootView
@joinClass() @joinClass()
else if @classCodeQueryVar and me.isAnonymous() else if @classCodeQueryVar and me.isAnonymous()
@openModalView(new CreateAccountModal()) @openModalView(new CreateAccountModal())
ownerIDs = _.map(@classrooms.models, (c) -> c.get('ownerID')) ? []
Promise.resolve($.ajax(NameLoader.loadNames(ownerIDs)))
.then(=>
@ownerNameMap = {}
@ownerNameMap[ownerID] = NameLoader.getName(ownerID) for ownerID in ownerIDs
@render?()
)
onClickLogInButton: -> onClickLogInButton: ->
modal = new AuthModal() modal = new AuthModal()