question begin

This commit is contained in:
Antti Pilto 2016-08-01 00:33:36 +03:00
parent 27dcb4dd6d
commit 7f3d4781ea
13 changed files with 283 additions and 32 deletions

View file

@ -12,7 +12,7 @@ class App extends Component {
super(props); super(props);
this.state = { this.state = {
isAuthenticated: this.isAuthenticated(), isAuthenticated: this.isAuthenticated(),
gameState: 'chooseCharacters' gameState: 'game'
/*profile: auth.getProfile()*/ /*profile: auth.getProfile()*/
} }
auth.on('profile_updated', (newProfile) => { auth.on('profile_updated', (newProfile) => {

View file

@ -8,17 +8,17 @@ class ChooseCharacters extends Component {
super(props); super(props);
this.state = { this.state = {
errMsg : '', errMsg : '',
selectedKana: ['h_group1'] selectedGroups: this.props.selectedGroups
} }
this.startGame = this.startGame.bind(this); this.startGame = this.startGame.bind(this);
this.showKanaRows = this.showKanaRows.bind(this); this.showGroupRows = this.showGroupRows.bind(this);
this.toggleSelect = this.toggleSelect.bind(this); this.toggleSelect = this.toggleSelect.bind(this);
this.selectAll = this.selectAll.bind(this); this.selectAll = this.selectAll.bind(this);
this.selectNone = this.selectNone.bind(this); this.selectNone = this.selectNone.bind(this);
} }
getIndex(groupName) { getIndex(groupName) {
return this.state.selectedKana.indexOf(groupName); return this.state.selectedGroups.indexOf(groupName);
} }
isSelected(groupName) { isSelected(groupName) {
@ -27,13 +27,13 @@ class ChooseCharacters extends Component {
removeSelect(groupName) { removeSelect(groupName) {
if(this.getIndex(groupName)<0) return; if(this.getIndex(groupName)<0) return;
let newSelectedKana = this.state.selectedKana.slice(); let newSelectedGroups = this.state.selectedGroups.slice();
newSelectedKana.splice(this.getIndex(groupName), 1); newSelectedGroups.splice(this.getIndex(groupName), 1);
this.setState({selectedKana: newSelectedKana}); this.setState({selectedGroups: newSelectedGroups});
} }
addSelect(groupName) { addSelect(groupName) {
this.setState({errMsg: '', selectedKana: this.state.selectedKana.concat(groupName)}); this.setState({errMsg: '', selectedGroups: this.state.selectedGroups.concat(groupName)});
} }
toggleSelect(groupName) { toggleSelect(groupName) {
@ -43,29 +43,29 @@ class ChooseCharacters extends Component {
selectAll(whichKana) { selectAll(whichKana) {
let thisKana = kanaDictionary[whichKana]; let thisKana = kanaDictionary[whichKana];
let newSelectedKana = this.state.selectedKana.slice(); let newSelectedGroups = this.state.selectedGroups.slice();
Object.keys(thisKana).map(function(groupName) { Object.keys(thisKana).map(function(groupName) {
if(!this.isSelected(groupName)) if(!this.isSelected(groupName))
newSelectedKana.push(groupName); newSelectedGroups.push(groupName);
}, this); }, this);
this.setState({errMsg: '', selectedKana: newSelectedKana}); this.setState({errMsg: '', selectedGroups: newSelectedGroups});
} }
selectNone(whichKana) { selectNone(whichKana) {
let newSelectedKana = []; let newSelectedGroups = [];
this.state.selectedKana.map(function(groupName) { this.state.selectedGroups.map(function(groupName) {
let mustBeRemoved = false; let mustBeRemoved = false;
Object.keys(kanaDictionary[whichKana]).map(function(removableGroupName) { Object.keys(kanaDictionary[whichKana]).map(function(removableGroupName) {
if(removableGroupName===groupName) if(removableGroupName===groupName)
mustBeRemoved = true; mustBeRemoved = true;
}, this); }, this);
if(!mustBeRemoved) if(!mustBeRemoved)
newSelectedKana.push(groupName); newSelectedGroups.push(groupName);
}, this); }, this);
this.setState({selectedKana: newSelectedKana}); this.setState({selectedGroups: newSelectedGroups});
} }
showKanaRows(whichKana) { showGroupRows(whichKana) {
let thisKana = kanaDictionary[whichKana]; let thisKana = kanaDictionary[whichKana];
return Object.keys(thisKana).map(function(groupName, idx) { return Object.keys(thisKana).map(function(groupName, idx) {
return ( return (
@ -81,11 +81,11 @@ class ChooseCharacters extends Component {
} }
startGame() { startGame() {
if(this.state.selectedKana.length < 1) { if(this.state.selectedGroups.length < 1) {
this.setState({ errMsg: 'Choose at least one group!'}); this.setState({ errMsg: 'Choose at least one group!'});
return; return;
} }
this.props.handleStartGame(this.state.selectedKana); this.props.handleStartGame(this.state.selectedGroups);
} }
render() { render() {
@ -104,9 +104,9 @@ class ChooseCharacters extends Component {
<div className="row"> <div className="row">
<div className="col-sm-6"> <div className="col-sm-6">
<div className="panel panel-default"> <div className="panel panel-default">
<div className="panel-heading">Hiragana <span className="pull-right">ひらがな</span></div> <div className="panel-heading">Hiragana · ひらがな<span className="pull-right">Progress</span></div>
<div className="panel-body selection-areas"> <div className="panel-body selection-areas">
{this.showKanaRows('hiragana')} {this.showGroupRows('hiragana')}
</div> </div>
<div className="panel-footer text-center"> <div className="panel-footer text-center">
<a href="javascript:;" onClick={()=>this.selectAll('hiragana')}>All</a> &nbsp;&middot;&nbsp; <a href="javascript:;" onClick={()=>this.selectNone('hiragana')}>None</a> <a href="javascript:;" onClick={()=>this.selectAll('hiragana')}>All</a> &nbsp;&middot;&nbsp; <a href="javascript:;" onClick={()=>this.selectNone('hiragana')}>None</a>
@ -115,9 +115,9 @@ class ChooseCharacters extends Component {
</div> </div>
<div className="col-sm-6"> <div className="col-sm-6">
<div className="panel panel-default"> <div className="panel panel-default">
<div className="panel-heading">Katakana <span className="pull-right">カタカナ</span></div> <div className="panel-heading">Katakana · カタカナ<span className="pull-right">Progress</span></div>
<div className="panel-body selection-areas"> <div className="panel-body selection-areas">
{this.showKanaRows('katakana')} {this.showGroupRows('katakana')}
</div> </div>
<div className="panel-footer text-center"> <div className="panel-footer text-center">
<a href="javascript:;" onClick={()=>this.selectAll('katakana')}>All</a> &nbsp;&middot;&nbsp; <a href="javascript:;" onClick={()=>this.selectNone('katakana')}>None</a> <a href="javascript:;" onClick={()=>this.selectAll('katakana')}>All</a> &nbsp;&middot;&nbsp; <a href="javascript:;" onClick={()=>this.selectNone('katakana')}>None</a>

View file

@ -11,6 +11,9 @@
.panel-heading { .panel-heading {
font-weight: bold; font-weight: bold;
} }
.panel-heading span {
color: #aaa;
}
.panel-footer a { .panel-footer a {
text-decoration: none; text-decoration: none;
color: #337ab7; color: #337ab7;
@ -18,7 +21,6 @@
.choose-row { .choose-row {
font-size: 1em; font-size: 1em;
padding: 5px; padding: 5px;
user-select: none;
} }
.choose-row:not(:last-child) { .choose-row:not(:last-child) {
border-bottom: 1px #eee solid; border-bottom: 1px #eee solid;

View file

@ -0,0 +1,40 @@
import React, { Component } from 'react';
import { kanaDictionary } from '../../data/kanaDictionary';
import './Game.scss';
import ShowStage from './ShowStage';
import Question from './Question';
class Game extends Component {
constructor(props) {
super(props);
this.state = {
stage: 0,
showScreen: ''
}
this.showQuestion = this.showQuestion.bind(this);
this.stageUp = this.stageUp.bind(this);
}
stageUp() {
this.setState({stage: this.state.stage+1, showScreen: 'stage'});
}
showQuestion() {
this.setState({showScreen: 'question'})
}
componentWillMount() {
this.stageUp();
}
render() {
return (
<div>
{ this.state.showScreen==='stage' ? <ShowStage handleShowQuestion={this.showQuestion} stage={this.state.stage} /> : '' }
{ this.state.showScreen==='question' ? <Question handleStageUp={this.stageUp} stage={this.state.stage} decidedGroups={this.props.decidedGroups} /> : '' }
</div>
);
}
}
export default Game;

View file

View file

@ -0,0 +1,102 @@
import React, { Component } from 'react';
import { kanaDictionary } from '../../data/kanaDictionary';
import { arrayContains, shuffle } from '../../data/helperFuncs';
import './Question.scss';
class Question extends Component {
constructor(props) {
super(props);
this.state = {
previousQuestion: {},
currentQuestion: ''
}
}
// getQuestionIndex(question) {
// return this.state.selectedGroups.indexOf(question);
// }
// removeSelect(groupName) {
// if(this.getQuestionIndex(groupName)<0) return;
// let newSelectedGroups = this.state.selectedGroups.slice();
// newSelectedGroups.splice(this.getIndex(groupName), 1);
// this.setState({selectedGroups: newSelectedGroups});
// }
getRandomKanas(amount) {
let randomizedKanas = [];
if(this.state.previousQuestion.length > 0)
removeFromAskable(this.state.previousQuestion);
shuffle(this.askableCharacterKeys);
for(let i = 0; i < amount; i++) {
randomizedKanas.push(this.askableCharacterKeys[i]);
}
return randomizedKanas;
// console.log(this.askableCharacters);
//return this.askableCharacterKeys[Math.floor(Math.random() * this.askableCharacterKeys.length)];
}
removeFromAskable(question) {
console.log('here');
//console.log(this.getQuestionIndex(question));
}
setNewQuestion() {
let question = this.getRandomKanas(1);
this.setState({currentQuestion: question[0]});
//console.log(question);
}
setAllowedAnswers() {
}
initializeCharacters() {
this.askableCharacters = {};
this.askableCharacterKeys = [];
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 askableCharacters
this.askableCharacters = Object.assign(this.askableCharacters, kanaDictionary[whichKana][groupName]['characters']);
Object.keys(kanaDictionary[whichKana][groupName]['characters']).map(function(key) {
// let's add all askable kana keys to array
this.askableCharacterKeys.push(key);
kanaDictionary[whichKana][groupName]['characters'][key].map(function(romaji) {
console.log(romaji);
}, this);
}, this);
}
}, this);
}, this);
// console.log(this.askableCharacters);
}
componentWillMount() {
}
componentDidMount() {
this.initializeCharacters();
this.setNewQuestion();
this.setAnswerOptions();
this.setAllowedAnswers();
}
render() {
return (
<div className="text-center question">
<div className="big-character">{this.state.currentQuestion}</div>
</div>
);
}
}
export default Question;

View file

@ -0,0 +1,6 @@
.question {
.big-character {
font-size: 5em;
}
margin-top: 70px;
}

View file

@ -0,0 +1,52 @@
import React, { Component } from 'react';
import './ShowStage.scss';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
class ShowStage extends Component {
constructor(props) {
super(props);
this.state = {
stageContent: ''
}
this.showStage = this.showStage.bind(this);
this.removeStage = this.removeStage.bind(this);
}
removeStage() {
this.setState({stageContent: ''});
clearTimeout(this.timeoutID);
this.timeoutID = setTimeout(this.props.handleShowQuestion, 1) // how soon we go to question (1000)
}
showStage() {
let stageDescription;
let stageSecondaryDescription = false;
if(this.props.stage===1) stageDescription = 'Choose one';
if(this.props.stage===2) { stageDescription = 'Choose one'; stageSecondaryDescription = 'Reverse'; }
if(this.props.stage===3) stageDescription = 'Write the answer';
if(this.props.stage===4) { stageDescription = 'Write the answer'; stageSecondaryDescription = 'Three at once'; }
let stageContent = <div><h1>Stage {this.props.stage}</h1><h3>{stageDescription}</h3>{stageSecondaryDescription?<h4>{stageSecondaryDescription}</h4>:''}</div>;
this.setState({stageContent: stageContent});
}
componentDidMount() {
this.timeoutID = setTimeout(this.removeStage, 1); // how soon we start fading out (1500)
this.showStage();
}
componentWillUnmount() {
clearTimeout(this.timeoutID);
}
render() {
return (
<div className="text-center show-stage">
<ReactCSSTransitionGroup transitionName="stage" transitionEnterTimeout={1000} transitionLeaveTimeout={1000}>
{this.state.stageContent}
</ReactCSSTransitionGroup>
</div>
);
}
}
export default ShowStage;

View file

@ -0,0 +1,24 @@
.show-stage {
margin-top: 200px;
h3 {
margin-top: 30px;
}
}
.stage-enter {
opacity: 0.01;
}
.stage-enter.stage-enter-active {
opacity: 1;
transition: opacity 1s ease-in;
}
.stage-leave {
opacity: 1;
}
.stage-leave.stage-leave-active {
opacity: 0.01;
transition: opacity 1s ease-in;
}

View file

@ -1,24 +1,34 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { kanaDictionary } from '../../data/kanaDictionary'; import { kanaDictionary } from '../../data/kanaDictionary';
import ChooseCharacters from '../ChooseCharacters/ChooseCharacters'; import ChooseCharacters from '../ChooseCharacters/ChooseCharacters';
import Game from '../Game/Game';
class GameContainer extends Component { class GameContainer extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.startGame = this.startGame.bind(this); this.startGame = this.startGame.bind(this);
this.state = {
decidedGroups: ['h_group1', 'h_group2']
}
} }
startGame(options) { startGame(decidedGroups) {
// console.log(options); // prints array // console.log(options); // prints array
this.setState({decidedGroups: decidedGroups});
this.props.handleStartGame(); this.props.handleStartGame();
} }
render() { render() {
let currentScreen = this.props.gameState==='chooseCharacters' ? <ChooseCharacters handleStartGame={this.startGame} nickName={this.props.nickName} /> :
(this.props.gameState==='game' ? '<Game />' : '');
return ( return (
<div> <div>
{currentScreen} { this.props.gameState==='chooseCharacters' ?
<ChooseCharacters selectedGroups={this.state.decidedGroups}
handleStartGame={this.startGame}
nickName={this.props.nickName}
/> : '' }
{ this.props.gameState==='game' ?
<Game decidedGroups={this.state.decidedGroups}
/> : '' }
</div> </div>
) )
} }

View file

@ -7,7 +7,7 @@ class Navbar extends Component {
switch(this.props.gameState) { switch(this.props.gameState) {
case 'chooseCharacters': case 'chooseCharacters':
default: default:
leftLink = <li id="nav-kanaquiz"><a href="javascript:;">Kana Quiz <span>2</span></a></li> leftLink = <li id="nav-kanaquiz"><p className="nav navbar-text">Kana Quiz <span>2</span></p></li>
break; break;
case 'game': case 'game':
leftLink = <li id="nav-choosecharacters"><a href="#" onClick={this.props.handleEndGame}><span className="glyphicon glyphicon-small glyphicon-arrow-left"></span> Back to menu</a></li> leftLink = <li id="nav-choosecharacters"><a href="#" onClick={this.props.handleEndGame}><span className="glyphicon glyphicon-small glyphicon-arrow-left"></span> Back to menu</a></li>

View file

@ -17,11 +17,10 @@
.nav a:hover { .nav a:hover {
color: #bbb !important; color: #bbb !important;
} }
#nav-kanaquiz a, #nav-kanaquiz { .navbar-text {
color: #fff !important; color: #fff !important;
span { cursor: default;
color: #fff !important; margin-bottom: 0;
}
} }
#nav-kanaquiz a:hover { #nav-kanaquiz a:hover {
cursor: default; cursor: default;

16
src/data/helperFuncs.js Normal file
View file

@ -0,0 +1,16 @@
export function arrayContains(needle, arrhaystack) {
return (arrhaystack.indexOf(needle) > -1);
}
export function shuffle(array) {
var i = 0
, j = 0
, temp = null
for (i = array.length - 1; i > 0; i -= 1) {
j = Math.floor(Math.random() * (i + 1))
temp = array[i]
array[i] = array[j]
array[j] = temp
}
}