2015-09-03 14:04:40 -04:00
Course = require ' models/Course '
2016-04-13 12:54:24 -04:00
Courses = require ' collections/Courses '
LevelSessions = require ' collections/LevelSessions '
2015-09-03 14:04:40 -04:00
CourseInstance = require ' models/CourseInstance '
2016-04-13 12:54:24 -04:00
CourseInstances = require ' collections/CourseInstances '
2015-11-09 21:08:39 -05:00
Classroom = require ' models/Classroom '
2016-03-30 19:20:37 -04:00
Classrooms = require ' collections/Classrooms '
2016-04-13 12:54:24 -04:00
Levels = require ' collections/Levels '
2015-09-13 01:01:59 -04:00
RootView = require ' views/core/RootView '
template = require ' templates/courses/course-details '
User = require ' models/User '
2015-12-02 13:59:55 -05:00
storage = require ' core/storage '
2015-09-03 14:04:40 -04:00
module.exports = class CourseDetailsView extends RootView
id: ' course-details-view '
template: template
2015-12-02 12:52:52 -05:00
teacherMode: false
memberSort: ' nameAsc '
2015-09-03 14:04:40 -04:00
2015-09-13 01:01:59 -04:00
events:
' click .btn-play-level ' : ' onClickPlayLevel '
2015-09-23 19:27:45 -04:00
' click .btn-select-instance ' : ' onClickSelectInstance '
2015-12-02 13:59:55 -05:00
' submit # school-form ' : ' onSubmitSchoolForm '
2015-09-13 01:01:59 -04:00
2015-09-24 20:12:18 -04:00
constructor: (options, @courseID, @courseInstanceID) ->
2015-09-03 14:04:40 -04:00
super options
2016-03-30 19:20:37 -04:00
@ownedClassrooms = new Classrooms ( )
2016-04-13 12:54:24 -04:00
@courses = new Courses ( )
@course = new Course ( )
@levelSessions = new LevelSessions ( )
@courseInstance = new CourseInstance ( { _id: @ courseInstanceID } )
@owner = new User ( )
2015-11-09 21:08:39 -05:00
@classroom = new Classroom ( )
2016-04-13 12:54:24 -04:00
@levels = new Levels ( )
@courseInstances = new CourseInstances ( )
@ supermodel . trackRequest @ ownedClassrooms . fetchMine ( { data: { project: ' _id ' } } )
@ supermodel . trackRequest ( @ courses . fetch ( ) . then ( =>
@course = @ courses . get ( @ courseID )
) )
sessionsLoaded = @ supermodel . trackRequest ( @ levelSessions . fetchForCourseInstance ( @ courseInstanceID , { cache: false } ) )
@ supermodel . trackRequest ( @ courseInstance . fetch ( ) . then ( =>
return if @ destroyed
@teacherMode = @ courseInstance . get ( ' ownerID ' ) is me . id
@owner = new User ( { _id: @ courseInstance . get ( ' ownerID ' ) } )
@ supermodel . trackRequest ( @ owner . fetch ( ) )
classroomID = @ courseInstance . get ( ' classroomID ' )
@classroom = new Classroom ( { _id: classroomID } )
@ supermodel . trackRequest ( @ classroom . fetch ( ) )
levelsLoaded = @ supermodel . trackRequest ( @ levels . fetchForClassroomAndCourse ( classroomID , @ courseID , {
2016-07-17 03:53:17 -04:00
data: { project: ' concepts,practice,type,slug,name,original,description,shareable,i18n ' }
2016-04-13 12:54:24 -04:00
} ) )
@ supermodel . trackRequest ( $ . when ( levelsLoaded , sessionsLoaded ) . then ( =>
@ buildSessionStats ( )
return if @ destroyed
if @ memberStats [ me . id ] ? . totalLevelsCompleted >= @ levels . size ( ) - 1 # Don't need to complete arena
# need to figure out the next course instance
@courseComplete = true
@courseInstances.comparator = ' courseID '
2016-07-14 11:58:43 -04:00
# TODO: make this logic use locked course content to figure out the next course, then fetch the
2016-05-18 20:03:49 -04:00
# course instance for that
2016-04-13 12:54:24 -04:00
@ supermodel . trackRequest ( @ courseInstances . fetchForClassroom ( classroomID ) . then ( =>
@nextCourseInstance = _ . find @ courseInstances . models , (ci) => ci . get ( ' courseID ' ) > @ courseID
if @ nextCourseInstance
nextCourseID = @ nextCourseInstance . get ( ' courseID ' )
@nextCourse = @ courses . get ( nextCourseID )
) )
@promptForSchool = @ courseComplete and not me . isAnonymous ( ) and not me . get ( ' schoolName ' ) and not storage . load ( ' no-school ' )
) )
) )
2015-09-13 01:01:59 -04:00
2016-06-08 09:24:59 -04:00
initialize: (options) ->
window . tracker ? . trackEvent ' Students Class Course Loaded ' , category: ' Students ' , [ ' Mixpanel ' ]
super ( options )
2016-04-13 12:54:24 -04:00
buildSessionStats: ->
2015-12-02 12:52:52 -05:00
return if @ destroyed
2016-04-13 12:54:24 -04:00
2015-09-13 01:01:59 -04:00
@levelConceptMap = { }
2016-04-13 12:54:24 -04:00
for level in @ levels . models
@ levelConceptMap [ level . get ( ' original ' ) ] ? = { }
2016-07-15 19:57:39 -04:00
for concept in level . get ( ' concepts ' ) or [ ]
2016-04-13 12:54:24 -04:00
@ levelConceptMap [ level . get ( ' original ' ) ] [ concept ] = true
2016-07-14 11:58:43 -04:00
if level . isType ( ' course-ladder ' )
2015-12-02 12:52:52 -05:00
@arenaLevel = level
2015-09-03 14:04:40 -04:00
2015-09-13 01:01:59 -04:00
# console.log 'onLevelSessionsSync'
2015-09-24 10:28:43 -04:00
@memberStats = { }
2015-09-13 01:01:59 -04:00
@userConceptStateMap = { }
@userLevelStateMap = { }
for levelSession in @ levelSessions . models
2015-12-01 20:23:33 -05:00
continue if levelSession . skipMe # Don't track second arena session as another completed level
2015-09-13 01:01:59 -04:00
userID = levelSession . get ( ' creator ' )
levelID = levelSession . get ( ' level ' ) . original
state = if levelSession . get ( ' state ' ) ? . complete then ' complete ' else ' started '
2015-12-01 20:23:33 -05:00
playtime = parseInt ( levelSession . get ( ' playtime ' ) ? 0 , 10 )
do (userID, levelID) =>
secondSessionForLevel = _ . find ( @ levelSessions . models , ( (otherSession) ->
otherSession . get ( ' creator ' ) is userID and otherSession . get ( ' level ' ) . original is levelID and otherSession . id isnt levelSession . id
) )
if secondSessionForLevel
state = ' complete ' if secondSessionForLevel . get ( ' state ' ) ? . complete
playtime = playtime + parseInt ( secondSessionForLevel . get ( ' playtime ' ) ? 0 , 10 )
secondSessionForLevel.skipMe = true
2015-09-24 10:28:43 -04:00
@ memberStats [ userID ] ? = totalLevelsCompleted: 0 , totalPlayTime: 0
@ memberStats [ userID ] . totalLevelsCompleted ++ if state is ' complete '
2015-12-01 20:23:33 -05:00
@ memberStats [ userID ] . totalPlayTime += playtime
2015-09-24 10:28:43 -04:00
@ userConceptStateMap [ userID ] ? = { }
2015-09-13 01:01:59 -04:00
for concept of @ levelConceptMap [ levelID ]
@ userConceptStateMap [ userID ] [ concept ] = state
2015-09-24 10:28:43 -04:00
@ userLevelStateMap [ userID ] ? = { }
@ userLevelStateMap [ userID ] [ levelID ] = state
2015-09-13 01:01:59 -04:00
@conceptsCompleted = { }
for userID , conceptStateMap of @ userConceptStateMap
for concept , state of conceptStateMap
@ conceptsCompleted [ concept ] ? = 0
@ conceptsCompleted [ concept ] ++
2016-07-14 11:58:43 -04:00
2015-09-13 01:01:59 -04:00
onClickPlayLevel: (e) ->
2015-12-04 17:28:05 -05:00
levelSlug = $ ( e . target ) . closest ( ' .btn-play-level ' ) . data ( ' level-slug ' )
levelID = $ ( e . target ) . closest ( ' .btn-play-level ' ) . data ( ' level-id ' )
2016-04-13 12:54:24 -04:00
level = @ levels . findWhere ( { original: levelID } )
2016-06-08 09:24:59 -04:00
window . tracker ? . trackEvent ' Students Class Course Play Level ' , category: ' Students ' , courseID: @ courseID , courseInstanceID: @ courseInstanceID , levelSlug: levelSlug , [ ' Mixpanel ' ]
2016-07-14 11:58:43 -04:00
if level . isType ( ' course-ladder ' )
2015-12-01 15:23:01 -05:00
viewClass = ' views/ladder/LadderView '
viewArgs = [ { supermodel: @ supermodel } , levelSlug ]
2015-11-19 16:20:21 -05:00
route = ' /play/ladder/ ' + levelSlug
2016-04-13 12:54:24 -04:00
route += ' /course/ ' + @ courseInstance . id
viewArgs = viewArgs . concat [ ' course ' , @ courseInstance . id ]
2015-11-18 17:02:45 -05:00
else
2015-12-01 15:23:01 -05:00
route = @ getLevelURL levelSlug
viewClass = ' views/play/level/PlayLevelView '
viewArgs = [ { courseID: @ courseID , courseInstanceID: @ courseInstanceID , supermodel: @ supermodel } , levelSlug ]
Backbone . Mediator . publish ' router:navigate ' , route: route , viewClass: viewClass , viewArgs: viewArgs
2015-09-13 01:01:59 -04:00
2015-11-12 12:57:34 -05:00
getLevelURL: (levelSlug) ->
" /play/level/ #{ levelSlug } ?course= #{ @ courseID } &course-instance= #{ @ courseInstanceID } "
2015-10-27 20:47:48 -04:00
getOwnerName: ->
2015-12-01 17:15:18 -05:00
return if @ owner . isNew ( )
2015-10-27 20:47:48 -04:00
if @ owner . get ( ' firstName ' ) and @ owner . get ( ' lastName ' )
return " #{ @ owner . get ( ' firstName ' ) } #{ @ owner . get ( ' lastName ' ) } "
2015-12-01 17:15:18 -05:00
@ owner . get ( ' name ' ) or @ owner . get ( ' email ' )
2015-12-02 13:59:55 -05:00
2015-12-11 15:59:53 -05:00
getLastLevelCompleted: ->
lastLevelCompleted = null
2016-04-13 12:54:24 -04:00
for levelID in @ levels . pluck ( ' original ' )
2015-12-11 15:59:53 -05:00
if @ userLevelStateMap ? [ me . id ] ? [ levelID ] is ' complete '
lastLevelCompleted = levelID
return lastLevelCompleted