Lettore 0.3.1: cambio capitolo affidabile con scrollBy

Il confronto con max calcolato (scrollHeight-innerHeight) falliva sul WebView
di Sailfish quando max è sovrastimato: scrollY non lo raggiungeva mai, ok
restava true e atEnd veniva ignorato -> si restava dentro il capitolo.
Ora: scrollBy(0,vh) + verifica 'lo scroll si è mosso'; se bloccato, unlock
CSS e riprova; se ancora fermo -> capitolo successivo (o precedente).
This commit is contained in:
2026-08-21 08:16:25 +02:00
parent fa3f19df75
commit 7bb4aa845a
2 changed files with 28 additions and 19 deletions
+20 -18
View File
@@ -349,27 +349,30 @@ Page {
loadChapter()
}
// pagina successiva: una viewport avanti; all'ultima pagina passa al capitolo
// dopo. max è calcolato su documentElement E body (alcuni libri scrollano il body).
// pagina successiva: una viewport avanti. Lo scroll avviene con scrollBy e
// la verifica è "lo scroll si è MOSSO?" — non un confronto con max calcolato
// (innerHeight/scrollHeight del WebView non sempre corrispondono allo scroll
// reale: con max sovrastimato scrollY non lo raggiungeva mai e il passaggio
// al capitolo successivo non scattava). Se non si muove: unlock CSS e riprova;
// se ancora fermo, siamo a fine capitolo (o capitolo non scrollabile) -> avanti.
function nextPage() {
if (!web.loaded || !page.ready)
return
web.runJavaScript(
"(function(){"
+ "var de=document.documentElement,b=document.body;"
+ "var max=Math.max(de.scrollHeight,b.scrollHeight)-window.innerHeight;"
+ "if(max<=1){"
+ "var vh=window.innerHeight;"
+ "var before=window.scrollY;"
+ "window.scrollBy(0,vh);"
+ "if(window.scrollY>before+1)"
+ "return JSON.stringify({ok:true,atEnd:false});"
+ "de.style.setProperty('overflow','visible','important');"
+ "b.style.setProperty('overflow','visible','important');"
+ "de.style.setProperty('height','auto','important');"
+ "b.style.setProperty('height','auto','important');"
+ "max=Math.max(de.scrollHeight,b.scrollHeight)-window.innerHeight;}"
+ "if(max<=1)return JSON.stringify({ok:false,atEnd:true});"
+ "var vh=window.innerHeight;"
+ "var cur=Math.max(0,Math.min(max,window.scrollY));"
+ "var target=Math.min(max,cur+vh);"
+ "if(target>cur+1){window.scrollTo(0,target);"
+ "return JSON.stringify({ok:true,atEnd:target>=max-1});}"
+ "window.scrollBy(0,vh);"
+ "if(window.scrollY>before+1)"
+ "return JSON.stringify({ok:true,atEnd:false});"
+ "return JSON.stringify({ok:false,atEnd:true});})()",
function(res) {
var r = JSON.parse(res)
@@ -381,19 +384,18 @@ Page {
})
}
// pagina precedente: una viewport indietro; dalla prima pagina torna al
// capitolo prima SULL'ULTIMA PAGINA (non salta la coda del capitolo)
// pagina precedente: una viewport indietro; se lo scroll non si muove siamo
// all'inizio -> capitolo prima SULL'ULTIMA PAGINA (non salta la coda)
function prevPage() {
if (!web.loaded || !page.ready)
return
web.runJavaScript(
"(function(){"
+ "var de=document.documentElement,b=document.body;"
+ "var max=Math.max(de.scrollHeight,b.scrollHeight)-window.innerHeight;"
+ "var vh=window.innerHeight;"
+ "var cur=Math.max(0,Math.min(max,window.scrollY));"
+ "if(cur>1){window.scrollTo(0,Math.max(0,cur-vh));"
+ "return JSON.stringify({ok:true,atStart:false});}"
+ "var before=window.scrollY;"
+ "window.scrollBy(0,-vh);"
+ "if(window.scrollY<before-1)"
+ "return JSON.stringify({ok:true,atStart:false});"
+ "return JSON.stringify({ok:false,atStart:true});})()",
function(res) {
var r = JSON.parse(res)