Adding dark mode using device settings

master
Arthur VALIN 2 years ago
parent acbd1b2c1b
commit f07853dc6f

@ -4,9 +4,11 @@
"\\assets", "\\assets",
"\\components", "\\components",
"\\model", "\\model",
"\\pages",
"\\redux", "\\redux",
"\\redux\\actions",
"\\redux\\reducers" "\\redux\\reducers"
], ],
"SelectedNode": "\\app.json", "SelectedNode": "\\components\\DrawingCanva.tsx",
"PreviewInSolutionExplorer": false "PreviewInSolutionExplorer": false
} }

Binary file not shown.

Binary file not shown.

@ -4,18 +4,19 @@ import store from "./redux/store";
import { Provider } from 'react-redux'; import { Provider } 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 Header from './components/Header';
import TabBar from './components/TabBar'; import TabBar from './navigation/TabBar';
export default function App() { export default function App() {
return ( return (
<Provider store={store}> <Provider store={store}>
<TouchableWithoutFeedback onPress={() => { Keyboard.dismiss(); }}> <TouchableWithoutFeedback onPress={() => { Keyboard.dismiss(); }}>
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Header/> <Header />
<TabBar/> <TabBar/>
<StatusBar style="auto" /> <StatusBar style="auto" />
</SafeAreaView> </SafeAreaView>
@ -34,9 +35,15 @@ const tabOptions = {
tabBarInactiveTintColor: "black" tabBarInactiveTintColor: "black"
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#FF5C5C', backgroundColor: '#FF5C5C',
}, },
}); });

@ -5,7 +5,7 @@
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",
"icon": "./src/assets/icon.png", "icon": "./src/assets/icon.png",
"userInterfaceStyle": "light", "userInterfaceStyle": "automatic",
"splash": { "splash": {
"image": "./src/assets/splash.png", "image": "./src/assets/splash.png",
"resizeMode": "contain", "resizeMode": "contain",
@ -23,7 +23,7 @@
"android": { "android": {
"adaptiveIcon": { "adaptiveIcon": {
"foregroundImage": "./src/assets/adaptive-icon.png", "foregroundImage": "./src/assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF" "backgroundColor": "#FFFFFF",
} }
}, },
"web": { "web": {

@ -1,7 +1,7 @@
import React, {useEffect, useRef, useState } from 'react'; import React, {useEffect, useRef, useState } from 'react';
import { SketchCanvas, SketchCanvasRef } from 'rn-perfect-sketch-canvas'; import { SketchCanvas, SketchCanvasRef } from 'rn-perfect-sketch-canvas';
import { StyleSheet, Button, View, Text } from 'react-native'; import { StyleSheet, Button, View, Text, useColorScheme } from 'react-native';
import { SvgUri } from 'react-native-svg'; import { SvgXml } from 'react-native-svg';
import Slider from '@react-native-community/slider' import Slider from '@react-native-community/slider'
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
@ -13,43 +13,54 @@ type DrawingCanvaProps = {
const DrawingCanva = (props: DrawingCanvaProps) => { const DrawingCanva = (props: DrawingCanvaProps) => {
const style = useColorScheme() == 'light' ? style_light : style_dark;
const canvasRef = useRef<SketchCanvasRef>(null); const canvasRef = useRef<SketchCanvasRef>(null);
const [strokeWidth, setStroke] = useState(5); const [strokeWidth, setStroke] = useState(5);
const [isCanvasReady, setIsCanvasReady] = useState(false); const [isCanvasReady, setIsCanvasReady] = useState(false);
const [imgXml, setImgXml] = useState('<svg></svg>');
const selectedKanji = KanjiMapper.SerializedObjectToKanji(useSelector(state => state.kanjiReducer.selectedKanji)); const selectedKanji = KanjiMapper.SerializedObjectToKanji(useSelector(state => state.kanjiReducer.selectedKanji));
useEffect(() => { useEffect(() => {
if (canvasRef.current) { if (canvasRef.current) {
fetchXml();
setIsCanvasReady(true); setIsCanvasReady(true);
} }
}, [canvasRef.current]); }, [canvasRef.current]);
const fetchXml = async () => {
const xml = await (await fetch(selectedKanji.image)).text();
setImgXml(xml);
}
return ( return (
<View style={styles.container}> <View style={style.container}>
{selectedKanji && (<SvgUri {selectedKanji && (
width="75%" <SvgXml
height="75%" xml={imgXml
uri={selectedKanji.image} .replace(/fill="#[0-9a-f]{6}"/g, `fill=${style.svg.color}`)}
style={styles.back} width="75%"
opacity={0.1} height="75%"
/>)} opacity={0.1}
style={style.back}
/>)}
<SketchCanvas <SketchCanvas
ref={canvasRef} ref={canvasRef}
strokeColor={'black'} strokeColor={style.canvas.strokeColor}
strokeWidth={strokeWidth} strokeWidth={strokeWidth}
containerStyle={styles.canvas} containerStyle={style.canvas}
/> />
<Slider <Slider
style={styles.slider} style={style.slider}
onValueChange={(val) => setStroke(val)} onValueChange={(val) => setStroke(val)}
minimumValue={5} minimumValue={5}
maximumValue={10} maximumValue={10}
minimumTrackTintColor={"#FF5C5C"} minimumTrackTintColor={"#FF5C5C"}
/> />
{isCanvasReady && (<View style={styles.menu}> {isCanvasReady && (<View style={style.menu}>
<Button color="#FF5C5C" onPress={canvasRef.current?.reset} title="Reset" /> <Button color="#FF5C5C" onPress={canvasRef.current?.reset} title="Reset" />
<Button color="#FF5C5C" onPress={canvasRef.current?.undo} title="Undo" /> <Button color="#FF5C5C" onPress={canvasRef.current?.undo} title="Undo" />
</View>)} </View>)}
@ -57,7 +68,42 @@ const DrawingCanva = (props: DrawingCanvaProps) => {
); );
}; };
const styles = StyleSheet.create({ const style_light = StyleSheet.create({
svg: {
color: "black"
},
container: {
flex: 1,
width: "100%",
},
back: {
alignSelf: "center",
width: "75%",
height: "75%",
position: "absolute"
},
canvas: {
alignSelf: "center",
height: "75%",
width: "75%",
borderWidth: 2,
borderColor: "black",
strokeColor: "black"
},
menu: {
flexDirection: "row",
justifyContent: "space-evenly",
},
slider: {
width: "75%",
alignSelf: "center",
}
});
const style_dark = StyleSheet.create({
svg: {
color: "white"
},
container: { container: {
flex: 1, flex: 1,
width: "100%", width: "100%",
@ -73,7 +119,9 @@ const styles = StyleSheet.create({
height: "75%", height: "75%",
width: "75%", width: "75%",
borderWidth: 2, borderWidth: 2,
borderColor: "black" borderColor: "white",
strokeColor: "white"
}, },
menu: { menu: {
flexDirection: "row", flexDirection: "row",
@ -85,4 +133,6 @@ const styles = StyleSheet.create({
} }
}); });
export default DrawingCanva; export default DrawingCanva;

@ -1,8 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native'; import { StyleSheet, Text, View, Button, useColorScheme } from 'react-native';
import { SvgUri } from 'react-native-svg'; import { SvgUri, SvgXml } from 'react-native-svg';
import KanjiAnswerField from './KanjiAnswerField'; import KanjiAnswerField from './KanjiAnswerField';
import { Kanji, KanjiMapper } from '../model/kanji';
type KanjiProps = { type KanjiProps = {
kanji: string; kanji: string;
@ -10,6 +9,9 @@ type KanjiProps = {
const KanjiCard = (props: KanjiProps) => { const KanjiCard = (props: KanjiProps) => {
const kanjiCardStyle = useColorScheme() == 'light' ? kanjiCardStyle_light : kanjiCardStyle_dark;
const options = { const options = {
method: 'GET', method: 'GET',
headers: { headers: {
@ -20,11 +22,15 @@ const KanjiCard = (props: KanjiProps) => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [res, setData] = useState(null); const [res, setData] = useState(null);
const [imgXml, setImgXml] = useState('<svg></svg>');
const fetchData = async () => { const fetchData = async () => {
await fetch(`https://kanjialive-api.p.rapidapi.com/api/public/kanji/${props.kanji}`, options) await fetch(`https://kanjialive-api.p.rapidapi.com/api/public/kanji/${props.kanji}`, options)
.then(async response => { .then(async response => {
setData(await response.json()); const data = await response.json()
setData(data);
const xml = await (await fetch(data.kanji.video.poster)).text();
setImgXml(xml);
}) })
.catch(err => console.log(err)); .catch(err => console.log(err));
} }
@ -36,28 +42,56 @@ const KanjiCard = (props: KanjiProps) => {
}); });
}, []); }, []);
return ( return (
<View style={kanjiCardStyle.container}> <View style={kanjiCardStyle.container}>
<Text> {loading ? <Text>Loading...</Text> : <Text>{res.kanji.onyomi.katakana}</Text>}</Text> <Text style={kanjiCardStyle.text}> {loading ? <Text>Loading...</Text> : <Text>{res.kanji.onyomi.katakana}</Text>}</Text>
{!loading && (<SvgUri {!loading && (
<SvgXml
xml={imgXml
.replace(/fill="#[0-9a-f]{6}"/g, `fill=${kanjiCardStyle.svg.color}`)}
width="200" width="200"
uri={res.kanji.video.poster} height="200"
/>)} />
<Text> {loading ? <Text/> : <Text>{res.kanji.meaning.english}</Text>}</Text> )}
<Text style={kanjiCardStyle.text}> {loading ? <Text/> : <Text>{res.kanji.meaning.english}</Text>}</Text>
<KanjiAnswerField/> <KanjiAnswerField/>
<Button title="OK" color="#FF5C5C" /> <Button title="OK" color="#FF5C5C" />
</View> </View>
); );
}; };
const kanjiCardStyle = StyleSheet.create({ const kanjiCardStyle_light = StyleSheet.create({
svg: {
color: "black",
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: "100%",
height: "100%"
},
text: {
color: "black"
}
})
const kanjiCardStyle_dark = StyleSheet.create({
svg: {
color: "white",
},
container: { container: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
width: "100%", width: "100%",
height: "100%" height: "100%"
},
text: {
color: "white"
} }
}) })

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { FlatList, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'; import { FlatList, StyleSheet, Text, TextInput, TouchableOpacity, useColorScheme, View } from 'react-native';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Kanji } from '../model/kanji'; import { Kanji } from '../model/kanji';
import { setSelectedKanji } from '../redux/actions/setSelectedKanji'; import { setSelectedKanji } from '../redux/actions/setSelectedKanji';
@ -12,6 +12,9 @@ interface kanjiPlaygroundListProps {
const KanjiPlaygroundList = (props: kanjiPlaygroundListProps) => { const KanjiPlaygroundList = (props: kanjiPlaygroundListProps) => {
const kanjiPlaygroundList = useColorScheme() == 'light' ? kanjiPlaygroundList_light : kanjiPlaygroundList_dark;
const selectedKanji = useSelector(state => state.kanjiReducer.selectedKanji); const selectedKanji = useSelector(state => state.kanjiReducer.selectedKanji);
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -35,7 +38,7 @@ const KanjiPlaygroundList = (props: kanjiPlaygroundListProps) => {
); );
}; };
const kanjiPlaygroundList = StyleSheet.create({ const kanjiPlaygroundList_light = StyleSheet.create({
container: { container: {
width: '70%', width: '70%',
height: '30%', height: '30%',
@ -65,4 +68,35 @@ const kanjiPlaygroundList = StyleSheet.create({
}, },
}) })
const kanjiPlaygroundList_dark = StyleSheet.create({
container: {
width: '70%',
height: '30%',
margin: 5,
},
entry: {
padding: 5,
margin: 1,
justifyContent: 'center',
flex: 1,
backgroundColor: '#1c1c1c',
},
entryText: {
fontWeight: "bold",
fontSize: 30,
textAlign: "center",
color: "white"
},
input: {
height: "20%",
margin: 12,
borderWidth: 1,
padding: 10,
width: "75%",
backgroundColor: "white",
borderRadius: 20,
alignSelf: "center"
},
})
export default KanjiPlaygroundList; export default KanjiPlaygroundList;

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { StyleSheet, TouchableNativeFeedback, View } from 'react-native' import { StyleSheet, TouchableNativeFeedback, useColorScheme, View } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'; import { NavigationContainer } from '@react-navigation/native';
import { BottomTabBarButtonProps, BottomTabNavigationOptions, createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { BottomTabBarButtonProps, BottomTabNavigationOptions, createBottomTabNavigator } from '@react-navigation/bottom-tabs';
@ -13,8 +13,11 @@ import List from '../pages/List';
import Playground from '../pages/Playground'; import Playground from '../pages/Playground';
const LearnButton = (props: BottomTabBarButtonProps) => { const LearnButton = (props: BottomTabBarButtonProps) => {
const learnButtonStyle = useColorScheme() == 'light' ? learnButtonStyle_light : learnButtonStyle_dark;
return ( return (
<View <View
style={{ style={{
@ -33,7 +36,7 @@ const LearnButton = (props: BottomTabBarButtonProps) => {
} }
const learnButtonStyle = StyleSheet.create({ const learnButtonStyle_light = StyleSheet.create({
button: { button: {
backgroundColor: "#FF5C5C", backgroundColor: "#FF5C5C",
width: 80, width: 80,
@ -44,6 +47,17 @@ const learnButtonStyle = StyleSheet.create({
} }
}); });
const learnButtonStyle_dark = StyleSheet.create({
button: {
backgroundColor: "#FF5C5C",
width: 80,
height: 80,
borderRadius: 40,
borderColor: "#2b2b2b",
borderWidth: 5
}
});
const TabBar = () => { const TabBar = () => {
const Tab = createBottomTabNavigator(); const Tab = createBottomTabNavigator();

@ -1,10 +1,13 @@
import React from 'react'; import React from 'react';
import { View, StyleSheet } from 'react-native'; import { View, StyleSheet, useColorScheme } from 'react-native';
import KanjiCard from '../components/KanjiCard'; import KanjiCard from '../components/KanjiCard';
const Learn = () => { const Learn = () => {
const learnStyle = useColorScheme() == 'light' ? learnStyle_light : learnStyle_dark;
return ( return (
<View style={learnStyle.container}> <View style={learnStyle.container}>
<KanjiCard kanji="所"></KanjiCard> <KanjiCard kanji="所"></KanjiCard>
@ -12,7 +15,8 @@ const Learn = () => {
); );
}; };
const learnStyle = StyleSheet.create({
const learnStyle_light = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
@ -21,4 +25,14 @@ const learnStyle = StyleSheet.create({
} }
}) })
const learnStyle_dark = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2B2B2B',
},
});
export default Learn; export default Learn;

@ -1,10 +1,12 @@
import React from 'react'; import React from 'react';
import { View, StyleSheet } from 'react-native'; import { View, StyleSheet, useColorScheme } from 'react-native';
import KanjiList from '../components/KanjiList'; import KanjiList from '../components/KanjiList';
const List = () => { const List = () => {
const listStyle = useColorScheme() == 'light' ? listStyle_light : listStyle_dark;
return ( return (
<View style={listStyle.container}> <View style={listStyle.container}>
<KanjiList/> <KanjiList/>
@ -12,7 +14,8 @@ const List = () => {
); );
}; };
const listStyle = StyleSheet.create({
const listStyle_light = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
@ -21,4 +24,14 @@ const listStyle = StyleSheet.create({
} }
}) })
const listStyle_dark = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2B2B2B',
},
});
export default List; export default List;

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { View, StyleSheet } from 'react-native'; import { View, StyleSheet, useColorScheme } from 'react-native';
import DrawingCanva from '../components/DrawingCanva'; import DrawingCanva from '../components/DrawingCanva';
import KanjiPlaygroundList from '../components/KanjiPlaygroundList'; import KanjiPlaygroundList from '../components/KanjiPlaygroundList';
import { Kanji } from '../model/kanji'; import { Kanji } from '../model/kanji';
@ -7,6 +7,9 @@ import { Kanji } from '../model/kanji';
const Playground = () => { const Playground = () => {
// 親 雨 序 余 貴 郷 // 親 雨 序 余 貴 郷
const playgroundStyle = useColorScheme() == 'light' ? playgroundStyle_light : playgroundStyle_dark;
return ( return (
<View style={playgroundStyle.container}> <View style={playgroundStyle.container}>
<KanjiPlaygroundList data={[ <KanjiPlaygroundList data={[
@ -19,7 +22,7 @@ const Playground = () => {
); );
}; };
const playgroundStyle = StyleSheet.create({ const playgroundStyle_light = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
@ -29,4 +32,17 @@ const playgroundStyle = StyleSheet.create({
} }
}) })
const playgroundStyle_dark = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2B2B2B',
},
});
export default Playground; export default Playground;
Loading…
Cancel
Save