TTikotok
This commit is contained in:
@@ -19,13 +19,13 @@ import { PlantRecognitionService } from '../services/plantRecognitionService';
|
||||
import { IdentificationResult } from '../types';
|
||||
import { ResultCard } from '../components/ResultCard';
|
||||
import { backendApiClient, isInsufficientCreditsError, isNetworkError, isTimeoutError } from '../services/backend/backendApiClient';
|
||||
import { isBackendApiError } from '../services/backend/contracts';
|
||||
import { createIdempotencyKey } from '../utils/idempotency';
|
||||
import { AuthService } from '../services/authService';
|
||||
import { consumeSharedImageUri, SHARE_INTENT_KEY } from '../utils/shareHandoff';
|
||||
import { OutOfCreditsSheet } from '../components/OutOfCreditsSheet';
|
||||
import { isBackendApiError } from '../services/backend/contracts';
|
||||
import { createIdempotencyKey } from '../utils/idempotency';
|
||||
import { AuthService } from '../services/authService';
|
||||
import { consumeSharedImageUri, SHARE_INTENT_KEY } from '../utils/shareHandoff';
|
||||
import { OutOfCreditsSheet } from '../components/OutOfCreditsSheet';
|
||||
|
||||
const DEMO_SCAN_LIMIT = 3;
|
||||
const DEMO_SCAN_LIMIT = 1;
|
||||
|
||||
const getBillingCopy = (language: 'de' | 'en' | 'es') => {
|
||||
if (language === 'de') {
|
||||
@@ -51,8 +51,8 @@ const getBillingCopy = (language: 'de' | 'en' | 'es') => {
|
||||
demoTitle: 'Rettungsplan bereit',
|
||||
demoMessage: 'Wir haben mögliche Ursachen erkannt. Schalte die vollständige KI-Diagnose und deinen 7-Tage-Rettungsplan frei.',
|
||||
demoNoCreditsTitle: 'Demo-Scans aufgebraucht',
|
||||
demoNoCreditsMessage: 'Du hast deine 3 kostenlosen Demo-Scans auf diesem Gerät genutzt. Starte Pro, um weiter Pflanzen zu scannen.',
|
||||
demoCreditsRemaining: (count: number) => `${count} Demo-Scans übrig`,
|
||||
demoNoCreditsMessage: 'Du hast deinen kostenlosen Demo-Scan auf diesem Gerät genutzt. Starte Pro, um weiter Pflanzen zu scannen.',
|
||||
demoCreditsRemaining: (count: number) => (count === 1 ? '1 Demo-Scan übrig' : `${count} Demo-Scans übrig`),
|
||||
creditsRemaining: (count: number) => `${count} Scans übrig`,
|
||||
appleCta: 'Mit Apple fortfahren',
|
||||
emailCta: 'Mit E-Mail fortfahren',
|
||||
@@ -83,8 +83,8 @@ const getBillingCopy = (language: 'de' | 'en' | 'es') => {
|
||||
demoTitle: 'Plan de rescate listo',
|
||||
demoMessage: 'Detectamos posibles causas. Desbloquea el diagnóstico completo con IA y tu plan de rescate de 7 días.',
|
||||
demoNoCreditsTitle: 'Escaneos demo agotados',
|
||||
demoNoCreditsMessage: 'Ya usaste tus 3 escaneos demo gratuitos en este dispositivo. Inicia Pro para seguir escaneando plantas.',
|
||||
demoCreditsRemaining: (count: number) => `${count} escaneos demo restantes`,
|
||||
demoNoCreditsMessage: 'Ya usaste tu escaneo demo gratuito en este dispositivo. Inicia Pro para seguir escaneando plantas.',
|
||||
demoCreditsRemaining: (count: number) => (count === 1 ? '1 escaneo demo restante' : `${count} escaneos demo restantes`),
|
||||
creditsRemaining: (count: number) => `${count} escaneos restantes`,
|
||||
appleCta: 'Continuar con Apple',
|
||||
emailCta: 'Continuar con email',
|
||||
@@ -114,8 +114,8 @@ const getBillingCopy = (language: 'de' | 'en' | 'es') => {
|
||||
demoTitle: 'Rescue plan ready',
|
||||
demoMessage: 'We found possible causes. Unlock the full AI diagnosis and your 7-day rescue plan.',
|
||||
demoNoCreditsTitle: 'Demo scans used',
|
||||
demoNoCreditsMessage: 'You used your 3 free demo scans on this device. Start Pro to keep scanning plants.',
|
||||
demoCreditsRemaining: (count: number) => `${count} demo scans left`,
|
||||
demoNoCreditsMessage: 'You used your free demo scan on this device. Start Pro to keep scanning plants.',
|
||||
demoCreditsRemaining: (count: number) => (count === 1 ? '1 demo scan left' : `${count} demo scans left`),
|
||||
creditsRemaining: (count: number) => `${count} scans left`,
|
||||
appleCta: 'Continue with Apple',
|
||||
emailCta: 'Continue with email',
|
||||
@@ -142,6 +142,7 @@ export default function ScannerScreen() {
|
||||
setPendingPlant,
|
||||
guestScanCount,
|
||||
incrementGuestScanCount,
|
||||
hasCompletedOnboarding,
|
||||
} = useApp();
|
||||
const colors = useColors(isDarkMode, colorPalette);
|
||||
const router = useRouter();
|
||||
@@ -160,7 +161,7 @@ export default function ScannerScreen() {
|
||||
: params.sharedImageKey;
|
||||
const hasActiveEntitlement = billingSummary?.entitlement?.plan === 'pro'
|
||||
&& billingSummary?.entitlement?.status === 'active';
|
||||
const isDemoMode = !session; // guests get limited AI demo scans; signed-in users burn real credits
|
||||
const isDemoMode = !session; // guests get limited AI demo scans; signed-in users burn real credits
|
||||
const availableCredits = billingSummary?.credits.available ?? 0;
|
||||
const demoScansRemaining = Math.max(0, DEMO_SCAN_LIMIT - guestScanCount);
|
||||
|
||||
@@ -293,22 +294,22 @@ export default function ScannerScreen() {
|
||||
}, 150);
|
||||
|
||||
try {
|
||||
if (isDemoMode) {
|
||||
posthog.capture('demo_scan_started', {
|
||||
authenticated: Boolean(session),
|
||||
scan_type: isHealthMode ? 'health_check' : 'identification',
|
||||
demo_scans_used: guestScanCount,
|
||||
demo_scans_remaining: demoScansRemaining,
|
||||
});
|
||||
const demoResult = await PlantRecognitionService.identify(imageUri, language, {
|
||||
idempotencyKey: createIdempotencyKey('demo-scan-plant'),
|
||||
});
|
||||
setAnalysisProgress(100);
|
||||
await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
|
||||
await new Promise(resolve => setTimeout(resolve, 350));
|
||||
incrementGuestScanCount();
|
||||
setAnalysisResult(demoResult);
|
||||
posthog.capture('demo_scan_completed', {
|
||||
if (isDemoMode) {
|
||||
posthog.capture('demo_scan_started', {
|
||||
authenticated: Boolean(session),
|
||||
scan_type: isHealthMode ? 'health_check' : 'identification',
|
||||
demo_scans_used: guestScanCount,
|
||||
demo_scans_remaining: demoScansRemaining,
|
||||
});
|
||||
const demoResult = await PlantRecognitionService.identify(imageUri, language, {
|
||||
idempotencyKey: createIdempotencyKey('demo-scan-plant'),
|
||||
});
|
||||
setAnalysisProgress(100);
|
||||
await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
|
||||
await new Promise(resolve => setTimeout(resolve, 350));
|
||||
incrementGuestScanCount();
|
||||
setAnalysisResult(demoResult);
|
||||
posthog.capture('demo_scan_completed', {
|
||||
authenticated: Boolean(session),
|
||||
latency_ms: Date.now() - startTime,
|
||||
demo_scans_used_after: guestScanCount + 1,
|
||||
@@ -600,7 +601,7 @@ export default function ScannerScreen() {
|
||||
router.back();
|
||||
return;
|
||||
}
|
||||
router.replace('/onboarding');
|
||||
router.replace(hasCompletedOnboarding ? '/(tabs)' : '/onboarding');
|
||||
};
|
||||
|
||||
const controlsPaddingBottom = Math.max(20, insets.bottom + 10);
|
||||
|
||||
Reference in New Issue
Block a user