goon/mobile
goon-foss 1e6be1926e fix(mobile): zdejmij maintainVisibleContentPosition, wywala apke na amen
GOON-1S: 53 wystapienia u 35 osob od 2026-07-03, poziom fatal. Lancuch przyczyn jest
jednoznaczny: JSApplicationIllegalArgumentException przy ustawianiu wlasciwosci
maintainVisibleContentPosition na RCTScrollView, dalej
MaintainVisibleScrollPositionHelper.getUIManagerModule() robi assertNotNull i gdy
ScrollView powstaje w chwili, w ktorej UIManager jest niedostepny, leci AssertionError.
To blad React Native 0.76.9, nie da sie go obejsc konfiguracja.

Wlasciwosc byla anti-jankiem: przy sort=created_at scrapery dosypuja sceny na gore,
wiec refetch potrafil szarpnac trescia pod palcem. Skakanie listy jest gorsze niz nic,
ale crash jest gorszy od skakania. Do rozwazenia po podniesieniu React Native.

Przy okazji GOON-4N (Cannot read property 'length' of undefined, 2 osoby): dokladnego
miejsca NIE da sie wskazac, bo build 0.2.2 poszedl bez source map, a zaden z naszych
czterech getNextPageParam nie siega po .length. Dokladamy tam tania defensywe na
niepelna strone; jesli bedzie wracac, najpierw trzeba naprawic wysylke source map.

Opublikowane OTA na 1.2 i 1.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 17:01:54 +02:00
..
android fix(mobile): EXPO_RUNTIME_VERSION w AndroidManifest na 1.2 2026-08-11 09:48:48 +02:00
assets feat(brand): oo logo — app icons, landing, in-app mark (Gemini-generated) 2026-05-30 22:38:52 +02:00
src fix(mobile): zdejmij maintainVisibleContentPosition, wywala apke na amen 2026-08-20 17:01:54 +02:00
.gitignore Initial commit 2026-05-20 10:10:22 +02:00
app.json feat(mobile): baner migracji na nowo podpisane APK + expo-keep-awake do buildu 2026-08-11 09:17:30 +02:00
App.tsx fix(ui): pasek zakladek naprawde plynie - zakladki jako stan, nie trasy 2026-08-18 09:59:24 +02:00
babel.config.js Initial commit 2026-05-20 10:10:22 +02:00
package-lock.json feat(mobile): baner migracji na nowo podpisane APK + expo-keep-awake do buildu 2026-08-11 09:17:30 +02:00
package.json feat(mobile): baner migracji na nowo podpisane APK + expo-keep-awake do buildu 2026-08-11 09:17:30 +02:00
README.md Initial commit 2026-05-20 10:10:22 +02:00
tsconfig.json Initial commit 2026-05-20 10:10:22 +02:00

goon mobile (Expo / React Native)

Mobile client do self-hosted goon backendu. iOS/Android jeden codebase.

Setup

cd mobile
npm install
npx expo start

Następnie:

  • Expo Go (iOS/Android): zeskanuj QR z terminala
  • Android emulator: npm run android
  • iOS simulator: npm run ios (tylko macOS)
  • Web preview: npm run web

Konfiguracja

Po pierwszym uruchomieniu zobaczysz ekran logowania:

  • Backend URL — adres twojego goon backendu, np.:
    • http://192.168.1.10:8000 (LAN)
    • https://goon.tvojadomena.dev (przez Cloudflare Tunnel/Caddy)
    • http://100.x.x.x:8000 (przez Tailscale)
  • API Key — klucz wygenerowany dla backendu, ustawiony w .env:
    API_KEYS=<klucz>
    
    Generowanie:
    python -c "import secrets; print(secrets.token_urlsafe(32))"
    

Klucz jest trzymany w expo-secure-store (Keychain na iOS, Keystore na Androidzie).

Ekrany

  • Login — backend URL + API key, weryfikacja przez /healthz + /scenes
  • Scenes — lista scen z search; pull-to-refresh
  • Scene detail — performerzy, tagi, źródła, opis
  • Merge queue — pending merge candidates, sortowane po score (desc)
  • Merge detail — side-by-side dwóch scen + reasons + akcje:
    • Merge → keep LEFT (default — left to wcześniejsza/kanoniczna)
    • Merge → keep RIGHT (gdy nowsza wersja ma lepsze metadane)
    • Reject (keep both) — to nie jest duplikat, zostawiamy oddzielnie

Stack

  • Expo SDK 52 + React Native 0.76 (new architecture)
  • TypeScript strict
  • React Navigation 7 (native stack)
  • TanStack Query 5 (cache, optimistic invalidation)
  • expo-secure-store (credentials)

Build .apk (sideload na Androida)

npx eas build --profile preview --platform android

Wymaga konta Expo. Bez niego można użyć expo prebuild + gradlew assembleRelease.

Dlaczego nie PWA

Wybrany RN+Expo zamiast PWA bo:

  • swipe gestures pasują do triage merge queue
  • secure-store jest natywny (Keychain/Keystore) zamiast localStorage
  • pull-to-refresh i FlatList virtualization out-of-the-box
  • Jeden .apk można rozdać testerom bez App Store