Cap LITE at one FAVORITED recipe

Freeing the FAVORITED tab for LITE put no ceiling on the list, and a list
of your own picks is what PRO is selling. One star is free, the second
names the build; un-starring stays open so the list can always come back
under the limit.
This commit is contained in:
2026-09-14 21:20:56 +07:00
parent 06d7e8f384
commit 42756ac7c3
2 changed files with 15 additions and 4 deletions
+7 -1
View File
@@ -26,7 +26,7 @@ import { processAndExportPhoto } from './src/utils/exportEngine';
import { processAndExportPhotoNative } from './src/utils/nativeExport';
import { exportRecipeXml, importRecipeXml } from './src/utils/recipeShare';
import { PARAM_DEFS } from './src/utils/paramDefs';
import { IS_PRO, LITE_MARK, LITE_RECIPE_LIMIT, proLookInUse } from './src/utils/entitlement';
import { IS_PRO, LITE_FAVORITE_LIMIT, LITE_MARK, LITE_RECIPE_LIMIT, proLookInUse } from './src/utils/entitlement';
import UltraWide from './modules/recipescam-ultrawide';
// @ts-ignore
@@ -949,6 +949,12 @@ export default function App() {
// untouched either way.
const handleToggleFavorite = (id: string) => {
const on = !favoriteIds.includes(id);
// LITE gets one favorite; PRO is what buys a list. Un-starring is never
// gated, so the way back under the limit is always open.
if (on && !pro && favoriteIds.length >= LITE_FAVORITE_LIMIT) {
promptProFeature(`Favoriting more than ${LITE_FAVORITE_LIMIT} recipe`);
return;
}
setFavoriteIds((ids) => (on ? [...ids, id] : ids.filter((x) => x !== id)));
setFavoriteId(id, on).catch((e) => console.warn('Failed to save favorite:', e));
};
+8 -3
View File
@@ -16,9 +16,9 @@ export const IS_PRO = IS_PRO_BUILD;
//
// What LITE owns outright: the eight film sims, the bundled recipes, its own
// recipes up to LITE_RECIPE_LIMIT, its own watermark text (in one face), the
// plain frames and every parameter. What needs PRO: the three printed frames,
// the GPS stamp, the platform's other fonts, and the next recipe past the
// limit.
// plain frames, one favorite and every parameter. What needs PRO: the three
// printed frames, the GPS stamp, the platform's other fonts, the next recipe
// past the limit, and the second favorite.
// Frames on the LITE side: the plain export only. The three printed looks are
// PRO (the artwork/card geometry is the paid half of the FRAME tab).
@@ -28,6 +28,11 @@ export const PRO_FRAMES: FrameId[] = ['classic-white', 'polaroid', 'wallframe'];
// free, deleting one is PRO — so a LITE list only ever grows to this size.
export const LITE_RECIPE_LIMIT = 3;
// FAVORITED is a LITE feature, but only one deep: the first star is free, the
// second needs PRO. Un-starring is always free, so the list can always come
// back under the limit.
export const LITE_FAVORITE_LIMIT = 1;
// Burned into every LITE export, bottom-right of the photo/frame area. Fractions
// of the stamp canvas, same space the custom mark uses. The user's own mark is
// free on top of it.