More ladder page support for leagues. Linking to clan league pages from clans pages.

This commit is contained in:
Nick Winter 2015-08-19 15:30:37 -07:00
parent 6f2b1b2a41
commit f4d796a717
11 changed files with 118 additions and 72 deletions

View file

@ -820,6 +820,7 @@
latest_achievement: "Latest Achievement"
playtime: "Playtime"
last_played: "Last played"
leagues_explanation: "Play in a league against other clan members in these multiplayer arena instances."
classes:
archmage_title: "Archmage"
@ -1009,6 +1010,7 @@
my_matches: "My Matches"
simulate: "Simulate"
simulation_explanation: "By simulating games you can get your game ranked faster!"
simulation_explanation_leagues: "You will mainly help simulate games for allied players in your clans and courses."
simulate_games: "Simulate Games!"
simulate_all: "RESET AND SIMULATE GAMES"
games_simulated_by: "Games simulated by you:"
@ -1059,6 +1061,7 @@
tournament_blurb_blog: "on our blog"
rules: "Rules"
winners: "Winners"
league: "League"
user:
stats: "Stats"

View file

@ -26,52 +26,62 @@ block content
button.btn(data-dismiss='modal', data-i18n="modal.close") Close
button.btn.edit-description-save-btn(data-i18n="common.save_changes") Save changes
if clan
h1 #{clan.get('name')}
if clan.get('type') === 'private'
small(data-i18n="clans.private") (private)
if clan.get('ownerID') === me.id
span.spl
button.btn.btn-xs.edit-name-btn(data-toggle='modal', data-target='#editNameModal', data-i18n="clans.edit_name") edit name
.row
.col-lg-6
if clan
h1 #{clan.get('name')}
if clan.get('type') === 'private'
small(data-i18n="clans.private") (private)
if clan.get('ownerID') === me.id
span.spl
button.btn.btn-xs.edit-name-btn(data-toggle='modal', data-target='#editNameModal', data-i18n="clans.edit_name") edit name
if clan.get('description')
.clan-description
each line in clan.get('description').split('\n')
p= line
if clan.get('ownerID') === me.id
button.btn.btn-xs.edit-description-btn(data-toggle='modal', data-target='#editDescriptionModal', data-i18n="clans.edit_description") edit description
if clan.get('description')
.clan-description
each line in clan.get('description').split('\n')
p= line
if clan.get('ownerID') === me.id
button.btn.btn-xs.edit-description-btn(data-toggle='modal', data-target='#editDescriptionModal', data-i18n="clans.edit_description") edit description
h5(data-i18n="clans.summary") Summary
table.table.table-condensed.stats-table
if owner
tr
td
span.spr(data-i18n="clans.chieftain") Chieftain
td
span.spr.player-hero-icon(data-memberid="#{clan.get('ownerID')}")
a(href="/user/#{clan.get('ownerID')}")= owner.get('name')
if stats.averageLevel
tr
td(data-i18n="clans.average_level") Average Level
td= stats.averageLevel
if stats.averageAchievements && clan.get('type') === 'public'
tr
td(data-i18n="clans.average_achievements") Average Achievements
td= stats.averageAchievements
h5(data-i18n="clans.summary") Summary
table.table.table-condensed.stats-table
if owner
tr
td
span.spr(data-i18n="clans.chieftain") Chieftain
td
span.spr.player-hero-icon(data-memberid="#{clan.get('ownerID')}")
a(href="/user/#{clan.get('ownerID')}")= owner.get('name')
if stats.averageLevel
tr
td(data-i18n="clans.average_level") Average Level
td= stats.averageLevel
if stats.averageAchievements && clan.get('type') === 'public'
tr
td(data-i18n="clans.average_achievements") Average Achievements
td= stats.averageAchievements
p
if isOwner
button.btn.btn-xs.btn-warning.delete-clan-btn(data-i18n="clans.delete_clan") Delete Clan
else if isMember
button.btn.btn-xs.btn-warning.leave-clan-btn(data-i18n="clans.leave_clan") Leave Clan
else
button.btn.btn-lg.btn-success.join-clan-btn(data-i18n="clans.join_clan") Join Clan
p
if isOwner
button.btn.btn-xs.btn-warning.delete-clan-btn(data-i18n="clans.delete_clan") Delete Clan
else if isMember
button.btn.btn-xs.btn-warning.leave-clan-btn(data-i18n="clans.leave_clan") Leave Clan
else
button.btn.btn-lg.btn-success.join-clan-btn(data-i18n="clans.join_clan") Join Clan
if clan.get('ownerID') === me.id || clan.get('type') === 'public'
div
span.spl.spr.join-link-prompt(data-i18n="clans.invite_1") Invite:
input.join-clan-link(type="text", readonly, value="#{joinClanLink}")
.small(data-i18n="clans.invite_2") *Invite players to this Clan by sending them this link.
if clan.get('ownerID') === me.id || clan.get('type') === 'public'
div
span.spl.spr.join-link-prompt(data-i18n="clans.invite_1") Invite:
input.join-clan-link(type="text", readonly, value="#{joinClanLink}")
.small(data-i18n="clans.invite_2") *Invite players to this Clan by sending them this link.
if arenas && arenas.length
.col-lg-6
h2(data-i18n="play.campaign_multiplayer")
p(data-i18n="clans.leagues_explanation")
for arena in arenas
h3
a(href="/play/ladder/#{arena.slug}/clan/#{clan.id}")= i18n(arena, 'name')
if members
h3

View file

@ -23,12 +23,13 @@ div#columns.row
- if(!showJustTop && topSessions.length == 20) topSessions = topSessions.slice(0, 10);
for session, rank in topSessions
- var myRow = session.get('creator') == me.id
- var sessionStats = league ? (_.find(session.get('leagues') || [], {leagueID: league.id}) || {}).stats || {} : session.attributes;
tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)" title=capitalize(session.get('submittedCodeLanguage')))
if level.get('type', true) == 'hero-ladder'
td.hero-portrait-cell(style="background-image: url(/file/db/thang.type/#{(session.get('heroConfig') || {}).thangType || '529ffbf1cf1818f2be000001'}/portrait.png)")
td.rank-cell= rank + 1
td.score-cell= Math.round(session.get('totalScore') * 100)
td.score-cell= Math.round(sessionStats.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}")
@ -41,12 +42,13 @@ div#columns.row
td(colspan=4).ellipsis-row ...
for session in team.leaderboard.nearbySessions()
- var myRow = session.get('creator') == me.id
- var sessionStats = league ? (_.find(session.get('leagues'), {leagueID: league.id}) || {}).stats || {} : session.attributes;
tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)")
if level.get('type', true) == 'hero-ladder'
td.hero-portrait-cell(style="background-image: url(/file/db/thang.type/#{(session.get('heroConfig') || {}).thangType || '529ffbf1cf1818f2be000001'}/portrait.png)")
td.rank-cell= session.rank
td.score-cell= Math.round(session.get('totalScore') * 100)
td.score-cell= Math.round(sessionStats.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}")

View file

@ -11,7 +11,9 @@ block content
h1= level.get('name')
if league
h1 #{league.get('name')} League
h1
a(href="/#{leagueType == 'clan' ? 'clans' : leagueType}/#{league.id}")= league.get('name')
span.spl(data-i18n="ladder.league") League
if level.get('name') == 'Greed'
.tournament-blurb

View file

@ -3,6 +3,7 @@ p(id="simulation-status-text")
| #{simulationStatus}
else
span(data-i18n="ladder.simulation_explanation") By simulating games you can get your game ranked faster!
span.spl(data-i18n="ladder.simulation_explanation_leagues") You will mainly help simulate games for allied players in your clans and courses.
p
button(data-i18n="ladder.simulate_games").btn.btn-warning.btn-lg.highlight#simulate-button Simulate Games!

View file

@ -10,6 +10,7 @@ LevelSession = require 'models/LevelSession'
SubscribeModal = require 'views/core/SubscribeModal'
ThangType = require 'models/ThangType'
User = require 'models/User'
utils = require 'core/utils'
# TODO: Add message for clan not found
# TODO: Progress visual for premium levels?
@ -60,7 +61,7 @@ module.exports = class ClanDetailsView extends RootView
@listenTo @memberAchievements, 'sync', @onMemberAchievementsSync
@listenTo @memberSessions, 'sync', @onMemberSessionsSync
@supermodel.loadModel @campaigns, 'clan', cache: false
@supermodel.loadModel @campaigns, 'campaigns', cache: false
@supermodel.loadModel @clan, 'clan', cache: false
@supermodel.loadCollection(@members, 'members', {cache: false})
@supermodel.loadCollection(@memberAchievements, 'member_achievements', {cache: false})
@ -120,6 +121,8 @@ module.exports = class ClanDetailsView extends RootView
context.lastUserCampaignLevelMap = lastUserCampaignLevelMap
context.showExpandedProgress = maxLastUserCampaignLevel <= 30 or @showExpandedProgress
context.userConceptsMap = userConceptsMap
context.arenas = @arenas
context.i18n = utils.i18n
context
afterRender: ->
@ -179,21 +182,24 @@ module.exports = class ClanDetailsView extends RootView
return unless @campaigns.loaded
@campaignLevelProgressions = []
@conceptsProgression = []
@arenas = []
for campaign in @campaigns.models
continue if campaign.get('slug') is 'auditions'
campaignLevelProgression =
ID: campaign.id
slug: campaign.get('slug')
name: campaign.get('fullName') or campaign.get('name')
name: utils.i18n(campaign.attributes, 'fullName') or utils.i18n(campaign.attributes, 'name')
levels: []
for levelID, level of campaign.get('levels')
campaignLevelProgression.levels.push
ID: levelID
slug: level.slug
name: level.name
name: utils.i18n level, 'name'
if level.concepts?
for concept in level.concepts
@conceptsProgression.push concept unless concept in @conceptsProgression
if level.type == 'hero-ladder'
@arenas.push level
@campaignLevelProgressions.push campaignLevelProgression
@render?()

View file

@ -43,11 +43,14 @@ module.exports = class LadderPlayModal extends ModalView
# PART 1: Load challengers from the db unless some are in the matches
startLoadingChallengersMaybe: ->
matches = @session?.get('matches')
if @options.league
matches = _.find(@session?.get('leagues'), leagueID: @options.league.id)?.stats.matches
else
matches = @session?.get('matches')
if matches?.length then @loadNames() else @loadChallengers()
loadChallengers: ->
@challengersCollection = new ChallengersData(@level, @team, @otherTeam, @session)
@challengersCollection = new ChallengersData(@level, @team, @otherTeam, @session, @options.league)
@listenTo(@challengersCollection, 'sync', @loadNames)
# PART 2: Loading the names of the other users
@ -156,7 +159,10 @@ module.exports = class LadderPlayModal extends ModalView
mediumInfo = @challengeInfoFromSession(@challengersCollection.mediumPlayer.models[0])
hardInfo = @challengeInfoFromSession(@challengersCollection.hardPlayer.models[0])
else
matches = @session.get('matches')
if @options.league
matches = _.find(@session?.get('leagues'), leagueID: @options.league.id)?.stats.matches
else
matches = @session?.get('matches')
won = (m for m in matches when m.metrics.rank < m.opponents[0].metrics.rank)
lost = (m for m in matches when m.metrics.rank > m.opponents[0].metrics.rank)
tied = (m for m in matches when m.metrics.rank is m.opponents[0].metrics.rank)
@ -195,18 +201,26 @@ module.exports = class LadderPlayModal extends ModalView
}
class ChallengersData
constructor: (@level, @team, @otherTeam, @session) ->
constructor: (@level, @team, @otherTeam, @session, @league) ->
_.extend @, Backbone.Events
score = @session?.get('totalScore') or 25
@easyPlayer = new LeaderboardCollection(@level, {order: 1, scoreOffset: score - 5, limit: 1, team: @otherTeam})
@easyPlayer.fetch cache: false
@listenToOnce(@easyPlayer, 'sync', @challengerLoaded)
@mediumPlayer = new LeaderboardCollection(@level, {order: 1, scoreOffset: score, limit: 1, team: @otherTeam})
@mediumPlayer.fetch cache: false
@listenToOnce(@mediumPlayer, 'sync', @challengerLoaded)
@hardPlayer = new LeaderboardCollection(@level, {order: -1, scoreOffset: score + 5, limit: 1, team: @otherTeam})
@hardPlayer.fetch cache: false
@listenToOnce(@hardPlayer, 'sync', @challengerLoaded)
if @league
score = _.find(@session?.get('leagues'), leagueID: @league.id)?.stats?.totalScore or 10
else
score = @session?.get('totalScore') or 10
for player in [
{type: 'easyPlayer', order: 1, scoreOffset: score - 5}
{type: 'mediumPlayer', order: 1, scoreOffset: score}
{type: 'hardPlayer', order: -1, scoreOffset: score + 5}
]
playerResource = @[player.type] = new LeaderboardCollection(@level, @collectionParameters(order: player.order, scoreOffset: player.scoreOffset))
playerResource.fetch cache: false
@listenToOnce playerResource, 'sync', @challengerLoaded
collectionParameters: (parameters) ->
parameters.team = @otherTeam
parameters.limit = 1
parameters['leagues.leagueID'] = @league.id if @league
parameters
challengerLoaded: ->
if @allLoaded()

View file

@ -183,6 +183,8 @@ module.exports = class LadderTabView extends CocoView
ctx.onFacebook = @facebookStatus is 'connected'
ctx.onGPlus = application.gplusHandler.loggedIn
ctx.capitalize = _.string.capitalize
ctx.league = @options.league
ctx._ = _
ctx
generateHistogram: (histogramElement, histogramData, teamName) ->
@ -229,8 +231,11 @@ module.exports = class LadderTabView extends CocoView
.attr('x', 1)
.attr('width', width/20)
.attr('height', (d) -> height - y(d.y))
if @leaderboards[teamName].session?
playerScore = @leaderboards[teamName].session.get('totalScore') * 100
if session = @leaderboards[teamName].session
if @options.league
playerScore = (_.find(session.get('leagues'), {leagueID: @options.league.id})?.stats.totalScore or 10) * 100
else
playerScore = session.get('totalScore') * 100
scorebar = svg.selectAll('.specialbar')
.data([playerScore])
.enter().append('g')
@ -319,14 +324,17 @@ module.exports.LeaderboardData = LeaderboardData = class LeaderboardData extends
promises.push @topPlayers.fetch cache: false
if @session
score = @session.get('totalScore') or 10
if @league
score = _.find(@session.get('leagues'), {leagueID: @league.id})?.stats.totalScore or 10
else
score = @session.get('totalScore') or 10
@playersAbove = new LeaderboardCollection(@level, @collectionParameters(order: 1, scoreOffset: score, limit: 4))
promises.push @playersAbove.fetch cache: false
@playersBelow = new LeaderboardCollection(@level, @collectionParameters(order: -1, scoreOffset: score, limit: 4))
promises.push @playersBelow.fetch cache: false
level = "#{@level.get('original')}.#{@level.get('version').major}"
success = (@myRank) =>
loadURL = "/db/level/#{level}/leaderboard_rank?scoreOffset=#{@session.get('totalScore')}&team=#{@team}"
loadURL = "/db/level/#{level}/leaderboard_rank?scoreOffset=#{score}&team=#{@team}"
loadURL += '&leagues.leagueID=' + @league.id if @league
promises.push $.ajax(loadURL, cache: false, success: success)
@promise = $.when(promises...)

View file

@ -113,7 +113,7 @@ module.exports = class LadderView extends RootView
showPlayModal: (teamID) ->
session = (s for s in @sessions.models when s.get('team') is teamID)[0]
modal = new LadderPlayModal({}, @level, session, teamID)
modal = new LadderPlayModal({league: @league}, @level, session, teamID)
@openModalView modal
onClickedLink: (e) ->

View file

@ -129,7 +129,7 @@ module.exports = class MyMatchesTabView extends CocoView
statsFromSession: (session) ->
return null unless session
if @options.league
return _.find(session.get('leagues') or [], leagueID: @options.league.id)?.stats
return _.find(session.get('leagues') or [], leagueID: @options.league.id)?.stats ? {}
session.attributes
generateScoreLineChart: (wrapperID, scoreHistory, teamName) =>

View file

@ -200,7 +200,7 @@ LevelHandler = class LevelHandler extends Handler
sortParameters =
'totalScore': req.query.order
selectProperties = ['totalScore', 'creatorName', 'creator', 'submittedCodeLanguage', 'heroConfig', 'leagues.leagueID']
selectProperties = ['totalScore', 'creatorName', 'creator', 'submittedCodeLanguage', 'heroConfig', 'leagues.leagueID', 'leagues.stats.totalScore']
query = Session
.find(sessionsQueryParameters)