mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-29 23:43:51 -04:00
Leaderboard skeletons.
This commit is contained in:
parent
a092444455
commit
4efbe0a12f
22 changed files with 246 additions and 4 deletions
app
assets/images/pages/front
locale
models
styles/play
level/modal
menu
game-menu-modal.sassguide-view.sassinventory-modal.sassitem-view.sassmultiplayer-view.sassoptions-view.sasssave-load-view.sass
modal
templates/play
views
common
editor/modal
play
Binary file not shown.
Before ![]() (image error) Size: 59 KiB |
|
@ -340,6 +340,14 @@
|
||||||
multiplayer_caption: "Play with friends!"
|
multiplayer_caption: "Play with friends!"
|
||||||
auth_caption: "Save your progress."
|
auth_caption: "Save your progress."
|
||||||
|
|
||||||
|
leaderboard:
|
||||||
|
leaderboard: "Leaderboard"
|
||||||
|
view_other_solutions: "View Other Solutions"
|
||||||
|
top_solutions: "Top Solutions"
|
||||||
|
day_tab: "Today"
|
||||||
|
week_tab: "This Week"
|
||||||
|
all_tab: "All-Time"
|
||||||
|
|
||||||
inventory:
|
inventory:
|
||||||
choose_inventory: "Equip Items"
|
choose_inventory: "Equip Items"
|
||||||
equipped_item: "Equipped"
|
equipped_item: "Equipped"
|
||||||
|
|
|
@ -133,6 +133,21 @@ module.exports = class User extends CocoModel
|
||||||
application.tracker.identify foreshadowsLevels: @foreshadowsLevels unless me.isAdmin()
|
application.tracker.identify foreshadowsLevels: @foreshadowsLevels unless me.isAdmin()
|
||||||
@foreshadowsLevels
|
@foreshadowsLevels
|
||||||
|
|
||||||
|
getLeaderboardsGroup: ->
|
||||||
|
return @leaderboardsGroup if @leaderboardsGroup?
|
||||||
|
group = me.get('testGroupNumber') % 64
|
||||||
|
if group < 16
|
||||||
|
@leaderboardsGroup = 'always'
|
||||||
|
else if group < 32
|
||||||
|
@leaderboardsGroup = 'early'
|
||||||
|
else if group < 48
|
||||||
|
@leaderboardsGroup = 'late'
|
||||||
|
else
|
||||||
|
@leaderboardsGroup = 'never'
|
||||||
|
@leaderboardsGroup = 'always' if me.isAdmin()
|
||||||
|
application.tracker.identify leaderboardsGroup: @leaderboardsGroup unless me.isAdmin()
|
||||||
|
@leaderboardsGroup
|
||||||
|
|
||||||
getVideoTutorialStylesIndex: (numVideos=0)->
|
getVideoTutorialStylesIndex: (numVideos=0)->
|
||||||
# A/B Testing video tutorial styles
|
# A/B Testing video tutorial styles
|
||||||
# Not a constant number of videos available (e.g. could be 0, 1, 3, or 4 currently)
|
# Not a constant number of videos available (e.g. could be 0, 1, 3, or 4 currently)
|
||||||
|
|
|
@ -320,6 +320,11 @@
|
||||||
margin: 0
|
margin: 0
|
||||||
float: left
|
float: left
|
||||||
|
|
||||||
|
.leaderboard-button
|
||||||
|
height: 60px
|
||||||
|
line-height: 30px
|
||||||
|
margin: 0 10px
|
||||||
|
float: left
|
||||||
|
|
||||||
.next-level-buttons
|
.next-level-buttons
|
||||||
float: right
|
float: right
|
||||||
|
|
93
app/styles/play/modal/leaderboard-modal.sass
Normal file
93
app/styles/play/modal/leaderboard-modal.sass
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
@import "app/styles/mixins"
|
||||||
|
|
||||||
|
#leaderboard-modal
|
||||||
|
|
||||||
|
//- Clear modal defaults
|
||||||
|
|
||||||
|
.modal-dialog
|
||||||
|
width: 820px
|
||||||
|
height: 570px
|
||||||
|
padding: 0
|
||||||
|
background: none
|
||||||
|
position: relative
|
||||||
|
top: 40px
|
||||||
|
|
||||||
|
|
||||||
|
//- Background
|
||||||
|
|
||||||
|
#leaderboard-background
|
||||||
|
position: absolute
|
||||||
|
top: -146px
|
||||||
|
left: -3px
|
||||||
|
|
||||||
|
|
||||||
|
//- Close modal button
|
||||||
|
|
||||||
|
#close-modal
|
||||||
|
position: absolute
|
||||||
|
left: 769px
|
||||||
|
top: -5px
|
||||||
|
width: 60px
|
||||||
|
height: 60px
|
||||||
|
color: white
|
||||||
|
text-align: center
|
||||||
|
font-size: 30px
|
||||||
|
padding-top: 17px
|
||||||
|
cursor: pointer
|
||||||
|
z-index: 2
|
||||||
|
@include rotate(-3deg)
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color: yellow
|
||||||
|
|
||||||
|
|
||||||
|
//- Nav bar
|
||||||
|
|
||||||
|
#leaderboard-nav
|
||||||
|
position: absolute
|
||||||
|
top: 53px
|
||||||
|
left: 42px
|
||||||
|
width: 178px
|
||||||
|
|
||||||
|
li
|
||||||
|
background: url(/images/pages/play/modal/menu-tab.png)
|
||||||
|
padding: 5px
|
||||||
|
margin: -5px 0
|
||||||
|
height: 80px
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
&.active
|
||||||
|
background: url(/images/pages/play/modal/menu-tab-selected.png)
|
||||||
|
width: 197px
|
||||||
|
|
||||||
|
a
|
||||||
|
font-size: 18px
|
||||||
|
line-height: 50px
|
||||||
|
background: none
|
||||||
|
color: rgb(195,153,124)
|
||||||
|
font-weight: bold
|
||||||
|
padding: 14px 20px
|
||||||
|
font-family: $headings-font-family
|
||||||
|
text-transform: uppercase
|
||||||
|
|
||||||
|
.glyphicon
|
||||||
|
margin-right: 6px
|
||||||
|
|
||||||
|
|
||||||
|
//- Tab panels
|
||||||
|
|
||||||
|
.leaderboard-tab-content
|
||||||
|
position: absolute
|
||||||
|
left: 219px
|
||||||
|
top: 21px
|
||||||
|
width: 571px
|
||||||
|
height: 514px
|
||||||
|
padding: 50px
|
||||||
|
overflow-y: scroll
|
||||||
|
|
||||||
|
::-webkit-scrollbar
|
||||||
|
// So that the scrollbar doesn't go on top of the close button.
|
||||||
|
// Wish we could easily do this for Firefox.
|
||||||
|
display: none
|
||||||
|
|
2
app/styles/play/modal/leaderboard-tab-view.sass
Normal file
2
app/styles/play/modal/leaderboard-tab-view.sass
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.leaderboard-tab-view
|
||||||
|
color: black
|
|
@ -68,6 +68,9 @@ block modal-footer-content
|
||||||
.sign-up-blurb(data-i18n="play_level.victory_sign_up_poke") Want to save your code? Create a free account!
|
.sign-up-blurb(data-i18n="play_level.victory_sign_up_poke") Want to save your code? Create a free account!
|
||||||
button.btn.btn-illustrated.btn-warning.sign-up-button.btn-lg(data-dismiss="modal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress
|
button.btn.btn-illustrated.btn-warning.sign-up-button.btn-lg(data-dismiss="modal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress
|
||||||
|
|
||||||
|
else if !showHourOfCodeDoneButton && showLeaderboard
|
||||||
|
button.btn.btn-illustrated.btn-warning.leaderboard-button.btn-lg(data-dismiss="modal", data-i18n="leaderboard.view_other_solutions") View Other Solutions
|
||||||
|
|
||||||
button.btn.btn-illustrated.btn-lg.btn-warning.hide#saving-progress-label(disabled, data-i18n="play_level.victory_saving_progress") Saving Progress
|
button.btn.btn-illustrated.btn-lg.btn-warning.hide#saving-progress-label(disabled, data-i18n="play_level.victory_saving_progress") Saving Progress
|
||||||
|
|
||||||
.next-level-buttons
|
.next-level-buttons
|
||||||
|
|
17
app/templates/play/modal/leaderboard-modal.jade
Normal file
17
app/templates/play/modal/leaderboard-modal.jade
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
.modal-dialog
|
||||||
|
.modal-content
|
||||||
|
img(src="/images/pages/play/modal/game-menu-background.png", draggable="false")#leaderboard-background
|
||||||
|
|
||||||
|
div#close-modal
|
||||||
|
span.glyphicon.glyphicon-remove
|
||||||
|
|
||||||
|
ul#leaderboard-nav.nav.nav-pills.nav-stacked
|
||||||
|
for submenu, index in submenus
|
||||||
|
li(class=submenu === showTab ? "active" : "")
|
||||||
|
a(href='#' + submenu + '-view', data-toggle='tab')
|
||||||
|
span(data-i18n='leaderboard.' + submenu + '_tab')
|
||||||
|
|
||||||
|
.tab-content.leaderboard-tab-content
|
||||||
|
for submenu, index in submenus
|
||||||
|
.tab-pane(id=submenu + '-view')
|
||||||
|
.leaderboard-tab-view
|
2
app/templates/play/modal/leaderboard-tab-view.jade
Normal file
2
app/templates/play/modal/leaderboard-tab-view.jade
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
div dis be da tab view for #{timespan}
|
||||||
|
span= Math.random()
|
|
@ -10,7 +10,7 @@ class SearchCollection extends Backbone.Collection
|
||||||
@url += 'created,permissions'
|
@url += 'created,permissions'
|
||||||
@url += ',' + projected for projected in projection
|
@url += ',' + projected for projected in projection
|
||||||
else @url += 'true'
|
else @url += 'true'
|
||||||
@url += "&term=#{term}" if @term
|
@url += "&term=#{@term}" if @term
|
||||||
|
|
||||||
comparator: (a, b) ->
|
comparator: (a, b) ->
|
||||||
score = 0
|
score = 0
|
||||||
|
|
|
@ -12,7 +12,7 @@ class VersionsViewCollection extends CocoCollection
|
||||||
|
|
||||||
initialize: (@url, @levelID, @model) ->
|
initialize: (@url, @levelID, @model) ->
|
||||||
super()
|
super()
|
||||||
@url = url + @levelID + '/versions'
|
@url = @url + @levelID + '/versions'
|
||||||
|
|
||||||
module.exports = class VersionsModal extends ModalView
|
module.exports = class VersionsModal extends ModalView
|
||||||
template: template
|
template: template
|
||||||
|
|
|
@ -11,6 +11,7 @@ MusicPlayer = require 'lib/surface/MusicPlayer'
|
||||||
storage = require 'core/storage'
|
storage = require 'core/storage'
|
||||||
AuthModal = require 'views/core/AuthModal'
|
AuthModal = require 'views/core/AuthModal'
|
||||||
SubscribeModal = require 'views/core/SubscribeModal'
|
SubscribeModal = require 'views/core/SubscribeModal'
|
||||||
|
LeaderboardModal = require 'views/play/modal/LeaderboardModal'
|
||||||
Level = require 'models/Level'
|
Level = require 'models/Level'
|
||||||
utils = require 'core/utils'
|
utils = require 'core/utils'
|
||||||
require 'vendor/three'
|
require 'vendor/three'
|
||||||
|
@ -205,6 +206,7 @@ module.exports = class CampaignView extends RootView
|
||||||
for nextLevelOriginal in level.nextLevels ? []
|
for nextLevelOriginal in level.nextLevels ? []
|
||||||
if nextLevel = _.find(@campaign.renderedLevels, original: nextLevelOriginal)
|
if nextLevel = _.find(@campaign.renderedLevels, original: nextLevelOriginal)
|
||||||
@createLine level.position, nextLevel.position
|
@createLine level.position, nextLevel.position
|
||||||
|
@showLeaderboard @options.justBeatLevel?.get('original') if (@options.showLeaderboard or true)
|
||||||
@applyCampaignStyles()
|
@applyCampaignStyles()
|
||||||
@testParticles()
|
@testParticles()
|
||||||
|
|
||||||
|
@ -217,6 +219,12 @@ module.exports = class CampaignView extends RootView
|
||||||
authModal.mode = 'signup'
|
authModal.mode = 'signup'
|
||||||
@openModalView authModal
|
@openModalView authModal
|
||||||
|
|
||||||
|
showLeaderboard: (levelOriginal) ->
|
||||||
|
#levelOriginal ?= '5411cb3769152f1707be029c' # Testing: show Dungeons of Kithgard
|
||||||
|
levelOriginal ?= '541c9a30c6362edfb0f34479' # Testing: show Kithgard Gates
|
||||||
|
leaderboardModal = new LeaderboardModal supermodel: @supermodel, levelOriginal: levelOriginal
|
||||||
|
@openModalView leaderboardModal
|
||||||
|
|
||||||
determineNextLevel: (levels) ->
|
determineNextLevel: (levels) ->
|
||||||
foundNext = false
|
foundNext = false
|
||||||
for level in levels
|
for level in levels
|
||||||
|
|
|
@ -23,6 +23,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click #continue-button': 'onClickContinue'
|
'click #continue-button': 'onClickContinue'
|
||||||
|
'click .leaderboard-button': 'onClickLeaderboard'
|
||||||
'click .return-to-ladder-button': 'onClickReturnToLadder'
|
'click .return-to-ladder-button': 'onClickReturnToLadder'
|
||||||
'click .sign-up-button': 'onClickSignupButton'
|
'click .sign-up-button': 'onClickSignupButton'
|
||||||
|
|
||||||
|
@ -145,6 +146,11 @@ module.exports = class HeroVictoryModal extends ModalView
|
||||||
# Show the "I'm done" button between 30 - 120 minutes if they definitely came from Hour of Code
|
# Show the "I'm done" button between 30 - 120 minutes if they definitely came from Hour of Code
|
||||||
c.showHourOfCodeDoneButton = me.get('hourOfCode') and showDone
|
c.showHourOfCodeDoneButton = me.get('hourOfCode') and showDone
|
||||||
|
|
||||||
|
lg = me.getLeaderboardsGroup()
|
||||||
|
c.showLeaderboard = lg is 'always'
|
||||||
|
c.showLeaderboard = true if me.level() >= 3 and lg.group is 'early'
|
||||||
|
c.showLeaderboard = true if me.level() >= 5 and lg.group is 'late'
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
|
@ -322,11 +328,18 @@ module.exports = class HeroVictoryModal extends ModalView
|
||||||
link += '/' + nextCampaign unless nextCampaign is 'dungeon'
|
link += '/' + nextCampaign unless nextCampaign is 'dungeon'
|
||||||
link
|
link
|
||||||
|
|
||||||
onClickContinue: (e) ->
|
onClickContinue: (e, extraOptions=null) ->
|
||||||
@playSound 'menu-button-click'
|
@playSound 'menu-button-click'
|
||||||
nextLevelLink = @getNextLevelLink()
|
nextLevelLink = @getNextLevelLink()
|
||||||
# Preserve the supermodel as we navigate back to the world map.
|
# Preserve the supermodel as we navigate back to the world map.
|
||||||
Backbone.Mediator.publish 'router:navigate', route: nextLevelLink, viewClass: require('views/play/CampaignView'), viewArgs: [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @getNextLevelCampaign()]
|
options =
|
||||||
|
justBeatLevel: @level
|
||||||
|
supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel
|
||||||
|
_.merge options, extraOptions if extraOptions
|
||||||
|
Backbone.Mediator.publish 'router:navigate', route: nextLevelLink, viewClass: require('views/play/CampaignView'), viewArgs: [options, @getNextLevelCampaign()]
|
||||||
|
|
||||||
|
onClickLeaderboard: (e) ->
|
||||||
|
@onClickContinue e, showLeaderboard: true
|
||||||
|
|
||||||
onClickReturnToLadder: (e) ->
|
onClickReturnToLadder: (e) ->
|
||||||
@playSound 'menu-button-click'
|
@playSound 'menu-button-click'
|
||||||
|
|
49
app/views/play/modal/LeaderboardModal.coffee
Normal file
49
app/views/play/modal/LeaderboardModal.coffee
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
ModalView = require 'views/core/ModalView'
|
||||||
|
template = require 'templates/play/modal/leaderboard-modal'
|
||||||
|
LeaderboardTabView = require 'views/play/modal/LeaderboardTabView'
|
||||||
|
|
||||||
|
module.exports = class LeaderboardModal extends ModalView
|
||||||
|
id: 'leaderboard-modal'
|
||||||
|
template: template
|
||||||
|
instant: true
|
||||||
|
timespans: ['day', 'week', 'all']
|
||||||
|
|
||||||
|
subscriptions: {}
|
||||||
|
|
||||||
|
events:
|
||||||
|
'shown.bs.tab #leaderboard-nav a': 'onTabShown'
|
||||||
|
'click #close-modal': 'hide'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
@levelOriginal = @options.levelOriginal
|
||||||
|
|
||||||
|
|
||||||
|
getRenderData: (c) ->
|
||||||
|
c = super c
|
||||||
|
c.submenus = @timespans
|
||||||
|
c.showTab = c.submenus[0]
|
||||||
|
c
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
for timespan, index in @timespans
|
||||||
|
submenuView = new LeaderboardTabView timespan: timespan, levelOriginal: @levelOriginal
|
||||||
|
@insertSubView submenuView, @$el.find "##{timespan}-view .leaderboard-tab-view"
|
||||||
|
if index is 0
|
||||||
|
submenuView.$el.parent().addClass 'active'
|
||||||
|
submenuView.onShown?()
|
||||||
|
@playSound 'game-menu-open'
|
||||||
|
@$el.find('.nano:visible').nanoScroller()
|
||||||
|
|
||||||
|
onTabShown: (e) ->
|
||||||
|
@playSound 'game-menu-tab-switch'
|
||||||
|
timespan = e.target.hash.substring(1).replace(/-view/g, '')
|
||||||
|
subview = _.find @subviews, timespan: timespan
|
||||||
|
subview.onShown?()
|
||||||
|
otherSubview.onHidden?() for subviewKey, otherSubview of @subviews when otherSubview isnt subview
|
||||||
|
|
||||||
|
onHidden: ->
|
||||||
|
super()
|
||||||
|
subview.onHidden?() for subviewKey, subview of @subviews
|
||||||
|
@playSound 'game-menu-close'
|
27
app/views/play/modal/LeaderboardTabView.coffee
Normal file
27
app/views/play/modal/LeaderboardTabView.coffee
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
CocoView = require 'views/core/CocoView'
|
||||||
|
template = require 'templates/play/modal/leaderboard-tab-view'
|
||||||
|
|
||||||
|
module.exports = class LeaderboardTabView extends CocoView
|
||||||
|
template: template
|
||||||
|
className: 'leaderboard-tab-view'
|
||||||
|
helpVideoHeight: '295'
|
||||||
|
helpVideoWidth: '471'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .start-subscription-button': "clickSubscribe"
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
@timespan = @options.timespan
|
||||||
|
@levelOriginal = @options.levelOriginal
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
super()
|
||||||
|
|
||||||
|
getRenderData: ->
|
||||||
|
c = super()
|
||||||
|
c.timespan = @timespan
|
||||||
|
c
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
Loading…
Add table
Add a link
Reference in a new issue