Merge remote-tracking branch 'upstream/staging' into staging
Conflicts: seed/challenges/html5-and-css.json
This commit is contained in:
@ -685,7 +685,7 @@ thead {
|
||||
padding-right: 10px;
|
||||
&:hover {
|
||||
padding-top: 14px;
|
||||
padding-bottom: 14px;
|
||||
padding-bottom: 12px;
|
||||
color: #4a2b0f;
|
||||
background-color: #eee;
|
||||
text-decoration: none;
|
||||
|
@ -252,14 +252,15 @@ var allSeeds = '';
|
||||
|
||||
editorValue = (codeStorage.isAlive())? codeStorage.getEditorValue() : allSeeds;
|
||||
|
||||
editor.setValue(editorValue);
|
||||
editor.setValue(editorValue.replace((/fccss/gi), '<script>').replace((/fcces/gi), '</script>'));
|
||||
editor.refresh();
|
||||
|
||||
var resetEditor = function resetEditor() {
|
||||
editor.setValue(allSeeds);
|
||||
editor.setValue(allSeeds.replace((/fccss/gi), '<script>').replace((/fcces/gi), '</script>'));
|
||||
updatePreview();
|
||||
codeStorage.updateStorage();
|
||||
};
|
||||
|
||||
/*
|
||||
var challengeSeed = challengeSeed || null;
|
||||
var allSeeds = '';
|
||||
(function() {
|
||||
@ -273,3 +274,4 @@ var allSeeds = '';
|
||||
}, 200);
|
||||
})();
|
||||
})();
|
||||
*/
|
||||
|
@ -159,12 +159,107 @@ $(document).ready(function() {
|
||||
$('#complete-zipline-or-basejump-dialog').modal('show');
|
||||
});
|
||||
|
||||
$('#completed-courseware-dialog').unbind('click');
|
||||
$('#next-courseware-button').unbind('click');
|
||||
$('#next-courseware-button').on('click', function() {
|
||||
$('#next-courseware-button').unbind('click');
|
||||
if ($('.signup-btn-nav').length < 1) {
|
||||
switch (challengeType) {
|
||||
case challengeTypes.HTML_CSS_JQ:
|
||||
case challengeTypes.JAVASCRIPT:
|
||||
case challengeTypes.VIDEO:
|
||||
$.post(
|
||||
'/completed-challenge/',
|
||||
{
|
||||
challengeInfo: {
|
||||
challengeId: challenge_Id,
|
||||
challengeName: challenge_Name
|
||||
}
|
||||
}).success(
|
||||
function(res) {
|
||||
if (res) {
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
}
|
||||
}).fail(
|
||||
function() {
|
||||
window.location.href="/challenges";
|
||||
}
|
||||
);
|
||||
break;
|
||||
case challengeTypes.ZIPLINE:
|
||||
var didCompleteWith = $('#completed-with').val() || null;
|
||||
var publicURL = $('#public-url').val() || null;
|
||||
$.post(
|
||||
'/completed-zipline-or-basejump/',
|
||||
{
|
||||
challengeInfo: {
|
||||
challengeId: challenge_Id,
|
||||
challengeName: challenge_Name,
|
||||
completedWith: didCompleteWith,
|
||||
publicURL: publicURL,
|
||||
challengeType: challengeType
|
||||
}
|
||||
}).success(
|
||||
function() {
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
}).fail(
|
||||
function() {
|
||||
window.location.href = '/challenges';
|
||||
});
|
||||
break;
|
||||
case challengeTypes.BASEJUMP:
|
||||
var didCompleteWith = $('#completed-with').val() || null;
|
||||
var publicURL = $('#public-url').val() || null;
|
||||
var githubURL = $('#github-url').val() || null;
|
||||
$.post(
|
||||
'/completed-zipline-or-basejump/',
|
||||
{
|
||||
challengeInfo: {
|
||||
challengeId: challenge_Id,
|
||||
challengeName: challenge_Name,
|
||||
completedWith: didCompleteWith,
|
||||
publicURL: publicURL,
|
||||
githubURL: githubURL,
|
||||
challengeType: challengeType,
|
||||
verified: false
|
||||
}
|
||||
}).success(function() {
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
}).fail(function() {
|
||||
window.location.replace(window.location.href);
|
||||
});
|
||||
break;
|
||||
case challengeTypes.BONFIRE:
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.next-challenge-button').unbind('click');
|
||||
$('.next-challenge-button').on('click', function() {
|
||||
l = location.pathname.split('/');
|
||||
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
|
||||
});
|
||||
|
||||
// Bonfire instructions functions
|
||||
$('#more-info').unbind('click');
|
||||
$('#more-info').on('click', function() {
|
||||
ga('send', 'event', 'Challenge', 'more-info', challengeName);
|
||||
$('#brief-instructions').hide();
|
||||
$('#long-instructions').show().removeClass('hide');
|
||||
|
||||
});
|
||||
$('#less-info').unbind('click');
|
||||
$('#less-info').on('click', function() {
|
||||
$('#brief-instructions').show();
|
||||
$('#long-instructions').hide();
|
||||
});
|
||||
|
||||
$('#complete-courseware-dialog').on('hidden.bs.modal', function() {
|
||||
editor.focus();
|
||||
});
|
||||
|
||||
$('#completed-zipline-or-basejump').unbind('click');
|
||||
$('#complete-zipline-or-basejump').on('hidden.bs.modal', function() {
|
||||
editor.focus();
|
||||
});
|
||||
@ -186,98 +281,6 @@ $(document).ready(function() {
|
||||
'BASEJUMP': '4',
|
||||
'BONFIRE': '5'
|
||||
};
|
||||
$('#next-courseware-button').on('click', function() {
|
||||
$('#next-courseware-button').unbind('click');
|
||||
if ($('.signup-btn-nav').length < 1) {
|
||||
switch (challengeType) {
|
||||
case challengeTypes.HTML_CSS_JQ:
|
||||
case challengeTypes.JAVASCRIPT:
|
||||
case challengeTypes.VIDEO:
|
||||
$.post(
|
||||
'/completed-challenge/',
|
||||
{
|
||||
challengeInfo: {
|
||||
challengeId: challenge_Id,
|
||||
challengeName: challenge_Name
|
||||
}
|
||||
}).success(
|
||||
function(res) {
|
||||
if (res) {
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
}
|
||||
}).fail(
|
||||
function() {
|
||||
window.location.href="/challenges";
|
||||
}
|
||||
);
|
||||
break;
|
||||
case challengeTypes.ZIPLINE:
|
||||
var didCompleteWith = $('#completed-with').val() || null;
|
||||
var publicURL = $('#public-url').val() || null;
|
||||
$.post(
|
||||
'/completed-zipline-or-basejump/',
|
||||
{
|
||||
challengeInfo: {
|
||||
challengeId: challenge_Id,
|
||||
challengeName: challenge_Name,
|
||||
completedWith: didCompleteWith,
|
||||
publicURL: publicURL,
|
||||
challengeType: challengeType
|
||||
}
|
||||
}).success(
|
||||
function() {
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
}).fail(
|
||||
function() {
|
||||
window.location.href = '/challenges';
|
||||
});
|
||||
break;
|
||||
case challengeTypes.BASEJUMP:
|
||||
var didCompleteWith = $('#completed-with').val() || null;
|
||||
var publicURL = $('#public-url').val() || null;
|
||||
var githubURL = $('#github-url').val() || null;
|
||||
$.post(
|
||||
'/completed-zipline-or-basejump/',
|
||||
{
|
||||
challengeInfo: {
|
||||
challengeId: challenge_Id,
|
||||
challengeName: challenge_Name,
|
||||
completedWith: didCompleteWith,
|
||||
publicURL: publicURL,
|
||||
githubURL: githubURL,
|
||||
challengeType: challengeType,
|
||||
verified: false
|
||||
}
|
||||
}).success(function() {
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
}).fail(function() {
|
||||
window.location.replace(window.location.href);
|
||||
});
|
||||
break;
|
||||
case challengeTypes.BONFIRE:
|
||||
window.location.href = '/challenges/next-challenge';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.next-challenge-button').on('click', function() {
|
||||
l = location.pathname.split('/');
|
||||
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
|
||||
});
|
||||
|
||||
// Bonfire instructions functions
|
||||
$('#more-info').on('click', function() {
|
||||
ga('send', 'event', 'Challenge', 'more-info', challengeName);
|
||||
$('#brief-instructions').hide();
|
||||
$('#long-instructions').show().removeClass('hide');
|
||||
|
||||
});
|
||||
$('#less-info').on('click', function() {
|
||||
$('#brief-instructions').show();
|
||||
$('#long-instructions').hide();
|
||||
});
|
||||
|
||||
function upvoteHandler(e) {
|
||||
e.preventDefault();
|
||||
|
@ -113,7 +113,7 @@
|
||||
"description": [
|
||||
"<code>data structures</code> have <code>properties</code>. For example, <code>strings</code> have a property called <code>.length</code> that will tell you how many characters are in the string.",
|
||||
"For example, if we created a variable <code>var firstName = \"Charles\"</code>, we could find out how long the string \"Charles\" is by using the <code>firstName.length</code> property.",
|
||||
"Use the <code>.length</code> property to count the number of characters in the <code>lastNameLength</code> variable."
|
||||
"Use the <code>.length</code> property to count the number of characters in the <code>lastName</code> variable."
|
||||
],
|
||||
"tests": [
|
||||
"assert((function(){if(typeof(lastNameLength) !== \"undefined\" && typeof(lastNameLength) === \"number\" && lastNameLength === 8){return(true);}else{return(false);}})(), 'lastNameLength should be equal to eight.');",
|
||||
@ -150,7 +150,7 @@
|
||||
"<code>Bracket notation</code> is a way to get a character at a specific <code>index</code> within a string.",
|
||||
"Computers don't start counting at 1 like humans do. They start at 0.",
|
||||
"For example, the character at index 0 in the word \"Charles\" is \"C\". So if <code>var firstName = \"Charles\"</code>, you can get the value of the first letter of the string by using <code>firstName[0]</code>.",
|
||||
"Use <code>bracket notation</code> to find the first character in a the <code>firstLetterOfLastName</code> variable.",
|
||||
"Use <code>bracket notation</code> to find the first character in the <code>firstLetterOfLastName</code> variable.",
|
||||
"Try looking at the <code>firstLetterOfFirstName</code> variable declaration if you get stuck."
|
||||
],
|
||||
"tests": [
|
||||
@ -216,7 +216,7 @@
|
||||
"In order to get the last letter of a string, you can subtract one from the string's length.",
|
||||
"For example, if <code>var firstName = \"Charles\"</code>, you can get the value of the last letter of the string by using <code>firstName[firstName.length - 1]</code>.",
|
||||
"Use <code>bracket notation</code> to find the last character in the <code>lastName</code> variable.",
|
||||
"Try looking at the <code>lastLetterOfLastName</code> variable declaration if you get stuck."
|
||||
"Try looking at the <code>lastLetterOfFirstName</code> variable declaration if you get stuck."
|
||||
],
|
||||
"tests": [
|
||||
"assert(lastLetterOfLastName === \"e\", 'lastLetterOfLastName should be \"e\"');",
|
||||
@ -496,7 +496,7 @@
|
||||
"// Only change code above this line.",
|
||||
"// We use this function to show you the value of your variable in your output box.",
|
||||
"// You'll learn about functions soon.",
|
||||
"if(typeof(myArray) !== \"undefined\" && typeof(data) !== \"undefined\"){(function(y,z){return('myArray = ' + JSON.stringify(y) + ', data = ' + JSON.stringify(z));})(myArray, data);}"
|
||||
"if(typeof(myArray) !== \"undefined\" && typeof(myData) !== \"undefined\"){(function(y,z){return('myArray = ' + JSON.stringify(y) + ', myData = ' + JSON.stringify(z));})(myArray, myData);}"
|
||||
],
|
||||
"type": "waypoint",
|
||||
"challengeType": 1
|
||||
@ -755,7 +755,7 @@
|
||||
"title": "Manipulate JavaScript Objects",
|
||||
"difficulty":"9.9823",
|
||||
"description":[
|
||||
"There are many ways to add and add and remove properties from objects.",
|
||||
"There are many ways to add and remove properties from objects.",
|
||||
"For example, we can add properties to objects like this:",
|
||||
"<code>myObject.myProperty = \"myValue\";</code>",
|
||||
"We can also delete them like this:",
|
||||
@ -832,7 +832,7 @@
|
||||
"difficulty":"9.9825",
|
||||
"description":[
|
||||
"You can run the same code multiple times by using a loop.",
|
||||
"Another type of JavaScript loop is called a \"while loop\" because it runs \"while\" something is true, and stops once that something is no longer true.",
|
||||
"Another type of JavaScript loop is called a \"while loop\", because it runs \"while\" something is true and stops once that something is no longer true.",
|
||||
"<code>var ourArray = [];</code>",
|
||||
"<code>var i = 0;</code>",
|
||||
"<code>while(i < 5) {</code>",
|
||||
@ -859,7 +859,7 @@
|
||||
"title": "Generate Random Fractions with JavaScript",
|
||||
"difficulty":"9.9827",
|
||||
"description":[
|
||||
"Random numbers are useful for creating random behaviours and games.",
|
||||
"Random numbers are useful for creating random behavior.",
|
||||
"JavaScript has a <code>Math.random()</code> function that generates a random decimal number.",
|
||||
"Use <code>Math.random()</code> to get <code>myFunction</code> to return a random number."
|
||||
],
|
||||
@ -956,16 +956,16 @@
|
||||
"difficulty":"9.983",
|
||||
"description":[
|
||||
"We can use if statements in JavaScript to only execute code if a certain condition is met.",
|
||||
"if statements require some sort of boolean condition evaluate.",
|
||||
"if statements require some sort of boolean condition to evaluate.",
|
||||
"Example:",
|
||||
"<code> if (1 == 2) {</code>",
|
||||
"<code> if (1 === 2) {</code>",
|
||||
"<code>  return(true);</code>",
|
||||
"<code>}</code>",
|
||||
"<code>else {</code>",
|
||||
"<code>  return(false);</code>",
|
||||
"<code>}</code>",
|
||||
"Let's use <code>if</code> and <code>else</code> statements to make a coin-flip game.",
|
||||
"Create an <code>if-else statement</code> to return <code>heads</code> if the flip var is zero and to return <code>tails</code> if it's not."
|
||||
"Create an <code>if-else statement</code> to return <code>heads</code> if the flip var is zero, or else return <code>tails</code> if it's not."
|
||||
],
|
||||
"tests":[
|
||||
"assert((function(){if(myFunction() === \"heads\" || myFunction() === \"tails\"){return(true);}else{return(false);}})(), 'myFunction should either return heads or tails');",
|
||||
@ -975,7 +975,7 @@
|
||||
"challengeSeed":[
|
||||
"function myFunction(){",
|
||||
" var flip = Math.floor(Math.random() * (1 - 0 + 1)) + 0;",
|
||||
" // Create and if else statement here to return \"heads\" if flip is 0. Otherwise return \"tails\".",
|
||||
" // Create an if-else statement here to return \"heads\" if flip is 0. Otherwise return \"tails\".",
|
||||
"",
|
||||
" // Only change code below this line.",
|
||||
"",
|
||||
@ -1002,7 +1002,7 @@
|
||||
"<code>g</code> means that we want to search the entire string for this pattern.",
|
||||
"<code>i</code> means that we want to ignore the case (uppercase or lowercase) when searching for the pattern.",
|
||||
"<code>Regular expressions</code> are usually surrounded by <code>/</code> symbols.",
|
||||
"Let's try selecting all the occurances of the word <code>and</code> in the string <code>George Boole and Alan Turing went to the shop and got some milk</code>. We can do this by replacing the <code>.+</code> part of our regular expression with the current <code>regular expression</code> with the word <code>and</code>."
|
||||
"Let's try selecting all the occurrences of the word <code>and</code> in the string <code>George Boole and Alan Turing went to the shop and got some milk</code>. We can do this by replacing the <code>.+</code> part of our regular expression with the current <code>regular expression</code> with the word <code>and</code>."
|
||||
],
|
||||
"tests":[
|
||||
"assert(test==2, 'Your <code>regular expression</code> should find two occurrences of the word <code>and</code>');",
|
||||
@ -1040,7 +1040,7 @@
|
||||
],
|
||||
"challengeSeed":[
|
||||
"var test = (function() {",
|
||||
" var testString = \"There's 3 cats but 4 dogs.\";",
|
||||
" var testString = \"There are 3 cats but 4 dogs.\";",
|
||||
"",
|
||||
" // Only change code below this line.",
|
||||
"",
|
||||
@ -1093,12 +1093,12 @@
|
||||
"You can invert any match by using the uppercase version of the selector <code>\\s</code> versus <code>\\S</code> for example."
|
||||
],
|
||||
"tests":[
|
||||
"assert(test === 36, 'Your RegEx should have found seven spaces in the <code>testString</code>.');",
|
||||
"assert(editor.getValue().match(/\\/\\\\S\\/gi/gi), 'You should be using the following expression <code>/\\+S/gi</code> to find the spaces in the <code>testString</code>.');"
|
||||
"assert(test === 49, 'Your RegEx should have found forty nine non-space characters in the <code>testString</code>.');",
|
||||
"assert(editor.getValue().match(/\\/\\\\S\\/gi/gi), 'You should be using the following expression <code>/\\S/gi</code> to find non-space characters in the <code>testString</code>.');"
|
||||
],
|
||||
"challengeSeed":[
|
||||
"var test = (function(){",
|
||||
" var testString = \"How many spaces are there in this sentence?\";",
|
||||
" var testString = \"How many non-space characters are there in this sentence?\";",
|
||||
"",
|
||||
" // Only change code below this line.",
|
||||
"",
|
||||
|
@ -48,11 +48,11 @@
|
||||
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
|
||||
"<span class='text-info'>User Story:</span> As a user, I can access all of the portfolio webpage's content just by scrolling.",
|
||||
"<span class='text-info'>User Story:</span> As a user, I can click different buttons that will take me to the portfolio creator's different social media pages.",
|
||||
"<span class='text-info'>User Story:</span> As a user, I can see thumbnail images of different projects the portfolio creator has built (if you don't haven't built any websites before, use placeholders.)",
|
||||
"<span class='text-info'>User Story:</span> As a user, I can see thumbnail images of different projects the portfolio creator has built (if you haven't built any websites before, use placeholders.)",
|
||||
"<span class='text-info'>Bonus User Story:</span> As a user, I navigate to different sections of the webpage by clicking buttons in the navigation.",
|
||||
"Don't worry if you don't have anything to showcase on your portfolio yet - you will build several several apps on the next few CodePen challenges, and can come back and update your portfolio later.",
|
||||
"There are many great portfolio templates out there, but for this challenge, you'll need to build a portfolio page yourself. Using Bootstrap will make this much easier for you.",
|
||||
"Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jquery, you will need to target invisible anchor elements like this one: <code><a target='_blank'&rt;</a>.",
|
||||
"Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jquery, you will need to target invisible anchor elements like this one: <code><a target='_blank'></a></code>.",
|
||||
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
|
||||
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
|
||||
"If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
|
||||
|
@ -133,7 +133,7 @@
|
||||
"",
|
||||
" <p>Click here for <a href=\"#\">cat photos</a>.</p>",
|
||||
"",
|
||||
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\"></a>",
|
||||
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"http://bit.ly/fcc-relaxing-cat\"></a>",
|
||||
"",
|
||||
" <p>Things cats love:</p>",
|
||||
" <ul>",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -263,7 +263,7 @@
|
||||
],
|
||||
"tests": [
|
||||
"assert(editor.match(/\\$\\(.*button/g), 'Use the <code>$(\"button\")</code> selector.')",
|
||||
"assert(editor.match(/\\$\\(.*.btn/g), 'Use the <code>$(\".btn\")</code> selector.')",
|
||||
"assert(editor.match(/\\$\\(.*\\.btn/g), 'Use the <code>$(\".btn\")</code> selector.')",
|
||||
"assert(editor.match(/\\$\\(.*#target1/g), 'Use the <code>$(\"#target1\")</code> selector.')",
|
||||
"assert(editor.match(/addClass/g) && editor.match(/addClass/g).length > 2, 'Only add one class with each of your three selectors.')",
|
||||
"assert($(\"#target1\").hasClass(\"animated\") && $(\"#target1\").hasClass(\"shake\") && $(\"#target1\").hasClass(\"btn-primary\"), 'Your <code>#target1</code> element should have the classes <code>animated</code>‚ <code>shake</code> and <code>btn-primary</code>.')",
|
||||
@ -314,7 +314,7 @@
|
||||
],
|
||||
"tests": [
|
||||
"assert($(\".btn-default\").length === 0, 'Remove the <code>btn-default</code> class from all of your <code>button</code> elements.')",
|
||||
"assert(editor.match(/btn btn-default/g), 'Only use jQuery to add these classes to the element.')"
|
||||
"assert(editor.match(/btn btn-default/g), 'Only use jQuery to remove this class from the element.')"
|
||||
],
|
||||
"challengeSeed": [
|
||||
"fccss",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"difficulty":0,
|
||||
"description":[
|
||||
"Before we dive into Object Oriented Programming, let's revisit JavaScript objects.",
|
||||
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engine</code> and <code>seats</code> attribute and set them to numbers."
|
||||
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers."
|
||||
],
|
||||
"tests":[
|
||||
"assert(typeof(motorBike.engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');",
|
||||
@ -54,7 +54,7 @@
|
||||
"difficulty":0,
|
||||
"description":[
|
||||
"We are also able to create objects using <code>constructor</code> functions.",
|
||||
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engine</code> and <code>seats</code> attribute and set them to numbers."
|
||||
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers."
|
||||
],
|
||||
"tests":[
|
||||
"assert(typeof((new MotorBike()).engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');",
|
||||
@ -62,7 +62,7 @@
|
||||
"assert(typeof((new MotorBike()).seats) === 'number', '<code>seats</code> should be have a <code>engines</code> attribute set to a number.');"
|
||||
],
|
||||
"challengeSeed":[
|
||||
"// Let's add the properties engine and seats to the car in the same way that the property wheels has been added below. They should both be numbers.",
|
||||
"// Let's add the properties engines and seats to the car in the same way that the property wheels has been added below. They should both be numbers.",
|
||||
"var Car = function() {",
|
||||
" this.wheels = 4;",
|
||||
" this.engines = 1;",
|
||||
|
@ -63,6 +63,7 @@ module.exports = function(app) {
|
||||
const findChallenge$ = observeMethod(Challenge, 'find');
|
||||
// create a stream of all the challenges
|
||||
const challenge$ = findChallenge$(challengesQuery)
|
||||
.doOnNext(() => debug('query challenges'))
|
||||
.flatMap(challenges => Observable.from(challenges))
|
||||
.shareReplay();
|
||||
|
||||
@ -128,18 +129,12 @@ module.exports = function(app) {
|
||||
app.use(router);
|
||||
|
||||
function returnNextChallenge(req, res, next) {
|
||||
|
||||
// find the user's current challenge and block
|
||||
// look in that block and find the index of their current challenge
|
||||
// if index + 1 < block.challenges.length
|
||||
// serve index + 1 challenge
|
||||
// otherwise increment block key and serve the first challenge in that block
|
||||
// unless the next block is undefined, which means no next block
|
||||
let nextChallengeName = firstChallenge;
|
||||
|
||||
const challengeId = req.user.currentChallenge ?
|
||||
req.user.currentChallenge.challengeId :
|
||||
'bd7123c8c441eddfaeb5bdef';
|
||||
|
||||
// find challenge
|
||||
return challenge$
|
||||
.map(challenge => challenge.toJSON())
|
||||
|
@ -4,24 +4,36 @@ var _ = require('lodash'),
|
||||
debug = require('debug')('freecc:cntr:userController');
|
||||
|
||||
|
||||
const daysBetween = 1.5;
|
||||
|
||||
function calcCurrentStreak(cals) {
|
||||
const revCals = cals.slice().reverse();
|
||||
let streakBroken = false;
|
||||
return revCals
|
||||
const lastDayInStreak = revCals
|
||||
.reduce((current, cal, index) => {
|
||||
// if streak not borken and diff between this cal and the call after it
|
||||
// is equal to zero
|
||||
// moment.diff will return the days between rounded down
|
||||
debug('cal', cal);
|
||||
debug('broken', streakBroken);
|
||||
const before = revCals[index === 0 ? 0 : index - 1];
|
||||
if (
|
||||
!streakBroken &&
|
||||
moment(revCals[index === 0 ? 0 : index - 1]).diff(cal, 'days') === 0
|
||||
moment(before).diff(cal, 'days', true) < daysBetween
|
||||
) {
|
||||
return current + 1;
|
||||
return index;
|
||||
}
|
||||
return 1;
|
||||
}, 1);
|
||||
streakBroken = true;
|
||||
return current;
|
||||
}, 0);
|
||||
|
||||
const lastTimestamp = revCals[lastDayInStreak];
|
||||
return Math.ceil(moment().diff(lastTimestamp, 'days', true));
|
||||
}
|
||||
|
||||
// TODO(berks): calc longest streak
|
||||
/*
|
||||
function longestStreak(cals) {
|
||||
}
|
||||
*/
|
||||
|
||||
module.exports = function(app) {
|
||||
var router = app.loopback.Router();
|
||||
var User = app.models.User;
|
||||
@ -129,9 +141,7 @@ module.exports = function(app) {
|
||||
objOrNum :
|
||||
objOrNum.timestamp;
|
||||
})
|
||||
.map(time => {
|
||||
return moment(time).format('YYYY-MM-DD');
|
||||
});
|
||||
.sort();
|
||||
|
||||
user.currentStreak = calcCurrentStreak(cals);
|
||||
|
||||
@ -146,6 +156,9 @@ module.exports = function(app) {
|
||||
objOrNum :
|
||||
objOrNum.timestamp;
|
||||
})
|
||||
.filter((timestamp) => {
|
||||
return !!timestamp;
|
||||
})
|
||||
.reduce((data, timeStamp) => {
|
||||
data[(timeStamp / 1000)] = 1;
|
||||
return data;
|
||||
|
@ -2,6 +2,14 @@
|
||||
"initial:before": {
|
||||
"loopback#favicon": {
|
||||
"params": "$!../public/favicon.ico"
|
||||
},
|
||||
"loopback#static": {
|
||||
"params": [
|
||||
"$!../public",
|
||||
{
|
||||
"maxAge": "86400000"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"initial": {
|
||||
@ -42,14 +50,6 @@
|
||||
"routes": {
|
||||
},
|
||||
"files": {
|
||||
"loopback#static": {
|
||||
"params": [
|
||||
"$!../public",
|
||||
{
|
||||
"maxAge": "86400000"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"final": {
|
||||
},
|
||||
|
@ -19,7 +19,7 @@ script.
|
||||
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js")
|
||||
script.
|
||||
if (typeof window.angular === 'undefined') {
|
||||
document.write('<script src="/bower_components/angular/angular.min.js"><\/script>')
|
||||
document.write('<script src="/bower_components/angular/angular.min.js"><\/script>');
|
||||
}
|
||||
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap.min.js")
|
||||
script.
|
||||
|
Reference in New Issue
Block a user