Adding learning page algorithm

master
Arthur VALIN 2 years ago
parent 2b45cebc2d
commit 8865c7a09b

Binary file not shown.

@ -10,6 +10,6 @@
"\\redux\\reducers", "\\redux\\reducers",
"\\redux\\thunks" "\\redux\\thunks"
], ],
"SelectedNode": "\\components\\KanjiListSearchPanel.tsx", "SelectedNode": "\\redux\\store.ts",
"PreviewInSolutionExplorer": false "PreviewInSolutionExplorer": false
} }

Binary file not shown.

@ -6,8 +6,6 @@ import { Provider, useDispatch } from 'react-redux';
import { StatusBar } from 'expo-status-bar'; import { StatusBar } from 'expo-status-bar';
import { Keyboard, SafeAreaView, StyleSheet, TouchableWithoutFeedback} from 'react-native'; import { Keyboard, SafeAreaView, StyleSheet, TouchableWithoutFeedback} from 'react-native';
import Header from './components/Header';
import TabBar from './navigation/TabBar';
import { InitStack } from './navigation/Startup'; import { InitStack } from './navigation/Startup';
export default function App() { export default function App() {

@ -19,8 +19,9 @@ const GradeChip = (props: gradeChipProps) => {
}, [isSelected]); }, [isSelected]);
const select = () => { const select = () => {
props.onSelect("Grade "+props.grade, isSelected);
setIsSelected(!isSelected); setIsSelected(!isSelected);
props.onSelect("Grade " + props.grade, isSelected);
} }
return ( return (

@ -2,24 +2,20 @@ import React from 'react';
import { Animated, StyleSheet, TextInput } from 'react-native'; import { Animated, StyleSheet, TextInput } from 'react-native';
import { startAnimation, stopAnimation, animatedStyles } from '../assets/animations/answerAnimation' import { startAnimation, stopAnimation, animatedStyles } from '../assets/animations/answerAnimation'
const KanjiAnswerField = () => { interface kanjiAnswerFieldProps {
answer: string,
setAnswer: React.Dispatch<React.SetStateAction<string>>
}
const options = { const KanjiAnswerField = (props: kanjiAnswerFieldProps) => {
method: 'GET',
headers: {
'X-RapidAPI-Key': '19516a9900mshce10de76f99976bp10f192jsn8c8d82222baa',
'X-RapidAPI-Host': 'kanjialive-api.p.rapidapi.com'
}
}
const [answer, onChangeText] = React.useState("");
return ( return (
<Animated.View style={[animatedStyles]}> <Animated.View style={[animatedStyles]}>
<TextInput <TextInput
style={answerFieldStyle.input} style={answerFieldStyle.input}
onChangeText={onChangeText} onChangeText={props.setAnswer}
value={answer} value={props.answer}
onFocus={startAnimation} onFocus={startAnimation}
onBlur={stopAnimation} onBlur={stopAnimation}
placeholder="Answer here" placeholder="Answer here"

@ -13,27 +13,27 @@ type KanjiProps = {
const KanjiCard = (props: KanjiProps) => { const KanjiCard = (props: KanjiProps) => {
const kanjiCardStyle = useColorScheme() == 'light' ? kanjiCardStyle_light : kanjiCardStyle_dark; var kanjiCardStyle = useColorScheme() == 'light' ? kanjiCardStyle_light : kanjiCardStyle_dark;
const [answerTextColor, setAnswerTextColor] = useState(kanjiCardStyle.text.color);
var textAnswerStyle = StyleSheet.create({
text: {
color: answerTextColor,
fontWeight: "bold",
fontSize: "20em"
}
})
const options = { const nextKanji = () => allKanjis[Math.floor(Math.random() * allKanjis.length)];
method: 'GET',
headers: {
'X-RapidAPI-Key': '19516a9900mshce10de76f99976bp10f192jsn8c8d82222baa',
'X-RapidAPI-Host': 'kanjialive-api.p.rapidapi.com'
}
}
const [kanji, setKanji] = useState((): Kanji | null => { return null }); const [kanji, setKanji] = useState((): Kanji | null => { return null });
const [imgXml, setImgXml] = useState('<svg></svg>'); const [imgXml, setImgXml] = useState('<svg></svg>');
const [hasAnswered, setHasAnswered] = useState(false);
const [answer, setAnswer] = React.useState("");
var kanjis: KanjiListByGrade = useSelector(state => state.kanjiReducer.kanjis); var kanjis: KanjiListByGrade = useSelector(state => state.kanjiReducer.kanjis);
const allKanjis: Kanji[] = [].concat(...Object.values(kanjis)) const allKanjis: Kanji[] = [].concat(...Object.values(kanjis))
const selectedKanji = allKanjis[Math.floor(Math.random() * allKanjis.length)]
const fetchXml = async () => { const fetchXml = async () => {
@ -44,7 +44,7 @@ const KanjiCard = (props: KanjiProps) => {
} }
useEffect(() => { useEffect(() => {
setKanji(selectedKanji); setKanji(nextKanji());
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -52,6 +52,22 @@ const KanjiCard = (props: KanjiProps) => {
}); });
}, [kanji]); }, [kanji]);
const computeAnswer = () => {
setAnswerTextColor(isAnswerRight() ? "green" : "red");
setHasAnswered(true);
}
const computeNext = () => {
setKanji(nextKanji());
setAnswer("");
setHasAnswered(false);
}
const isAnswerRight = () => {
const arr1 = answer.toLowerCase().split(',').map(word => word.trim()).sort();
const arr2 = kanji?.meaning.toLowerCase().split(',').map(word => word.trim()).sort();
return JSON.stringify(arr1) === JSON.stringify(arr2);
}
return ( return (
<View style={kanjiCardStyle.container}> <View style={kanjiCardStyle.container}>
@ -62,9 +78,19 @@ const KanjiCard = (props: KanjiProps) => {
width="200" width="200"
height="200" height="200"
/> />
<Text style={kanjiCardStyle.text}>{kanji?.meaning}</Text> {!hasAnswered && (
<KanjiAnswerField /> <>
<Button title="OK" color="#FF5C5C" /> <Text style={kanjiCardStyle.text}>{kanji?.meaning}</Text>
<KanjiAnswerField answer={answer} setAnswer={setAnswer} />
<Button title="OK" color="#FF5C5C" onPress={computeAnswer} />
</>
) || (
<>
<Text style={textAnswerStyle.text}>{kanji?.meaning}</Text>
<Text style={kanjiCardStyle.text}>{answer}</Text>
<Button title="NEXT" color="#FF5C5C" onPress={computeNext}/>
</>
)}
</View> </View>
); );
}; };

@ -42,7 +42,7 @@ export default function Startup() {
await (await fetchKanjis())(dispatch); await (await fetchKanjis())(dispatch);
//await new Promise(resolve => setTimeout(resolve, 5000)); //await new Promise(resolve => setTimeout(resolve, 5000));
navigator.navigate("Main"); navigator.replace("Main");
} }
useEffect(() => { useEffect(() => {

@ -15,18 +15,22 @@ const Detail = ({route}) => {
const fetchXml = async () => { const fetchXml = async () => {
const imgxml = await (await fetch(kanji.image)).text(); const imgxml = await (await fetch(kanji.image)).text();
setImgXml(imgxml); setImgXml(imgxml);
const iconxml = await (await fetch(kanji.radical.position)).text(); if (kanji.radical.position) {
setIconXml(iconxml); const iconxml = await (await fetch(kanji.radical.position))?.text();
setIconXml(iconxml);
}
} }
useEffect(() => { useEffect(() => {
console.log(kanji)
fetchXml(); fetchXml();
}, []); }, []);
return ( return (
<View style={detailStyle.container}> <View style={detailStyle.container}>
<View> <View style={detailStyle.pronounciation}>
<Text style={detailStyle.text}>{kanji.onyomi}</Text> <Text style={detailStyle.text}>{kanji.onyomi}</Text>
<Text style={detailStyle.text}>{kanji.kunyomi}</Text> <Text style={detailStyle.text}>{kanji.kunyomi}</Text>
</View> </View>
@ -39,11 +43,16 @@ const Detail = ({route}) => {
<Text style={detailStyle.tinyText}>{kanji.strokes + " strokes"}</Text> <Text style={detailStyle.tinyText}>{kanji.strokes + " strokes"}</Text>
<Text style={detailStyle.meaningText}>{kanji.meaning}</Text> <Text style={detailStyle.meaningText}>{kanji.meaning}</Text>
<Text style={detailStyle.title}>Radical</Text> {kanji.radical.position && kanji.radical.character &&
<DetailRadical character={kanji.radical.character} icon={iconXml}/> (<>
<Text style={detailStyle.title}>Radical</Text>
<Text style={detailStyle.title}>Examples</Text> <DetailRadical character={kanji.radical.character} icon={iconXml}/>
<DetailExamples data={kanji.examples} /> </>)}
{kanji.examples &&
(<>
<Text style={detailStyle.title}>Examples</Text>
<DetailExamples data={kanji.examples} />
</>)}
</View> </View>
); );
}; };
@ -59,6 +68,9 @@ const detailStyle_light = StyleSheet.create({
height: "100%", height: "100%",
width: "100%" width: "100%"
}, },
pronounciation: {
alignItems: "center"
},
svg: { svg: {
color: "black" color: "black"
}, },
@ -77,7 +89,7 @@ const detailStyle_light = StyleSheet.create({
fontSize: 20, fontSize: 20,
color: "#FF5C5C", color: "#FF5C5C",
fontWeight: "900", fontWeight: "900",
textAlign: "center"
} }
}) })
@ -89,6 +101,9 @@ const detailStyle_dark = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
backgroundColor: "#1c1c1c", backgroundColor: "#1c1c1c",
}, },
pronounciation: {
alignItems: "center"
},
svg: { svg: {
color: "white" color: "white"
}, },
@ -108,6 +123,7 @@ const detailStyle_dark = StyleSheet.create({
fontSize: 20, fontSize: 20,
color: "#FF5C5C", color: "#FF5C5C",
fontWeight: "900", fontWeight: "900",
textAlign: "center"
} }
}); });

@ -11,11 +11,9 @@ export default function kanjiReducer(state = initialState, action) {
switch (action.type) { switch (action.type) {
case c.SET_KANJIS: case c.SET_KANJIS:
// @ts-ignore // @ts-ignore
console.log("SET KANJIS");
return { ...state, kanjis: action.payload }; return { ...state, kanjis: action.payload };
case c.SET_SELECTED_KANJI: case c.SET_SELECTED_KANJI:
// @ts-ignore // @ts-ignore
console.log("SET SELECTED");
return { ...state, selectedKanji: action.payload }; return { ...state, selectedKanji: action.payload };
default: default:
return state; return state;

@ -1,4 +1,4 @@
import { configureStore, createSerializableStateInvariantMiddleware } from '@reduxjs/toolkit' import { configureStore, createSerializableStateInvariantMiddleware, getDefaultMiddleware } from '@reduxjs/toolkit'
import kanjiReducer from './reducers/kanjiReducer'; import kanjiReducer from './reducers/kanjiReducer';
// Reference here all your application reducers // Reference here all your application reducers
@ -10,10 +10,10 @@ const reducer = {
const store = configureStore( const store = configureStore(
{ {
reducer, reducer,
middleware: [createSerializableStateInvariantMiddleware({ middleware: getDefaultMiddleware({
ignoredActions: ["SET_KANJIS", "SET_SELECTED_KANJI"], serializableCheck: false
ignoreActions: true })
})]
},); },);
export default store; export default store;
Loading…
Cancel
Save