Merge pull request #7998 from FreeCodeCamp/staging

Release staging
This commit is contained in:
Berkeley Martinez
2016-04-08 15:26:26 -07:00
13 changed files with 283 additions and 152 deletions

View File

@ -29,7 +29,7 @@
white-space: pre; white-space: pre;
padding: 5px 10px; padding: 5px 10px;
margin-bottom: 10px; margin-bottom: 10px;
margin-top: -10px; margin-top: -5px;
overflow: auto; overflow: auto;
} }
dfn { dfn {
@ -111,3 +111,28 @@ iframe.iphone {
right: -207px; right: -207px;
} }
} }
.night {
.challenge-instructions blockquote {
background-color: #242424;
border-color: #515151;
color: #ABABAB
}
div.CodeMirror {
background-color:#242424;
color:#ABABAB;
&-gutters {
background-color:#242424;
color:#ABABAB;
}
.cm-bracket, .cm-tag {
color:#5CAFD6;
}
.cm-property, .cm-string {
color:#B5753A;
}
.cm-keyword, .cm-attribute {
color:#9BBBDC;
}
}
}

View File

@ -54,6 +54,10 @@ html {
border-color: @brand-primary; border-color: @brand-primary;
} }
body {
display: none;
}
body.full-screen-body-background { body.full-screen-body-background {
background-color: @body-bg; background-color: @body-bg;
} }
@ -678,7 +682,7 @@ thead {
/** /**
* Bonfire styling * Challenge styling
*/ */
form.code span { form.code span {
@ -986,7 +990,7 @@ hr {
} }
code { code {
padding: 0; padding: 1px 5px;
} }
@media only screen and (min-width: 993px) { @media only screen and (min-width: 993px) {
@ -1133,6 +1137,49 @@ code {
} }
} }
.night {
background-color: #333;
color: #999;
.btn-group,
.text-success,
.challenge-list-header,
.fcc-footer {
background-color: #333;
}
.navbar-default .navbar-nav > li > a {
color: #CCC;
&:hover {
background-color: #666;
}
}
a, .input-group-addon {
color: #CCC;
}
.black-text {
color:#111;
}
code {
background-color: #2A2A2A;
color: #006400;
}
.fcc-footer {
a {
&hover {
background-color: #333;
}
}
}
.btn-primary {
background-color: #006400;
color:#CCC;
transition: color 0.2s, background-color 0.2s;
&:hover {
background-color: #ABABAB!important;
color: #333!important;
}
}
}
@import "chat.less"; @import "chat.less";
@import "jobs.less"; @import "jobs.less";
@import "challenge.less"; @import "challenge.less";

View File

@ -2,6 +2,7 @@
* based off of https://github.com/gitterHQ/sidecar * based off of https://github.com/gitterHQ/sidecar
* license: MIT * license: MIT
*/ */
.map-aside { .map-aside {
width:500px; width:500px;
@ -314,3 +315,33 @@
.map-aside-action-collapse { .map-aside-action-collapse {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzEuNDI5IDE3MS40MjkiIGZpbGw9IiMzYTMxMzMiPjxwYXRoIGQ9Ik0xMjIuNDMzLDEwNi4xMzhsLTE2LjI5NSwxNi4yOTVjLTAuNzQ0LDAuNzQ0LTEuNiwxLjExNi0yLjU2NiwxLjExNmMtMC45NjgsMC0xLjgyMy0wLjM3Mi0yLjU2Ny0xLjExNmwtMTUuMjktMTUuMjkgbC0xNS4yOSwxNS4yOWMtMC43NDQsMC43NDQtMS42LDEuMTE2LTIuNTY3LDEuMTE2cy0xLjgyMy0wLjM3Mi0yLjU2Ny0xLjExNmwtMTYuMjk0LTE2LjI5NWMtMC43NDQtMC43NDQtMS4xMTYtMS42LTEuMTE2LTIuNTY2IGMwLTAuOTY4LDAuMzcyLTEuODIzLDEuMTE2LTIuNTY3bDE1LjI5LTE1LjI5bC0xNS4yOS0xNS4yOWMtMC43NDQtMC43NDQtMS4xMTYtMS42LTEuMTE2LTIuNTY3czAuMzcyLTEuODIzLDEuMTE2LTIuNTY3IEw2NS4yOSw0OC45OTZjMC43NDQtMC43NDQsMS42LTEuMTE2LDIuNTY3LTEuMTE2czEuODIzLDAuMzcyLDIuNTY3LDEuMTE2bDE1LjI5LDE1LjI5bDE1LjI5LTE1LjI5IGMwLjc0NC0wLjc0NCwxLjYtMS4xMTYsMi41NjctMS4xMTZjMC45NjcsMCwxLjgyMiwwLjM3MiwyLjU2NiwxLjExNmwxNi4yOTUsMTYuMjk0YzAuNzQ0LDAuNzQ0LDEuMTE2LDEuNiwxLjExNiwyLjU2NyBzLTAuMzcyLDEuODIzLTEuMTE2LDIuNTY3bC0xNS4yOSwxNS4yOWwxNS4yOSwxNS4yOWMwLjc0NCwwLjc0NCwxLjExNiwxLjYsMS4xMTYsMi41NjcgQzEyMy41NDksMTA0LjUzOSwxMjMuMTc3LDEwNS4zOTQsMTIyLjQzMywxMDYuMTM4eiBNMTQ2LjQyOSw4NS43MTRjMC0xMS4wMTItMi43MTctMjEuMTY4LTguMTQ4LTMwLjQ2OSBzLTEyLjc5Ny0xNi42NjctMjIuMDk4LTIyLjA5OFM5Ni43MjYsMjUsODUuNzE0LDI1cy0yMS4xNjgsMi43MTYtMzAuNDY5LDguMTQ3UzM4LjU3OSw0NS45NDUsMzMuMTQ3LDU1LjI0NlMyNSw3NC43MDMsMjUsODUuNzE0IHMyLjcxNiwyMS4xNjgsOC4xNDcsMzAuNDY5czEyLjc5NywxNi42NjYsMjIuMDk4LDIyLjA5OHMxOS40NTcsOC4xNDgsMzAuNDY5LDguMTQ4czIxLjE2OC0yLjcxNywzMC40NjktOC4xNDggczE2LjY2Ni0xMi43OTcsMjIuMDk4LTIyLjA5OFMxNDYuNDI5LDk2LjcyNiwxNDYuNDI5LDg1LjcxNHogTTE3MS40MjksODUuNzE0YzAsMTUuNTUxLTMuODMyLDI5Ljg5My0xMS40OTYsNDMuMDI0IGMtNy42NjQsMTMuMTMzLTE4LjA2MiwyMy41My0zMS4xOTQsMzEuMTk0Yy0xMy4xMzIsNy42NjQtMjcuNDc0LDExLjQ5Ni00My4wMjQsMTEuNDk2cy0yOS44OTItMy44MzItNDMuMDI0LTExLjQ5NiBjLTEzLjEzMy03LjY2NC0yMy41MzEtMTguMDYyLTMxLjE5NC0zMS4xOTRDMy44MzIsMTE1LjYwNywwLDEwMS4yNjUsMCw4NS43MTRTMy44MzIsNTUuODIyLDExLjQ5Niw0Mi42OSBjNy42NjQtMTMuMTMzLDE4LjA2Mi0yMy41MzEsMzEuMTk0LTMxLjE5NEM1NS44MjIsMy44MzIsNzAuMTY0LDAsODUuNzE0LDBzMjkuODkzLDMuODMyLDQzLjAyNCwxMS40OTYgYzEzLjEzMyw3LjY2NCwyMy41MywxOC4wNjIsMzEuMTk0LDMxLjE5NEMxNjcuNTk3LDU1LjgyMiwxNzEuNDI5LDcwLjE2NCwxNzEuNDI5LDg1LjcxNHoiLz48L3N2Zz4=) background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzEuNDI5IDE3MS40MjkiIGZpbGw9IiMzYTMxMzMiPjxwYXRoIGQ9Ik0xMjIuNDMzLDEwNi4xMzhsLTE2LjI5NSwxNi4yOTVjLTAuNzQ0LDAuNzQ0LTEuNiwxLjExNi0yLjU2NiwxLjExNmMtMC45NjgsMC0xLjgyMy0wLjM3Mi0yLjU2Ny0xLjExNmwtMTUuMjktMTUuMjkgbC0xNS4yOSwxNS4yOWMtMC43NDQsMC43NDQtMS42LDEuMTE2LTIuNTY3LDEuMTE2cy0xLjgyMy0wLjM3Mi0yLjU2Ny0xLjExNmwtMTYuMjk0LTE2LjI5NWMtMC43NDQtMC43NDQtMS4xMTYtMS42LTEuMTE2LTIuNTY2IGMwLTAuOTY4LDAuMzcyLTEuODIzLDEuMTE2LTIuNTY3bDE1LjI5LTE1LjI5bC0xNS4yOS0xNS4yOWMtMC43NDQtMC43NDQtMS4xMTYtMS42LTEuMTE2LTIuNTY3czAuMzcyLTEuODIzLDEuMTE2LTIuNTY3IEw2NS4yOSw0OC45OTZjMC43NDQtMC43NDQsMS42LTEuMTE2LDIuNTY3LTEuMTE2czEuODIzLDAuMzcyLDIuNTY3LDEuMTE2bDE1LjI5LDE1LjI5bDE1LjI5LTE1LjI5IGMwLjc0NC0wLjc0NCwxLjYtMS4xMTYsMi41NjctMS4xMTZjMC45NjcsMCwxLjgyMiwwLjM3MiwyLjU2NiwxLjExNmwxNi4yOTUsMTYuMjk0YzAuNzQ0LDAuNzQ0LDEuMTE2LDEuNiwxLjExNiwyLjU2NyBzLTAuMzcyLDEuODIzLTEuMTE2LDIuNTY3bC0xNS4yOSwxNS4yOWwxNS4yOSwxNS4yOWMwLjc0NCwwLjc0NCwxLjExNiwxLjYsMS4xMTYsMi41NjcgQzEyMy41NDksMTA0LjUzOSwxMjMuMTc3LDEwNS4zOTQsMTIyLjQzMywxMDYuMTM4eiBNMTQ2LjQyOSw4NS43MTRjMC0xMS4wMTItMi43MTctMjEuMTY4LTguMTQ4LTMwLjQ2OSBzLTEyLjc5Ny0xNi42NjctMjIuMDk4LTIyLjA5OFM5Ni43MjYsMjUsODUuNzE0LDI1cy0yMS4xNjgsMi43MTYtMzAuNDY5LDguMTQ3UzM4LjU3OSw0NS45NDUsMzMuMTQ3LDU1LjI0NlMyNSw3NC43MDMsMjUsODUuNzE0IHMyLjcxNiwyMS4xNjgsOC4xNDcsMzAuNDY5czEyLjc5NywxNi42NjYsMjIuMDk4LDIyLjA5OHMxOS40NTcsOC4xNDgsMzAuNDY5LDguMTQ4czIxLjE2OC0yLjcxNywzMC40NjktOC4xNDggczE2LjY2Ni0xMi43OTcsMjIuMDk4LTIyLjA5OFMxNDYuNDI5LDk2LjcyNiwxNDYuNDI5LDg1LjcxNHogTTE3MS40MjksODUuNzE0YzAsMTUuNTUxLTMuODMyLDI5Ljg5My0xMS40OTYsNDMuMDI0IGMtNy42NjQsMTMuMTMzLTE4LjA2MiwyMy41My0zMS4xOTQsMzEuMTk0Yy0xMy4xMzIsNy42NjQtMjcuNDc0LDExLjQ5Ni00My4wMjQsMTEuNDk2cy0yOS44OTItMy44MzItNDMuMDI0LTExLjQ5NiBjLTEzLjEzMy03LjY2NC0yMy41MzEtMTguMDYyLTMxLjE5NC0zMS4xOTRDMy44MzIsMTE1LjYwNywwLDEwMS4yNjUsMCw4NS43MTRTMy44MzIsNTUuODIyLDExLjQ5Niw0Mi42OSBjNy42NjQtMTMuMTMzLDE4LjA2Mi0yMy41MzEsMzEuMTk0LTMxLjE5NEM1NS44MjIsMy44MzIsNzAuMTY0LDAsODUuNzE0LDBzMjkuODkzLDMuODMyLDQzLjAyNCwxMS40OTYgYzEzLjEzMyw3LjY2NCwyMy41MywxOC4wNjIsMzEuMTk0LDMxLjE5NEMxNjcuNTk3LDU1LjgyMiwxNzEuNDI5LDcwLjE2NCwxNzEuNDI5LDg1LjcxNHoiLz48L3N2Zz4=)
} }
.night {
.map-fixed-header {
background-color: #333;
}
.map-aside {
border-left-color:#222;
}
#map-filter, .input-group-addon {
border-color: #222;
background-color: #666;
color:#ABABAB;
}
.map-accordion h2 > a {
background:#666;
}
.map-accordion a:focus, #noneFound {
color: #ABABAB;
}
.input-group-addon {
&.filled{
background: #555;
border-color: #000d00;
color: white;
}
}
.challenge-title {
color: #999;
}
}

View File

@ -356,7 +356,7 @@ $(document).ready(function() {
function showMap() { function showMap() {
if (!main.isMapAsideLoad) { if (!main.isMapAsideLoad) {
var mapAside = $('<iframe>'); var mapAside = $('<iframe id = "map-aside-frame" >');
mapAside.attr({ mapAside.attr({
src: '/map-aside', src: '/map-aside',
frameBorder: '0' frameBorder: '0'
@ -534,4 +534,82 @@ $(document).ready(function() {
// keyboard shortcuts: open map // keyboard shortcuts: open map
window.Mousetrap.bind('g m', toggleMap); window.Mousetrap.bind('g m', toggleMap);
// Night Mode
function changeMode() {
var newValue = false;
try {
newValue = !JSON.parse(localStorage.getItem('nightMode'));
} catch (e) {
console.error('Error parsing value form local storage:', 'nightMode', e);
}
localStorage.setItem('nightMode', String(newValue));
toggleNightMode(newValue);
}
function toggleNightMode(nightModeEnabled) {
var iframe = document.getElementById('map-aside-frame');
if (iframe) {
iframe.src = iframe.src;
}
var body = $('body');
body.hide();
if (nightModeEnabled) {
body.addClass('night');
} else {
body.removeClass('night');
}
body.fadeIn('100');
}
if (typeof localStorage.getItem('nightMode') !== 'undefined') {
var oldVal = false;
try {
oldVal = JSON.parse(localStorage.getItem('nightMode'));
} catch (e) {
console.error('Error parsing value form local storage:', 'nightMode', e);
}
toggleNightMode(oldVal);
$('.nightMode-btn').on('click', function() {
changeMode();
});
} else {
localStorage.setItem('nightMode', 'false');
toggleNightMode('false');
}
// Hot Keys
window.Mousetrap.bind('g t n', changeMode);
window.Mousetrap.bind('g n n', () => {
// Next Challenge
window.location = '/challenges/next-challenge';
});
window.Mousetrap.bind('g n a', () => {
// Account
window.location = '/account';
});
window.Mousetrap.bind('g n m', () => {
// Map
window.location = '/map';
});
window.Mousetrap.bind('g n w', () => {
// Wiki
window.location = '/wiki';
});
window.Mousetrap.bind('g n a', () => {
// About
window.location = '/about';
});
window.Mousetrap.bind('g n s', () => {
// Shop
window.location = '/shop';
});
window.Mousetrap.bind('g n o', () => {
// Settings
window.location = '/settings';
});
window.Mousetrap.bind('g n r', () => {
// Repo
window.location = 'https://github.com/freecodecamp/freecodecamp/';
});
}); });

View File

@ -4953,7 +4953,7 @@
"description": [ "description": [
"Random numbers are useful for creating random behavior.", "Random numbers are useful for creating random behavior.",
"JavaScript has a <code>Math.random()</code> function that generates a random decimal number between <code>0</code> (inclusive) and not quite up to <code>1</code> (exclusive). Thus <code>Math.random()</code> can return a <code>0</code> but never quite return a <code>1</code>", "JavaScript has a <code>Math.random()</code> function that generates a random decimal number between <code>0</code> (inclusive) and not quite up to <code>1</code> (exclusive). Thus <code>Math.random()</code> can return a <code>0</code> but never quite return a <code>1</code>",
"<strong>Note</strong><br>Like <a href='waypoint-storing-values-with-the-equal-operator' target='_blank'>Storing Values with the Equal Operator</a>, all function calls will be resolved before the <code>return</code> executes, so we can simply <code>return</code> the value of the <code>Math.random()</code> function.", "<strong>Note</strong><br>Like <a href='storing-values-with-the-assignment-operator' target='_blank'>Storing Values with the Equal Operator</a>, all function calls will be resolved before the <code>return</code> executes, so we can simply <code>return</code> the value of the <code>Math.random()</code> function.",
"<h4>Instructions</h4>", "<h4>Instructions</h4>",
"Change <code>randomFraction</code> to return a random number instead of returning <code>0</code>." "Change <code>randomFraction</code> to return a random number instead of returning <code>0</code>."
], ],

View File

@ -17,10 +17,11 @@
"Click the \"Create workspace\" button.", "Click the \"Create workspace\" button.",
"Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. In this window use the following commands. You don't need to know what these mean at this point.", "Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. In this window use the following commands. You don't need to know what these mean at this point.",
"Install <code>git-it</code> with this command: <code>npm install -g git-it</code>", "Install <code>git-it</code> with this command: <code>npm install -g git-it</code>",
"Before you start, read <a href='https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/' target='_blank'>Adding a new SSH key to your GitHub account</a> if you have two-factor authentication set up on your GitHub account.",
"Now start the tutorial by running <code>git-it</code>.", "Now start the tutorial by running <code>git-it</code>.",
"Note that you can resize the c9.io's windows by dragging their borders.", "Note that you can resize the c9.io's windows by dragging their borders.",
"Make sure that you are always in your project's \"workspace\" directory. You can always navigate back to this directory by running this command: <code>cd ~/workspace</code>.", "Make sure that you are always in your project's \"workspace\" directory. You can always navigate back to this directory by running this command: <code>cd ~/workspace</code>.",
"You can view this Node School module's source code on GitHub at <a href='https://github.com/jlord/git-it'>https://github.com/jlord/git-it</a>.", "You can view this Node School module's source code on GitHub at <a href='https://github.com/jlord/git-it' target='_blank'>https://github.com/jlord/git-it</a>.",
"Complete \"Get Git\"", "Complete \"Get Git\"",
"Complete \"Repository\"", "Complete \"Repository\"",
"Complete \"Commit to it\"", "Complete \"Commit to it\"",
@ -54,7 +55,7 @@
"Ahora inicia el tutorial ejecutando <code>git-it</code>", "Ahora inicia el tutorial ejecutando <code>git-it</code>",
"Puedes modificar el tamaño de las ventanas en c9.io arrastrándolas por el borde.", "Puedes modificar el tamaño de las ventanas en c9.io arrastrándolas por el borde.",
"Asegúrate de que siempre te encuentres en el directorio \"workspace\" de tu proyecto. Puedes regresar a este directorio cuando quieras usando el comando: <code>cd ~/workspace</code>.", "Asegúrate de que siempre te encuentres en el directorio \"workspace\" de tu proyecto. Puedes regresar a este directorio cuando quieras usando el comando: <code>cd ~/workspace</code>.",
"Puedes ver el código fuente de este módulo de Node School en GitHub visitando <a href='https://github.com/jlord/git-it'>https://github.com/jlord/git-it</a>.", "Puedes ver el código fuente de este módulo de Node School en GitHub visitando <a href='https://github.com/jlord/git-it' target='_blank'>https://github.com/jlord/git-it</a>.",
"Completa \"Get Git\"", "Completa \"Get Git\"",
"Completa \"Repository\"", "Completa \"Repository\"",
"Completa \"Commit to it\"", "Completa \"Commit to it\"",

View File

@ -84,7 +84,7 @@ export default function certificate(app) {
function verifyCert(certType, req, res, next) { function verifyCert(certType, req, res, next) {
const { user } = req; const { user } = req;
return user.getChallengeMap() return user.getChallengeMap$()
.flatMap(() => certTypeIds[certType]) .flatMap(() => certTypeIds[certType])
.flatMap(challenge => { .flatMap(challenge => {
const { const {

View File

@ -1,24 +1,15 @@
var Rx = require('rx'), import request from 'request';
async = require('async'), import constantStrings from '../utils/constantStrings.json';
moment = require('moment'), import labs from '../resources/labs.json';
request = require('request'), import testimonials from '../resources/testimonials.json';
debug = require('debug')('fcc:cntr:resources'), import secrets from '../../config/secrets';
constantStrings = require('../utils/constantStrings.json'),
labs = require('../resources/labs.json'),
testimonials = require('../resources/testimonials.json'),
secrets = require('../../config/secrets');
module.exports = function(app) { module.exports = function(app) {
var router = app.loopback.Router(); const router = app.loopback.Router();
var User = app.models.User; const User = app.models.User;
var Challenge = app.models.Challenge;
var Story = app.models.Story;
var Nonprofit = app.models.Nonprofit;
router.get('/api/github', githubCalls); router.get('/api/github', githubCalls);
router.get('/api/blogger', bloggerCalls); router.get('/api/blogger', bloggerCalls);
router.get('/api/trello', trelloCalls); router.get('/api/trello', trelloCalls);
router.get('/sitemap.xml', sitemap);
router.get('/chat', chat); router.get('/chat', chat);
router.get('/coding-bootcamp-cost-calculator', bootcampCalculator); router.get('/coding-bootcamp-cost-calculator', bootcampCalculator);
router.get('/twitch', twitch); router.get('/twitch', twitch);
@ -43,7 +34,6 @@ module.exports = function(app) {
router.get('/how-nonprofit-projects-work', howNonprofitProjectsWork); router.get('/how-nonprofit-projects-work', howNonprofitProjectsWork);
router.get('/code-of-conduct', codeOfConduct); router.get('/code-of-conduct', codeOfConduct);
router.get('/academic-honesty', academicHonesty); router.get('/academic-honesty', academicHonesty);
router.get( router.get(
'/the-fastest-web-page-on-the-internet', '/the-fastest-web-page-on-the-internet',
theFastestWebPageOnTheInternet theFastestWebPageOnTheInternet
@ -51,118 +41,6 @@ module.exports = function(app) {
app.use(router); app.use(router);
function sitemap(req, res, next) {
var appUrl = 'http://www.freecodecamp.com';
var now = moment(new Date()).format('YYYY-MM-DD');
// TODO(berks): refactor async to rx
async.parallel({
users: function(callback) {
User.find(
{
where: { username: { nlike: '' } },
fields: { username: true }
},
function(err, users) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
Rx.Observable.from(users, null, null, Rx.Scheduler.default)
.map(function(user) {
return user.username;
})
.toArray()
.subscribe(
function(usernames) {
callback(null, usernames);
},
callback
);
}
});
},
challenges: function(callback) {
Challenge.find(
{ fields: { name: true } },
function(err, challenges) {
if (err) {
debug('Challenge err: ', err);
callback(err);
} else {
Rx.Observable.from(challenges, null, null, Rx.Scheduler.default)
.map(function(challenge) {
return challenge.name;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
});
},
stories: function(callback) {
Story.find(
{ field: { link: true } },
function(err, stories) {
if (err) {
debug('Story err: ', err);
callback(err);
} else {
Rx.Observable.from(stories, null, null, Rx.Scheduler.default)
.map(function(story) {
return story.link;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
}
);
},
nonprofits: function(callback) {
Nonprofit.find(
{ field: { name: true } },
function(err, nonprofits) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
Rx.Observable.from(nonprofits, null, null, Rx.Scheduler.default)
.map(function(nonprofit) {
return nonprofit.name;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
});
}
}, function(err, results) {
if (err) {
return next(err);
}
return process.nextTick(function() {
res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', {
appUrl: appUrl,
now: now,
users: results.users,
challenges: results.challenges,
stories: results.stories,
nonprofits: results.nonprofits
});
});
}
);
}
function chat(req, res) { function chat(req, res) {
res.redirect('https://gitter.im/FreeCodeCamp/FreeCodeCamp'); res.redirect('https://gitter.im/FreeCodeCamp/FreeCodeCamp');
} }

64
server/boot/sitemap.js Normal file
View File

@ -0,0 +1,64 @@
import moment from 'moment';
import { Scheduler, Observable } from 'rx';
import { timeCache, observeQuery } from '../utils/rx';
import { dasherize } from '../utils';
const cacheTimeout = [ 24, 'hours' ];
const appUrl = 'https://www.freecodecamp.com';
// getCachedObservable(
// app: ExpressApp,
// modelName: String,
// nameProp: String,
// map: (nameProp: String) => String
// ) => Observable[models]
function getCachedObservable(app, modelName, nameProp, map) {
return observeQuery(
app.models[modelName],
'find',
{ fields: { [nameProp]: true } }
)
.flatMap(models => {
return Observable.from(models, null, null, Scheduler.default);
})
.filter(model => !!model[nameProp])
.map(model => model[nameProp])
.map(map ? map : (x) => x)
.toArray()
::timeCache(cacheTimeout[0], cacheTimeout[1]);
}
export default function sitemapRouter(app) {
const router = app.loopback.Router();
const challenges$ = getCachedObservable(app, 'Challenge', 'dashedName');
const stories$ = getCachedObservable(app, 'Story', 'storyLink', dasherize);
const jobs$ = getCachedObservable(app, 'Job', 'id');
function sitemap(req, res, next) {
const now = moment(new Date()).format('YYYY-MM-DD');
return Observable.combineLatest(
challenges$,
stories$,
jobs$,
(
challenges,
stories,
jobs
) => ({ challenges, stories, jobs })
)
.subscribe(
({ challenges, stories, jobs }) => {
res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', {
appUrl,
now,
challenges,
stories,
jobs
});
},
next
);
}
router.get('/sitemap.xml', sitemap);
app.use(router);
}

View File

@ -25,15 +25,20 @@ export function saveInstance(instance) {
// alias saveInstance // alias saveInstance
export const saveUser = saveInstance; export const saveUser = saveInstance;
export function observeQuery(Model, method, query) { // observeQuery(Model: Object, methodName: String, query: Any) => Observable
return Rx.Observable.fromNodeCallback(Model[method], Model)(query); export function observeQuery(Model, methodName, query) {
return Rx.Observable.fromNodeCallback(Model[methodName], Model)(query);
} }
// observeMethod(
// context: Object, methodName: String
// ) => (query: Any) => Observable
export function observeMethod(context, methodName) { export function observeMethod(context, methodName) {
return Rx.Observable.fromNodeCallback(context[methodName], context); return Rx.Observable.fromNodeCallback(context[methodName], context);
} }
// timeChache(amount: Number, unit: String) => Observable // must be bound to an observable instance
// timeCache(amount: Number, unit: String) => Observable
export function timeCache(time, unit) { export function timeCache(time, unit) {
const source = this; const source = this;
let cache; let cache;

View File

@ -3,6 +3,9 @@ block content
h1.text-center Settings for your Account h1.text-center Settings for your Account
hr hr
h2.text-center Actions h2.text-center Actions
.row
.col-xs-12
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(class = "nightMode-btn") Night Mode
.row .row
.col-xs-12 .col-xs-12
if (!user.isGithubCool) if (!user.isGithubCool)

View File

@ -8,7 +8,7 @@ html(lang='en')
include partials/scripts include partials/scripts
block content block content
else else
body.no-top-and-bottom-margins.full-screen-body-background body.no-top-and-bottom-margins
include partials/scripts include partials/scripts
include partials/navbar include partials/navbar
include partials/flash include partials/flash

View File

@ -49,24 +49,23 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
lastmod= now lastmod= now
priority= 0.9 priority= 0.9
//- User
each user in users
url
loc #{appUrl}/#{user}
lastmod= now
changefreq weekly
priority= 0.5
each challenge in challenges each challenge in challenges
url url
loc #{appUrl}/challenges/#{challenge.replace(/\s/g, '-')} loc #{appUrl}/challenges/#{challenge}
lastmod= now lastmod= now
changefreq weekly changefreq weekly
priority= 0.9 priority= 0.9
each story in stories each story in stories
url url
loc #{appUrl}/news/#{story.replace(/\s/g, '-')} loc #{appUrl}/news/#{story}
lastmod= now lastmod= now
changefreq weekly changefreq monthly
priority= 0.5
each job in jobs
url
loc #{appUrl}/jobs/#{job}
lastmod= now
changefreq monthly
priority= 0.5 priority= 0.5