added action handling for ambilight

main
alex 2023-08-06 23:17:59 +00:00
parent 0c4db80d8c
commit 4a92df31b0
9 changed files with 350 additions and 251 deletions

42
App.js
View File

@ -21,10 +21,6 @@ import { createStackNavigator } from "@react-navigation/stack";
import { TouchableOpacity } from "react-native";
import MyIcon from "./src/Components/Icon";
import { useTranslation } from "react-i18next";
import {
LayersEditActionColorModeSelectionModalContent,
LightsEditActionModalContent,
} from "./src/Screens/Device/modals/EditActions/Lights";
import ChooseSceneModalContent from "./src/Screens/Device/modals/ChooseScene";
import CreateSceneModalContent from "./src/Screens/Device/modals/ChooseScene/CreateScene";
import AddSceneActionModalContent from "./src/Screens/Device/modals/AddSceneAction";
@ -33,9 +29,12 @@ import {
SettingsAppColorSchemeModalContent,
SettingsAppLanguageModalContent,
} from "./src/Screens/Settings";
import { EditActionAnimationSelectionModalContent } from "./src/Screens/Device/modals/EditActions";
import UpdateSceneNameModalContent from "./src/Screens/Device/modals/UpdateSceneName";
import SettingsChangeDeviceDisplayNameModalContent from "./src/Screens/Device/modals/SettingsChangeDeviceDisplayName";
import LightsEditActionModalContent, {
LightsEditActionColorModeSelectionModalContent,
} from "./src/Screens/Device/modals/EditActions/Lights";
import { EditActionAnimationSelectionModalContent } from "./src/Screens/Device/modals/EditActions";
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
@ -161,66 +160,47 @@ export function MyApp() {
/>
<Stack.Screen
name="modalLayerSection"
name="modalLayerSelection"
component={LayerSelectionModalContent}
options={({ navigation }) =>
options({
navigation: navigation,
pageTitle: t(
"screens.device.scenes.modalLayerSection.pageTitle"
"screens.device.scenes.modalLayerSelection.pageTitle"
),
})
}
/>
<Stack.Screen
name="modalLayersEditAction"
name="modalLightsEditAction"
component={LightsEditActionModalContent}
options={({ navigation }) =>
options({
navigation: navigation,
pageTitle: t(
"screens.device.scenes.modalLayersEditAction.pageTitle"
),
})
}
/>
<Stack.Screen
name="modalLayersEditActionColorModeSelection"
component={LayersEditActionColorModeSelectionModalContent}
name="modalLightsEditActionColorModeSelection"
component={LightsEditActionColorModeSelectionModalContent}
options={({ navigation }) =>
options({
navigation: navigation,
pageTitle: t(
"screens.device.scenes.modalLayersEditActionColorModeSelection.pageTitle"
"screens.device.scenes.editActions.modalLightsEditActionColorModeSelection.pageTitle"
),
})
}
/>
<Stack.Screen
name="modalEditActionAnimationInSelection"
name="modalEditActionAnimationInOrOutSelection"
component={EditActionAnimationSelectionModalContent}
options={({ navigation }) =>
options({
navigation: navigation,
pageTitle: t(
"screens.device.scenes.modalEditActionAnimationInSelection.pageTitle"
),
})
}
/>
<Stack.Screen
name="modalEditActionAnimationOutSelection"
component={EditActionAnimationSelectionModalContent}
options={({ navigation }) =>
options({
navigation: navigation,
pageTitle: t(
"screens.device.scenes.modalEditActionAnimationOutSelection.pageTitle"
),
})
}
/>

View File

@ -46,7 +46,8 @@
"oneLayer": "Ebene",
"multipleLayers": "Ebenen"
}
}
},
"ambilight": "Umgebungslicht setzen auf"
},
"modalChooseScene": {
"pageTitle": "Wähle eine Szene aus",
@ -75,11 +76,13 @@
"jumpToScene": "Springe zu Szene"
}
},
"modalLayerSection": {
"modalLayerSelection": {
"pageTitle": "Layer auswahl"
},
"modalLayersEditAction": {
"pageTitle": "Ebenen bearbeiten",
"editActions": {
"modalLightsEditAction": {
"layersPageTitle": "Ebenen bearbeiten",
"ambilightPageTitle": "Ambilight bearbeiten",
"dropdownColorModeSelection": {
"label": "Wähle einen Farbmodus",
"noColorModeSelected": "Kein Farbmodus ausgewählt"
@ -100,7 +103,7 @@
"label": "Wähle eine Animation out"
}
},
"modalLayersEditActionColorModeSelection": {
"modalLightsEditActionColorModeSelection": {
"pageTitle": "Wähle einen Farbmodus"
},
"modalEditActionAnimationInSelection": {
@ -110,6 +113,7 @@
"modalEditActionAnimationOutSelection": {
"pageTitle": "Animation out auswählen",
"noResult": "Keine Animationen verfügbar"
}
},
"modalUpdateSceneName": {
"pageTitle": "Szenennamen ändern",

View File

@ -46,7 +46,8 @@
"oneLayer": "layer",
"multipleLayers": "layers"
}
}
},
"ambilight": "Set ambilight to"
},
"modalChooseScene": {
"pageTitle": "Choose a scene",
@ -75,11 +76,13 @@
"jumpToScene": "Jump to scene"
}
},
"modalLayerSection": {
"modalLayerSelection": {
"pageTitle": "Layer selection"
},
"modalLayersEditAction": {
"pageTitle": "Edit layers",
"editActions": {
"modalLightsEditAction": {
"layersPageTitle": "Edit layers",
"ambilightPageTitle": "Edit ambilight",
"dropdownColorModeSelection": {
"label": "Choose a color mode",
"noColorModeSelected": "No color mode selected"
@ -100,7 +103,7 @@
"label": "Choose an animation out"
}
},
"modalLayersEditActionColorModeSelection": {
"modalLightsEditActionColorModeSelection": {
"pageTitle": "Choose a color mode"
},
"modalEditActionAnimationInSelection": {
@ -110,6 +113,7 @@
"modalEditActionAnimationOutSelection": {
"pageTitle": "Choose animation out",
"noResult": "No animations available"
}
},
"modalUpdateSceneName": {
"pageTitle": "Change scene name",

View File

@ -1,6 +1,6 @@
import { Text, View } from "react-native";
import { TouchableOpacity } from "react-native";
import { AppContext, AppStyles, IsPlatformIos } from "../../utils";
import { AppContext, AppStyles } from "../../utils";
import { useContext } from "react";
import MyIcon from "../Icon";

View File

@ -96,7 +96,10 @@ export default function LayerSelectionModalContent({ navigation, route }) {
route.params["actionId"] = newAction.actionId;
navigation.navigate(AppSelectedUserDevice.current.routeName);
navigation.navigate("modalLayersEditAction", route.params);
navigation.navigate("modalLightsEditAction", {
...route.params,
actionType: Constants.actionType.layers,
});
}}
/>
</View>

View File

@ -1,10 +1,12 @@
import { useContext } from "react";
import { Image, ScrollView, Text, View } from "react-native";
import {
AppContext,
AppSelectedUserDevice,
AppStyles,
Constants,
GetDevice,
ModalContainer,
NewAction,
} from "../../../../utils";
import MyIcon from "../../../../Components/Icon";
import { Divider } from "../../../../Components/Divider";
@ -12,6 +14,7 @@ import { useTranslation } from "react-i18next";
import MyTag from "../../../../Components/Tag";
import MyPressable from "../../../../Components/Pressable";
import { ActionTypeIconName } from "../../scene";
import { useContext } from "react";
function Action({
text,
@ -74,12 +77,33 @@ function Action({
}
export default function AddSceneActionModalContent({ navigation, route }) {
const appContext = useContext(AppContext);
const { t } = useTranslation();
const deviceFirmwareVersion = route.params.deviceFirmwareVersion;
// TODO: show only actions by device model
// this code is also in ./LayerSelection/index.js
const handleCreateAction = (actionType, modeAdjustments, navigateTo) => {
const newAction = NewAction(
GetDevice(appContext.devices).selectedScene,
actionType,
modeAdjustments
);
appContext.setDeviceSceneActions((arr) => [...arr, newAction]);
route.params["actionId"] = newAction.actionId;
if (actionType === Constants.actionType.ambilight) {
route.params["actionType"] = Constants.actionType.ambilight;
}
navigation.navigate(AppSelectedUserDevice.current.routeName);
navigation.navigate(navigateTo, route.params);
};
return (
<ScrollView>
<ModalContainer withoutPadding>
@ -87,7 +111,7 @@ export default function AddSceneActionModalContent({ navigation, route }) {
text={t("screens.device.scenes.modalAddSceneAction.actions.layers")}
iconName={ActionTypeIconName(Constants.actionType.layers)}
imageSource={require("../../../../../assets/layers.gif")}
onPress={() => navigation.navigate("modalLayerSection", route.params)}
onPress={() => navigation.navigate("modalLayerSelection", route.params)}
deviceFirmwareVersion={deviceFirmwareVersion}
supportedFirmwareVersions={["1.0.1"]}
/>
@ -98,7 +122,13 @@ export default function AddSceneActionModalContent({ navigation, route }) {
)}
iconName={ActionTypeIconName(Constants.actionType.ambilight)}
imageSource={require("../../../../../assets/ambilight.gif")}
onPress={() => console.log("pressed action")}
onPress={() => {
handleCreateAction(
Constants.actionType.ambilight,
{},
"modalLightsEditAction"
);
}}
deviceFirmwareVersion={deviceFirmwareVersion}
supportedFirmwareVersions={["1.0.1"]}
/>

View File

@ -5,75 +5,40 @@ import {
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 { useTranslation } from "react-i18next";
import { ColorPickerRef } from "reanimated-color-picker"; // used
import {
MyDotsModal,
MyPickerModalListItem,
} from "../../../../../Components/Modal";
import { MyColorPickerV2 } from "../../../../../Components/ColorPicker";
AppContext,
AppStyles,
Constants,
ModalContainer,
} from "../../../../../utils";
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 "../../..";
import {
MyDeviceTabButton,
MyDeviceTabButtonContainer,
} from "../../../deviceTabButton";
import Card from "../../../../../Components/Card";
import MyDropdown from "../../../../../Components/Dropdown";
import { MyIconButton } from "../../../../../Components/Button";
import { MyColorPickerV2 } from "../../../../../Components/ColorPicker";
import {
EditActionAdjustmentsContent,
EditActionAnimationsCardContent,
} from "..";
import {
MyDotsModal,
MyPickerModalListItem,
} from "../../../../../Components/Modal";
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 }) {
// This component is used by layers and ambilight
export default function LightsEditActionModalContent({ navigation, route }) {
const appContext = useContext(AppContext);
const sharedLightModeDefaultColors = useSharedValue([]);
@ -82,16 +47,26 @@ export function LightsEditActionModalContent({ navigation, route }) {
const colorPickerRef = useRef(ColorPickerRef);
const { t } = useTranslation();
const { actionId, deviceFirmwareVersion } = route.params;
const { actionType, actionId, deviceFirmwareVersion } = route.params;
console.log("actionType", actionType);
useFocusEffect(
useCallback(() => {
navigation.setOptions({
title:
actionType === Constants.actionType.layers
? t(
"screens.device.scenes.editActions.modalLightsEditAction.layersPageTitle"
)
: t(
"screens.device.scenes.editActions.modalLightsEditAction.ambilightPageTitle"
),
headerRight: () => (
<MyDotsModal
modalData={[
/*{
Duplicated item as references to the old action -> if the color is changed it will apply on both actions
bug: Duplicated item as references to the old action -> if the color is changed it will apply on both actions
icon: "content-duplicate",
label: t(
@ -118,7 +93,7 @@ export function LightsEditActionModalContent({ navigation, route }) {
{
icon: "trash-can",
label: t(
"screens.device.scenes.modalDotsEditAction.deleteAction"
"screens.device.scenes.editActions.modalDotsEditAction.deleteAction"
),
onPress: () => {
appContext.setDeviceSceneActions((actions) =>
@ -212,17 +187,17 @@ export function LightsEditActionModalContent({ navigation, route }) {
<MyDropdown
style={{ marginBottom: 2 }}
label={t(
"screens.device.scenes.modalLayersEditAction.dropdownColorModeSelection.label"
"screens.device.scenes.editActions.modalLightsEditAction.dropdownColorModeSelection.label"
)}
selectedItemLabel={
selectedSceneAction.modeId === ""
? t(
"screens.device.scenes.modalLayersEditAction.dropdownColorModeSelection.noColorModeSelected"
"screens.device.scenes.editActions.modalLightsEditAction.dropdownColorModeSelection.noColorModeSelected"
)
: selectedLightMode.name[appContext.appLanguage]
}
onPress={() =>
navigation.navigate("modalLayersEditActionColorModeSelection", {
navigation.navigate("modalLightsEditActionColorModeSelection", {
supportedDeviceLightModes: supportedDeviceLightModes,
action: selectedSceneAction,
})
@ -252,7 +227,7 @@ export function LightsEditActionModalContent({ navigation, route }) {
]}
>
{t(
"screens.device.scenes.modalLayersEditAction.modeSpecificColors"
"screens.device.scenes.editActions.modalLightsEditAction.modeSpecificColors"
)}
</Text>
@ -329,7 +304,47 @@ export function LightsEditActionModalContent({ navigation, route }) {
);
}
export function LayersEditActionColorModeSelectionModalContent({
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 LightsEditActionColorModeSelectionModalContent({
navigation,
route,
}) {

View File

@ -1,20 +1,21 @@
import { FlatList, Text, View } from "react-native";
import Card from "../../../../Components/Card";
import {
AppContext,
AppStyles,
IsPlatformIos,
ModalContainer,
} from "../../../../utils";
import { useCallback, useContext, useState } from "react";
import { useTranslation } from "react-i18next";
import Card from "../../../../Components/Card";
import MyDropdown from "../../../../Components/Dropdown";
import { useContext, useState } from "react";
import MyResult from "../../../../Components/Result";
import { MyPickerModalListItem } from "../../../../Components/Modal";
import MyIcon from "../../../../Components/Icon";
import MySlider from "../../../../Components/Slider";
import { useTranslation } from "react-i18next";
import MyIcon from "../../../../Components/Icon";
import { useFocusEffect } from "@react-navigation/native";
export default function EditActionAnimationsCardContent({
export function EditActionAnimationsCardContent({
disabled,
navigation,
deviceFirmwareVersion,
@ -43,7 +44,7 @@ export default function EditActionAnimationsCardContent({
]}
>
{t(
"screens.device.scenes.editActionAnimationsCardContent.animationsIn"
"screens.device.scenes.editActions.editActionAnimationsCardContent.animationsIn"
)}
</Text>
@ -51,13 +52,13 @@ export default function EditActionAnimationsCardContent({
disabled={disabled}
style={{ marginTop: 2 }}
label={t(
"screens.device.scenes.editActionAnimationsCardContent.dropdownAnimationIn.label"
"screens.device.scenes.editActions.editActionAnimationsCardContent.dropdownAnimationIn.label"
)}
selectedItemLabel={
selectedLightAnimationIn.name[appContext.appLanguage]
}
onPress={() =>
navigation.navigate("modalEditActionAnimationInSelection", {
navigation.navigate("modalEditActionAnimationInOrOutSelection", {
animationType: "animationIn",
deviceFirmwareVersion: deviceFirmwareVersion,
action: action,
@ -82,7 +83,7 @@ export default function EditActionAnimationsCardContent({
]}
>
{t(
"screens.device.scenes.editActionAnimationsCardContent.animationsOut"
"screens.device.scenes.editActions.editActionAnimationsCardContent.animationsOut"
)}
</Text>
@ -90,13 +91,13 @@ export default function EditActionAnimationsCardContent({
disabled={disabled}
style={{ marginTop: 2 }}
label={t(
"screens.device.scenes.editActionAnimationsCardContent.dropdownAnimationOut.label"
"screens.device.scenes.editActions.editActionAnimationsCardContent.dropdownAnimationOut.label"
)}
selectedItemLabel={
selectedLightAnimationOut.name[appContext.appLanguage]
}
onPress={() =>
navigation.navigate("modalEditActionAnimationOutSelection", {
navigation.navigate("modalEditActionAnimationInOrOutSelection", {
animationType: "animationOut",
deviceFirmwareVersion: deviceFirmwareVersion,
action: action,
@ -119,6 +120,7 @@ export function EditActionAnimationSelectionModalContent({
route,
}) {
const appContext = useContext(AppContext);
const { t } = useTranslation();
let { animationType, deviceFirmwareVersion, action } = route.params;
@ -140,6 +142,21 @@ export function EditActionAnimationSelectionModalContent({
animationType =
animationType === "animationIn" ? "animationInId" : "animationOutId";
useFocusEffect(
useCallback(() => {
navigation.setOptions({
title:
animationType === "animationInId"
? t(
"screens.device.scenes.editActions.modalEditActionAnimationInSelection.pageTitle"
)
: t(
"screens.device.scenes.editActions.modalEditActionAnimationOutSelection.pageTitle"
),
});
}, [])
);
return (
<ModalContainer withoutPadding>
{supportedLightAnimations.length === 0 ? (
@ -147,10 +164,10 @@ export function EditActionAnimationSelectionModalContent({
text={
animationType === "animationInId"
? t(
"screens.device.scenes.modalEditActionAnimationInSelection.noResult"
"screens.device.scenes.editActions.modalEditActionAnimationInSelection.noResult"
)
: t(
"screens.device.scenes.modalEditActionAnimationOutSelection.noResult"
"screens.device.scenes.editActions.modalEditActionAnimationOutSelection.noResult"
)
}
iconName="select-search"

View File

@ -239,10 +239,9 @@ function ActionListItem({ drag, navigation, device, item }) {
const ListItemAdjustments = () => {
let adjustments = [];
if (
item.type === Constants.actionType.layers &&
item.modeAdjustments.layers !== undefined
) {
switch (item.type) {
case Constants.actionType.layers:
if (item.modeAdjustments.layers !== undefined) {
const layerGrammarForm =
item.modeAdjustments.layers.length > 1
? t(
@ -272,7 +271,9 @@ function ActionListItem({ drag, navigation, device, item }) {
LAYER_GRAMMAR_FORM: layerGrammarForm,
AFFECTED_LAYERS: affectedLayers,
}
)} ${item.modeAdjustments.colors.length === 0 ? "???" : ""}`}
)} ${
item.modeAdjustments.colors.length === 0 ? "???" : ""
}`}
</Text>
{item.modeAdjustments.colors !== undefined &&
@ -287,6 +288,34 @@ function ActionListItem({ drag, navigation, device, item }) {
</View>
);
}
break;
case Constants.actionType.ambilight:
console.log("item", item);
adjustments.push(
<View style={{ flexDirection: "row", alignItems: "center" }}>
<Text style={{ color: appContext.appTheme.textSecondary }}>
{t("screens.device.scenes.sceneActionsListItems.ambilight")}{" "}
</Text>
{item.modeAdjustments.colors !== undefined &&
item.modeAdjustments.colors.map((color, index) => (
<MyColorSwatch
key={index}
backgroundColor={color}
size={16}
style={{ marginRight: -2 }}
/>
))}
</View>
);
break;
default:
console.log(
`item type ${item.type} not found in to display ListItemAdjustments`
);
break;
}
if (
item.animationInId !== Constants.defaultAnimationId ||
@ -334,12 +363,29 @@ function ActionListItem({ drag, navigation, device, item }) {
return (
<View style={{ marginLeft: 15, marginRight: 15 }}>
<TouchableOpacity
onPress={() =>
navigation.navigate("modalLayersEditAction", {
onPress={() => {
let navigateTo;
let options = {
actionId: item.actionId,
deviceFirmwareVersion: device.firmware.version,
})
};
switch (item.type) {
case Constants.actionType.layers:
navigateTo = "modalLightsEditAction";
options.actionType = Constants.actionType.layers;
break;
case Constants.actionType.ambilight:
navigateTo = "modalLightsEditAction";
options.actionType = Constants.actionType.ambilight;
break;
default:
console.log("no navigation defined for item type " + item.type);
return;
}
navigation.navigate(navigateTo, options);
}}
>
<View
style={{