Files
RecipesCam/src/utils/storageUtils.ts
T

73 lines
2.8 KiB
TypeScript

import AsyncStorage from '@react-native-async-storage/async-storage';
import { Recipe } from '../types';
import { DEFAULT_RECIPES, DEFAULT_ADJUSTMENTS } from './defaultRecipes';
const CUSTOM_RECIPES_KEY = '@camrecipe_pro:custom_recipes';
const FAVORITES_KEY = '@camrecipe_pro:favorites';
// FAVORITED recipes: a list of recipe ids. Pure metadata — starring a recipe
// never touches the look, so RESET and re-selecting a recipe leave it alone.
export async function getFavoriteIds(): Promise<string[]> {
try {
const data = await AsyncStorage.getItem(FAVORITES_KEY);
if (!data) return [];
const parsed = JSON.parse(data);
return Array.isArray(parsed) ? parsed.filter((id) => typeof id === 'string') : [];
} catch (error) {
console.error('Failed to load favorites:', error);
return [];
}
}
export async function setFavoriteId(id: string, on: boolean): Promise<void> {
const ids = await getFavoriteIds();
const updated = on
? [...new Set([...ids, id])]
: ids.filter((x) => x !== id);
await AsyncStorage.setItem(FAVORITES_KEY, JSON.stringify(updated));
}
export async function getCustomRecipes(): Promise<Recipe[]> {
try {
const data = await AsyncStorage.getItem(CUSTOM_RECIPES_KEY);
if (!data) return [];
return JSON.parse(data);
} catch (error) {
console.error('Failed to load custom recipes:', error);
return [];
}
}
export async function getAllRecipes(): Promise<Recipe[]> {
const custom = await getCustomRecipes();
// Backfill newer adjustment fields onto recipes persisted before they existed.
const fill = (r: Recipe): Recipe => ({ ...r, adjustments: { ...DEFAULT_ADJUSTMENTS, ...r.adjustments } });
return [...DEFAULT_RECIPES.map(fill), ...custom.map(fill)];
}
export async function saveCustomRecipe(recipe: Omit<Recipe, 'id' | 'isCustom'>): Promise<Recipe> {
const custom = await getCustomRecipes();
const newRecipe: Recipe = {
...recipe,
id: `custom_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
isCustom: true,
};
const updated = [...custom, newRecipe];
await AsyncStorage.setItem(CUSTOM_RECIPES_KEY, JSON.stringify(updated));
return newRecipe;
}
// Overwrite an existing custom recipe in place (Save). No-op if the id is gone.
export async function updateCustomRecipe(id: string, recipe: Omit<Recipe, 'id' | 'isCustom'>): Promise<void> {
const custom = await getCustomRecipes();
const updated = custom.map((r) => (r.id === id ? { ...r, ...recipe, id, isCustom: true } : r));
await AsyncStorage.setItem(CUSTOM_RECIPES_KEY, JSON.stringify(updated));
}
export async function deleteCustomRecipe(id: string): Promise<void> {
const custom = await getCustomRecipes();
const updated = custom.filter(r => r.id !== id);
await AsyncStorage.setItem(CUSTOM_RECIPES_KEY, JSON.stringify(updated));
}