import AsyncStorage from "@react-native-async-storage/async-storage"; import { createContext, createRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Appearance, Platform, StyleSheet, View } from "react-native"; import uuid from "react-native-uuid"; import * as Haptics from "expo-haptics"; export const Constants = { defaultLanguage: "de", defaultColorSwatchesFavorites: [ "#2ecc71", "#3498db", "#9b59b6", "#f1c40f", "#e67e22", "#e74c3c", "#fff", ], languages: [ { name: "de", label: "Deutsch", }, { name: "en", label: "English", }, ], actionType: { layers: 0, ambilight: 1, motor: 2, wait: 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({ typography20: { fontSize: 20, fontWeight: "bold", lineHeight: 24, }, typography16: { fontSize: 16, lineHeight: 24, }, typography14: { fontSize: 14, lineHeight: 20, }, Shadow: { elevation: 2, // only android shadowColor: "#000", // only ios shadowOffset: { width: 0, height: 1 }, // only ios shadowOpacity: 0.2, // only ios shadowRadius: 1, // only ios }, disabled: { opacity: 0.6, }, headerNavigationIcons: { padding: 17, }, deviceLivePreview: { height: 200, }, appBottom: { marginBottom: 40, }, }); const DarkAppTheme = { _id: "dark", // needed for status bar colors: { primary: "#e67e22", secondary: "#9b59b6", gray: "#b2bec3", }, text: "#fff", textSecondary: "#ddd", textDisabled: "#b2bec3", backgroundColor: "#21252a", card: { backgroundColor: "#2b3139", }, drawer: { backgroundColor: "#2b3139", icon: "#fff", item: { inactiveTintColor: "#fff", activeTintColor: "#e67e22", iconColor: "#fff", activeBackgroundColor: "rgba(0, 0, 0, 0.1)", }, }, divider: "#434443", textInputBottomColor: "#b2b3b3", icon: "#ddd", iconDisabled: "#b2b3b3", switch: { trackColorTrue: "#01d064", trackColorFalse: "#b2b3b3", thumbColorTrue: "#f4f3f4", thumbColorFalse: "#f4f3f4", ios_backgroundColor: "#3e3e3e", }, slider: { minimumTrackTintColor: "#e67e22", maximumTrackTintColor: "#fff", thumbTintColor: "#e67e22", }, tag: { red: { backgroundColor: "#3d0801", text: "#fe4f50", borderColor: "#760b01", }, }, colorPickerDisabled: "rgba(0, 0, 0, 0.3)", modal: { pressedPickerItemColor: "rgba(0, 0, 0, 0.3)", }, }; const LightAppTheme = { _id: "light", // needed for status bar colors: { primary: "#e67e22", secondary: "#9b59b6", gray: "#636e72", }, text: "#000", textSecondary: "#555", textDisabled: "#636e72", backgroundColor: "#f7f7f7", card: { backgroundColor: "#fff", }, drawer: { backgroundColor: "#fff", item: { inactiveTintColor: "#000", activeTintColor: "#e67e22", iconColor: "#000", activeBackgroundColor: "rgba(0, 0, 0, 0.05)", }, }, divider: "#ddd", textInputBottomColor: "#b2b3b3", icon: "#000", iconDisabled: "#b2b3b3", switch: { trackColorTrue: "#01d064", trackColorFalse: "#b2b3b3", thumbColorTrue: "#f4f3f4", thumbColorFalse: "#f4f3f4", ios_backgroundColor: "#3e3e3e", }, slider: { minimumTrackTintColor: "#e67e22", maximumTrackTintColor: "#555", thumbTintColor: "#e67e22", }, tag: { red: { backgroundColor: "#fff3f1", text: "#ff6060", borderColor: "#fecdc7", }, }, colorPickerDisabled: "rgba(0, 0, 0, 0.3)", modal: { pressedPickerItemColor: "rgba(0, 0, 0, 0.1)", }, }; export async function StoreData(key, value) { try { const jsonValue = JSON.stringify(value); await AsyncStorage.setItem(key, jsonValue); } catch (e) { console.log("err", e); } } export async function GetData(key) { try { const jsonValue = await AsyncStorage.getItem(key); return jsonValue != null ? JSON.parse(jsonValue) : null; } catch (e) { console.log("err", e); } } export async function GetMultipleData(keys) { try { const data = await AsyncStorage.multiGet(keys); const retrievedData = data.map(([key, value]) => [key, JSON.parse(value)]); return retrievedData; } catch (e) { console.log("err", e); } } export function GetDataFromList(list, key) { return list.find((v) => v[0] === key)[1]; } export function GetUuid() { return uuid.v4(); } // data set in the app by default or provided by our servers on firmware update const devDevicesFirmwareModes = { lightModes: [ { id: "6138e651-54c5-4fd4-8f40-3364f4e9dfe2", supportedFirmwareVersions: ["1.0.1"], name: { de: "Einfarbig", en: "Solid", }, defaults: ["red"], adjustments: [], }, { id: "c7097a60-faa9-4928-a531-0a8ecbc115d9", supportedFirmwareVersions: ["1.0.1"], name: { de: "Zufällig", en: "Random", }, defaults: ["red", "orange", "blue"], adjustments: [ { type: "slider", variableName: "colorSwitching", iconName: "fan", name: { de: "Wechsel der Farben", en: "Color changing", }, min: 0, max: 6, defaultValue: 2, unitOfMeasurement: { de: "s", en: "s", }, }, ], }, { id: "b42c665a-c2ab-4029-9162-2280caae3274", supportedFirmwareVersions: ["1.0.1"], name: { de: "Regenbogen", en: "Rainbow", }, defaults: [], adjustments: [ { type: "slider", variableName: "modeSpeed", iconName: "fan", name: { de: "Schnelligkeit des Modus", en: "Speed of the mode", }, min: 0, max: 10, defaultValue: 5, unitOfMeasurement: { de: "s", en: "s", }, }, { type: "slider", variableName: "repeatingInterval", iconName: "repeat-variant", name: { de: "Wiederholungsinterval", en: "Repeating interval", }, min: 1, max: 10, defaultValue: 8, unitOfMeasurement: { de: "s", en: "s", }, }, ], }, ], lightAnimationsIn: [ { id: "00000000-0000-0000-0000-000000000000", supportedFirmwareVersions: ["*"], name: { de: "Keine", en: "None", }, adjustment: {}, }, { id: "6c5570da-ec53-4788-a8cd-03c724eb81b8", supportedFirmwareVersions: ["1.0.1"], name: { de: "Aufblenden", en: "Fade in", }, adjustment: { type: "slider", variableName: "duration", name: { de: "Dauer", en: "Duration", }, iconName: "repeat-variant", min: 1, max: 6, defaultValue: 4, unitOfMeasurement: { de: "s", en: "s", }, }, }, ], lightAnimationsOut: [ { id: "00000000-0000-0000-0000-000000000000", supportedFirmwareVersions: ["*"], name: { de: "Keine", en: "None", }, adjustment: {}, }, { id: "cb5b791e-213c-4684-9585-b0c42cbfafb5", supportedFirmwareVersions: ["1.0.1"], name: { de: "Ausblenden", en: "Fade out", }, adjustment: { type: "slider", variableName: "duration", name: { de: "Dauer", en: "Duration", }, iconName: "repeat-variant", min: 1, max: 6, defaultValue: 2, unitOfMeasurement: { de: "s", en: "s", }, }, }, ], motorModes: [ { id: "41de8c57-fc99-40a4-b6eb-a8d0d4569bc8", supportedFirmwareVersions: ["1.0.1"], name: { de: "Hin und her", en: "Back and forth", }, defaults: [], adjustments: [ { type: "slider", variableName: "duration", iconName: "repeat-variant", name: { de: "Dauer", en: "Duration", }, min: 1, max: 6, defaultValue: 2, unitOfMeasurement: { de: "s", en: "s", }, }, ], }, ], motorAnimationsIn: [ { id: "b27003a7-447d-4b2b-b89a-5780b91f6614", supportedFirmwareVersions: ["1.0.1"], name: { de: "Ruckartig in", en: "Jerking in", }, defaults: [], adjustment: { type: "slider", variableName: "duration", iconName: "repeat-variant", name: { de: "Dauer", en: "Duration", }, min: 1, max: 3, defaultValue: 2, unitOfMeasurement: { de: "s", en: "s", }, }, }, { id: "13096781-92d7-4694-a8b8-b3a92399b922", supportedFirmwareVersions: ["1.0.1"], name: { de: "Glatt in", en: "Smooth in", }, defaults: [], adjustment: { type: "slider", variableName: "duration", iconName: "repeat-variant", name: { de: "Dauer", en: "Duration", }, min: 1, max: 8, defaultValue: 4, unitOfMeasurement: { de: "s", en: "s", }, }, }, ], motorAnimationsOut: [ { id: "b27003a7-447d-4b2b-b89a-5780b91f6614", supportedFirmwareVersions: ["1.0.1"], name: { de: "Ruckartig out", en: "Jerking out", }, defaults: [], adjustment: { type: "slider", variableName: "duration", iconName: "repeat-variant", name: { de: "Dauer", en: "Duration", }, min: 1, max: 3, defaultValue: 2, unitOfMeasurement: { de: "s", en: "s", }, }, }, { id: "13096781-92d7-4694-a8b8-b3a92399b922", supportedFirmwareVersions: ["1.0.1"], name: { de: "Glatt out", en: "Smooth out", }, defaults: [], adjustment: { type: "slider", variableName: "duration", iconName: "repeat-variant", name: { de: "Dauer", en: "Duration", }, min: 1, max: 8, defaultValue: 4, unitOfMeasurement: { de: "s", en: "s", }, }, }, ], }; // this data is transmitted from the device to the user app const devDevices = [ { id: "1f21a12a-0bec-4336-99bb-df3f9fc9f537", // deviceId displayName: "Turtle", deviceModel: "Aurora", deviceIp: "127.0.0.1", firmware: { version: "1.0.1", lastUpdated: "11.07.2023 um 20:33 Uhr", }, selectedScene: "", }, { id: "5b331a12a-0bec-4336-99bb-df3f9fc9f537", // deviceId displayName: "Elona", deviceModel: "Aurora", deviceIp: "192.168.0.1", firmware: { version: "1.0.1", lastUpdated: "11.07.2023 um 20:33 Uhr", }, selectedScene: "", }, ]; export function AddNewDevice(displayName, deviceModel, deviceIp) { return { id: GetUuid(), displayName: displayName, deviceModel: deviceModel, deviceIp: deviceIp, firmware: { version: "1.0.1", lastUpdated: "11.07.2023 um 20:33 Uhr", }, selectedScene: "", }; } // preview const devDeviceScenes = [ { sceneId: "", // sceneId deviceId: "", name: "", }, ]; export function NewDeviceScene(name) { return { sceneId: GetUuid(), deviceId: AppSelectedUserDevice.current.id, name: 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: "", animationInAdjustment: { duration: 32, }, animationOutAdjustment: { duration: 32, }, }, ]; 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 animationOutAdjustment: {}, }; } export function GetDevice(devices) { return devices.find((d) => d.id === AppSelectedUserDevice.current.id); } const appContextPreview = { appColorScheme: "", appLanguage: "", isUserExpertModeEnabled: "", isUserDeveloperModeEnabled: "", appTheme: DarkAppTheme, devices: [], deviceScenes: [], deviceSceneActions: [], deviceFirmwareModes: [], userColorSwatchesFavorites: [], }; export const AppSelectedUserDevice = createRef(); AppSelectedUserDevice.current = { id: "", routeName: "" }; export const AppContext = createContext(appContextPreview); export function AppProvider({ children }) { const [appLanguage, setAppLanguage] = useState("de"); const [appColorScheme, setAppColorScheme] = useState("light"); const [appTheme, setAppTheme] = useState(DarkAppTheme); const [isUserExpertModeEnabled, setIsUserExpertModeEnabled] = useState(false); const [devices, setDevices] = useState(devDevices); const [deviceScenes, setDeviceScenes] = useState([]); const [deviceSceneActions, setDeviceSceneActions] = useState([]); const [deviceFirmwareModes, setDeviceFirmwareModes] = useState( devDevicesFirmwareModes ); const [userColorSwatchesFavorites, setUserColorSwatchesFavorites] = useState( [] ); const { i18n } = useTranslation(); // TODO: only while development const [isUserDeveloperModeEnabled, setIsUserDeveloperModeEnabled] = useState(false); const saveAppColorScheme = async (value) => { StoreData("appColorScheme", value); setAppColorScheme(value); let colorScheme; colorScheme = value === "auto" ? Appearance.getColorScheme() : value; setAppTheme(colorScheme === "light" ? LightAppTheme : DarkAppTheme); }; const saveAppLanguage = async (value) => { StoreData("appLanguage", value); setAppLanguage(value); i18n.changeLanguage(value); }; const saveUserExpertMode = async (value) => { StoreData("userExpertMode", value); setIsUserExpertModeEnabled(value); }; // TODO: only while development const saveUserDeveloperMode = async (value) => { StoreData("userDeveloperMode", value); setIsUserDeveloperModeEnabled(value); }; const saveUserColorSwatchesFavorites = async (value) => { StoreData("userColorSwatchesFavorites", value); setUserColorSwatchesFavorites(value); }; return ( {children} ); } export function IsPlatformIos() { return Platform.OS === "ios"; } export function VibrateShort() { //Vibration.vibrate(50); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); } export function ModalContainer({ children, withoutPadding }) { return ( {children} ); }