Skip to content

Instantly share code, notes, and snippets.

@forest
Last active September 2, 2018 22:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save forest/25823bd32d48d484e63119afca5d22a3 to your computer and use it in GitHub Desktop.
Save forest/25823bd32d48d484e63119afca5d22a3 to your computer and use it in GitHub Desktop.
export class GameActions {
constructor() { }
makeChoice() {
var result = this.getRandomInt(1,3);
switch (result) {
case 1: // rock
return { type: 'GAME_ROCK' };
case 2: // paper
return { type: 'GAME_PAPER' };
case 3: // scissors
return { type: 'GAME_SCISSORS' };
}
}
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
<template>
<require from="card"></require>
<require from="three-converter"></require>
<div class="container">
<h1>${message}</h1>
<div class="row mt-3">
<!-- card is a custom element -->
<card class="col" title="Rock" icon-class="fa-hand-rock-o" count.bind="rockCount | showThree"></card>
<card class="col" title="Paper" icon-class="fa-hand-paper-o" count.bind="paperCount"></card>
<card class="col" title="Scissors" icon-class="fa-hand-scissors-o" count.bind="scissorsCount | showThree"></card>
</div>
<div class="row justify-content-center mt-5">
<div class="col-3">
<button type="button" class="btn btn-outline-dark" click.delegate="play()">Play</button>
</div>
</div>
</div>
<p class="text-muted small mt-5 ml-2">
Install <a href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd" target="_blank">Redux DevTools</a> to see how the state changes.
</p>
</template>
import { inject } from 'aurelia-framework';
import { ApplicationStore } from 'store';
import { GameActions } from 'actions';
@inject(ApplicationStore, GameActions)
export class App {
rockCount = 0;
paperCount = 0;
scissorsCount = 0;
// the ApplicationStore and GameActions dependencies are injected
constructor(store, gameActions){
this.store = store;
this.gameActions = gameActions;
this.message = "Let's Play";
// subscribe to the store's state changes
this.unsubscribe = this.store.subscribe(() => {
this.update();
});
this.update();
}
// unsubscribe from state changes when this view is deactivated
deactivate() {
this.unsubscribe();
}
// get the game data from the state when it changes
// and update our view model data
update() {
let state = this.store.getState();
this.rockCount = state.game.rock;
this.paperCount = state.game.paper;
this.scissorsCount = state.game.scissors;
}
// play button click handler
// dispatches the game make choice action
play() {
this.store.dispatch(this.gameActions.makeChoice());
}
}
<template>
<div class="col card text-center border ${borderColor}">
<div class="card-body" mouseover.delegate="mouseover()" mouseout.delegate="mouseout()">
<h4 class="card-title">${title} <i class="fa ${iconClass}"></i></h4>
<p class="card-text display-3">${count}</p>
</div>
</div>
</template>
import { bindable } from 'aurelia-framework';
export class CardCustomElement {
@bindable title = "";
@bindable iconClass = "";
@bindable count = null;
borderColor = '';
mouseover() {
this.borderColor = 'border-success';
}
mouseout() {
this.borderColor = '';
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
rel="stylesheet" >
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.min.js" integrity="sha256-Y8AuGIYFWCOBO5/w1oXzcEErW4JALGUWiG5VWleVWyw=" crossorigin="anonymous"></script>
<script src="https://freshcutdevelopment.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://freshcutdevelopment.github.io/rjs-bundle/config.js"></script>
<script src="https://freshcutdevelopment.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://freshcutdevelopment.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
export function configure(aurelia) {
aurelia.use.basicConfiguration();
aurelia.start().then(() => aurelia.setRoot());
}
const { combineReducers } = Redux; // import { combineReducers } from 'redux';
const initialGameState = {
rock: 0,
paper: 0,
scissors: 0
};
function game(state = initialGameState, action) {
switch (action.type) {
case 'GAME_ROCK':
return Object.assign({}, state, {
rock: state.rock + 1
});
case 'GAME_PAPER':
return Object.assign({}, state, {
paper: state.paper + 1
});
case 'GAME_SCISSORS':
return Object.assign({}, state, {
scissors: state.scissors + 1
});
default:
return state;
}
}
const reducer = combineReducers({
game
});
export default reducer;
import reducer from 'reducer';
const { createStore } = Redux; // import {createStore} from 'redux';
// just a simple wrapper around the redux store
export class ApplicationStore {
constructor() {
this.store = this._configureStore();
}
dispatch(action) {
return this.store.dispatch(action);
}
getState() {
return this.store.getState();
}
subscribe(listener) {
return this.store.subscribe(listener);
}
_configureStore() {
return createStore(reducer, {}, window.devToolsExtension ? window.devToolsExtension() : undefined);
}
}
export class ShowThreeValueConverter {
toView(value) {
return (parseInt(value) === 3) ? 'three' : value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment