no devices found and buttons for factory reset and disconnect from device
parent
22d4a8bae7
commit
aa46586b98
22
App.js
22
App.js
|
@ -40,7 +40,6 @@ import MotorEditActionModalContent, {
|
||||||
} from "./src/Screens/Device/modals/EditActions/Motor";
|
} from "./src/Screens/Device/modals/EditActions/Motor";
|
||||||
import WaitXSecondsEditActionModalContent from "./src/Screens/Device/modals/EditActions/Wait";
|
import WaitXSecondsEditActionModalContent from "./src/Screens/Device/modals/EditActions/Wait";
|
||||||
import StopEditActionModalContent from "./src/Screens/Device/modals/EditActions/Stop";
|
import StopEditActionModalContent from "./src/Screens/Device/modals/EditActions/Stop";
|
||||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
||||||
import SearchForNewDevicesModalContent from "./src/Screens/SearchForNewDevices";
|
import SearchForNewDevicesModalContent from "./src/Screens/SearchForNewDevices";
|
||||||
|
|
||||||
const Drawer = createDrawerNavigator();
|
const Drawer = createDrawerNavigator();
|
||||||
|
@ -48,6 +47,9 @@ const Stack = createStackNavigator();
|
||||||
|
|
||||||
const SettingsScreen = lazy(() => import("./src/Screens/Settings"));
|
const SettingsScreen = lazy(() => import("./src/Screens/Settings"));
|
||||||
const HelpScreen = lazy(() => import("./src/Screens/Help"));
|
const HelpScreen = lazy(() => import("./src/Screens/Help"));
|
||||||
|
const NoDevicesConnectedScreen = lazy(() =>
|
||||||
|
import("./src/Screens/NoDevicesConnected")
|
||||||
|
);
|
||||||
|
|
||||||
export function MyApp() {
|
export function MyApp() {
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
|
@ -363,6 +365,11 @@ function MyDrawer() {
|
||||||
|
|
||||||
<Drawer.Screen name="Help" component={HelpScreenStack} />
|
<Drawer.Screen name="Help" component={HelpScreenStack} />
|
||||||
<Drawer.Screen name="Settings" component={SettingsScreenStack} />
|
<Drawer.Screen name="Settings" component={SettingsScreenStack} />
|
||||||
|
|
||||||
|
<Drawer.Screen
|
||||||
|
name="_noDevicesConnected"
|
||||||
|
component={NoDevicesConnectedStack}
|
||||||
|
/>
|
||||||
</Drawer.Navigator>
|
</Drawer.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -379,6 +386,19 @@ const DeviceScreenStack = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const NoDevicesConnectedStack = (props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyScreenStack
|
||||||
|
name="noDevicesConnected"
|
||||||
|
pageTitle={t("screens.noDevicesConnected.pageTitle")}
|
||||||
|
component={NoDevicesConnectedScreen}
|
||||||
|
navigation={props.navigation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const HelpScreenStack = (props) => {
|
const HelpScreenStack = (props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"devicesTitle": "Geräte",
|
"devicesTitle": "Geräte",
|
||||||
"settings": "Einstellungen",
|
"settings": "Einstellungen",
|
||||||
"help": "Hilfe"
|
"help": "Hilfe",
|
||||||
|
"noDevicesConnected": "Keine Geräte verbunden",
|
||||||
|
"textButtonSearchForNewDevices": "Suche nach neuen Geräten"
|
||||||
},
|
},
|
||||||
"screens": {
|
"screens": {
|
||||||
"device": {
|
"device": {
|
||||||
|
@ -20,11 +22,30 @@
|
||||||
"deviceModelText": "Gerätemodell",
|
"deviceModelText": "Gerätemodell",
|
||||||
"deviceFirmwareVersionText": "Firmware Version",
|
"deviceFirmwareVersionText": "Firmware Version",
|
||||||
"deviceLastUpdatedText": "Letzte Aktualisierung",
|
"deviceLastUpdatedText": "Letzte Aktualisierung",
|
||||||
|
"deviceMacAddressText": "MAC-Adresse",
|
||||||
"deviceIPAddressText": "IP-Adresse",
|
"deviceIPAddressText": "IP-Adresse",
|
||||||
"modalSettingsChangeDeviceDisplayName": {
|
"modalSettingsChangeDeviceDisplayName": {
|
||||||
"pageTitle": "Gerätename ändern",
|
"pageTitle": "Gerätename ändern",
|
||||||
"textTitle": "Gerätename",
|
"textTitle": "Gerätename",
|
||||||
"textDescription": "Der Name wird lokal auf dem Gerät gespeichert und dient dazu, die verbundenen Geräte in der App voneinander zu unterscheiden."
|
"textDescription": "Der Name wird lokal auf dem Gerät gespeichert und dient dazu, die verbundenen Geräte in der App voneinander zu unterscheiden."
|
||||||
|
},
|
||||||
|
"closeConnectionTitle": "Verbindung zum Gerät trennen",
|
||||||
|
"closeConnectionDescription": "Die Verbindung zum Gerät wird getrennt. Um das Gerät wieder zu verwenden, müssen Sie es erneut mit der App verbinden.",
|
||||||
|
"closeConnectionButton": "Verbindung trennen",
|
||||||
|
"resetToFactorySettingsTitle": "Auf Werkseinstellungen zurücksetzen",
|
||||||
|
"resetToFactorySettingsDescription": "Alle Einstellungen werden auf die Werkseinstellungen zurückgesetzt. Dies kann nicht rückgängig gemacht werden.",
|
||||||
|
"resetToFactorySettingsButton": "Zurücksetzen",
|
||||||
|
"bottomSheetModalCloseConnection": {
|
||||||
|
"headerTitle": "Verbindung trennen",
|
||||||
|
"description": "Die Verbindung zum Gerät wird getrennt. Um das Gerät wieder zu verwenden, müssen Sie es erneut mit der App verbinden.",
|
||||||
|
"cancelButton": "Abbrechen",
|
||||||
|
"confirmButton": "Verbindung trennen"
|
||||||
|
},
|
||||||
|
"bottomSheetModalResetToFactorySettings": {
|
||||||
|
"headerTitle": "Auf Werkseinstellungen zurücksetzen",
|
||||||
|
"description": "Alle Einstellungen werden auf die Werkseinstellungen zurückgesetzt. Dies kann nicht rückgängig gemacht werden.",
|
||||||
|
"cancelButton": "Abbrechen",
|
||||||
|
"confirmButton": "Zurücksetzen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scenes": {
|
"scenes": {
|
||||||
|
@ -159,6 +180,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"noDevicesConnected": {
|
||||||
|
"pageTitle": "Keine Geräte verbunden",
|
||||||
|
"textDescription": "Es sind keine Geräte mit der App verbunden. Verbinden Sie ein Gerät, um es zu verwenden.",
|
||||||
|
"buttonSearchForNewDevices": "Nach neuen Geräten suchen"
|
||||||
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"pageTitle": "Hilfe"
|
"pageTitle": "Hilfe"
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"devicesTitle": "Devices",
|
"devicesTitle": "Devices",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"help": "Help"
|
"help": "Help",
|
||||||
|
"noDevicesConnected": "No devices connected",
|
||||||
|
"textButtonSearchForNewDevices": "Search for new devices"
|
||||||
},
|
},
|
||||||
"screens": {
|
"screens": {
|
||||||
"device": {
|
"device": {
|
||||||
|
@ -20,11 +22,30 @@
|
||||||
"deviceModelText": "Device model",
|
"deviceModelText": "Device model",
|
||||||
"deviceFirmwareVersionText": "Firmware Version",
|
"deviceFirmwareVersionText": "Firmware Version",
|
||||||
"deviceLastUpdatedText": "Last updated",
|
"deviceLastUpdatedText": "Last updated",
|
||||||
|
"deviceMacAddressText": "MAC address",
|
||||||
"deviceIPAddressText": "IP address",
|
"deviceIPAddressText": "IP address",
|
||||||
"modalSettingsChangeDeviceDisplayName": {
|
"modalSettingsChangeDeviceDisplayName": {
|
||||||
"pageTitle": "Customize device name",
|
"pageTitle": "Customize device name",
|
||||||
"textTitle": "Device name",
|
"textTitle": "Device name",
|
||||||
"textDescription": "The name of the device is stored locally on the device and serves you to distinguish the connected devices from each other in the app."
|
"textDescription": "The name of the device is stored locally on the device and serves you to distinguish the connected devices from each other in the app."
|
||||||
|
},
|
||||||
|
"closeConnectionTitle": "Disconnect from device",
|
||||||
|
"closeConnectionDescription": "The connection to the device will be disconnected. To use the device again, you'll need to reconnect it with the app.",
|
||||||
|
"closeConnectionButton": "Disconnect",
|
||||||
|
"resetToFactorySettingsTitle": "Reset to Factory Settings",
|
||||||
|
"resetToFactorySettingsDescription": "All settings will be reset to their factory defaults. This action cannot be undone.",
|
||||||
|
"resetToFactorySettingsButton": "Reset",
|
||||||
|
"bottomSheetModalCloseConnection": {
|
||||||
|
"headerTitle": "Disconnect Connection",
|
||||||
|
"description": "The connection to the device is being disconnected. To use the device again, you will need to reconnect it with the app.",
|
||||||
|
"cancelButton": "Cancel",
|
||||||
|
"confirmButton": "Disconnect"
|
||||||
|
},
|
||||||
|
"bottomSheetModalResetToFactorySettings": {
|
||||||
|
"headerTitle": "Reset to Factory Settings",
|
||||||
|
"description": "All settings will be reset to their factory defaults. This cannot be undone.",
|
||||||
|
"cancelButton": "Cancel",
|
||||||
|
"confirmButton": "Reset"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scenes": {
|
"scenes": {
|
||||||
|
@ -159,6 +180,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"noDevicesConnected": {
|
||||||
|
"pageTitle": "No devices connected"
|
||||||
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"pageTitle": "Help"
|
"pageTitle": "Help"
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"react-native": "0.71.8",
|
"react-native": "0.71.8",
|
||||||
"react-native-draggable-flatlist": "^4.0.1",
|
"react-native-draggable-flatlist": "^4.0.1",
|
||||||
"react-native-gesture-handler": "~2.9.0",
|
"react-native-gesture-handler": "~2.9.0",
|
||||||
|
"react-native-linear-gradient": "^2.8.2",
|
||||||
"react-native-pager-view": "6.1.2",
|
"react-native-pager-view": "6.1.2",
|
||||||
"react-native-reanimated": "~2.14.4",
|
"react-native-reanimated": "~2.14.4",
|
||||||
"react-native-safe-area-context": "4.5.0",
|
"react-native-safe-area-context": "4.5.0",
|
||||||
|
@ -11939,6 +11940,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz",
|
||||||
"integrity": "sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ=="
|
"integrity": "sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-linear-gradient": {
|
||||||
|
"version": "2.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.2.tgz",
|
||||||
|
"integrity": "sha512-hgmCsgzd58WNcDCyPtKrvxsaoETjb/jLGxis/dmU3Aqm2u4ICIduj4ECjbil7B7pm9OnuTkmpwXu08XV2mpg8g==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native-pager-view": {
|
"node_modules/react-native-pager-view": {
|
||||||
"version": "6.1.2",
|
"version": "6.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-6.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-6.1.2.tgz",
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
"react-native": "0.71.8",
|
"react-native": "0.71.8",
|
||||||
"react-native-draggable-flatlist": "^4.0.1",
|
"react-native-draggable-flatlist": "^4.0.1",
|
||||||
"react-native-gesture-handler": "~2.9.0",
|
"react-native-gesture-handler": "~2.9.0",
|
||||||
|
"react-native-linear-gradient": "^2.8.2",
|
||||||
"react-native-pager-view": "6.1.2",
|
"react-native-pager-view": "6.1.2",
|
||||||
"react-native-reanimated": "~2.14.4",
|
"react-native-reanimated": "~2.14.4",
|
||||||
"react-native-safe-area-context": "4.5.0",
|
"react-native-safe-area-context": "4.5.0",
|
||||||
|
|
|
@ -15,9 +15,15 @@ export default function MyButton({
|
||||||
disabled,
|
disabled,
|
||||||
onPress,
|
onPress,
|
||||||
buttonLeftComponent,
|
buttonLeftComponent,
|
||||||
|
buttonBackgroundColor,
|
||||||
}) {
|
}) {
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
|
|
||||||
|
const bBackgroundColor =
|
||||||
|
buttonBackgroundColor === undefined
|
||||||
|
? appContext.appTheme.colors.primary
|
||||||
|
: buttonBackgroundColor;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableHighlight
|
<TouchableHighlight
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
@ -27,7 +33,7 @@ export default function MyButton({
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
{
|
{
|
||||||
backgroundColor: appContext.appTheme.colors.primary,
|
backgroundColor: bBackgroundColor,
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
padding: 10,
|
padding: 10,
|
||||||
},
|
},
|
||||||
|
@ -37,7 +43,12 @@ export default function MyButton({
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{buttonLeftComponent}
|
{buttonLeftComponent}
|
||||||
<Text style={{ textAlign: "center", color: appContext.appTheme.text }}>
|
<Text
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
color: appContext.appTheme.buttonTextColor,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useRef, useState } from "react";
|
||||||
import { AppContext, AppStyles, ModalContainer } from "../../utils";
|
import { AppContext, AppStyles, ModalContainer } from "../../utils";
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
|
@ -7,13 +7,21 @@ import {
|
||||||
Text,
|
Text,
|
||||||
TouchableWithoutFeedback,
|
TouchableWithoutFeedback,
|
||||||
View,
|
View,
|
||||||
|
FlatList,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import MyIcon from "../Icon";
|
import MyIcon from "../Icon";
|
||||||
import MyTextInput from "../TextInput";
|
import MyTextInput from "../TextInput";
|
||||||
import { MyIconButton } from "../Button";
|
import { MyIconButton } from "../Button";
|
||||||
import { Divider } from "../Divider";
|
import { Divider } from "../Divider";
|
||||||
import MyPressable from "../Pressable";
|
import MyPressable from "../Pressable";
|
||||||
import { FlatList } from "react-native-gesture-handler";
|
import Animated, {
|
||||||
|
Easing,
|
||||||
|
useAnimatedStyle,
|
||||||
|
useSharedValue,
|
||||||
|
withSpring,
|
||||||
|
withTiming,
|
||||||
|
} from "react-native-reanimated";
|
||||||
|
import { StatusBar } from "expo-status-bar";
|
||||||
|
|
||||||
//const modalContentStyle = { margin: 10, paddingTop: 10 };
|
//const modalContentStyle = { margin: 10, paddingTop: 10 };
|
||||||
|
|
||||||
|
@ -333,34 +341,74 @@ export function MyBottomSheetModal({
|
||||||
}) {
|
}) {
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
|
|
||||||
|
const translateY = useSharedValue(0);
|
||||||
|
const opacity = useSharedValue(0);
|
||||||
|
|
||||||
|
translateY.value = withTiming(isOpen ? 0 : modalHeight, {
|
||||||
|
duration: 250,
|
||||||
|
easing: Easing.ease,
|
||||||
|
});
|
||||||
|
|
||||||
|
opacity.value = withTiming(isOpen ? 1 : 0, {
|
||||||
|
duration: 250,
|
||||||
|
easing: Easing.ease,
|
||||||
|
});
|
||||||
|
|
||||||
|
const animatedStyle = useAnimatedStyle(() => ({
|
||||||
|
transform: [{ translateY: translateY.value }],
|
||||||
|
opacity: opacity.value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
translateY.value = withTiming(modalHeight, {
|
||||||
|
duration: 100,
|
||||||
|
easing: Easing.ease,
|
||||||
|
});
|
||||||
|
opacity.value = withTiming(0, { duration: 100, easing: Easing.ease });
|
||||||
|
setTimeout(() => closeModal(), 100);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
statusBarTranslucent
|
||||||
visible={isOpen}
|
visible={isOpen}
|
||||||
transparent
|
transparent
|
||||||
animationType="slide"
|
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
onRequestClose={() => closeModal()}
|
onRequestClose={() => handleCloseModal()}
|
||||||
>
|
>
|
||||||
<TouchableWithoutFeedback onPress={() => closeModal()}>
|
<TouchableWithoutFeedback onPress={() => handleCloseModal()}>
|
||||||
<View style={{ flex: 1 }} />
|
|
||||||
</TouchableWithoutFeedback>
|
|
||||||
|
|
||||||
<View>
|
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: appContext.appTheme.card.backgroundColor,
|
flex: 1,
|
||||||
height: modalHeight,
|
backgroundColor:
|
||||||
borderTopLeftRadius: 20,
|
appContext.appTheme.modal.transparentBackgroundColor,
|
||||||
borderTopRightRadius: 20,
|
|
||||||
paddingTop: 12,
|
|
||||||
shadowRadius: 8,
|
|
||||||
shadowOffset: {
|
|
||||||
width: 0,
|
|
||||||
height: -10,
|
|
||||||
},
|
|
||||||
shadowColor: "#000000",
|
|
||||||
elevation: 6,
|
|
||||||
}}
|
}}
|
||||||
|
/>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: appContext.appTheme.modal.transparentBackgroundColor,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
backgroundColor: appContext.appTheme.card.backgroundColor,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
height: modalHeight,
|
||||||
|
paddingTop: 12,
|
||||||
|
shadowRadius: 8,
|
||||||
|
shadowOffset: {
|
||||||
|
width: 0,
|
||||||
|
height: -10,
|
||||||
|
},
|
||||||
|
shadowColor: "#000000",
|
||||||
|
elevation: 6,
|
||||||
|
},
|
||||||
|
animatedStyle,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
|
@ -384,12 +432,12 @@ export function MyBottomSheetModal({
|
||||||
iconSize={24}
|
iconSize={24}
|
||||||
iconColor={appContext.appTheme.icon}
|
iconColor={appContext.appTheme.icon}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
onPress={() => closeModal()}
|
onPress={() => handleCloseModal()}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</Animated.View>
|
||||||
</View>
|
</View>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,7 +17,11 @@ export default function MyResult({ text, iconName }) {
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
AppStyles.typography16,
|
AppStyles.typography16,
|
||||||
{ color: appContext.appTheme.text, marginTop: 10 },
|
{
|
||||||
|
color: appContext.appTheme.text,
|
||||||
|
marginTop: 10,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
|
|
|
@ -5,7 +5,8 @@ import { AppContext, AppSelectedUserDevice, AppStyles } from "../../utils";
|
||||||
import { Divider } from "../Divider";
|
import { Divider } from "../Divider";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import MyIcon from "../Icon";
|
import MyIcon from "../Icon";
|
||||||
import { MyIconButton } from "../Button";
|
import { MyIconButton, MyTextButton } from "../Button";
|
||||||
|
import MyResult from "../Result";
|
||||||
|
|
||||||
export default function Sidebar(props) {
|
export default function Sidebar(props) {
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
|
@ -104,6 +105,9 @@ export default function Sidebar(props) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openModalSearchForNewDevices = () =>
|
||||||
|
props.navigation.navigate("modalSearchForNewDevices");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{appContext.isUserDeveloperModeEnabled ? (
|
{appContext.isUserDeveloperModeEnabled ? (
|
||||||
|
@ -147,23 +151,38 @@ export default function Sidebar(props) {
|
||||||
iconName="plus"
|
iconName="plus"
|
||||||
iconSize={24}
|
iconSize={24}
|
||||||
style={{ padding: 2 }}
|
style={{ padding: 2 }}
|
||||||
onPress={() => props.navigation.navigate("modalSearchForNewDevices")}
|
onPress={() => openModalSearchForNewDevices()}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<DrawerContentScrollView contentContainerStyle={{ paddingTop: 0 }}>
|
<DrawerContentScrollView contentContainerStyle={{ paddingTop: 0 }}>
|
||||||
{appContext.devices.map((device, i) => (
|
{appContext.devices.length > 0 ? (
|
||||||
<MyDrawerItem
|
appContext.devices.map((device) => (
|
||||||
key={device.id}
|
<MyDrawerItem
|
||||||
_deviceId={device.id}
|
key={device.id}
|
||||||
isDevice
|
_deviceId={device.id}
|
||||||
deviceName={device.displayName}
|
isDevice
|
||||||
deviceModel={device.deviceModel}
|
deviceName={device.displayName}
|
||||||
onPress={() => props.navigation.navigate(device.displayName)}
|
deviceModel={device.deviceModel}
|
||||||
iconName={"glass-stange"}
|
onPress={() => props.navigation.navigate(device.displayName)}
|
||||||
routeName={device.displayName}
|
iconName={"glass-stange"}
|
||||||
/>
|
routeName={device.displayName}
|
||||||
))}
|
/>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<View style={{ alignItems: "center", marginTop: 20, gap: 10 }}>
|
||||||
|
<MyResult
|
||||||
|
text={t("sideBar.noDevicesConnected")}
|
||||||
|
iconName={"selection-search"}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MyTextButton
|
||||||
|
title={t("sideBar.textButtonSearchForNewDevices")}
|
||||||
|
actionColor
|
||||||
|
onPress={() => openModalSearchForNewDevices()}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</DrawerContentScrollView>
|
</DrawerContentScrollView>
|
||||||
|
|
||||||
<View style={{ justifyContent: "flex-end" }}>
|
<View style={{ justifyContent: "flex-end" }}>
|
||||||
|
|
|
@ -64,6 +64,8 @@ const windowHeight = Dimensions.get("window").height;
|
||||||
|
|
||||||
const modalHeight = windowHeight * 0.6; // 60 % of device screen
|
const modalHeight = windowHeight * 0.6; // 60 % of device screen
|
||||||
|
|
||||||
|
console.log("modalHe", modalHeight);
|
||||||
|
|
||||||
export default function WaitEditActionModalContent({ navigation, route }) {
|
export default function WaitEditActionModalContent({ navigation, route }) {
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
|
@ -132,21 +132,6 @@ export default function SceneView({ navigation }) {
|
||||||
|
|
||||||
const lastSceneAction = deviceSceneActions[deviceSceneActions.length - 1];
|
const lastSceneAction = deviceSceneActions[deviceSceneActions.length - 1];
|
||||||
|
|
||||||
console.log(
|
|
||||||
"lastSceneAction",
|
|
||||||
lastSceneAction?.type === Constants.actionType.stop
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
) : (
|
|
||||||
<ActionListItem
|
|
||||||
navigation={navigation}
|
|
||||||
device={device}
|
|
||||||
item={deviceSceneActions[deviceSceneActions.length - 1]}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{device.selectedScene === "" ? (
|
{device.selectedScene === "" ? (
|
||||||
|
|
|
@ -1,41 +1,58 @@
|
||||||
import { ScrollView, Text, View } from "react-native";
|
import { Button, ScrollView, Text, View } from "react-native";
|
||||||
import Card from "../../Components/Card";
|
import Card from "../../Components/Card";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { AppContext, AppSelectedUserDevice, AppStyles } from "../../utils";
|
import {
|
||||||
|
AppContext,
|
||||||
|
AppSelectedUserDevice,
|
||||||
|
AppStyles,
|
||||||
|
GetDevice,
|
||||||
|
} from "../../utils";
|
||||||
import { Divider } from "../../Components/Divider";
|
import { Divider } from "../../Components/Divider";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import MySwitch from "../../Components/Switch";
|
import MySwitch from "../../Components/Switch";
|
||||||
import { MyIconButton } from "../../Components/Button";
|
import MyButton, { MyIconButton, MyTextButton } from "../../Components/Button";
|
||||||
|
import { MyBottomSheetModal, MyConfirmModal } from "../../Components/Modal";
|
||||||
|
|
||||||
export default function SettingsView({ navigation }) {
|
export default function SettingsView({ navigation }) {
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [switchState, setSwitchState] = useState(false);
|
const [switchState, setSwitchState] = useState(false);
|
||||||
const [textDeviceIdHidden, setTextDeviceIdHidden] = useState(true);
|
const [textDeviceIdHidden, setTextDeviceIdHidden] = useState(true);
|
||||||
|
const [textDeviceMacAddressHidden, setTextDeviceMacAddressHidden] =
|
||||||
|
useState(true);
|
||||||
|
const [
|
||||||
|
isBottomSheetModalCloseConnectionOpen,
|
||||||
|
setIsBottomSheetModalCloseConnectionOpen,
|
||||||
|
] = useState(false);
|
||||||
|
const [
|
||||||
|
isBottomSheetModalResetToFactorySettingsOpen,
|
||||||
|
setIsBottomSheetModalResetToFactorySettingsOpen,
|
||||||
|
] = useState(false);
|
||||||
|
|
||||||
const device = appContext.devices.find(
|
const device = GetDevice(appContext.devices);
|
||||||
(d) => d.id === AppSelectedUserDevice.current.id
|
|
||||||
);
|
|
||||||
|
|
||||||
const SettingsText = ({ containerStyle, title, description, hidden }) => {
|
const SettingsText = ({ containerStyle, title, description, hidden }) => {
|
||||||
return (
|
return (
|
||||||
<View style={containerStyle}>
|
<View style={[containerStyle]}>
|
||||||
<Text
|
<View>
|
||||||
style={
|
<Text
|
||||||
([AppStyles.typography16], { color: appContext.appTheme.text })
|
style={
|
||||||
}
|
([AppStyles.typography16], { color: appContext.appTheme.text })
|
||||||
>
|
}
|
||||||
{title}
|
>
|
||||||
</Text>
|
{title}
|
||||||
<Text
|
</Text>
|
||||||
selectable
|
|
||||||
style={
|
<Text
|
||||||
([AppStyles.typography14],
|
selectable
|
||||||
{ color: appContext.appTheme.textSecondary })
|
style={
|
||||||
}
|
([AppStyles.typography14],
|
||||||
>
|
{ color: appContext.appTheme.textSecondary })
|
||||||
{hidden ? "************" : description}
|
}
|
||||||
</Text>
|
>
|
||||||
|
{hidden ? "************" : description}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -46,9 +63,39 @@ export default function SettingsView({ navigation }) {
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const deleteDeviceFromApp = () => {
|
||||||
|
console.log("dev", appContext.devices.length);
|
||||||
|
|
||||||
|
appContext.setDevices((devices) =>
|
||||||
|
devices.filter((d) => d.id !== device.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
appContext.setDeviceScenes((scenes) =>
|
||||||
|
scenes.filter((s) => s.deviceId !== device.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
appContext.setDeviceSceneActions((actions) =>
|
||||||
|
actions.filter((a) => a.deviceId !== device.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("dev", appContext.devices.length);
|
||||||
|
|
||||||
|
// show no devices connected screen if there are no devices left
|
||||||
|
if (appContext.devices.length < 2) {
|
||||||
|
navigation.navigate("_noDevicesConnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove device from app async storage if it is not already handled by appContext
|
||||||
|
};
|
||||||
|
|
||||||
|
const bottomSheetModalHeight = appContext.appLanguage === "en" ? 150 : 170;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<Card cardTopicText={t("screens.device.settings.settingsTitle")}>
|
<Card
|
||||||
|
cardTopicText={t("screens.device.settings.settingsTitle")}
|
||||||
|
disablePaddingBottom
|
||||||
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
@ -69,7 +116,10 @@ export default function SettingsView({ navigation }) {
|
||||||
</View>
|
</View>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card cardTopicText={t("screens.device.settings.deviceInformationText")}>
|
<Card
|
||||||
|
cardTopicText={t("screens.device.settings.deviceInformationText")}
|
||||||
|
disablePaddingBottom
|
||||||
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
@ -118,6 +168,31 @@ export default function SettingsView({ navigation }) {
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SettingsText
|
||||||
|
title={t("screens.device.settings.deviceMacAddressText")}
|
||||||
|
description={device.deviceMacAddress}
|
||||||
|
hidden={textDeviceMacAddressHidden}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MyIconButton
|
||||||
|
onPress={() =>
|
||||||
|
setTextDeviceMacAddressHidden(!textDeviceMacAddressHidden)
|
||||||
|
}
|
||||||
|
iconName={textDeviceMacAddressHidden ? "eye-off" : "eye"}
|
||||||
|
iconSize={18}
|
||||||
|
style={{ padding: 4 }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
@ -139,6 +214,150 @@ export default function SettingsView({ navigation }) {
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<Card cardTopicText={"Geräteverwaltung"}>
|
||||||
|
<SettingsText
|
||||||
|
title={t("screens.device.settings.closeConnectionTitle")}
|
||||||
|
description={t("screens.device.settings.closeConnectionDescription")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View style={{ alignItems: "center", marginTop: 6 }}>
|
||||||
|
<MyButton
|
||||||
|
title={t("screens.device.settings.closeConnectionButton")}
|
||||||
|
style={{
|
||||||
|
width: "80%",
|
||||||
|
}}
|
||||||
|
onPress={() => setIsBottomSheetModalCloseConnectionOpen(true)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<MyBottomSheetModal
|
||||||
|
isOpen={isBottomSheetModalCloseConnectionOpen}
|
||||||
|
closeModal={() => setIsBottomSheetModalCloseConnectionOpen(false)}
|
||||||
|
headerTitle={t(
|
||||||
|
"screens.device.settings.bottomSheetModalCloseConnection.headerTitle"
|
||||||
|
)}
|
||||||
|
modalHeight={bottomSheetModalHeight}
|
||||||
|
>
|
||||||
|
<View style={{ margin: 10 }}>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
{ color: appContext.appTheme.text },
|
||||||
|
AppStyles.typography14,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{t(
|
||||||
|
"screens.device.settings.bottomSheetModalCloseConnection.description"
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
gap: 10,
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MyButton
|
||||||
|
title={t(
|
||||||
|
"screens.device.settings.bottomSheetModalCloseConnection.cancelButton"
|
||||||
|
)}
|
||||||
|
style={{ width: 100 }}
|
||||||
|
buttonBackgroundColor={appContext.appTheme.buttonSecondary}
|
||||||
|
onPress={() => setIsBottomSheetModalCloseConnectionOpen(false)}
|
||||||
|
/>
|
||||||
|
<MyButton
|
||||||
|
title={t(
|
||||||
|
"screens.device.settings.bottomSheetModalCloseConnection.confirmButton"
|
||||||
|
)}
|
||||||
|
style={{ width: 160 }}
|
||||||
|
onPress={() => {
|
||||||
|
// TODO: is a request needed to the esp? or is it enough to just remove the device from the app?
|
||||||
|
console.log("close connection to device", device.id);
|
||||||
|
|
||||||
|
deleteDeviceFromApp();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</MyBottomSheetModal>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<SettingsText
|
||||||
|
title={t("screens.device.settings.resetToFactorySettingsTitle")}
|
||||||
|
description={t(
|
||||||
|
"screens.device.settings.resetToFactorySettingsDescription"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View style={{ alignItems: "center", marginTop: 6 }}>
|
||||||
|
<MyButton
|
||||||
|
title={t("screens.device.settings.resetToFactorySettingsButton")}
|
||||||
|
style={{ width: "80%" }}
|
||||||
|
onPress={() =>
|
||||||
|
setIsBottomSheetModalResetToFactorySettingsOpen(true)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<MyBottomSheetModal
|
||||||
|
isOpen={isBottomSheetModalResetToFactorySettingsOpen}
|
||||||
|
closeModal={() =>
|
||||||
|
setIsBottomSheetModalResetToFactorySettingsOpen(false)
|
||||||
|
}
|
||||||
|
headerTitle={t(
|
||||||
|
"screens.device.settings.bottomSheetModalResetToFactorySettings.headerTitle"
|
||||||
|
)}
|
||||||
|
modalHeight={bottomSheetModalHeight}
|
||||||
|
>
|
||||||
|
<View style={{ margin: 10 }}>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
{ color: appContext.appTheme.text },
|
||||||
|
AppStyles.typography14,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{t(
|
||||||
|
"screens.device.settings.bottomSheetModalResetToFactorySettings.description"
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
gap: 10,
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MyButton
|
||||||
|
title={t(
|
||||||
|
"screens.device.settings.bottomSheetModalResetToFactorySettings.cancelButton"
|
||||||
|
)}
|
||||||
|
style={{ width: 100 }}
|
||||||
|
buttonBackgroundColor={appContext.appTheme.buttonSecondary}
|
||||||
|
onPress={() =>
|
||||||
|
setIsBottomSheetModalResetToFactorySettingsOpen(false)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<MyButton
|
||||||
|
title={t(
|
||||||
|
"screens.device.settings.bottomSheetModalResetToFactorySettings.confirmButton"
|
||||||
|
)}
|
||||||
|
style={{ width: 160 }}
|
||||||
|
onPress={() => {
|
||||||
|
// TODO: API request to esp for reset to factory settings
|
||||||
|
console.log("reseting esp and closing connection", device.id);
|
||||||
|
|
||||||
|
deleteDeviceFromApp();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</MyBottomSheetModal>
|
||||||
|
</Card>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { View } from "react-native";
|
||||||
|
import MyResult from "../../Components/Result";
|
||||||
|
import { MyTextButton } from "../../Components/Button";
|
||||||
|
|
||||||
|
// this screen is shown when no devices are connected to the app
|
||||||
|
export default function NoDevicesConnectedScreen({ navigation }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
// TODO: add ref to faq for help to connect a new device
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ alignItems: "center", margin: 20, gap: 10 }}>
|
||||||
|
<MyResult
|
||||||
|
text={t("screens.noDevicesConnected.textDescription")}
|
||||||
|
iconName={"selection-search"}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MyTextButton
|
||||||
|
title={t("screens.noDevicesConnected.buttonSearchForNewDevices")}
|
||||||
|
actionColor
|
||||||
|
onPress={() => navigation.navigate("modalSearchForNewDevices")}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
|
@ -89,6 +89,8 @@ const DarkAppTheme = {
|
||||||
text: "#fff",
|
text: "#fff",
|
||||||
textSecondary: "#ddd",
|
textSecondary: "#ddd",
|
||||||
textDisabled: "#b2bec3",
|
textDisabled: "#b2bec3",
|
||||||
|
buttonTextColor: "#fff",
|
||||||
|
buttonSecondary: "#818081",
|
||||||
backgroundColor: "#21252a",
|
backgroundColor: "#21252a",
|
||||||
card: {
|
card: {
|
||||||
backgroundColor: "#2b3139",
|
backgroundColor: "#2b3139",
|
||||||
|
@ -128,6 +130,7 @@ const DarkAppTheme = {
|
||||||
},
|
},
|
||||||
colorPickerDisabled: "rgba(0, 0, 0, 0.3)",
|
colorPickerDisabled: "rgba(0, 0, 0, 0.3)",
|
||||||
modal: {
|
modal: {
|
||||||
|
transparentBackgroundColor: "rgba(0, 0, 0, 0.4)",
|
||||||
pressedPickerItemColor: "rgba(0, 0, 0, 0.3)",
|
pressedPickerItemColor: "rgba(0, 0, 0, 0.3)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -142,6 +145,8 @@ const LightAppTheme = {
|
||||||
text: "#000",
|
text: "#000",
|
||||||
textSecondary: "#555",
|
textSecondary: "#555",
|
||||||
textDisabled: "#636e72",
|
textDisabled: "#636e72",
|
||||||
|
buttonTextColor: "#fff",
|
||||||
|
buttonSecondary: "#aaa69d",
|
||||||
backgroundColor: "#f7f7f7",
|
backgroundColor: "#f7f7f7",
|
||||||
card: {
|
card: {
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
|
@ -180,6 +185,7 @@ const LightAppTheme = {
|
||||||
},
|
},
|
||||||
colorPickerDisabled: "rgba(0, 0, 0, 0.3)",
|
colorPickerDisabled: "rgba(0, 0, 0, 0.3)",
|
||||||
modal: {
|
modal: {
|
||||||
|
transparentBackgroundColor: "rgba(0, 0, 0, 0.3)",
|
||||||
pressedPickerItemColor: "rgba(0, 0, 0, 0.1)",
|
pressedPickerItemColor: "rgba(0, 0, 0, 0.1)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -515,6 +521,7 @@ const devDevices = [
|
||||||
id: "1f21a12a-0bec-4336-99bb-df3f9fc9f537", // deviceId
|
id: "1f21a12a-0bec-4336-99bb-df3f9fc9f537", // deviceId
|
||||||
displayName: "Turtle",
|
displayName: "Turtle",
|
||||||
deviceModel: "Aurora",
|
deviceModel: "Aurora",
|
||||||
|
deviceMacAddress: "12:34:56:78:9A:BC",
|
||||||
deviceIp: "127.0.0.1",
|
deviceIp: "127.0.0.1",
|
||||||
firmware: {
|
firmware: {
|
||||||
version: "1.0.1",
|
version: "1.0.1",
|
||||||
|
@ -526,6 +533,7 @@ const devDevices = [
|
||||||
id: "5b331a12a-0bec-4336-99bb-df3f9fc9f537", // deviceId
|
id: "5b331a12a-0bec-4336-99bb-df3f9fc9f537", // deviceId
|
||||||
displayName: "Elona",
|
displayName: "Elona",
|
||||||
deviceModel: "Aurora",
|
deviceModel: "Aurora",
|
||||||
|
deviceMacAddress: "AB:CD:EF:12:34:56",
|
||||||
deviceIp: "192.168.0.1",
|
deviceIp: "192.168.0.1",
|
||||||
firmware: {
|
firmware: {
|
||||||
version: "1.0.1",
|
version: "1.0.1",
|
||||||
|
|
Loading…
Reference in New Issue