feat(panel): add a FAVORITED tab with a star on every recipe

This commit is contained in:
2026-09-11 09:32:21 +07:00
parent ba7e579986
commit ba971f136c
4 changed files with 120 additions and 16 deletions
+16 -1
View File
@@ -17,7 +17,7 @@ import SettingsModal from './src/components/SettingsModal';
import PhotoViewerModal from './src/components/PhotoViewerModal';
import { Recipe, ColorAdjustments, CustomWatermark, GpsWatermark, FrameId, GPSInfo, AspectRatio, MeterMode, PhotoEntry, ShutterSound, StartupMode, CropRatio, CropRect, CROP_W_H, DEFAULT_CROP_RECT } from './src/types';
import { getAllRecipes, saveCustomRecipe, updateCustomRecipe, deleteCustomRecipe } from './src/utils/storageUtils';
import { getAllRecipes, saveCustomRecipe, updateCustomRecipe, deleteCustomRecipe, getFavoriteIds, setFavoriteId } from './src/utils/storageUtils';
import { DEFAULT_ADJUSTMENTS, FILM_SIMS, filmSimToRecipe } from './src/utils/defaultRecipes';
import { getCurrentGPS, requestLocationPermissions, reverseGeocode } from './src/utils/locationUtils';
import { resolvePhotoGPS } from './src/utils/photoGps';
@@ -78,6 +78,9 @@ export default function App() {
};
}, []);
const [recipes, setRecipes] = useState<Recipe[]>([]);
// FAVORITED: ids of the starred recipes. Metadata only — never saved into the
// session look, so RESET and applying a recipe leave it untouched.
const [favoriteIds, setFavoriteIds] = useState<string[]>([]);
const [selectedRecipe, setSelectedRecipe] = useState<Recipe | null>(null);
// Custom recipe open in the parameter editor (the CREATE form in edit mode).
const [editingRecipe, setEditingRecipe] = useState<Recipe | null>(null);
@@ -321,6 +324,7 @@ export default function App() {
const initSession = async () => {
const list = await getAllRecipes();
setRecipes(list);
setFavoriteIds(await getFavoriteIds());
// Device/camera settings restore first: they apply under BOTH startup
// modes ('default' resets only the look, not these hardware choices).
@@ -771,6 +775,15 @@ export default function App() {
}
};
// Star/un-star a recipe: optimistic (the chip repaints on tap), persisted in
// the background. The write is the only failure worth logging — the look is
// untouched either way.
const handleToggleFavorite = (id: string) => {
const on = !favoriteIds.includes(id);
setFavoriteIds((ids) => (on ? [...ids, id] : ids.filter((x) => x !== id)));
setFavoriteId(id, on).catch((e) => console.warn('Failed to save favorite:', e));
};
const handlePickImage = async () => {
if (isProcessing) return;
@@ -1327,6 +1340,8 @@ export default function App() {
onCloseEdit={() => setEditingRecipe(null)}
onUpdateRecipe={handleUpdateRecipe}
onSelectRecipe={handleSelectRecipe}
favoriteIds={favoriteIds}
onToggleFavorite={handleToggleFavorite}
onUpdateAdjustments={handleUpdateAdjustments}
onUpdateFrame={handleUpdateFrame}
onToggleGeotag={handleToggleGeotag}