From 7a6c42b89f1b29f34b836a38c2bb19c2f0930cb9 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Wed, 18 Nov 2015 14:02:45 -0800
Subject: [PATCH] Set up course-ladder level handling

* LadderView displays course info, different style for course-ladder levels
* LadderView hides simulate tab for course-ladder levels
* HeroVictoryModal links to LadderView for course-ladder levels
* CourseDetails page links to LadderView for course-ladder levels
* Enable course instances for league simulation
---
 app/styles/play/ladder/ladder.sass            | 22 +++++++++++++
 app/templates/courses/course-details.jade     |  2 +-
 app/templates/play/ladder/ladder.jade         | 32 ++++++++++++++-----
 app/views/courses/CourseDetailsView.coffee    | 17 +++++++---
 app/views/ladder/LadderPlayModal.coffee       |  1 +
 app/views/ladder/LadderView.coffee            | 16 +++++++---
 .../play/level/modal/HeroVictoryModal.coffee  |  7 ++++
 server/queues/scoring/createNewTask.coffee    |  2 +-
 8 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/app/styles/play/ladder/ladder.sass b/app/styles/play/ladder/ladder.sass
index b134ec5c1..f6aefedd7 100644
--- a/app/styles/play/ladder/ladder.sass
+++ b/app/styles/play/ladder/ladder.sass
@@ -5,6 +5,22 @@
     margin: -14px -12px 20px -12px
     padding-bottom: 30px
     border-bottom: 1px solid #888
+    
+  #course-header
+    background-color: black
+    font-size: 24px
+    padding: 6px 4px 8px
+    font-weight: bold
+
+    #course-details-link
+      position: absolute
+      background-color: white
+      padding: 2px 5px
+      a
+        color: black
+      
+    #course-name
+      color: white
 
   #level-column
     padding-top: 14px
@@ -13,6 +29,12 @@
     img
       margin-top: -14px
       width: 100%
+      
+  #course-h1
+    color: black
+    font-size: 72px
+    text-transform: capitalize
+    margin-top: 0
 
   h1
     text-align: center
diff --git a/app/templates/courses/course-details.jade b/app/templates/courses/course-details.jade
index bf7b20852..3e48d4f53 100644
--- a/app/templates/courses/course-details.jade
+++ b/app/templates/courses/course-details.jade
@@ -273,7 +273,7 @@ mixin levels-tab
           tr
             td
               if lastLevelCompleted || adminMode
-                button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n="home.play")
+                button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n="home.play", data-level-id=levelID)
             td
               if userLevelStateMap[me.id]
                 div= userLevelStateMap[me.id][levelID]
diff --git a/app/templates/play/ladder/ladder.jade b/app/templates/play/ladder/ladder.jade
index 928604fa8..8a923a76e 100644
--- a/app/templates/play/ladder/ladder.jade
+++ b/app/templates/play/ladder/ladder.jade
@@ -3,14 +3,28 @@ block content
   - var base = "/images/pages/play/ladder/prize_";
 
   div#ladder-top
+    
+    if leagueType == 'course'
+      #course-header
+        #course-details-link
+          a(href="/courses/"+view.course.id+"/"+view.league.id)
+            span.glyphicon.glyphicon-arrow-left
+            span.spl Levels
+      
+        .text-center
+          span#course-name
+            span= view.course.get('name')
+            span.spl - Arena
+        
 
     div#level-column
+      if leagueType === 'course'
+        h1#course-h1= (level.get('name') || '').toUpperCase()
+      
       if levelDescription
         div!= levelDescription
-      else
-        h1= level.get('name')
 
-      if league
+      if leagueType === 'clan'
         h1.league-header
           a(href="/#{leagueType == 'clan' ? 'clans' : leagueType}/#{league.id}")= league.get('name')
           span.spl(data-i18n="ladder.league") League
@@ -132,9 +146,10 @@ block content
             span= team.displayName
       div.column.col-md-2
   
-    .spectate-button-container
-      a(href="/play/spectate/#{level.get('slug')}" + (league ? "?league=" + league.id : "")).spectate-button.btn.btn-illustrated.btn-info.center
-        span(data-i18n="play.spectate") Spectate
+    if leagueType !== 'course'
+      .spectate-button-container
+        a(href="/play/spectate/#{level.get('slug')}" + (league ? "?league=" + league.id : "")).spectate-button.btn.btn-illustrated.btn-info.center
+          span(data-i18n="play.spectate") Spectate
 
   ul.nav.nav-pills
     li.active
@@ -142,8 +157,9 @@ block content
     if !me.get('anonymous')
       li
         a(href="#my-matches", data-toggle="tab", data-i18n="ladder.my_matches") My Matches
-      li
-        a(href="#simulate", data-toggle="tab", data-i18n="ladder.simulate") Simulate
+      if leagueType !== 'course'
+        li
+          a(href="#simulate", data-toggle="tab", data-i18n="ladder.simulate") Simulate
     if level.get('name') == 'Greed'
       li
         a(href="#prizes", data-toggle="tab", data-i18n="ladder_prizes.prizes") Prizes
diff --git a/app/views/courses/CourseDetailsView.coffee b/app/views/courses/CourseDetailsView.coffee
index aa6a0bd2a..954f6a771 100644
--- a/app/views/courses/CourseDetailsView.coffee
+++ b/app/views/courses/CourseDetailsView.coffee
@@ -218,11 +218,18 @@ module.exports = class CourseDetailsView extends RootView
 
   onClickPlayLevel: (e) ->
     levelSlug = $(e.target).data('level-slug')
-    Backbone.Mediator.publish 'router:navigate', {
-      route: @getLevelURL levelSlug
-      viewClass: 'views/play/level/PlayLevelView'
-      viewArgs: [{courseID: @courseID, courseInstanceID: @courseInstanceID}, levelSlug]
-    }
+    levelID = $(e.target).data('level-id')
+    level = @campaign.get('levels')[levelID]
+    if level.type is 'course-ladder'
+      Backbone.Mediator.publish 'router:navigate', {
+        route: '/play/ladder/' + levelSlug + '/course/' + @courseInstance.id
+      }
+    else
+      Backbone.Mediator.publish 'router:navigate', {
+        route: @getLevelURL levelSlug
+        viewClass: 'views/play/level/PlayLevelView'
+        viewArgs: [{courseID: @courseID, courseInstanceID: @courseInstanceID}, levelSlug]
+      }
 
   getLevelURL: (levelSlug) ->
     "/play/level/#{levelSlug}?course=#{@courseID}&course-instance=#{@courseInstanceID}"
diff --git a/app/views/ladder/LadderPlayModal.coffee b/app/views/ladder/LadderPlayModal.coffee
index 473843792..44c88a6fd 100644
--- a/app/views/ladder/LadderPlayModal.coffee
+++ b/app/views/ladder/LadderPlayModal.coffee
@@ -81,6 +81,7 @@ module.exports = class LadderPlayModal extends ModalView
   # PART 4: Render
 
   finishRendering: ->
+    return if @destroyed
     @checkTutorialLevelExists (exists) =>
       @tutorialLevelExists = exists
       @render()
diff --git a/app/views/ladder/LadderView.coffee b/app/views/ladder/LadderView.coffee
index 423d54d92..437fb9664 100644
--- a/app/views/ladder/LadderView.coffee
+++ b/app/views/ladder/LadderView.coffee
@@ -13,7 +13,8 @@ LadderPlayModal = require './LadderPlayModal'
 CocoClass = require 'core/CocoClass'
 
 Clan = require 'models/Clan'
-#CourseInstance = require 'models/CourseInstance'
+CourseInstance = require 'models/CourseInstance'
+Course = require 'models/Course'
 
 HIGHEST_SCORE = 1000000
 
@@ -44,13 +45,20 @@ module.exports = class LadderView extends RootView
     @sessions = @supermodel.loadCollection(new LevelSessionsCollection(@levelID), 'your_sessions', {cache: false}).model
     @teams = []
     @loadLeague()
+    @course = new Course()
 
   loadLeague: ->
-    @leagueID = @leagueType = null unless @leagueType in ['clan']  #, 'course']
+    @leagueID = @leagueType = null unless @leagueType in ['clan', 'course']
     return unless @leagueID
-    modelClass = if @leagueType is 'clan' then Clan else null# else CourseInstance
-    resourceString = if @leagueType is 'clan' then 'clans.clan' else null# else 'courses.course'
+    modelClass = if @leagueType is 'clan' then Clan else CourseInstance
+    resourceString = if @leagueType is 'clan' then 'clans.clan' else 'courses.course'
     @league = @supermodel.loadModel(new modelClass(_id: @leagueID), resourceString).model
+    if @leagueType is 'course'
+      @listenToOnce @league, 'sync', @onCourseInstanceLoaded
+
+  onCourseInstanceLoaded: (courseInstance) ->
+    course = new Course({_id: courseInstance.get('courseID')})
+    @course = @supermodel.loadModel(course, 'courses.course').model
 
   onLoaded: ->
     @teams = teamDataFromLevel @level
diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee
index 4eeaf3782..8df5c81c7 100644
--- a/app/views/play/level/modal/HeroVictoryModal.coffee
+++ b/app/views/play/level/modal/HeroVictoryModal.coffee
@@ -441,6 +441,13 @@ module.exports = class HeroVictoryModal extends ModalView
         viewClass = require 'views/courses/CourseDetailsView'
         viewArgs.push @courseID
         viewArgs.push @courseInstanceID if @courseInstanceID
+    else if @level.get('type', true) is 'course-ladder'
+      leagueID = @getQueryVariable 'league'
+      link = "/play/ladder/"+@level.get('slug')+"/course/"+leagueID
+      Backbone.Mediator.publish 'router:navigate', {
+        route: link
+      }
+      return
     else
       viewClass = require 'views/play/CampaignView'
       viewArgs = [options, @getNextLevelCampaign()]
diff --git a/server/queues/scoring/createNewTask.coffee b/server/queues/scoring/createNewTask.coffee
index 6b6370c27..4ded373e5 100644
--- a/server/queues/scoring/createNewTask.coffee
+++ b/server/queues/scoring/createNewTask.coffee
@@ -67,7 +67,7 @@ updateSessionToSubmit = (transpiledCode, user, sessionToUpdate, callback) ->
 
   # Reset all league stats as well, and enter the session into any leagues the user is currently part of (not retroactive when joining new leagues)
   leagueIDs = user.get('clans') or []
-  #leagueIDs = leagueIDs.concat user.get('courseInstances') or []
+  leagueIDs = leagueIDs.concat user.get('courseInstances') or []
   leagueIDs = (leagueID + '' for leagueID in leagueIDs)  # Make sure to save them as strings.
   newLeagues = []
   for leagueID in leagueIDs