Control: tags -1 patch
Please find a debdiff attached.
diff -Nru piperka-client-0.2.2/debian/changelog piperka-client-0.2.2/debian/changelog --- piperka-client-0.2.2/debian/changelog 2019-05-20 21:50:39.000000000 +0200 +++ piperka-client-0.2.2/debian/changelog 2026-04-06 11:34:53.000000000 +0200 @@ -1,3 +1,10 @@ +piperka-client (0.2.2-1.1) unstable; urgency=medium + + * Non-maintainer upload + * Update to Qt6 (Closes: #1132848) + + -- Bastian Germann <[email protected]> Mon, 06 Apr 2026 11:34:53 +0200 + piperka-client (0.2.2-1) unstable; urgency=medium * New upstream version 0.2.2 diff -Nru piperka-client-0.2.2/debian/control piperka-client-0.2.2/debian/control --- piperka-client-0.2.2/debian/control 2019-05-20 21:04:47.000000000 +0200 +++ piperka-client-0.2.2/debian/control 2026-04-06 11:34:53.000000000 +0200 @@ -2,7 +2,7 @@ Section: web Priority: optional Maintainer: Kari Pahula <[email protected]> -Build-Depends: debhelper (>= 11), libqt5webview5-dev +Build-Depends: debhelper (>= 11), qt6-webview-dev Standards-Version: 4.1.3 Homepage: https://piperka.net/ Vcs-Browser: https://gitlab.com/piperka/client @@ -10,7 +10,7 @@ Package: piperka-client Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, qml-module-qtquick-controls, qml-module-qtquick-controls2, qml-module-qtwebview +Depends: ${shlibs:Depends}, ${misc:Depends}, qml6-module-qtquick-controls, qml6-module-qtwebview Description: Mobile oriented web comics reader client Piperka is a web comic tracking and bookmarking service with over 5000 comics listed on it. It doesn't host any web comics by itself diff -Nru piperka-client-0.2.2/debian/patches/Qt-6-compatibility.patch piperka-client-0.2.2/debian/patches/Qt-6-compatibility.patch --- piperka-client-0.2.2/debian/patches/Qt-6-compatibility.patch 1970-01-01 01:00:00.000000000 +0100 +++ piperka-client-0.2.2/debian/patches/Qt-6-compatibility.patch 2026-04-06 11:34:53.000000000 +0200 @@ -0,0 +1,826 @@ +Origin: backport, 5ffcaf9fa2d3f2d755f4485b1e44b3c56c614837 +From: Kari Pahula <[email protected]> +Date: Sat, 29 Oct 2022 13:09:03 +0300 +Subject: Qt 6 compatibility and port 0.3 changes to the generic version +--- +diff --git a/generic/android/AndroidManifest.xml b/generic/android/AndroidManifest.xml +index 2247897..d59c275 100644 +--- a/generic/android/AndroidManifest.xml ++++ b/generic/android/AndroidManifest.xml +@@ -1,5 +1,5 @@ + <?xml version="1.0"?> +-<manifest package="net.piperka.client" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.2.2" android:versionCode="2" android:installLocation="auto"> ++<manifest package="net.piperka.client" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.3.1" android:versionCode="3" android:installLocation="auto"> + <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/> + + <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. +@@ -12,17 +12,15 @@ + + <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> + +- <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Piperka Client" android:icon="@drawable/icon"> ++ <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Piperka Client" android:icon="@drawable/icon" android:usesCleartextTraffic="true"> + <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="Piperka Client" android:screenOrientation="unspecified" android:launchMode="singleTop"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> +- + <!-- Application arguments --> + <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ --> + <!-- Application arguments --> +- + <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> + <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> + <meta-data android:name="android.app.repository" android:value="default"/> +@@ -46,7 +44,6 @@ + <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> + <meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/> + <!-- Messages maps --> +- + <!-- Splash screen --> + <!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation, + then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and +@@ -57,7 +54,6 @@ + <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ --> + <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ --> + <!-- Splash screen --> +- + <!-- Background running --> + <!-- Warning: changing this value to true may cause unexpected crashes if the + application still try to draw after +@@ -65,11 +61,9 @@ + signal is sent! --> + <meta-data android:name="android.app.background_running" android:value="false"/> + <!-- Background running --> +- + <!-- auto screen scale factor --> + <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/> + <!-- auto screen scale factor --> +- + <!-- extract android style --> + <!-- available android:values : + * default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons +@@ -79,10 +73,8 @@ + --> + <meta-data android:name="android.app.extract_android_style" android:value="default"/> + <!-- extract android style --> +- </activity> +- +- <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> +- ++ </activity> ++ <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> + </application> + + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> +diff --git a/generic/isrgrootx1.pem b/generic/isrgrootx1.pem +new file mode 120000 +index 0000000..b1c4d4c +--- /dev/null ++++ b/generic/isrgrootx1.pem +@@ -0,0 +1 @@ ++../harbour/isrgrootx1.pem +\ No newline at end of file +diff --git a/generic/piperka-client.pro b/generic/piperka-client.pro +index ad0844b..5b198cc 100644 +--- a/generic/piperka-client.pro ++++ b/generic/piperka-client.pro +@@ -55,19 +57,36 @@ VERSION = $$system("grep -E '^\*' ../CHANGES | head -n 1 | sed -r 's/^.+ ([0-9.] + + DEFINES += APP_VERSION=\\\"$$VERSION\\\" CLIENT_NAME=\\\"GenericPiperka\\\" + ++RESOURCES += \ ++ resources.qrc ++ + QT += network qml quick webview + + contains(ANDROID_TARGET_ARCH,armeabi-v7a) { + ANDROID_PACKAGE_SOURCE_DIR = \ + $$PWD/android ++ ANDROID_EXTRA_LIBS= \ ++ $$PWD/libs-arm/libcrypto_1_1.so \ ++ $$PWD/libs-arm/libssl_1_1.so + } + + contains(ANDROID_TARGET_ARCH,arm64-v8a) { + ANDROID_PACKAGE_SOURCE_DIR = \ + $$PWD/android ++ ANDROID_EXTRA_LIBS= \ ++ $$PWD/libs-arm64/libcrypto_1_1.so \ ++ $$PWD/libs-arm64/libssl_1_1.so + } + + contains(ANDROID_TARGET_ARCH,x86) { + ANDROID_PACKAGE_SOURCE_DIR = \ + $$PWD/android + } ++ ++contains(ANDROID_TARGET_ARCH,x86_64) { ++ ANDROID_PACKAGE_SOURCE_DIR = \ ++ $$PWD/android ++ ANDROID_EXTRA_LIBS= \ ++ $$PWD/libs-x86_64/libcrypto_1_1.so \ ++ $$PWD/libs-x86_64/libssl_1_1.so ++} +diff --git a/generic/qml/LoginPage.qml b/generic/qml/LoginPage.qml +index d337cd3..6b1d1c6 100644 +--- a/generic/qml/LoginPage.qml ++++ b/generic/qml/LoginPage.qml +@@ -17,7 +17,7 @@ + ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + **************************************************************************/ + +-import QtQuick 2.9 ++import QtQuick 2.15 + import QtQuick.Controls 2.4 + + Item { +@@ -44,7 +44,7 @@ Item { + id: back + text: "<" + onClicked: pageStack.pop() +- visible: platform.explicitBackButtons ++ visible: platform ? true : platform.explicitBackButtons + } + + Text { +@@ -59,8 +59,8 @@ Item { + width: parent.width + inputMethodHints: Qt.ImhNoAutoUppercase + placeholderText: qsTr("User name") +- text: user.storedLoginName +- validator: RegExpValidator { regExp: /.{2,}/ } ++ text: user ? user.storedLoginName : "" ++ validator: RegularExpressionValidator { regularExpression: /.{2,}/ } + onAccepted: passwordField.focus = true + } + +@@ -69,7 +69,7 @@ Item { + echoMode: TextInput.Password + width: parent.width + placeholderText: qsTr("Password") +- validator: RegExpValidator { regExp: /.{2,}/ } ++ validator: RegularExpressionValidator { regularExpression: /.{2,}/ } + onAccepted: dialog.login() + } + +@@ -77,18 +77,18 @@ Item { + id: rememberField + text: qsTr("Remember me") + width: parent.width +- checked: user.rememberMe ++ checked: user && user.rememberMe + } + + CheckBox { + id: importBookmarks + width: parent.width + text: qsTr("Import bookmarks") +- visible: user.localBookmarks() ++ visible: user && user.localBookmarks() + } + + Text { +- visible: user.localBookmarks() ++ visible: user && user.localBookmarks() + text: qsTr("Importing bookmarks will overwrite the ones on server. Not importing will discard local bookmarks.") + } + +diff --git a/generic/qml/MainPage.qml b/generic/qml/MainPage.qml +index 838a423..4d36817 100644 +--- a/generic/qml/MainPage.qml ++++ b/generic/qml/MainPage.qml +@@ -17,7 +17,7 @@ + ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + **************************************************************************/ + +-import QtQuick 2.9 ++import QtQuick 2.15 + import QtQuick.Controls 2.4 + + ApplicationWindow +@@ -25,34 +25,36 @@ ApplicationWindow + id: appWindow + visible: true + title: "Piperka" ++ width: appWindow.width ++ height: appWindow.height + + BusyIndicator { + id: busy + anchors.centerIn: parent +- running: user.loading || updatesModel.subscriptionFlag ++ running: !user || user.loading || !updatesModel || updatesModel.subscriptionFlag + } + + Connections { + target: user + +- onLoginFailed: { ++ function onLoginFailed() { + pageStack.push(Qt.resolvedUrl("LoginPage.qml")) + } + +- onCreateAccountNameReserved: { ++ function onCreateAccountNameReserved() { + pageStack.push(Qt.resolvedUrl("NewAccountPage.qml")) + } + +- onNetworkError: { ++ function onNetworkError() { + pageStack.push(Qt.resolvedUrl("NetworkErrorPage.qml")) + } + +- onForceLogout: { ++ function onForceLogout() { + pageStack.push(Qt.resolvedUrl("ForceLogout.qml")) + } + +- onSilentSyncFailureChanged: { +- syncFailedLabel.text = user.silentSyncFailure == 1 ? ++ function onSilentSyncFailureChanged() { ++ syncFailedLabel.text = user.silentSyncFailure === 1 ? + qsTr("The last scheduled sync failed. The client will retry hourly.") : + user.silentSyncFailure > 1 ? + qsTr("Last %L1 scheduled syncs failed. The client will retry hourly.").arg(user.silentSyncFailure) : ""; +@@ -64,15 +66,18 @@ ApplicationWindow + StackView { + id: pageStack + initialItem: mainFlickable ++ anchors.fill: parent + + focus: true + Keys.onBackPressed: pop() + +- Flickable { ++ ListView { + id: mainFlickable + contentWidth: parent.width +- contentHeight: mainColumn.height +- Column { ++ //anchors.bottom: parent.bottom ++ contentHeight: appWindow.height ++ model: scheduleModel ++ header: Column { + id: mainColumn + width: appWindow.width + spacing: 5 +@@ -83,7 +88,7 @@ ApplicationWindow + anchors.right: parent.right + Connections { + target: user +- onLoggedChange: { ++ function onLoggedChange() { + if (user.name) { + header.text = user.name + " — Piperka" + } else { +@@ -105,20 +110,20 @@ ApplicationWindow + } + + Button { +- visible: !user.logged ++ visible: user && !user.logged + id: loginButton + text: qsTr("Login") + onClicked: pageStack.push(Qt.resolvedUrl("LoginPage.qml")) + } + + Button { +- visible: !user.logged ++ visible: user && !user.logged + text: qsTr("Create account") + onClicked: pageStack.push(Qt.resolvedUrl("NewAccountPage.qml")) + } + + Button { +- visible: user.logged ++ visible: user && user.logged + text: qsTr("Logout") + onClicked: logoutPopup.open() + } +@@ -126,7 +131,7 @@ ApplicationWindow + + + Button { +- enabled: !user.loading ++ enabled: user && !user.loading + anchors { + left: parent.left + right: parent.right +@@ -144,7 +149,7 @@ ApplicationWindow + right: parent.right + } + +- text: qsTr("Recommendations") + ((user.recSubscriptions && user.logged) ? "" : " *") ++ text: qsTr("Recommendations") + ((user && user.recSubscriptions && user.logged) ? "" : " *") + onClicked: { + if (user.recSubscriptions && user.logged) + pageStack.push(Qt.resolvedUrl("RecommendPage.qml")) +@@ -154,21 +159,21 @@ ApplicationWindow + } + + Button { +- enabled: !updatesModel.noUnread && !user.loading ++ enabled: updatesModel && !updatesModel.noUnread && !user.loading + anchors { + left: parent.left + right: parent.right + } + + text: qsTr("Updates")+ +- (!updatesModel.noUnread ? ++ (updatesModel && !updatesModel.noUnread ? + (" ("+updatesModel.unreadPages+" / "+updatesModel.rowCount()+")") : "") + + onClicked: pageStack.push(Qt.resolvedUrl("UpdatesPage.qml")) + } + + Button { +- enabled: !updatesModel.noUnread && !user.loading ++ enabled: updatesModel && !updatesModel.noUnread && !user.loading + anchors { + left: parent.left + right: parent.right +@@ -180,6 +185,7 @@ ApplicationWindow + pageModel.loadComic(updatesModel.firstCid()); + pageModel.autoBookmark = true; + pageModel.autoSwitch = true; ++ pageModel.quickLoad = true; + pageStack.push(Qt.resolvedUrl("ReaderPage.qml")) + } + } +@@ -187,10 +193,11 @@ ApplicationWindow + Label { + width: parent.width + wrapMode: Text.WordWrap +- text: user.noSubscriptions ? ++ text: user && user.noSubscriptions ? + qsTr("Select comics to read from the browse comics page.") : + qsTr("You have no unread comics. Wait for updates or subscribe to more comics.") +- visible: updatesModel.noUnread ++ visible: updatesModel ++ && updatesModel.noUnread + && !updatesModel.subscriptionFlag + && !user.loading + } +@@ -200,7 +207,45 @@ ApplicationWindow + width: parent.width + wrapMode: Text.WordWrap + text: "" +- visible: user.silentSyncFailure > 0 ++ visible: user && user.silentSyncFailure > 0 ++ } ++ ++ Item { ++ height: 10 ++ width: parent.width ++ } ++ ++ Label { ++ id: scheduleLabel ++ visible: scheduleModel && !scheduleModel.noSchedule ++ width: parent.width ++ x: 10 ++ text: qsTr("Expected updates") ++ font.pixelSize: 15 ++ } ++ Item { ++ height: 5 ++ width: parent.width ++ } ++ } ++ ++ delegate: Item { ++ visible: user.silentSyncFailure === 0 ++ height: projected.height+10 ++ Label { ++ id: projected ++ x: 5 ++ anchors.verticalCenter: parent.verticalCenter ++ text: projected_update+"h" ++ } ++ ++ Label { ++ text: title ++ anchors { ++ left: projected.right ++ leftMargin: 10 ++ verticalCenter: parent.verticalCenter ++ } + } + } + } +@@ -270,9 +315,9 @@ ApplicationWindow + } + + Button { +- text: user.syncAvailable ? qsTr("Synchronize now") : qsTr("Please wait") ++ text: user && user.syncAvailable ? qsTr("Synchronize now") : qsTr("Please wait") + onClicked: user.syncNow(true); +- enabled: user.syncAvailable && !user.loading ++ enabled: user && user.syncAvailable && !user.loading + } + } + } +diff --git a/generic/qml/NewAccountPage.qml b/generic/qml/NewAccountPage.qml +index aeae745..1b76a7f 100644 +--- a/generic/qml/NewAccountPage.qml ++++ b/generic/qml/NewAccountPage.qml +@@ -17,7 +17,7 @@ + ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + **************************************************************************/ + +-import QtQuick 2.9 ++import QtQuick 2.15 + import QtQuick.Controls 2.4 + import net.piperka 0.1 + +@@ -65,7 +65,7 @@ Item { + width: parent.width + inputMethodHints: Qt.ImhNoAutoUppercase + placeholderText: qsTr("User name") +- validator: RegExpValidator { regExp: /^.{2,}/ } ++ validator: RegularExpressionValidator { regularExpression: /.{2,}/ } + onAccepted: emailField.focus = true + } + +@@ -82,7 +82,7 @@ Item { + id: passwordField + width: parent.width + placeholderText: qsTr("Password") +- validator: RegExpValidator { regExp: /^.{4,}/ } ++ validator: RegularExpressionValidator { regularExpression: /.{4,}/ } + objectName: "newAccountPassword" + text: user.storedCreatePassword + onAccepted: passwordFieldAgain.focus = true +diff --git a/generic/qml/PageDetailPage.qml b/generic/qml/PageDetailPage.qml +index 09b9c67..642cfea 100644 +--- a/generic/qml/PageDetailPage.qml ++++ b/generic/qml/PageDetailPage.qml +@@ -72,6 +72,16 @@ ListView { + height: 5 + } + ++ Label { ++ width: parent.width ++ text: comicModel.getTitle(pageModel.cid) ++ anchors { ++ left: parent.left ++ leftMargin: 5 ++ right: parent.right ++ } ++ } ++ + Row { + width: parent.width + spacing: 5 +@@ -195,9 +205,9 @@ ListView { + text: qsTr("Set bookmark") + onClicked: { + if (currentMarker) +- user.subscribe(pageModel.cid(), false); ++ user.subscribe(pageModel.cid, false); + else +- user.subscribeAt(pageModel.cid(), ord); ++ user.subscribeAt(pageModel.cid, ord); + } + } + } +diff --git a/generic/qml/ReaderPage.qml b/generic/qml/ReaderPage.qml +index 51d10f6..3986b31 100644 +--- a/generic/qml/ReaderPage.qml ++++ b/generic/qml/ReaderPage.qml +@@ -26,6 +26,7 @@ Item { + id: readerPage + width: appWindow.width + height: appWindow.height ++ property bool isReader: true + + BusyIndicator { + anchors.centerIn: parent +@@ -46,6 +47,16 @@ Item { + visible: !pageModel.allRead + } + ++ Component.onCompleted: { ++ if (pageModel.quickLoad) { ++ titlePeekOpacity.start(); ++ titlePeek.height = 10; ++ ++ titlePeekHideTimer.restart(); ++ pageModel.quickLoad = false; ++ } ++ } ++ + Item { + id: naviRow + anchors { +@@ -54,6 +65,82 @@ Item { + bottom: parent.bottom + } + height: prev.height ++ property bool pressing: false; ++ property int seenCid: -1; ++ property bool usedMark: false; ++ property bool loadingNext: false; ++ ++ Connections { ++ target: user ++ ++ function onLoadingChanged() { ++ if (!user.loading) ++ naviRow.loadingNext = false; ++ } ++ } ++ ++ Item { ++ id: titlePeek ++ anchors { ++ left: parent.left ++ right: next.left ++ bottom: parent.bottom ++ top: parent.top ++ } ++ opacity: 0 ++ ++ Label { ++ text: if (naviRow.pressing) { ++ qsTr("Next")+": "+comicModel.getTitle(pageModel.getNextCid()); ++ } else if (naviRow.usedMark) { ++ qsTr("Bookmark updated"); ++ } else { ++ comicModel.getTitle(pageModel.cid); ++ } ++ ++ anchors { ++ left: parent.left ++ leftMargin: 5 ++ right: parent.right ++ rightMargin: 5 ++ verticalCenter: parent.verticalCenter ++ } ++ ++ elide: Text.ElideRight ++ } ++ ++ NumberAnimation { ++ id: titlePeekOpacity ++ target: titlePeek ++ properties: "opacity" ++ from: 0 ++ to: 1 ++ duration: 500 ++ easing.type: Easing.InOutQuad ++ } ++ ++ NumberAnimation { ++ id: titlePeekOpacityHide ++ target: titlePeek ++ properties: "opacity" ++ from: 1 ++ to: 0 ++ duration: 500 ++ easing.type: Easing.InOutQuad ++ onStopped: { ++ naviRow.usedMark = false; ++ } ++ } ++ ++ Timer { ++ id: titlePeekHideTimer ++ interval: 2500 ++ onTriggered: { ++ titlePeekOpacityHide.start(); ++ } ++ } ++ } ++ + + Button { + anchors.left: parent.left +@@ -61,14 +148,34 @@ Item { + text: "⇐" + enabled: !pageModel.allRead && pageModel.cursor.row > 0 + onClicked: pageModel.setCursor(pageModel.cursor.row-1) ++ opacity: Math.pow(1-titlePeek.opacity, 4) + } + + Button { + anchors.left: prev.right ++ id: mark ++ text: "🔖" ++ enabled: pageModel && pageModel.subscription.row === pageModel.cursor.row ++ visible: pageModel && pageModel.autoBookmark && ++ (pageModel.subscription.row === pageModel.cursor.row ++ || naviRow.loadingNext && pageModel.subscription.row === pageModel.cursor.row-1) ++ onClicked: { ++ naviRow.usedMark = true; ++ naviRow.loadingNext = false; ++ titlePeekOpacity.start(); ++ titlePeekHideTimer.restart(); ++ user.subscribeAt(pageModel.cid, pageModel.cursor.row+1) ++ } ++ opacity: Math.pow(1-titlePeek.opacity,4) ++ } ++ ++ Button { ++ anchors.left: mark.right + id: back + text: "<" + onClicked: pageStack.pop() + visible: platform.explicitBackButtons ++ opacity: Math.pow(1-titlePeek.opacity,4) + } + + Button { +@@ -77,17 +184,19 @@ Item { + right: next.left + } + id: options +- text: (1+pageModel.cursor.row) + "/" + (pageModel.rowCount-1) +- enabled: !pageModel.allRead ++ text: pageModel ? ((1+pageModel.cursor.row) + "/" + (pageModel.rowCount-1)) : "Loading" ++ enabled: pageModel && !pageModel.allRead ++ opacity: Math.pow(1-titlePeek.opacity, 4) + onClicked: pageStack.push(Qt.resolvedUrl("PageDetailPage.qml")) + } + + Button { + anchors.right: parent.right + id: next +- text: pageModel.nextIsSwitch ? "↵" : "⇒" +- enabled: pageModel.haveNext ++ text: pageModel && pageModel.nextIsSwitch ? "↵" : "⇒" ++ enabled: pageModel && pageModel.haveNext + onClicked: { ++ naviRow.usedMark = false; + if (pageModel.nextIsSwitch) { + if (!pageModel.switchNext()) { + var depth = pageStack.depth +@@ -96,9 +205,33 @@ Item { + pageStack.pop(StackView.Immediate) + } + pageStack.push(Qt.resolvedUrl("AllReadPage.qml"), StackView.Immediate); ++ } else if (naviRow.seenCid !== pageModel.cid) { ++ titlePeekOpacity.start(); ++ titlePeekHideTimer.restart(); + } +- } else ++ } else { ++ if (pageModel.autoBookmark) ++ naviRow.loadingNext = true; + pageModel.setCursorNext() ++ } ++ } ++ ++ onPressAndHold: { ++ if (pageModel.nextIsSwitch) { ++ titlePeekHideTimer.stop(); ++ titlePeekOpacity.start(); ++ titlePeek.height = 10; ++ naviRow.pressing = true; ++ naviRow.seenCid = pageModel.getNextCid() ++ } ++ } ++ onReleased: { ++ if (naviRow.pressing) { ++ naviRow.pressing = false; ++ titlePeekOpacity.stop(); ++ titlePeek.opacity = 0; ++ titlePeek.height = 0; ++ } + } + } + } +diff --git a/generic/qml/UpdatesPage.qml b/generic/qml/UpdatesPage.qml +index 86572ce..491aa72 100644 +--- a/generic/qml/UpdatesPage.qml ++++ b/generic/qml/UpdatesPage.qml +@@ -53,13 +53,13 @@ ListView { + id: back + text: "<" + onClicked: pageStack.pop() +- visible: platform.explicitBackButtons ++ visible: !platform || platform.explicitBackButtons + } + + CheckBox { + id: offsetBack + text: qsTr("Offset back by one") +- checked: user.offsetBack ++ checked: user && user.offsetBack + onClicked: user.offsetBack = offsetBack.checked + } + +@@ -81,7 +81,7 @@ ListView { + left: label.right + right: parent.right + } +- currentIndex: updatesModel.sortType ++ currentIndex: updatesModel ? updatesModel.sortType : 1 + model: ListModel { + ListElement { + text: qsTr("Least new pages first") +@@ -94,7 +94,8 @@ ListView { + } + } + onCurrentIndexChanged: { +- updatesModel.sortType = sortType.currentIndex ++ if (updatesModel) ++ updatesModel.sortType = sortType.currentIndex; + } + } + } +diff --git a/generic/resources.qrc b/generic/resources.qrc +new file mode 120000 +index 0000000..2e9e7aa +--- /dev/null ++++ b/generic/resources.qrc +@@ -0,0 +1 @@ ++../harbour/resources.qrc +\ No newline at end of file +diff --git a/generic/src/piperka-client.cpp b/generic/src/piperka-client.cpp +index f2139b7..09ea7f0 100644 +--- a/generic/src/piperka-client.cpp ++++ b/generic/src/piperka-client.cpp +@@ -20,6 +20,7 @@ + #include <QtGui/QGuiApplication> + #include <QtQml/QQmlContext> + #include <QtQuick/QQuickView> ++#include <QtWebView/QtWebView> + #include <QCommandLineParser> + #include <QQmlApplicationEngine> + +@@ -30,7 +31,7 @@ int main(int argc, char *argv[]) + { + QCoreApplication::setOrganizationName("piperka.net"); + QCoreApplication::setApplicationName("piperka-client"); +- QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); ++ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + QGuiApplication app(argc, argv); + QCoreApplication::setApplicationName("piperka-client"); + QCoreApplication::setApplicationVersion(APP_VERSION); +diff --git a/src/updates.cpp b/src/updates.cpp +index 7355e52..0567538 100644 +--- a/src/updates.cpp ++++ b/src/updates.cpp +@@ -128,7 +128,7 @@ bool UpdatesModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourcePare + { + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + QVariant unread = sourceModel()->data(index, ComicModel::UnreadCountRole); +- return unread.isValid() && unread > 0; ++ return unread.isValid() && unread.toInt() > 0; + } + + bool UpdatesModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const +diff --git a/src/user.cpp b/src/user.cpp +index 228c8a5..4ff101f 100644 +--- a/src/user.cpp ++++ b/src/user.cpp +@@ -266,7 +266,7 @@ void User::resetStoredAccountDetails() + + void User::syncNow(bool interactive) + { +- lastSync.start(); ++ lastSync = QTime::currentTime(); + if (interactive && m_syncAvailable) { + m_syncAvailable = false; + syncAvailableTimer.start(interactiveSyncInterval); +@@ -286,7 +286,7 @@ void User::syncNow(bool interactive) + + void User::unlockSync() + { +- if (lastSync.elapsed() > unlockSyncInterval) ++ if (QTime::currentTime().msecsTo(lastSync) > unlockSyncInterval) + syncNow(false); + } + +diff --git a/src/download.cpp b/src/download.cpp +index 086eeb5..68075ab 100644 +--- a/src/download.cpp ++++ b/src/download.cpp +@@ -46,11 +46,11 @@ void addBookmarksToPostData(QByteArray &postData, const QMap<int, int> &bm) + for (QMap<int, int>::const_iterator iter = bm.cbegin(); iter != bm.cend(); ++iter) { + postData.append("&bm="); + if (iter.value() == -1) +- postData.append(QString::number(iter.key())); ++ postData.append(QString::number(iter.key()).toLatin1()); + else +- postData.append(QString::number(iter.key())) ++ postData.append(QString::number(iter.key()).toLatin1()) + .append('+') +- .append(QString::number(iter.value())); ++ .append(QString::number(iter.value()).toLatin1()); + } + + } +@@ -65,7 +65,7 @@ Download::Download(QObject *parent) + #endif + userAgent + .append(" (") +- .append(QSysInfo::prettyProductName()) ++ .append(QSysInfo::prettyProductName().toUtf8()) + .append(")"); + } + diff -Nru piperka-client-0.2.2/debian/patches/qt6.patch piperka-client-0.2.2/debian/patches/qt6.patch --- piperka-client-0.2.2/debian/patches/qt6.patch 1970-01-01 01:00:00.000000000 +0100 +++ piperka-client-0.2.2/debian/patches/qt6.patch 2026-04-06 11:34:53.000000000 +0200 @@ -0,0 +1,169 @@ +Origin: https://gitlab.com/piperka/client/-/merge_requests/3 +From: Bastian Germann <[email protected]> +Date: Mon, 6 Apr 2026 11:31:36 +0200 +Subject: Port project to Qt6 across generic and Sailfish targets + +- migrate Sailfish packaging metadata from Qt5 to Qt6 + (qtc6 builder, Qt6Core/Qml/Quick, sailfishsilica-qt6) +- update spec macros/install steps to qmake6 equivalents +- switch Harbour reader page from QtWebKit/SilicaWebView to QtWebView +- add Qt module declarations for harbour build (including webview) +- make optional android OpenSSL .pri include conditional in generic .pro +- replace deprecated foreach usage with range-based for loops in C++ +--- +diff --git a/harbour/qml/pages/ReaderPage.qml b/harbour/qml/pages/ReaderPage.qml +index 52aa74f..866e3db 100644 +--- a/harbour/qml/pages/ReaderPage.qml ++++ b/harbour/qml/pages/ReaderPage.qml +@@ -18,7 +18,7 @@ + + import QtQuick 2.2 + import Sailfish.Silica 1.0 +-import QtWebKit 3.0 ++import QtWebView 1.1 + + Page { + id: readerPage +@@ -31,7 +31,7 @@ Page { + running: user.loading + } + +- SilicaWebView { ++ WebView { + id: webView + + anchors { +diff --git a/harbour/rpm/harbour-piperka.spec b/harbour/rpm/harbour-piperka.spec +index 4d4b71c..f6a4f1e 100644 +--- a/harbour/rpm/harbour-piperka.spec ++++ b/harbour/rpm/harbour-piperka.spec +@@ -9,7 +9,7 @@ Name: harbour-piperka + # << macros + + %{!?qtc_qmake:%define qtc_qmake %qmake} +-%{!?qtc_qmake5:%define qtc_qmake5 %qmake5} ++%{!?qtc_qmake6:%define qtc_qmake6 %qmake6} + %{!?qtc_make:%define qtc_make make} + %{?qtc_builddir:%define _builddir %qtc_builddir} + Summary: Piperka Client +@@ -20,11 +20,11 @@ License: LICENSE + URL: https://piperka.net/ + Source0: %{name}-%{version}.tar.bz2 + Source100: harbour-piperka.yaml +-Requires: sailfishsilica-qt5 >= 0.10.9 ++Requires: sailfishsilica-qt6 >= 0.10.9 + BuildRequires: pkgconfig(sailfishapp) >= 1.0.2 +-BuildRequires: pkgconfig(Qt5Core) +-BuildRequires: pkgconfig(Qt5Qml) +-BuildRequires: pkgconfig(Qt5Quick) ++BuildRequires: pkgconfig(Qt6Core) ++BuildRequires: pkgconfig(Qt6Qml) ++BuildRequires: pkgconfig(Qt6Quick) + BuildRequires: desktop-file-utils + + %description +@@ -41,7 +41,7 @@ Piperka Client app — Read web comics and follow their updates + # >> build pre + # << build pre + +-%qtc_qmake5 \ ++%qtc_qmake6 \ + VERSION=%{version} \ + RELEASE=%{release} + +@@ -54,7 +54,7 @@ Piperka Client app — Read web comics and follow their updates + rm -rf %{buildroot} + # >> install pre + # << install pre +-%qmake5_install ++%qmake6_install + + # >> install post + # << install post +diff --git a/harbour/rpm/harbour-piperka.yaml b/harbour/rpm/harbour-piperka.yaml +index 0e0a551..d3ee531 100644 +--- a/harbour/rpm/harbour-piperka.yaml ++++ b/harbour/rpm/harbour-piperka.yaml +@@ -14,9 +14,9 @@ Sources: + Description: | + Piperka Client app — Read web comics and follow their updates + Configure: none +-# The qtc5 builder inserts macros to allow QtCreator to have fine ++# The qtc6 builder inserts macros to allow QtCreator to have fine + # control over qmake/make execution +-Builder: qtc5 ++Builder: qtc6 + QMakeOptions: + - VERSION=%{version} + - RELEASE=%{release} +@@ -25,9 +25,9 @@ QMakeOptions: + # This is the preferred way of specifying build dependencies for your package. + PkgConfigBR: + - sailfishapp >= 1.0.2 +- - Qt5Core +- - Qt5Qml +- - Qt5Quick ++ - Qt6Core ++ - Qt6Qml ++ - Qt6Quick + + # Build dependencies without a pkgconfig setup can be listed here + # PkgBR: +@@ -35,7 +35,7 @@ PkgConfigBR: + + # Runtime dependencies which are not automatically detected + Requires: +- - sailfishsilica-qt5 >= 0.10.9 ++ - sailfishsilica-qt6 >= 0.10.9 + + # All installed files + Files: +diff --git a/src/comic.cpp b/src/comic.cpp +index 1637549..89fe8f6 100644 +--- a/src/comic.cpp ++++ b/src/comic.cpp +@@ -162,11 +162,11 @@ void ComicModel::finishComicsListSync() + { + if (!loadPending && !syncPending) { + if (toAdd.empty()) { +- foreach(QPointer<Subscription> subs, pendingSubscriptions.values()) { ++ for (const QPointer<Subscription> &subs : pendingSubscriptions.values()) { + setSubscription(subs); + } + } else { +- foreach(QPointer<Subscription> subs, pendingSubscriptionRefresh) { ++ for (const QPointer<Subscription> &subs : pendingSubscriptionRefresh) { + pendingSubscriptions.insert(subs->cid(), subs); + } + +diff --git a/src/user.cpp b/src/user.cpp +index 4aa22f4..7ce8f5c 100644 +--- a/src/user.cpp ++++ b/src/user.cpp +@@ -440,7 +440,7 @@ void User::deleteSubscriptions() + { + subs_set.clear(); + QList<Subscription *> subs = findChildren<Subscription *>(); +- foreach(Subscription *sub, subs) { ++ for (Subscription *sub : subs) { + emit sub->unsubscribing(); + sub->deleteLater(); + } +@@ -494,7 +494,7 @@ void User::fetchSubscriptions() + if (reply->error() != QNetworkReply::NoError) { + // Emit all old subscriptions for comic model + QList<Subscription *> subs = findChildren<Subscription *>(); +- foreach(Subscription *sub, subs) { ++ for (Subscription *sub : subs) { + emit refreshSubscription(QPointer<Subscription>(sub)); + } + emit fetchSubscriptionsEnd(); +@@ -528,7 +528,7 @@ void User::fetchSubscriptions() + addSubscription(array); + } + } +- foreach(int cid, oldSubsCids) { ++ for (int cid : oldSubsCids) { + Subscription *subs = subs_set.take(cid); + if (subs) { + emit subs->unsubscribing(); diff -Nru piperka-client-0.2.2/debian/patches/series piperka-client-0.2.2/debian/patches/series --- piperka-client-0.2.2/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ piperka-client-0.2.2/debian/patches/series 2026-04-06 11:34:53.000000000 +0200 @@ -0,0 +1,2 @@ +Qt-6-compatibility.patch +qt6.patch diff -Nru piperka-client-0.2.2/debian/rules piperka-client-0.2.2/debian/rules --- piperka-client-0.2.2/debian/rules 2019-05-20 21:18:14.000000000 +0200 +++ piperka-client-0.2.2/debian/rules 2026-04-06 11:34:53.000000000 +0200 @@ -1,9 +1,9 @@ #!/usr/bin/make -f -export QT_SELECT=qt5 +export QT_SELECT=qt6 %: - dh $@ --buildsystem=qmake --sourcedirectory=generic + dh $@ --buildsystem=qmake6 --sourcedirectory=generic override_dh_install: dh_install

