mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 19:06:59 -05:00
Merge branch 'master' of https://github.com/codecombat/codecombat
This commit is contained in:
commit
476d153717
16 changed files with 141 additions and 36 deletions
|
@ -5,7 +5,7 @@ module.exports.load = (key) ->
|
|||
value = JSON.parse(s)
|
||||
return value
|
||||
catch SyntaxError
|
||||
console.warning('error loading from storage', key)
|
||||
console.warn('error loading from storage', key)
|
||||
return null
|
||||
|
||||
module.exports.save = (key, value) ->
|
||||
|
|
|
@ -668,3 +668,4 @@
|
|||
user_schema: "User Schema"
|
||||
user_profile: "User Profile"
|
||||
patches: "Patches"
|
||||
model: "Model"
|
||||
|
|
|
@ -175,29 +175,29 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t
|
|||
edit_settings: "Beállítások szerkesztése"
|
||||
# profile_for_prefix: "Profile for "
|
||||
# profile_for_suffix: ""
|
||||
# approved: "Approved"
|
||||
# not_approved: "Not Approved"
|
||||
# looking_for: "Looking for:"
|
||||
# last_updated: "Last updated:"
|
||||
# contact: "Contact"
|
||||
# work_experience: "Work Experience"
|
||||
# education: "Education"
|
||||
approved: "Jóváhagyva"
|
||||
not_approved: "Nincs jóváhagyva"
|
||||
looking_for: "Keres:"
|
||||
last_updated: "Legutóbb napra-készre hozva:"
|
||||
contact: "Kapcsolat"
|
||||
work_experience: "Munkatapasztalat"
|
||||
education: "Végzettség"
|
||||
# our_notes: "Our Notes"
|
||||
# projects: "Projects"
|
||||
projects: "Projektek"
|
||||
|
||||
# employers:
|
||||
# want_to_hire_our_players: "Want to hire expert CodeCombat players?"
|
||||
# contact_george: "Contact George to see our candidates"
|
||||
# candidates_count_prefix: "We currently have "
|
||||
# candidates_count_many: "many"
|
||||
# candidates_count_suffix: "highly skilled and vetted developers looking for work."
|
||||
# candidate_name: "Name"
|
||||
munkaadók:
|
||||
want_to_hire_our_players: "Akarsz szakértő CodeCombat játékosokat alkalmazni?"
|
||||
contact_george: "Vedd fel a kapcsolatot George-dzsal, hogy megtekinthesd jelöltjeinket"
|
||||
candidates_count_prefix: "Pillanatnyilag van"
|
||||
candidates_count_many: "sok"
|
||||
candidates_count_suffix: "magasan képzett és ellenőrzött fejlesztő, aki munkát keres."
|
||||
candidate_name: "Név"
|
||||
# candidate_location: "Location"
|
||||
# candidate_looking_for: "Looking For"
|
||||
# candidate_role: "Role"
|
||||
candidate_looking_for: "Keres"
|
||||
candidate_role: "Szerep"
|
||||
# candidate_top_skills: "Top Skills"
|
||||
# candidate_years_experience: "Yrs Exp"
|
||||
# candidate_last_updated: "Last Updated"
|
||||
candidate_last_updated: "Legutóbb napra-készre hozva"
|
||||
|
||||
play_level:
|
||||
level_load_error: "A pályát nem sikerült betölteni: "
|
||||
|
|
|
@ -8,7 +8,8 @@ module.exports = class Level extends CocoModel
|
|||
urlRoot: "/db/level"
|
||||
|
||||
serialize: (supermodel) ->
|
||||
o = _.cloneDeep @attributes # slow in level editor when there are hundreds of Thangs
|
||||
# o = _.cloneDeep @attributes # slow in level editor when there are hundreds of Thangs
|
||||
o = $.extend true, {}, @attributes
|
||||
|
||||
# Figure out Components
|
||||
o.levelComponents = _.cloneDeep (lc.attributes for lc in supermodel.getModels LevelComponent)
|
||||
|
|
|
@ -101,9 +101,13 @@ _.extend LevelSessionSchema.properties,
|
|||
source:
|
||||
type: 'string'
|
||||
|
||||
# TODO: specify this more
|
||||
code:
|
||||
type: 'object'
|
||||
additionalProperties:
|
||||
type: 'object'
|
||||
additionalProperties:
|
||||
type: 'string'
|
||||
format: 'javascript'
|
||||
|
||||
teamSpells:
|
||||
type: 'object'
|
||||
|
@ -134,6 +138,11 @@ _.extend LevelSessionSchema.properties,
|
|||
|
||||
submittedCode:
|
||||
type: 'object'
|
||||
additionalProperties:
|
||||
type: 'object'
|
||||
additionalProperties:
|
||||
type: 'string'
|
||||
format: 'javascript'
|
||||
|
||||
isRanking:
|
||||
type: 'boolean'
|
||||
|
|
9
app/styles/modal/model.sass
Normal file
9
app/styles/modal/model.sass
Normal file
|
@ -0,0 +1,9 @@
|
|||
#model-modal
|
||||
.treema-root
|
||||
background-color: white
|
||||
|
||||
.modal-dialog
|
||||
width: 1000px
|
||||
|
||||
.treema-ace .ace_editor
|
||||
height: 600px
|
|
@ -5,6 +5,9 @@
|
|||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
.histogram-display
|
||||
height: 130px
|
||||
|
||||
.bar rect
|
||||
fill: steelblue
|
||||
shape-rendering: crispEdges
|
||||
|
@ -40,3 +43,7 @@
|
|||
.ogres-rank-text
|
||||
fill: #3f44bf
|
||||
|
||||
.load-more-ladder-entries
|
||||
position: absolute
|
||||
right: 15px
|
||||
bottom: -5px
|
||||
|
|
9
app/templates/modal/model.jade
Normal file
9
app/templates/modal/model.jade
Normal file
|
@ -0,0 +1,9 @@
|
|||
extends /templates/modal/modal_base
|
||||
|
||||
block modal-header
|
||||
|
||||
block modal-body-content
|
||||
for model in models
|
||||
h3= model.type() + ': ' + model.id
|
||||
.model-treema(data-model-id=model.id)
|
||||
hr
|
|
@ -1,5 +1,5 @@
|
|||
div#columns.row
|
||||
for team in teams
|
||||
for team, teamIndex in teams
|
||||
div.column.col-md-4
|
||||
div(id="histogram-display-#{team.name}", class="histogram-display",data-team-name=team.name)
|
||||
table.table.table-bordered.table-condensed.table-hover
|
||||
|
@ -17,10 +17,10 @@ div#columns.row
|
|||
|
||||
- var topSessions = team.leaderboard.topPlayers.models;
|
||||
- var showJustTop = team.leaderboard.inTopSessions() || me.get('anonymous');
|
||||
- if(!showJustTop) topSessions = topSessions.slice(0, 10);
|
||||
- if(!showJustTop && topSessions.length == 20) topSessions = topSessions.slice(0, 10);
|
||||
for session, rank in topSessions
|
||||
- var myRow = session.get('creator') == me.id
|
||||
tr(class=myRow ? "success" : "")
|
||||
tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
|
||||
td.rank-cell= rank + 1
|
||||
td.score-cell= Math.round(session.get('totalScore') * 100)
|
||||
td.name-col-cell= session.get('creatorName') || "Anonymous"
|
||||
|
@ -33,13 +33,15 @@ div#columns.row
|
|||
td(colspan=4).ellipsis-row ...
|
||||
for session in team.leaderboard.nearbySessions()
|
||||
- var myRow = session.get('creator') == me.id
|
||||
tr(class=myRow ? "success" : "")
|
||||
tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
|
||||
td.rank-cell= session.rank
|
||||
td.score-cell= Math.round(session.get('totalScore') * 100)
|
||||
td.name-col-cell= session.get('creatorName') || "Anonymous"
|
||||
td.fight-cell
|
||||
a(href="/play/level/#{level.get('slug') || level.id}/?team=#{team.otherTeam}&opponent=#{session.id}")
|
||||
span(data-i18n="ladder.fight") Fight!
|
||||
if teamIndex == 1
|
||||
.btn.btn-sm.load-more-ladder-entries moar
|
||||
|
||||
div.column.col-md-4
|
||||
h4.friends-header Friends Playing
|
||||
|
|
|
@ -78,7 +78,7 @@ module.exports = class SettingsView extends View
|
|||
buildPictureTreema: ->
|
||||
data = photoURL: me.get('photoURL')
|
||||
data.photoURL = null if data.photoURL?.search('gravatar') isnt -1 # Old style
|
||||
schema = _.cloneDeep me.schema()
|
||||
schema = $.extend true, {}, me.schema()
|
||||
schema.properties = _.pick me.schema().properties, 'photoURL'
|
||||
schema.required = ['photoURL']
|
||||
treemaOptions =
|
||||
|
@ -93,7 +93,6 @@ module.exports = class SettingsView extends View
|
|||
@$el.find('.gravatar-fallback').toggle not me.get 'photoURL'
|
||||
|
||||
onPictureChanged: (e) =>
|
||||
console.log "on Picture TChoinagaegd"
|
||||
@trigger 'change'
|
||||
@$el.find('.gravatar-fallback').toggle not me.get 'photoURL'
|
||||
|
||||
|
|
|
@ -113,15 +113,18 @@ class CocoView extends Backbone.View
|
|||
@listenToOnce modelOrCollection, 'sync', @updateProgress
|
||||
@listenTo modelOrCollection, 'error', @onResourceLoadFailed
|
||||
@updateProgress()
|
||||
@loaded = false
|
||||
|
||||
addRequestToLoad: (jqxhr, name, retryFunc, value=1) ->
|
||||
@loadProgress.requests.push {request:jqxhr, value:value, name: name, retryFunc: retryFunc}
|
||||
jqxhr.done @updateProgress
|
||||
jqxhr.fail @onRequestLoadFailed
|
||||
@loaded = false
|
||||
|
||||
addSomethingToLoad: (name, value=1) ->
|
||||
@loadProgress.somethings.push {loaded: false, name: name, value: value}
|
||||
@updateProgress()
|
||||
@loaded = false
|
||||
|
||||
somethingLoaded: (name) ->
|
||||
r = _.find @loadProgress.somethings, {name: name}
|
||||
|
@ -145,9 +148,9 @@ class CocoView extends Backbone.View
|
|||
console.debug 'Loaded', r.name if arguments[0] and r = _.find @loadProgress.somethings, {name:arguments[0]}
|
||||
|
||||
denom = 0
|
||||
denom += r.value for r in @loadProgress.resources
|
||||
denom += r.value for r in @loadProgress.resources when not r.resource.destroyed
|
||||
denom += r.value for r in @loadProgress.requests
|
||||
denom += r.value for r in @loadProgress.somethings
|
||||
denom += r.value for r in @loadProgress.somethings when not r.destroyed
|
||||
num = @loadProgress.num
|
||||
num += r.value for r in @loadProgress.resources when r.resource.loaded
|
||||
num += r.value for r in @loadProgress.requests when r.request.status
|
||||
|
|
47
app/views/modal/model_modal.coffee
Normal file
47
app/views/modal/model_modal.coffee
Normal file
|
@ -0,0 +1,47 @@
|
|||
View = require 'views/kinds/ModalView'
|
||||
template = require 'templates/modal/model'
|
||||
|
||||
module.exports = class ModelModal extends View
|
||||
id: 'model-modal'
|
||||
template: template
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@models = options.models
|
||||
for model in @models when not model.loaded
|
||||
@addResourceToLoad model, 'model'
|
||||
model.fetch()
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
c.models = @models
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
return if @loading()
|
||||
for model in @models
|
||||
data = $.extend true, {}, model.attributes
|
||||
schema = $.extend true, {}, model.schema()
|
||||
treemaOptions =
|
||||
schema: schema
|
||||
data: data
|
||||
readOnly: true
|
||||
modelTreema = @$el.find(".model-treema[data-model-id='#{model.id}']").treema treemaOptions
|
||||
modelTreema?.build()
|
||||
modelTreema?.open()
|
||||
@openTastyTreemas modelTreema, model
|
||||
|
||||
openTastyTreemas: (modelTreema, model) ->
|
||||
# To save on quick inspection, let's auto-open the properties we're most likely to want to see.
|
||||
delicacies = ['code']
|
||||
for dish in delicacies
|
||||
child = modelTreema.childrenTreemas[dish]
|
||||
child?.open()
|
||||
if child and dish is 'code' and model.type() is 'LevelSession' and team = modelTreema.get('team')
|
||||
desserts = {
|
||||
humans: ['programmable-tharin', 'programmable-librarian']
|
||||
ogres: ['programmable-brawler', 'programmable-shaman']
|
||||
}[team]
|
||||
for dessert in desserts
|
||||
child.childrenTreemas[dessert]?.open()
|
|
@ -18,7 +18,6 @@ module.exports = class SaveVersionModal extends ModalView
|
|||
constructor: (options) ->
|
||||
super options
|
||||
@model = options.model or options.level
|
||||
new Patch() # hack to get the schema to load, delete this later
|
||||
@isPatch = not @model.hasWriteAccess()
|
||||
|
||||
getRenderData: ->
|
||||
|
|
|
@ -3,8 +3,10 @@ CocoClass = require 'lib/CocoClass'
|
|||
Level = require 'models/Level'
|
||||
LevelSession = require 'models/LevelSession'
|
||||
CocoCollection = require 'models/CocoCollection'
|
||||
User = require 'models/User'
|
||||
LeaderboardCollection = require 'collections/LeaderboardCollection'
|
||||
{teamDataFromLevel} = require './utils'
|
||||
ModelModal = require 'views/modal/model_modal'
|
||||
|
||||
HIGHEST_SCORE = 1000000
|
||||
|
||||
|
@ -23,6 +25,8 @@ module.exports = class LadderTabView extends CocoView
|
|||
events:
|
||||
'click .connect-facebook': 'onConnectFacebook'
|
||||
'click .connect-google-plus': 'onConnectGPlus'
|
||||
'click .name-col-cell': 'onClickPlayerName'
|
||||
'click .load-more-ladder-entries': 'onLoadMoreLadderEntries'
|
||||
|
||||
subscriptions:
|
||||
'fbapi-loaded': 'checkFriends'
|
||||
|
@ -134,7 +138,8 @@ module.exports = class LadderTabView extends CocoView
|
|||
for team in @teams
|
||||
@leaderboards[team.id]?.destroy()
|
||||
teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
|
||||
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession)
|
||||
@ladderLimit ?= parseInt @getQueryVariable('top_players', 20)
|
||||
@leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession, @ladderLimit)
|
||||
|
||||
@addResourceToLoad @leaderboards[team.id], 'leaderboard', 3
|
||||
|
||||
|
@ -245,17 +250,30 @@ module.exports = class LadderTabView extends CocoView
|
|||
sessions.reverse()
|
||||
sessions
|
||||
|
||||
# Admin view of players' code
|
||||
onClickPlayerName: (e) ->
|
||||
return unless me.isAdmin()
|
||||
row = $(e.target).parent()
|
||||
player = new User _id: row.data 'player-id'
|
||||
session = new LevelSession _id: row.data 'session-id'
|
||||
@openModalView new ModelModal models: [session, player]
|
||||
|
||||
onLoadMoreLadderEntries: (e) ->
|
||||
@ladderLimit ?= 100
|
||||
@ladderLimit += 100
|
||||
@refreshLadder()
|
||||
|
||||
class LeaderboardData extends CocoClass
|
||||
###
|
||||
Consolidates what you need to load for a leaderboard into a single Backbone Model-like object.
|
||||
###
|
||||
|
||||
constructor: (@level, @team, @session) ->
|
||||
constructor: (@level, @team, @session, @limit) ->
|
||||
super()
|
||||
@fetch()
|
||||
|
||||
fetch: ->
|
||||
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: 20})
|
||||
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: @limit})
|
||||
promises = []
|
||||
promises.push @topPlayers.fetch()
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ module.exports = class LadderView extends RootView
|
|||
return if @loading()
|
||||
@insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions))
|
||||
@insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions))
|
||||
@refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 10 * 1000)
|
||||
@refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 20 * 1000)
|
||||
hash = document.location.hash[1..] if document.location.hash
|
||||
if hash and not (hash in ['my-matches', 'simulate', 'ladder'])
|
||||
@showPlayModal(hash) if @sessions.loaded
|
||||
|
|
|
@ -17,6 +17,7 @@ module.exports = class LevelLoadingView extends View
|
|||
@$el.find('.to-remove').remove()
|
||||
|
||||
onLevelLoaderProgressChanged: (e) ->
|
||||
return if @destroyed
|
||||
@progress = e.progress
|
||||
@progress = 0.01 if @progress < 0.01
|
||||
@updateProgressBar()
|
||||
|
|
Loading…
Reference in a new issue