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>
This commit is contained in:
goon-foss 2026-08-20 17:01:54 +02:00
parent 5065df6220
commit 1e6be1926e
6 changed files with 23 additions and 5 deletions

View file

@ -16,6 +16,15 @@ export type ChangelogEntry = {
};
export const CHANGELOG: ChangelogEntry[] = [
{
id: '2026-08-20c',
date: 'August 2026',
items: [
'Fixed a crash that closed the app while scrolling lists. It came from the trick we used to stop the grid jumping when fresh scenes arrive; the crash was worse than the jump, so the trick is gone until we move to a newer React Native.',
'Site pages now put newly added scenes at the top. Most tubes never report a release date, so those scenes were sorted to the very bottom and the site looked frozen even though it was not.',
'Thumbnails that used to stay blank now load, including sites whose image servers refuse our server directly.',
],
},
{
id: '2026-08-20b',
date: 'August 2026',

View file

@ -370,10 +370,13 @@ export function sceneGridProps(cols: number) {
maxToRenderPerBatch: 8,
initialNumToRender: 8,
updateCellsBatchingPeriod: 50,
// Anti-jank (report): sort=created_at desc → scrapery dosypują nowe sceny NA GÓRĘ.
// Gdy refetch wstawi je nad viewportem, treść skacze/tearing pod palcem. RN pinuje
// widoczny element (minIndexForVisible:0) i sam koryguje offset. autoscrollToTopThreshold:
// gdy user jest przy samej górze (<48px), nowe wskakują normalnie; niżej lista stoi.
maintainVisibleContentPosition: { minIndexForVisible: 0, autoscrollToTopThreshold: 48 },
// NIE dodawaj tu z powrotem `maintainVisibleContentPosition`. Byla tu jako anti-jank
// (przy sort=created_at scrapery dosypuja sceny na gore, wiec refetch potrafil szarpnac
// trescia pod palcem), ale w React Native 0.76.9 ta wlasciwosc wywala apke NA AMEN:
// MaintainVisibleScrollPositionHelper.getUIManagerModule() robi assertNotNull i gdy
// ScrollView powstaje w momencie, w ktorym UIManager jest niedostepny, leci
// AssertionError o poziomie fatal. GOON-1S: 53 wystapienia u 35 osob od 2026-07-03,
// wylacznie ten jeden lancuch przyczyn. Skakanie listy jest gorsze niz nic, ale crash
// jest gorszy od skakania. Do rozwazenia ponownie po podniesieniu React Native.
};
}

View file

@ -94,6 +94,9 @@ export function MoviesScreen() {
}),
initialPageParam: 1,
getNextPageParam: (last) => {
// Defensywa: react-query potrafi zawolac to z niepelna strona, gdy fetch padl
// w polowie. Bez tego leci TypeError zamiast zwyklego konca paginacji (GOON-4N).
if (!last) return undefined;
const loaded = last.page * last.per_page;
return loaded < last.total ? last.page + 1 : undefined;
},

View file

@ -100,6 +100,7 @@ export function ScenesScreen({
}),
initialPageParam: 1,
getNextPageParam: (lastPage) => {
if (!lastPage) return undefined;
// Paginuj po has_more (źródło prawdy z fetcha per_page+1). `total` jest dla
// list filtrowanych bounded ("1000+"), więc NIE nadaje się do liczenia stron.
// Fallback na loaded<total gdy stary backend nie zwraca has_more.

View file

@ -73,6 +73,7 @@ export function SiteScenesScreen() {
}),
initialPageParam: 1,
getNextPageParam: (lastPage) => {
if (!lastPage) return undefined;
// Paginuj po has_more (z fetcha per_page+1). `total` bywa bounded ("1000+").
const more =
lastPage.has_more ?? lastPage.page * lastPage.per_page < lastPage.total;

View file

@ -78,6 +78,7 @@ export function StudioMoviesScreen() {
}),
initialPageParam: 1,
getNextPageParam: (last) => {
if (!last) return undefined;
const loaded = last.page * last.per_page;
return loaded < last.total ? last.page + 1 : undefined;
},