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() loadChapter()
} }
// pagina successiva: una viewport avanti; all'ultima pagina passa al capitolo // pagina successiva: una viewport avanti. Lo scroll avviene con scrollBy e
// dopo. max è calcolato su documentElement E body (alcuni libri scrollano il body). // 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() { function nextPage() {
if (!web.loaded || !page.ready) if (!web.loaded || !page.ready)
return return
web.runJavaScript( web.runJavaScript(
"(function(){" "(function(){"
+ "var de=document.documentElement,b=document.body;" + "var de=document.documentElement,b=document.body;"
+ "var max=Math.max(de.scrollHeight,b.scrollHeight)-window.innerHeight;" + "var vh=window.innerHeight;"
+ "if(max<=1){" + "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');" + "de.style.setProperty('overflow','visible','important');"
+ "b.style.setProperty('overflow','visible','important');" + "b.style.setProperty('overflow','visible','important');"
+ "de.style.setProperty('height','auto','important');" + "de.style.setProperty('height','auto','important');"
+ "b.style.setProperty('height','auto','important');" + "b.style.setProperty('height','auto','important');"
+ "max=Math.max(de.scrollHeight,b.scrollHeight)-window.innerHeight;}" + "window.scrollBy(0,vh);"
+ "if(max<=1)return JSON.stringify({ok:false,atEnd:true});" + "if(window.scrollY>before+1)"
+ "var vh=window.innerHeight;" + "return JSON.stringify({ok:true,atEnd:false});"
+ "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});}"
+ "return JSON.stringify({ok:false,atEnd:true});})()", + "return JSON.stringify({ok:false,atEnd:true});})()",
function(res) { function(res) {
var r = JSON.parse(res) var r = JSON.parse(res)
@@ -381,19 +384,18 @@ Page {
}) })
} }
// pagina precedente: una viewport indietro; dalla prima pagina torna al // pagina precedente: una viewport indietro; se lo scroll non si muove siamo
// capitolo prima SULL'ULTIMA PAGINA (non salta la coda del capitolo) // all'inizio -> capitolo prima SULL'ULTIMA PAGINA (non salta la coda)
function prevPage() { function prevPage() {
if (!web.loaded || !page.ready) if (!web.loaded || !page.ready)
return return
web.runJavaScript( web.runJavaScript(
"(function(){" "(function(){"
+ "var de=document.documentElement,b=document.body;"
+ "var max=Math.max(de.scrollHeight,b.scrollHeight)-window.innerHeight;"
+ "var vh=window.innerHeight;" + "var vh=window.innerHeight;"
+ "var cur=Math.max(0,Math.min(max,window.scrollY));" + "var before=window.scrollY;"
+ "if(cur>1){window.scrollTo(0,Math.max(0,cur-vh));" + "window.scrollBy(0,-vh);"
+ "return JSON.stringify({ok:true,atStart:false});}" + "if(window.scrollY<before-1)"
+ "return JSON.stringify({ok:true,atStart:false});"
+ "return JSON.stringify({ok:false,atStart:true});})()", + "return JSON.stringify({ok:false,atStart:true});})()",
function(res) { function(res) {
var r = JSON.parse(res) var r = JSON.parse(res)
+8 -1
View File
@@ -1,6 +1,6 @@
Name: harbour-calibreweb Name: harbour-calibreweb
Summary: Client OPDS per Calibre Web Summary: Client OPDS per Calibre Web
Version: 0.3.0 Version: 0.3.1
Release: 1 Release: 1
Group: Qt/Qt Group: Qt/Qt
License: MIT License: MIT
@@ -24,6 +24,13 @@ reflow del testo, margini configurabili e posizione salvata
in locale. in locale.
%changelog %changelog
* Fri Aug 21 2026 Carlo Baratto <carlo@carlobaratto.it> - 0.3.1-1
- Fix passaggio di capitolo: il tap avanti/indietro usava un confronto con max
calcolato (scrollHeight - innerHeight), che sul WebView di Sailfish può essere
sovrastimato: scrollY non raggiungeva mai max e il cambio capitolo non
scattava (si restava dentro il capitolo). Ora lo scroll avviene con scrollBy
e la condizione è "lo scroll si è MOSSO?" — infallibile anche con max errato;
se il documento è bloccato (overflow hidden), unlock CSS e riprova
* Fri Aug 21 2026 Carlo Baratto <carlo@carlobaratto.it> - 0.3.0-1 * Fri Aug 21 2026 Carlo Baratto <carlo@carlobaratto.it> - 0.3.0-1
- Lettore: bookmark per POSIZIONE (numero di carattere, chiave cw:v2:<assoluto>) - Lettore: bookmark per POSIZIONE (numero di carattere, chiave cw:v2:<assoluto>)
invece di capitolo+frazione: la posizione è stabile cambiando font e margini; invece di capitolo+frazione: la posizione è stabile cambiando font e margini;