Fix animations on the level page

This commit is contained in:
Alexander Polynomdivision 2018-09-14 16:13:42 +02:00
parent 4e0506f607
commit 91b6d2a955
4 changed files with 54 additions and 19 deletions

View File

@ -112,16 +112,15 @@ export default class Application extends React.Component<{}, IState> {
// TODO: Actually implement this // TODO: Actually implement this
// TODO: Don't fetch this when it was already fetched once. // TODO: Don't fetch this when it was already fetched once.
return [{ return [{
latin: "Vinum", german: ["Wein"],
german: "Wein",
hint: "Worte auf '-um' sind meistens NeutrUM" hint: "Worte auf '-um' sind meistens NeutrUM"
type: VocabType.NOMEN, type: VocabType.NOMEN,
latin: {
grundform: "Vinum",
genitiv: "Vini",
genus: "Neutrum"
},
id: 0 id: 0
}, {
latin: "Vinum (Genitiv)",
german: "Vini",
type: VocabType.NOMEN,
id: 1
}/* , { }/* , {
* latin: "Vici", * latin: "Vici",
* german: "<Wortbedeutung>", * german: "<Wortbedeutung>",

View File

@ -10,13 +10,34 @@ export enum VocabType {
ADVERB ADVERB
} }
export interface INomenData {
grundform: string;
genitiv: string;
genus: string;
}
export interface IVerbData {
grundform: string;
// 1. Person
praesens: string;
perfekt: string;
// TODO: Was ist das PPP?
}
export interface IAdjektivData {
grundform: string;
nominativ_a: string;
nominativ_b: string;
}
export interface IVocab { export interface IVocab {
german: string; // If a word has multiple meanings
latin: string; german: string[];
hint?: string; hint?: string;
mnemonic?: string; mnemonic?: string;
type: VocabType; type: VocabType;
latin: INomenData | IVerbData | IAdjektivData;
// This number is lesson specific // This number is lesson specific
id: number; id: number;

View File

@ -26,6 +26,9 @@ interface IState {
export default class LevelPage extends React.Component<IProps, IState> { export default class LevelPage extends React.Component<IProps, IState> {
private uid = 0; private uid = 0;
// To prevent React from redrawing the vocabulary list and prematurely
// cancelling the animation
private uids: { [key: string]: string } = {};
constructor(props: any) { constructor(props: any) {
super(props); super(props);
@ -37,8 +40,14 @@ export default class LevelPage extends React.Component<IProps, IState> {
}; };
} }
genUID = (): string => { genUID = (vocab: IVocab): string => {
return "LEVELPAGE" + this.uid++; const { grundform } = vocab.latin;
if (grundform in this.uids) {
return this.uids[grundform];
} else {
this.uids[grundform] = "LEVELPAGE" + this.uid++;
return this.uids[grundform];
}
} }
renderVocabListItem = (vocab: IVocab): any => { renderVocabListItem = (vocab: IVocab): any => {
@ -46,7 +55,7 @@ export default class LevelPage extends React.Component<IProps, IState> {
const lookedAt = this.state.lookedAt.find((el) => el === vocab.id) || vocab.id === 0; const lookedAt = this.state.lookedAt.find((el) => el === vocab.id) || vocab.id === 0;
// TODO: Actually update the "Vocab View" when clicking // TODO: Actually update the "Vocab View" when clicking
return <ListItem button key={this.genUID()} onClick={() => { return <ListItem button key={this.genUID(vocab)} onClick={() => {
// Prevent the user from using too much memory by always clicking on the elements // Prevent the user from using too much memory by always clicking on the elements
// Show the clicked at vocab word // Show the clicked at vocab word
this.setState({ this.setState({
@ -55,14 +64,15 @@ export default class LevelPage extends React.Component<IProps, IState> {
}); });
}}> }}>
<ListItemText> <ListItemText>
{`${vocab.latin} ${lookedAt ? "✔" : ""}`} {`${vocab.latin.grundform} ${lookedAt ? "✔" : ""}`}
</ListItemText> </ListItemText>
</ListItem>; </ListItem>;
} }
toReview = () => { toReview = () => {
const { levelVocab, id } = this.props;
// Only go to the review if all vocabulary item have been looked at // Only go to the review if all vocabulary item have been looked at
if (this.props.levelVocab().length === this.state.lookedAt.length) { if (levelVocab(id).length === this.state.lookedAt.length) {
this.setState({ this.setState({
toReview: true, toReview: true,
}); });
@ -76,7 +86,8 @@ export default class LevelPage extends React.Component<IProps, IState> {
<Grid container direction="row"> <Grid container direction="row">
<Grid item xs={3}> <Grid item xs={3}>
<List> <List>
{this.props.levelVocab(this.props.id).map(this.renderVocabListItem)} {this.props.levelVocab(this.props.id)
.map(this.renderVocabListItem)}
{/* TODO*/} {/* TODO*/}
<ListItem button onClick={this.toReview}> <ListItem button onClick={this.toReview}>
<ListItemText> <ListItemText>
@ -96,10 +107,10 @@ export default class LevelPage extends React.Component<IProps, IState> {
<Card> <Card>
<CardContent> <CardContent>
<Typography gutterBottom variant="headline" component="h2"> <Typography gutterBottom variant="headline" component="h2">
{currentVocab.latin} {currentVocab.latin.grundform}
</Typography> </Typography>
<Typography gutterBottom variant="headline" component="h3"> <Typography gutterBottom variant="headline" component="h3">
{currentVocab.german} {currentVocab.german.join(", ")}
</Typography> </Typography>
{ {
currentVocab.hint ? ( currentVocab.hint ? (

View File

@ -59,9 +59,13 @@ export default class ReviewPage extends React.Component<IProps, IState> {
checkInput = () => { checkInput = () => {
const current = this.currentVocab(); const current = this.currentVocab();
// Check if the given answer is somewhere in the german words
const german = this.currentVocab().german.map((str) => str.toLowerCase());
const found = german.find((el) => el === this.state.input.toLowerCase());
// Check if the user's answer was correct // Check if the user's answer was correct
// TODO: Levensthein-Distance? // TODO: Levensthein-Distance?
if (this.state.input.toLowerCase() === current.german.toLowerCase()) { if (found) {
// TODO: Show it's correct // TODO: Show it's correct
// Show the next vocab word // Show the next vocab word
if (this.state.current + 1 >= this.vocab.length) { if (this.state.current + 1 >= this.vocab.length) {
@ -102,7 +106,7 @@ export default class ReviewPage extends React.Component<IProps, IState> {
<CardContent> <CardContent>
<Grid container direction="column"> <Grid container direction="column">
<Typography variant="display2"> <Typography variant="display2">
{this.currentVocab().latin} {this.currentVocab().latin.grundform}
</Typography> </Typography>
<TextField <TextField
margin="normal" margin="normal"