i18n
parent
1a2f47bf7c
commit
835c97a20f
32
App.js
32
App.js
|
@ -1,6 +1,6 @@
|
|||
import "react-native-gesture-handler";
|
||||
import { StatusBar } from "expo-status-bar";
|
||||
import { Appearance, StyleSheet } from "react-native";
|
||||
import { Appearance, StyleSheet, Text, View } from "react-native";
|
||||
import { createDrawerNavigator } from "@react-navigation/drawer";
|
||||
import { NavigationContainer } from "@react-navigation/native";
|
||||
import SideBar from "./src/Components/SideBar";
|
||||
|
@ -16,8 +16,9 @@ import {
|
|||
} from "./src/utils";
|
||||
import DeviceScreen from "./src/Screens/Device";
|
||||
import SettingsScreen from "./src/Screens/Settings";
|
||||
import { useContext, useEffect } from "react";
|
||||
import { Suspense, useContext, useEffect } from "react";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import "./i18n";
|
||||
|
||||
const Drawer = createDrawerNavigator();
|
||||
|
||||
|
@ -42,7 +43,7 @@ export function MyApp() {
|
|||
appLanguage === null ? Constants.defaultLanguage : appLanguage
|
||||
);
|
||||
appContext.setAppColorScheme(
|
||||
appColorScheme === null ? Appearance.getColorScheme() : appColorScheme
|
||||
appColorScheme === null ? "auto" : appColorScheme
|
||||
);
|
||||
|
||||
appContext.setIsUserExpertModeEnabled(
|
||||
|
@ -88,17 +89,18 @@ export function MyApp() {
|
|||
|
||||
export default function App() {
|
||||
return (
|
||||
<AppProvider>
|
||||
<MyApp />
|
||||
</AppProvider>
|
||||
<Suspense
|
||||
fallback={
|
||||
<View
|
||||
style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
|
||||
>
|
||||
<Text>Loading...</Text>
|
||||
</View>
|
||||
}
|
||||
>
|
||||
<AppProvider>
|
||||
<MyApp />
|
||||
</AppProvider>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#fff",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
});
|
||||
|
|
|
@ -9,3 +9,7 @@ https://pictogrammers.com/library/mdi/
|
|||
# RNUILib
|
||||
|
||||
https://wix.github.io/react-native-ui-lib/docs/getting-started/setup
|
||||
|
||||
https://stackoverflow.com/questions/68243384/dark-mode-usecolorscheme-always-returns-light-on-android
|
||||
|
||||
https://stackoverflow.com/questions/70493788/i18nextpluralresolver-your-environment-seems-not-to-be-intl-api-compatible-u
|
||||
|
|
12
app.json
12
app.json
|
@ -5,23 +5,23 @@
|
|||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/icon.png",
|
||||
"userInterfaceStyle": "light",
|
||||
"userInterfaceStyle": "automatic",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"assetBundlePatterns": [
|
||||
"**/*"
|
||||
],
|
||||
"assetBundlePatterns": ["**/*"],
|
||||
"ios": {
|
||||
"supportsTablet": true
|
||||
"supportsTablet": true,
|
||||
"userInterfaceStyle": "automatic"
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
"foregroundImage": "./assets/adaptive-icon.png",
|
||||
"backgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
"userInterfaceStyle": "automatic"
|
||||
},
|
||||
"web": {
|
||||
"favicon": "./assets/favicon.png"
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
import de from "./locales/de.json";
|
||||
import en from "./locales/en.json";
|
||||
|
||||
const resources = {
|
||||
de: {
|
||||
translation: de,
|
||||
},
|
||||
en: {
|
||||
translation: en,
|
||||
},
|
||||
};
|
||||
|
||||
i18n
|
||||
.use(initReactI18next) // passes i18n down to react-i18next
|
||||
.init({
|
||||
compatibilityJSON: "v3",
|
||||
resources,
|
||||
lng: "en", // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources
|
||||
// you can use the i18n.changeLanguage function to change the language manually: https://www.i18next.com/overview/api#changelanguage
|
||||
// if you're using a language detector, do not define the lng option
|
||||
interpolation: {
|
||||
escapeValue: false, // react already safes from xss
|
||||
},
|
||||
});
|
||||
|
||||
export default i18n;
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"test": "Einstellungen",
|
||||
"sideBar": {
|
||||
"devicesTitle": "Geräte",
|
||||
"settings": "Einstellungen",
|
||||
"faq": "FAQ",
|
||||
"feedback": "Feedback geben"
|
||||
},
|
||||
"screens": {
|
||||
"device": {
|
||||
"settings": {
|
||||
"settingsTitle": "Einstellungen",
|
||||
"wifiStandByTitle": "WLAN im Standby",
|
||||
"wifiStandByDescription": "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.",
|
||||
"deviceInformationTitle": "Geräteinformationen",
|
||||
"deviceModelTitle": "Gerätemodell",
|
||||
"deviceFirmwareVersionTitle": "Firmware Version",
|
||||
"deviceLastUpdated": "Letzte Aktualisierung"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"settingsCardTitle": "Einstellungen",
|
||||
"languageText": "Sprache",
|
||||
"appColorSchemeText": "Anzeigemodus",
|
||||
"appColorSchemePicker": {
|
||||
"auto": "Systemvoreinstellung",
|
||||
"dark": "Dunkel",
|
||||
"light": "Hell"
|
||||
},
|
||||
"expertModeTitle": "Experten Modus",
|
||||
"expertModeDescription": "Durch das Einschalten werden zusätzliche Funktionen in der App freigeschaltet, wie beispielsweise die Möglichkeit, benutzerdefinierte Farbcodes anzugeben."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"test": "Settings",
|
||||
"sideBar": {
|
||||
"devicesTitle": "Devices",
|
||||
"settings": "Settings",
|
||||
"faq": "FAQ",
|
||||
"feedback": "Give feedback"
|
||||
},
|
||||
"screens": {
|
||||
"device": {
|
||||
"settings": {
|
||||
"settingsTitle": "Settings",
|
||||
"wifiStandByTitle": "WLAN in standby",
|
||||
"wifiStandByDescription": "The WLAN connection remains established even if the device is switched off. Please note that this can lead to increased power consumption.",
|
||||
"deviceInformationTitle": "Device information",
|
||||
"deviceModelTitle": "Device model",
|
||||
"deviceFirmwareVersionTitle": "Firmware Version",
|
||||
"deviceLastUpdated": "Last updated"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"settingsCardTitle": "Settings",
|
||||
"languageText": "Language",
|
||||
"appColorSchemeText": "Appearance",
|
||||
"appColorSchemePicker": {
|
||||
"auto": "System default",
|
||||
"dark": "Dark",
|
||||
"light": "Light"
|
||||
},
|
||||
"expertModeTitle": "Expert mode",
|
||||
"expertModeDescription": "Turning it on unlocks additional features in the app, such as the ability to specify custom color codes."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,10 @@
|
|||
"@react-navigation/native-stack": "^6.9.13",
|
||||
"expo": "~48.0.18",
|
||||
"expo-status-bar": "~1.4.4",
|
||||
"i18next": "^23.2.11",
|
||||
"i18next-browser-languagedetector": "^7.1.0",
|
||||
"react": "18.2.0",
|
||||
"react-i18next": "^13.0.2",
|
||||
"react-native": "0.71.8",
|
||||
"react-native-gesture-handler": "~2.9.0",
|
||||
"react-native-pager-view": "6.1.2",
|
||||
|
@ -8091,6 +8094,14 @@
|
|||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/html-parse-stringify": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
|
||||
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
|
||||
"dependencies": {
|
||||
"void-elements": "3.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
|
@ -8126,6 +8137,36 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "23.2.11",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.2.11.tgz",
|
||||
"integrity": "sha512-MA4FsxOjyCaOZtRDB4yuwjCvqYEioD4G4LlXOn7SO3rnQUlxTufyLsOqfL9MKakeLRBkefe8bqcs0D6Z/xFk1w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://locize.com"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://locize.com/i18next.html"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.22.5"
|
||||
}
|
||||
},
|
||||
"node_modules/i18next-browser-languagedetector": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.1.0.tgz",
|
||||
"integrity": "sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.19.4"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
@ -12105,6 +12146,27 @@
|
|||
"react": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-i18next": {
|
||||
"version": "13.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-13.0.2.tgz",
|
||||
"integrity": "sha512-NEVxC32v0oR4egwYM0QM0WE93AiJG5r0NTXTL8mhQfAhsMfDS2fSO6jpluyfsfypP988KzUQrAXncspcJ7+GHA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.22.5",
|
||||
"html-parse-stringify": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"i18next": ">= 23.2.3",
|
||||
"react": ">= 16.8.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
|
@ -14351,6 +14413,14 @@
|
|||
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
|
||||
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
|
||||
},
|
||||
"node_modules/void-elements": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/walker": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
"@react-navigation/native-stack": "^6.9.13",
|
||||
"expo": "~48.0.18",
|
||||
"expo-status-bar": "~1.4.4",
|
||||
"i18next": "^23.2.11",
|
||||
"i18next-browser-languagedetector": "^7.1.0",
|
||||
"react": "18.2.0",
|
||||
"react-i18next": "^13.0.2",
|
||||
"react-native": "0.71.8",
|
||||
"react-native-gesture-handler": "~2.9.0",
|
||||
"react-native-pager-view": "6.1.2",
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
import { useContext } from "react";
|
||||
import { AppContext, AppStyles } from "../../utils";
|
||||
import Icon from "@expo/vector-icons/MaterialCommunityIcons";
|
||||
import { Modal, Text, TouchableOpacity, View } from "react-native";
|
||||
import { Divider } from "../Divider";
|
||||
|
||||
export default function PickerModal({ isOpen, setIsOpen, items }) {
|
||||
const appContext = useContext(AppContext);
|
||||
const closeModal = () => setIsOpen(false);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={isOpen}
|
||||
animationType="slide"
|
||||
onRequestClose={() => closeModal()}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: appContext.appTheme.backgroundColor,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
console.log("press");
|
||||
setIsOpen(false);
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name="window-close"
|
||||
size={24}
|
||||
style={{ marginLeft: 10, marginTop: 20, marginBottom: 20 }}
|
||||
color={appContext.appTheme.icon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
{items.map((item, i) => {
|
||||
return item.selected ? (
|
||||
<View key={i}>
|
||||
<TouchableOpacity onPress={() => closeModal()}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
marginLeft: 20,
|
||||
marginRight: 20,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
AppStyles.typography16,
|
||||
{ color: appContext.appTheme.text },
|
||||
]}
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
<Icon
|
||||
name="check"
|
||||
size={24}
|
||||
color={appContext.appTheme.colors.primary}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<Divider />
|
||||
</View>
|
||||
) : (
|
||||
<View key={i}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
closeModal();
|
||||
item.onPress();
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
AppStyles.typography16,
|
||||
{ marginLeft: 20, color: appContext.appTheme.text },
|
||||
]}
|
||||
>
|
||||
{item.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Divider />
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</Modal>
|
||||
);
|
||||
}
|
|
@ -4,10 +4,11 @@ import { Image, Text, TouchableOpacity, View } from "react-native";
|
|||
import { AppContext, AppStyles } from "../../utils";
|
||||
import { Divider } from "../Divider";
|
||||
import Icon from "@expo/vector-icons/MaterialCommunityIcons";
|
||||
import { useIsFocused } from "@react-navigation/native";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function Sidebar(props) {
|
||||
const appContext = useContext(AppContext);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const MyDrawerItem = ({
|
||||
label,
|
||||
|
@ -53,7 +54,7 @@ export default function Sidebar(props) {
|
|||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
onPress={() => console.log("Pressed")}
|
||||
onPress={() => console.log("Pressed power")}
|
||||
style={{ right: -30 }}
|
||||
>
|
||||
<Icon
|
||||
|
@ -118,7 +119,7 @@ export default function Sidebar(props) {
|
|||
{ marginLeft: 10, marginTop: 10, color: appContext.appTheme.text },
|
||||
]}
|
||||
>
|
||||
Geräte
|
||||
{t("sideBar.devicesTitle")}
|
||||
</Text>
|
||||
<DrawerContentScrollView contentContainerStyle={{ paddingTop: 0 }}>
|
||||
{["Turtle"].map((item, i) => (
|
||||
|
@ -137,19 +138,19 @@ export default function Sidebar(props) {
|
|||
<View style={{ justifyContent: "flex-end" }}>
|
||||
<Divider style={{ marginLeft: 10, marginRight: 10 }} />
|
||||
<MyDrawerItem
|
||||
label={"FAQ"}
|
||||
label={t("sideBar.faq")}
|
||||
onPress={() => props.navigation.navigate("FAQ")}
|
||||
iconName="frequently-asked-questions"
|
||||
routeName="FAQ"
|
||||
/>
|
||||
<MyDrawerItem
|
||||
label={"Feedback geben"}
|
||||
label={t("sideBar.feedback")}
|
||||
onPress={() => props.navigation.navigate("Feedback")}
|
||||
iconName="comment-quote"
|
||||
routeName="Feedback"
|
||||
/>
|
||||
<MyDrawerItem
|
||||
label={"Einstellungen"}
|
||||
label={t("sideBar.settings")}
|
||||
onPress={() => props.navigation.navigate("Settings")}
|
||||
iconName="cog"
|
||||
routeName="Settings"
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
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 { useContext, useState } from "react";
|
||||
import { AppContext, AppStyles } from "../../utils";
|
||||
import { Divider } from "../../Components/Divider";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function SettingsView() {
|
||||
const appContext = useContext(AppContext);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [switchState, setSwitchState] = useState(false);
|
||||
const [sliderValue, setSliderValue] = useState(0);
|
||||
|
||||
|
@ -16,12 +20,12 @@ export default function SettingsView() {
|
|||
style={[
|
||||
AppStyles.typography20,
|
||||
{
|
||||
color: "#fff",
|
||||
color: appContext.appTheme.text,
|
||||
marginBottom: 10,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Einstellungen
|
||||
{t("screens.device.settings.settingsTitle")}
|
||||
</Text>
|
||||
|
||||
<View
|
||||
|
@ -33,12 +37,10 @@ export default function SettingsView() {
|
|||
>
|
||||
<View style={{ width: "80%" }}>
|
||||
<Text style={[AppStyles.typography16, { color: "#fff" }]}>
|
||||
WLAN im Standby
|
||||
{t("screens.device.settings.wifiStandByTitle")}
|
||||
</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.
|
||||
{t("screens.device.settings.wifiStandByDescription")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
|
@ -58,22 +60,22 @@ export default function SettingsView() {
|
|||
},
|
||||
]}
|
||||
>
|
||||
Geräteinformationen
|
||||
{t("screens.device.settings.deviceInformationTitle")}
|
||||
</Text>
|
||||
<Text style={([AppStyles.typography16], { color: "#fff" })}>
|
||||
Gerätemodell
|
||||
{t("screens.device.settings.deviceModelTitle")}
|
||||
</Text>
|
||||
<Text style={([AppStyles.typography14], { color: "#ddd" })}>
|
||||
Shimmex Aurora
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text style={([AppStyles.typography16], { color: "#fff" })}>
|
||||
Firmware Version
|
||||
{t("screens.device.settings.deviceFirmwareVersionTitle")}
|
||||
</Text>
|
||||
<Text style={([AppStyles.typography14], { color: "#ddd" })}>1.0.1</Text>
|
||||
<Divider />
|
||||
<Text style={([AppStyles.typography16], { color: "#fff" })}>
|
||||
Letzte Aktualisierung
|
||||
{t("screens.device.settings.deviceLastUpdated")}
|
||||
</Text>
|
||||
<Text style={([AppStyles.typography14], { color: "#ddd" })}>
|
||||
11.07.2023 um 20:33 Uhr
|
||||
|
|
|
@ -2,13 +2,17 @@ import { useContext, useState } from "react";
|
|||
import { Modal, Text, TouchableOpacity, View } from "react-native";
|
||||
import { Picker, Switch } from "react-native-ui-lib";
|
||||
import Card from "../../Components/Card";
|
||||
import { AppContext, AppStyles } from "../../utils";
|
||||
import { AppContext, AppStyles, Constants } from "../../utils";
|
||||
import { Divider } from "../../Components/Divider";
|
||||
import Icon from "@expo/vector-icons/MaterialCommunityIcons";
|
||||
import PickerModal from "../../Components/PickerModal";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function SettingsScreen() {
|
||||
const appContext = useContext(AppContext);
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const [modalAppColorSchemeVisible, setAppColorSchemeModalVisible] =
|
||||
useState(false);
|
||||
const [modalAppLanguageVisible, setModalAppLanguageVisible] = useState(false);
|
||||
|
||||
return (
|
||||
<View
|
||||
|
@ -27,33 +31,64 @@ export default function SettingsScreen() {
|
|||
},
|
||||
]}
|
||||
>
|
||||
Einstellungen
|
||||
{t("screens.settings.settingsCardTitle")}
|
||||
</Text>
|
||||
|
||||
<Picker
|
||||
label="Sprache"
|
||||
value={appContext.appLanguage}
|
||||
onChange={(v) => appContext.setAppLanguage(v)}
|
||||
fieldType={Picker.fieldTypes.settings}
|
||||
showSearch
|
||||
searchPlaceholder="Search a language"
|
||||
searchStyle={{ color: "#fff", placeholderTextColor: "#fff" }}
|
||||
<TouchableOpacity
|
||||
onPress={() => setModalAppLanguageVisible(true)}
|
||||
style={{ marginBottom: 6 }}
|
||||
>
|
||||
<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>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
AppStyles.typography14,
|
||||
{ color: appContext.appTheme.text },
|
||||
]}
|
||||
>
|
||||
{t("screens.settings.languageText")}
|
||||
</Text>
|
||||
<Text style={{ color: appContext.appTheme.colors.primary }}>
|
||||
{
|
||||
Constants.languages.find(
|
||||
(language) => language.name === appContext.appLanguage
|
||||
).label
|
||||
}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity onPress={() => setAppColorSchemeModalVisible(true)}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
AppStyles.typography14,
|
||||
{ color: appContext.appTheme.text },
|
||||
]}
|
||||
>
|
||||
{t("screens.settings.appColorSchemeText")}
|
||||
</Text>
|
||||
<Text style={{ color: appContext.appTheme.colors.primary }}>
|
||||
{appContext.appColorScheme === "auto"
|
||||
? t("screens.settings.appColorSchemePicker.auto")
|
||||
: appContext.appColorScheme === "dark"
|
||||
? t("screens.settings.appColorSchemePicker.dark")
|
||||
: t("screens.settings.appColorSchemePicker.light")}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Picker
|
||||
label="Anzeigemodus"
|
||||
value={appContext.appColorScheme}
|
||||
onChange={(v) => appContext.setAppColorScheme(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="Light" value={"light"} />
|
||||
</Picker>
|
||||
<Divider />
|
||||
<View
|
||||
style={{
|
||||
|
@ -69,7 +104,7 @@ export default function SettingsScreen() {
|
|||
{ color: appContext.appTheme.text },
|
||||
]}
|
||||
>
|
||||
Experten Modus
|
||||
{t("screens.settings.expertModeTitle")}
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
|
@ -77,9 +112,7 @@ export default function SettingsScreen() {
|
|||
{ color: appContext.appTheme.textSecondary },
|
||||
]}
|
||||
>
|
||||
Durch das Einschalten werden zusätzliche Funktionen in der App
|
||||
freigeschaltet, wie beispielsweise die Möglichkeit,
|
||||
benutzerdefinierte Farbcodes anzugeben.
|
||||
{t("screens.settings.expertModeDescription")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
|
@ -106,108 +139,38 @@ export default function SettingsScreen() {
|
|||
/>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity onPress={() => setModalVisible(true)}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: appContext.appTheme.text }}>
|
||||
Anzeigemodus
|
||||
</Text>
|
||||
<Text style={{ color: appContext.appTheme.colors.primary }}>
|
||||
{appContext.appColorScheme}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<PickerModal
|
||||
isOpen={modalAppColorSchemeVisible}
|
||||
setIsOpen={setAppColorSchemeModalVisible}
|
||||
items={[
|
||||
{
|
||||
label: t("screens.settings.appColorSchemePicker.auto"),
|
||||
onPress: () => appContext.setAppColorScheme("auto"),
|
||||
},
|
||||
{
|
||||
label: t("screens.settings.appColorSchemePicker.dark"),
|
||||
onPress: () => appContext.setAppColorScheme("dark"),
|
||||
selected: appContext.appColorScheme === "dark",
|
||||
},
|
||||
{
|
||||
label: t("screens.settings.appColorSchemePicker.light"),
|
||||
onPress: () => appContext.setAppColorScheme("light"),
|
||||
selected: appContext.appColorScheme === "light",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
visible={modalVisible}
|
||||
animationType="slide"
|
||||
onRequestClose={() => {
|
||||
setModalVisible(!modalVisible);
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity onPress={() => setModalVisible(false)}>
|
||||
<Icon
|
||||
name="window-close"
|
||||
size={24}
|
||||
style={{ marginLeft: 10, marginTop: 20, marginBottom: 20 }}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={[AppStyles.typography16, { marginLeft: 20 }]}>
|
||||
System default
|
||||
</Text>
|
||||
|
||||
<Divider />
|
||||
|
||||
{appContext.appColorScheme === "dark" ? (
|
||||
<TouchableOpacity onPress={() => setModalVisible(false)}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
marginLeft: 20,
|
||||
marginRight: 20,
|
||||
}}
|
||||
>
|
||||
<Text style={[AppStyles.typography16]}>Dark</Text>
|
||||
<Icon
|
||||
name="check"
|
||||
size={24}
|
||||
color={appContext.appTheme.colors.primary}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
setModalVisible(false);
|
||||
appContext.setAppColorScheme("dark");
|
||||
}}
|
||||
>
|
||||
<Text style={[AppStyles.typography16, { marginLeft: 20 }]}>
|
||||
Dark
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
<Divider />
|
||||
|
||||
{appContext.appColorScheme === "light" ? (
|
||||
<TouchableOpacity onPress={() => setModalVisible(false)}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
marginLeft: 20,
|
||||
marginRight: 20,
|
||||
}}
|
||||
>
|
||||
<Text style={[AppStyles.typography16]}>Light</Text>
|
||||
<Icon
|
||||
name="check"
|
||||
size={24}
|
||||
color={appContext.appTheme.colors.primary}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
setModalVisible(false);
|
||||
appContext.setAppColorScheme("light");
|
||||
}}
|
||||
>
|
||||
<Text style={[AppStyles.typography16, { marginLeft: 20 }]}>
|
||||
Light
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</Modal>
|
||||
<PickerModal
|
||||
isOpen={modalAppLanguageVisible}
|
||||
setIsOpen={setModalAppLanguageVisible}
|
||||
items={Constants.languages.map((language) => {
|
||||
return {
|
||||
label: language.label,
|
||||
onPress: () => appContext.setAppLanguage(language.name),
|
||||
selected: appContext.appLanguage === language.name,
|
||||
};
|
||||
})}
|
||||
/>
|
||||
</Card>
|
||||
</View>
|
||||
);
|
||||
|
|
30
src/utils.js
30
src/utils.js
|
@ -1,10 +1,20 @@
|
|||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { createContext, useState } from "react";
|
||||
import { StyleSheet } from "react-native";
|
||||
import { Colors } from "react-native-ui-lib";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Appearance, StyleSheet } from "react-native";
|
||||
|
||||
export const Constants = {
|
||||
defaultLanguage: "de",
|
||||
languages: [
|
||||
{
|
||||
name: "de",
|
||||
label: "Deutsch",
|
||||
},
|
||||
{
|
||||
name: "en",
|
||||
label: "English",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const AppStyles = StyleSheet.create({
|
||||
|
@ -45,7 +55,7 @@ const DarkAppTheme = {
|
|||
},
|
||||
},
|
||||
divider: "#ddd",
|
||||
icon: "#fff",
|
||||
icon: "#ddd",
|
||||
};
|
||||
|
||||
const LightAppTheme = {
|
||||
|
@ -122,23 +132,23 @@ export function AppProvider({ children }) {
|
|||
// TODO: only while development
|
||||
const [isUserDeveloperModeEnabled, setIsUserDeveloperModeEnabled] =
|
||||
useState(false);
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
const saveAppColorScheme = async (value) => {
|
||||
StoreData("appColorScheme", value);
|
||||
setAppColorScheme(value);
|
||||
|
||||
if (value === "dark") {
|
||||
setAppTheme(DarkAppTheme);
|
||||
console.log("dark");
|
||||
} else {
|
||||
setAppTheme(LightAppTheme);
|
||||
console.log("light");
|
||||
}
|
||||
let colorScheme;
|
||||
|
||||
colorScheme = value === "auto" ? Appearance.getColorScheme() : value;
|
||||
|
||||
setAppTheme(colorScheme === "light" ? LightAppTheme : DarkAppTheme);
|
||||
};
|
||||
|
||||
const saveAppLanguage = async (value) => {
|
||||
StoreData("appLanguage", value);
|
||||
setAppLanguage(value);
|
||||
i18n.changeLanguage(value);
|
||||
};
|
||||
|
||||
const saveUserExpertMode = async (value) => {
|
||||
|
|
Loading…
Reference in New Issue