mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-29 10:35:51 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
27c70d0a98
10 changed files with 155 additions and 28 deletions
|
@ -231,9 +231,8 @@ module.exports = class Simulator extends CocoClass
|
||||||
createAether: (methodName, method) ->
|
createAether: (methodName, method) ->
|
||||||
aetherOptions =
|
aetherOptions =
|
||||||
functionName: methodName
|
functionName: methodName
|
||||||
protectAPI: false
|
protectAPI: true
|
||||||
includeFlow: false
|
includeFlow: false
|
||||||
#includeFlow: true
|
|
||||||
requiresThis: true
|
requiresThis: true
|
||||||
yieldConditionally: false
|
yieldConditionally: false
|
||||||
problems:
|
problems:
|
||||||
|
|
|
@ -286,10 +286,19 @@ module.exports.thangNames = thangNames =
|
||||||
]
|
]
|
||||||
"Potion Master": [
|
"Potion Master": [
|
||||||
"Snake"
|
"Snake"
|
||||||
|
"Amaranth"
|
||||||
|
"Zander"
|
||||||
|
"Arora"
|
||||||
]
|
]
|
||||||
"Librarian": [
|
"Librarian": [
|
||||||
"Hushbaum"
|
"Hushbaum"
|
||||||
|
"Matilda"
|
||||||
|
"Agnes"
|
||||||
|
"Agathe"
|
||||||
]
|
]
|
||||||
"Equestrian": [
|
"Equestrian": [
|
||||||
"Reynaldo"
|
"Reynaldo"
|
||||||
|
"Ryder"
|
||||||
|
"Thoron"
|
||||||
|
"Mirial"
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,6 +29,34 @@
|
||||||
.ellipsis-row
|
.ellipsis-row
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
|
// friend column
|
||||||
|
|
||||||
|
.friends-header
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 5px
|
||||||
|
|
||||||
|
.connect-buttons
|
||||||
|
margin-bottom: 10px
|
||||||
|
.btn
|
||||||
|
margin-left: 5px
|
||||||
|
|
||||||
|
.friend-entry img
|
||||||
|
float: left
|
||||||
|
margin-right: 10px
|
||||||
|
|
||||||
|
.friend-entry
|
||||||
|
margin-bottom: 15px
|
||||||
|
|
||||||
|
.connect-facebook
|
||||||
|
background-color: #4c66a4 !important
|
||||||
|
background-image: none
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.connect-google-plus
|
||||||
|
background-color: #CC3234 !important
|
||||||
|
background-image: none
|
||||||
|
color: white
|
||||||
|
|
||||||
td
|
td
|
||||||
padding: 1px 2px
|
padding: 1px 2px
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
div#columns.row
|
div#columns.row
|
||||||
for team in teams
|
for team in teams
|
||||||
div.column.col-md-6
|
div.column.col-md-4
|
||||||
table.table.table-bordered.table-condensed.table-hover
|
table.table.table-bordered.table-condensed.table-hover
|
||||||
tr
|
tr
|
||||||
th
|
th
|
||||||
|
@ -15,8 +15,8 @@ div#columns.row
|
||||||
th
|
th
|
||||||
|
|
||||||
- var topSessions = team.leaderboard.topPlayers.models;
|
- var topSessions = team.leaderboard.topPlayers.models;
|
||||||
- var inTheTop = team.leaderboard.inTopSessions();
|
- var showJustTop = team.leaderboard.inTopSessions() || me.get('anonymous');
|
||||||
- if(!inTheTop) topSessions = topSessions.slice(0, 10);
|
- if(!showJustTop) topSessions = topSessions.slice(0, 10);
|
||||||
for session, rank in topSessions
|
for session, rank in topSessions
|
||||||
- var myRow = session.get('creator') == me.id
|
- var myRow = session.get('creator') == me.id
|
||||||
tr(class=myRow ? "success" : "")
|
tr(class=myRow ? "success" : "")
|
||||||
|
@ -27,7 +27,7 @@ div#columns.row
|
||||||
a(href="/play/level/#{level.get('slug') || level.id}/?team=#{team.otherTeam}&opponent=#{session.id}")
|
a(href="/play/level/#{level.get('slug') || level.id}/?team=#{team.otherTeam}&opponent=#{session.id}")
|
||||||
span(data-i18n="ladder.fight") Fight!
|
span(data-i18n="ladder.fight") Fight!
|
||||||
|
|
||||||
if !inTheTop && team.leaderboard.nearbySessions().length
|
if !showJustTop && team.leaderboard.nearbySessions().length
|
||||||
tr(class="active")
|
tr(class="active")
|
||||||
td(colspan=4).ellipsis-row ...
|
td(colspan=4).ellipsis-row ...
|
||||||
for session in team.leaderboard.nearbySessions()
|
for session in team.leaderboard.nearbySessions()
|
||||||
|
@ -38,4 +38,40 @@ div#columns.row
|
||||||
td.name-col-cell= session.get('creatorName') || "Anonymous"
|
td.name-col-cell= session.get('creatorName') || "Anonymous"
|
||||||
td.fight-cell
|
td.fight-cell
|
||||||
a(href="/play/level/#{level.get('slug') || level.id}/?team=#{team.otherTeam}&opponent=#{session.id}")
|
a(href="/play/level/#{level.get('slug') || level.id}/?team=#{team.otherTeam}&opponent=#{session.id}")
|
||||||
span(data-i18n="ladder.fight") Fight!
|
span(data-i18n="ladder.fight") Fight!
|
||||||
|
|
||||||
|
div.column.col-md-4
|
||||||
|
h4.friends-header Friends Playing
|
||||||
|
if me.get('anonymous')
|
||||||
|
div.alert.alert-info
|
||||||
|
a(data-toggle="coco-modal", data-target="modal/signup") Sign up to play with your friends!
|
||||||
|
|
||||||
|
else
|
||||||
|
if !onFacebook
|
||||||
|
div.connect-buttons
|
||||||
|
| Connect:
|
||||||
|
if !onFacebook
|
||||||
|
button.btn.btn-sm.connect-facebook Facebook
|
||||||
|
//button.btn.btn-sm.connect-google-plus Google+
|
||||||
|
|
||||||
|
if !!friends
|
||||||
|
|
||||||
|
if friends.length
|
||||||
|
for friend in friends
|
||||||
|
p.friend-entry
|
||||||
|
img(src="http://graph.facebook.com/#{friend.facebookID}/picture").img-thumbnail
|
||||||
|
span= friend.creatorName + ' (' + friend.facebookName + ')'
|
||||||
|
br
|
||||||
|
span= Math.round(friend.totalScore * 100)
|
||||||
|
span :
|
||||||
|
span= friend.team
|
||||||
|
br
|
||||||
|
a(href="/play/level/#{level.get('slug') || level.id}/?team=#{friend.otherTeam}&opponent=#{friend._id}")
|
||||||
|
span(data-i18n="ladder.fight") Fight!
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
p Invite your friends to join you in battle!
|
||||||
|
|
||||||
|
else
|
||||||
|
p Connect to social networks to play with your friends!
|
||||||
|
|
|
@ -8,7 +8,7 @@ Simulator = require 'lib/simulator/Simulator'
|
||||||
module.exports = class HomeView extends View
|
module.exports = class HomeView extends View
|
||||||
id: 'home-view'
|
id: 'home-view'
|
||||||
template: template
|
template: template
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super(arguments...)
|
super(arguments...)
|
||||||
ThangType.loadUniversalWizard()
|
ThangType.loadUniversalWizard()
|
||||||
|
@ -31,14 +31,12 @@ module.exports = class HomeView extends View
|
||||||
$('input:visible:first', @).focus()
|
$('input:visible:first', @).focus()
|
||||||
|
|
||||||
# Try to find latest level and set "Play" link to go to that level
|
# Try to find latest level and set "Play" link to go to that level
|
||||||
if localStorage?
|
lastLevel = me.get("lastLevel")
|
||||||
lastLevel = localStorage["lastLevel"]
|
lastLevel ?= localStorage?["lastLevel"] # Temp, until it's migrated to user property
|
||||||
if lastLevel? and lastLevel isnt ""
|
if lastLevel
|
||||||
playLink = @$el.find("#beginner-campaign")
|
playLink = @$el.find("#beginner-campaign")
|
||||||
if playLink[0]?
|
if playLink[0]?
|
||||||
href = playLink.attr("href").split("/")
|
href = playLink.attr("href").split("/")
|
||||||
href[href.length-1] = lastLevel if href.length isnt 0
|
href[href.length-1] = lastLevel if href.length isnt 0
|
||||||
href = href.join("/")
|
href = href.join("/")
|
||||||
playLink.attr("href", href)
|
playLink.attr("href", href)
|
||||||
else
|
|
||||||
console.log("TODO: Insert here code to get latest level played from the database. If this can't be found, we just let the user play the first level.")
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ module.exports = class ThangTypeHomeView extends View
|
||||||
hash = document.location.hash[1..]
|
hash = document.location.hash[1..]
|
||||||
searchInput = @$el.find('#search')
|
searchInput = @$el.find('#search')
|
||||||
searchInput.val(hash) if hash?
|
searchInput.val(hash) if hash?
|
||||||
|
delete @collection?.term
|
||||||
searchInput.trigger('change')
|
searchInput.trigger('change')
|
||||||
searchInput.focus()
|
searchInput.focus()
|
||||||
|
|
||||||
|
|
|
@ -19,25 +19,75 @@ module.exports = class LadderTabView extends CocoView
|
||||||
id: 'ladder-tab-view'
|
id: 'ladder-tab-view'
|
||||||
template: require 'templates/play/ladder/ladder_tab'
|
template: require 'templates/play/ladder/ladder_tab'
|
||||||
startsLoading: true
|
startsLoading: true
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .connect-facebook': 'onConnectFacebook'
|
||||||
|
|
||||||
|
subscriptions:
|
||||||
|
'facebook-logged-in': 'onConnectedWithFacebook'
|
||||||
|
|
||||||
constructor: (options, @level, @sessions) ->
|
constructor: (options, @level, @sessions) ->
|
||||||
super(options)
|
super(options)
|
||||||
@teams = teamDataFromLevel @level
|
@teams = teamDataFromLevel @level
|
||||||
@leaderboards = {}
|
@leaderboards = {}
|
||||||
@refreshLadder()
|
@refreshLadder()
|
||||||
|
@checkFriends()
|
||||||
|
|
||||||
|
onConnectFacebook: ->
|
||||||
|
@connecting = true
|
||||||
|
FB.login()
|
||||||
|
|
||||||
|
onConnectedWithFacebook: ->
|
||||||
|
location.reload() if @connecting
|
||||||
|
|
||||||
|
checkFriends: ->
|
||||||
|
@loadingFriends = true
|
||||||
|
FB.getLoginStatus (response) =>
|
||||||
|
@facebookStatus = response.status
|
||||||
|
if @facebookStatus is 'connected'
|
||||||
|
@loadFriendSessions()
|
||||||
|
else
|
||||||
|
@loadingFriends = false
|
||||||
|
@renderMaybe()
|
||||||
|
|
||||||
|
loadFriendSessions: ->
|
||||||
|
FB.api '/me/friends', (response) =>
|
||||||
|
@facebookData = response.data
|
||||||
|
console.log 'got facebookData', @facebookData
|
||||||
|
levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
|
||||||
|
url = "/db/level/#{levelFrag}/leaderboard_friends"
|
||||||
|
$.ajax url, {
|
||||||
|
data: { friendIDs: (f.id for f in @facebookData) }
|
||||||
|
method: 'POST'
|
||||||
|
success: @facebookFriendsLoaded
|
||||||
|
}
|
||||||
|
|
||||||
|
facebookFriendsLoaded: (result) =>
|
||||||
|
friendsMap = {}
|
||||||
|
friendsMap[friend.id] = friend.name for friend in @facebookData
|
||||||
|
for friend in result
|
||||||
|
friend.facebookName = friendsMap[friend.facebookID]
|
||||||
|
friend.otherTeam = if friend.team is 'humans' then 'ogres' else 'humans'
|
||||||
|
@friends = result
|
||||||
|
@loadingFriends = false
|
||||||
|
@renderMaybe()
|
||||||
|
|
||||||
refreshLadder: ->
|
refreshLadder: ->
|
||||||
|
promises = []
|
||||||
for team in @teams
|
for team in @teams
|
||||||
@leaderboards[team.id]?.off 'sync'
|
@leaderboards[team.id]?.off 'sync'
|
||||||
teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
|
teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
|
||||||
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession)
|
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession)
|
||||||
@leaderboards[team.id].once 'sync', @onLeaderboardLoaded, @
|
promises.push @leaderboards[team.id].promise
|
||||||
|
@loadingLeaderboards = true
|
||||||
onLeaderboardLoaded: -> @renderMaybe()
|
$.when(promises...).then(@leaderboardsLoaded)
|
||||||
|
|
||||||
|
leaderboardsLoaded: =>
|
||||||
|
@loadingLeaderboards = false
|
||||||
|
@renderMaybe()
|
||||||
|
|
||||||
renderMaybe: ->
|
renderMaybe: ->
|
||||||
leaderboardModels = _.values(@leaderboards)
|
return if @loadingFriends or @loadingLeaderboards
|
||||||
return unless _.every leaderboardModels, (loader) -> loader.loaded
|
|
||||||
@startsLoading = false
|
@startsLoading = false
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
@ -48,6 +98,8 @@ module.exports = class LadderTabView extends CocoView
|
||||||
ctx.teams = @teams
|
ctx.teams = @teams
|
||||||
team.leaderboard = @leaderboards[team.id] for team in @teams
|
team.leaderboard = @leaderboards[team.id] for team in @teams
|
||||||
ctx.levelID = @levelID
|
ctx.levelID = @levelID
|
||||||
|
ctx.friends = @friends
|
||||||
|
ctx.onFacebook = @facebookStatus is 'connected'
|
||||||
ctx
|
ctx
|
||||||
|
|
||||||
class LeaderboardData
|
class LeaderboardData
|
||||||
|
@ -69,8 +121,9 @@ class LeaderboardData
|
||||||
level = "#{level.get('original')}.#{level.get('version').major}"
|
level = "#{level.get('original')}.#{level.get('version').major}"
|
||||||
success = (@myRank) =>
|
success = (@myRank) =>
|
||||||
promises.push $.ajax "/db/level/#{level}/leaderboard_rank?scoreOffset=#{@session.get('totalScore')}&team=#{@team}", {success}
|
promises.push $.ajax "/db/level/#{level}/leaderboard_rank?scoreOffset=#{@session.get('totalScore')}&team=#{@team}", {success}
|
||||||
|
@promise = $.when(promises...)
|
||||||
$.when(promises...).then @onLoad
|
@promise.then @onLoad
|
||||||
|
@promise
|
||||||
|
|
||||||
onLoad: =>
|
onLoad: =>
|
||||||
@loaded = true
|
@loaded = true
|
||||||
|
|
|
@ -154,7 +154,9 @@ module.exports = class PlayLevelView extends View
|
||||||
return Backbone.Mediator.subscribeOnce 'modal-closed', @onLevelLoaderLoaded, @
|
return Backbone.Mediator.subscribeOnce 'modal-closed', @onLevelLoaderLoaded, @
|
||||||
|
|
||||||
# Save latest level played in local storage
|
# Save latest level played in local storage
|
||||||
localStorage["lastLevel"] = @levelID if localStorage? and not (@levelLoader.level.get('type') in ['ladder', 'ladder-tutorial'])
|
if not (@levelLoader.level.get('type') in ['ladder', 'ladder-tutorial'])
|
||||||
|
me.set('lastLevel', @levelID)
|
||||||
|
me.save()
|
||||||
@grabLevelLoaderData()
|
@grabLevelLoaderData()
|
||||||
team = @getQueryVariable("team") ? @world.teamForPlayer(0)
|
team = @getQueryVariable("team") ? @world.teamForPlayer(0)
|
||||||
@loadOpponentTeam(team)
|
@loadOpponentTeam(team)
|
||||||
|
|
|
@ -18,7 +18,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
'name', 'photoURL', 'password', 'anonymous', 'wizardColor1', 'volume',
|
'name', 'photoURL', 'password', 'anonymous', 'wizardColor1', 'volume',
|
||||||
'firstName', 'lastName', 'gender', 'facebookID', 'emailSubscriptions',
|
'firstName', 'lastName', 'gender', 'facebookID', 'emailSubscriptions',
|
||||||
'testGroupNumber', 'music', 'hourOfCode', 'hourOfCodeComplete', 'preferredLanguage',
|
'testGroupNumber', 'music', 'hourOfCode', 'hourOfCodeComplete', 'preferredLanguage',
|
||||||
'wizard', 'aceConfig', 'simulatedBy', 'simulatedFor', 'autocastDelay'
|
'wizard', 'aceConfig', 'autocastDelay', 'lastLevel'
|
||||||
]
|
]
|
||||||
|
|
||||||
jsonSchema: schema
|
jsonSchema: schema
|
||||||
|
|
|
@ -18,6 +18,7 @@ UserSchema = c.object {},
|
||||||
volume: c.pct({title: 'Volume'})
|
volume: c.pct({title: 'Volume'})
|
||||||
music: {type: 'boolean', default: true}
|
music: {type: 'boolean', default: true}
|
||||||
autocastDelay: {type: 'integer', 'default': 5000 }
|
autocastDelay: {type: 'integer', 'default': 5000 }
|
||||||
|
lastLevel: { type: 'string' }
|
||||||
|
|
||||||
emailSubscriptions: c.array {uniqueItems: true, 'default': ['announcement', 'notification']}, {'enum': emailSubscriptions}
|
emailSubscriptions: c.array {uniqueItems: true, 'default': ['announcement', 'notification']}, {'enum': emailSubscriptions}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue