main
alex 2023-07-11 19:59:29 +00:00
parent 4ba01853ba
commit e62e6182f9
13 changed files with 636 additions and 191 deletions

2
App.js
View File

@ -11,6 +11,7 @@ import { Theme } from "./src/utils";
import DeviceOldScreen from "./src/Screens/DeviceOld"; import DeviceOldScreen from "./src/Screens/DeviceOld";
import DeviceScreen from "./src/Screens/Device"; import DeviceScreen from "./src/Screens/Device";
import { Colors } from "react-native-ui-lib"; import { Colors } from "react-native-ui-lib";
import SettingsScreen from "./src/Screens/Settings";
Colors.loadSchemes({ Colors.loadSchemes({
light: { light: {
@ -51,6 +52,7 @@ export default function App() {
<Drawer.Screen name="Spinner V6" component={DeviceOldScreen} /> <Drawer.Screen name="Spinner V6" component={DeviceOldScreen} />
<Drawer.Screen name="FAQ" component={FaqScreen} /> <Drawer.Screen name="FAQ" component={FaqScreen} />
<Drawer.Screen name="Feedback" component={FeedbackScreen} /> <Drawer.Screen name="Feedback" component={FeedbackScreen} />
<Drawer.Screen name="Settings" component={SettingsScreen} />
</Drawer.Navigator> </Drawer.Navigator>
</NavigationContainer> </NavigationContainer>

31
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "app", "name": "app",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@react-native-async-storage/async-storage": "^1.19.0",
"@react-navigation/drawer": "^6.6.3", "@react-navigation/drawer": "^6.6.3",
"@react-navigation/native": "^6.1.7", "@react-navigation/native": "^6.1.7",
"@react-navigation/native-stack": "^6.9.13", "@react-navigation/native-stack": "^6.9.13",
@ -3679,6 +3680,17 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/@react-native-async-storage/async-storage": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.19.0.tgz",
"integrity": "sha512-xOFkz/FaQctD6yNJDur+WnHdSTigOs3pTz6HmfC8X8PYwcnnN3R9UxuWiwsfK8vvT2WioAxUkQt3lB7GySNA2w==",
"dependencies": {
"merge-options": "^3.0.4"
},
"peerDependencies": {
"react-native": "^0.0.0-0 || 0.60 - 0.72 || 1000.0.0"
}
},
"node_modules/@react-native-community/cli": { "node_modules/@react-native-community/cli": {
"version": "10.2.2", "version": "10.2.2",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.2.tgz", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.2.tgz",
@ -8442,6 +8454,14 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"engines": {
"node": ">=8"
}
},
"node_modules/is-plain-object": { "node_modules/is-plain-object": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@ -9680,6 +9700,17 @@
"resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
"integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA=="
}, },
"node_modules/merge-options": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
"integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
"dependencies": {
"is-plain-obj": "^2.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/merge-stream": { "node_modules/merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",

View File

@ -9,6 +9,7 @@
"web": "expo start --web" "web": "expo start --web"
}, },
"dependencies": { "dependencies": {
"@react-native-async-storage/async-storage": "^1.19.0",
"@react-navigation/drawer": "^6.6.3", "@react-navigation/drawer": "^6.6.3",
"@react-navigation/native": "^6.1.7", "@react-navigation/native": "^6.1.7",
"@react-navigation/native-stack": "^6.9.13", "@react-navigation/native-stack": "^6.9.13",

View File

@ -0,0 +1,25 @@
import { ScrollView, View } from "react-native";
export default function Card({ children }) {
return (
<View
style={{
paddingTop: 10,
paddingLeft: 20,
paddingRight: 20,
paddingBottom: 10,
}}
>
<View
style={{
borderRadius: 20,
backgroundColor: "#3f4042",
elevation: 5,
padding: 20,
}}
>
{children}
</View>
</View>
);
}

View File

@ -0,0 +1,7 @@
import { View } from "react-native";
export function Divider() {
return (
<View style={{ height: 1, backgroundColor: "gray", marginVertical: 10 }} />
);
}

View File

@ -1,14 +1,30 @@
import { DrawerContentScrollView, DrawerItem } from "@react-navigation/drawer"; import { DrawerContentScrollView, DrawerItem } from "@react-navigation/drawer";
import { useEffect, useState } from "react";
import { Image, StyleSheet, View } from "react-native"; import { Image, StyleSheet, View } from "react-native";
import { Divider, Text } from "react-native-paper"; import { Divider, Text } from "react-native-paper";
import { GetData } from "../../utils";
export default function Sidebar(props) { export default function Sidebar(props) {
const [isDeveloperModeEnabled, setIsDeveloperModeEnabled] = useState(false);
useEffect(() => {
async function getDeveloperMode() {
setIsDeveloperModeEnabled(await GetData("developerMode"));
}
getDeveloperMode();
}, []);
return ( return (
<> <>
<Image {isDeveloperModeEnabled ? (
source={require("../../../assets/image.png")} <Image
style={styles.image} source={require("../../../assets/image.png")}
/> style={styles.image}
/>
) : (
<View style={[styles.image, { backgroundColor: "#ddd" }]} />
)}
<Text variant="titleLarge" style={{ fontWeight: "bold", marginLeft: 10 }}> <Text variant="titleLarge" style={{ fontWeight: "bold", marginLeft: 10 }}>
Geräte Geräte
</Text> </Text>
@ -32,6 +48,10 @@ export default function Sidebar(props) {
label={"Feedback geben"} label={"Feedback geben"}
onPress={() => props.navigation.navigate("Feedback")} onPress={() => props.navigation.navigate("Feedback")}
/> />
<DrawerItem
label={"Einstellungen"}
onPress={() => props.navigation.navigate("Settings")}
/>
</View> </View>
</> </>
); );

View File

@ -1,17 +1,11 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import { Image, ScrollView, StyleSheet } from "react-native"; import { Image, ScrollView, StyleSheet, View, Text } from "react-native";
import { Avatar, Card, IconButton } from "react-native-paper"; import { IconButton } from "react-native-paper";
import { import { Colors } from "react-native-ui-lib";
Slider,
Picker,
Icon,
Colors,
Text,
View,
Switch,
Incubator,
} from "react-native-ui-lib";
import LightView from "./light"; import LightView from "./light";
import { GetData } from "../../utils";
import MotorView from "./motor";
import SettingsView from "./settings";
const spaceToSide = 10; // left and right const spaceToSide = 10; // left and right
const top = 35; const top = 35;
@ -26,22 +20,46 @@ const iconButtonNotActiveColor = "#fff";
export default function DeviceScreen() { export default function DeviceScreen() {
const [selectedView, setSelectedView] = useState(0); const [selectedView, setSelectedView] = useState(0);
const [isDeveloperModeEnabled, setIsDeveloperModeEnabled] = useState(false);
useEffect(() => {
async function getMode() {
const data = await GetData("developerMode");
setIsDeveloperModeEnabled(data);
}
getMode();
}, []);
const SelectedView = () => { const SelectedView = () => {
switch (selectedView) { switch (selectedView) {
case 0: case 0:
return <LightView />; return <LightView />;
case 2:
return <MotorView />;
case 3:
return <SettingsView />;
default: default:
<Text>Not found</Text>; <Text>Not found</Text>;
} }
}; };
return ( return (
<View style={{ height: "100%", backgroundColor: "#2e2e30" }}> <View
<Image style={{
source={require("../../../assets/image.png")} height: "100%",
style={styles.image} backgroundColor: "#2e2e30",
/> }}
>
{isDeveloperModeEnabled ? (
<Image
source={require("../../../assets/image.png")}
style={styles.image}
/>
) : (
<View style={[styles.image, { backgroundColor: "#ddd" }]} />
)}
<IconButton <IconButton
icon="lightbulb-on-outline" icon="lightbulb-on-outline"
@ -73,10 +91,12 @@ export default function DeviceScreen() {
<IconButton <IconButton
icon="cog-outline" icon="cog-outline"
iconColor={"#fff"} iconColor={
selectedView === 3 ? iconButtonActiveColor : iconButtonNotActiveColor
}
style={[styles.iconButton, { top: topFirst, right: spaceToSide }]} style={[styles.iconButton, { top: topFirst, right: spaceToSide }]}
size={30} size={30}
onPress={() => console.log("Pressed")} onPress={() => setSelectedView(3)}
/> />
<IconButton <IconButton
icon="palette-outline" icon="palette-outline"
@ -100,9 +120,7 @@ export default function DeviceScreen() {
/> />
<ScrollView style={{ height: "100%" }}> <ScrollView style={{ height: "100%" }}>
<View style={{ padding: 20 }}> <SelectedView />
<SelectedView />
</View>
</ScrollView> </ScrollView>
</View> </View>
); );

View File

@ -1,47 +1,36 @@
import { useEffect, useRef, useState } from "react"; import { useEffect, useState } from "react";
import { StyleSheet, Text, TouchableHighlight } from "react-native"; import { StyleSheet, Text, View } from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { IconButton, TouchableRipple } from "react-native-paper"; import { IconButton, TouchableRipple } from "react-native-paper";
import Animated, { import Animated, {
useAnimatedStyle, useAnimatedStyle,
useDerivedValue,
useSharedValue, useSharedValue,
withTiming,
} from "react-native-reanimated"; } from "react-native-reanimated";
import { import { Icon, Incubator, Picker, Switch } from "react-native-ui-lib";
Icon,
Incubator,
Picker,
Switch,
TouchableOpacity,
View,
} from "react-native-ui-lib";
import ColorPicker, { import ColorPicker, {
Panel3,
Swatches, Swatches,
colorKit,
BrightnessSlider,
InputWidget, InputWidget,
HueCircular,
Panel1,
} from "reanimated-color-picker"; } from "reanimated-color-picker";
import { GetData } from "../../utils";
import Card from "../../Components/Card";
const dropdown = require("../../../assets/icons/chevronDown.png"); const dropdown = require("../../../assets/icons/chevronDown.png");
const options = [ const options = [
{ label: "JavaScript", value: "js" }, { label: "Pulse", value: "pulse" },
{ label: "Java", value: "java" }, { label: "Random", value: "random" },
{ label: "Python", value: "python" }, { label: "Rainbow", value: "rainbow" },
{ label: "C++", value: "c++", disabled: true },
{ label: "Perl", value: "perl" },
]; ];
export default function LightView() { function ColorLayer({ layerNumber, sharedColor, selected, onPress }) {
const [pickerValue, setPickerValue] = useState(""); const backgroundColorStyle = useAnimatedStyle(() => {
const [switchState, setSwitchState] = useState(false); return {
const [sliderValue, setSliderValue] = useState(0); backgroundColor: sharedColor.value,
const [isSwitchOn, setIsSwitchOn] = useState(false); };
const [selectedColorPicker, setSelectedColorPicker] = useState("#fff"); });
const ColorLayer = ({ layerNumber, color, onPress }) => { const contrastColor = useAnimatedStyle(() => {
const getContrastRatio = (hexColor) => { const getContrastRatio = (hexColor) => {
const hex = hexColor.replace("#", ""); const hex = hexColor.replace("#", "");
const r = parseInt(hex.substr(0, 2), 16); const r = parseInt(hex.substr(0, 2), 16);
@ -51,93 +40,153 @@ export default function LightView() {
return luminance > 0.5 ? "#000000" : "#ffffff"; return luminance > 0.5 ? "#000000" : "#ffffff";
}; };
const contrastColor = getContrastRatio(color); let obj = {};
return ( obj["color"] = getContrastRatio(sharedColor.value);
<TouchableRipple
borderless if (selected === true) {
style={{ obj.borderColor = obj.color;
borderRadius: 10, obj.borderBottomWidth = 4;
width: 40, } else {
height: 40, obj.borderBottomWidth = 0;
}} }
onPress={onPress}
rippleColor="rgba(0, 0, 0, .32)" return obj;
});
return (
<TouchableRipple
borderless
style={[{ width: 30, height: 30, borderRadius: 10, marginRight: 10 }]}
onPress={onPress}
rippleColor="rgba(0, 0, 0, .32)"
>
<Animated.View
style={[
{
width: "100%",
height: "100%",
justifyContent: "center",
alignItems: "center",
},
backgroundColorStyle,
]}
> >
<View <Animated.Text
style={[ style={[{ fontSize: 16, fontWeight: "bold" }, contrastColor]}
{
backgroundColor: "red",
width: "100%",
height: "100%",
justifyContent: "center",
alignItems: "center",
},
]}
> >
<Text {layerNumber}
style={{ color: contrastColor, fontSize: 24, fontWeight: "bold" }} </Animated.Text>
> </Animated.View>
{layerNumber} </TouchableRipple>
</Text> );
</View> }
</TouchableRipple>
);
};
const onToggleSwitch = () => setIsSwitchOn(!isSwitchOn); /*
function ColorSwatch({ color, onPress }) {
return (
<TouchableRipple
borderless
style={{
width: 25,
height: 25,
borderRadius: 16,
marginLeft: 5,
marginTop: 5,
}}
onPress={onPress}
rippleColor="rgba(0, 0, 0, .32)"
>
<View
style={{
width: "100%",
height: "100%",
backgroundColor: color,
}}
/>
</TouchableRipple>
);
} */
const customSwatches = new Array(12) export default function LightView() {
const [pickerValue, setPickerValue] = useState("");
const [switchState, setSwitchState] = useState(false);
const [sliderValue, setSliderValue] = useState(0);
const [selectedGlasLayer, setSelectedGlasLayer] = useState(1);
const [colorSwatchesFavorites, setColorSwatchesFavorites] = useState([]);
const [isExpertModeEnabled, setSwitchExpertModeEnabled] = useState(false);
/*const customSwatches = new Array(12)
.fill("#fff") .fill("#fff")
.map(() => colorKit.randomRgbColor().hex()); .map(() => colorKit.randomRgbColor().hex()); */
const selectedColor = useSharedValue(customSwatches[0]); const selectedColorPickerColor = useSharedValue("#fff");
const selectedColorLayer1 = useSharedValue(selectedColorPickerColor.value);
const selectedColorLayer2 = useSharedValue(selectedColorPickerColor.value);
const selectedColorLayer3 = useSharedValue(selectedColorPickerColor.value);
const selectedColorLayer4 = useSharedValue(selectedColorPickerColor.value);
useEffect(() => {
async function getModes() {
const data = await GetData("expertMode");
setSwitchExpertModeEnabled(data);
}
getModes();
}, []);
const onColorSelect = (color) => { const onColorSelect = (color) => {
selectedColor.value = color.hex; selectedColorPickerColor.value = color.hex;
switch (selectedGlasLayer) {
case 1:
selectedColorLayer1.value = color.hex;
break;
case 2:
selectedColorLayer2.value = color.hex;
break;
case 3:
selectedColorLayer3.value = color.hex;
break;
case 4:
selectedColorLayer4.value = color.hex;
break;
}
}; };
return ( return (
<View <Card>
style={{
borderRadius: 20,
backgroundColor: "#3f4042",
elevation: 5,
padding: 20,
}}
>
<Picker <Picker
label="Farbmodus" label="Farbmodus"
placeholder="Pick a Language" placeholder="Pick a Language"
useWheelPicker useWheelPicker
// useWheelPicker
value={pickerValue} value={pickerValue}
onChange={(nativePickerValue) => setPickerValue(nativePickerValue)} onChange={(nativePickerValue) => setPickerValue(nativePickerValue)}
trailingAccessory={<Icon source={dropdown} />} trailingAccessory={<Icon source={dropdown} />}
// containerStyle={{marginTop: 20}} //containerStyle={{ marginTop: 20 }}
// renderPicker={() => { //renderPicker={() => {
// return ( //return (
// <View> //<View>
// <Text>Open Native Picker!</Text> // <Text>Open Native Picker!</Text>
// </View> // </View>
// ); // );
// }} //}}
// topBarProps={{doneLabel: 'YES', cancelLabel: 'NO'}} //topBarProps={{ doneLabel: "YES", cancelLabel: "NO" }}
> >
{options.map((option) => ( {options.map((option) => (
<Picker.Item <Picker.Item
key={option.value} key={option.value}
value={option.value} value={option.value}
label={option.label} label={option.label}
disabled={option.disabled}
/> />
))} ))}
</Picker> </Picker>
<View row centerV> <View style={{ flexDirection: "row", alignItems: "center" }}>
<Switch value={switchState} onValueChange={(e) => setSwitchState(e)} /> <Switch value={switchState} onValueChange={(e) => setSwitchState(e)} />
<IconButton icon="brightness-7" iconColor={"#fff"} size={20} /> <IconButton icon="brightness-7" iconColor={"#fff"} size={20} />
<View flex> <View style={{ flex: 1 }}>
<Incubator.Slider <Incubator.Slider
value={sliderValue} value={sliderValue}
step={1} step={1}
@ -153,60 +202,115 @@ export default function LightView() {
</View> </View>
</View> </View>
<IconButton
icon="star-outline"
onPress={() => console.log("press star")}
/>
<Animated.View style={styles.animatedViewContainer}> <Animated.View style={styles.animatedViewContainer}>
<View row spread>
<ColorLayer
layerNumber={1}
color={selectedColor.value}
onPress={() => console.log("pressed")}
/>
<ColorLayer
layerNumber={2}
color="lime"
onPress={() => console.log("pressed")}
/>
<ColorLayer
layerNumber={3}
color="lime"
onPress={() => console.log("pressed")}
/>
<ColorLayer
layerNumber={4}
color="lime"
onPress={() => console.log("pressed")}
/>
</View>
<ColorPicker <ColorPicker
value={selectedColor.value} value={selectedColorPickerColor.value}
sliderThickness={25} sliderThickness={25}
thumbSize={27} thumbSize={27}
onChange={onColorSelect} onChange={onColorSelect}
> >
<Panel3 style={styles.panelStyle} /> <View
style={{
justifyContent: "center",
flexDirection: "row",
alignItems: "center",
marginBottom: 10,
}}
>
<ColorLayer
layerNumber={1}
sharedColor={selectedColorLayer1}
selected={selectedGlasLayer === 1}
onPress={() => {
setSelectedGlasLayer(1);
selectedColorPickerColor.value = selectedColorLayer1.value;
}}
/>
<ColorLayer
layerNumber={2}
sharedColor={selectedColorLayer2}
selected={selectedGlasLayer === 2}
onPress={() => {
setSelectedGlasLayer(2);
selectedColorPickerColor.value = selectedColorLayer2.value;
}}
/>
<ColorLayer
layerNumber={3}
sharedColor={selectedColorLayer3}
selected={selectedGlasLayer === 3}
onPress={() => {
setSelectedGlasLayer(3);
selectedColorPickerColor.value = selectedColorLayer3.value;
}}
/>
<ColorLayer
layerNumber={4}
sharedColor={selectedColorLayer4}
selected={selectedGlasLayer === 4}
onPress={() => {
setSelectedGlasLayer(4);
selectedColorPickerColor.value = selectedColorLayer4.value;
}}
/>
</View>
<BrightnessSlider style={styles.sliderStyle} /> <IconButton
style={{ position: "absolute", top: 40, right: -5 }}
icon={"star-outline"}
size={20}
onPress={() => {
setColorSwatchesFavorites([
...colorSwatchesFavorites,
selectedColorPickerColor.value,
]);
}}
/>
<View style={{ marginLeft: 30, marginRight: 30 }}>
<HueCircular containerStyle={styles.hueContainer} thumbShape="pill">
<Panel1 style={styles.panelStyle} />
</HueCircular>
</View>
<Swatches <Swatches
style={styles.swatchesContainer} style={styles.swatchesContainer}
swatchStyle={styles.swatchStyle} swatchStyle={styles.swatchStyle}
colors={customSwatches} colors={colorSwatchesFavorites}
/> />
<View style={styles.previewTxtContainer}> {isExpertModeEnabled && (
<InputWidget inputStyle={styles.inputWidget} iconColor="#707070" /> <View style={styles.previewTxtContainer}>
</View> <InputWidget
inputStyle={styles.inputWidget}
iconColor="#707070"
/>
</View>
)}
</ColorPicker> </ColorPicker>
</Animated.View> </Animated.View>
</View> </Card>
); );
} }
/*
<View row center style={{ flexWrap: "wrap", marginTop: 5 }}>
{colorSwatchesFavorites.map((color, i) => (
<ColorSwatch
key={i}
color={color}
onPress={() => {
console.log("press", color, renderKey);
selectedColorPickerColor.value = color;
setRenderKey((prevKey) => prevKey + 1);
}}
/>
))}
</View>
*/
// <BrightnessSlider style={styles.sliderStyle} /> <Panel3 style={styles.panelStyle} />
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
@ -245,10 +349,20 @@ const styles = StyleSheet.create({
shadowRadius: 6.27, shadowRadius: 6.27,
elevation: 5, elevation: 5,
}, },
hueContainer: {
justifyContent: "center",
backgroundColor: "#3f4042",
},
panelStyle: {
width: "60%",
height: "60%",
alignSelf: "center",
borderRadius: 16,
},
/*
panelStyle: { panelStyle: {
margin: 10, margin: 10,
marginLeft: 20, marginLeft: 20,
borderRadius: 16,
shadowColor: "#000", shadowColor: "#000",
shadowOffset: { shadowOffset: {
width: 0, width: 0,
@ -257,7 +371,7 @@ const styles = StyleSheet.create({
shadowOpacity: 0.25, shadowOpacity: 0.25,
shadowRadius: 3.84, shadowRadius: 3.84,
elevation: 5, elevation: 5,
}, },*/
sliderStyle: { sliderStyle: {
borderRadius: 20, borderRadius: 20,
marginTop: 20, marginTop: 20,
@ -276,14 +390,13 @@ const styles = StyleSheet.create({
borderColor: "#bebdbe", borderColor: "#bebdbe",
marginTop: 20, marginTop: 20,
paddingTop: 20, paddingTop: 20,
alignItems: "center", justifyContent: "center",
//flexWrap: "nowrap",
gap: 10, gap: 10,
}, },
swatchStyle: { swatchStyle: {
borderRadius: 20, borderRadius: 20,
height: 30, height: 25,
width: 30, width: 25,
margin: 0, margin: 0,
marginBottom: 0, marginBottom: 0,
marginHorizontal: 0, marginHorizontal: 0,

View File

@ -0,0 +1,33 @@
import { Text, View } from "react-native";
import Card from "../../Components/Card";
import { Incubator, Switch } from "react-native-ui-lib";
import { IconButton } from "react-native-paper";
import { useState } from "react";
export default function MotorView() {
const [switchState, setSwitchState] = useState(false);
const [sliderValue, setSliderValue] = useState(0);
return (
<Card>
<View style={{ flexDirection: "row", alignItems: "center" }}>
<Switch value={switchState} onValueChange={(e) => setSwitchState(e)} />
<IconButton icon="fan" iconColor={"#fff"} size={20} />
<View style={{ flex: 1 }}>
<Incubator.Slider
value={sliderValue}
step={1}
initialMinimumValue={0}
minimumValue={0}
maximumValue={100}
onValueChange={(v) => setSliderValue(v)}
containerStyle={{
flex: 1,
marginHorizontal: 8,
}}
/>
</View>
</View>
</Card>
);
}

View File

@ -0,0 +1,84 @@
import { Text, View } from "react-native";
import Card from "../../Components/Card";
import { Incubator, Switch } from "react-native-ui-lib";
import { useState } from "react";
import { AppStyles } from "../../utils";
import { Divider } from "../../Components/Divider";
export default function SettingsView() {
const [switchState, setSwitchState] = useState(false);
const [sliderValue, setSliderValue] = useState(0);
return (
<>
<Card>
<Text
style={[
AppStyles.typography20,
{
color: "#fff",
marginBottom: 10,
},
]}
>
Einstellungen
</Text>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
>
<View style={{ width: "80%" }}>
<Text style={[AppStyles.typography16, { color: "#fff" }]}>
WLAN im Standby
</Text>
<Text style={[AppStyles.typography14, { color: "#ddd" }]}>
Die WLAN-Verbindung bleibt bestehen, auch wenn das Gerät
ausgeschaltet ist. Bitte beachten Sie, dass dies zu einem erhöhten
Stromverbrauch führen kann.
</Text>
</View>
<Switch
value={switchState}
onValueChange={(e) => setSwitchState(e)}
/>
</View>
</Card>
<Card>
<Text
style={[
AppStyles.typography20,
{
color: "#fff",
marginBottom: 10,
},
]}
>
Geräteinformationen
</Text>
<Text style={([AppStyles.typography16], { color: "#fff" })}>
Gerätemodell
</Text>
<Text style={([AppStyles.typography14], { color: "#ddd" })}>
Shimmex Aurora
</Text>
<Divider />
<Text style={([AppStyles.typography16], { color: "#fff" })}>
Firmware Version
</Text>
<Text style={([AppStyles.typography14], { color: "#ddd" })}>1.0.1</Text>
<Divider />
<Text style={([AppStyles.typography16], { color: "#fff" })}>
Letzte Aktualisierung
</Text>
<Text style={([AppStyles.typography14], { color: "#ddd" })}>
11.07.2023 um 20:33 Uhr
</Text>
</Card>
</>
);
}

View File

@ -1,39 +1,3 @@
import { useState } from "react";
import { View, useWindowDimensions } from "react-native";
import { SceneMap, TabView } from "react-native-tab-view";
const FirstRoute = () => (
<View style={{ flex: 1, backgroundColor: "#ff4081" }} />
);
const SecondRoute = () => (
<View style={{ flex: 1, backgroundColor: "#673ab7" }} />
);
const ThirdRoute = () => <View style={{ flex: 1, backgroundColor: "red" }} />;
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
third: ThirdRoute,
});
export default function FaqScreen() { export default function FaqScreen() {
const layout = useWindowDimensions(); return <></>;
const [index, setIndex] = useState(0);
const [routes] = useState([
{ key: "first", title: "First" },
{ key: "second", title: "Second" },
{ key: "third", title: "Third" },
]);
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: layout.width }}
/>
);
} }

View File

@ -0,0 +1,105 @@
import { useEffect, useState } from "react";
import { Text, View } from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { Picker, Switch } from "react-native-ui-lib";
import Card from "../../Components/Card";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { AppStyles, GetData, GetMultipleData, StoreData } from "../../utils";
export default function SettingsScreen() {
const [switchDeveloperMode, setSwitchDeveloperMode] = useState(false);
const [switchExpertMode, setSwitchExpertMode] = useState(false);
const [selectedColorScheme, setSelectedColorScheme] = useState("auto");
const [selectedLanguage, setSelectedLanguage] = useState("de");
useEffect(() => {
async function getModes() {
const data = await GetMultipleData(["developerMode", "expertMode"]);
setSwitchDeveloperMode(data[0][1]);
setSwitchExpertMode(data[1][1]);
}
getModes();
}, []);
return (
<View style={{ height: "100%", backgroundColor: "#2e2e30" }}>
<Card>
<Text
style={[
AppStyles.typography20,
{
color: "#fff",
marginBottom: 10,
},
]}
>
Einstellungen
</Text>
<Picker
label="Sprache"
value={selectedLanguage}
onChange={(v) => setSelectedLanguage(v)}
fieldType={Picker.fieldTypes.settings}
showSearch
searchPlaceholder="Search a language"
searchStyle={{ color: "#fff", placeholderTextColor: "#fff" }}
>
<Picker.Item key={1} label="System default" value={"auto"} />
<Picker.Item key={2} label="Deutsch" value={"de"} />
<Picker.Item key={3} label="English" value={"en"} />
</Picker>
<Picker
label="Anzeigemodus"
value={selectedColorScheme}
onChange={(v) => setSelectedColorScheme(v)}
fieldType={Picker.fieldTypes.settings}
>
<Picker.Item key={1} label="System default" value={"auto"} />
<Picker.Item key={2} label="Dark" value={"dark"} />
<Picker.Item key={3} label="White" value={"white"} />
</Picker>
</Card>
<Card>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
>
<Text style={{ color: "#fff" }}>Developer Mode</Text>
<Switch
value={switchDeveloperMode}
onValueChange={(e) => {
setSwitchDeveloperMode(e);
StoreData("developerMode", e);
}}
/>
</View>
<View
style={{
marginTop: 10,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
>
<Text style={{ color: "#fff" }}>Expert Mode</Text>
<Switch
value={switchExpertMode}
onValueChange={async (e) => {
setSwitchExpertMode(e);
StoreData("expertMode", e);
}}
/>
</View>
</Card>
</View>
);
}

View File

@ -1,13 +1,27 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import { StyleSheet } from "react-native"; import { StyleSheet } from "react-native";
import { DefaultTheme } from "react-native-paper"; import { DefaultTheme } from "react-native-paper";
const Styles = StyleSheet.create({ export const AppStyles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: "#fff", backgroundColor: "#fff",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
}, },
typography20: {
fontSize: 20,
fontWeight: "bold",
lineHeight: 24,
},
typography16: {
fontSize: 16,
lineHeight: 24,
},
typography14: {
fontSize: 14,
lineHeight: 20,
},
}); });
export const Theme = { export const Theme = {
@ -56,3 +70,31 @@ export const Theme = {
mySegmentedButtonsCheckedColor: "#fff", mySegmentedButtonsCheckedColor: "#fff",
}, },
}; };
export async function StoreData(key, value) {
try {
const jsonValue = JSON.stringify(value);
await AsyncStorage.setItem(key, jsonValue);
} catch (e) {
console.log("err", e);
}
}
export async function GetData(key) {
try {
const jsonValue = await AsyncStorage.getItem(key);
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch (e) {
console.log("err", e);
}
}
export async function GetMultipleData(keys) {
try {
const data = await AsyncStorage.multiGet(keys);
const retrievedData = data.map(([key, value]) => [key, JSON.parse(value)]);
return retrievedData;
} catch (e) {
console.log("err", e);
}
}