From fd22c30c9f3c3b1781026c093f023cd96fe3e7b8 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Sat, 28 May 2016 01:28:50 -0700 Subject: [PATCH] Add random compliment on challenge completion --- client/sagas/completion-saga.js | 31 +++++ client/sagas/frame-saga.js | 11 +- client/sagas/index.js | 2 + common/app/routes/challenges/redux/actions.js | 3 +- common/app/routes/challenges/redux/types.js | 2 +- common/app/utils/get-words.js | 18 +++ common/app/utils/words.json | 128 ++++++++++++++++++ 7 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 client/sagas/completion-saga.js create mode 100644 common/app/utils/get-words.js create mode 100644 common/app/utils/words.json diff --git a/client/sagas/completion-saga.js b/client/sagas/completion-saga.js new file mode 100644 index 0000000000..e66a0b2a5d --- /dev/null +++ b/client/sagas/completion-saga.js @@ -0,0 +1,31 @@ +import { Observable } from 'rx'; +import types from '../../common/app/routes/challenges/redux/types'; +import { makeToast } from '../../common/app/redux/actions'; + +import { randomCompliment } from '../../common/app/utils/get-words'; +/* +import { + updateOutput, + checkChallenge, + updateTests +} from '../../common/app/routes/challenges/redux/actions'; +*/ + +export default function completionSaga(actions$, getState) { + return actions$ + .filter(({ type }) => ( + type === types.checkChallenge + )) + .flatMap(() => { + const { tests } = getState().challengesApp; + if (tests.length > 1 && tests.every(test => test.pass && !test.err)) { + return Observable.of( + makeToast({ + type: 'success', + message: randomCompliment() + }) + ); + } + return Observable.just(null); + }); +} diff --git a/client/sagas/frame-saga.js b/client/sagas/frame-saga.js index 1650ac15e2..89b2b4197e 100644 --- a/client/sagas/frame-saga.js +++ b/client/sagas/frame-saga.js @@ -2,9 +2,8 @@ import Rx, { Observable, Subject } from 'rx'; import loopProtect from 'loop-protect'; import types from '../../common/app/routes/challenges/redux/types'; import { - updateOutput -} from '../../common/app/routes/challenges/redux/actions'; -import { + updateOutput, + checkChallenge, updateTests } from '../../common/app/routes/challenges/redux/actions'; @@ -108,9 +107,13 @@ export default function frameSaga(actions$, getState, { window, document }) { runTests$.flatMap(() => { const { frame } = getFrameDocument(document, testId); const { tests } = getState().challengesApp; + const postTests = Observable.of( + updateOutput('// tests completed'), + checkChallenge() + ).delay(250); return frame.__runTests$(tests) .map(updateTests) - .concat(Observable.just(updateOutput('// tests completed')).delay(250)); + .concat(postTests); }), result$ ); diff --git a/client/sagas/index.js b/client/sagas/index.js index e1c78d0243..409cc245ee 100644 --- a/client/sagas/index.js +++ b/client/sagas/index.js @@ -5,6 +5,7 @@ import hardGoToSaga from './hard-go-to-saga'; import windowSaga from './window-saga'; import executeChallengeSaga from './execute-challenge-saga'; import frameSaga from './frame-saga'; +import completionSaga from './completion-saga'; import codeStorageSaga from './code-storage-saga'; export default [ @@ -15,5 +16,6 @@ export default [ windowSaga, executeChallengeSaga, frameSaga, + completionSaga, codeStorageSaga ]; diff --git a/common/app/routes/challenges/redux/actions.js b/common/app/routes/challenges/redux/actions.js index d814159c6c..afec078e65 100644 --- a/common/app/routes/challenges/redux/actions.js +++ b/common/app/routes/challenges/redux/actions.js @@ -48,7 +48,6 @@ export const executeChallenge = createAction(types.executeChallenge); export const updateMain = createAction(types.updateMain); export const frameMain = createAction(types.frameMain); -export const frameOutput = createAction(types.frameOutput); export const frameTests = createAction(types.frameTests); export const runTests = createAction(types.runTests); @@ -57,6 +56,8 @@ export const updateTests = createAction(types.updateTests); export const initOutput = createAction(types.initOutput, loggerToStr); export const updateOutput = createAction(types.updateOutput, loggerToStr); +export const checkChallenge = createAction(types.checkChallenge); + // code storage export const saveCode = createAction(types.saveCode); export const loadCode = createAction(types.loadCode); diff --git a/common/app/routes/challenges/redux/types.js b/common/app/routes/challenges/redux/types.js index 44a3735153..a940a7ec95 100644 --- a/common/app/routes/challenges/redux/types.js +++ b/common/app/routes/challenges/redux/types.js @@ -24,11 +24,11 @@ export default createTypes([ 'updateMain', 'runTests', 'frameMain', - 'frameOutput', 'frameTests', 'updateOutput', 'initOutput', 'updateTests', + 'checkChallenge', // code storage 'saveCode', diff --git a/common/app/utils/get-words.js b/common/app/utils/get-words.js new file mode 100644 index 0000000000..5fa1f5d00d --- /dev/null +++ b/common/app/utils/get-words.js @@ -0,0 +1,18 @@ +import words from './words.json'; + + +function randomItem(arr) { + return arr[ Math.floor(Math.random() * arr.length) ]; +} + +export function randomPhrase() { + return randomItem(words.phrases); +} + +export function randomVerb() { + return randomItem(words.verbs); +} + +export function randomCompliment() { + return randomItem(words.compliments); +} diff --git a/common/app/utils/words.json b/common/app/utils/words.json new file mode 100644 index 0000000000..4321afca62 --- /dev/null +++ b/common/app/utils/words.json @@ -0,0 +1,128 @@ +{ + "verbs": [ + "aced", + "nailed", + "rocked", + "destroyed", + "owned", + "crushed", + "conquered", + "shredded", + "demolished", + "devoured", + "banished", + "wrangled" + ], + "compliments": [ + "Over the top!", + "Down the rabbit hole we go!", + "Bring that rain!", + "Target acquired!", + "Feel that need for speed!", + "You've got guts!", + "We have liftoff!", + "To infinity and beyond!", + "Encore!", + "Onward, ho!", + "Challenge destroyed!", + "It's on like Donkey Kong!", + "Power level? It's over 9000!", + "Coding spree!", + "Code long and prosper.", + "The crowd goes wild!", + "One for the guinness book!", + "Flawless victory!", + "Most efficient!", + "Party on, Wayne!", + "You've got the touch!", + "You're on fire!", + "Don't hurt 'em, Hammer!", + "The town is now red!", + "To the nines!", + "The world rejoices!", + "That's the way it's done!", + "You rock!", + "Woo-hoo!", + "We knew you could do it!", + "Hyper Combo Finish!", + "Nothing but net!", + "Boom-shakalaka!", + "You're a shooting star!", + "You're unstoppable!", + "Way cool!", + "You're king of the world!", + "Walk on that sunshine!", + "Keep on trucking!", + "Off the charts!", + "There is no spoon!", + "Cranked it up to 11!", + "Escape velocity reached!", + "You make this look easy!", + "Passed with flying colors!", + "You've got this!", + "Happy, happy, joy, joy!", + "Tomorrow, the world!", + "Your powers combined!", + "A winner is you!", + "It's alive. It's alive!", + "Sonic Boom!", + "Here's looking at you, Code!", + "Ride like the wind!", + "Legen - wait for it - dary!", + "Ludicrous Speed! Go!", + "Yes we can!", + "Most triumphant!", + "One loop to rule them all!", + "By the power of Grayskull!", + "You did it!", + "Storm that castle!", + "Face-melting guitar solo!", + "Checkmate!", + "Bodacious!", + "Tubular!", + "You're outta sight!", + "Keep calm and code on!", + "Even sad panda smiles!", + "Even grumpy cat approves!", + "Kool Aid Man says oh yeah!", + "Bullseye!", + "Far out!", + "You're heating up!", + "Hasta la vista, challenge!", + "Terminated.", + "Hodor!", + "Off the hook!", + "Thundercats, Hooo!", + "Shiver me timbers!", + "Raise the roof!", + "We've underestimated you.", + "I also live dangerously.", + "Get to the choppa!", + "Bingo!", + "And you're all out of gum.", + "Even honeybadger cares!", + "Helm, Warp Nine. Engage!", + "Gotta code 'em all!", + "Spool up the FTL drive!", + "Cool beans!", + "They're in another castle.", + "Power UP!", + "Nuclear launch detected.", + "Pikachu chooses you!", + "We're gonna pump you up!", + "I gotta have more cow bell." + ], + "phrases": [ + "Shout it from on top of a mountain", + "Tell everyone and their dogs", + "Show them. Show them all!", + "Inspire your friends", + "Tell the world of your greatness", + "Look accomplished on social media", + "Share news of your grand endeavor", + "Establish your alibi for the past two hours", + "Prove to mom that computers aren't just for games", + "With coding power comes sharing responsibility", + "Have you told your friends of your coding powers?" + ] +}