726 lines
16 KiB
JavaScript
726 lines
16 KiB
JavaScript
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 (
|
|
<AppContext.Provider
|
|
value={{
|
|
appLanguage: appLanguage,
|
|
setAppLanguage: saveAppLanguage,
|
|
appColorScheme: appColorScheme,
|
|
setAppColorScheme: saveAppColorScheme,
|
|
appTheme: appTheme,
|
|
isUserExpertModeEnabled: isUserExpertModeEnabled,
|
|
setIsUserExpertModeEnabled: saveUserExpertMode,
|
|
devices: devices,
|
|
setDevices: setDevices,
|
|
deviceScenes: deviceScenes,
|
|
setDeviceScenes: setDeviceScenes,
|
|
deviceSceneActions: deviceSceneActions,
|
|
setDeviceSceneActions: setDeviceSceneActions,
|
|
deviceFirmwareModes: deviceFirmwareModes,
|
|
setDeviceFirmwareModes: setDeviceFirmwareModes,
|
|
userColorSwatchesFavorites: userColorSwatchesFavorites,
|
|
setUserColorSwatchesFavorites: saveUserColorSwatchesFavorites,
|
|
isUserDeveloperModeEnabled: isUserDeveloperModeEnabled,
|
|
setUserIsDeveloperModeEnabled: saveUserDeveloperMode,
|
|
}}
|
|
>
|
|
{children}
|
|
</AppContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function IsPlatformIos() {
|
|
return Platform.OS === "ios";
|
|
}
|
|
|
|
export function VibrateShort() {
|
|
//Vibration.vibrate(50);
|
|
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
|
|
}
|
|
|
|
export function ModalContainer({ children, withoutPadding }) {
|
|
return (
|
|
<View style={[{ flex: 1 }, !withoutPadding && { padding: 10 }]}>
|
|
{children}
|
|
</View>
|
|
);
|
|
}
|