diff --git a/mobile/app/onboarding/pet.tsx b/mobile/app/onboarding/pet.tsx
index ea064a9..de507ef 100644
--- a/mobile/app/onboarding/pet.tsx
+++ b/mobile/app/onboarding/pet.tsx
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { ScrollView } from "react-native";
+import { FlatList } from "react-native";
import { useRouter } from "expo-router";
import { useActivePet } from "../../src/context/ActivePetContext";
import { OnboardingGuidelines } from "../../src/components/onboarding/OnboardingGuidelines";
@@ -7,7 +7,7 @@ import { UploadConsent } from "../../src/components/onboarding/UploadConsent";
import { ArachnophobiaOptIn } from "../../src/components/onboarding/ArachnophobiaOptIn";
import { PetCreateForm } from "../../src/components/onboarding/PetCreateForm";
import { AvatarStep } from "../../src/components/onboarding/AvatarStep";
-import { colors } from "../../src/theme/tokens";
+import { useTheme } from "../../src/context/ThemeContext";
/**
* Port of web's src/app/onboarding/pet/page.tsx — same five-step flow and
@@ -18,6 +18,7 @@ import { colors } from "../../src/theme/tokens";
*/
export default function OnboardingPetScreen() {
const router = useRouter();
+ const { colors } = useTheme();
const { setActivePetId } = useActivePet();
const [guidelinesAcknowledged, setGuidelinesAcknowledged] = useState(false);
const [uploadConsentGiven, setUploadConsentGiven] = useState(false);
@@ -47,8 +48,20 @@ export default function OnboardingPetScreen() {
}
return (
-
- {content}
-
+ // FlatList, not ScrollView, as the scroll container: PetCreateForm's
+ // Rassen-Dropdown (OptionPicker) nests its own vertical ScrollView, and
+ // two plain same-axis ScrollViews stacked inside each other silently eat
+ // the inner one's scroll gestures on Android (nestedScrollEnabled does
+ // not reliably fix real-ScrollView-in-ScrollView nesting) — a FlatList
+ // outer container is exactly explore.tsx's already-working fix for the
+ // same OptionPicker component (see its ListHeaderComponent usage there).
+ {content}>}
+ />
);
}
+
+const EMPTY_DATA: never[] = [];
diff --git a/mobile/found.md b/mobile/found.md
index 18b12a9..12e4e9b 100644
--- a/mobile/found.md
+++ b/mobile/found.md
@@ -39,4 +39,13 @@ TODO Neu2:
- [x] im Feed fehlt ein Indikator wenn in einem Post mehrere Bilder hinterlegt sind. das wischen funktioniert, aber nur wenn man weiß das dort mehrere bilder hinterlegt sind. unwissende würde nur ein bild sehen können.
→ Zähler-Badge oben rechts ("1 / 3") plus Punkte-Indikator unter dem Bild ergänzt (analog zur Web-Version), live bestätigt.
- [x] Kommentar Fenster ist nicht im Darkmode
+- [x] Tier Anlegen ist nicht im Darkmode + Rassen werden als Dropdown angezeigt lassen sich aber nicht scrollen.
+ → Darkmode: PetCreateForm.tsx + onboarding/pet.tsx nutzten noch die statischen (Hell-only) `colors`/`typography` statt `useTheme()` — umgestellt auf das gleiche Muster wie sign-up.tsx/OptionPicker.tsx. Scroll-Bug: onboarding/pet.tsx nutzte als äußeren Container ein normales `ScrollView`, darin verschachtelt der Rassen-Dropdown (OptionPicker) sein eigenes `ScrollView` — zwei gleichachsige ScrollViews ineinander verschlucken auf Android die Scroll-Geste des inneren, auch mit `nestedScrollEnabled`. Fix: äußeren Container auf `FlatList` (leere Liste + `ListHeaderComponent`) umgestellt, exakt das bereits funktionierende Muster aus explore.tsx für dieselbe OptionPicker-Komponente. Typecheck + Lint sauber, i18n-Parität unverändert (243/243) — nicht live auf Android getestet (kein Emulator in dieser Session), nur strukturell gegen den bekannten Explore-Fix abgeglichen.
+- [x] Nach dem Speichern des ersten Tiers, und dem Hochladen des Profilfotos, wird man wieder zurück geworfen auf Tier erstellen. erst ein neustart der app lässt einen auf den feed zugreifen. (BUG)
+ → Ursache: `pets.create`-Mutation in PetCreateForm.tsx hat die `trpc.pets.list`-Query (ActivePetContext) nie invalidiert. Nach dem Avatar-Schritt landet man in `(app)`, aber `OnboardingRedirect` (app/_layout.tsx) sah dort weiterhin den alten, leeren Pets-Stand aus dem Cache und schickte sofort wieder zurück nach `/onboarding/pet` — nur ein Neustart hat die Liste frisch geladen. Fix: `queryClient.invalidateQueries` auf `trpc.pets.list` direkt im `onSuccess` der Create-Mutation. Typecheck sauber. videos die angeklickt werden, laufen in endlosschleife weiter obwohl man im feed weiter scrollt
+ - Profilbilder sind nicht vergrößerbar
+ - Profilbearbeiten, lässt sich die Rasse nicht mehr ändern; wäre wichtig wenn man bei der erstellung fehler gemacht hat.
+ - sowie kann man beim Tier kein geburtstag hinterlegen oder adoptionstag wie es im web vorhanden ist.
+ - Meilensteine sind nicht im Darkmode verfügbar
+ -
-
\ No newline at end of file
diff --git a/mobile/src/components/onboarding/PetCreateForm.tsx b/mobile/src/components/onboarding/PetCreateForm.tsx
index dd1c69f..56e5cbf 100644
--- a/mobile/src/components/onboarding/PetCreateForm.tsx
+++ b/mobile/src/components/onboarding/PetCreateForm.tsx
@@ -1,12 +1,13 @@
-import { useState } from "react";
+import { useMemo, useState } from "react";
import { View, Text, StyleSheet } from "react-native";
import { useTranslation } from "react-i18next";
-import { useMutation, useQuery } from "@tanstack/react-query";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useTRPC } from "../../api/trpc";
import { TextField } from "../TextField";
import { Button } from "../Button";
import { OptionPicker, type PickerOption } from "../OptionPicker";
-import { colors, typography } from "../../theme/tokens";
+import { useTheme } from "../../context/ThemeContext";
+import { getTypography, type ColorTokens } from "../../theme/tokens";
type Props = { onSuccess: (pet: { id: string; name: string }) => void };
@@ -19,6 +20,9 @@ type Props = { onSuccess: (pet: { id: string; name: string }) => void };
export function PetCreateForm({ onSuccess }: Props) {
const { t } = useTranslation();
const trpc = useTRPC();
+ const queryClient = useQueryClient();
+ const { colors } = useTheme();
+ const styles = useMemo(() => makeStyles(colors), [colors]);
const [name, setName] = useState("");
const [nickname, setNickname] = useState("");
const [speciesId, setSpeciesId] = useState(null);
@@ -31,7 +35,14 @@ export function PetCreateForm({ onSuccess }: Props) {
const createMutation = useMutation(
trpc.pets.create.mutationOptions({
- onSuccess: (pet) => onSuccess({ id: pet.id, name: pet.name }),
+ onSuccess: (pet) => {
+ // Ohne dieses Invalidate bleibt ActivePetContext.pets (trpc.pets.list)
+ // auf dem alten "keine Tiere"-Stand stehen, bis die App neu startet —
+ // OnboardingRedirect wirft dann sofort wieder auf /onboarding/pet
+ // zurück, sobald man nach dem Avatar-Schritt in (app) landet.
+ queryClient.invalidateQueries({ queryKey: trpc.pets.list.queryOptions().queryKey });
+ onSuccess({ id: pet.id, name: pet.name });
+ },
onError: (err) => setError(err.message),
})
);
@@ -161,12 +172,15 @@ function BreedPicker({
);
}
-const styles = StyleSheet.create({
- container: { padding: 24, gap: 6 },
- title: { ...typography.title, fontSize: 18, marginBottom: 4 },
- subtitle: { ...typography.body, color: colors.quietGray, marginBottom: 16 },
- label: { ...typography.label, textTransform: "none", letterSpacing: 0, marginTop: 10 },
- multiline: { height: 80, textAlignVertical: "top", paddingTop: 12 },
- error: { ...typography.body, color: colors.alertRed, marginTop: 8 },
- cta: { marginTop: 16 },
-});
+function makeStyles(colors: ColorTokens) {
+ const typography = getTypography(colors);
+ return StyleSheet.create({
+ container: { padding: 24, gap: 6 },
+ title: { ...typography.title, fontSize: 18, marginBottom: 4 },
+ subtitle: { ...typography.body, color: colors.quietGray, marginBottom: 16 },
+ label: { ...typography.label, textTransform: "none", letterSpacing: 0, marginTop: 10 },
+ multiline: { height: 80, textAlignVertical: "top", paddingTop: 12 },
+ error: { ...typography.body, color: colors.alertRed, marginTop: 8 },
+ cta: { marginTop: 16 },
+ });
+}