diff --git a/README.md b/README.md index 84b6820..15d3f43 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Kana Quiz 2 +# Kana Quiz Kana Quiz made with React.js. See live at https://kana.pro/ @@ -8,4 +8,4 @@ Install deps: `npm install` Development: `npm start` -Production: `npm run build` \ No newline at end of file +Production: `npm run build` diff --git a/package.json b/package.json index 7a42d96..39bc666 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "homepage": "https://github.com/anzzstuff/kanaquiz#readme", "browserslist": [ - "> 0.25%", + ">0.25%", "not dead" ], "devDependencies": { diff --git a/src/components/App/App.jsx b/src/components/App/App.jsx index fa34a2b..c5a3eec 100644 --- a/src/components/App/App.jsx +++ b/src/components/App/App.jsx @@ -7,57 +7,50 @@ import { removeHash } from '../../data/helperFuncs'; const options = {}; class App extends Component { - constructor(props) { - super(props); - this.state = { - gameState: 'chooseCharacters' - } - this.startGame = this.startGame.bind(this); - this.endGame = this.endGame.bind(this); - } + state = { gameState: 'chooseCharacters' }; - startGame() { - this.setState({gameState: 'game'}); - } + startGame = () => { + this.setState({gameState: 'game'}); + } - endGame() { - this.setState({gameState: 'chooseCharacters'}); - } + endGame = () => { + this.setState({gameState: 'chooseCharacters'}); + } - componentWillUpdate(nextProps, nextState) { - // This is primarily for demo site purposes. Hides #footer when game is on. - if(document.getElementById('footer')) { - if(nextState.gameState=='chooseCharacters') - document.getElementById('footer').style.display = "block"; - else - document.getElementById('footer').style.display = "none"; - } + componentWillUpdate(nextProps, nextState) { + // This is primarily for demo site purposes. Hides #footer when game is on. + if(document.getElementById('footer')) { + if(nextState.gameState=='chooseCharacters') + document.getElementById('footer').style.display = "block"; + else + document.getElementById('footer').style.display = "none"; } + } - componentWillMount() { - if(document.getElementById('footer')) - document.getElementById('footer').style.display = "block"; - } + componentWillMount() { + if(document.getElementById('footer')) + document.getElementById('footer').style.display = "block"; + } - render() { - return ( -
- -
-
- -
-
-
- ) - } + render() { + return ( +
+ +
+
+ +
+
+
+ ) + } } -export default App; \ No newline at end of file +export default App; diff --git a/src/components/App/App.scss b/src/components/App/App.scss index 9c6fb85..810244d 100644 --- a/src/components/App/App.scss +++ b/src/components/App/App.scss @@ -1,41 +1,41 @@ html { - height: 100%; /* height sets are for android chrome background fix */ - min-height: 100%; + height: 100%; /* height sets are for android chrome background fix */ + min-height: 100%; } body { - min-height: 100%; - font-family: "Trebuchet MS","Lucida Grande","Lucida Sans Unicode","Lucida Sans",Tahoma,sans-serif; - background-color: #e5e5e5; - color: #111; + min-height: 100%; + font-family: "Trebuchet MS","Lucida Grande","Lucida Sans Unicode","Lucida Sans",Tahoma,sans-serif; + background-color: #e5e5e5; + color: #111; } .outercontainer { - background-color: #f5f5f5; - padding-bottom: 20px; - border-bottom: 1px #dadada solid; - min-height: 500px; /* 690 */ - @media (max-width: 768px) { - min-height: auto; - } + background-color: #f5f5f5; + padding-bottom: 20px; + border-bottom: 1px #dadada solid; + min-height: 500px; /* 690 */ + @media (max-width: 768px) { + min-height: auto; + } } .container { - margin: 0 auto; - max-width: 968px; + margin: 0 auto; + max-width: 968px; } .row { - margin: 0; + margin: 0; } .login-button { - font-size: 1.3em; - margin-top: 15px; - margin-bottom: 0; - a { - color: #888; - } + font-size: 1.3em; + margin-top: 15px; + margin-bottom: 0; + a { + color: #888; + } } .game { - padding-top: 70px; + padding-top: 70px; } .glyphicon-none:before { - content: "\2122"; - color: transparent !important; -} \ No newline at end of file + content: "\2122"; + color: transparent !important; +} diff --git a/src/components/ChooseCharacters/CharacterGroup.jsx b/src/components/ChooseCharacters/CharacterGroup.jsx index 5ded6a0..2bd3180 100644 --- a/src/components/ChooseCharacters/CharacterGroup.jsx +++ b/src/components/ChooseCharacters/CharacterGroup.jsx @@ -1,55 +1,50 @@ import React, { Component } from 'react'; class CharacterGroup extends Component { - constructor(props) { - super(props); - this.state = { - shownChars : '', - } - this.changeShownChars = this.changeShownChars.bind(this); - } + state = { shownChars: '' } - changeShownChars(newString, e) { - this.setState({shownChars: newString}) - } + changeShownChars(newString) { + this.setState({shownChars: newString}) + } - getShowableCharacters(whichKana) { - let strRomajiCharacters = ''; - let strKanaCharacters = ''; - Object.keys(this.props.characters).map(function(character) { - strRomajiCharacters+=this.props.characters[character][0]+' · '; - strKanaCharacters+=character+' · '; - }, this); - strRomajiCharacters = strRomajiCharacters.slice(0, -2); - strKanaCharacters = strKanaCharacters.slice(0, -2); - if(whichKana=='romaji') return strRomajiCharacters; - else return strKanaCharacters; - } + getShowableCharacters(whichKana) { + let strRomajiCharacters = ''; + let strKanaCharacters = ''; + Object.keys(this.props.characters).map(character => { + strRomajiCharacters+=this.props.characters[character][0]+' · '; + strKanaCharacters+=character+' · '; + }); + strRomajiCharacters = strRomajiCharacters.slice(0, -2); + strKanaCharacters = strKanaCharacters.slice(0, -2); + if(whichKana=='romaji') return strRomajiCharacters; + else return strKanaCharacters; + } - componentWillMount() { + componentWillMount() { + this.changeShownChars(this.getShowableCharacters('romaji')); + } + + render() { + return ( +
{ + this.props.handleToggleSelect(this.props.groupName); this.changeShownChars(this.getShowableCharacters('romaji')); - } - - render() { - return ( -
{ - this.props.handleToggleSelect(this.props.groupName); - this.changeShownChars(this.getShowableCharacters('romaji')); - }} - onMouseDown={()=>this.changeShownChars(this.getShowableCharacters('kana'))} - onMouseOut={()=>this.changeShownChars(this.getShowableCharacters('romaji'))} - onTouchStart={()=>this.changeShownChars(this.getShowableCharacters('kana'))} - onTouchEnd={()=>this.changeShownChars(this.getShowableCharacters('romaji'))} - > - {this.state.shownChars} -
- ); - } + }} + onMouseDown={()=>this.changeShownChars(this.getShowableCharacters('kana'))} + onMouseOut={()=>this.changeShownChars(this.getShowableCharacters('romaji'))} + onTouchStart={()=>this.changeShownChars(this.getShowableCharacters('kana'))} + onTouchEnd={()=>this.changeShownChars(this.getShowableCharacters('romaji'))} + > + {this.state.shownChars} +
+ ); + } } export default CharacterGroup; diff --git a/src/components/ChooseCharacters/ChooseCharacters.jsx b/src/components/ChooseCharacters/ChooseCharacters.jsx index 901c063..9a784ce 100644 --- a/src/components/ChooseCharacters/ChooseCharacters.jsx +++ b/src/components/ChooseCharacters/ChooseCharacters.jsx @@ -5,279 +5,273 @@ import './ChooseCharacters.scss'; import CharacterGroup from './CharacterGroup'; class ChooseCharacters extends Component { - constructor(props) { - super(props); - this.state = { - errMsg : '', - selectedGroups: this.props.selectedGroups, - showAlternatives: [], - showSimilars: [], - startIsVisible: true - } - this.toggleSelect = this.toggleSelect.bind(this); - this.startGame = this.startGame.bind(this); - this.testIsStartVisible = this.testIsStartVisible.bind(this); + state = { + errMsg : '', + selectedGroups: this.props.selectedGroups, + showAlternatives: [], + showSimilars: [], + startIsVisible: true + } + + componentDidMount() { + this.testIsStartVisible(); + window.addEventListener('resize', this.testIsStartVisible); + window.addEventListener('scroll', this.testIsStartVisible); + } + + componentWillUnmount() { + window.removeEventListener('resize', this.testIsStartVisible); + window.removeEventListener('scroll', this.testIsStartVisible); + } + + componentDidUpdate(prevProps, prevState) { + this.testIsStartVisible(); + } + + testIsStartVisible = () => { + if(this.startRef) { + const rect = this.startRef.getBoundingClientRect(); + if(rect.y > window.innerHeight && this.state.startIsVisible) + this.setState({ startIsVisible: false }); + else if(rect.y <= window.innerHeight && !this.state.startIsVisible) + this.setState({ startIsVisible: true }); } + } - componentDidMount() { - this.testIsStartVisible(); - window.addEventListener('resize', this.testIsStartVisible); - window.addEventListener('scroll', this.testIsStartVisible); + scrollToStart() { + if(this.startRef) { + const rect = this.startRef.getBoundingClientRect(); + const absTop = rect.top + window.pageYOffset; + const scrollPos = absTop - window.innerHeight + 50; + window.scrollTo(0, scrollPos > 0 ? scrollPos : 0); } + } - componentWillUnmount() { - window.removeEventListener('resize', this.testIsStartVisible); - window.removeEventListener('scroll', this.testIsStartVisible); + getIndex(groupName) { + return this.state.selectedGroups.indexOf(groupName); + } + + isSelected(groupName) { + return this.getIndex(groupName) > -1 ? true : false; + } + + removeSelect(groupName) { + if(this.getIndex(groupName)<0) + return; + let newSelectedGroups = this.state.selectedGroups.slice(); + newSelectedGroups.splice(this.getIndex(groupName), 1); + this.setState({selectedGroups: newSelectedGroups}); + } + + addSelect(groupName) { + this.setState({errMsg: '', selectedGroups: this.state.selectedGroups.concat(groupName)}); + } + + toggleSelect = groupName => { + if(this.getIndex(groupName) > -1) + this.removeSelect(groupName); + else + this.addSelect(groupName); + } + + selectAll(whichKana, altOnly=false, similarOnly=false) { + const thisKana = kanaDictionary[whichKana]; + let newSelectedGroups = this.state.selectedGroups.slice(); + Object.keys(thisKana).forEach(groupName => { + if(!this.isSelected(groupName) && ( + (altOnly && groupName.endsWith('_a')) || + (similarOnly && groupName.endsWith('_s')) || + (!altOnly && !similarOnly) + )) + newSelectedGroups.push(groupName); + }); + this.setState({errMsg: '', selectedGroups: newSelectedGroups}); + } + + selectNone(whichKana, altOnly=false, similarOnly=false) { + let newSelectedGroups = []; + this.state.selectedGroups.forEach(groupName => { + let mustBeRemoved = false; + Object.keys(kanaDictionary[whichKana]).forEach(removableGroupName => { + if(removableGroupName === groupName && ( + (altOnly && groupName.endsWith('_a')) || + (similarOnly && groupName.endsWith('_s')) || + (!altOnly && !similarOnly) + )) + mustBeRemoved = true; + }); + if(!mustBeRemoved) + newSelectedGroups.push(groupName); + }); + this.setState({selectedGroups: newSelectedGroups}); + } + + toggleAlternative(whichKana, postfix) { + let show = postfix == '_a' ? this.state.showAlternatives : this.state.showSimilars; + const idx = show.indexOf(whichKana); + if(idx >= 0) + show.splice(idx, 1); + else + show.push(whichKana) + if(postfix == '_a') + this.setState({showAlternatives: show}); + if(postfix == '_s') + this.setState({showSimilars: show}); + } + + getSelectedAlternatives(whichKana, postfix) { + return this.state.selectedGroups.filter(groupName => { + return groupName.startsWith(whichKana == 'hiragana' ? 'h_' : 'k_') && + groupName.endsWith(postfix); + }).length; + } + + getAmountOfAlternatives(whichKana, postfix) { + return Object.keys(kanaDictionary[whichKana]).filter(groupName => { + return groupName.endsWith(postfix); + }).length; + } + + alternativeToggleRow(whichKana, postfix, show) { + let checkBtn = "glyphicon glyphicon-small glyphicon-" + let status; + if(this.getSelectedAlternatives(whichKana, postfix) >= this.getAmountOfAlternatives(whichKana, postfix)) + status = 'check'; + else if(this.getSelectedAlternatives(whichKana, postfix) > 0) + status = 'check half'; + else + status = 'unchecked' + checkBtn += status + + return
this.toggleAlternative(whichKana, postfix)} + className="choose-row" + > + { + if(status == 'check') + this.selectNone(whichKana, postfix == '_a', postfix == '_s'); + else if(status == 'check half' || status == 'unchecked') + this.selectAll(whichKana, postfix == '_a', postfix == '_s'); + e.stopPropagation(); + }} + > + { + show ? + : + } + { + postfix == '_a' ? 'Alternative characters (ga · ba · kya..)' : + 'Look-alike characters' + } +
+ } + + showGroupRows(whichKana, showAlternatives, showSimilars = false) { + const thisKana = kanaDictionary[whichKana]; + let rows = []; + Object.keys(thisKana).forEach((groupName, idx) => { + if(groupName == "h_group11_a" || groupName == "k_group13_a") + rows.push(this.alternativeToggleRow(whichKana, "_a", showAlternatives)); + if(groupName == "k_group11_s") + rows.push(this.alternativeToggleRow(whichKana, "_s", showSimilars)); + + if((!groupName.endsWith("a") || showAlternatives) && + (!groupName.endsWith("s") || showSimilars)) { + rows.push(); + } + }); + + return rows; + } + + startGame() { + if(this.state.selectedGroups.length < 1) { + this.setState({ errMsg: 'Choose at least one group!'}); + return; } + this.props.handleStartGame(this.state.selectedGroups); + } - componentDidUpdate(prevProps, prevState) { - this.testIsStartVisible(); - } - - testIsStartVisible() { - if(this.startRef) { - const rect = this.startRef.getBoundingClientRect(); - if(rect.y > window.innerHeight && this.state.startIsVisible) - this.setState({ startIsVisible: false }); - else if(rect.y <= window.innerHeight && !this.state.startIsVisible) - this.setState({ startIsVisible: true }); - } - } - - scrollToStart() { - if(this.startRef) { - const rect = this.startRef.getBoundingClientRect(); - const absTop = rect.top + window.pageYOffset; - const scrollPos = absTop - window.innerHeight + 50; - window.scrollTo(0, scrollPos > 0 ? scrollPos : 0); - } - } - - getIndex(groupName) { - return this.state.selectedGroups.indexOf(groupName); - } - - isSelected(groupName) { - return this.getIndex(groupName) > -1 ? true : false; - } - - removeSelect(groupName) { - if(this.getIndex(groupName)<0) - return; - let newSelectedGroups = this.state.selectedGroups.slice(); - newSelectedGroups.splice(this.getIndex(groupName), 1); - this.setState({selectedGroups: newSelectedGroups}); - } - - addSelect(groupName) { - this.setState({errMsg: '', selectedGroups: this.state.selectedGroups.concat(groupName)}); - } - - toggleSelect(groupName) { - if(this.getIndex(groupName) > -1) - this.removeSelect(groupName); - else - this.addSelect(groupName); - } - - selectAll(whichKana, altOnly=false, similarOnly=false) { - const thisKana = kanaDictionary[whichKana]; - let newSelectedGroups = this.state.selectedGroups.slice(); - Object.keys(thisKana).forEach(groupName => { - if(!this.isSelected(groupName) && ( - (altOnly && groupName.endsWith('_a')) || - (similarOnly && groupName.endsWith('_s')) || - (!altOnly && !similarOnly) - )) - newSelectedGroups.push(groupName); - }); - this.setState({errMsg: '', selectedGroups: newSelectedGroups}); - } - - selectNone(whichKana, altOnly=false, similarOnly=false) { - let newSelectedGroups = []; - this.state.selectedGroups.forEach(groupName => { - let mustBeRemoved = false; - Object.keys(kanaDictionary[whichKana]).forEach(removableGroupName => { - if(removableGroupName === groupName && ( - (altOnly && groupName.endsWith('_a')) || - (similarOnly && groupName.endsWith('_s')) || - (!altOnly && !similarOnly) - )) - mustBeRemoved = true; - }); - if(!mustBeRemoved) - newSelectedGroups.push(groupName); - }); - this.setState({selectedGroups: newSelectedGroups}); - } - - toggleAlternative(whichKana, postfix) { - let show = postfix == '_a' ? this.state.showAlternatives : this.state.showSimilars; - const idx = show.indexOf(whichKana); - if(idx >= 0) - show.splice(idx, 1); - else - show.push(whichKana) - if(postfix == '_a') - this.setState({showAlternatives: show}); - if(postfix == '_s') - this.setState({showSimilars: show}); - } - - getSelectedAlternatives(whichKana, postfix) { - return this.state.selectedGroups.filter(groupName => { - return groupName.startsWith(whichKana == 'hiragana' ? 'h_' : 'k_') && - groupName.endsWith(postfix); - }).length; - } - - getAmountOfAlternatives(whichKana, postfix) { - return Object.keys(kanaDictionary[whichKana]).filter(groupName => { - return groupName.endsWith(postfix); - }).length; - } - - alternativeToggleRow(whichKana, postfix, show) { - let checkBtn = "glyphicon glyphicon-small glyphicon-" - let status; - if(this.getSelectedAlternatives(whichKana, postfix) >= this.getAmountOfAlternatives(whichKana, postfix)) - status = 'check'; - else if(this.getSelectedAlternatives(whichKana, postfix) > 0) - status = 'check half'; - else - status = 'unchecked' - checkBtn += status - - return
this.toggleAlternative(whichKana, postfix)} - className="choose-row" - > - { - if(status == 'check') - this.selectNone(whichKana, postfix == '_a', postfix == '_s'); - else if(status == 'check half' || status == 'unchecked') - this.selectAll(whichKana, postfix == '_a', postfix == '_s'); - e.stopPropagation(); - }} - > - { - show ? - : - } - { - postfix == '_a' ? 'Alternative characters (ga · ba · kya..)' : - 'Look-alike characters' - } -
- } - - showGroupRows(whichKana, showAlternatives, showSimilars = false) { - const thisKana = kanaDictionary[whichKana]; - let rows = []; - Object.keys(thisKana).forEach((groupName, idx) => { - if(groupName == "h_group11_a" || groupName == "k_group13_a") - rows.push(this.alternativeToggleRow(whichKana, "_a", showAlternatives)); - if(groupName == "k_group11_s") - rows.push(this.alternativeToggleRow(whichKana, "_s", showSimilars)); - - if((!groupName.endsWith("a") || showAlternatives) && - (!groupName.endsWith("s") || showSimilars)) { - rows.push(); - } - }); - - return rows; - } - - startGame() { - if(this.state.selectedGroups.length < 1) { - this.setState({ errMsg: 'Choose at least one group!'}); - return; - } - this.props.handleStartGame(this.state.selectedGroups); - } - - render() { - return ( -
-
-
-
-
-

Welcome to Kana Quiz!

-

Please choose the groups of characters that you'd like to be studying.

-
-
-
-
-
-
-
-
Hiragana · ひらがな
-
- {this.showGroupRows('hiragana', this.state.showAlternatives.indexOf('hiragana') >= 0)} -
- -
-
-
-
-
Katakana · カタカナ
-
- {this.showGroupRows('katakana', this.state.showAlternatives.indexOf('katakana') >= 0, this.state.showSimilars.indexOf('katakana') >= 0)} -
- -
-
-
- Lock to stage   - { - this.props.isLocked && - this.props.lockStage(e.target.value, true)} - value={this.props.stage} - /> - } - this.props.lockStage(1)} on={this.props.isLocked} /> -
-
- { - this.state.errMsg != '' && -
{this.state.errMsg}
- } - -
-
this.scrollToStart(e)} - > - Start -
-
+ render() { + return ( +
+
+
+
+
+

Welcome to Kana Pro!

+

Please choose the groups of characters that you'd like to be studying.

+
- ); - } +
+
+
+
+
+
Hiragana · ひらがな
+
+ {this.showGroupRows('hiragana', this.state.showAlternatives.indexOf('hiragana') >= 0)} +
+ +
+
+
+
+
Katakana · カタカナ
+
+ {this.showGroupRows('katakana', this.state.showAlternatives.indexOf('katakana') >= 0, this.state.showSimilars.indexOf('katakana') >= 0)} +
+ +
+
+
+ Lock to stage   + { + this.props.isLocked && + this.props.lockStage(e.target.value, true)} + value={this.props.stage} + /> + } + this.props.lockStage(1)} on={this.props.isLocked} /> +
+
+ { + this.state.errMsg != '' && +
{this.state.errMsg}
+ } + +
+
this.scrollToStart(e)} + > + Start +
+
+
+ ); + } } export default ChooseCharacters; diff --git a/src/components/ChooseCharacters/ChooseCharacters.scss b/src/components/ChooseCharacters/ChooseCharacters.scss index f6b0a64..cff1d26 100644 --- a/src/components/ChooseCharacters/ChooseCharacters.scss +++ b/src/components/ChooseCharacters/ChooseCharacters.scss @@ -1,143 +1,143 @@ .welcome { - p:last-child { - margin-bottom: 0; - } - h4 { - margin-top: 0; - } + p:last-child { + margin-bottom: 0; + } + h4 { + margin-top: 0; + } } .choose-characters { - .panel-heading { - font-weight: bold; - } - .panel-heading span { - color: #aaa; - } - .panel-footer a { - text-decoration: none; - color: #337ab7; - } - .choose-row { - font-size: 1em; - padding: 5px; - } - .choose-row:not(:last-child) { - border-bottom: 1px #eee solid; - } - .alt-row { - padding-left: 20px; - background-color: #fafafa; - } - .toggle-caret { - margin: 0 4px; - } - @media (min-width: 768px) { - .choose-row:hover { - background-color: #f4f4f4; - } - } + .panel-heading { + font-weight: bold; + } + .panel-heading span { + color: #aaa; + } + .panel-footer a { + text-decoration: none; + color: #337ab7; + } + .choose-row { + font-size: 1em; + padding: 5px; + } + .choose-row:not(:last-child) { + border-bottom: 1px #eee solid; + } + .alt-row { + padding-left: 20px; + background-color: #fafafa; + } + .toggle-caret { + margin: 0 4px; + } + @media (min-width: 768px) { .choose-row:hover { - cursor: pointer; - } - .glyphicon { - font-size: 0.9em; - } - .glyphicon-check { - color: green; - } - .glyphicon-check.half { - color: #ccc; - } - .glyphicon-unchecked { - color: #ccc; - } - .selection-areas { - padding: 7px; - } - .success-percent { - color: #ccc; + background-color: #f4f4f4; } + } + .choose-row:hover { + cursor: pointer; + } + .glyphicon { + font-size: 0.9em; + } + .glyphicon-check { + color: green; + } + .glyphicon-check.half { + color: #ccc; + } + .glyphicon-unchecked { + color: #ccc; + } + .selection-areas { + padding: 7px; + } + .success-percent { + color: #ccc; + } } .error-message { - color: #d9534f; - padding-bottom: 10px; + color: #d9534f; + padding-bottom: 10px; } .lock { - color: #888; - margin-bottom: 10px; + color: #888; + margin-bottom: 10px; } .stage-choice { - border: 1px solid #999; - padding-left: 5px; - border-radius: 5px; - margin-right: 5px; - outline: none; + border: 1px solid #999; + padding-left: 5px; + border-radius: 5px; + margin-right: 5px; + outline: none; } .switch { - border: 1px solid #ccc; - background: #e5e5e5; - width: 44px; - height: 19px; - border-radius: 13px; - cursor: pointer; - display: block; - float: right; - margin-top: 1px; + border: 1px solid #ccc; + background: #e5e5e5; + width: 44px; + height: 19px; + border-radius: 13px; + cursor: pointer; + display: block; + float: right; + margin-top: 1px; } .switch-toggle { - border: 1px solid #999; - box-shadow: 1px 1px 1px #ccc; - width: 19px; - height: 17px; - left: 0; - border-radius: 12px; - background: #eee; - position: relative; - transition: left .2s ease-in-out; + border: 1px solid #999; + box-shadow: 1px 1px 1px #ccc; + width: 19px; + height: 17px; + left: 0; + border-radius: 12px; + background: #eee; + position: relative; + transition: left .2s ease-in-out; } .switch.on { - border: 1px solid #4da94f; - background: #5cb85c; + border: 1px solid #4da94f; + background: #5cb85c; } .switch.on .switch-toggle { - left: 23px; - border: 1px solid #b8ffb2; - background: #b8ffb2; + left: 23px; + border: 1px solid #b8ffb2; + background: #b8ffb2; } .switch.disabled { - cursor: not-allowed; + cursor: not-allowed; } .down-arrow { - user-select: none; - cursor: pointer; - border-radius: 4px 4px 0 0; - display: block; - position: fixed; - bottom: 20px; - right: 12px; - color: #fff; - background: #d9534f; - padding: 7px 0 2px; - width: 60px; - text-align: center; + user-select: none; + cursor: pointer; + border-radius: 4px 4px 0 0; + display: block; + position: fixed; + bottom: 20px; + right: 12px; + color: #fff; + background: #d9534f; + padding: 7px 0 2px; + width: 60px; + text-align: center; } .down-arrow:after { - content: ''; - display: block; - position: absolute; - left: 0; - top: 100%; - width: 0; - height: 0; - border-top: 10px solid #d9534f; - border-right: 30px solid transparent; - border-bottom: 0 solid transparent; - border-left: 30px solid transparent; + content: ''; + display: block; + position: absolute; + left: 0; + top: 100%; + width: 0; + height: 0; + border-top: 10px solid #d9534f; + border-right: 30px solid transparent; + border-bottom: 0 solid transparent; + border-left: 30px solid transparent; } diff --git a/src/components/Game/Game.jsx b/src/components/Game/Game.jsx index 1f413c0..9ce5bc9 100644 --- a/src/components/Game/Game.jsx +++ b/src/components/Game/Game.jsx @@ -4,42 +4,40 @@ import ShowStage from './ShowStage'; import Question from './Question'; class Game extends Component { - constructor(props) { - super(props); - this.state = { - showScreen: '' + state = { showScreen: '' } + + componentWillMount() { + this.setState({showScreen: 'stage'}); + } + + stageUp = () => { + this.props.stageUp(); + this.setState({showScreen: 'stage'}); + } + + lockStage = stage => { + this.setState({showScreen: 'question'}); + this.props.lockStage(stage); + } + + showQuestion = () => { + this.setState({showScreen: 'question'}) + } + + render() { + return ( +
+ { + this.state.showScreen==='stage' && + } - this.showQuestion = this.showQuestion.bind(this); - this.stageUp = this.stageUp.bind(this); - this.lockStage = this.lockStage.bind(this); - } - - stageUp() { - this.props.stageUp(); - this.setState({showScreen: 'stage'}); - } - - lockStage(stage) { - this.setState({showScreen: 'question'}); - this.props.lockStage(stage); - } - - showQuestion() { - this.setState({showScreen: 'question'}) - } - - componentWillMount() { - this.setState({showScreen: 'stage'}); - } - - render() { - return ( -
- { this.state.showScreen==='stage' ? : '' } - { this.state.showScreen==='question' ? : '' } -
- ); - } + { + this.state.showScreen==='question' && + + } +
+ ); + } } -export default Game; \ No newline at end of file +export default Game; diff --git a/src/components/Game/Question.jsx b/src/components/Game/Question.jsx index 7264596..3d67aa0 100644 --- a/src/components/Game/Question.jsx +++ b/src/components/Game/Question.jsx @@ -5,264 +5,272 @@ import { findRomajisAtKanaKey, removeFromArray, arrayContains, shuffle, cartesia import './Question.scss'; class Question extends Component { - constructor(props) { - super(props); - this.state = { - previousQuestion: [], - previousAnswer: '', - currentAnswer: '', - currentQuestion: [], - answerOptions: [], - stageProgress: 0 + state = { + previousQuestion: [], + previousAnswer: '', + currentAnswer: '', + currentQuestion: [], + answerOptions: [], + stageProgress: 0 + } + // this.setNewQuestion = this.setNewQuestion.bind(this); + // this.handleAnswer = this.handleAnswer.bind(this); + // this.handleAnswerChange = this.handleAnswerChange.bind(this); + // this.handleSubmit = this.handleSubmit.bind(this); + // } + + getRandomKanas(amount, include, exclude) { + let randomizedKanas = this.askableKanaKeys.slice(); + + if(exclude && exclude.length > 0) { + // we're excluding previous question when deciding a new question + randomizedKanas = removeFromArray(exclude, randomizedKanas); + } + + if(include && include.length > 0) { + // we arrive here when we're deciding answer options (included = currentQuestion) + + // remove included kana + randomizedKanas = removeFromArray(include, randomizedKanas); + shuffle(randomizedKanas); + + // cut the size to make looping quicker + randomizedKanas = randomizedKanas.slice(0,20); + + // let's remove kanas that have the same answer as included + let searchFor = findRomajisAtKanaKey(include, kanaDictionary)[0]; + randomizedKanas = randomizedKanas.filter(character => { + return searchFor!=findRomajisAtKanaKey(character, kanaDictionary)[0]; + }); + + // now let's remove "duplicate" kanas (if two kanas have same answers) + let tempRandomizedKanas = randomizedKanas.slice(); + randomizedKanas = randomizedKanas.filter(r => { + let dupeFound = false; + searchFor = findRomajisAtKanaKey(r, kanaDictionary)[0]; + tempRandomizedKanas.shift(); + tempRandomizedKanas.forEach(w => { + if(findRomajisAtKanaKey(w, kanaDictionary)[0]==searchFor) + dupeFound = true; + }); + return !dupeFound; + }); + + // alright, let's cut the array and add included to the end + randomizedKanas = randomizedKanas.slice(0, amount-1); // -1 so we have room to add included + randomizedKanas.push(include); + shuffle(randomizedKanas); + } + else { + shuffle(randomizedKanas); + randomizedKanas = randomizedKanas.slice(0, amount); + } + return randomizedKanas; + } + + setNewQuestion() { + if(this.props.stage!=4) + this.currentQuestion = this.getRandomKanas(1, false, this.previousQuestion); + else + this.currentQuestion = this.getRandomKanas(3, false, this.previousQuestion); + this.setState({currentQuestion: this.currentQuestion}); + this.setAnswerOptions(); + this.setAllowedAnswers(); + // console.log(this.currentQuestion); + } + + setAnswerOptions() { + this.answerOptions = this.getRandomKanas(3, this.currentQuestion[0], false); + this.setState({answerOptions: this.answerOptions}); + // console.log(this.answerOptions); + } + + setAllowedAnswers() { + // console.log(this.currentQuestion); + this.allowedAnswers = []; + if(this.props.stage==1 || this.props.stage==3) + this.allowedAnswers = findRomajisAtKanaKey(this.currentQuestion, kanaDictionary); + else if(this.props.stage==2) + this.allowedAnswers = this.currentQuestion; + else if(this.props.stage==4) { + let tempAllowedAnswers = []; + + this.currentQuestion.forEach(key => { + tempAllowedAnswers.push(findRomajisAtKanaKey(key, kanaDictionary)); + }); + + cartesianProduct(tempAllowedAnswers).forEach(answer => { + this.allowedAnswers.push(answer.join('')); + }); + } + // console.log(this.allowedAnswers); + } + + handleAnswer = answer => { + if(this.props.stage<=2) document.activeElement.blur(); // reset answer button's :active + this.previousQuestion = this.currentQuestion; + this.setState({previousQuestion: this.previousQuestion}); + this.previousAnswer = answer; + this.setState({previousAnswer: this.previousAnswer}); + this.previousAllowedAnswers = this.allowedAnswers; + if(this.isInAllowedAnswers(this.previousAnswer)) + this.stageProgress = this.stageProgress+1; + else + this.stageProgress = this.stageProgress > 0 ? this.stageProgress - 1 : 0; + this.setState({stageProgress: this.stageProgress}); + if(this.stageProgress >= quizSettings.stageLength[this.props.stage] && !this.props.isLocked) { + setTimeout(() => { this.props.handleStageUp() }, 300); + } + else + this.setNewQuestion(); + } + + initializeCharacters() { + this.askableKanas = {}; + this.askableKanaKeys = []; + this.askableRomajis = []; + this.previousQuestion = ''; + this.previousAnswer = ''; + this.stageProgress = 0; + Object.keys(kanaDictionary).forEach(whichKana => { + // console.log(whichKana); // 'hiragana' or 'katakana' + Object.keys(kanaDictionary[whichKana]).forEach(groupName => { + // console.log(groupName); // 'h_group1', ... + // do we want to include this group? + if(arrayContains(groupName, this.props.decidedGroups)) { + // let's merge the group to our askableKanas + this.askableKanas = Object.assign(this.askableKanas, kanaDictionary[whichKana][groupName]['characters']); + Object.keys(kanaDictionary[whichKana][groupName]['characters']).forEach(key => { + // let's add all askable kana keys to array + this.askableKanaKeys.push(key); + this.askableRomajis.push(kanaDictionary[whichKana][groupName]['characters'][key][0]); + }); } - this.setNewQuestion = this.setNewQuestion.bind(this); - this.handleAnswer = this.handleAnswer.bind(this); - this.handleAnswerChange = this.handleAnswerChange.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - } + }); + }); + // console.log(this.askableKanas); + } - getRandomKanas(amount, include, exclude) { - let randomizedKanas = this.askableKanaKeys.slice(); + getAnswerType() { + if(this.props.stage==2) return 'kana'; + else return 'romaji'; + } - if(exclude && exclude.length > 0) { - // we're excluding previous question when deciding a new question - randomizedKanas = removeFromArray(exclude, randomizedKanas); - } - - if(include && include.length > 0) { - // we arrive here when we're deciding answer options (included = currentQuestion) - - // remove included kana - randomizedKanas = removeFromArray(include, randomizedKanas); - shuffle(randomizedKanas); + getShowableQuestion() { + if(this.getAnswerType()=='kana') + return findRomajisAtKanaKey(this.state.currentQuestion, kanaDictionary)[0]; + else return this.state.currentQuestion; + } - // cut the size to make looping quicker - randomizedKanas = randomizedKanas.slice(0,20); + getPreviousResult() { + let resultString=''; + // console.log(this.previousAnswer); + if(this.previousQuestion=='') + resultString =
Let's go! Which character is this?
+ else { + let rightAnswer = ( + this.props.stage==2 ? + findRomajisAtKanaKey(this.previousQuestion, kanaDictionary)[0] + : this.previousQuestion.join('') + )+' = '+ this.previousAllowedAnswers[0]; - // let's remove kanas that have the same answer as included - let searchFor = findRomajisAtKanaKey(include, kanaDictionary)[0]; - randomizedKanas = randomizedKanas.filter(function(character) { - return searchFor!=findRomajisAtKanaKey(character, kanaDictionary)[0]; - }, this); - - // now let's remove "duplicate" kanas (if two kanas have same answers) - let tempRandomizedKanas = randomizedKanas.slice(); - randomizedKanas = randomizedKanas.filter(function(r) { - let dupeFound = false; - searchFor = findRomajisAtKanaKey(r, kanaDictionary)[0]; - tempRandomizedKanas.shift(); - tempRandomizedKanas.map(function(w) { - if(findRomajisAtKanaKey(w, kanaDictionary)[0]==searchFor) - dupeFound = true; - }, this); - return !dupeFound; - }, this); - - // alright, let's cut the array and add included to the end - randomizedKanas = randomizedKanas.slice(0, amount-1); // -1 so we have room to add included - randomizedKanas.push(include); - shuffle(randomizedKanas); - } - else { - shuffle(randomizedKanas); - randomizedKanas = randomizedKanas.slice(0, amount); - } - return randomizedKanas; - } - - setNewQuestion() { - if(this.props.stage!=4) - this.currentQuestion = this.getRandomKanas(1, false, this.previousQuestion); - else - this.currentQuestion = this.getRandomKanas(3, false, this.previousQuestion); - this.setState({currentQuestion: this.currentQuestion}); - this.setAnswerOptions(); - this.setAllowedAnswers(); - // console.log(this.currentQuestion); - } - - setAnswerOptions() { - this.answerOptions = this.getRandomKanas(3, this.currentQuestion[0], false); - this.setState({answerOptions: this.answerOptions}); - // console.log(this.answerOptions); - } - - setAllowedAnswers() { - // console.log(this.currentQuestion); - this.allowedAnswers = []; - if(this.props.stage==1 || this.props.stage==3) - this.allowedAnswers = findRomajisAtKanaKey(this.currentQuestion, kanaDictionary); - else if(this.props.stage==2) - this.allowedAnswers = this.currentQuestion; - else if(this.props.stage==4) { - let tempAllowedAnswers = []; - - this.currentQuestion.map(function(key, idx) { - tempAllowedAnswers.push(findRomajisAtKanaKey(key, kanaDictionary)); - }, this); - - cartesianProduct(tempAllowedAnswers).map(function(answer) { - this.allowedAnswers.push(answer.join('')); - }, this); - } - // console.log(this.allowedAnswers); - } - - handleAnswer(answer) { - if(this.props.stage<=2) document.activeElement.blur(); // reset answer button's :active - this.previousQuestion = this.currentQuestion; - this.setState({previousQuestion: this.previousQuestion}); - this.previousAnswer = answer; - this.setState({previousAnswer: this.previousAnswer}); - this.previousAllowedAnswers = this.allowedAnswers; - if(this.isInAllowedAnswers(this.previousAnswer)) - this.stageProgress = this.stageProgress+1; - else - this.stageProgress = this.stageProgress > 0 ? this.stageProgress - 1 : 0; - this.setState({stageProgress: this.stageProgress}); - if(this.stageProgress >= quizSettings.stageLength[this.props.stage] && - !this.props.isLocked) { - let that = this; - setTimeout(function() { that.props.handleStageUp(); }, 300); - } - else - this.setNewQuestion(); - } - - initializeCharacters() { - this.askableKanas = {}; - this.askableKanaKeys = []; - this.askableRomajis = []; - this.previousQuestion = ''; - this.previousAnswer = ''; - this.stageProgress = 0; - Object.keys(kanaDictionary).map(function(whichKana) { - // console.log(whichKana); // 'hiragana' or 'katakana' - Object.keys(kanaDictionary[whichKana]).map(function(groupName) { - // console.log(groupName); // 'h_group1', ... - // do we want to include this group? - if(arrayContains(groupName, this.props.decidedGroups)) { - // let's merge the group to our askableKanas - this.askableKanas = Object.assign(this.askableKanas, kanaDictionary[whichKana][groupName]['characters']); - Object.keys(kanaDictionary[whichKana][groupName]['characters']).map(function(key) { - // let's add all askable kana keys to array - this.askableKanaKeys.push(key); - this.askableRomajis.push(kanaDictionary[whichKana][groupName]['characters'][key][0]); - }, this); - } - }, this); - }, this); - // console.log(this.askableKanas); - } - - getAnswerType() { - if(this.props.stage==2) return 'kana'; - else return 'romaji'; - } - - getShowableQuestion() { - if(this.getAnswerType()=='kana') - return findRomajisAtKanaKey(this.state.currentQuestion, kanaDictionary)[0]; - else return this.state.currentQuestion; - } - - getPreviousResult() { - let resultString=''; - // console.log(this.previousAnswer); - if(this.previousQuestion=='') - resultString =
Let's go! Which character is this?
- else { - let rightAnswer = (this.props.stage==2?findRomajisAtKanaKey(this.previousQuestion, kanaDictionary)[0]:this.previousQuestion.join(''))+' = '+ - this.previousAllowedAnswers[0]; - if(this.isInAllowedAnswers(this.previousAnswer)) - resultString =
{rightAnswer}
- else - resultString =
{rightAnswer}
- } - return resultString; - } - - isInAllowedAnswers(previousAnswer) { - // console.log(previousAnswer); - // console.log(this.allowedAnswers); - if(arrayContains(previousAnswer, this.previousAllowedAnswers)) - return true; - else return false; - } - - handleAnswerChange(e) { - this.setState({currentAnswer: e.target.value.replace(/\s+/g, '')}); - } - - handleSubmit(e) { - e.preventDefault(); - if(this.state.currentAnswer!='') { - this.handleAnswer(this.state.currentAnswer.toLowerCase()); - this.setState({currentAnswer: ''}); - } - } - - componentWillMount() { - this.initializeCharacters(); - } - - componentDidMount() { - this.setNewQuestion(); - } - - render() { - let btnClass = "btn btn-default answer-button"; - if ('ontouchstart' in window) - btnClass += " no-hover"; // disables hover effect on touch screens - let stageProgressPercentage = Math.round((this.state.stageProgress/quizSettings.stageLength[this.props.stage])*100)+'%'; - let stageProgressPercentageStyle = { width: stageProgressPercentage } - return ( -
- {this.getPreviousResult()} -
{this.getShowableQuestion()}
-
- {this.props.stage<3?this.state.answerOptions.map(function(answer, idx) { - return - }, this): -
-
- -
-
- } -
-
-
- Stage {this.props.stage} {this.props.isLocked?' (Locked)':''} -
-
-
+ if(this.isInAllowedAnswers(this.previousAnswer)) + resultString = ( +
+ {rightAnswer} +
+ ); + else + resultString = ( +
+ {rightAnswer} +
); } + return resultString; + } + + isInAllowedAnswers(previousAnswer) { + // console.log(previousAnswer); + // console.log(this.allowedAnswers); + if(arrayContains(previousAnswer, this.previousAllowedAnswers)) + return true; + else return false; + } + + handleAnswerChange = e => { + this.setState({currentAnswer: e.target.value.replace(/\s+/g, '')}); + } + + handleSubmit = e => { + e.preventDefault(); + if(this.state.currentAnswer!='') { + this.handleAnswer(this.state.currentAnswer.toLowerCase()); + this.setState({currentAnswer: ''}); + } + } + + componentWillMount() { + this.initializeCharacters(); + } + + componentDidMount() { + this.setNewQuestion(); + } + + render() { + let btnClass = "btn btn-default answer-button"; + if ('ontouchstart' in window) + btnClass += " no-hover"; // disables hover effect on touch screens + let stageProgressPercentage = Math.round((this.state.stageProgress/quizSettings.stageLength[this.props.stage])*100)+'%'; + let stageProgressPercentageStyle = { width: stageProgressPercentage } + return ( +
+ {this.getPreviousResult()} +
{this.getShowableQuestion()}
+
+ {this.props.stage<3?this.state.answerOptions.map(function(answer, idx) { + return + }, this): +
+
+ +
+
+ } +
+
+
+ Stage {this.props.stage} {this.props.isLocked?' (Locked)':''} +
+
+
+ ); + } } class AnswerButton extends Component { - getShowableAnswer() { - if(this.props.answertype=='romaji') - return findRomajisAtKanaKey(this.props.answer, kanaDictionary)[0]; - else return this.props.answer; - } + getShowableAnswer() { + if(this.props.answertype=='romaji') + return findRomajisAtKanaKey(this.props.answer, kanaDictionary)[0]; + else return this.props.answer; + } - render() { - return ( - - ); - } + render() { + return ( + + ); + } } -export default Question; \ No newline at end of file +export default Question; diff --git a/src/components/Game/Question.scss b/src/components/Game/Question.scss index 825c0f9..8e1ad62 100644 --- a/src/components/Game/Question.scss +++ b/src/components/Game/Question.scss @@ -1,87 +1,87 @@ .question { - .progress { - position: relative; - background-color: #ddd; - height: 30px; - @media (max-width: 768px) { - max-width: 360px; - margin: 0 auto; - } + .progress { + position: relative; + background-color: #ddd; + height: 30px; + @media (max-width: 768px) { + max-width: 360px; + margin: 0 auto; } - .progress span { - position: absolute; - top: 5px; - color: #444; - display: block; - width: 100%; + } + .progress span { + position: absolute; + top: 5px; + color: #444; + display: block; + width: 100%; + } + .previous-result{ + max-width: 360px; + padding: 8px; + margin: 30px auto 28px; + border-radius: 3px; + @media (max-width: 768px) { + margin: 0px auto 0px; } - .previous-result{ - max-width: 360px; - padding: 8px; - margin: 30px auto 28px; - border-radius: 3px; - @media (max-width: 768px) { - margin: 0px auto 0px; - } + } + .size-up { + font-size: 1.1em; + } + .none { + background-color: #aaa; + color: #f5f5f5; + } + .correct { + color: #f5f5f5; + background-color: #5cb85c; + } + .wrong { + color: #f5f5f5; + background-color: #d9534f; + } + .previous-result-none { + max-width: 360px; + padding: 6px; + margin: 30px auto; + color: #f5f5f5; + } + .big-character { + font-size: 5em; + } + .answer-container { + max-width: 360px; + margin: 0 auto; + display: flex; + justify-content: space-between; + } + .answer-form-container { + max-width: 100px; + margin: 0 auto; + } + .answer-button { + min-width: 90px; + font-size: 2em; + margin: 30px 0 60px; + @media (max-width: 768px) { + margin: 0px 0 15px; } - .size-up { - font-size: 1.1em; + } + .answer-input, .answer-input:focus { + outline: none; + width: 110px; + text-align: center; + font-size: 2em; + margin: 25px 0 60px; + background: none; + border: none; + border-bottom: solid 1px #aaa; + @media (max-width: 768px) { + margin: 0px 0 25px; } - .none { - background-color: #aaa; - color: #f5f5f5; - } - .correct { - color: #f5f5f5; - background-color: #5cb85c; - } - .wrong { - color: #f5f5f5; - background-color: #d9534f; - } - .previous-result-none { - max-width: 360px; - padding: 6px; - margin: 30px auto; - color: #f5f5f5; - } - .big-character { - font-size: 5em; - } - .answer-container { - max-width: 360px; - margin: 0 auto; - display: flex; - justify-content: space-between; - } - .answer-form-container { - max-width: 100px; - margin: 0 auto; - } - .answer-button { - min-width: 90px; - font-size: 2em; - margin: 30px 0 60px; - @media (max-width: 768px) { - margin: 0px 0 15px; - } - } - .answer-input, .answer-input:focus { - outline: none; - width: 110px; - text-align: center; - font-size: 2em; - margin: 25px 0 60px; - background: none; - border: none; - border-bottom: solid 1px #aaa; - @media (max-width: 768px) { - margin: 0px 0 25px; - } - } - .no-hover { - /* disables hover effect on touch screens */ - background-color: #fff; - border-color: #ccc; - } -} \ No newline at end of file + } + .no-hover { + /* disables hover effect on touch screens */ + background-color: #fff; + border-color: #ccc; + } +} diff --git a/src/components/GameContainer/GameContainer.jsx b/src/components/GameContainer/GameContainer.jsx index 779a6c3..fee51a7 100644 --- a/src/components/GameContainer/GameContainer.jsx +++ b/src/components/GameContainer/GameContainer.jsx @@ -4,66 +4,63 @@ import ChooseCharacters from '../ChooseCharacters/ChooseCharacters'; import Game from '../Game/Game'; class GameContainer extends Component { - constructor(props) { - super(props); - this.startGame = this.startGame.bind(this); - this.state = { - stage:1, - isLocked: false, - decidedGroups: ['h_group1'] - } - this.stageUp = this.stageUp.bind(this); - this.lockStage = this.lockStage.bind(this); - } + state = { + stage:1, + isLocked: false, + decidedGroups: JSON.parse(localStorage.getItem('decidedGroups') || null) || [] + } - startGame(decidedGroups) { - if(parseInt(this.state.stage)<1 || isNaN(parseInt(this.state.stage))) - this.setState({stage: 1}); - else if(parseInt(this.state.stage)>4) - this.setState({stage: 4}); + componentWillReceiveProps() { + if(!this.state.isLocked) + this.setState({stage: 1}); + } - this.setState({decidedGroups: decidedGroups}); - this.props.handleStartGame(); - } + startGame = decidedGroups => { + if(parseInt(this.state.stage)<1 || isNaN(parseInt(this.state.stage))) + this.setState({stage: 1}); + else if(parseInt(this.state.stage)>4) + this.setState({stage: 4}); - stageUp() { - this.setState({stage: this.state.stage+1}); - } + this.setState({decidedGroups: decidedGroups}); + localStorage.setItem('decidedGroups', JSON.stringify(decidedGroups)); + this.props.handleStartGame(); + } - lockStage(stage, forceLock) { - // if(stage<1 || stage>4) stage=1; // don't use this to allow backspace - if(forceLock) - this.setState({stage: stage, isLocked: true}); - else - this.setState({stage: stage, isLocked: !this.state.isLocked}); - } + stageUp = () => { + this.setState({stage: this.state.stage+1}); + } - componentWillReceiveProps() { - if(!this.state.isLocked) - this.setState({stage: 1}); - } + lockStage = (stage, forceLock) => { + // if(stage<1 || stage>4) stage=1; // don't use this to allow backspace + if(forceLock) + this.setState({stage: stage, isLocked: true}); + else + this.setState({stage: stage, isLocked: !this.state.isLocked}); + } - render() { - return ( -
- { this.props.gameState==='chooseCharacters' ? - : '' } - { this.props.gameState==='game' ? - : '' } -
- ) - } + render() { + return ( +
+ { this.props.gameState==='chooseCharacters' && + + } + { this.props.gameState==='game' && + + } +
+ ) + } } -export default GameContainer; \ No newline at end of file +export default GameContainer; diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx index 7e9da98..4dd5905 100644 --- a/src/components/Navbar/Navbar.jsx +++ b/src/components/Navbar/Navbar.jsx @@ -2,28 +2,27 @@ import React, { Component } from 'react'; import './Navbar.scss'; class Navbar extends Component { - render() { - let leftLink; - switch(this.props.gameState) { - case 'chooseCharacters': - default: - leftLink = - break; - case 'game': - leftLink = - } - return ( - - ) - } + render() { + return ( + + ) + } } -export default Navbar; \ No newline at end of file +export default Navbar; diff --git a/src/components/Navbar/Navbar.scss b/src/components/Navbar/Navbar.scss index 04ef8c6..dd071be 100644 --- a/src/components/Navbar/Navbar.scss +++ b/src/components/Navbar/Navbar.scss @@ -1,15 +1,15 @@ #navbar ul li { - font-size: 1.2em; - @media (max-width: 768px) { - font-size: 1.0em; - } - .glyphicon { - font-size: 0.9em; - color: #d9534f; - } + font-size: 1.2em; + @media (max-width: 768px) { + font-size: 1.0em; + } + .glyphicon { + font-size: 0.9em; + color: #d9534f; + } } .navbar-inverse { - background-color: #333; + background-color: #333; } .hidden-nano { @media (max-width: 390px) { @@ -88,7 +88,7 @@ border-width: 0 1px 1px; border-radius: 0 0 4px 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); - box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); } .navbar-default .navbar-nav .open .dropdown-menu > li > a { color: #333; @@ -106,4 +106,4 @@ .navbar .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #999 !important; background-color: transparent !important; -} \ No newline at end of file +} diff --git a/src/index.html b/src/index.html index fcf6fcd..abc1050 100644 --- a/src/index.html +++ b/src/index.html @@ -1,13 +1,13 @@ - Kana Quiz 2: Learn hiragana & katakana fast and easy + Kana Pro: Learn hiragana & katakana fast and easy -
+
- \ No newline at end of file + diff --git a/src/index.js b/src/index.js index e91090e..e80d34f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,10 @@ import React from 'react'; -import { render } from 'react-dom'; +import ReactDOM from 'react-dom'; import Bootstrap from './assets/stylesheets/bootstrap.min.css'; import App from './components/App/App'; -let element = React.createElement(App, {}); -render(element, document.querySelector('.app')); +let appEl = document.getElementById('app'); +if(!appEl) // in case of old index.html in cache + appEl = document.querySelector('.app'); + +ReactDOM.render(, appEl);