diff --git a/App.js b/App.js index b74f208..268d9c7 100644 --- a/App.js +++ b/App.js @@ -15,13 +15,14 @@ import { Suspense, lazy, useContext, useEffect } from "react"; import { SafeAreaView } from "react-native-safe-area-context"; import "./i18n"; import DeviceScreen from "./src/Screens/Device"; +import DeviceOldScreen from "./src/Screens/DeviceOld"; + +const Drawer = createDrawerNavigator(); const SettingsScreen = lazy(() => import("./src/Screens/Settings")); const FaqScreen = lazy(() => import("./src/Screens/FAQ")); const FeedbackScreen = lazy(() => import("./src/Screens/Feedback")); -const Drawer = createDrawerNavigator(); - export function MyApp() { const appContext = useContext(AppContext); @@ -63,7 +64,7 @@ export function MyApp() { } > + diff --git a/assets/ambilight.gif b/assets/ambilight.gif new file mode 100644 index 0000000..e3499bf Binary files /dev/null and b/assets/ambilight.gif differ diff --git a/assets/layers.gif b/assets/layers.gif new file mode 100644 index 0000000..1b4a759 Binary files /dev/null and b/assets/layers.gif differ diff --git a/assets/motor.gif b/assets/motor.gif new file mode 100644 index 0000000..694f65a Binary files /dev/null and b/assets/motor.gif differ diff --git a/package-lock.json b/package-lock.json index 7cde497..6a302ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", "react-native-tab-view": "^3.5.2", + "react-native-uuid": "^2.0.1", "reanimated-color-picker": "^2.3.1" }, "devDependencies": { @@ -5010,34 +5011,6 @@ "react-native-screens": ">= 3.0.0" } }, - "node_modules/@react-navigation/drawer/node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/@react-navigation/drawer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@react-navigation/drawer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/@react-navigation/elements": { "version": "1.3.18", "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz", @@ -6291,6 +6264,18 @@ "node": ">=0.10.0" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6313,6 +6298,22 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", @@ -7101,6 +7102,15 @@ "expo": "*" } }, + "node_modules/expo-asset/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/expo-constants": { "version": "14.2.1", "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-14.2.1.tgz", @@ -7113,6 +7123,15 @@ "expo": "*" } }, + "node_modules/expo-constants/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/expo-file-system": { "version": "15.2.2", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.2.2.tgz", @@ -7124,6 +7143,15 @@ "expo": "*" } }, + "node_modules/expo-file-system/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/expo-font": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-11.1.1.tgz", @@ -7269,6 +7297,15 @@ "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.4.4.tgz", "integrity": "sha512-5DV0hIEWgatSC3UgQuAZBoQeaS9CqeWRZ3vzBR9R/+IUD87Adbi4FGhU10nymRqFXOizGsureButGZIXPs7zEA==" }, + "node_modules/expo/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -11931,6 +11968,15 @@ "react-native-pager-view": "*" } }, + "node_modules/react-native-uuid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-native-uuid/-/react-native-uuid-2.0.1.tgz", + "integrity": "sha512-cptnoIbL53GTCrWlb/+jrDC6tvb7ypIyzbXNJcpR3Vab0mkeaaVd5qnB3f0whXYzS+SMoSQLcUUB0gEWqkPC0g==", + "engines": { + "node": ">=10.0.0", + "npm": ">=6.0.0" + } + }, "node_modules/react-native/node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", @@ -13795,15 +13841,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/valid-url": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", diff --git a/package.json b/package.json index 0558c71..79d24c5 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", "react-native-tab-view": "^3.5.2", + "react-native-uuid": "^2.0.1", "reanimated-color-picker": "^2.3.1" }, "devDependencies": { diff --git a/src/Components/Button/index.js b/src/Components/Button/index.js new file mode 100644 index 0000000..9822305 --- /dev/null +++ b/src/Components/Button/index.js @@ -0,0 +1,29 @@ +import { useContext } from "react"; +import { Text, TouchableHighlight, View } from "react-native"; +import { AppContext, AppStyles } from "../../utils"; + +export default function MyButton({ title, style, disabled, onPress }) { + const appContext = useContext(AppContext); + + return ( + + + {title} + + + ); +} diff --git a/src/Components/Card/index.js b/src/Components/Card/index.js index 3dfb664..3616f6e 100644 --- a/src/Components/Card/index.js +++ b/src/Components/Card/index.js @@ -2,9 +2,14 @@ import { useContext } from "react"; import { View } from "react-native"; import { AppContext, AppStyles } from "../../utils"; -export default function Card({ children }) { +export default function Card({ children, cardBackgroundColor }) { const appContext = useContext(AppContext); + const backgroundColor = + cardBackgroundColor === undefined + ? appContext.appTheme.card.backgroundColor + : cardBackgroundColor; + return ( onPress()}> + + + {label} + + {selectedItemLabel} + + + + + + ); +} diff --git a/src/Components/Icon/index.js b/src/Components/Icon/index.js index d9713c6..73e05d0 100644 --- a/src/Components/Icon/index.js +++ b/src/Components/Icon/index.js @@ -1,5 +1,11 @@ import Icon from "@expo/vector-icons/MaterialCommunityIcons"; +import { useContext } from "react"; +import { AppContext } from "../../utils"; export default function MyIcon({ style, name, color, size }) { - return ; + const appContext = useContext(AppContext); + + const iconColor = color === undefined ? appContext.appTheme.icon : color; + + return ; } diff --git a/src/Components/PickerModal/index.js b/src/Components/Modal/index.js similarity index 72% rename from src/Components/PickerModal/index.js rename to src/Components/Modal/index.js index 8582a9c..38aa2bb 100644 --- a/src/Components/PickerModal/index.js +++ b/src/Components/Modal/index.js @@ -3,7 +3,7 @@ import { AppContext, AppStyles, IsPlatformIos } from "../../utils"; import { KeyboardAvoidingView, Modal, - Platform, + ScrollView, Text, TextInput, TouchableOpacity, @@ -13,15 +13,134 @@ import { Divider } from "../Divider"; import MyIcon from "../Icon"; import { useTranslation } from "react-i18next"; -const modalIosPaddingTop = 10; +/* +transparent: set this to prevent modal reopening on iOS +https://github.com/facebook/react-native/issues/34018 +*/ -export default function PickerModal({ +const modalContentStyle = { margin: 10, paddingTop: 10 }; + +export default function MyModal({ + children, isOpen, - setIsOpen, - items, - searchFilter, + closeModal, + header, + content, + disableAnimationForIos, + scrollView, }) { const appContext = useContext(AppContext); + + const getContent = () => { + if (scrollView) { + return ( + + {content} + + ); + } + + return {content}; + }; + + return ( + + closeModal()} + transparent + > + {children} + + + {header} + + {getContent()} + + + + ); +} + +export function MyPickerDefaultHeader({ title, closeModal }) { + const appContext = useContext(AppContext); + + return ( + + closeModal()}> + + + + + {title} + + + + + ); +} + +export function MyPickerModalListItem({ onPress, itemName, itemSelected }) { + const appContext = useContext(AppContext); + + return ( + <> + + + + {itemName} + + + {itemSelected && ( + + )} + + + + + + ); +} + +export function MyPickerModal({ isOpen, setIsOpen, items, searchFilter }) { + const appContext = useContext(AppContext); const { t } = useTranslation(); const [providedItems, setProvidedItems] = useState([]); const [searchFilterInput, setSearchFilterInput] = useState(""); @@ -47,7 +166,6 @@ export default function PickerModal({ flex: 1, backgroundColor: appContext.appTheme.backgroundColor, }, - IsPlatformIos() && { paddingTop: modalIosPaddingTop }, ]} > @@ -193,7 +311,7 @@ export default function PickerModal({ ); } -export function TextInputModal({ +export function MyTextInputModal({ isOpen, setIsOpen, onTextInputSave, @@ -217,7 +335,6 @@ export function TextInputModal({ flex: 1, backgroundColor: appContext.appTheme.backgroundColor, }, - IsPlatformIos() && { paddingTop: modalIosPaddingTop }, ]} > - {["Turtle"].map((item, i) => ( + {["Turtle", "Old Turtle"].map((item, i) => ( import("./motor")); -const SettingsView = lazy(() => import("./settings")); -const ColorScenesView = lazy(() => import("./colorScenes")); +import SettingsView from "./settings"; +import SceneView from "./scene"; const spaceToSide = 10; // left and right const top = 35; @@ -27,43 +22,16 @@ const topFirst = top; const topSecond = top + spaceBetweenButtons; const topThird = top + 2 * spaceBetweenButtons; -const windowDimensions = Dimensions.get("window"); - -let data = []; - -const ledLines = 4; -const ledsPerLine = 16; - -const deviceLeds = ledLines * ledsPerLine; - -// setting default color for testing -for (let i = 0; i < deviceLeds; i++) { - data.push("lime"); -} - export default function DeviceScreen() { const appContext = useContext(AppContext); const [selectedView, setSelectedView] = useState(0); - const [deviceLedsColors, setDeviceLedsColor] = useState(data); - const [selectedDeviceLed, setSelectedDeviceLed] = useState(2); const SelectedView = () => { switch (selectedView) { case 0: - return ; - case 2: - return ; - case 3: return ; - case 4: - return ( - - ); + case 2: + return ; default: Not found; } @@ -102,59 +70,6 @@ export default function DeviceScreen() { ); }; - const DeviceLedsColor = () => { - let elements = []; - let test = 400; - - for (let l = 0; l < ledLines; l++) { - let left = 0; - let ledsElements = []; - - for (let p = 0; p < ledsPerLine; p++) { - left = left + 1.5; - - const ledId = l > 0 ? l * 16 + p : p; - - const deviceLedColor = - l > 0 ? deviceLedsColors[l * 16 + p] : deviceLedsColors[p]; - - ledsElements.push( - 360 - ? 0.27 * (test / 16) - : 0.26 * (test / 16), - }} - /> - ); - } - - elements.push( - - {ledsElements} - - ); - } - - return <>{elements}; - }; - return ( - - - - diff --git a/src/Screens/Device/modals/ActionEdits/Layers/index.js b/src/Screens/Device/modals/ActionEdits/Layers/index.js new file mode 100644 index 0000000..f065fe7 --- /dev/null +++ b/src/Screens/Device/modals/ActionEdits/Layers/index.js @@ -0,0 +1,5 @@ +import { Text } from "react-native"; + +export default function LayersActionEditModalContent() { + return Layers; +} diff --git a/src/Screens/Device/modals/AddSceneAction/LayerSelection/index.js b/src/Screens/Device/modals/AddSceneAction/LayerSelection/index.js new file mode 100644 index 0000000..6930f20 --- /dev/null +++ b/src/Screens/Device/modals/AddSceneAction/LayerSelection/index.js @@ -0,0 +1,83 @@ +import { useState } from "react"; +import { Text, TouchableHighlight, View } from "react-native"; +import MyButton from "../../../../../Components/Button"; + +function Layer({ number, selected, onPress }) { + return ( + + + + + {number} + + + + + ); +} + +export default function LayerSelectionModalContent({ + openLayersActionEditModal, +}) { + const [selectedLayer, setSelectedLayer] = useState([]); + + const handleSelectLayerClick = (layerNumber) => { + if (selectedLayer.includes(layerNumber)) { + setSelectedLayer((sLayer) => + sLayer.filter((item) => item != layerNumber) + ); + } else { + setSelectedLayer((sLayer) => [...sLayer, layerNumber]); + } + }; + + return ( + <> + + {Array.from({ length: 4 }).map((_, i) => ( + handleSelectLayerClick(i + 1)} + /> + ))} + + + + openLayersActionEditModal()} + /> + + + ); +} diff --git a/src/Screens/Device/modals/AddSceneAction/index.js b/src/Screens/Device/modals/AddSceneAction/index.js new file mode 100644 index 0000000..dcb957b --- /dev/null +++ b/src/Screens/Device/modals/AddSceneAction/index.js @@ -0,0 +1,89 @@ +import { useContext } from "react"; +import { Image, Text, TouchableOpacity, View } from "react-native"; +import { AppContext, AppStyles } from "../../../../utils"; +import MyIcon from "../../../../Components/Icon"; +import { Divider } from "../../../../Components/Divider"; + +function Action({ text, iconName, imageSource, onPress }) { + const appContext = useContext(AppContext); + + return ( + <> + + + + + {text} + + + {imageSource !== undefined && ( + + )} + + + + ); +} + +export default function AddSceneActionModalContent({ + openLayerSelectionModal, +}) { + return ( + <> + + + console.log("pressed action")} + /> + + console.log("pressed action")} + /> + + console.log("pressed action")} + /> + + console.log("pressed action")} + /> + + console.log("pressed action")} + /> + + ); +} diff --git a/src/Screens/Device/modals/ChooseScene/CreateScene/index.js b/src/Screens/Device/modals/ChooseScene/CreateScene/index.js new file mode 100644 index 0000000..7af8d92 --- /dev/null +++ b/src/Screens/Device/modals/ChooseScene/CreateScene/index.js @@ -0,0 +1,54 @@ +import { useContext } from "react"; +import { + AppContext, + DevDeviceId, + NewEmptyDeviceScene, +} from "../../../../../utils"; +import { FlatList, View } from "react-native"; +import { MyPickerModalListItem } from "../../../../../Components/Modal"; + +export default function CreateSceneModalContent({ closeChooseSceneModals }) { + const appContext = useContext(AppContext); + + const options = [ + { + id: 0, + name: "Leere Szene erstellen", + }, + { + id: 1, + name: "Standard Szene erstellen", + }, + { + id: 2, + name: "Vorhandene Szene kopieren", + }, + ]; + + return ( + item.id} + renderItem={({ item }) => ( + { + console.log("pressed", item); + + appContext.setDevices((arr) => { + const newArr = [...arr]; + + newArr[arr.findIndex((d) => d.id === DevDeviceId)].scenes.push( + NewEmptyDeviceScene() + ); + + return newArr; + }); + + closeChooseSceneModals(); + }} + /> + )} + /> + ); +} diff --git a/src/Screens/Device/modals/ChooseScene/index.js b/src/Screens/Device/modals/ChooseScene/index.js new file mode 100644 index 0000000..e97a201 --- /dev/null +++ b/src/Screens/Device/modals/ChooseScene/index.js @@ -0,0 +1,64 @@ +import { useContext, useState } from "react"; +import { FlatList, Text, TouchableOpacity } from "react-native"; +import { AppContext, AppStyles, DevDeviceId } from "../../../../utils"; +import { Divider } from "../../../../Components/Divider"; +import { View } from "react-native"; +import MyIcon from "../../../../Components/Icon"; +import { MyPickerModalListItem } from "../../../../Components/Modal"; + +export default function ChooseSceneModalContent({ openCreateSceneModal }) { + const appContext = useContext(AppContext); + + const device = appContext.devices.find((device) => device.id === DevDeviceId); + + return ( + <> + item.id} + renderItem={({ item }) => ( + { + appContext.setDevices((arr) => { + const newArr = [...arr]; + + newArr[ + arr.findIndex((d) => d.id === DevDeviceId) + ].selectedScene = item.id; + + return newArr; + }); + }} + /> + )} + /> + + + + + Neue Szene erstellen + + + + ); +} diff --git a/src/Screens/Device/scene.js b/src/Screens/Device/scene.js new file mode 100644 index 0000000..7916ab9 --- /dev/null +++ b/src/Screens/Device/scene.js @@ -0,0 +1,227 @@ +import { FlatList, Text, TouchableOpacity, View } from "react-native"; +import Card from "../../Components/Card"; +import { AppContext, AppStyles, DevDeviceId } from "../../utils"; +import { useContext, useState } from "react"; +import { useTranslation } from "react-i18next"; +import MyDropdown from "../../Components/Dropdown"; +import MyIcon from "../../Components/Icon"; +import MyModal, { MyPickerDefaultHeader } from "../../Components/Modal"; +import CreateSceneModalContent from "./modals/ChooseScene/CreateScene"; +import ChooseSceneModalContent from "./modals/ChooseScene"; +import AddSceneActionModalContent from "./modals/AddSceneAction"; +import LayerSelectionModalContent from "./modals/AddSceneAction/LayerSelection"; +import LayersActionEditModalContent from "./modals/ActionEdits/Layers"; + +function NothingSelected({ text }) { + const appContext = useContext(AppContext); + + return ( + + + + {text} + + + ); +} + +export default function SceneView() { + const appContext = useContext(AppContext); + + const [modalOpenStates, setModalOpenStates] = useState({ + modalChooseSceneIsOpen: false, + modalCreateSceneIsOpen: false, + modalAddSceneActionIsOpen: false, + modalLayerSectionIsOpen: false, + modalLayersActionEditIsOpen: false, + }); + + const setModalOpen = (modalName, open) => { + console.log("setModalOpen", modalName, open); + + setModalOpenStates((prevState) => ({ + ...prevState, + [modalName]: open, + })); + }; + + const device = appContext.devices.find((device) => device.id === DevDeviceId); + + const deviceScene = device.scenes.find( + (scene) => scene.id === device.selectedScene + ); + + const closeChooseSceneModals = () => { + setModalOpenStates((prevState) => ({ + ...prevState, + modalChooseSceneIsOpen: false, + modalCreateSceneIsOpen: false, + })); + }; + + const actionColor = + deviceScene === undefined || deviceScene.actions.length === 0 + ? appContext.appTheme.colors.primary + : appContext.appTheme.textSecondary; + + return ( + <> + + { + console.log("pressed"); + setModalOpen("modalChooseSceneIsOpen", true); + }} + selectedItemLabel={ + device.selectedScene === 0 + ? "Keine Szene ausgewählt" + : device.scenes.find((scene) => scene.id === device.selectedScene) + .name + } + /> + + {device.selectedScene === 0 ? ( + + ) : ( + + {deviceScene.actions.length === 0 ? ( + + ) : ( + item.id} + renderItem={({ item }) => ( + + {item.name} + + )} + /> + )} + + setModalOpen("modalAddSceneActionIsOpen", true)} + > + + + Aktion hinzufügen + + + + )} + setModalOpen("modalChooseSceneIsOpen", false)} + header={ + setModalOpen("modalChooseSceneIsOpen", false)} + /> + } + content={ + + setModalOpen("modalCreateSceneIsOpen", true) + } + /> + } + > + setModalOpen("modalCreateSceneIsOpen", false)} + header={ + setModalOpen("modalCreateSceneIsOpen", false)} + /> + } + content={ + + } + /> + + + setModalOpen("modalAddSceneActionIsOpen", false)} + header={ + setModalOpen("modalAddSceneActionIsOpen", false)} + /> + } + content={ + + setModalOpen("modalLayerSectionIsOpen", true) + } + /> + } + > + setModalOpen("modalLayerSectionIsOpen", false)} + header={ + setModalOpen("modalLayerSectionIsOpen", false)} + /> + } + content={ + + setModalOpen("modalLayersActionEditIsOpen", true) + } + /> + } + > + + setModalOpen("modalLayersActionEditIsOpen", false) + } + header={ + + setModalOpen("modalLayersActionEditIsOpen", false) + } + /> + } + content={} + /> + + + + ); +} diff --git a/src/Screens/Device/settings.js b/src/Screens/Device/settings.js index 9e7da82..6dc1a6c 100644 --- a/src/Screens/Device/settings.js +++ b/src/Screens/Device/settings.js @@ -6,7 +6,7 @@ import { Divider } from "../../Components/Divider"; import { useTranslation } from "react-i18next"; import MySwitch from "../../Components/Switch"; import MyIcon from "../../Components/Icon"; -import { TextInputModal } from "../../Components/PickerModal"; +import { MyTextInputModal } from "../../Components/Modal"; export default function SettingsView() { const appContext = useContext(AppContext); @@ -104,7 +104,7 @@ export default function SettingsView() { - console.log("save")} diff --git a/src/Screens/Device/colorScenes.js b/src/Screens/DeviceOld/colorScenes.js similarity index 100% rename from src/Screens/Device/colorScenes.js rename to src/Screens/DeviceOld/colorScenes.js diff --git a/src/Screens/DeviceOld/index.js b/src/Screens/DeviceOld/index.js new file mode 100644 index 0000000..97719e3 --- /dev/null +++ b/src/Screens/DeviceOld/index.js @@ -0,0 +1,261 @@ +import { lazy, useContext, useState } from "react"; +import { + Image, + ScrollView, + StyleSheet, + View, + Text, + TouchableHighlight, + TouchableOpacity, + Dimensions, + Platform, + ImageBackground, +} from "react-native"; +import LightView from "./light"; +import { AppContext } from "../../utils"; +import MyIcon from "../../Components/Icon"; + +const MotorView = lazy(() => import("./motor")); +const SettingsView = lazy(() => import("./settings")); +const ColorScenesView = lazy(() => import("./colorScenes")); + +const spaceToSide = 10; // left and right +const top = 35; +const spaceBetweenButtons = 60; + +const topFirst = top; +const topSecond = top + spaceBetweenButtons; +const topThird = top + 2 * spaceBetweenButtons; + +const windowDimensions = Dimensions.get("window"); + +let data = []; + +const ledLines = 4; +const ledsPerLine = 16; + +const deviceLeds = ledLines * ledsPerLine; + +// setting default color for testing +for (let i = 0; i < deviceLeds; i++) { + data.push("lime"); +} + +export default function DeviceOldScreen() { + const appContext = useContext(AppContext); + const [selectedView, setSelectedView] = useState(0); + const [deviceLedsColors, setDeviceLedsColor] = useState(data); + const [selectedDeviceLed, setSelectedDeviceLed] = useState(2); + + const SelectedView = () => { + switch (selectedView) { + case 0: + return ; + case 2: + return ; + case 3: + return ; + case 4: + return ( + + ); + default: + Not found; + } + }; + + const MyButton = ({ selectedViewNumber, top, left, space, iconName }) => { + const TouchComponent = + appContext.appColorScheme === "dark" + ? TouchableHighlight + : TouchableOpacity; + + return ( + setSelectedView(selectedViewNumber)} + style={[ + { + position: "absolute", + backgroundColor: appContext.appTheme.card.backgroundColor, + borderRadius: 10, + padding: 8, + }, + { top: top }, + left === true ? { left: space } : { right: space }, + ]} + > + + + ); + }; + + const DeviceLedsColor = () => { + let elements = []; + let test = 400; + + for (let l = 0; l < ledLines; l++) { + let left = 0; + let ledsElements = []; + + for (let p = 0; p < ledsPerLine; p++) { + left = left + 1.5; + + const ledId = l > 0 ? l * 16 + p : p; + + const deviceLedColor = + l > 0 ? deviceLedsColors[l * 16 + p] : deviceLedsColors[p]; + + ledsElements.push( + 360 + ? 0.27 * (test / 16) + : 0.26 * (test / 16), + }} + /> + ); + } + + elements.push( + + {ledsElements} + + ); + } + + return <>{elements}; + }; + + return ( + + {selectedView === 4 && ( + + + + + + )} + + {appContext.isUserDeveloperModeEnabled ? ( + <> + {selectedView !== 4 && ( + + )} + + ) : ( + <> + {selectedView !== 4 && ( + + )} + + )} + + + + + + + + + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center", + backgroundColor: "#2e2e30", + }, + scrollView: { + width: "100%", + padding: 20, + }, + image: { + width: "100%", + height: 250, + }, +}); diff --git a/src/Screens/Device/light.js b/src/Screens/DeviceOld/light.js similarity index 99% rename from src/Screens/Device/light.js rename to src/Screens/DeviceOld/light.js index 273e20f..2297353 100644 --- a/src/Screens/Device/light.js +++ b/src/Screens/DeviceOld/light.js @@ -25,9 +25,9 @@ import { AppContext, AppStyles, IsPlatformIos } from "../../utils"; import Card from "../../Components/Card"; import MySwitch from "../../Components/Switch"; import MyIcon from "../../Components/Icon"; -import PickerModal from "../../Components/PickerModal"; import { useTranslation } from "react-i18next"; import MySlider from "../../Components/Slider"; +import MyPickerModal from "../../Components/Modal"; const colorModePickerOptions = [ { label: "Pulse", value: "pulse" }, @@ -198,7 +198,7 @@ export default function LightView() { - + + + {t("screens.device.settings.settingsTitle")} + + + + + + {t("screens.device.settings.wifiStandByTitle")} + + + {t("screens.device.settings.wifiStandByDescription")} + + + setSwitchState(e)} + /> + + + + + + {t("screens.device.settings.deviceInformationText")} + + + + + + {t("screens.device.settings.deviceNameText")} + + + Turtle + + + + setModalTextInputVisible(true)}> + + + + + console.log("save")} + modalTitle={t("screens.device.settings.deviceNameText")} + inputTitle={t("screens.device.settings.deviceNameText")} + inputDescription={t( + "screens.device.settings.modalTextInputDeviceNameDescription" + )} + /> + + + + + {t("screens.device.settings.deviceModelText")} + + + Shimmex Aurora + + + + + + {t("screens.device.settings.deviceFirmwareVersionText")} + + + 1.0.1 + + + + + + {t("screens.device.settings.deviceLastUpdatedText")} + + + 11.07.2023 um 20:33 Uhr + + + + ); +} diff --git a/src/Screens/Settings/index.js b/src/Screens/Settings/index.js index a358ebc..8fae57b 100644 --- a/src/Screens/Settings/index.js +++ b/src/Screens/Settings/index.js @@ -3,9 +3,9 @@ import { Text, TouchableOpacity, View } from "react-native"; import Card from "../../Components/Card"; import { AppContext, AppStyles, Constants } from "../../utils"; import { Divider } from "../../Components/Divider"; -import PickerModal from "../../Components/PickerModal"; import { useTranslation } from "react-i18next"; import MySwitch from "../../Components/Switch"; +import { MyPickerModal } from "../../Components/Modal"; export default function SettingsScreen() { const appContext = useContext(AppContext); @@ -139,7 +139,7 @@ export default function SettingsScreen() { /> - - { diff --git a/src/utils.js b/src/utils.js index db9d3c6..9b30155 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,6 +2,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; import { createContext, useState } from "react"; import { useTranslation } from "react-i18next"; import { Appearance, Platform, StyleSheet } from "react-native"; +import uuid from "react-native-uuid"; export const Constants = { defaultLanguage: "de", @@ -147,14 +148,66 @@ export function GetDataFromList(list, key) { return list.find((v) => v[0] === key)[1]; } +export function GetUuid() { + return uuid.v4(); +} + const appContextPreview = { appColorScheme: "", appLanguage: "", isUserExpertModeEnabled: "", isUserDeveloperModeEnabled: "", appTheme: DarkAppTheme, + devices: [], }; +export const DevDeviceId = 0; + +const devData = [ + { + id: 0, // deviceId + selectedScene: 0, + scenes: [ + { + id: 1, + name: "Szene 1", + actions: [ + { + id: 0, + name: "Test", + }, + { + id: 1, + name: "Test1", + }, + ], + }, + { + id: 2, + name: "Szene 2", + actions: [ + { + id: 0, + name: "Haha", + }, + { + id: 1, + name: "Haha 1", + }, + ], + }, + ], + }, +]; + +export function NewEmptyDeviceScene() { + return { + id: GetUuid(), + name: "Leere Szene", + actions: [], + }; +} + export const AppContext = createContext(appContextPreview); export function AppProvider({ children }) { @@ -165,6 +218,7 @@ export function AppProvider({ children }) { // TODO: only while development const [isUserDeveloperModeEnabled, setIsUserDeveloperModeEnabled] = useState(false); + const [devices, setDevices] = useState(devData); const { i18n } = useTranslation(); const saveAppColorScheme = async (value) => { @@ -207,6 +261,8 @@ export function AppProvider({ children }) { setIsUserExpertModeEnabled: saveUserExpertMode, isUserDeveloperModeEnabled: isUserDeveloperModeEnabled, setUserIsDeveloperModeEnabled: saveUserDeveloperMode, + devices: devices, + setDevices: setDevices, }} > {children}