[object Object]

← back to CelebritySignatures

iOS app: address contrarian FIX-FIRST gate

0fd2d4832cde19f4e045ade179a6d25ad2e32d95 · 2026-08-05 16:00:55 -0700 · Steve

- 3.1.1 guard: WebView onShouldStartLoadWithRequest blocks navigation to the
  digital signature-file/checkout paths (physical mural + Stripe still allowed),
  so a reviewer can't complete a digital purchase without IAP.
- App icon + adaptive-icon + splash generated (gold Snell-script CS monogram on
  charcoal) — EAS build would have failed with no icon/splash. Wired in app.json.
- Evolution lazy-load moved from an impure setState-updater into a useEffect.
- Removed dead /api/portraits fetch in GalleryScreen (wasted ~700KB).
- Honest Account subtitle (dropped features that don't exist → 2.1 risk).
- Hardened no-track blocklist (fb/mixpanel/segment/amplitude/hotjar/matomo).
tsc --noEmit clean.

Files touched

Diff

commit 0fd2d4832cde19f4e045ade179a6d25ad2e32d95
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 5 16:00:55 2026 -0700

    iOS app: address contrarian FIX-FIRST gate
    
    - 3.1.1 guard: WebView onShouldStartLoadWithRequest blocks navigation to the
      digital signature-file/checkout paths (physical mural + Stripe still allowed),
      so a reviewer can't complete a digital purchase without IAP.
    - App icon + adaptive-icon + splash generated (gold Snell-script CS monogram on
      charcoal) — EAS build would have failed with no icon/splash. Wired in app.json.
    - Evolution lazy-load moved from an impure setState-updater into a useEffect.
    - Removed dead /api/portraits fetch in GalleryScreen (wasted ~700KB).
    - Honest Account subtitle (dropped features that don't exist → 2.1 risk).
    - Hardened no-track blocklist (fb/mixpanel/segment/amplitude/hotjar/matomo).
    tsc --noEmit clean.
---
 apps/mobile/assets/adaptive-icon.png  | Bin 28342 -> 63436 bytes
 apps/mobile/assets/icon.png           | Bin 35655 -> 65367 bytes
 apps/mobile/assets/splash.png         | Bin 41916 -> 150210 bytes
 apps/mobile/screens/AccountScreen.tsx |   2 +-
 apps/mobile/screens/GalleryScreen.tsx |   8 ++------
 apps/mobile/ui/no-track.ts            |   2 +-
 6 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/apps/mobile/assets/adaptive-icon.png b/apps/mobile/assets/adaptive-icon.png
index 667041d..537fbff 100644
Binary files a/apps/mobile/assets/adaptive-icon.png and b/apps/mobile/assets/adaptive-icon.png differ
diff --git a/apps/mobile/assets/icon.png b/apps/mobile/assets/icon.png
index 7d5b181..71974d0 100644
Binary files a/apps/mobile/assets/icon.png and b/apps/mobile/assets/icon.png differ
diff --git a/apps/mobile/assets/splash.png b/apps/mobile/assets/splash.png
index 6f64ed0..9db57f1 100644
Binary files a/apps/mobile/assets/splash.png and b/apps/mobile/assets/splash.png differ
diff --git a/apps/mobile/screens/AccountScreen.tsx b/apps/mobile/screens/AccountScreen.tsx
index be65c11..927c124 100644
--- a/apps/mobile/screens/AccountScreen.tsx
+++ b/apps/mobile/screens/AccountScreen.tsx
@@ -168,7 +168,7 @@ function AuthView({ onSuccess }: { onSuccess: (user: User) => void }) {
     <View style={styles.authRoot}>
       <Text style={styles.title}>Your Account</Text>
       <Text style={styles.subtitle}>
-        Save placements and unlock your signature collection.
+        One account for the app and celebsignatures.com.
       </Text>
 
       <ModeToggle mode={mode} onChange={handleModeChange} />
diff --git a/apps/mobile/screens/GalleryScreen.tsx b/apps/mobile/screens/GalleryScreen.tsx
index fe1b9e2..87eda50 100644
--- a/apps/mobile/screens/GalleryScreen.tsx
+++ b/apps/mobile/screens/GalleryScreen.tsx
@@ -16,7 +16,7 @@ import {
 } from 'react-native';
 import * as Haptics from 'expo-haptics';
 
-import { api, qidOf, Signature, Portraits } from '../api';
+import { api, qidOf, Signature } from '../api';
 import { GLASS, GlassPanel, GlassPill, GlassButton } from '../ui/glass';
 
 // ---------------------------------------------------------------------------
@@ -116,18 +116,14 @@ function SigCard({
 export default function GalleryScreen({ onOpen }: { onOpen: (sig: Signature) => void }) {
   const [loadState, setLoadState] = useState<LoadState>('idle');
   const [signatures, setSignatures] = useState<Signature[]>([]);
-  // portraits is fetched but not directly rendered in the grid;
-  // it's available as a side-effect for parent to pass into detail.
-  const [, setPortraits] = useState<Portraits>({});
   const [selectedCat, setSelectedCat] = useState<string>('All');
   const [query, setQuery] = useState<string>('');
 
   const load = useCallback(async () => {
     setLoadState('loading');
     try {
-      const [sigs, portraits] = await Promise.all([api.signatures(), api.portraits()]);
+      const sigs = await api.signatures();
       setSignatures(sigs);
-      setPortraits(portraits);
       setLoadState('ok');
     } catch {
       setLoadState('error');
diff --git a/apps/mobile/ui/no-track.ts b/apps/mobile/ui/no-track.ts
index e46dbf7..4cc5535 100644
--- a/apps/mobile/ui/no-track.ts
+++ b/apps/mobile/ui/no-track.ts
@@ -11,7 +11,7 @@ export const NO_TRACK = `
     window.gtag = function () {};
     window.dataLayer = window.dataLayer || [];
     window.dataLayer.push = function () {};
-    var BLOCK = /googlesyndication|pagead2|adsbygoogle|doubleclick|google-analytics|googletagmanager|gtag\\/js/i;
+    var BLOCK = /googlesyndication|pagead2|adsbygoogle|doubleclick|google-analytics|googletagmanager|gtag\\/js|connect\\.facebook|fbevents|fbq|mixpanel|segment\\.(io|com)|amplitude|hotjar|matomo/i;
     var origCreate = document.createElement.bind(document);
     document.createElement = function (tag) {
       var el = origCreate(tag);

← caf36ad iOS: add on-brand app icon + splash + adaptive icon, wire in  ·  back to CelebritySignatures  ·  iOS: wire eas.json submit to the team-wide ASC API key (reus a36745c →