Skip to content

Commit

Permalink
FEATURE: Match scores
Browse files Browse the repository at this point in the history
Working match scores updates the decklist and scores views.
  • Loading branch information
diogosilverio committed Feb 3, 2018
1 parent 80f7e4b commit 646e220
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 63 deletions.
9 changes: 9 additions & 0 deletions actions/deck.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const LOAD_DECKS = "LOAD_DECKS";
export const NEW_DECK = "NEW_DECK";
export const DELETE_DECK = "DELETE_DECK";
export const UPDATE_DECK_SCORE = "UPDATE_DECK_SCORE";

export const ADD_CARD = "ADD_CARD";
export const DELETE_CARD = "DELETE_CARD";
Expand Down Expand Up @@ -40,4 +41,12 @@ export function deleteCard(deckKey, cardName){
deckKey,
cardName
}
}

export function updateDeckScore(deckKey, score){
return {
type: UPDATE_DECK_SCORE,
deckKey,
score
}
}
12 changes: 10 additions & 2 deletions actions/score.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
export const LOAD_SCORES = "LOAD_SCORE";
export const UPDATE_SCORE = "UPDATE_SCORE";

export function updateScore(scores){
export function loadScores(scores){
return {
type: UPDATE_SCORE,
type: LOAD_SCORES,
scores
}
}

export function updateScores(score){
return {
type: UPDATE_SCORE,
score
}
}
2 changes: 1 addition & 1 deletion components/flashcards/DeckList.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class DeckList extends Component {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Entypo size={75} name="emoji-sad" />
<Text>You have no registered decks.</Text>
<Text>You do not have registered decks.</Text>
<TouchableOpacity style={styles.btnAdd} onPress={this.navigateToNewDeck.bind(this)}>
<Text style={styles.text}>Add a new deck!</Text>
</TouchableOpacity>
Expand Down
6 changes: 5 additions & 1 deletion components/flashcards/Quiz.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { MaterialCommunityIcons } from '@expo/vector-icons';
import { saveScore } from '../../services';

import { COLOR_WHITE, COLOR_B_4, COLOR_A_1, COLOR_B_6, COLOR_SUCCESS, COLOR_BLACK, COLOR_FAILURE } from '../../utils/colors';
import { UPDATE_SCORE, updateScores } from '../../actions/score';
import { updateDeckScore } from '../../actions/deck';

const ANSWER = 'A';
const QUESTION = 'Q';
Expand Down Expand Up @@ -165,7 +167,9 @@ class Quiz extends Component {
const { navigation } = this.props;
const { deckKey } = navigation.state.params;

await saveScore(deckKey, status);
const result = await saveScore(deckKey, status);
this.props.dispatch(updateScores(result.lastScore));
this.props.dispatch(updateDeckScore(deckKey, result.deckScore));
Alert.alert(
title,
message,
Expand Down
93 changes: 37 additions & 56 deletions components/flashcards/Scores.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,59 @@
import React, { Component } from 'react';
import { Text, View, ScrollView, StyleSheet } from 'react-native';
import { Text, View, ScrollView, StyleSheet, ActivityIndicator, TouchableOpacity } from 'react-native';
import { connect } from 'react-redux';

import ScoreItem from '../ui/ScoreItem';

import { getScores } from '../../services';
import { loadScores } from '../../actions/score';

import { COLOR_B_1 } from '../../utils/colors';
import Entypo from '@expo/vector-icons/Entypo';

export default class Scores extends Component {
class Scores extends Component {

async componentDidMount() {
const scores = await getScores();
// console.log(scores);
this.props.dispatch(loadScores(scores));
}

render() {
return (
<ScrollView style={styles.container}>

<View style={styles.match}>
<View style={styles.resultContainer}>
<Text style={styles.resultText}>W</Text>
</View>
<View style={styles.statusContainer}>
<Text style={styles.statusText}>Deck 'A' @ 10/20/2017 19:22:40</Text>
</View>
const { scores } = this.props;

if (this.props.scores === null) {
return (
<View style={{ flex: 1, alignContent: 'center', justifyContent: 'center' }}>
<ActivityIndicator size={50} />
</View>
<View style={styles.match}>
<View style={styles.resultContainerL}>
<Text style={styles.resultText}>L</Text>
</View>
<View style={styles.statusContainer}>
<Text style={styles.statusText}>Deck 'A' @ 10/20/2017 19:22:40</Text>
</View>
);
} else if (scores.length === 0) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Entypo size={75} name="emoji-sad" />
<Text>You have no scores.</Text>
</View>

</ScrollView>
);
);
} else {
return (
<ScrollView style={styles.container}>
{scores.map(score => (<ScoreItem key={score.date} score={score} />))}
</ScrollView>
);
}
}
}

const styles = StyleSheet.create({
container: {
flex: 1
},
match: {
flex: 1,
flexDirection: 'row',
height: 64,
borderBottomWidth: 1,
borderBottomColor: COLOR_B_1
},
resultContainer: {
flex: 1,
backgroundColor: 'green',
alignItems: 'center',
justifyContent: 'center'
},
resultContainerL: {
flex: 1,
backgroundColor: 'red',
alignItems: 'center',
justifyContent: 'center'
},
resultText: {
color: 'white',
fontWeight: 'bold',
fontSize: 30
},
statusContainer: {
flex: 4,
alignItems: 'flex-start',
justifyContent: 'center',
paddingLeft: 5
},
statusText: {
fontSize: 17
}
});
});

function mapStateToProps({ scores }) {
return {
scores
}
}

export default connect(mapStateToProps)(Scores);
52 changes: 52 additions & 0 deletions components/ui/ScoreItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { Component } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { COLOR_B_1 } from '../../utils/colors';

export default class ScoreItem extends Component {

render() {

const { score } = this.props;
const scoreColor = score.status === 'L' ? 'red' : (score.status === 'W') ? 'green' : 'gray';

return (
<View style={styles.match}>
<View style={[styles.resultContainer, { backgroundColor: scoreColor }]}>
<Text style={styles.resultText}>{score.status}</Text>
</View>
<View style={styles.statusContainer}>
<Text style={styles.statusText}>Deck '{score.deck}' @ {new Date(score.date).toLocaleDateString()}</Text>
</View>
</View>
);
}
}

const styles = StyleSheet.create({
match: {
flex: 1,
flexDirection: 'row',
height: 64,
borderBottomWidth: 1,
borderBottomColor: COLOR_B_1
},
resultContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
resultText: {
color: 'white',
fontWeight: 'bold',
fontSize: 30
},
statusContainer: {
flex: 4,
alignItems: 'flex-start',
justifyContent: 'center',
paddingLeft: 5
},
statusText: {
fontSize: 17
}
});
18 changes: 17 additions & 1 deletion reducers/decks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import {
LOAD_DECKS,
NEW_DECK,
ADD_CARD,
UPDATE_DECK,
DELETE_DECK,
UPDATE_DECK_SCORE,
DELETE_CARD
} from '../actions/deck';

Expand All @@ -27,11 +29,25 @@ function decks(state = {}, action) {
}
case DELETE_DECK: {
const { deckKey } = action;

const refreshedDecks = Object.assign({}, decks);
delete refreshedDecks[deckKey];
return refreshedDecks;
}
case UPDATE_DECK_SCORE: {
const { score, deckKey } = action;

const refreshedDecks = {
...decks,
[deckKey]: {
...decks[deckKey],
won: score.won,
lost: score.lost
}
}

return refreshedDecks;
}
case ADD_CARD: {
const { card, deckKey } = action;
const freshDeck = decks[deckKey];
Expand Down
6 changes: 5 additions & 1 deletion reducers/scores.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { UPDATE_SCORE } from '../actions/score';
import { UPDATE_SCORE, LOAD_SCORES } from '../actions/score';

function scores(state = [], action) {
const { type } = action;
const scores = state;

switch (type) {
case UPDATE_SCORE: {
const refreshedScores = [...scores, action.score];
return refreshedScores;
}
case LOAD_SCORES: {
return action.scores;
}
default: {
Expand Down
19 changes: 18 additions & 1 deletion services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,24 @@ export async function getScores() {
export async function saveScore(deck, status) {
const scores = await getScores();
const date = Date.now();
scores.push({ deck, status, date });
const lastScore = { deck, status, date };
scores.push(lastScore);

const playedDeck = await getDeck(deck);

if (status === 'W') {
playedDeck.won += 1;
} else if (status === 'L') {
playedDeck.lost += 1;
}

const deckScore = {
won: playedDeck.won,
lost: playedDeck.lost
}

persistDeck(playedDeck);

await AsyncStorage.setItem(SCORES_STORAGE_KEY, JSON.stringify(scores));
return { lastScore, deckScore };
}

0 comments on commit 646e220

Please sign in to comment.