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) =>
_.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()

View file

@ -1235,7 +1235,7 @@
play_now_learn_2: "while loops to solve pesky puzzles"
play_now_learn_3: "strings & variables to customize actions"
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!"
ready_for_more_header: "Ready for more? Play the campaign mode!"
ready_for_more_1: "Use gems to unlock new items!"
@ -1243,10 +1243,9 @@
ready_for_more_3: "Learn even more programming!"
saved_games: "Saved Games"
hoc: "Hour of Code"
my_classes: "My Classes"
my_classes: "Current Classes" # {change}
class_added: "Class successfully added!"
view_class: "view class"
view_levels: "view levels"
view_levels: "view all levels in course" # {change}
join_class: "Join A 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:"
@ -1257,7 +1256,7 @@
play_arena: "Play Arena"
view_project: "View Project"
start: "Start"
last_level: "Last Level"
last_level: "Last level played" # {change}
welcome_to_hoc: "Adventurers, welcome to our Hour of Code!"
logged_in_as: "Logged in as:"
not_you: "Not you?"

View file

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

View file

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

View file

@ -38,7 +38,7 @@ block content
else
.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
.hero-avatar
@ -51,10 +51,11 @@ block content
span(data-i18n="courses.change_hero")
if view.classrooms.size()
h3.text-uppercase(data-i18n="courses.my_classes")
hr
br
h3(data-i18n="courses.my_classes")
for classroom in view.classrooms.models
hr.class-break
- var justAdded = classroom.id === view.classroomJustAdded;
- var classroomClass = justAdded ? 'just-added' : '';
if justAdded
@ -65,8 +66,12 @@ block content
h5
span.spr= classroom.get('name')
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});
for courseInstance in courseInstances
@ -78,7 +83,7 @@ block content
a.view-levels-btn(data-course-id=courseInstance.get('courseID'), data-courseinstance-id=courseInstance.id, data-i18n="courses.view_levels")
+course-instance-body(courseInstance, classroom)
.clearfix
h3.text-uppercase(data-i18n="courses.join_class")
hr
@ -111,11 +116,11 @@ mixin course-instance-body(courseInstance, classroom)
- var projectLevel = stats.levels.project;
if arenaLevel
- 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")
else if projectLevel
- 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")
else
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")
span(data-i18n="courses.start")
div
span(data-i18n="clans.playtime")
span.spr :
span= moment.duration(stats.playtime, 'seconds').humanize()
if stats.levels.lastPlayed
div
span(data-i18n="courses.last_level")
span.spr :
span= stats.levels.lastPlayed.get('name')
span : #{stats.levels.lastPlayedNumber}.
span.spl= stats.levels.lastPlayed.get('name')
.clearfix
.progress

View file

@ -51,7 +51,7 @@ module.exports = class AuthModal extends ModalView
return forms.applyErrorsToForm(@$el, res.errors) unless res.valid
new Promise(me.loginPasswordUser(userObject.emailOrUsername, userObject.password).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) =>
showingError = false
@ -85,7 +85,7 @@ module.exports = class AuthModal extends ModalView
existingUser.fetchGPlusUser(gplusAttrs.gplusID, {
success: =>
me.loginGPlusUser(gplusAttrs.gplusID, {
success: -> window.location.reload()
success: -> loginNavigate()
error: @onGPlusLoginError
})
error: @onGPlusLoginError
@ -116,7 +116,7 @@ module.exports = class AuthModal extends ModalView
existingUser.fetchFacebookUser(facebookAttrs.facebookID, {
success: =>
me.loginFacebookUser(facebookAttrs.facebookID, {
success: -> window.location.reload()
success: -> loginNavigate()
error: @onFacebookLoginError
})
error: @onFacebookLoginError
@ -148,3 +148,11 @@ formSchema = {
}
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', ->
if @signupState.get('accountCreated') and not application.testing
# 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: ->
@openModalView(new AuthModal({ initialValues: @signupState.get('authModalInitialValues') }))

View file

@ -13,6 +13,7 @@ Course = require 'models/Course'
Classroom = require 'models/Classroom'
Classrooms = require 'collections/Classrooms'
LevelSession = require 'models/LevelSession'
NameLoader = require 'core/NameLoader'
Campaign = require 'models/Campaign'
ThangType = require 'models/ThangType'
utils = require 'core/utils'
@ -59,7 +60,7 @@ module.exports = class CoursesView extends RootView
@listenTo @hero, 'all', ->
@render()
window.tracker?.trackEvent 'Students Loaded', category: 'Students', ['Mixpanel']
afterInsert: ->
super()
unless me.isStudent() or (@classCodeQueryVar and not me.isTeacher())
@ -90,6 +91,14 @@ module.exports = class CoursesView extends RootView
@joinClass()
else if @classCodeQueryVar and me.isAnonymous()
@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: ->
modal = new AuthModal()