main
alex 2023-07-12 14:29:08 +00:00
parent e62e6182f9
commit 315281c202
8 changed files with 297 additions and 117 deletions

67
App.js
View File

@ -1,17 +1,26 @@
import "react-native-gesture-handler"; import "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar"; import { StatusBar } from "expo-status-bar";
import { StyleSheet } from "react-native"; import { Appearance, StyleSheet } from "react-native";
import { createDrawerNavigator } from "@react-navigation/drawer"; import { createDrawerNavigator } from "@react-navigation/drawer";
import { NavigationContainer } from "@react-navigation/native"; import { NavigationContainer } from "@react-navigation/native";
import SideBar from "./src/Components/SideBar"; import SideBar from "./src/Components/SideBar";
import FaqScreen from "./src/Screens/FAQ"; import FaqScreen from "./src/Screens/FAQ";
import FeedbackScreen from "./src/Screens/Feedback"; import FeedbackScreen from "./src/Screens/Feedback";
import { PaperProvider } from "react-native-paper"; import { PaperProvider } from "react-native-paper";
import { Theme } from "./src/utils"; import {
AppContext,
AppProvider,
Constants,
GetData,
GetDataFromList,
GetMultipleData,
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"; import SettingsScreen from "./src/Screens/Settings";
import { useContext, useEffect } from "react";
Colors.loadSchemes({ Colors.loadSchemes({
light: { light: {
@ -43,11 +52,53 @@ const Drawer = createDrawerNavigator();
SECONDARY: "#9b59b6", SECONDARY: "#9b59b6",
*/ */
export default function App() { export function MyApp() {
const appContext = useContext(AppContext);
useEffect(() => {
const loadData = async () => {
const data = await GetMultipleData([
"appLanguage",
"appColorScheme",
"userExpertMode",
"userDeveloperMode",
]);
const appLanguage = GetDataFromList(data, "appLanguage");
const appColorScheme = GetDataFromList(data, "appColorScheme");
const userExpertMode = GetDataFromList(data, "userExpertMode");
const userDeveloperMode = GetDataFromList(data, "userDeveloperMode");
appContext.setAppLanguage(
appLanguage === null ? Constants.defaultLanguage : appLanguage
);
appContext.setAppColorScheme(
appColorScheme === null ? Appearance.getColorScheme() : appColorScheme
);
appContext.setIsUserExpertModeEnabled(
userExpertMode == null ? false : userExpertMode
);
appContext.setUserIsDeveloperModeEnabled(
userDeveloperMode == null ? false : userDeveloperMode
);
};
loadData();
}, []);
return ( return (
<PaperProvider theme={Theme}> <PaperProvider theme={Theme}>
<NavigationContainer> <NavigationContainer>
<Drawer.Navigator drawerContent={(props) => <SideBar {...props} />}> <Drawer.Navigator
screenOptions={{
drawerStyle: {
backgroundColor: appContext.appTheme.drawer.backgroundColor,
},
}}
drawerContent={(props) => <SideBar {...props} />}
>
<Drawer.Screen name="Splash X3" component={DeviceScreen} /> <Drawer.Screen name="Splash X3" component={DeviceScreen} />
<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} />
@ -61,6 +112,14 @@ export default function App() {
); );
} }
export default function App() {
return (
<AppProvider>
<MyApp />
</AppProvider>
);
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,

View File

@ -1,6 +1,10 @@
import { useContext } from "react";
import { ScrollView, View } from "react-native"; import { ScrollView, View } from "react-native";
import { AppContext } from "../../utils";
export default function Card({ children }) { export default function Card({ children }) {
const appContext = useContext(AppContext);
return ( return (
<View <View
style={{ style={{
@ -13,7 +17,7 @@ export default function Card({ children }) {
<View <View
style={{ style={{
borderRadius: 20, borderRadius: 20,
backgroundColor: "#3f4042", backgroundColor: appContext.appTheme.card.backgroundColor,
elevation: 5, elevation: 5,
padding: 20, padding: 20,
}} }}

View File

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

View File

@ -1,36 +1,55 @@
import { DrawerContentScrollView, DrawerItem } from "@react-navigation/drawer"; import { DrawerContentScrollView, DrawerItem } from "@react-navigation/drawer";
import { useEffect, useState } from "react"; import { useContext } from "react";
import { Image, StyleSheet, View } from "react-native"; import { Image, Text, View } from "react-native";
import { Divider, Text } from "react-native-paper"; import { AppContext, AppStyles } from "../../utils";
import { GetData } from "../../utils"; import { Divider } from "../Divider";
export default function Sidebar(props) { export default function Sidebar(props) {
const [isDeveloperModeEnabled, setIsDeveloperModeEnabled] = useState(false); const appContext = useContext(AppContext);
useEffect(() => { const MyDrawerItem = ({ label, onPress }) => {
async function getDeveloperMode() { return (
setIsDeveloperModeEnabled(await GetData("developerMode")); <DrawerItem
} label={label}
onPress={onPress}
getDeveloperMode(); inactiveTintColor={appContext.appTheme.drawer.item.inactiveTintColor}
}, []); activeTintColor={appContext.appTheme.drawer.item.activeTintColor}
/>
);
};
return ( return (
<> <>
{isDeveloperModeEnabled ? ( {appContext.isUserDeveloperModeEnabled ? (
<Image <Image
source={require("../../../assets/image.png")} source={require("../../../assets/image.png")}
style={styles.image} style={{
width: "100%",
height: 250,
}}
/> />
) : ( ) : (
<View style={[styles.image, { backgroundColor: "#ddd" }]} /> <View
style={[
{
width: "100%",
height: 250,
},
{ backgroundColor: "#ddd" },
]}
/>
)} )}
<Text variant="titleLarge" style={{ fontWeight: "bold", marginLeft: 10 }}> <Text
style={[
AppStyles.typography20,
{ marginLeft: 10, marginTop: 10, color: appContext.appTheme.text },
]}
>
Geräte Geräte
</Text> </Text>
<DrawerContentScrollView contentContainerStyle={{ paddingTop: 0 }}> <DrawerContentScrollView contentContainerStyle={{ paddingTop: 0 }}>
{["Splash X3", "Spinner V6"].map((item, i) => ( {["Splash X3", "Spinner V6"].map((item, i) => (
<DrawerItem <MyDrawerItem
key={i} key={i}
label={item} label={item}
onPress={() => props.navigation.navigate(item)} onPress={() => props.navigation.navigate(item)}
@ -40,15 +59,15 @@ export default function Sidebar(props) {
<View style={{ justifyContent: "flex-end" }}> <View style={{ justifyContent: "flex-end" }}>
<Divider style={{ marginLeft: 10, marginRight: 10 }} /> <Divider style={{ marginLeft: 10, marginRight: 10 }} />
<DrawerItem <MyDrawerItem
label={"FAQ"} label={"FAQ"}
onPress={() => props.navigation.navigate("FAQ")} onPress={() => props.navigation.navigate("FAQ")}
/> />
<DrawerItem <MyDrawerItem
label={"Feedback geben"} label={"Feedback geben"}
onPress={() => props.navigation.navigate("Feedback")} onPress={() => props.navigation.navigate("Feedback")}
/> />
<DrawerItem <MyDrawerItem
label={"Einstellungen"} label={"Einstellungen"}
onPress={() => props.navigation.navigate("Settings")} onPress={() => props.navigation.navigate("Settings")}
/> />
@ -56,10 +75,3 @@ export default function Sidebar(props) {
</> </>
); );
} }
const styles = StyleSheet.create({
image: {
width: "100%",
height: 250,
},
});

View File

@ -1,9 +1,9 @@
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { Image, ScrollView, StyleSheet, View, Text } from "react-native"; import { Image, ScrollView, StyleSheet, View, Text } from "react-native";
import { IconButton } from "react-native-paper"; import { IconButton } from "react-native-paper";
import { Colors } from "react-native-ui-lib"; import { Colors } from "react-native-ui-lib";
import LightView from "./light"; import LightView from "./light";
import { GetData } from "../../utils"; import { AppContext, GetData } from "../../utils";
import MotorView from "./motor"; import MotorView from "./motor";
import SettingsView from "./settings"; import SettingsView from "./settings";
@ -19,18 +19,8 @@ const iconButtonActiveColor = "#e67e22";
const iconButtonNotActiveColor = "#fff"; const iconButtonNotActiveColor = "#fff";
export default function DeviceScreen() { export default function DeviceScreen() {
const appContext = useContext(AppContext);
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) {
@ -49,10 +39,10 @@ export default function DeviceScreen() {
<View <View
style={{ style={{
height: "100%", height: "100%",
backgroundColor: "#2e2e30", backgroundColor: appContext.appTheme.backgroundColor,
}} }}
> >
{isDeveloperModeEnabled ? ( {appContext.isUserDeveloperModeEnabled ? (
<Image <Image
source={require("../../../assets/image.png")} source={require("../../../assets/image.png")}
style={styles.image} style={styles.image}

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { StyleSheet, Text, View } from "react-native"; import { StyleSheet, Text, View } from "react-native";
import { IconButton, TouchableRipple } from "react-native-paper"; import { IconButton, TouchableRipple } from "react-native-paper";
import Animated, { import Animated, {
@ -12,7 +12,7 @@ import ColorPicker, {
HueCircular, HueCircular,
Panel1, Panel1,
} from "reanimated-color-picker"; } from "reanimated-color-picker";
import { GetData } from "../../utils"; import { AppContext, GetData } from "../../utils";
import Card from "../../Components/Card"; import Card from "../../Components/Card";
const dropdown = require("../../../assets/icons/chevronDown.png"); const dropdown = require("../../../assets/icons/chevronDown.png");
@ -109,12 +109,12 @@ function ColorSwatch({ color, onPress }) {
} */ } */
export default function LightView() { export default function LightView() {
const appContext = useContext(AppContext);
const [pickerValue, setPickerValue] = useState(""); const [pickerValue, setPickerValue] = useState("");
const [switchState, setSwitchState] = useState(false); const [switchState, setSwitchState] = useState(false);
const [sliderValue, setSliderValue] = useState(0); const [sliderValue, setSliderValue] = useState(0);
const [selectedGlasLayer, setSelectedGlasLayer] = useState(1); const [selectedGlasLayer, setSelectedGlasLayer] = useState(1);
const [colorSwatchesFavorites, setColorSwatchesFavorites] = useState([]); const [colorSwatchesFavorites, setColorSwatchesFavorites] = useState([]);
const [isExpertModeEnabled, setSwitchExpertModeEnabled] = useState(false);
/*const customSwatches = new Array(12) /*const customSwatches = new Array(12)
.fill("#fff") .fill("#fff")
@ -126,16 +126,6 @@ export default function LightView() {
const selectedColorLayer3 = useSharedValue(selectedColorPickerColor.value); const selectedColorLayer3 = useSharedValue(selectedColorPickerColor.value);
const selectedColorLayer4 = 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) => {
selectedColorPickerColor.value = color.hex; selectedColorPickerColor.value = color.hex;
@ -279,7 +269,7 @@ export default function LightView() {
colors={colorSwatchesFavorites} colors={colorSwatchesFavorites}
/> />
{isExpertModeEnabled && ( {appContext.isUserExpertModeEnabled && (
<View style={styles.previewTxtContainer}> <View style={styles.previewTxtContainer}>
<InputWidget <InputWidget
inputStyle={styles.inputWidget} inputStyle={styles.inputWidget}

View File

@ -1,36 +1,34 @@
import { useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { Text, View } from "react-native"; import { Text, View } from "react-native";
import { ScrollView } from "react-native-gesture-handler"; import { ScrollView } from "react-native-gesture-handler";
import { Picker, Switch } from "react-native-ui-lib"; import { Picker, Switch } from "react-native-ui-lib";
import Card from "../../Components/Card"; import Card from "../../Components/Card";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import { AppStyles, GetData, GetMultipleData, StoreData } from "../../utils"; import {
AppContext,
AppStyles,
GetData,
GetMultipleData,
StoreData,
} from "../../utils";
import { Divider } from "../../Components/Divider";
export default function SettingsScreen() { export default function SettingsScreen() {
const [switchDeveloperMode, setSwitchDeveloperMode] = useState(false); const appContext = useContext(AppContext);
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 ( return (
<View style={{ height: "100%", backgroundColor: "#2e2e30" }}> <View
style={{
height: "100%",
backgroundColor: appContext.appTheme.backgroundColor,
}}
>
<Card> <Card>
<Text <Text
style={[ style={[
AppStyles.typography20, AppStyles.typography20,
{ {
color: "#fff", color: appContext.appTheme.text,
marginBottom: 10, marginBottom: 10,
}, },
]} ]}
@ -40,8 +38,8 @@ export default function SettingsScreen() {
<Picker <Picker
label="Sprache" label="Sprache"
value={selectedLanguage} value={appContext.appLanguage}
onChange={(v) => setSelectedLanguage(v)} onChange={(v) => appContext.setAppLanguage(v)}
fieldType={Picker.fieldTypes.settings} fieldType={Picker.fieldTypes.settings}
showSearch showSearch
searchPlaceholder="Search a language" searchPlaceholder="Search a language"
@ -54,14 +52,47 @@ export default function SettingsScreen() {
<Picker <Picker
label="Anzeigemodus" label="Anzeigemodus"
value={selectedColorScheme} value={appContext.appColorScheme}
onChange={(v) => setSelectedColorScheme(v)} onChange={(v) => appContext.setAppColorScheme(v)}
fieldType={Picker.fieldTypes.settings} fieldType={Picker.fieldTypes.settings}
> >
<Picker.Item key={1} label="System default" value={"auto"} /> <Picker.Item key={1} label="System default" value={"auto"} />
<Picker.Item key={2} label="Dark" value={"dark"} /> <Picker.Item key={2} label="Dark" value={"dark"} />
<Picker.Item key={3} label="White" value={"white"} /> <Picker.Item key={3} label="Light" value={"light"} />
</Picker> </Picker>
<Divider />
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
>
<View style={{ width: "80%" }}>
<Text
style={[
AppStyles.typography16,
{ color: appContext.appTheme.text },
]}
>
Experten Modus
</Text>
<Text
style={[
AppStyles.typography14,
{ color: appContext.appTheme.textSecondary },
]}
>
Durch das Einschalten werden zusätzliche Funktionen in der App
freigeschaltet, wie beispielsweise die Möglichkeit,
benutzerdefinierte Farbcodes anzugeben.
</Text>
</View>
<Switch
value={appContext.isUserExpertModeEnabled}
onValueChange={(e) => appContext.setIsUserExpertModeEnabled(e)}
/>
</View>
</Card> </Card>
<Card> <Card>
@ -72,31 +103,12 @@ export default function SettingsScreen() {
justifyContent: "space-between", justifyContent: "space-between",
}} }}
> >
<Text style={{ color: "#fff" }}>Developer Mode</Text> <Text style={{ color: appContext.appTheme.text }}>
Developer Mode
</Text>
<Switch <Switch
value={switchDeveloperMode} value={appContext.isUserDeveloperModeEnabled}
onValueChange={(e) => { onValueChange={(e) => appContext.setUserIsDeveloperModeEnabled(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> </View>
</Card> </Card>

View File

@ -1,14 +1,13 @@
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import { createContext, useState } from "react";
import { StyleSheet } from "react-native"; import { StyleSheet } from "react-native";
import { DefaultTheme } from "react-native-paper"; import { DefaultTheme } from "react-native-paper";
export const Constants = {
defaultLanguage: "de",
};
export const AppStyles = StyleSheet.create({ export const AppStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
typography20: { typography20: {
fontSize: 20, fontSize: 20,
fontWeight: "bold", fontWeight: "bold",
@ -24,6 +23,46 @@ export const AppStyles = StyleSheet.create({
}, },
}); });
const DarkAppTheme = {
colors: {
primary: "#e67e22",
secondary: "#9b59b6",
},
text: "#fff",
textSecondary: "#ddd",
backgroundColor: "#2e2e30",
card: {
backgroundColor: "#3f4042",
},
drawer: {
backgroundColor: "#2e2e30",
item: {
inactiveTintColor: "#fff",
activeTintColor: "lime",
},
},
};
const LightAppTheme = {
colors: {
primary: "#e67e22",
secondary: "#9b59b6",
},
text: "#000",
textSecondary: "#555",
backgroundColor: "#fff",
card: {
backgroundColor: "#fff",
},
drawer: {
backgroundColor: "#fff",
item: {
inactiveTintColor: "#fff",
activeTintColor: "lime",
},
},
};
export const Theme = { export const Theme = {
...DefaultTheme, ...DefaultTheme,
colors: { colors: {
@ -98,3 +137,72 @@ export async function GetMultipleData(keys) {
console.log("err", e); console.log("err", e);
} }
} }
export function GetDataFromList(list, key) {
return list.find((v) => v[0] === key)[1];
}
const appContextPreview = {
appColorScheme: "",
appLanguage: "",
isUserExpertModeEnabled: "",
isUserDeveloperModeEnabled: "",
appTheme: DarkAppTheme,
};
export const AppContext = createContext(appContextPreview);
export function AppProvider({ children }) {
const [appLanguage, setAppLanguage] = useState("de");
const [appColorScheme, setAppColorScheme] = useState("");
const [appTheme, setAppTheme] = useState(DarkAppTheme);
const [isUserExpertModeEnabled, setIsUserExpertModeEnabled] = useState(false);
// TODO: only while development
const [isUserDeveloperModeEnabled, setIsUserDeveloperModeEnabled] =
useState(false);
const saveAppColorScheme = async (value) => {
StoreData("appColorScheme", value);
setAppColorScheme(value);
if (value === "dark") {
setAppTheme(DarkAppTheme);
} else {
setAppTheme(LightAppTheme);
}
};
const saveAppLanguage = async (value) => {
StoreData("appLanguage", value);
setAppLanguage(value);
};
const saveUserExpertMode = async (value) => {
StoreData("userExpertMode", value);
setIsUserExpertModeEnabled(value);
};
// TODO: only while development
const saveUserDeveloperMode = async (value) => {
StoreData("userDeveloperMode", value);
setIsUserDeveloperModeEnabled(value);
};
return (
<AppContext.Provider
value={{
appLanguage: appLanguage,
setAppLanguage: saveAppLanguage,
appColorScheme: appColorScheme,
setAppColorScheme: saveAppColorScheme,
appTheme: appTheme,
isUserExpertModeEnabled: isUserExpertModeEnabled,
setIsUserExpertModeEnabled: saveUserExpertMode,
isUserDeveloperModeEnabled: isUserDeveloperModeEnabled,
setUserIsDeveloperModeEnabled: saveUserDeveloperMode,
}}
>
{children}
</AppContext.Provider>
);
}