From 8c013c1192791db6aae3755b6d9a2fe91b4836ed Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Mon, 31 Mar 2014 15:48:22 -0700 Subject: [PATCH] Fixed 101: added level completion status to /play. --- app/styles/play.sass | 10 +++++++- app/templates/play.jade | 2 +- app/views/play_view.coffee | 24 ++++++++++++++++++- server/commons/Handler.coffee | 3 +-- .../sessions/level_session_handler.coffee | 7 +++++- server/users/user_handler.coffee | 15 ++++++++++++ 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/app/styles/play.sass b/app/styles/play.sass index 83611f8b8..e3e31d8fa 100644 --- a/app/styles/play.sass +++ b/app/styles/play.sass @@ -15,6 +15,14 @@ a[disabled] .level opacity: 0.7 + a.complete h3:after + content: " - Complete!" + color: green + + a.started h3:after + content: " - Started" + color: desaturate(green, 50%) + .level @include box-sizing(border-box) border: 1px solid transparent @@ -40,4 +48,4 @@ .alert-warning h2 color: black - text-align: center \ No newline at end of file + text-align: center diff --git a/app/templates/play.jade b/app/templates/play.jade index 6f3a77edd..911f14c92 100644 --- a/app/templates/play.jade +++ b/app/templates/play.jade @@ -22,7 +22,7 @@ block content a(href="/play/#{campaign.levels[0].levelPath || 'level'}/#{campaign.levels[0].id}", data-i18n="play.campaign_#{campaign.id}")= campaign.name p.campaign-description(data-i18n="[html]play.campaign_#{campaign.id}_description")!= campaign.description each level in campaign.levels - a(href=level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled) + a(href=level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled, class=levelStatusMap[level.id] || '') .level.row if level.image img.level-image(src="#{level.image}", alt="#{level.name}") diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index 6a92978e3..349f900c7 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -1,10 +1,32 @@ View = require 'views/kinds/RootView' template = require 'templates/play' +LevelSession = require 'models/LevelSession' +CocoCollection = require 'models/CocoCollection' + +class LevelSessionsCollection extends CocoCollection + url: '' + model: LevelSession + + constructor: (model) -> + super() + @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID" module.exports = class PlayView extends View id: "play-view" template: template + constructor: (options) -> + super options + @levelStatusMap = {} + @sessions = new LevelSessionsCollection() + @sessions.fetch() + @listenToOnce @sessions, 'sync', @onSessionsLoaded + + onSessionsLoaded: (e) -> + for session in @sessions.models + @levelStatusMap[session.get('levelID')] = if session.get('state')?.complete then 'complete' else 'started' + @render() + getRenderData: (context={}) -> context = super(context) context.home = true @@ -198,7 +220,7 @@ module.exports = class PlayView extends View {id: "dev", name: "Random Harder Levels", description: "... in which you learn the interface while doing something a little harder.", levels: experienced} {id: "player_created", name: "Player-Created", description: "... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>.", levels: playerCreated} ] - + context.levelStatusMap = @levelStatusMap context afterRender: -> diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 0787ca9d2..1f40ce397 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -112,8 +112,7 @@ module.exports = class Handler log.warn "Whoa, we haven't yet thought about public properties for User projection yet." else projection = {} - for field in req.query.project.split(',') - projection[field] = 1 + projection[field] = 1 for field in req.query.project.split(',') for filter in filters callback = (err, results) => return @sendDatabaseError(res, err) if err diff --git a/server/levels/sessions/level_session_handler.coffee b/server/levels/sessions/level_session_handler.coffee index d3ab07830..ca8680a17 100644 --- a/server/levels/sessions/level_session_handler.coffee +++ b/server/levels/sessions/level_session_handler.coffee @@ -1,5 +1,6 @@ LevelSession = require('./LevelSession') Handler = require('../../commons/Handler') +log = require 'winston' TIMEOUT = 1000 * 30 # no activity for 30 seconds means it's not active @@ -10,7 +11,11 @@ class LevelSessionHandler extends Handler 'chat', 'teamSpells', 'submitted', 'unsubscribed'] getByRelationship: (req, res, args...) -> - return @sendNotFoundError(res) unless args.length is 2 and args[1] is 'active' + return @getActiveSessions req, res if args.length is 2 and args[1] is 'active' + return @sendNotFoundError(res) + + getActiveSessions: (req, res) -> + return @sendUnauthorizedError(res) unless req.user.isAdmin() start = new Date() start = new Date(start.getTime() - TIMEOUT) query = @modelClass.find({'changed': {$gt: start}}) diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 4abfb65e3..168f10d91 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -8,6 +8,7 @@ config = require '../../server_config' errors = require '../commons/errors' async = require 'async' log = require 'winston' +LevelSession = require('../levels/sessions/LevelSession') serverProperties = ['passwordHash', 'emailLower', 'nameLower', 'passwordReset'] privateProperties = [ @@ -169,6 +170,7 @@ UserHandler = class UserHandler extends Handler return @avatar(req, res, args[0]) if args[1] is 'avatar' return @getNamesByIds(req, res) if args[1] is 'names' return @nameToID(req, res, args[0]) if args[1] is 'nameToID' + return @getLevelSessions(req, res, args[0]) if args[1] is 'level.sessions' return @sendNotFoundError(res) agreeToCLA: (req, res) -> @@ -194,4 +196,17 @@ UserHandler = class UserHandler extends Handler res.redirect(document?.get('photoURL') or '/images/generic-wizard-icon.png') res.end() + getLevelSessions: (req, res, userID) -> + return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() + query = {'creator': userID} + projection = null + if req.query.project + projection = {} + projection[field] = 1 for field in req.query.project.split(',') + LevelSession.find(query).select(projection).exec (err, documents) => + return @sendDatabaseError(res, err) if err + documents = (@formatEntity(req, doc) for doc in documents) + @sendSuccess(res, documents) + + module.exports = new UserHandler()