mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-04 17:19:47 -04:00
Set up a basic achievements list modal for the world map.
This commit is contained in:
parent
fe018309d0
commit
13de055c0b
8 changed files with 215 additions and 21 deletions
app
models
styles/play/modal
templates/play
views/play/modal
server
|
@ -50,6 +50,8 @@ class CocoModel extends Backbone.Model
|
|||
@loading = false
|
||||
@jqxhr = null
|
||||
@loadFromBackup()
|
||||
|
||||
getCreationDate: -> new Date(parseInt(@id.slice(0,8), 16)*1000)
|
||||
|
||||
getNormalizedURL: -> "#{@urlRoot}/#{@id}"
|
||||
|
||||
|
|
|
@ -1,4 +1,82 @@
|
|||
#play-achievements-modal
|
||||
.achievement-view
|
||||
color: black
|
||||
|
||||
.modal-header
|
||||
padding-bottom: 20px
|
||||
|
||||
img.icon
|
||||
float: left
|
||||
width: 40px
|
||||
margin-right: 10px
|
||||
|
||||
|
||||
//- Unachieved Panels
|
||||
|
||||
.panel
|
||||
margin: 5px 0
|
||||
position: relative
|
||||
border: 2px solid rgb(75,75,75)
|
||||
padding: 2px
|
||||
|
||||
h3
|
||||
margin: 0 0 0 50px
|
||||
color: rgb(75,75,75)
|
||||
|
||||
p
|
||||
margin: 0 0 0 50px
|
||||
color: rgb(75,75,75)
|
||||
|
||||
.panel-body
|
||||
padding: 5px 150px 5px 5px
|
||||
border: 2px solid rgb(150,150,150)
|
||||
|
||||
.created
|
||||
position: absolute
|
||||
right: 10px
|
||||
top: 5px
|
||||
color: rgb(75,75,75)
|
||||
font-size: 12px
|
||||
|
||||
|
||||
//- Achieved Panels
|
||||
|
||||
.panel.earned
|
||||
background: rgb(50,40,33)
|
||||
border: 5px solid rgb(26,21,17)
|
||||
padding: 0
|
||||
|
||||
h3
|
||||
color: white
|
||||
|
||||
p
|
||||
color: rgb(203,170,148)
|
||||
|
||||
.panel-body
|
||||
border: 2px solid rgb(75,62,51)
|
||||
|
||||
.created
|
||||
color: rgb(255,189,68)
|
||||
|
||||
|
||||
//- Rewards
|
||||
|
||||
.rewards
|
||||
position: absolute
|
||||
right: .2em
|
||||
//bottom: 10px
|
||||
top: 29px
|
||||
|
||||
.label
|
||||
font-size: 18px
|
||||
margin-left: 5px
|
||||
color: rgb(50,40,33)
|
||||
background: rgb(203,170,148)
|
||||
|
||||
.gems
|
||||
background: #94ccc7
|
||||
|
||||
.worth
|
||||
background: #d8c488
|
||||
|
||||
img
|
||||
width: 12px
|
||||
height: 12px
|
|
@ -4,4 +4,29 @@ block modal-header-content
|
|||
h3(data-i18n="play.achievements") Achievements
|
||||
|
||||
block modal-body-content
|
||||
p TODO: show all dem achievements
|
||||
for achievement in achievements
|
||||
.panel(class=achievement.earned ? 'earned' : '')
|
||||
.panel-body
|
||||
img.icon(src=achievement.getImageURL())
|
||||
h3= achievement.name
|
||||
p= achievement.description
|
||||
|
||||
if achievement.earnedDate
|
||||
.created=moment(achievement.earnedDate).fromNow()
|
||||
else
|
||||
.created(data-i18n="user.status_unfinished")
|
||||
|
||||
.rewards
|
||||
- rewards = achievement.get('rewards')
|
||||
- rewards = { gems: 100 }
|
||||
if rewards && rewards.gems
|
||||
span.gems.label.label-default
|
||||
span= rewards.gems
|
||||
img.gem(src="/images/common/gem.png")
|
||||
|
||||
- worth = achievement.get('worth')
|
||||
if worth
|
||||
span.worth.label.label-default
|
||||
span #{worth}xp
|
||||
// maybe add more icons/numbers for items, heroes, levels, xp?
|
||||
block modal-footer
|
|
@ -43,10 +43,10 @@
|
|||
.game-controls.header-font
|
||||
button.btn.items(data-toggle='coco-modal', data-target='play/modal/PlayItemsModal', data-i18n="[title]play.items")
|
||||
button.btn.heroes(data-toggle='coco-modal', data-target='play/modal/PlayHeroesModal', data-i18n="[title]play.heroes")
|
||||
button.btn.achievements(data-toggle='coco-modal', data-target='play/modal/PlayAchievementsModal', data-i18n="[title]play.achievements")
|
||||
if me.get('anonymous') === false
|
||||
button.btn.gems(data-toggle='coco-modal', data-target='play/modal/BuyGemsModal', data-i18n="[title]play.buy_gems")
|
||||
if me.isAdmin()
|
||||
button.btn.achievements(data-toggle='coco-modal', data-target='play/modal/PlayAchievementsModal', data-i18n="[title]play.achievements")
|
||||
button.btn.account(data-toggle='coco-modal', data-target='play/modal/PlayAccountModal', data-i18n="[title]play.account")
|
||||
button.btn.settings(data-toggle='coco-modal', data-target='play/modal/PlaySettingsModal', data-i18n="[title]play.settings")
|
||||
else if me.get('anonymous', true)
|
||||
|
|
|
@ -2,27 +2,92 @@ ModalView = require 'views/kinds/ModalView'
|
|||
template = require 'templates/play/modal/play-achievements-modal'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
Achievement = require 'models/Achievement'
|
||||
#AchievementView = require 'views/game-menu/AchievementView'
|
||||
EarnedAchievement = require 'models/EarnedAchievement'
|
||||
|
||||
utils = require 'lib/utils'
|
||||
|
||||
PAGE_SIZE = 200
|
||||
|
||||
module.exports = class PlayAchievementsModal extends ModalView
|
||||
className: 'modal fade play-modal'
|
||||
template: template
|
||||
modalWidthPercent: 90
|
||||
id: 'play-achievements-modal'
|
||||
#instant: true
|
||||
|
||||
#events:
|
||||
# 'change input.select': 'onSelectionChanged'
|
||||
plain: true
|
||||
|
||||
earnedMap: {}
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
#@achievements = new CocoCollection([], {model: Achievement})
|
||||
#@achievements.url = '/db/thang.type?view=achievements&project=name,description,components,original,rasterIcon'
|
||||
#@supermodel.loadCollection(@achievements, 'achievements')
|
||||
@achievements = new Backbone.Collection()
|
||||
earnedMap = {}
|
||||
|
||||
achievementsFetcher = new CocoCollection([], {url: '/db/achievement', model: Achievement})
|
||||
achievementsFetcher.setProjection([
|
||||
'name'
|
||||
'description'
|
||||
'icon'
|
||||
'worth'
|
||||
'i18n'
|
||||
'rewards'
|
||||
'collection'
|
||||
])
|
||||
|
||||
earnedAchievementsFetcher = new CocoCollection([], {url: '/db/earned_achievement', model: EarnedAchievement})
|
||||
earnedAchievementsFetcher.setProjection([ 'achievement' ])
|
||||
|
||||
achievementsFetcher.skip = 0
|
||||
achievementsFetcher.fetch({data: {skip: 0, limit: PAGE_SIZE}})
|
||||
earnedAchievementsFetcher.skip = 0
|
||||
earnedAchievementsFetcher.fetch({data: {skip: 0, limit: PAGE_SIZE}})
|
||||
|
||||
@listenTo achievementsFetcher, 'sync', @onAchievementsLoaded
|
||||
@listenTo earnedAchievementsFetcher, 'sync', @onEarnedAchievementsLoaded
|
||||
|
||||
@supermodel.loadCollection(achievementsFetcher, 'achievement')
|
||||
@supermodel.loadCollection(earnedAchievementsFetcher, 'achievement')
|
||||
|
||||
@onEverythingLoaded = _.after(2, @onEverythingLoaded)
|
||||
|
||||
onAchievementsLoaded: (fetcher) ->
|
||||
needMore = fetcher.models.length is PAGE_SIZE
|
||||
@achievements.add(fetcher.models)
|
||||
if needMore
|
||||
fetcher.skip += PAGE_SIZE
|
||||
fetcher.fetch({data: {skip: fetcher.skip, limit: PAGE_SIZE}})
|
||||
else
|
||||
@stopListening(fetcher)
|
||||
@onEverythingLoaded()
|
||||
|
||||
onEarnedAchievementsLoaded: (fetcher) ->
|
||||
needMore = fetcher.models.length is PAGE_SIZE
|
||||
for earned in fetcher.models
|
||||
@earnedMap[earned.get('achievement')] = earned
|
||||
if needMore
|
||||
fetcher.skip += PAGE_SIZE
|
||||
fetcher.fetch({data: {skip: fetcher.skip, limit: PAGE_SIZE}})
|
||||
else
|
||||
@stopListening(fetcher)
|
||||
@onEverythingLoaded()
|
||||
|
||||
onEverythingLoaded: =>
|
||||
@achievements.set(@achievements.filter((m) -> m.get('collection') isnt 'level.sessions'))
|
||||
for achievement in @achievements.models
|
||||
if earned = @earnedMap[achievement.id]
|
||||
achievement.earned = earned
|
||||
achievement.earnedDate = earned.getCreationDate()
|
||||
achievement.earnedDate ?= ''
|
||||
@achievements.comparator = (m) -> m.earnedDate
|
||||
@achievements.sort()
|
||||
@achievements.set(@achievements.models.reverse())
|
||||
for achievement in @achievements.models
|
||||
achievement.name = utils.i18n achievement.attributes, 'name'
|
||||
achievement.description = utils.i18n achievement.attributes, 'description'
|
||||
@render()
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
context = super(context)
|
||||
#context.achievements = @achievements.models
|
||||
context.achievements = @achievements.models
|
||||
context
|
||||
|
||||
afterRender: ->
|
||||
|
|
|
@ -2,12 +2,6 @@ mongoose = require 'mongoose'
|
|||
jsonschema = require '../../app/schemas/models/earned_achievement'
|
||||
|
||||
EarnedAchievementSchema = new mongoose.Schema({
|
||||
created:
|
||||
type: Date
|
||||
default: Date.now
|
||||
changed:
|
||||
type: Date
|
||||
default: Date.now
|
||||
notified:
|
||||
type: Boolean
|
||||
default: false
|
||||
|
|
|
@ -16,7 +16,26 @@ class EarnedAchievementHandler extends Handler
|
|||
|
||||
get: (req, res) ->
|
||||
return @getByAchievementIDs(req, res) if req.query.view is 'get-by-achievement-ids'
|
||||
super(arguments...)
|
||||
query = { user: req.user._id+''}
|
||||
|
||||
projection = {}
|
||||
if req.query.project
|
||||
projection[field] = 1 for field in req.query.project.split(',')
|
||||
|
||||
q = EarnedAchievement.find(query, projection)
|
||||
|
||||
skip = parseInt(req.query.skip)
|
||||
if skip? and skip < 1000000
|
||||
q.skip(skip)
|
||||
|
||||
limit = parseInt(req.query.limit)
|
||||
if limit? and limit < 1000
|
||||
q.limit(limit)
|
||||
|
||||
q.exec (err, documents) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
documents = (@formatEntity(req, doc) for doc in documents)
|
||||
@sendSuccess(res, documents)
|
||||
|
||||
getByAchievementIDs: (req, res) ->
|
||||
query = { user: req.user._id+''}
|
||||
|
|
|
@ -129,6 +129,10 @@ module.exports = class Handler
|
|||
term = req.query.term
|
||||
matchedObjects = []
|
||||
filters = if @modelClass.schema.uses_coco_versions or @modelClass.schema.uses_coco_permissions then [filter: {index: true}] else [filter: {}]
|
||||
|
||||
skip = parseInt(req.query.skip)
|
||||
limit = parseInt(req.query.limit)
|
||||
|
||||
if @modelClass.schema.uses_coco_permissions and req.user
|
||||
filters.push {filter: {index: req.user.get('id')}}
|
||||
projection = null
|
||||
|
@ -158,7 +162,14 @@ module.exports = class Handler
|
|||
else
|
||||
args = [filter.filter]
|
||||
args.push projection if projection
|
||||
@modelClass.find(args...).limit(FETCH_LIMIT).exec callback
|
||||
q = @modelClass.find(args...)
|
||||
if skip? and skip < 1000000
|
||||
q.skip(skip)
|
||||
if limit? and limit < FETCH_LIMIT
|
||||
q.limit(limit)
|
||||
else
|
||||
q.limit(FETCH_LIMIT)
|
||||
q.exec callback
|
||||
# if it's not a text search but the user is an admin, let him try stuff anyway
|
||||
else if req.user?.isAdmin()
|
||||
# admins can send any sort of query down the wire
|
||||
|
|
Loading…
Add table
Reference in a new issue