From 3c9ea427d8e6f7f932ffc8fedc2d8fd5562307a5 Mon Sep 17 00:00:00 2001 From: Daniel Sinn Date: Tue, 26 Nov 2019 02:37:06 -0500 Subject: [PATCH] Implement keypads module in React --- index.html | 5 - ktane.js | 48 ------- {keypads => public/keypads}/ae.png | Bin {keypads => public/keypads}/at.png | Bin {keypads => public/keypads}/balloon.png | Bin {keypads => public/keypads}/bt.png | Bin {keypads => public/keypads}/copyright.png | Bin {keypads => public/keypads}/cursive.png | Bin {keypads => public/keypads}/doublek.png | Bin {keypads => public/keypads}/dragon.png | Bin {keypads => public/keypads}/euro.png | Bin {keypads => public/keypads}/filledstar.png | Bin {keypads => public/keypads}/hollowstar.png | Bin {keypads => public/keypads}/hookn.png | Bin {keypads => public/keypads}/leftc.png | Bin {keypads => public/keypads}/meltedthree.png | Bin {keypads => public/keypads}/nwithhat.png | Bin {keypads => public/keypads}/omega.png | Bin {keypads => public/keypads}/paragraph.png | Bin {keypads => public/keypads}/pitchfork.png | Bin {keypads => public/keypads}/pumpkin.png | Bin {keypads => public/keypads}/questionmark.png | Bin {keypads => public/keypads}/rightc.png | Bin {keypads => public/keypads}/six.png | Bin {keypads => public/keypads}/smileyface.png | Bin {keypads => public/keypads}/squidknife.png | Bin {keypads => public/keypads}/squigglyn.png | Bin {keypads => public/keypads}/tracks.png | Bin {keypads => public/keypads}/upsidedowny.png | Bin src/App.css | 26 ---- src/App.js | 2 + src/components/ButtonModule.js | 4 +- src/components/KeypadsModule.js | 137 +++++++++++++++++++ src/components/KtaneModule.js | 10 +- src/components/ResetButton.js | 13 ++ src/components/WiresModule.js | 4 +- src/css/KeypadsModule.css | 21 +++ src/css/ResetButton.css | 3 + 38 files changed, 188 insertions(+), 85 deletions(-) rename {keypads => public/keypads}/ae.png (100%) rename {keypads => public/keypads}/at.png (100%) rename {keypads => public/keypads}/balloon.png (100%) rename {keypads => public/keypads}/bt.png (100%) rename {keypads => public/keypads}/copyright.png (100%) rename {keypads => public/keypads}/cursive.png (100%) rename {keypads => public/keypads}/doublek.png (100%) rename {keypads => public/keypads}/dragon.png (100%) rename {keypads => public/keypads}/euro.png (100%) rename {keypads => public/keypads}/filledstar.png (100%) rename {keypads => public/keypads}/hollowstar.png (100%) rename {keypads => public/keypads}/hookn.png (100%) rename {keypads => public/keypads}/leftc.png (100%) rename {keypads => public/keypads}/meltedthree.png (100%) rename {keypads => public/keypads}/nwithhat.png (100%) rename {keypads => public/keypads}/omega.png (100%) rename {keypads => public/keypads}/paragraph.png (100%) rename {keypads => public/keypads}/pitchfork.png (100%) rename {keypads => public/keypads}/pumpkin.png (100%) rename {keypads => public/keypads}/questionmark.png (100%) rename {keypads => public/keypads}/rightc.png (100%) rename {keypads => public/keypads}/six.png (100%) rename {keypads => public/keypads}/smileyface.png (100%) rename {keypads => public/keypads}/squidknife.png (100%) rename {keypads => public/keypads}/squigglyn.png (100%) rename {keypads => public/keypads}/tracks.png (100%) rename {keypads => public/keypads}/upsidedowny.png (100%) create mode 100644 src/components/KeypadsModule.js create mode 100644 src/components/ResetButton.js create mode 100644 src/css/KeypadsModule.css create mode 100644 src/css/ResetButton.css diff --git a/index.html b/index.html index 41aad9b..294d04f 100755 --- a/index.html +++ b/index.html @@ -13,11 +13,6 @@

Keep Talking and Nobody Explodes

-
-

Keypads

- -
-

Simon Says

diff --git a/ktane.js b/ktane.js index ad9987b..63a0b21 100755 --- a/ktane.js +++ b/ktane.js @@ -39,54 +39,6 @@ $('section').each(function () { id && $('#navList').append($('
  • ').append($a)); }); -(function () { - /** - * Keypads - */ - var columns = [ - ['balloon', 'at', 'upsidedowny', 'squigglyn', 'squidknife', 'hookn', 'leftc'], - ['euro', 'balloon', 'leftc', 'cursive', 'hollowstar', 'hookn', 'questionmark'], - ['copyright', 'pumpkin', 'cursive', 'doublek', 'meltedthree', 'upsidedowny', 'hollowstar'], - ['six', 'paragraph', 'bt', 'squidknife', 'doublek', 'questionmark', 'smileyface'], - ['pitchfork', 'smileyface', 'bt', 'rightc', 'paragraph', 'dragon', 'filledstar'], - ['six', 'euro', 'tracks', 'ae', 'pitchfork', 'nwithhat', 'omega'] - ], - $section = $('#sectionKeypads'), - $imageLists = {}; // name -> $('')[] - - $.each(columns, function (i, column) { - var $column = $(''); - $section.append($column); - - $.each(column, function (i, name) { - var $img = $(''); - $column.append($('
  • ').append($img)); - - name in $imageLists - ? $imageLists[name].push($img) - : $imageLists[name] = [$img]; - }); - }); - - $section.on('click', 'img', function () { - var $img = $(this), - name = $img.data('name'), - endState = !$img.hasClass('selected'), - offset = endState ? 1 : -1; - - $.each($imageLists[name], function (i, $img) { - var $column = $img.parent().parent(); - $img.toggleClass('selected', endState); - $column.attr('data-count', parseInt($column.attr('data-count'), 10) + offset); - }); - }); - - $section.find('.jsResetSection').on('click', function () { - // Also need to reset the indices after removing .selected - $section.find('ul').attr('data-count', 0); - }); -})(); - (function () { /** * Simon diff --git a/keypads/ae.png b/public/keypads/ae.png similarity index 100% rename from keypads/ae.png rename to public/keypads/ae.png diff --git a/keypads/at.png b/public/keypads/at.png similarity index 100% rename from keypads/at.png rename to public/keypads/at.png diff --git a/keypads/balloon.png b/public/keypads/balloon.png similarity index 100% rename from keypads/balloon.png rename to public/keypads/balloon.png diff --git a/keypads/bt.png b/public/keypads/bt.png similarity index 100% rename from keypads/bt.png rename to public/keypads/bt.png diff --git a/keypads/copyright.png b/public/keypads/copyright.png similarity index 100% rename from keypads/copyright.png rename to public/keypads/copyright.png diff --git a/keypads/cursive.png b/public/keypads/cursive.png similarity index 100% rename from keypads/cursive.png rename to public/keypads/cursive.png diff --git a/keypads/doublek.png b/public/keypads/doublek.png similarity index 100% rename from keypads/doublek.png rename to public/keypads/doublek.png diff --git a/keypads/dragon.png b/public/keypads/dragon.png similarity index 100% rename from keypads/dragon.png rename to public/keypads/dragon.png diff --git a/keypads/euro.png b/public/keypads/euro.png similarity index 100% rename from keypads/euro.png rename to public/keypads/euro.png diff --git a/keypads/filledstar.png b/public/keypads/filledstar.png similarity index 100% rename from keypads/filledstar.png rename to public/keypads/filledstar.png diff --git a/keypads/hollowstar.png b/public/keypads/hollowstar.png similarity index 100% rename from keypads/hollowstar.png rename to public/keypads/hollowstar.png diff --git a/keypads/hookn.png b/public/keypads/hookn.png similarity index 100% rename from keypads/hookn.png rename to public/keypads/hookn.png diff --git a/keypads/leftc.png b/public/keypads/leftc.png similarity index 100% rename from keypads/leftc.png rename to public/keypads/leftc.png diff --git a/keypads/meltedthree.png b/public/keypads/meltedthree.png similarity index 100% rename from keypads/meltedthree.png rename to public/keypads/meltedthree.png diff --git a/keypads/nwithhat.png b/public/keypads/nwithhat.png similarity index 100% rename from keypads/nwithhat.png rename to public/keypads/nwithhat.png diff --git a/keypads/omega.png b/public/keypads/omega.png similarity index 100% rename from keypads/omega.png rename to public/keypads/omega.png diff --git a/keypads/paragraph.png b/public/keypads/paragraph.png similarity index 100% rename from keypads/paragraph.png rename to public/keypads/paragraph.png diff --git a/keypads/pitchfork.png b/public/keypads/pitchfork.png similarity index 100% rename from keypads/pitchfork.png rename to public/keypads/pitchfork.png diff --git a/keypads/pumpkin.png b/public/keypads/pumpkin.png similarity index 100% rename from keypads/pumpkin.png rename to public/keypads/pumpkin.png diff --git a/keypads/questionmark.png b/public/keypads/questionmark.png similarity index 100% rename from keypads/questionmark.png rename to public/keypads/questionmark.png diff --git a/keypads/rightc.png b/public/keypads/rightc.png similarity index 100% rename from keypads/rightc.png rename to public/keypads/rightc.png diff --git a/keypads/six.png b/public/keypads/six.png similarity index 100% rename from keypads/six.png rename to public/keypads/six.png diff --git a/keypads/smileyface.png b/public/keypads/smileyface.png similarity index 100% rename from keypads/smileyface.png rename to public/keypads/smileyface.png diff --git a/keypads/squidknife.png b/public/keypads/squidknife.png similarity index 100% rename from keypads/squidknife.png rename to public/keypads/squidknife.png diff --git a/keypads/squigglyn.png b/public/keypads/squigglyn.png similarity index 100% rename from keypads/squigglyn.png rename to public/keypads/squigglyn.png diff --git a/keypads/tracks.png b/public/keypads/tracks.png similarity index 100% rename from keypads/tracks.png rename to public/keypads/tracks.png diff --git a/keypads/upsidedowny.png b/public/keypads/upsidedowny.png similarity index 100% rename from keypads/upsidedowny.png rename to public/keypads/upsidedowny.png diff --git a/src/App.css b/src/App.css index 756bac5..b0381a2 100755 --- a/src/App.css +++ b/src/App.css @@ -93,10 +93,6 @@ h2 { margin: 0; } -.jsResetSection { - display: block; -} - nav { background-color: white; border-left: 1px solid black; @@ -112,28 +108,6 @@ nav { padding: 0.1em 0.5em; } -#sectionKeypads ul { - display: inline-block; - list-style-type: none; - margin-right: 2em; - padding-left: 0; -} -#sectionKeypads li { - border: 1px solid black; - border-bottom: 0; - cursor: pointer; - line-height: 0; -} -#sectionKeypads li:last-child { - border-bottom: 1px solid black; -} -#sectionKeypads .selected { - background-color: #ff6; -} -#sectionKeypads ul[data-count='4'] .selected { - background-color: lightgreen; -} - #simonInputs { float: left; margin-right: 5em; diff --git a/src/App.js b/src/App.js index d34ae6d..435656e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,7 @@ import React from 'react'; import './App.css'; import ButtonModule from "./components/ButtonModule"; +import KeypadsModule from "./components/KeypadsModule"; import WiresModule from "./components/WiresModule"; function App() { @@ -12,6 +13,7 @@ function App() { + ); } diff --git a/src/components/ButtonModule.js b/src/components/ButtonModule.js index bdebc95..992f8c6 100644 --- a/src/components/ButtonModule.js +++ b/src/components/ButtonModule.js @@ -94,9 +94,9 @@ export default class ButtonModule extends KtaneModule { ) } - resetState() { + getInitialState() { // @TODO Put string literals into constants - this.state = { + return { colour: "blue", text: "Abort" }; diff --git a/src/components/KeypadsModule.js b/src/components/KeypadsModule.js new file mode 100644 index 0000000..c7473c9 --- /dev/null +++ b/src/components/KeypadsModule.js @@ -0,0 +1,137 @@ +import KtaneModule from "./KtaneModule"; +import React from "react"; +import ResetButton from "./ResetButton"; +import "../css/KeypadsModule.css"; + +export default class KeypadsModule extends KtaneModule { + constructor(props) { + super(props); + + this.resetState = this.resetState.bind(this); + this.toggleHighlight = this.toggleHighlight.bind(this); + } + + computeKeyColumnMap() { + const map = {}; + + this.state.columns.forEach((column, index) => { + column.keys.forEach(key => { + if (!map.hasOwnProperty(key)) { + map[key] = []; + } + map[key].push(index); + }); + }); + + return map; + } + + getInitialState() { + return { + columns: [ + { + highlightCount: 0, + keys: ["balloon", "at", "upsidedowny", "squigglyn", "squidknife", "hookn", "leftc"] + }, + { + highlightCount: 0, + keys: ["euro", "balloon", "leftc", "cursive", "hollowstar", "hookn", "questionmark"] + }, + { + highlightCount: 0, + keys: ["copyright", "pumpkin", "cursive", "doublek", "meltedthree", "upsidedowny", "hollowstar"] + }, + { + highlightCount: 0, + keys: ["six", "paragraph", "bt", "squidknife", "doublek", "questionmark", "smileyface"] + }, + { + highlightCount: 0, + keys: ["pitchfork", "smileyface", "bt", "rightc", "paragraph", "dragon", "filledstar"] + }, + { + highlightCount: 0, + keys: ["six", "euro", "tracks", "ae", "pitchfork", "nwithhat", "omega"] + } + ], + highlights: { + ae: false, + at: false, + balloon: false, + bt: false, + copyright: false, + cursive: false, + doublek: false, + dragon: false, + euro: false, + filledstar: false, + hollowstar: false, + hookn: false, + leftc: false, + meltedthree: false, + paragraph: false, + pumpkin: false, + questionmark: false, + rightc: false, + six: false, + smileyface: false, + squidknife: false, + squigglyn: false, + upsidedowny: false + } + }; + } + + getTitle() { + return "Keypads"; + } + + mainRender() { + return ( + <> + + { + this.state.columns.map((column, index) => { + return
      + { + column.keys.map(key => { + return ( +
    • + {key} +
    • + ); + }) + } +
    ; + }) + } + + ) + } + + resetState() { + this.setState(this.getInitialState()); + } + + toggleHighlight(event) { + this.keyColumnMap = this.keyColumnMap || this.computeKeyColumnMap(); + + const key = event.currentTarget.dataset.key; + + this.setState(state => { + const step = state.highlights[key] ? -1 : 1; + + this.keyColumnMap[key].forEach(columnIndex => { + state.columns[columnIndex].highlightCount += step; + }); + + state.highlights[key] = !state.highlights[key]; + return state; + }); + } +} diff --git a/src/components/KtaneModule.js b/src/components/KtaneModule.js index 6d159c9..7c25208 100644 --- a/src/components/KtaneModule.js +++ b/src/components/KtaneModule.js @@ -5,7 +5,13 @@ class KtaneModule extends Component { constructor(props) { super(props); - this.resetState(); + this.state = this.getInitialState(); + + this.resetState = this.resetState.bind(this); + } + + getInitialState() { + throw new Error("getInitialState() not implemented."); } getTitle() { @@ -27,7 +33,7 @@ class KtaneModule extends Component { } resetState() { - throw new Error("mainRender() not implemented."); + this.setState(this.getInitialState()); } } diff --git a/src/components/ResetButton.js b/src/components/ResetButton.js new file mode 100644 index 0000000..844a7dc --- /dev/null +++ b/src/components/ResetButton.js @@ -0,0 +1,13 @@ +import PropTypes from "prop-types"; +import React, {Component} from "react"; +import "../css/ResetButton.css"; + +export default class ResetButton extends Component { + render() { + return ; + } +} + +ResetButton.propTypes = { + onClick: PropTypes.func +}; diff --git a/src/components/WiresModule.js b/src/components/WiresModule.js index f217996..8326281 100644 --- a/src/components/WiresModule.js +++ b/src/components/WiresModule.js @@ -174,8 +174,8 @@ export default class WiresModule extends KtaneModule { ) } - resetState() { - this.state = { + getInitialState() { + return { // @TODO Convert this.allColours to a constant that is available here, i.e., before the constructor's super call counts: ["red", "yellow", "blue", "white", "black"].reduce((counts, colour) => { counts[colour] = 0; diff --git a/src/css/KeypadsModule.css b/src/css/KeypadsModule.css new file mode 100644 index 0000000..84bc3d9 --- /dev/null +++ b/src/css/KeypadsModule.css @@ -0,0 +1,21 @@ +#sectionKeypads ul { + display: inline-block; + list-style-type: none; + margin-right: 2em; + padding-left: 0; +} +#sectionKeypads li { + border: 1px solid black; + border-bottom: 0; + cursor: pointer; + line-height: 0; +} +#sectionKeypads li:last-child { + border-bottom: 1px solid black; +} +#sectionKeypads .selected { + background-color: #ff6; +} +#sectionKeypads .matching .selected { + background-color: lightgreen; +} diff --git a/src/css/ResetButton.css b/src/css/ResetButton.css new file mode 100644 index 0000000..d9361d8 --- /dev/null +++ b/src/css/ResetButton.css @@ -0,0 +1,3 @@ +.jsResetSection { + display: block; +}