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}
);
}