mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-01-05 20:22:44 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
b4f67a71e6
9 changed files with 69 additions and 28 deletions
|
@ -69,8 +69,8 @@ module.exports = class CocoRouter extends Backbone.Router
|
||||||
'contribute/diplomat': go('contribute/DiplomatView')
|
'contribute/diplomat': go('contribute/DiplomatView')
|
||||||
'contribute/scribe': go('contribute/ScribeView')
|
'contribute/scribe': go('contribute/ScribeView')
|
||||||
|
|
||||||
'courses': go('courses/CoursesView', { studentsOnly: true })
|
'courses': go('courses/CoursesView')
|
||||||
'Courses': go('courses/CoursesView', { studentsOnly: true })
|
'Courses': go('courses/CoursesView')
|
||||||
'courses/students': redirect('/courses')
|
'courses/students': redirect('/courses')
|
||||||
'courses/teachers': redirect('/teachers/classes')
|
'courses/teachers': redirect('/teachers/classes')
|
||||||
'courses/purchase': redirect('/teachers/licenses')
|
'courses/purchase': redirect('/teachers/licenses')
|
||||||
|
|
|
@ -364,8 +364,8 @@ module.exports = class World
|
||||||
endFrame = @frames.length
|
endFrame = @frames.length
|
||||||
#console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames
|
#console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames
|
||||||
[transferableObjects, nontransferableObjects] = [0, 0]
|
[transferableObjects, nontransferableObjects] = [0, 0]
|
||||||
delete flag.processed for flag in @flagHistory
|
serializedFlagHistory = (_.omit(_.clone(flag), 'processed') for flag in @flagHistory)
|
||||||
o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: @flagHistory, difficulty: @difficulty, scores: @getScores(), randomSeed: @randomSeed, picoCTFFlag: @picoCTFFlag}
|
o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: serializedFlagHistory, difficulty: @difficulty, scores: @getScores(), randomSeed: @randomSeed, picoCTFFlag: @picoCTFFlag}
|
||||||
o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
|
o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
|
||||||
|
|
||||||
for thangID, methods of @userCodeMap
|
for thangID, methods of @userCodeMap
|
||||||
|
|
|
@ -5,19 +5,21 @@ block page_nav
|
||||||
|
|
||||||
block content
|
block content
|
||||||
if me.isAnonymous() || (!me.isTeacher() && !view.classrooms.size())
|
if me.isAnonymous() || (!me.isTeacher() && !view.classrooms.size())
|
||||||
.access-restricted.container.text-center.m-y-3
|
.container
|
||||||
h5(data-i18n='teacher.access_restricted')
|
.access-restricted.container.text-center.m-y-3
|
||||||
p(data-i18n='teacher.teacher_account_required')
|
h5(data-i18n='teacher.access_restricted')
|
||||||
if me.isAnonymous()
|
p(data-i18n='teacher.teacher_account_required')
|
||||||
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
|
if me.isAnonymous()
|
||||||
a.btn.btn-lg.btn-primary-alt(href="/teachers/signup" data-i18n='teacher.create_teacher_account')
|
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
|
||||||
else
|
a.btn.btn-lg.btn-primary-alt(href="/teachers/signup" data-i18n='teacher.create_teacher_account')
|
||||||
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
|
else
|
||||||
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
|
||||||
|
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
||||||
|
|
||||||
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
.container
|
||||||
h5(data-i18n='teacher.what_is_a_teacher_account')
|
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
||||||
p(data-i18n='teacher.teacher_account_explanation')
|
h5(data-i18n='teacher.what_is_a_teacher_account')
|
||||||
|
p(data-i18n='teacher.teacher_account_explanation')
|
||||||
|
|
||||||
else
|
else
|
||||||
if !me.isTeacher()
|
if !me.isTeacher()
|
||||||
|
|
|
@ -17,6 +17,7 @@ block content
|
||||||
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
||||||
|
|
||||||
if me.isTeacher()
|
if me.isTeacher()
|
||||||
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
.container
|
||||||
h5(data-i18n='teacher.what_is_a_teacher_account')
|
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
||||||
p(data-i18n='teacher.teacher_account_explanation')
|
h5(data-i18n='teacher.what_is_a_teacher_account')
|
||||||
|
p(data-i18n='teacher.teacher_account_explanation')
|
||||||
|
|
|
@ -15,9 +15,10 @@ block content
|
||||||
button.btn.btn-lg.btn-primary.update-teacher-btn(data-event-action="Teachers Classes Convert Teacher Account", data-i18n="teachers_quote.convert_account_title")
|
button.btn.btn-lg.btn-primary.update-teacher-btn(data-event-action="Teachers Classes Convert Teacher Account", data-i18n="teachers_quote.convert_account_title")
|
||||||
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
||||||
|
|
||||||
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
.container
|
||||||
h5(data-i18n='teacher.what_is_a_teacher_account')
|
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
||||||
p(data-i18n='teacher.teacher_account_explanation')
|
h5(data-i18n='teacher.what_is_a_teacher_account')
|
||||||
|
p(data-i18n='teacher.teacher_account_explanation')
|
||||||
|
|
||||||
else
|
else
|
||||||
if !me.isTeacher()
|
if !me.isTeacher()
|
||||||
|
|
|
@ -14,6 +14,7 @@ block content
|
||||||
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
|
a.btn.btn-lg.btn-primary(href="/teachers/update-account" data-i18n="teachers_quote.convert_account_title")
|
||||||
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
|
||||||
|
|
||||||
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
.container
|
||||||
h5(data-i18n='teacher.what_is_a_teacher_account')
|
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
|
||||||
p(data-i18n='teacher.teacher_account_explanation')
|
h5(data-i18n='teacher.what_is_a_teacher_account')
|
||||||
|
p(data-i18n='teacher.teacher_account_explanation')
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = class CoursesView extends RootView
|
||||||
@courseInstances = new CocoCollection([], { url: "/db/user/#{me.id}/course_instances", model: CourseInstance})
|
@courseInstances = new CocoCollection([], { url: "/db/user/#{me.id}/course_instances", model: CourseInstance})
|
||||||
@courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID')
|
@courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID')
|
||||||
@listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded
|
@listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded
|
||||||
@supermodel.loadCollection(@courseInstances)
|
@supermodel.loadCollection(@courseInstances, { cache: false })
|
||||||
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
|
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
|
||||||
@supermodel.loadCollection(@classrooms, { data: {memberID: me.id}, cache: false })
|
@supermodel.loadCollection(@classrooms, { data: {memberID: me.id}, cache: false })
|
||||||
@ownedClassrooms = new Classrooms()
|
@ownedClassrooms = new Classrooms()
|
||||||
|
@ -59,6 +59,11 @@ module.exports = class CoursesView extends RootView
|
||||||
@listenTo @hero, 'all', ->
|
@listenTo @hero, 'all', ->
|
||||||
@render()
|
@render()
|
||||||
window.tracker?.trackEvent 'Students Loaded', category: 'Students', ['Mixpanel']
|
window.tracker?.trackEvent 'Students Loaded', category: 'Students', ['Mixpanel']
|
||||||
|
|
||||||
|
afterInsert: ->
|
||||||
|
super()
|
||||||
|
unless me.isStudent() or (@classCodeQueryVar and not me.isTeacher())
|
||||||
|
@onClassLoadError()
|
||||||
|
|
||||||
onCourseInstancesLoaded: ->
|
onCourseInstancesLoaded: ->
|
||||||
map = {}
|
map = {}
|
||||||
|
@ -135,12 +140,21 @@ module.exports = class CoursesView extends RootView
|
||||||
else
|
else
|
||||||
modal = new JoinClassModal({ @classCode })
|
modal = new JoinClassModal({ @classCode })
|
||||||
@openModalView modal
|
@openModalView modal
|
||||||
|
@listenTo modal, 'error', @onClassLoadError
|
||||||
@listenTo modal, 'join:success', @onJoinClassroomSuccess
|
@listenTo modal, 'join:success', @onJoinClassroomSuccess
|
||||||
@listenTo modal, 'join:error', @onJoinClassroomError
|
@listenTo modal, 'join:error', @onJoinClassroomError
|
||||||
|
@listenToOnce modal, 'hidden', ->
|
||||||
|
unless me.isStudent()
|
||||||
|
@onClassLoadError()
|
||||||
@listenTo modal, 'hidden', ->
|
@listenTo modal, 'hidden', ->
|
||||||
@state = null
|
@state = null
|
||||||
@renderSelectors '#join-class-form'
|
@renderSelectors '#join-class-form'
|
||||||
|
|
||||||
|
# Super hacky way to patch users being able to join class while hiding /courses from others
|
||||||
|
onClassLoadError: ->
|
||||||
|
_.defer ->
|
||||||
|
application.router.routeDirectly('courses/RestrictedToStudentsView')
|
||||||
|
|
||||||
onJoinClassroomError: (classroom, jqxhr, options) ->
|
onJoinClassroomError: (classroom, jqxhr, options) ->
|
||||||
@state = null
|
@state = null
|
||||||
if jqxhr.status is 422
|
if jqxhr.status is 422
|
||||||
|
|
|
@ -16,6 +16,8 @@ module.exports = class JoinClassModal extends ModalView
|
||||||
jqxhr = @supermodel.trackRequest @classroom.fetchByCode(@classCode)
|
jqxhr = @supermodel.trackRequest @classroom.fetchByCode(@classCode)
|
||||||
unless me.get('emailVerified')
|
unless me.get('emailVerified')
|
||||||
@supermodel.trackRequest $.post("/db/user/#{me.id}/request-verify-email")
|
@supermodel.trackRequest $.post("/db/user/#{me.id}/request-verify-email")
|
||||||
|
@listenTo @classroom, 'error', ->
|
||||||
|
@trigger('error')
|
||||||
@listenTo @classroom, 'sync', ->
|
@listenTo @classroom, 'sync', ->
|
||||||
@render
|
@render
|
||||||
@listenTo @classroom, 'join:success', ->
|
@listenTo @classroom, 'join:success', ->
|
||||||
|
|
|
@ -57,7 +57,20 @@ const emailDelayMinutes = 27;
|
||||||
const scriptStartTime = new Date();
|
const scriptStartTime = new Date();
|
||||||
const closeIoApiKey = process.argv[2];
|
const closeIoApiKey = process.argv[2];
|
||||||
// Automatic mails sent as API owners, first key assumed to be primary and gets 50% of the leads
|
// Automatic mails sent as API owners, first key assumed to be primary and gets 50% of the leads
|
||||||
const closeIoMailApiKeys = [process.argv[3], process.argv[3], process.argv[4], process.argv[5]];
|
const closeIoMailApiKeys = [
|
||||||
|
{
|
||||||
|
apiKey: process.argv[3],
|
||||||
|
weight: .7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiKey: process.argv[4],
|
||||||
|
weight: .25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
apiKey: process.argv[5],
|
||||||
|
weight: .05
|
||||||
|
},
|
||||||
|
];
|
||||||
const closeIoEuMailApiKey = process.argv[6];
|
const closeIoEuMailApiKey = process.argv[6];
|
||||||
const intercomAppIdApiKey = process.argv[7];
|
const intercomAppIdApiKey = process.argv[7];
|
||||||
const intercomAppId = intercomAppIdApiKey.split(':')[0];
|
const intercomAppId = intercomAppIdApiKey.split(':')[0];
|
||||||
|
@ -238,7 +251,14 @@ function isUSSchoolStatus(status) {
|
||||||
function getEmailApiKey(leadStatus) {
|
function getEmailApiKey(leadStatus) {
|
||||||
if (leadStatus === defaultEuLeadStatus) return closeIoEuMailApiKey;
|
if (leadStatus === defaultEuLeadStatus) return closeIoEuMailApiKey;
|
||||||
if (closeIoMailApiKeys.length < 0) return;
|
if (closeIoMailApiKeys.length < 0) return;
|
||||||
return closeIoMailApiKeys[Math.floor(Math.random() * closeIoMailApiKeys.length)];
|
const weightedList = [];
|
||||||
|
for (let closeIoMailApiKey of closeIoMailApiKeys) {
|
||||||
|
const multiples = closeIoMailApiKey.weight * 100;
|
||||||
|
for (let i = 0; i < multiples; i++) {
|
||||||
|
weightedList.push(closeIoMailApiKey.apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return weightedList[Math.floor(Math.random() * weightedList.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomEmailTemplate(templates) {
|
function getRandomEmailTemplate(templates) {
|
||||||
|
|
Loading…
Reference in a new issue