diff --git a/App.js b/App.js index fd63e46..49d72ff 100644 --- a/App.js +++ b/App.js @@ -38,6 +38,7 @@ import { EditActionAnimationSelectionModalContent } from "./src/Screens/Device/m import MotorEditActionModalContent, { MotorEditActionMotorModeSelectionModalContent, } from "./src/Screens/Device/modals/EditActions/Motor"; +import WaitXSecondsEditActionModalContent from "./src/Screens/Device/modals/EditActions/Wait"; const Drawer = createDrawerNavigator(); const Stack = createStackNavigator(); @@ -234,6 +235,19 @@ export function MyApp() { } /> + + options({ + navigation: navigation, + pageTitle: t( + "screens.device.scenes.editActions.modalWaitEditAction.pageTitle" + ), + }) + } + /> + + closeModal()} + > + closeModal()}> + + + + + + + + {headerTitle} + + + closeModal()} + /> + + + {children} + + + + ); +} + /* export function MyPickerModal({ isOpen, setIsOpen, items, searchFilter }) { const appContext = useContext(AppContext); diff --git a/src/Components/TextInput/index.js b/src/Components/TextInput/index.js index cc6df77..ba4ccff 100644 --- a/src/Components/TextInput/index.js +++ b/src/Components/TextInput/index.js @@ -8,6 +8,7 @@ export default function MyTextInput({ textMaxLength, value, onChangeText, + inputMode, }) { const appContext = useContext(AppContext); @@ -17,6 +18,7 @@ export default function MyTextInput({ {textTitle} console.log("pressed action")} + text={t("screens.device.scenes.modalAddSceneAction.actions.wait")} + iconName={ActionTypeIconName(Constants.actionType.wait)} + onPress={() => + handleCreateAction( + Constants.actionType.wait, + { hours: 0, minutes: 0, seconds: 0 }, + "modalWaitEditAction" + ) + } deviceFirmwareVersion={deviceFirmwareVersion} supportedFirmwareVersions={["1.0.1"]} /> diff --git a/src/Screens/Device/modals/EditActions/Lights/index.js b/src/Screens/Device/modals/EditActions/Lights/index.js index d1fa7b2..946645f 100644 --- a/src/Screens/Device/modals/EditActions/Lights/index.js +++ b/src/Screens/Device/modals/EditActions/Lights/index.js @@ -33,10 +33,7 @@ import { EditActionAnimationsCardContent, RenderHeaderRight, } from ".."; -import { - MyDotsModal, - MyPickerModalListItem, -} from "../../../../../Components/Modal"; +import { MyPickerModalListItem } from "../../../../../Components/Modal"; // This component is used by layers and ambilight export default function LightsEditActionModalContent({ navigation, route }) { diff --git a/src/Screens/Device/modals/EditActions/Wait/index.js b/src/Screens/Device/modals/EditActions/Wait/index.js new file mode 100644 index 0000000..9e529fa --- /dev/null +++ b/src/Screens/Device/modals/EditActions/Wait/index.js @@ -0,0 +1,301 @@ +import { useCallback, useContext, useState } from "react"; +import { Dimensions, Text, TouchableOpacity, View } from "react-native"; +import { AppContext, AppStyles, ModalContainer } from "../../../../../utils"; +import { FlatList } from "react-native"; +import { + MyBottomSheetModal, + MyPickerModalListItem, +} from "../../../../../Components/Modal"; +import { useTranslation } from "react-i18next"; +import { useFocusEffect } from "@react-navigation/native"; +import { RenderHeaderRight } from ".."; + +const dataHours = [ + { number: "00" }, + { number: "01" }, + { number: "02" }, + { number: "03" }, + { number: "04" }, + { number: "05" }, + { number: "06" }, + { number: "07" }, + { number: "08" }, + { number: "09" }, + { number: "10" }, + { number: "11" }, + { number: "12" }, + { number: "13" }, + { number: "14" }, + { number: "15" }, + { number: "16" }, + { number: "17" }, + { number: "18" }, + { number: "19" }, + { number: "20" }, + { number: "21" }, + { number: "22" }, + { number: "23" }, +]; + +const dataMinutesAndSeconds = [ + { number: "00" }, + { number: "01" }, + { number: "02" }, + { number: "03" }, + { number: "04" }, + { number: "05" }, + { number: "06" }, + { number: "07" }, + { number: "08" }, + { number: "09" }, + { number: "10" }, + { number: "15" }, + { number: "20" }, + { number: "25" }, + { number: "30" }, + { number: "35" }, + { number: "40" }, + { number: "45" }, + { number: "50" }, + { number: "55" }, +]; + +const windowHeight = Dimensions.get("window").height; + +const modalHeight = windowHeight * 0.6; // 60 % of device screen + +export default function WaitEditActionModalContent({ navigation, route }) { + const appContext = useContext(AppContext); + const { t } = useTranslation(); + + const { action } = route.params; + + console.log("params", route.params); + + const [selectedHours, setSelectedHours] = useState( + action.modeAdjustments.hours + ); + const [selectedMinutes, setSelectedMinutes] = useState( + action.modeAdjustments.minutes + ); + const [selectedSeconds, setSelectedSeconds] = useState( + action.modeAdjustments.seconds + ); + + const NumberSelection = ({ + headerTitle, + data, + numberDescription, + selectedNumber, + setSelectedNumber, + action, + timeUnit, + }) => { + return ( + + + + ); + }; + + const NumberDivider = () => { + return ( + + : + + ); + }; + + useFocusEffect( + useCallback(() => { + navigation.setOptions({ + headerRight: () => ( + + ), + }); + }, []) + ); + + return ( + + + + + + + + + + + + + + + + {t( + "screens.device.scenes.editActions.modalWaitEditAction.waitDescription" + )} + + + + ); +} + +export function MyNumberModal({ + headerTitle, + numberDescription, + data, + selectedNumber, + setSelectedNumber, + action, + timeUnit, +}) { + const appContext = useContext(AppContext); + + const [isNumberModalOpen, setIsNumberModalOpen] = useState(false); + + return ( + <> + setIsNumberModalOpen(true)} + style={{ alignItems: "center" }} + > + + {data.find((d) => parseInt(d.number, 10) === selectedNumber).number} + + + + {numberDescription} + + + + setIsNumberModalOpen(false)} + headerTitle={headerTitle} + modalHeight={modalHeight} + > + item.number} + renderItem={({ item }) => ( + { + setSelectedNumber(parseInt(item.number, 10)); + + appContext.setDeviceSceneActions((arr) => { + const newArr = [...arr]; + + const actionIndex = newArr.findIndex( + (a) => a.actionId === action.actionId + ); + + if (actionIndex !== -1) { + newArr[actionIndex].modeAdjustments[timeUnit] = parseInt( + item.number, + 10 + ); + } + + return newArr; + }); + }} + itemSelected={selectedNumber === parseInt(item.number, 10)} + /> + )} + /> + + + ); +} diff --git a/src/Screens/Device/scene.js b/src/Screens/Device/scene.js index a16b0b0..73d843a 100644 --- a/src/Screens/Device/scene.js +++ b/src/Screens/Device/scene.js @@ -242,17 +242,23 @@ function ActionListItem({ drag, navigation, device, item }) { }; const ListItemTitle = () => { + let title = "???"; + + if (item.type === Constants.actionType.wait) { + title = t("screens.device.scenes.modalAddSceneAction.actions.wait"); + } else if (item.modeId !== "") { + title = itemModeList.find((m) => m.id === item.modeId).name[ + appContext.appLanguage + ]; + } + return ( - {item.modeId === "" - ? "???" - : itemModeList.find((m) => m.id === item.modeId).name[ - appContext.appLanguage - ]} + {title} ); }; @@ -351,8 +357,76 @@ function ActionListItem({ drag, navigation, device, item }) { case Constants.actionType.motor: navigateTo = "modalMotorEditAction"; itemModeList = appContext.deviceFirmwareModes.motorModes; + break; + case Constants.actionType.wait: + navigateTo = "modalWaitEditAction"; - //adjustments.push(); + let msg = ""; + + const hours = item.modeAdjustments.hours; + const minutes = item.modeAdjustments.minutes; + const seconds = item.modeAdjustments.seconds; + + const hoursText = + hours === 1 + ? t( + "screens.device.scenes.editActions.modalWaitEditAction.hours.singular" + ) + : t( + "screens.device.scenes.editActions.modalWaitEditAction.hours.plural" + ); + + const minutesText = + minutes === 1 + ? t( + "screens.device.scenes.editActions.modalWaitEditAction.minutes.singular" + ) + : t( + "screens.device.scenes.editActions.modalWaitEditAction.minutes.plural" + ); + + const secondsText = + seconds === 1 + ? t( + "screens.device.scenes.editActions.modalWaitEditAction.seconds.singular" + ) + : t( + "screens.device.scenes.editActions.modalWaitEditAction.seconds.plural" + ); + + const wordAndForBetterSceneActionListAdjustmentReadingText = t( + "screens.device.scenes.editActions.modalWaitEditAction.wordAndForBetterSceneActionListAdjustmentReading" + ); + + if (hours > 0) { + msg += `${hours} ${hoursText}`; + } + + if (minutes > 0) { + if (msg.length > 0) { + msg += ", "; + } + + if (hours > 0 && seconds === 0) { + msg += ` ${wordAndForBetterSceneActionListAdjustmentReadingText} `; + } + + msg += `${minutes} ${minutesText}`; + } + + if (seconds > 0) { + if (msg.length > 0) { + msg += ` ${wordAndForBetterSceneActionListAdjustmentReadingText} `; + } + + msg += `${seconds} ${secondsText}`; + } + + if (msg.length === 0) { + msg = `0 ${secondsText}`; + } + + adjustments.push({msg}} />); break; default: console.log("item type not defined" + item.type); @@ -395,6 +469,22 @@ function ActionListItem({ drag, navigation, device, item }) { ); } + const renderAdjustments = () => { + if (item.modeId === "" && item.type !== Constants.actionType.wait) { + return null; + } + + return ( + <> + {adjustments.map((adjustment, index) => ( + + {adjustment} + + ))} + + ); + }; + return ( - {item.modeId !== "" && ( - <> - {adjustments.map((adjustment, index) => ( - - {adjustment} - - ))} - - )} + {renderAdjustments()} @@ -462,7 +544,7 @@ export function ActionTypeIconName(actionType) { case Constants.actionType.motor: iconName = "axis-z-rotate-counterclockwise"; break; - case Constants.actionType.waitXSeconds: + case Constants.actionType.wait: iconName = "timer-sand"; break; case Constants.actionType.waitUntilTimeX: diff --git a/src/utils.js b/src/utils.js index 378d823..1412076 100644 --- a/src/utils.js +++ b/src/utils.js @@ -27,7 +27,7 @@ export const Constants = { layers: 0, ambilight: 1, motor: 2, - waitXSeconds: 3, + wait: 3, waitUntilTimeX: 4, stop: 5, timeControl: 6,