diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 390cf1b76e..e967118e06 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -84,6 +84,26 @@ function updateUserProgress(user, challengeId, completedChallenge) { return user; } + +// small helper function to determine whether to mark something as new +const dateFormat = 'MMM MMMM DD, YYYY'; +function shouldShowNew(element, block) { + if (element) { + return typeof element.releasedOn !== 'undefined' && + moment(element.releasedOn, dateFormat).diff(moment(), 'days') >= -30; + } + + if (block) { + const newCount = block.reduce((sum, { markNew }) => { + if (markNew) { + return sum + 1; + } + return sum; + }, 0); + return newCount / block.length * 100 === 100; + } +} + module.exports = function(app) { const router = app.loopback.Router(); @@ -113,23 +133,31 @@ module.exports = function(app) { .shareReplay(); // create a stream of challenge blocks - const blocks$ = challenge$ + const superBlocks$ = challenge$ .map(challenge => challenge.toJSON()) // group challenges by block | returns a stream of observables .groupBy(challenge => challenge.block) // turn block group stream into an array - .flatMap(block$ => block$.toArray()) + .flatMap(blocks$ => blocks$.toArray()) // turn array into stream of object .map(blockArray => ({ name: blockArray[0].block, dashedName: dasherize(blockArray[0].block), - challenges: blockArray + challenges: blockArray, + superBlock: blockArray[0].superBlock })) .filter(({ name })=> { return name !== 'Hikes'; }) + .groupBy(block => block.superBlock) + .flatMap(superBlocks$ => superBlocks$.toArray()) .shareReplay(); + const blocks$ = superBlocks$ + .flatMap(superBlock => Observable.just(superBlock)) + .shareReplay(); + + superBlocks$.subscribe(() => {}); const User = app.models.User; const userCount$ = observeMethod(User, 'count'); @@ -455,23 +483,6 @@ module.exports = function(app) { function challengeMap({ user = {} }, res, next) { - // small helper function to determine whether to mark something as new - function shouldShowNew(element, block) { - if (element) { - return (typeof element.releasedOn !== 'undefined' && - moment(element.releasedOn, 'MMM MMMM DD, YYYY') - .diff(moment(), 'days') >= -30); - } else if (block) { - const newCount = block.reduce((sum, { markNew }) => { - if (markNew) { - return sum + 1; - } - return sum; - }, 0); - return newCount / block.length * 100 === 100; - } - } - let lastCompleted; const daysRunning = moment().diff(new Date('10/15/2014'), 'days'); @@ -485,7 +496,7 @@ module.exports = function(app) { .map(camperCount => numberWithCommas(camperCount)); // create a stream of an array of all the challenge blocks - const blocks$ = challenge$ + const superBlocks$ = challenge$ // mark challenge completed .map(challengeModel => { const challenge = challengeModel.toJSON(); @@ -511,6 +522,7 @@ module.exports = function(app) { return { isBeta, name: blockArray[0].block, + superBlock: blockArray[0].superBlock, dashedName: dasherize(blockArray[0].block), markNew: shouldShowNew(null, blockArray), challenges: blockArray, @@ -521,22 +533,31 @@ module.exports = function(app) { .filter(({ name }) => name !== 'Hikes') // turn stream of blocks into a stream of an array .toArray() - .doOnNext((blocks) => { + .doOnNext(blocks => { const lastCompletedBlock = _.findLast(blocks, (block) => { return block.completed === 100; }); lastCompleted = lastCompletedBlock && lastCompletedBlock.name || null; - }); + }) + .flatMap(blocks => Observable.from(blocks, null, null, Scheduler.default)) + .groupBy(block => block.superBlock) + .flatMap(blocks$ => blocks$.toArray()) + .map(superBlockArray => ({ + name: superBlockArray[0].superBlock, + blocks: superBlockArray + })) + .toArray(); Observable.combineLatest( camperCount$, - blocks$, - (camperCount, blocks) => ({ camperCount, blocks }) + superBlocks$, + (camperCount, superBlocks) => ({ camperCount, superBlocks }) ) .subscribe( - ({ camperCount, blocks }) => { + ({ camperCount, superBlocks }) => { + console.log('sup', superBlocks); res.render('challengeMap/show', { - blocks, + superBlocks, daysRunning, globalCompletedCount: numberWithCommas( 5612952 + (Math.floor((Date.now() - 1446268581061) / 2000)) diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade index c02ac8ab0c..495b81009a 100644 --- a/server/views/challengeMap/show.jade +++ b/server/views/challengeMap/show.jade @@ -45,35 +45,38 @@ block content .row .col-xs-12.col-sm-8.col-sm-offset-2 h3 800 Hours of Practice: - - var i = 0 - for challengeBlock in blocks - - i++ - .row - if (user) - if (challengeBlock.completed === 100) - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-11.col-sm-8.col-md-9 - span.map-p.faded.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-danger.small     - strong - em NEW - else - .hidden-xs.col-sm-3.col-md-2 - .progress.progress-bar-padding.text-center.thin-progress-bar - .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-11.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-danger.small     - strong - em NEW + ol + for superBlock in superBlocks + h1= superBlock.name + - var i = 0 + for challengeBlock in superBlock.blocks + - i++ + .row + if (user) + if (challengeBlock.completed === 100) + .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-11.col-sm-8.col-md-9 + li.map-p.faded.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-danger.small     + strong + em NEW + else + .hidden-xs.col-sm-3.col-md-2 + .progress.progress-bar-padding.text-center.thin-progress-bar + .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-11.col-sm-8.col-md-9 + li.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-danger.small     + strong + em NEW else .hidden-xs.col-sm-3.col-md-2 .col-xs-1.col-sm-1.col-md-1.map-row-numbers @@ -117,21 +120,19 @@ block content .col-xs-10.col-sm-8.col-md-9 span.map-p.negative-10 300-hour Nonprofit Project hr + for superBlock in superBlocks + for challengeBlock in superBlock.blocks + .row + a(href='#' name=challengeBlock.dashedName) + .spacer.negative-55 - for challengeBlock in blocks - .row - a(href='#' name=challengeBlock.dashedName) - .spacer.negative-55 - - .row - .hidden-xs.col-sm-3.col-md-2 - h3.text-primary.text-right.nowrap - i.fa.fa-clock-o - = challengeBlock.time - .col-xs-12.col-sm-9.col-md-10 - h3 #{challengeBlock.name}   - - + .row + .hidden-xs.col-sm-3.col-md-2 + h3.text-primary.text-right.nowrap + i.fa.fa-clock-o + = challengeBlock.time + .col-xs-12.col-sm-9.col-md-10 + h3 #{challengeBlock.name}   - var i = 0 for challenge in challengeBlock.challenges - i++ @@ -185,4 +186,4 @@ block content }, 1000); localStorage.hideRedditNotice = "true"; }); - }); \ No newline at end of file + });