Harte Paywall

This commit is contained in:
2026-04-29 21:16:16 +02:00
committed by Timo Knuth
parent 0f933da3c9
commit d37b49f1f6
10 changed files with 305 additions and 129 deletions

View File

@@ -10,6 +10,7 @@ import * as ImagePicker from 'expo-image-picker';
import * as ImageManipulator from 'expo-image-manipulator';
import * as Haptics from 'expo-haptics';
import * as AppleAuthentication from 'expo-apple-authentication';
import Constants from 'expo-constants';
import { usePostHog } from 'posthog-react-native';
import { useApp } from '../context/AppContext';
import { useColors } from '../constants/Colors';
@@ -157,10 +158,15 @@ export default function ScannerScreen() {
const [analysisResult, setAnalysisResult] = useState<IdentificationResult | null>(null);
const [demoResultVisible, setDemoResultVisible] = useState(false);
const cameraRef = useRef<CameraView>(null);
const scanLineProgress = useRef(new Animated.Value(0)).current;
const scanPulse = useRef(new Animated.Value(0)).current;
const scanLineProgress = useRef(new Animated.Value(0)).current;
const scanPulse = useRef(new Animated.Value(0)).current;
const isExpoGo = Constants.appOwnership === 'expo';
useEffect(() => {
if (isExpoGo) {
setAppleAvailable(false);
return;
}
let mounted = true;
AppleAuthentication.isAvailableAsync()
.then((available) => {
@@ -172,7 +178,7 @@ export default function ScannerScreen() {
return () => {
mounted = false;
};
}, []);
}, [isExpoGo]);
useEffect(() => {
if (!isAnalyzing) {
@@ -447,7 +453,7 @@ export default function ScannerScreen() {
};
const handleSave = async () => {
if (analysisResult && selectedImage) {
if (analysisResult && selectedImage) {
if (!session) {
// Guest mode: store result and go to signup
setPendingPlant(analysisResult, selectedImage);
@@ -455,10 +461,14 @@ export default function ScannerScreen() {
return;
}
try {
await savePlant(analysisResult, selectedImage);
router.back();
} catch (error) {
try {
await savePlant(analysisResult, selectedImage);
if (router.canGoBack()) {
router.back();
} else {
router.replace('/(tabs)');
}
} catch (error) {
console.error('Saving identified plant failed', error);
Alert.alert(billingCopy.genericErrorTitle, billingCopy.genericErrorMessage);
}
@@ -507,7 +517,7 @@ export default function ScannerScreen() {
});
await hydrateSession(nextSession);
posthog.capture('apple_login_succeeded', { surface: 'scanner_demo' });
router.replace('/profile/billing');
router.replace(nextSession.isNewUser ? '/profile/billing' : '/(tabs)');
} catch (error: any) {
if (error?.code === 'ERR_REQUEST_CANCELED') {
return;
@@ -528,8 +538,12 @@ export default function ScannerScreen() {
};
const handleClose = () => {
router.back();
};
if (router.canGoBack()) {
router.back();
return;
}
router.replace('/onboarding');
};
const controlsPaddingBottom = Math.max(20, insets.bottom + 10);
const controlsPanelHeight = 28 + 80 + controlsPaddingBottom;
@@ -712,7 +726,7 @@ export default function ScannerScreen() {
activeOpacity={0.85}
>
<Text style={[styles.demoPrimaryText, { color: colors.onPrimary }]}>
{isAuthLoading ? '...' : session ? billingCopy.unlockCta : billingCopy.appleCta}
{isAuthLoading ? '...' : session ? billingCopy.unlockCta : appleAvailable ? billingCopy.appleCta : billingCopy.emailCta}
</Text>
</TouchableOpacity>
)}