Commit Graph
19 Commits
Author SHA1 Message Date
admin c04b69a11f fix(mobile): dark mode on auth screens + RepostCard, expand .easignore
Sign-in/sign-up and RepostCard used the static (light-only) color
tokens instead of useTheme() — in dark mode the login screen kept a
light background with light-theme-colored text baked in, and
RepostCard's text color was hardcoded independent of its (already
theme-aware) surrounding background, both landing on illegible
low-contrast text. Same bug class as earlier dark-mode fixes this
session, converted the same way (useTheme() + makeStyles(colors)).

Also add a root-level .easignore (EAS Build's archive root may resolve
above mobile/ for monorepo purposes) excluding backend/tooling
directories the mobile app never needs at build or runtime (.claude,
.impeccable, .planning, docker, prisma — the last is only a type-only
dependency via mobile's tRPC router import, erased before Metro
bundles anything).
2026-09-06 21:10:49 +02:00
admin 82c9bb87b9 feat(mobile): add multi-image indicator to feed posts
Multi-photo posts gave no visual hint they were swipeable — a viewer
would only ever see the first image unless they already knew to swipe.
Adds a "1 / N" counter badge (top-right overlay) and a dot-page
indicator below the carousel, porting web's PostCard indicators.
2026-09-06 20:12:21 +02:00
admin 3d196b1528 fix(mobile): notification post link and actor-name link, comments dark mode
Notification taps for post-related types (REACTION/COMMENT/MENTION/
PAW_BACK) landed on a bare "no comments yet" screen with no sign of the
actual post. The comments screen now fetches the post via the existing
posts.getById and shows it (image/caption/header) via the shared
PostCard above the comment list.

The actor's name in each notification row is now its own tappable text
run that links to their profile, separate from tapping the rest of the
row (which still opens the notification's target) — ported from web's
notifications page, which does the same split between a Link and plain
text.

Also fixed: the comments screen used the static (light-only) color
tokens throughout, so embedding the theme-aware PostCard produced
near-invisible light text on its own light background in dark mode.
Converted the screen to useTheme() like the rest of the dark-mode-
converted screens.
2026-09-06 19:56:48 +02:00
admin 73ea97ac16 fix(mobile): notification separators/navigation, own-post delete option
Notifications: add a visible hairline separator between rows and make
each row tappable — it marks read and navigates to the relevant post
(comments screen) or pet profile, porting web's getHref()/getPostId()
routing logic.

Feed: the "..." menu on a post now opens a delete confirmation instead
of the report sheet when the post belongs to the currently active pet;
report sheet stays unchanged for posts from other pets. Reuses the
pre-existing posts.delete mutation, no backend changes needed.
2026-09-06 19:39:52 +02:00
admin 6b01046ded feat(mobile): mix trending posts into the Feed, update app icon assets
- explore.getTrending posts are now interleaved into the chronological
  Feed at semi-random intervals (src/lib/interleave-trending.ts),
  marked with a small "Trending" badge on PostCard — a lightweight
  stand-in for web's separate Explore "Trending" tab, which mobile
  wasn't going to get as its own screen. No backend change: reuses the
  existing explore.getTrending procedure as-is.
- update app icon / splash / favicon / Android adaptive-icon assets
  (user-provided)
- README: correct the now-stale Dark Mode "not yet converted" list
  (Explore/Notifications/pet profile/health were converted in the
  found.md batch) and document the report/date-format/pinch-zoom/
  legal-links fixes
2026-09-06 19:12:39 +02:00
admin 4a35fce20b fix(mobile): found.md batch — reports, dark mode, health form fixes
- new report feature: a "..." button on every post opens a reason-picker
  sheet (reports.create), matching web's ReportSheet reasons/copy
- pet profile, edit, followers/following, and the whole health screen
  (incl. consent gate) converted to the makeStyles(colors) dark-mode
  pattern
- fixed the invisible back button on every pushed (app)/_layout.tsx
  screen: headerTintColor was never set, so the native-stack default
  back chevron kept its platform tint instead of the theme color —
  black-on-black in dark mode looked like a missing button entirely
- health forms (weight/vet visit/vaccine) now take dates as DD-MM-YYYY
  instead of the backend's raw YYYY-MM-DD, converting internally
  (src/lib/date-format.ts); invalid dates now show an error instead of
  the mutation silently failing with no onError handler at all — this,
  not persistence, was the actual "Gesundheitsdaten werden nicht
  gespeichert" bug
- pinch-to-zoom on the full-screen image viewer via a plain
  PanResponder (no new native dependency)
- Pets tab: language switcher now uses flag emoji (🇩🇪/🇬🇧/🌐), and a
  new footer section links Impressum/Datenschutz/Nutzungsbedingungen
  plus the installed app version

All live-verified against the deployed backend except pinch-zoom
(two-finger gestures aren't simulatable over adb).
2026-09-06 18:55:12 +02:00
admin 462f295caa feat(mobile): add German/English i18n across the whole app
- i18next + react-i18next + expo-localization: device-locale detection,
  an MMKV-persisted DE/EN/Automatisch override (mirrors web's cookie-only
  locale, no backend field needed), and a language switcher on the Pets
  tab next to the theme toggle
- every screen and shared component converted from hardcoded German
  strings to translation keys; de.json/en.json kept in exact key-parity
  (218 keys each, verified programmatically)
- backend: src/trpc/init.ts now accepts an x-locale header as a fallback
  locale source (cookie still wins, web unaffected) since mobile has no
  cookie jar to set NEXT_LOCALE in; mobile's tRPC client sends the
  current language on every request
- fixes a latent bug: species/breed pickers were hardcoded to locale
  "de" while every other pet query resolved names via ctx.locale's
  default (English, since mobile never sent a locale cookie) — both now
  use the same current-language value
- expo-localization is a new native module (config plugin) and needs a
  native rebuild to actually link; deviceLocale() falls back to English
  instead of crashing when it isn't linked yet, so the app stays usable
  before that rebuild happens

Needs a NAS deploy (src/trpc/init.ts is shared backend code) before the
x-locale fallback and the species/breed locale fix take effect for mobile.
2026-09-06 17:31:41 +02:00
admin 0c6421c8de fix(mobile): dark mode on Explore/Notifications, breed dropdown overlay
- Explore and Notifications tabs now read colors from ThemeContext
  instead of the static light-only tokens
- OptionPicker's option list is position:absolute so it overlays
  following content instead of pushing it down, with zIndex on the
  component root (and FlatList's ListHeaderComponentStyle on Explore)
  so it actually paints above sibling content instead of underneath it
- check off found.md's resolved items, record the three newly reported ones
2026-09-06 16:30:02 +02:00
admin 0408be2063 feat(mobile): add onboarding flow, dark mode, and bugfixes
- 5-step onboarding (guidelines, upload consent, spider opt-in, pet
  creation, avatar) that gates first launch until a pet exists
- Add/delete pet flows on the Pets tab, with a shared OptionPicker
  (ScrollView-based, not FlatList, to avoid nested-VirtualizedList
  warnings inside onboarding's outer ScrollView)
- App-wide light/dark/auto theme via ThemeContext, synced with the
  existing owner.getThemePreference/setThemePreference backend
  procedures; core navigation chrome, Feed, Pets tab, and shared
  primitives (Button, TextField, Card, PetAvatar, PostCard, StoryTray)
  converted to the makeStyles(colors) pattern
- found.md fixes: safe-area insets on image/story viewers so controls
  clear the status bar, auto-mark-all-read on the notifications tab,
  and an Explore species/breed filter
2026-09-06 16:14:44 +02:00
adminandClaude Sonnet 5 d3bf94799e fix: exclude mobile/ from the web app's TypeScript checking and Docker build
Next.js's production build type-checks the whole repo by tsconfig.json's
default include glob, which picked up mobile/'s .tsx files once the
Docker image's git checkout finally included mobile/ (first pull to
include it) — none of mobile's own dependencies (react-native, expo-router,
...) are installed in that container, so the build failed outright.
mobile/ is now excluded from tsconfig.json and .dockerignore; it's a
separate app with its own tsconfig/package.json and was never meant to be
type-checked or shipped as part of the web image.

Also completes the mobile EAS/FCM push setup (app.json's extra.eas.projectId
and googleServicesFile, google-services.json gitignored) and adds a 15s
timeout around getExpoPushTokenAsync so a device that can't reach FCM fails
visibly instead of hanging silently forever.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 14:07:27 +02:00
adminandClaude Sonnet 5 a3f19ff70f feat(mobile): add health tracking, milestones, messaging, and push registration
Health: consent gate (Art. 9 DSGVO) plus weight/vet-visit/vaccine log
sections, gated behind health.getConsentStatus like the web app.
Milestones: view a pet's milestone posts and create the 5 user-initiated
types with an optional photo. Messaging: chat detail/compose screen
(messages/[conversationId].tsx) polling while focused, reachable from the
conversations list and from a pet profile's new "Nachricht" entry point.
Push: usePushNotifications requests permission and registers the Expo
push token with owner.registerPushToken; real delivery still needs an EAS
project id (`eas init`), tracked in the README.

All four verified live on a real Android emulator: health CRUD (add/list/
delete a weight log), Health/Milestones/Nachricht entry points gated
correctly by own-pet vs. other-pet, and full chat history loading via an
existing conversation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 09:50:07 +02:00
adminandClaude Sonnet 5 eda6d3b801 feat(mobile): add stories, video playback, and search
Story tray/creation/viewer with PawRing seen/unseen indicator, expo-video
playback for VIDEO posts (replacing the static placeholder), and a
pets/people/hashtags search screen reachable from the Explore tab header.
Extracts FollowButton from the pet-profile screen since search results
need the same follow/unfollow toggle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 08:53:07 +02:00
admin 925d121bb8 feat(mobile): add repost (Paw-Back) creation
PawBackButton toggles reposts.create/delete with an isReposted-backed
optimistic state, mirroring web's PawBackButton — replaces the static
repost count in PostCard's action row. RepostCard renders a REPOST
post as a read-only "Paw-Back von {name}" attribution wrapper around
the original post's pet header, image, and caption, ported from web's
RepostCard with no action row (matches web: only the original post is
reactable/commentable).
2026-09-05 15:43:48 +02:00
admin 085d2abb53 feat(mobile): add post creation and comments
Post creation: gallery/camera picker (expo-image-picker) uploads each
image straight to Supabase Storage via a presigned PUT
(posts.getPresignedUrl + expo-file-system), then posts.create with the
resulting storage keys — reachable via a new "+" header button on the
Feed tab. No client-side blurhash (browser Canvas API, no RN
equivalent) or AI-disclosure/mention support yet, matching the rest of
mobile's plain-text captions.

Comments: a dedicated screen (posts/[postId]/comments) for reading,
posting, and deleting one's own comments, reachable by tapping the
comment icon on a PostCard. Ported from web's PostDetailDialog comment
panel, scoped down to just that panel since mobile's image full-view
already has its own route.
2026-09-05 15:35:32 +02:00
admin c1067b3245 feat(mobile): add header wordmark and full-screen image viewer
Header now shows the PawFeed paw+text logo on the Feed tab (matching
web's Sidebar wordmark). Tapping a post image opens a full-screen
viewer as a route-based fullScreenModal, with a blurred edge-to-edge
copy of the same photo behind the sharp foreground image instead of a
flat black backdrop, for a more dynamic Photos-app-style lightbox.
2026-09-05 14:53:13 +02:00
admin a737a17976 fix(mobile): feed separation, adaptive launcher icon; feat: full pet profile
Fixes from user testing on a real device:
- Feed: replaced an invisible spacing-only separator with an actual
  hairline divider between posts.
- Android launcher icon showed Expo's default placeholder (a blue arrow)
  because the app icon and the Android adaptive-icon layers
  (foreground/background/monochrome) are two separate asset sets — only
  icon.png/favicon.png had been replaced. Added scripts/derive-adaptive-
  icon.js to crop the paw glyph out of icon.png (detected by its marigold
  color) and generate all three adaptive-icon layers plus the splash icon;
  this is an explicit placeholder per user's own call, not final art.

New: full pet profile (app/(app)/pets/[petId]/), matching web's
src/app/(app)/pets/[petId]/page.tsx:
- View: identity, species, bio/adoption story, follower/following counts
  (tappable → list screens), the pet's own posts below.
- Follow/unfollow with real initial state (follows.isFollowing) and
  optimistic toggle — unlike feed reactions, this endpoint actually
  exists, so no need to fake an initial state.
- Edit screen (name/nickname/bio/adoption story via pets.update) for the
  owner's own pets.
- Tapping a pet (feed header, Explore card, Pets-tab row) now opens this
  profile instead of nowhere; the Pets tab's active-pet switch is now a
  separate checkmark control instead of overloading the whole row tap.

PostCard's post-shape prop is now structural rather than tied to
feed.getFeed's output type, since posts.byPetId selects `pet` via the
narrower petIdentitySelect (no isVerified/owner) — both need to satisfy
the same component.

Verified end-to-end on-device: feed separator visible, own-pet profile
shows a working Bearbeiten button whose form is correctly prefilled (a
stray edit was made to Bianca's nickname field by mistake during testing
and was discarded via back-navigation without saving — never sent to the
server), someone else's pet profile shows a working Follow/Unfollow
toggle, followers list navigates correctly, and the home-screen launcher
icon now shows the paw instead of the default Expo icon.
2026-09-05 13:47:20 +02:00
admin c35d4cda46 feat(mobile): Phase 1 — real Feed/Explore/Notifications/Pets tabs
Moves the mobile app from a connectivity scaffold to a real Phase 1 app:

- Migrate off Expo Go onto a local custom dev client (expo-dev-client,
  built via expo prebuild + expo run:android against the local Android
  SDK — no EAS account needed). Needed because react-native-mmkv requires
  native code Expo Go doesn't ship.
- Persisted, MMKV-backed TanStack Query cache (PersistQueryClientProvider)
  plus expo-image, so a relaunch renders the last-known feed/pets/
  notifications instantly instead of a blank screen while refetching.
- ActivePetContext: every pet-scoped procedure requires an explicit petId
  server-side (no server-side "current pet"), ported from web's
  ActivePetContext, MMKV-backed instead of localStorage.
- Bottom Tabs (Feed/Explore/Notifications/Pets) mirroring the web app's
  actual mobile nav, with Messages as a header button rather than a tab
  (matches web). Feed, PostCard, PawButton reactions, pet discovery grid,
  notifications list, and a conversations list are all wired to the real
  backend and verified against the live database.
- Design tokens/components extended with PostCard/PawButton/PetAvatar/
  PetIdentityBadges, all styled from the existing src/theme/tokens.ts.
- Fixed a react/react-dom version mismatch surfaced along the way, and
  handle Clerk's needs_client_trust (Device Trust) sign-in status with an
  email-code step.

Verified end-to-end in the Android emulator against pawfeed.org: feed
scrolls and paginates with real posts/images, paw reactions toggle
optimistically and persist, pet switching updates every screen, and
notifications/explore show live data.
2026-09-05 13:19:01 +02:00
admin dc344f1188 feat(mobile): match PawFeed web design system, fix Clerk device trust
- Add design tokens (colors, radii, typography) mirroring DESIGN.md's
  "Spotlight Porch" system, plus Button/TextField/Card components built
  on them. Restyle the sign-in and placeholder home screens to match.
- Load Inter via @expo-google-fonts/inter, gate rendering on fonts +
  Clerk being ready instead of a blank screen.
- Pin react-dom to match react's version — Metro/Hermes hard-require
  exact equality, and react-dom wasn't pinned anywhere before.
- Handle Clerk's `needs_client_trust` status (Device Trust, tied to the
  dashboard's Native Applications API): send/verify an email code
  before finalizing sign-in.

Verified end-to-end in the Android emulator against the live backend:
sign-in, device-trust code verification, and the home screen showing
real stats.getPublicStats data.
2026-09-05 11:51:17 +02:00
admin 9eb31c3323 feat(mobile): add Expo/React Native scaffold for PawFeed Android app
Connectivity + auth scaffold only: Expo Router, Clerk session auth via
expo-secure-store, and a type-only tRPC AppRouter import from the web
app's router — no backend changes needed. See mobile/README.md.
2026-09-05 11:01:49 +02:00