dynamic actions
parent
7ff264d494
commit
260f40fef3
|
@ -254,6 +254,8 @@ export function MyColorPickerV2({
|
|||
isUserExpertModeEnabled,
|
||||
appThemeText,
|
||||
onColorPickerChange,
|
||||
onColorPickerComplete,
|
||||
onColorSwatchPress,
|
||||
disabled,
|
||||
style,
|
||||
}) {
|
||||
|
@ -271,6 +273,7 @@ export function MyColorPickerV2({
|
|||
onColorPickerChange(color.hex);
|
||||
}}
|
||||
boundedThumb
|
||||
onComplete={onColorPickerComplete}
|
||||
>
|
||||
{disabled && (
|
||||
<View
|
||||
|
@ -330,6 +333,7 @@ export function MyColorPickerV2({
|
|||
onPress={() => {
|
||||
pickerRef.current.setColor(color);
|
||||
onColorPickerChange(color);
|
||||
onColorSwatchPress();
|
||||
}}
|
||||
onLongPress={() => {
|
||||
let filteredColors =
|
||||
|
@ -413,7 +417,7 @@ export function MyColorSwatch({ size, backgroundColor, style }) {
|
|||
borderRadius: 16,
|
||||
},
|
||||
AppStyles.Shadow,
|
||||
style
|
||||
style,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -9,6 +9,7 @@ export default function MySlider({
|
|||
minimumValue,
|
||||
maximumValue,
|
||||
inverted,
|
||||
onSlidingComplete,
|
||||
}) {
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
|
@ -24,6 +25,7 @@ export default function MySlider({
|
|||
maximumTrackTintColor={appContext.appTheme.slider.maximumTrackTintColor}
|
||||
thumbTintColor={appContext.appTheme.slider.thumbTintColor}
|
||||
step={1}
|
||||
onSlidingComplete={onSlidingComplete}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,8 @@ export default function LayerSelectionModalContent({ navigation, route }) {
|
|||
onPress={() => {
|
||||
const newAction = NewAction(
|
||||
GetDevice(appContext.devices).selectedScene,
|
||||
Constants.actionType.layers
|
||||
Constants.actionType.layers,
|
||||
{ layers: selectedLayer }
|
||||
);
|
||||
|
||||
appContext.setDeviceSceneActions((arr) => [...arr, newAction]);
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import { useContext } from "react";
|
||||
import { Image, ScrollView, Text, View } from "react-native";
|
||||
import { AppContext, AppStyles, ModalContainer } from "../../../../utils";
|
||||
import {
|
||||
AppContext,
|
||||
AppStyles,
|
||||
Constants,
|
||||
ModalContainer,
|
||||
} from "../../../../utils";
|
||||
import MyIcon from "../../../../Components/Icon";
|
||||
import { Divider } from "../../../../Components/Divider";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import MyTag from "../../../../Components/Tag";
|
||||
import MyPressable from "../../../../Components/Pressable";
|
||||
import { ActionTypeIconName } from "../../scene";
|
||||
|
||||
function Action({
|
||||
text,
|
||||
|
@ -79,7 +85,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
<ModalContainer withoutPadding>
|
||||
<Action
|
||||
text={t("screens.device.scenes.modalAddSceneAction.actions.layers")}
|
||||
iconName="lightbulb-on-outline"
|
||||
iconName={ActionTypeIconName(Constants.actionType.layers)}
|
||||
imageSource={require("../../../../../assets/layers.gif")}
|
||||
onPress={() => navigation.navigate("modalLayerSection", route.params)}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
|
@ -88,7 +94,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
|
||||
<Action
|
||||
text={t("screens.device.scenes.modalAddSceneAction.actions.motor")}
|
||||
iconName="axis-z-rotate-counterclockwise"
|
||||
iconName={ActionTypeIconName(Constants.actionType.motor)}
|
||||
imageSource={require("../../../../../assets/motor.gif")}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
|
@ -99,7 +105,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
text={t(
|
||||
"screens.device.scenes.modalAddSceneAction.actions.ambilight"
|
||||
)}
|
||||
iconName="television-ambient-light"
|
||||
iconName={ActionTypeIconName(Constants.actionType.ambilight)}
|
||||
imageSource={require("../../../../../assets/ambilight.gif")}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
|
@ -110,7 +116,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
text={t(
|
||||
"screens.device.scenes.modalAddSceneAction.actions.waitXSeconds"
|
||||
)}
|
||||
iconName="timer-sand"
|
||||
iconName={ActionTypeIconName(Constants.actionType.waitXSeconds)}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
supportedFirmwareVersions={["1.0.1"]}
|
||||
|
@ -120,7 +126,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
text={t(
|
||||
"screens.device.scenes.modalAddSceneAction.actions.waitUntilTimeX"
|
||||
)}
|
||||
iconName="clock-time-eight-outline"
|
||||
iconName={ActionTypeIconName(Constants.actionType.waitUntilTimeX)}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
supportedFirmwareVersions={["1.0.1"]}
|
||||
|
@ -128,7 +134,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
|
||||
<Action
|
||||
text={t("screens.device.scenes.modalAddSceneAction.actions.stop")}
|
||||
iconName="pause-octagon-outline"
|
||||
iconName={ActionTypeIconName(Constants.actionType.stop)}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
supportedFirmwareVersions={["1.0.1"]}
|
||||
|
@ -138,7 +144,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
text={t(
|
||||
"screens.device.scenes.modalAddSceneAction.actions.timeControl"
|
||||
)}
|
||||
iconName="timer-cog"
|
||||
iconName={ActionTypeIconName(Constants.actionType.timeControl)}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
supportedFirmwareVersions={["1.0.1"]}
|
||||
|
@ -148,7 +154,9 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
text={t(
|
||||
"screens.device.scenes.modalAddSceneAction.actions.waitForConfirmationWithKey"
|
||||
)}
|
||||
iconName="gesture-tap-button"
|
||||
iconName={ActionTypeIconName(
|
||||
Constants.actionType.waitForConfirmationWithKey
|
||||
)}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
supportedFirmwareVersions={["1.0.0"]}
|
||||
|
@ -158,7 +166,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
|
|||
text={t(
|
||||
"screens.device.scenes.modalAddSceneAction.actions.jumpToScene"
|
||||
)}
|
||||
iconName="debug-step-over"
|
||||
iconName={ActionTypeIconName(Constants.actionType.jumpToScene)}
|
||||
onPress={() => console.log("pressed action")}
|
||||
deviceFirmwareVersion={deviceFirmwareVersion}
|
||||
supportedFirmwareVersions={["1.0.0"]}
|
||||
|
|
|
@ -21,11 +21,10 @@ import Animated, {
|
|||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
} from "react-native-reanimated";
|
||||
import { Divider } from "../../../../../Components/Divider";
|
||||
import { MyIconButton } from "../../../../../Components/Button";
|
||||
import { ColorPickerRef } from "reanimated-color-picker"; // used
|
||||
import EditActionAnimationsCardContent, {
|
||||
EditActionAdjustmentContent,
|
||||
EditActionAdjustmentsContent,
|
||||
} from "..";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
|
@ -71,7 +70,7 @@ function LightModeDefaultColor({
|
|||
|
||||
export function LightsEditActionModalContent({ navigation, route }) {
|
||||
const appContext = useContext(AppContext);
|
||||
const [lightModeDefaultColors, setLightModeDefaultColors] = useState([]);
|
||||
|
||||
const sharedLightModeDefaultColors = useSharedValue([]);
|
||||
const [selectedDefaultLightModeColor, setSelectedDefaultLightModeColor] =
|
||||
useState(0);
|
||||
|
@ -89,24 +88,46 @@ export function LightsEditActionModalContent({ navigation, route }) {
|
|||
(a) => a.actionId === actionId
|
||||
);
|
||||
|
||||
const [lightModeDefaultColors, setLightModeDefaultColors] = useState([]);
|
||||
|
||||
const selectedLightMode = supportedDeviceLightModes.find(
|
||||
(s) => s.id === selectedSceneAction.modeId
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (colorPickerRef.current && selectedLightMode.defaults.length > 0) {
|
||||
colorPickerRef.current.setColor(selectedLightMode.defaults[0]);
|
||||
colorPickerRef.current.setColor(
|
||||
selectedSceneAction.modeAdjustments.colors[0]
|
||||
);
|
||||
}
|
||||
}, [lightModeDefaultColors]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedLightMode !== undefined) {
|
||||
sharedLightModeDefaultColors.value = selectedLightMode.defaults;
|
||||
setLightModeDefaultColors(selectedLightMode.defaults);
|
||||
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;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
|
@ -202,19 +223,6 @@ export function LightsEditActionModalContent({ navigation, route }) {
|
|||
<TouchableOpacity
|
||||
key={index}
|
||||
onPress={() => {
|
||||
/*const newSelection =
|
||||
selectedDefaultLightModeColor !== index
|
||||
? index
|
||||
: undefined;
|
||||
|
||||
setSelectedDefaultLightModeColor(newSelection);
|
||||
|
||||
if (newSelection !== undefined) {
|
||||
colorPickerRef.current.setColor(
|
||||
sharedLightModeDefaultColors.value[index]
|
||||
);
|
||||
}*/
|
||||
|
||||
setSelectedDefaultLightModeColor(index);
|
||||
|
||||
colorPickerRef.current.setColor(
|
||||
|
@ -247,23 +255,17 @@ export function LightsEditActionModalContent({ navigation, route }) {
|
|||
sharedLightModeDefaultColors.value = newColors;
|
||||
}
|
||||
}}
|
||||
onColorPickerComplete={() => saveColorsToModeAdjustments()}
|
||||
onColorSwatchPress={() => saveColorsToModeAdjustments()}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedLightMode.adjustments.length > 0 && (
|
||||
<>
|
||||
{selectedLightMode.adjustments.map((adjustment, index) => (
|
||||
<View key={index} style={{ marginTop: 10 }}>
|
||||
<EditActionAdjustmentContent
|
||||
adjustment={adjustment}
|
||||
appThemeText={appContext.appTheme.text}
|
||||
appLanguage={appContext.appLanguage}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<EditActionAdjustmentsContent
|
||||
action={selectedSceneAction}
|
||||
adjustmentType="mode"
|
||||
adjustments={selectedLightMode.adjustments}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
|
@ -306,6 +308,27 @@ export function LayersEditActionColorModeSelectionModalContent({
|
|||
|
||||
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;
|
||||
|
|
|
@ -3,6 +3,7 @@ import Card from "../../../../Components/Card";
|
|||
import {
|
||||
AppContext,
|
||||
AppStyles,
|
||||
Constants,
|
||||
IsPlatformIos,
|
||||
ModalContainer,
|
||||
} from "../../../../utils";
|
||||
|
@ -23,8 +24,6 @@ export default function EditActionAnimationsCardContent({
|
|||
const appContext = useContext(AppContext);
|
||||
const { t } = useTranslation();
|
||||
|
||||
console.log("act", action);
|
||||
|
||||
const selectedLightAnimationIn =
|
||||
appContext.deviceFirmwareModes.lightAnimationsIn.find(
|
||||
(animation) => animation.id === action.animationInId
|
||||
|
@ -67,15 +66,11 @@ export default function EditActionAnimationsCardContent({
|
|||
}
|
||||
/>
|
||||
|
||||
{selectedLightAnimationIn.adjustments.length > 0 &&
|
||||
selectedLightAnimationIn.adjustments.map((adjustment, index) => (
|
||||
<EditActionAdjustmentContent
|
||||
key={index}
|
||||
adjustment={adjustment}
|
||||
appLanguage={appContext.appLanguage}
|
||||
appThemeText={appContext.appTheme.text}
|
||||
/>
|
||||
))}
|
||||
<EditActionAdjustmentsContent
|
||||
action={action}
|
||||
adjustmentType="animationIn"
|
||||
adjustment={selectedLightAnimationIn.adjustment}
|
||||
/>
|
||||
|
||||
<Text
|
||||
style={[
|
||||
|
@ -110,15 +105,11 @@ export default function EditActionAnimationsCardContent({
|
|||
}
|
||||
/>
|
||||
|
||||
{selectedLightAnimationOut.adjustments.length > 0 &&
|
||||
selectedLightAnimationOut.adjustments.map((adjustment, index) => (
|
||||
<EditActionAdjustmentContent
|
||||
key={index}
|
||||
adjustment={adjustment}
|
||||
appLanguage={appContext.appLanguage}
|
||||
appThemeText={appContext.appTheme.text}
|
||||
/>
|
||||
))}
|
||||
<EditActionAdjustmentsContent
|
||||
action={action}
|
||||
adjustmentType="animationOut"
|
||||
adjustment={selectedLightAnimationOut.adjustment}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
|
@ -185,6 +176,14 @@ export function EditActionAnimationSelectionModalContent({
|
|||
|
||||
newArr[foundActionIndex][animationType] = item.id;
|
||||
|
||||
const type =
|
||||
animationType === "animationInId"
|
||||
? "animationInAdjustment"
|
||||
: "animationOutAdjustment";
|
||||
|
||||
newArr[foundActionIndex][type][item.adjustment.variableName] =
|
||||
item.adjustment.defaultValue;
|
||||
|
||||
return newArr;
|
||||
});
|
||||
}}
|
||||
|
@ -196,44 +195,101 @@ export function EditActionAnimationSelectionModalContent({
|
|||
);
|
||||
}
|
||||
|
||||
export function EditActionAdjustmentContent({
|
||||
export function EditActionAdjustmentsContent({
|
||||
action,
|
||||
adjustmentType,
|
||||
adjustment,
|
||||
appThemeText,
|
||||
appLanguage,
|
||||
adjustments,
|
||||
}) {
|
||||
const [sliderValue, setSliderValue] = useState(0);
|
||||
if (adjustments === undefined && Object.keys(adjustment).length === 0)
|
||||
return <></>;
|
||||
|
||||
if (adjustment.type === "slider") {
|
||||
if (adjustments !== undefined) {
|
||||
return (
|
||||
<>
|
||||
<Text style={[AppStyles.typography14, { color: appThemeText }]}>
|
||||
{adjustment.name[appLanguage]}
|
||||
</Text>
|
||||
<FlatList
|
||||
data={adjustments}
|
||||
scrollEnabled={false}
|
||||
renderItem={({ item }) => {
|
||||
if (item.type === "slider") {
|
||||
return (
|
||||
<EditActionSliderAdjustment
|
||||
action={action}
|
||||
adjustmentType={adjustmentType}
|
||||
adjustment={item}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<MyIcon name={adjustment.iconName} size={24} />
|
||||
|
||||
<MySlider
|
||||
style={[{ flex: 1 }, IsPlatformIos() && { marginLeft: 6 }]}
|
||||
minimumValue={adjustment.min}
|
||||
maximumValue={adjustment.max}
|
||||
onValueChange={(v) => {
|
||||
console.log(`change ${adjustment.variableName}`, v);
|
||||
setSliderValue(v);
|
||||
}}
|
||||
value={sliderValue}
|
||||
/>
|
||||
|
||||
<View style={{ width: 32, alignItems: "center" }}>
|
||||
<Text style={{ color: appThemeText }}>
|
||||
{sliderValue}
|
||||
{adjustment.unitOfMeasurement}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
return <Text>Item type not found</Text>;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
return (
|
||||
<EditActionSliderAdjustment
|
||||
action={action}
|
||||
adjustmentType={adjustmentType}
|
||||
adjustment={adjustment}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function EditActionSliderAdjustment({ action, adjustmentType, adjustment }) {
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
const type =
|
||||
adjustmentType === "mode"
|
||||
? "modeAdjustments"
|
||||
: adjustmentType === "animationIn"
|
||||
? "animationInAdjustment"
|
||||
: "animationOutAdjustment";
|
||||
|
||||
const [sliderValue, setSliderValue] = useState(
|
||||
action[type][adjustment.variableName]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
style={[AppStyles.typography14, { color: appContext.appTheme.text }]}
|
||||
>
|
||||
{adjustment.name[appContext.appLanguage]}
|
||||
</Text>
|
||||
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<MyIcon name={adjustment.iconName} size={24} />
|
||||
|
||||
<MySlider
|
||||
style={[{ flex: 1 }, IsPlatformIos() && { marginLeft: 6 }]}
|
||||
minimumValue={adjustment.min}
|
||||
maximumValue={adjustment.max}
|
||||
onValueChange={(v) => setSliderValue(v)}
|
||||
value={sliderValue}
|
||||
onSlidingComplete={(v) =>
|
||||
appContext.setDeviceSceneActions((arr) => {
|
||||
const newArr = [...arr];
|
||||
|
||||
const foundActionIndex = arr.findIndex(
|
||||
(a) => a.actionId === action.actionId
|
||||
);
|
||||
|
||||
if (foundActionIndex !== -1) {
|
||||
newArr[foundActionIndex][type][adjustment.variableName] = v;
|
||||
}
|
||||
|
||||
return newArr;
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
||||
<View style={{ width: 32, alignItems: "center" }}>
|
||||
<Text style={{ color: appContext.appTheme.text }}>
|
||||
{sliderValue}
|
||||
{adjustment.unitOfMeasurement[appContext.appLanguage]}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -85,52 +85,46 @@ export default function SceneView({ navigation }) {
|
|||
iconName={"selection-search"}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<FlatList
|
||||
scrollEnabled={false}
|
||||
data={deviceSceneActions}
|
||||
keyExtractor={(item) => item.actionId}
|
||||
ListEmptyComponent={
|
||||
<MyResult
|
||||
text={t("screens.device.scenes.infoNoActionsAvailableInScene")}
|
||||
iconName={"selection-search"}
|
||||
<FlatList
|
||||
scrollEnabled={false}
|
||||
data={deviceSceneActions}
|
||||
keyExtractor={(item) => item.actionId}
|
||||
ListEmptyComponent={
|
||||
<MyResult
|
||||
text={t("screens.device.scenes.infoNoActionsAvailableInScene")}
|
||||
iconName={"selection-search"}
|
||||
/>
|
||||
}
|
||||
ListFooterComponent={
|
||||
<MyTextButton
|
||||
title={t("screens.device.scenes.buttonAddAction")}
|
||||
styleContainer={{
|
||||
alignItems: "center",
|
||||
marginTop: 10,
|
||||
}}
|
||||
style={{ padding: 8 }}
|
||||
actionColor={
|
||||
deviceSceneActions === undefined ||
|
||||
deviceSceneActions.length === 0
|
||||
}
|
||||
onPress={() =>
|
||||
navigation.navigate("modalAddSceneAction", {
|
||||
deviceFirmwareVersion: device.firmware.version,
|
||||
})
|
||||
}
|
||||
iconName="plus-circle-outline"
|
||||
/>
|
||||
}
|
||||
renderItem={({ item }) => {
|
||||
return (
|
||||
<ActionListItem
|
||||
navigation={navigation}
|
||||
device={device}
|
||||
item={item}
|
||||
/>
|
||||
}
|
||||
ListFooterComponent={
|
||||
<MyTextButton
|
||||
title={t("screens.device.scenes.buttonAddAction")}
|
||||
styleContainer={{
|
||||
alignItems: "center",
|
||||
marginTop: 10,
|
||||
}}
|
||||
style={{ padding: 8 }}
|
||||
actionColor={
|
||||
deviceSceneActions === undefined ||
|
||||
deviceSceneActions.length === 0
|
||||
}
|
||||
onPress={() =>
|
||||
navigation.navigate("modalAddSceneAction", {
|
||||
deviceFirmwareVersion: device.firmware.version,
|
||||
})
|
||||
}
|
||||
iconName="plus-circle-outline"
|
||||
/>
|
||||
}
|
||||
renderItem={({ item }) => {
|
||||
console.log("item", item);
|
||||
|
||||
return (
|
||||
<ActionListItem
|
||||
navigation={navigation}
|
||||
device={device}
|
||||
item={item}
|
||||
appThemeText={appContext.appTheme.text}
|
||||
appThemeTextSecondary={appContext.appTheme.textSecondary}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MyDotsModal
|
||||
|
@ -187,15 +181,110 @@ export default function SceneView({ navigation }) {
|
|||
);
|
||||
}
|
||||
|
||||
function ActionListItem({
|
||||
navigation,
|
||||
device,
|
||||
item,
|
||||
appThemeText,
|
||||
appThemeTextSecondary,
|
||||
}) {
|
||||
function ActionListItem({ navigation, device, item }) {
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
const ListItemTitle = () => {
|
||||
return (
|
||||
<Text
|
||||
style={{
|
||||
color: appContext.appTheme.colors.primary,
|
||||
}}
|
||||
>
|
||||
{item.modeId === ""
|
||||
? "???"
|
||||
: appContext.deviceFirmwareModes.lightModes.find(
|
||||
(lM) => lM.id === item.modeId
|
||||
).name[appContext.appLanguage]}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
const getAnimationText = (animationInOrOutList, itemId, itemAdjustment) => {
|
||||
const usedAnimation = animationInOrOutList.find((lA) => lA.id === itemId);
|
||||
|
||||
return `${usedAnimation.name[appContext.appLanguage]} (${
|
||||
itemAdjustment[usedAnimation.adjustment.variableName]
|
||||
}${usedAnimation.adjustment.unitOfMeasurement[appContext.appLanguage]})`;
|
||||
};
|
||||
|
||||
const ListItemAdjustments = () => {
|
||||
let adjustments = [];
|
||||
|
||||
if (
|
||||
item.type === Constants.actionType.layers &&
|
||||
item.modeAdjustments.layers !== undefined
|
||||
) {
|
||||
adjustments.push(
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<Text style={{ color: appContext.appTheme.textSecondary }}>
|
||||
{appContext.deviceFirmwareModes.lightModes.find(
|
||||
(lM) => lM.id === item.modeId
|
||||
).defaults.length === 0
|
||||
? `Apply to layer ${item.modeAdjustments.layers.join(", ")}`
|
||||
: ` Set layer ${item.modeAdjustments.layers.join(", ")} to ${
|
||||
item.modeAdjustments.colors.length === 0 ? "???" : ""
|
||||
}`}
|
||||
</Text>
|
||||
|
||||
{item.modeAdjustments.colors !== undefined &&
|
||||
item.modeAdjustments.colors.map((color, index) => (
|
||||
<MyColorSwatch
|
||||
key={index}
|
||||
backgroundColor={color}
|
||||
size={16}
|
||||
style={{ marginRight: -2 }}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
item.animationInId !== Constants.defaultAnimationId ||
|
||||
item.animationOutId !== Constants.defaultAnimationId
|
||||
) {
|
||||
let inAndOutAnimation = [];
|
||||
|
||||
if (item.animationInId !== Constants.defaultAnimationId) {
|
||||
inAndOutAnimation.push(
|
||||
getAnimationText(
|
||||
appContext.deviceFirmwareModes.lightAnimationsIn,
|
||||
item.animationInId,
|
||||
item.animationInAdjustment
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (item.animationOutId !== Constants.defaultAnimationId) {
|
||||
inAndOutAnimation.push(
|
||||
getAnimationText(
|
||||
appContext.deviceFirmwareModes.lightAnimationsOut,
|
||||
item.animationOutId,
|
||||
item.animationOutAdjustment
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
adjustments.push(
|
||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 6 }}>
|
||||
<MyIcon name="transition" size={16} />
|
||||
<Text style={{ color: appContext.appTheme.textSecondary }}>
|
||||
{inAndOutAnimation.join(", ")}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return adjustments.map((adjustment, index) => (
|
||||
<View key={index} style={{ flexDirection: "row" }}>
|
||||
{adjustment}
|
||||
</View>
|
||||
));
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={{ marginLeft: 10, marginRight: 10 }}>
|
||||
<View style={{ marginLeft: 15, marginRight: 15 }}>
|
||||
<TouchableOpacity
|
||||
onPress={() =>
|
||||
navigation.navigate("modalLayersEditAction", {
|
||||
|
@ -211,41 +300,17 @@ function ActionListItem({
|
|||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
{console.log("itemtype", item.type)}
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<MyIcon name={ActionTypeIconName(item.type)} size={24} />
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
<MyIcon
|
||||
name={ActionTypeIconName(item.type)}
|
||||
size={24}
|
||||
style={item.modeId !== "" && { marginTop: 6 }}
|
||||
/>
|
||||
|
||||
<View style={{ marginLeft: 12 }}>
|
||||
<Text
|
||||
style={{
|
||||
color: appThemeText,
|
||||
}}
|
||||
>
|
||||
{item.modeId === "" ? "???" : item.modeId}
|
||||
</Text>
|
||||
<ListItemTitle />
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: appThemeTextSecondary,
|
||||
}}
|
||||
>
|
||||
Set to
|
||||
</Text>
|
||||
|
||||
<MyColorSwatch
|
||||
style={{ marginLeft: 6 }}
|
||||
size={16}
|
||||
backgroundColor={"red"}
|
||||
/>
|
||||
<MyColorSwatch size={16} backgroundColor={"orange"} />
|
||||
<MyColorSwatch size={16} backgroundColor={"blue"} />
|
||||
</View>
|
||||
{item.modeId !== "" && <ListItemAdjustments />}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
|
|
108
src/utils.js
108
src/utils.js
|
@ -26,11 +26,18 @@ export const Constants = {
|
|||
layers: 0,
|
||||
ambilight: 1,
|
||||
motor: 2,
|
||||
waitXSeconds: 3,
|
||||
waitUntilTimeX: 4,
|
||||
stop: 5,
|
||||
timeControl: 6,
|
||||
waitForConfirmationWithKey: 7,
|
||||
jumpToScene: 8,
|
||||
},
|
||||
globals: {
|
||||
max_device_name_length: 20,
|
||||
max_scene_name_length: 20,
|
||||
},
|
||||
defaultAnimationId: "00000000-0000-0000-0000-000000000000", // used id for -> No animation selected
|
||||
};
|
||||
|
||||
export const AppStyles = StyleSheet.create({
|
||||
|
@ -219,7 +226,7 @@ const devDevicesFirmwareModes = {
|
|||
de: "Zufällig",
|
||||
en: "Random",
|
||||
},
|
||||
defaults: ["pink", "orange", "blue"],
|
||||
defaults: ["red", "orange", "blue"],
|
||||
adjustments: [
|
||||
{
|
||||
type: "slider",
|
||||
|
@ -231,7 +238,11 @@ const devDevicesFirmwareModes = {
|
|||
},
|
||||
min: 0,
|
||||
max: 6,
|
||||
unitOfMeasurement: "s",
|
||||
defaultValue: 2,
|
||||
unitOfMeasurement: {
|
||||
de: "s",
|
||||
en: "s",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -254,7 +265,11 @@ const devDevicesFirmwareModes = {
|
|||
},
|
||||
min: 0,
|
||||
max: 100,
|
||||
unitOfMeasurement: "s",
|
||||
defaultValue: 45,
|
||||
unitOfMeasurement: {
|
||||
de: "s",
|
||||
en: "s",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "slider",
|
||||
|
@ -266,7 +281,11 @@ const devDevicesFirmwareModes = {
|
|||
},
|
||||
min: 1,
|
||||
max: 10,
|
||||
unitOfMeasurement: "s",
|
||||
defaultValue: 8,
|
||||
unitOfMeasurement: {
|
||||
de: "s",
|
||||
en: "s",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -279,7 +298,7 @@ const devDevicesFirmwareModes = {
|
|||
de: "Keine",
|
||||
en: "None",
|
||||
},
|
||||
adjustments: [],
|
||||
adjustment: {},
|
||||
},
|
||||
{
|
||||
id: "6c5570da-ec53-4788-a8cd-03c724eb81b8",
|
||||
|
@ -288,20 +307,22 @@ const devDevicesFirmwareModes = {
|
|||
de: "Aufblenden",
|
||||
en: "Fade in",
|
||||
},
|
||||
adjustments: [
|
||||
{
|
||||
type: "slider",
|
||||
variableName: "duration",
|
||||
name: {
|
||||
de: "Dauer",
|
||||
en: "Duration",
|
||||
},
|
||||
iconName: "repeat-variant",
|
||||
min: 1,
|
||||
max: 60,
|
||||
unitOfMeasurement: "s",
|
||||
adjustment: {
|
||||
type: "slider",
|
||||
variableName: "duration",
|
||||
name: {
|
||||
de: "Dauer",
|
||||
en: "Duration",
|
||||
},
|
||||
],
|
||||
iconName: "repeat-variant",
|
||||
min: 1,
|
||||
max: 60,
|
||||
defaultValue: 30,
|
||||
unitOfMeasurement: {
|
||||
de: "s",
|
||||
en: "s",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
lightAnimationsOut: [
|
||||
|
@ -312,7 +333,7 @@ const devDevicesFirmwareModes = {
|
|||
de: "Keine",
|
||||
en: "None",
|
||||
},
|
||||
adjustments: [],
|
||||
adjustment: {},
|
||||
},
|
||||
{
|
||||
id: "cb5b791e-213c-4684-9585-b0c42cbfafb5",
|
||||
|
@ -321,20 +342,22 @@ const devDevicesFirmwareModes = {
|
|||
de: "Ausblenden",
|
||||
en: "Fade out",
|
||||
},
|
||||
adjustments: [
|
||||
{
|
||||
type: "slider",
|
||||
variableName: "duration",
|
||||
name: {
|
||||
de: "Dauer",
|
||||
en: "Duration",
|
||||
},
|
||||
iconName: "repeat-variant",
|
||||
min: 1,
|
||||
max: 60,
|
||||
unitOfMeasurement: "s",
|
||||
adjustment: {
|
||||
type: "slider",
|
||||
variableName: "duration",
|
||||
name: {
|
||||
de: "Dauer",
|
||||
en: "Duration",
|
||||
},
|
||||
],
|
||||
iconName: "repeat-variant",
|
||||
min: 1,
|
||||
max: 60,
|
||||
defaultValue: 30,
|
||||
unitOfMeasurement: {
|
||||
de: "s",
|
||||
en: "s",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
motorModes: [
|
||||
|
@ -351,8 +374,6 @@ const devDevicesFirmwareModes = {
|
|||
],
|
||||
};
|
||||
|
||||
export const DevDeviceId = "1f21a12a-0bec-4336-99bb-df3f9fc9f537";
|
||||
|
||||
// this data is transmitted from the device to the user app
|
||||
const devDevices = [
|
||||
{
|
||||
|
@ -394,27 +415,40 @@ export function NewDeviceScene(name) {
|
|||
};
|
||||
}
|
||||
|
||||
// preview
|
||||
const devDeviceSceneActions = [
|
||||
{
|
||||
actionId: "", // random id
|
||||
sceneId: "",
|
||||
type: "", // layers, ambilight, motor
|
||||
modeId: "",
|
||||
// affected layers, animation speed...
|
||||
modeAdjustments: {
|
||||
layers: [0, 1],
|
||||
colors: ["#fff", "#000"],
|
||||
},
|
||||
animationInId: "",
|
||||
animationOutId: "",
|
||||
adjustments: [], // affected layers, animation speed...
|
||||
animationInAdjustment: {
|
||||
duration: 32,
|
||||
},
|
||||
animationOutAdjustment: {
|
||||
duration: 32,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export function NewAction(sceneId, actionType) {
|
||||
export function NewAction(sceneId, actionType, modeAdjustments) {
|
||||
return {
|
||||
actionId: GetUuid(),
|
||||
sceneId: sceneId,
|
||||
type: actionType, // layers, ambilight, motor
|
||||
modeId: "",
|
||||
modeAdjustments: modeAdjustments,
|
||||
animationInId: "00000000-0000-0000-0000-000000000000", // default animation id for -> No animation selected
|
||||
animationInAdjustment: {},
|
||||
animationOutId: "00000000-0000-0000-0000-000000000000", // default animation id for -> No animation selected
|
||||
adjustments: [],
|
||||
animationOutAdjustment: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue