Jan slusznie zapytal, czy WebView jest w ogole potrzebny. Rozlozylem protokol do konca: po przejsciu zabezpieczenia strona robi POST na WLASNY adres z cialem 'cf-turnstile-response=<token>' i dostaje JSON z polem link, czyli gotowy plik. Endpoint to po prostu adres strony pliku, nie zadne osobne API. Bez tokenu sie nie da: POST z pustym albo brakujacym cf-turnstile-response oddaje zwykly HTML (701 kB), a nie JSON. Sprawdzone trzy warianty ciala. Tokenu nie wyprodukuje klient HTTP, bo wymaga silnika JS. Ale NIE wymaga czlowieka: widget jest w trybie flexible z callbackiem, wiec na czystym domowym laczu przechodzi sam. Wykorzystujemy to: WebView zostaje jako silnik JS, tylko podsluchujemy ten jeden POST i gdy w odpowiedzi pojawi sie link, oddajemy go aplikacji przez istniejacy kanal video_url. Aplikacja przechodzi wtedy na NATYWNY odtwarzacz, bez reklam i bez ogladania strony hostera. Oswojony wyglad strony zostaje jako zabezpieczenie na wypadek, gdyby zabezpieczenie jednak zazadalo kliniecia. Blok zwalidowany jako realny JavaScript (new Function po zamianie podwojnych backslashy na pojedyncze, tak jak robi to szablon). Typecheck bez nowych bledow. Opublikowane OTA na 1.2 i 1.1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| android | ||
| assets | ||
| src | ||
| .gitignore | ||
| app.json | ||
| App.tsx | ||
| babel.config.js | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
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:
Generowanie:API_KEYS=<klucz>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