a85ebf0a81
- One free Play app (com.locphamtran.recipescamera) with an expo-iap PRO unlock, replacing the paid apk for the store channel - Android SEND/SEND_MULTIPLE share target feeds photos into the editor, on cold start and on resume - BACK button in the TopBar and press-and-hold PEEK replace the chip row - NOISE REDUCTION and SHARPENING accept -10: a negative SHARPENING softens the frame before the grain pass, a negative NOISE REDUCTION re-grains it, in the Skia engine, the live preview and the Kotlin export path alike
61 lines
2.6 KiB
TypeScript
61 lines
2.6 KiB
TypeScript
import { FrameId } from '../types';
|
|
|
|
// LITE (free) vs PRO. Two apks come out of this one tree: the PRO apk
|
|
// (src/provariant.ts, rewritten by tools/set-variant.mjs) is born owned, while
|
|
// the LITE apk is the free build and buys the tier through Google Play. The
|
|
// tier itself is runtime state, so it lives in src/utils/proUnlock.ts and every
|
|
// caller takes it from there (useProUnlock) or by prop.
|
|
|
|
// The gate is on the FILE, not on the preview: a LITE user composes with any
|
|
// look and compares it before/after — only the render/export of a PRO look is
|
|
// held back, and every LITE export carries the mark below.
|
|
//
|
|
// 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, one favorite and every parameter except the HDF effect.
|
|
// What needs PRO: the three printed frames, the GPS stamp, the HDF effect,
|
|
// 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).
|
|
export const PRO_FRAMES: FrameId[] = ['classic-white', 'polaroid', 'wallframe'];
|
|
|
|
// LITE may store its own recipes, up to this many: creating and editing them is
|
|
// 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.
|
|
export const LITE_MARK = {
|
|
text: 'RECIPESCAM',
|
|
x: 0.55,
|
|
y: 0.94,
|
|
color: '#ffffff',
|
|
size: 0.8,
|
|
};
|
|
|
|
export interface Look {
|
|
frame: FrameId;
|
|
gpsWm: boolean;
|
|
hdf: number;
|
|
}
|
|
|
|
// The first PRO feature a look is using, or null when it is LITE-clean. One
|
|
// string, so the caller can name it back to the user in the alert.
|
|
export function proLookInUse(look: Look): string | null {
|
|
if (PRO_FRAMES.includes(look.frame)) return 'A PRO frame';
|
|
if (look.gpsWm) return 'The GPS watermark';
|
|
// A LITE build can no longer reach the HDF row (paramDefs marks it PRO and
|
|
// the panel greys the chip out), but a session or recipe stored before the
|
|
// gate existed still carries a value: it is caught here, at the render.
|
|
if (look.hdf > 0) return 'The HDF effect';
|
|
return null;
|
|
}
|