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.
This commit is contained in:
2026-09-14 20:31:07 +07:00
parent 1b60ca2f22
commit 499e61644d
+24 -2
View File
@@ -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 (
<View
key={c.key}
@@ -337,6 +342,15 @@ export default function AdjustmentPanel({
chipXRef.current[c.key] = e.nativeEvent.layout.x;
}}
>
{proTag && (
<View
pointerEvents="none"
className="absolute z-10 rounded-sm bg-amber-500 px-1"
style={{ top: -4, right: -4 }}
>
<Text className="font-mono text-[7px] font-bold text-black">PRO</Text>
</View>
)}
{c.trash || c.star ? (
<View className={`flex-row items-center rounded-full border py-1.5 pl-3 pr-1 ${tone}`}>
<TouchableOpacity onPress={() => { 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,