From 499e61644d69fde0f600e8fe27230341e2b41b6f Mon Sep 17 00:00:00 2001 From: locphamtran Date: Mon, 14 Sep 2026 20:31:07 +0700 Subject: [PATCH] Tag PRO-only chips in LITE with a corner PRO marker LITE lets you pick any preset, frame or watermark and preview it; only the export is held back, and nothing on screen said which chips those were until you hit the alert. Each such chip now carries a small amber PRO tag at its top-right corner. ChipDef gains an optional `pro` flag, set on the three printed frames, on recipe chips (bundled or user-made, via isFreeRecipe), and on the custom watermark chip. The tag renders only where `!IS_PRO`, so it is invisible in the PRO apk. --- src/components/AdjustmentPanel.tsx | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/AdjustmentPanel.tsx b/src/components/AdjustmentPanel.tsx index 653c5fb..d60c697 100644 --- a/src/components/AdjustmentPanel.tsx +++ b/src/components/AdjustmentPanel.tsx @@ -6,6 +6,7 @@ import { Star, Trash2 } from 'lucide-react-native'; import { Skia } from '@shopify/react-native-skia'; import { Recipe, ColorAdjustments, CustomWatermark, GpsWatermark, FrameId, BaseFilter, CropRatio } from '../types'; import { FRAMES } from '../utils/frameUtils'; +import { IS_PRO, PRO_FRAMES, isFreeRecipe } from '../utils/entitlement'; import { PARAM_DEFS, ContinuousParamDef } from '../utils/paramDefs'; import { FILM_SIMS, filmSimToRecipe } from '../utils/defaultRecipes'; import RecipeCreateModal from './RecipeCreateModal'; @@ -150,6 +151,7 @@ interface ChipDef { onPressStar?: () => void; disabled?: boolean; // informational label, not tappable amberValue?: boolean; // amber text driven by edited value, not selection + pro?: boolean; // a PRO feature: LITE draws the corner tag on it } interface ParamDef { @@ -329,6 +331,9 @@ export default function AdjustmentPanel({ ? 'border-amber-500/70 bg-amber-500/15' : 'border-zinc-700/60 bg-titan/80'; const textTone = c.active || c.amberValue ? 'text-amber-500' : 'text-zinc-300'; + // LITE only: corner tag on every chip whose look LITE cannot export. PRO + // never sees it (there the condition is a constant false). + const proTag = c.pro && !IS_PRO; return ( + {proTag && ( + + PRO + + )} {c.trash || c.star ? ( { haptic(); c.onPress(); }} activeOpacity={0.7}> @@ -423,7 +437,7 @@ export default function AdjustmentPanel({ const choiceChips = ( keyPrefix: string, - options: { v: string; d: string }[], + options: { v: string; d: string; pro?: boolean }[], current: string, onPick: (v: string) => void ): ChipDef[] => @@ -431,6 +445,7 @@ export default function AdjustmentPanel({ key: `${keyPrefix}:${o.v}`, label: o.d, active: current === o.v, + pro: o.pro, onPress: () => onPick(o.v), })); @@ -715,6 +730,7 @@ export default function AdjustmentPanel({ key: 'custom-wm', label: customWm.enabled ? 'CUSTOM WATERMARK ON' : 'CUSTOM WATERMARK OFF', active: customWm.enabled, + pro: true, onPress: () => onUpdateCustomWm({ ...customWm, enabled: !customWm.enabled }), }, ...(wmOn @@ -825,6 +841,7 @@ export default function AdjustmentPanel({ key: r.id, label: r.name, active: r.id === currentRecipeId, + pro: !isFreeRecipe(r.id), star: true, starred: true, onPress: () => onSelectRecipe(r), @@ -867,7 +884,11 @@ export default function AdjustmentPanel({ [ ...choiceChips( 'fr', - FRAMES.map((f) => ({ v: f.id, d: f.name.toUpperCase() })), + FRAMES.map((f) => ({ + v: f.id, + d: f.name.toUpperCase(), + pro: PRO_FRAMES.includes(f.id), + })), selectedFrame, (val) => { // Picking another frame is another parameter: the open slider @@ -1003,6 +1024,7 @@ export default function AdjustmentPanel({ key: r.id, label: r.name, active: r.id === currentRecipeId, + pro: !isFreeRecipe(r.id), star: true, starred: favoriteIds.includes(r.id), trash: !!r.isCustom,