Name: harbour-calibreweb Summary: Client OPDS per Calibre Web Version: 0.4.12 Release: 1 Group: Qt/Qt License: MIT URL: https://github.com/kaneda/harbour-calibreweb Source0: %{name}-%{version}.tar.gz Source1: %{name}.desktop Requires: sailfishsilica-qt5 >= 0.10.9 BuildRequires: pkgconfig(sailfishapp) >= 1.0.2 BuildRequires: pkgconfig(Qt5Core) BuildRequires: pkgconfig(Qt5Qml) BuildRequires: pkgconfig(Qt5Quick) BuildRequires: desktop-file-utils %description Client per navigare e scaricare libri da un'istanza Calibre Web (o dal Content Server di Calibre) tramite il protocollo OPDS. Supporta autenticazione di base, ricerca, copertine, download in tutti i formati disponibili e lettura EPUB integrata con reflow del testo, margini configurabili e posizione salvata in locale. %changelog * Mon Sep 07 2026 Carlo Baratto - 0.4.12-1 - Default margine verticale lettore 24 (era 0): il testo arrivava a filo dei bordi alto/basso su config senza valore o migrate dalle build vecchie (la migrazione non scrive piu' chiavi margine spurie a 0) - MarginDialog coerente: slider "Top and bottom" parte da 24 * Fri Aug 21 2026 Carlo Baratto - 0.4.11-1 - Rimossi gli slider margini dalle Impostazioni: i margini si regolano solo dal lettore (Margini del testo nel PullDownMenu) - Margini alto/basso STRUTTURALI: la finestra di lettura vive dentro i margini (top/bottom margin del Flickable): il testo non puo' uscire dai bordi e i margini sono identici su ogni pagina (via le fasce colorate della 0.4.9/0.4.10) * Fri Aug 21 2026 Carlo Baratto - 0.4.10-1 - Fix margini lettore (0.4.9): sfondo di lettura UNIFORME nel lettore (colore pieno per tema, niente gradiente di sistema). Le fasce dei margini usano lo stesso identico colore dello sfondo: margine visibile su ogni pagina, senza bande stonate e senza effetto "fascia che copre il testo" * Fri Aug 21 2026 Carlo Baratto - 0.4.9-1 - Margini verticali su OGNI schermata del lettore (non solo a inizio capitolo): due fasce opache (colore di sfondo) sopra e sotto la viewport coprono il testo a cavallo dei bordi; il padding inferiore del contenitore include il deficit dell'ultima pagina, cosi' max-scroll e' un multiplo esatto del passo e l'ultima pagina non ripete righe della penultima. Anteprima live dal dialog margini inclusa * Fri Aug 21 2026 Carlo Baratto - 0.4.8-1 - Best practice audit: orientazioni per pagina (finestra senza vincoli, il lettore ora ruota davvero in landscape; pagine di lista in portrait; rimossa la proprieta' privata _defaultPageOrientations) - Licenza MIT installata nel pacchetto (/usr/share/licenses/harbour-calibreweb) - EPUB: lunghezze testo LAZY per capitolo (l'apertura non parse piu' tutto il libro: niente freeze sui libri grossi; cache al primo accesso) - Cover dinamica: con un libro aperto mostra titolo e posizione di lettura (ReaderState esposto come context property, aggiornato dal ReaderPage) - Impostazioni: niente sync su disco a ogni tasto nei campi di testo (flush() all'uscita della pagina e prima del test connessione) - Pulizia: rimossa proprieta' morta chapterFraction, commenti obsoleti aggiornati (settings.h, .pro) * Fri Aug 21 2026 Carlo Baratto - 0.4.7-1 - Fix margini lettore: il passo di pagina era la viewport intera, quindi il testo scorreva a filo dei bordi e i margini verticali si vedevano solo all'inizio del capitolo. Ora il passo e' viewport - 2*margine verticale: ogni pagina mostra il testo DENTRO i margini (prima riga e ultima riga distanziate dai bordi), anche l'ultima pagina del capitolo * Fri Aug 21 2026 Carlo Baratto - 0.4.6-1 - Fix impostazioni lettore non salvate: la scala del font era una proprieta' QML di pagina (mai persistita) -> l'ingrandimento spariva alla chiusura del libro. Aggiunta readerFontScale in QSettings (default 1.0): il lettore parte dalla scala salvata e la persiste a ogni cambio A-/A+. Margini gia' persistiti (verificati con test su disco) * Fri Aug 21 2026 Carlo Baratto - 0.4.5-1 - Fix ingrandimento testo: il restore dopo il reflow usava la frazione di scroll (instabile col cambio font) e il timer di 80ms poteva scattare prima del ricalcolo rich text -> posizione persa e ingrandimenti che sembravano bloccarsi. Ora il restore usa l'offset in CARATTERI (stabile col reflow), il reflow applica via onContentHeightChanged, il timer di sicurezza e' passato a 500ms; limite font portato a 3.5x e passo a 0.1 (molti piu' ingrandimenti prima del limite) * Fri Aug 21 2026 Carlo Baratto - 0.4.4-1 - LETTORE A PAGINE RIGIDE: eliminato del tutto lo scroll libero. Struttura a due livelli: SilicaFlickable esterno NON scrollabile (contentHeight=height, solo per i pulley menu) + Flickable interno interactive:false (il dito non lo muove MAI, contentY cambia solo col tap). Rimossi snap/preventStealing/ onClosed/active: niente piu' compromessi tra scroll e menu, i pulley funzionano sempre e il testo non si sposta mai col dito * Fri Aug 21 2026 Carlo Baratto - 0.4.3-1 - FIX "Impossibile caricare la pagina": rimossi onClosed sui pulley menu e la guardia menu.active (API non disponibili su questa versione di Silica: errore di compilazione QML -> pagina non caricata). Lo snap ora usa solo API sicure: readerFlick.dragging + menu.open (proprieta' standard); il timer si riavvia durante le animazioni dei menu, quindi lo snap scatta solo a tutto fermo e i menu restano aperti * Fri Aug 21 2026 Carlo Baratto - 0.4.2-1 - Fix PushUpMenu che si richiudeva da solo: lo snap usava la guardia menu.open (vera solo a menu aperto), ma durante l'apertura il pulley sposta il contenuto e lo snap scattava nel mezzo -> il menu si annullava. Ora la guardia e' menu.active (vera anche durante il trascinamento); dopo la chiusura del menu (onClosed) lo snap riallinea il contenuto se serve * Fri Aug 21 2026 Carlo Baratto - 0.4.1-1 - Fix scroll libero e pulley menu: rimosso preventStealing dalla MouseArea (ruba il gesto al PushUpMenu appena il dito entra nella zona centrale). Lo scroll libero e' ora neutralizzato dallo SNAP alle pagine: dopo ogni movimento il contenuto torna alla pagina piu' vicina (soglia 70%, zona finale parziale -> fondo), i menu pulley funzionano normalmente * Fri Aug 21 2026 Carlo Baratto - 0.4.0-1 - LETTORE RIFATTO senza WebView: i capitoli sono rich text Qt in un Text QML dentro un SilicaFlickable. Lo scroll (contentY/contentHeight) e' nativo QML e sempre affidabile: sul WebView di Sailfish lo scroll programmatico non funziona (window.scrollY stale, contentHeight/scrollPosition non scrivibili) e il cambio capitolo non scattava mai (regressioni 0.3.x) - Paginazione a tap su contentY: avanti/indietro di una viewport, cambio capitolo deterministico (fine = contentY >= contentHeight - height) - Bookmark v2 invariato (posizione per carattere, stimata dalla frazione di scroll: stabile col reflow del font); migrazione v1 invariata - HTML->rich text in C++: tag di base (p, h1-h6, b/i/u/s, liste, tabelle, blockquote), entita' HTML comuni decodificate, script/style/head/immagini saltati, fallback per HTML malformato - NOTA: il lettore non mostra piu' le immagini inline dei capitoli (limite del rich text Qt); niente scroll libero (paginazione a tap, come richiesto) * Fri Aug 21 2026 Carlo Baratto - 0.3.4-1 - Fix tap avanti: scrollToCharJs usava window.scrollTo(0, rect.top+scrollY-8) e window.scrollY e' stale sul WebView Sailfish -> il tap oscillava di pochi pixel invece di avanzare. Ora scrollBy relativo (0, rect.top-8): nessuna lettura di scrollY, avanzamento di una pagina esatta * Fri Aug 21 2026 Carlo Baratto - 0.3.3-1 - Paginazione per CONTENUTO: il tap avanza di una pagina di testo (offset in caratteri calcolato sui text node del DOM), la fine del capitolo e' decisa confrontando l'offset con la lunghezza del capitolo nota in C++ — nessuna dipendenza dallo scroll del WebView (window.scrollY non riflette lo scroll reale; contentHeight/scrollPosition nativi non scrivibili su Qt 5.6) - Impostazioni: numero di versione in fondo alla pagina (label "Version") - Fix definitivo del cambio capitolo avanti/indietro * Fri Aug 21 2026 Carlo Baratto - 0.3.2-1 - Fix definitivo cambio capitolo: la navigazione non usa piu' window.scrollY/ scrollBy via runJavaScript (lo scroll reale del WebView Sailfish non e' sempre riflesso in window.scrollY: la posizione non arrivava mai a fine documento e il cambio capitolo non scattava). Ora paginazione con le proprieta' NATIVE del WebView (contentHeight/scrollPosition): aritmetica QML pura, affidabile * Fri Aug 21 2026 Carlo Baratto - 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 - 0.3.0-1 - Lettore: bookmark per POSIZIONE (numero di carattere, chiave cw:v2:) invece di capitolo+frazione: la posizione è stabile cambiando font e margini; le vecchie chiavi cw:v1 vengono migrate automaticamente al primo avvio - Lettore: paginazione a tap corretta quando il CSS del libro blocca lo scroll (height:100%/overflow:hidden): stile iniettato con height:auto+overflow:visible e sblocco JS dei contenitori nascosti — prima ogni tap saltava al capitolo successivo perdendo tutto il testo del capitolo - Lettore: prevPage dall'inizio del capitolo torna all'ULTIMA pagina del capitolo precedente (prima ripartiva dall'inizio saltando la coda del testo) - Lettore: cambio font A-/A+ mantiene la posizione di lettura (ripristino per carattere dopo il reflow) - Lettore: label del menu con pagina corrente/totale del capitolo; avanzamento calcolato su documentElement E body (libri che scrollano il body) - Parser EPUB: lunghezze testo per capitolo (text node del DOM) per la mappatura offset assoluto -> capitolo - Test: harness C++ locale (Qt) + test JS con DOM mock per conteggio caratteri, ripristino e paginazione * Wed Aug 19 2026 Carlo Baratto - 0.2.0-1 - Sandbox SailJail (Sailfish 4.4+/5.x): profilo X-Sailjail esplicito nel desktop file (Internet;Downloads, org harbour/app calibreweb) e config in AppConfigLocation (~/.config/harbour/calibreweb/calibreweb.conf, l'unica zona persistente della sandbox). Senza profilo la sandbox nascondeva ~/.config/harbour e le impostazioni dal launcher sparivano (config solo funzionante da SSH). Migrazione automatica dal vecchio file per-utente. - Fix crash 'Close book': pop(null) differito con Timer (distruggere la pagina dall'handler del suo MenuItem crashava) - Config condivisa nemo/defaultuser: permessi aperti su /home/nemo/.config/harbour e sul file a ogni scrittura (il launcher gira come nemo, il debug SSH come defaultuser: prima le impostazioni salvate da un lato sparivano dall'altro) - Selettore lingua nelle impostazioni (System/English/Italiano, applicata al riavvio; QTranslator in main.cpp, pattern quill). Catalogo .qm nel data dir dell'app (/usr/share/harbour-calibreweb/translations, il validatore RPM rifiuta /usr/share/translations) - Localizzazione: lingua di default inglese (qsTr ovunque), catalogo italiano harbour-calibreweb_it.ts/.qm nel data dir dell'app - Fix configurazione persa: file di configurazione unico e fisso (/home/nemo/.config/harbour/calibreweb.conf) indipendente dall'utente che avvia l'app (launcher nemo / debug SSH defaultuser), con migrazione automatica dei valori gia' salvati - Config auto-adattiva: la home grafica su Jolla Phone 2026 (Sailfish 5.1) e' /home/rootitanium (non nemo): candidate rootitanium -> nemo -> home dell'utente corrente, file esistente prima, poi prima home scrivibile; permessi aperti sulla home scelta a ogni scrittura - Lettore EPUB nativo (WebView): capitoli, reflow A-/A+, margini configurabili, posizione salvata in locale (QSettings) e ripristinata all'apertura - Parser EPUB in C++ (ZIP minimale + container/OPF/spine, TOC EPUB2+3) - Rimossa la sync server dell'avanzamento (route web con login di sessione): resta solo il segno locale - URL risolti RFC 3986 (sottopath /calibre non piu raddoppiato), copertine validate prima del cache, pagine corrette per Silica 5.1 - Icone in struttura standard hicolor %prep %setup -q -n %{name}-%{version} %build %qmake5 make %{?_smp_mflags} # Translation catalogue: generated explicitly with lrelease (the sailfishapp_i18n # template does not produce the .qm reliably on the 5.1 kit). The .ts lives in # the source tree; sfdk uses the sources live (shadow build), so locate it # across the possible layouts. if [ -f %{_builddir}/../%{name}-%{version}/translations/%{name}_it.ts ]; then TS=%{_builddir}/../%{name}-%{version}/translations/%{name}_it.ts elif [ -f %{_builddir}/%{name}-%{version}/translations/%{name}_it.ts ]; then TS=%{_builddir}/%{name}-%{version}/translations/%{name}_it.ts elif [ -f %{_builddir}/translations/%{name}_it.ts ]; then TS=%{_builddir}/translations/%{name}_it.ts else echo "ERROR: %{name}_it.ts not found" >&2 exit 1 fi lrelease "$TS" -qm %{_builddir}/%{name}_it.qm %install make install INSTALL_ROOT=%{buildroot} mkdir -p %{buildroot}%{_datadir}/applications install -m 0644 %{SOURCE1} %{buildroot}%{_datadir}/applications/%{name}.desktop desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop || true # Italian translation: installed in the app data dir (the RPM validator # rejects /usr/share/translations); main.cpp loads it from there. mkdir -p %{buildroot}%{_datadir}/%{name}/translations install -m 0644 %{_builddir}/%{name}_it.qm %{buildroot}%{_datadir}/%{name}/translations/ # MIT license: installed in the package (Harbour best practice). mkdir -p %{buildroot}%{_datadir}/licenses/%{name} if [ -f %{_builddir}/../%{name}-%{version}/LICENSE ]; then install -m 0644 %{_builddir}/../%{name}-%{version}/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/ elif [ -f %{_builddir}/%{name}-%{version}/LICENSE ]; then install -m 0644 %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/ elif [ -f %{_builddir}/LICENSE ]; then install -m 0644 %{_builddir}/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/ else echo "ERROR: LICENSE not found" >&2 exit 1 fi %files %defattr(-,root,root,-) %{_bindir}/%{name} %{_datadir}/applications/%{name}.desktop %{_datadir}/icons/hicolor/86x86/apps/%{name}.png %{_datadir}/icons/hicolor/108x108/apps/%{name}.png %{_datadir}/icons/hicolor/128x128/apps/%{name}.png %{_datadir}/icons/hicolor/172x172/apps/%{name}.png %{_datadir}/%{name}/qml %{_datadir}/%{name}/translations/%{name}*.qm %{_datadir}/licenses/%{name}/LICENSE