expo-app/src/Screens/Device/modals/EditActions/Lights/index.js

393 lines
12 KiB
JavaScript

import {
FlatList,
ScrollView,
Text,
TouchableOpacity,
View,
} from "react-native";
import {
MyDeviceTabButton,
MyDeviceTabButtonContainer,
topFirst,
topSecond,
} from "../../../deviceTabButton";
import Card from "../../../../../Components/Card";
import MyDropdown from "../../../../../Components/Dropdown";
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { AppContext, AppStyles, ModalContainer } from "../../../../../utils";
import {
MyDotsModal,
MyPickerModalListItem,
} from "../../../../../Components/Modal";
import { MyColorPickerV2 } from "../../../../../Components/ColorPicker";
import Animated, {
useAnimatedStyle,
useSharedValue,
} from "react-native-reanimated";
import { MyIconButton } from "../../../../../Components/Button";
import { ColorPickerRef } from "reanimated-color-picker"; // used
import EditActionAnimationsCardContent, {
EditActionAdjustmentsContent,
} from "..";
import { useTranslation } from "react-i18next";
import { useFocusEffect } from "@react-navigation/native";
import { DeviceLivePreview } from "../../..";
function LightModeDefaultColor({
sharedColor,
index,
backgroundColor,
selected,
}) {
const backgroundColorStyle = useAnimatedStyle(() => {
return {
backgroundColor: sharedColor.value[index],
};
});
return (
<Animated.View
style={[
{
width: 32,
height: 32,
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
},
backgroundColorStyle,
]}
>
<Animated.View
style={[
{
width: 28,
height: 28,
borderRadius: 8,
},
backgroundColorStyle,
selected && { borderWidth: 2, borderColor: backgroundColor },
]}
/>
</Animated.View>
);
}
export function LightsEditActionModalContent({ navigation, route }) {
const appContext = useContext(AppContext);
const sharedLightModeDefaultColors = useSharedValue([]);
const [selectedDefaultLightModeColor, setSelectedDefaultLightModeColor] =
useState(0);
const colorPickerRef = useRef(ColorPickerRef);
const { t } = useTranslation();
const { actionId, deviceFirmwareVersion } = route.params;
useFocusEffect(
useCallback(() => {
navigation.setOptions({
headerRight: () => (
<MyDotsModal
modalData={[
/*{
Duplicated item as references to the old action -> if the color is changed it will apply on both actions
icon: "content-duplicate",
label: t(
"screens.device.scenes.modalDotsEditAction.duplicateAction"
),
onPress: () => {
const currentSelectedAction =
appContext.deviceSceneActions.find(
(a) => a.actionId === actionId
);
appContext.setDeviceSceneActions((arr) => {
const duplicatedAction = {
...currentSelectedAction,
actionId: GetUuid(),
};
return [...arr, duplicatedAction];
});
navigation.goBack();
},
},*/
{
icon: "trash-can",
label: t(
"screens.device.scenes.modalDotsEditAction.deleteAction"
),
onPress: () => {
appContext.setDeviceSceneActions((actions) =>
actions.filter((a) => a.actionId !== actionId)
);
navigation.goBack();
},
},
]}
/>
),
});
}, [])
);
const supportedDeviceLightModes =
appContext.deviceFirmwareModes.lightModes.filter((lightMode) =>
lightMode.supportedFirmwareVersions.includes(deviceFirmwareVersion)
);
const selectedSceneAction = appContext.deviceSceneActions.find(
(a) => a.actionId === actionId
);
const [lightModeDefaultColors, setLightModeDefaultColors] = useState([]);
// check if selectedSceneAction exists before accessing modeId as the action could be deleted by the user
const selectedLightMode = supportedDeviceLightModes.find(
(s) => s.id === (selectedSceneAction && selectedSceneAction.modeId)
);
useEffect(() => {
if (colorPickerRef.current && selectedLightMode.defaults.length > 0) {
colorPickerRef.current.setColor(
selectedSceneAction.modeAdjustments.colors[0]
);
}
}, [lightModeDefaultColors]);
useEffect(() => {
if (selectedLightMode !== undefined) {
sharedLightModeDefaultColors.value =
selectedSceneAction.modeAdjustments.colors;
setLightModeDefaultColors(selectedSceneAction.modeAdjustments.colors);
setSelectedDefaultLightModeColor(0);
}
}, [selectedSceneAction?.modeId]);
const saveColorsToModeAdjustments = () => {
appContext.setDeviceSceneActions((arr) => {
const newArr = [...arr];
const foundSceneActionIndex = arr.findIndex(
(a) => a.actionId === selectedSceneAction.actionId
);
if (foundSceneActionIndex !== -1) {
newArr[foundSceneActionIndex].modeAdjustments.colors =
sharedLightModeDefaultColors.value;
}
return newArr;
});
};
if (!selectedSceneAction) return null;
return (
<View
style={{
backgroundColor: appContext.appTheme.backgroundColor,
height: "100%",
}}
>
<DeviceLivePreview />
<MyDeviceTabButtonContainer>
<MyDeviceTabButton
iconName="play-network-outline"
onPress={() => console.log("pressed")}
/>
<MyDeviceTabButton
iconName="play-box-multiple-outline"
onPress={() => console.log("pressed2")}
/>
</MyDeviceTabButtonContainer>
<ScrollView>
<Card>
<MyDropdown
style={{ marginBottom: 2 }}
label={t(
"screens.device.scenes.modalLayersEditAction.dropdownColorModeSelection.label"
)}
selectedItemLabel={
selectedSceneAction.modeId === ""
? t(
"screens.device.scenes.modalLayersEditAction.dropdownColorModeSelection.noColorModeSelected"
)
: selectedLightMode.name[appContext.appLanguage]
}
onPress={() =>
navigation.navigate("modalLayersEditActionColorModeSelection", {
supportedDeviceLightModes: supportedDeviceLightModes,
action: selectedSceneAction,
})
}
/>
{selectedSceneAction.modeId !== "" && (
<>
{lightModeDefaultColors.length > 0 && (
<>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginTop: 2,
}}
>
<Text
style={[
AppStyles.typography14,
{
marginTop: 4,
marginBottom: 4,
color: appContext.appTheme.text,
},
]}
>
{t(
"screens.device.scenes.modalLayersEditAction.modeSpecificColors"
)}
</Text>
<MyIconButton iconName="restore" iconSize={24} />
</View>
<View
style={{
flexDirection: "row",
gap: 10,
flexWrap: "wrap",
justifyContent: "center",
}}
>
{lightModeDefaultColors.map((_, index) => (
<TouchableOpacity
key={index}
onPress={() => {
setSelectedDefaultLightModeColor(index);
colorPickerRef.current.setColor(
sharedLightModeDefaultColors.value[index]
);
}}
>
<LightModeDefaultColor
sharedColor={sharedLightModeDefaultColors}
index={index}
backgroundColor={appContext.appTheme.backgroundColor}
selected={selectedDefaultLightModeColor === index}
/>
</TouchableOpacity>
))}
</View>
<MyColorPickerV2
pickerRef={colorPickerRef}
style={{ marginTop: 10 }}
appThemeText={appContext.appTheme.text}
isUserExpertModeEnabled={appContext.isUserExpertModeEnabled}
disabled={selectedDefaultLightModeColor === undefined}
onColorPickerChange={(color) => {
if (selectedDefaultLightModeColor !== undefined) {
let newColors = sharedLightModeDefaultColors.value;
newColors[selectedDefaultLightModeColor] = color;
sharedLightModeDefaultColors.value = newColors;
}
}}
onColorPickerComplete={() => saveColorsToModeAdjustments()}
onColorSwatchPress={() => saveColorsToModeAdjustments()}
/>
</>
)}
<EditActionAdjustmentsContent
action={selectedSceneAction}
adjustmentType="mode"
adjustments={selectedLightMode.adjustments}
/>
</>
)}
</Card>
<EditActionAnimationsCardContent
disabled={selectedSceneAction.modeId === ""}
navigation={navigation}
deviceFirmwareVersion={deviceFirmwareVersion}
action={selectedSceneAction}
/>
</ScrollView>
</View>
);
}
export function LayersEditActionColorModeSelectionModalContent({
navigation,
route,
}) {
const appContext = useContext(AppContext);
const { action } = route.params;
return (
<ModalContainer withoutPadding>
<FlatList
data={route.params.supportedDeviceLightModes}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<MyPickerModalListItem
itemName={item.name[appContext.appLanguage]}
itemSelected={action.modeId === item.id}
onPress={() => {
appContext.setDeviceSceneActions((arr) => {
const newArr = [...arr];
const actionIndex = newArr.findIndex(
(a) => a.actionId === action.actionId
);
if (actionIndex !== -1) {
newArr[actionIndex].modeId = item.id;
const lightModeDefaultColors =
appContext.deviceFirmwareModes.lightModes.find(
(lM) => lM.id === item.id
);
if (lightModeDefaultColors !== undefined) {
if (lightModeDefaultColors.defaults !== undefined) {
newArr[actionIndex].modeAdjustments.colors =
appContext.deviceFirmwareModes.lightModes.find(
(lM) => lM.id === item.id
).defaults;
}
}
item.adjustments.forEach(
(adjustment) =>
(newArr[actionIndex].modeAdjustments[
adjustment.variableName
] = adjustment.defaultValue)
);
}
return newArr;
});
navigation.goBack();
}}
/>
)}
/>
</ModalContainer>
);
}