diff --git a/.gitignore b/.gitignore index dce9578..f3e4def 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -.DS_Store -FeedTheMonkey.pro.user* -build +#Added by cargo + +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..28b8141 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "feedthemonkey" +version = "3.0.0" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f7f7a9d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "feedthemonkey" +version = "3.0.0" +authors = ["Jeena "] +edition = "2018" +readme = "README.md" +repository = "https://github.com/jeena/feedthemonkey" +descrition = "Desktop client for the TinyTinyRSS feed reader" +licese = "GPL-3.0-or-later" +license-file = "COPYING" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/FeedTheMonkey.pro b/FeedTheMonkey.pro deleted file mode 100644 index 91d3739..0000000 --- a/FeedTheMonkey.pro +++ /dev/null @@ -1,66 +0,0 @@ -requires(contains(QT_CONFIG, accessibility)) - -qtHaveModule(widgets) { - QT += widgets # QApplication is required to get native styling with QtQuickControls -} - -TARGET = feedthemonkey - -TEMPLATE = app -QT += qml quick webenginewidgets webengine -CONFIG += c++11 -CONFIG += qtquickcompiler - -SOURCES += \ - src/main.cpp \ - src/post.cpp \ - src/tinytinyrss.cpp \ - src/tinytinyrsslogin.cpp - -RESOURCES += \ - html/html.qrc \ - qml/qml.qrc \ - -mac { - RC_FILE = misc/Icon.icns - TARGET = FeedTheMonkey -} - -unix { - isEmpty(PREFIX) { - PREFIX = /usr/local - } - - target.path = $$PREFIX/bin - - shortcutfiles.files = misc/feedthemonkey.desktop - shortcutfiles.path = $$PREFIX/share/applications/ - data.files += misc/feedthemonkey.xpm - data.path = $$PREFIX/share/pixmaps/ - - INSTALLS += shortcutfiles - INSTALLS += data -} - -INSTALLS += target - - -# Needed for bringing browser from background to foreground using QDesktopServices: http://bugreports.qt-project.org/browse/QTBUG-8336 -TARGET.CAPABILITY += SwEvent - -# Additional import path used to resolve QML modules in Qt Creator's code model -QML_IMPORT_PATH = - -OTHER_FILES += - -HEADERS += \ - src/post.h \ - src/tinytinyrss.h \ - src/tinytinyrsslogin.h - -DISTFILES += \ - misc/feedthemonkey.desktop \ - misc/feedthemonkey.xpm \ - misc/Icon.icns \ - README.md \ - LICENSE.txt diff --git a/README.md b/README.md index 155358a..5454f06 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # FeedTheMonkey Icon @@ -6,17 +7,11 @@ FeedTheMonkey is a desktop client for [TinyTinyRSS](http://tt-rss.org). That mea it doesn't work as a standalone feed reader but only as a client for the TinyTinyRSS API which it uses to get the normalized feeds and to synchronize the "article read" marks. -It is written in C++ with Qt and QML, it also uses Blink to show the contents. You need -to have Qt 5.6 installed to be able to compile and have a account on a TinyTinyRSS server. +It is written in Rust and GTK. You need to have an account on a TinyTinyRSS server. ## Installation -If you run Linux then there is an AppImage on the [Latest release](https://github.com/jeena/FeedTheMonkey/releases/latest) page. You download it, make executable and are able to run, it should work on most of the distributions out there. - -For ArchLinux I package it and it's available on https://aur.archlinux.org/packages/feedthemonkey/ - -You can compile and install it everywhere Qt is suported, this means on macOS, Windows -and Linux. +TBD ## Keyboard shortcuts @@ -33,13 +28,11 @@ The keyboard shortcuts are inspired by other feed readers which are inspired by `Ctrl -` zoom out `Ctrl 0` reset zoom -On macOS use `Cmd` instead of `Ctrl`. - ## Trivia -This is version 2 of FeedTheMonkey, you can find version 1 which was written in PyQt in the v1 branch -of this repo. My goal is to make this usable on many different targets, for now it is only for -the use on a desktop computer but I'd like to see it on a mobile device too. +This is version 3 of FeedTheMonkey, you can find version 1 which was written +in PyQt in the v1 branch of this repo and version 2 which was written in C++ +and Qt/QML in the v2 branch. ## Screenshot @@ -49,7 +42,7 @@ the use on a desktop computer but I'd like to see it on a mobile device too. This file is part of FeedTheMonkey. -Copyright 2015-2017 Jeena +Copyright 2020 Jeena FeedTheMonkey is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/html/html.qrc b/html/html.qrc deleted file mode 100644 index c6cf166..0000000 --- a/html/html.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - content.css - content.html - - diff --git a/misc/misc.qrc b/misc/misc.qrc deleted file mode 100644 index 615a2a0..0000000 --- a/misc/misc.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - feedthemonkey.xpm - Icon.icns - feedthemonkey.desktop - - diff --git a/ports/arch/PKGBUILD b/ports/arch/PKGBUILD deleted file mode 100644 index 07c344b..0000000 --- a/ports/arch/PKGBUILD +++ /dev/null @@ -1,25 +0,0 @@ -# Maintainer: Jeena - -pkgname=feedthemonkey -_name=FeedTheMonkey -pkgver=2.2.0 -pkgrel=1 -pkgdesc="Desktop client for the TinyTinyRSS reader" -arch=('i686' 'x86_64') -url="http://jabs.nu/feedthemonkey" -license=('GPL3') -depends=('qt5-declarative' 'qt5-quick1' 'qt5-quickcontrols' 'qt5-webengine') -source=("https://github.com/jeena/${_name}/archive/v${pkgver}.tar.gz") -md5sums=('SKIP') - -build() { - cd "${_name}-$pkgver" - qmake-qt5 PREFIX=${pkgdir}/usr - make -} - -package() { - cd "${_name}-$pkgver" - make install - install -D -m644 COPYING "${pkgdir}/usr/share/licenses/${pkgname}/COPYING" -} diff --git a/ports/osx/deploy.sh b/ports/osx/deploy.sh deleted file mode 100755 index 369e2ec..0000000 --- a/ports/osx/deploy.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -# The macdeployqt app you get while installing Qt is broken for newer Qt -# versions like 5.4 which we use, we will have to replace it. -# -# Download and compile https://github.com/MaximAlien/macdeployqt do not -# use the .dmg which is too old. Move the new macdeployqt so it is in -# $QTDIR/bin/macdeployqt. -# -# Use fixqtlibspath.sh to fix your Qt installation, you need to change the -# path in this script, you don't have to run the Predator part. -# -# Build FeedTheMonkey.app in QtCreator as Release. - -if [[ "" == "$QTDIR" ]]; then - QTDIR=~/Qt/5.4/clang_64/ -fi - -BUILDDIR=$1 -APPDIR=$BUILDDIR/FeedTheMonkey.app -CONTENTSDIR=$APPDIR/Contents -ABSPATH=$(cd "$(dirname "$0")"; pwd) - -if [[ "" == "$BUILDDIR" ]]; then - echo "Usage: $0 path/to/build/" - exit 1 -fi - -# libexec -mkdir -p $APPDIR/Contents/libexec -cp $QTDIR/libexec/QtWebProcess $CONTENTSDIR/libexec -cat > $CONTENTSDIR/libexec/qt.conf << EOF -[Paths] -Plugins = ../PlugIns -Qml2Imports = ../Imports/qtquick2 -EOF - -# lab settings -mkdir -p $CONTENTSDIR/Imports/qtquick2/Qt/labs -cp -R $QTDIR/qml/Qt/labs/settings $CONTENTSDIR/Imports/qtquick2/Qt/labs -cat > $CONTENTSDIR/Resources/qt.conf << EOF -[Paths] -Plugins = PlugIns -Qml2Imports = Imports/qtquick2 -EOF - -# deploy -$QTDIR/bin/macdeployqt $APPDIR -no-strip -qmldir=$ABSPATH/../../qml -executable=$CONTENTSDIR/libexec/QtWebProcess - -open $BUILDDIR - diff --git a/qml/Content.qml b/qml/Content.qml deleted file mode 100644 index 07440be..0000000 --- a/qml/Content.qml +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -import QtWebEngine 1.8 -import QtQuick 2.0 -import QtQuick.Controls 1.3 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Styles 1.3 -import TTRSS 1.0 - -Item { - id: content - property Post post - property ApplicationWindow app - - property int textFontSize: 14 - property bool nightmode - property int scrollJump: 48 - property int pageJump: parent.height - Layout.minimumWidth: 400 - onTextFontSizeChanged: webView.setDefaults() - onNightmodeChanged: webView.setDefaults() - - function scrollDown(jump) { - if(!jump) { - webView.runJavaScript("window.scrollTo(0, document.body.scrollHeight - " + height + ");") - } else { - webView.runJavaScript("window.scrollBy(0, " + jump + ");") - } - } - - function scrollUp(jump) { - if(!jump) { - webView.runJavaScript("window.scrollTo(0, 0);") - } else { - webView.runJavaScript("window.scrollBy(0, -" + jump + ");") - } - } - - function loggedOut() { - post = null - } - - Label { id: fontLabel } - - WebEngineView { - id: webView - anchors.fill: parent - url: "../html/content.html" - - property Post post: content.post - - function setPost() { - if(post) { - webView.runJavaScript("setArticle(" + post.jsonString + ")") - } else { - webView.runJavaScript("setArticle('logout')") - } - } - - function setDefaults() { - // font name needs to be enclosed in single quotes - // and this is needed for El Capitain because ".SF NS Text" won't work - var defFont = ", system, -apple-system, '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande'"; - var font = "'" + fontLabel.font.family + "'" + defFont; - webView.runJavaScript("document.body.style.fontFamily = \"" + font + "\";"); - webView.runJavaScript("document.body.style.fontSize = '" + content.textFontSize + "pt';"); - webView.runJavaScript("if(typeof setNightmode == \"function\") setNightmode(" + (content.nightmode ? "true" : "false") + ")") - } - - onNavigationRequested: { - if (request.url == "feedthemonkey:previous") { - request.action = WebEngineView.IgnoreRequest; - app.showPreviousPost(); - } else if (request.url == "feedthemonkey:next") { - request.action = WebEngineView.IgnoreRequest; - app.showNextPost(); - } else if (request.url == "feedthemonkey:open") { - request.action = WebEngineView.IgnoreRequest; - Qt.openUrlExternally(post.link) - } else if (request.navigationType !== WebEngineNavigationRequest.LinkClickedNavigation) { - request.action = WebEngineView.AcceptRequest; - } else { - request.action = WebEngineView.IgnoreRequest; - Qt.openUrlExternally(request.url); - } - } - - onLoadingChanged: { - if(!loading) { - setPost() - setDefaults() - } - } - - onPostChanged: setPost() - Keys.onPressed: app.keyPressed(event) - } -} - diff --git a/qml/Login.qml b/qml/Login.qml deleted file mode 100644 index 5948a12..0000000 --- a/qml/Login.qml +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -import QtQuick 2.0 -import QtQuick.Controls 1.2 - -Rectangle { - color: "transparent" - anchors.fill: parent - - property string serverUrl: serverUrl.text - property string userName: userName.text - property string password: password.text - - Column { - anchors.centerIn: parent - width: parent.width / 2 - anchors.margins: parent.width / 4 - spacing: 10 - - Text { - text: qsTr("Please specify a server url, a username and a password.") - wrapMode: Text.WordWrap - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 20 - font.pointSize: 20 - } - - TextField { - id: serverUrl - placeholderText: "http://example.com/ttrss/" - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 20 - validator: RegExpValidator { regExp: /https?:\/\/.+/ } - onAccepted: login() - } - - TextField { - id: userName - placeholderText: qsTr("username") - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 20 - onAccepted: login() - } - - TextField { - id: password - placeholderText: qsTr("password") - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 20 - echoMode: TextInput.Password - onAccepted: login() - } - - Button { - id: loginButton - text: "Ok" - anchors.right: parent.right - anchors.margins: 20 - onClicked: login() - } - } - -} diff --git a/qml/PostListItem.qml b/qml/PostListItem.qml deleted file mode 100644 index 63bf813..0000000 --- a/qml/PostListItem.qml +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -import QtQuick 2.0 -import QtQuick.Controls 1.3 - -Item { - property int textFontSize: 14 - property int smallfontSize: 11 - property bool nightmode - - Component.onCompleted: fixFontSize() - onTextFontSizeChanged: fixFontSize() - - function fixFontSize() { - smallfontSize = textFontSize * 0.8 - } - - id: item - height: d.height + t.height + e.height + 2 - - Item { - anchors.fill: parent - - Item { - anchors.fill: parent - anchors.leftMargin: 15 - anchors.rightMargin: 15 - anchors.topMargin: 10 - anchors.bottomMargin: 10 - - Column { - id: column - width: parent.width - - Item { - width: parent.width - height: d.height - - Label { - text: feedTitle - font.pointSize: smallfontSize - textFormat: Text.PlainText - color: nightmode ? "#888" : "gray" - wrapMode: Text.WrapAnywhere - renderType: Text.NativeRendering - elide: Text.ElideLeft - anchors.top: parent.top - anchors.left: parent.left - anchors.right: d.left - maximumLineCount: 1 - } - Label { - id: d - text: date.toLocaleString(Qt.locale(), Locale.ShortFormat) - font.pointSize: smallfontSize - textFormat: Text.PlainText - color: nightmode ? "#888" : "gray" - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - renderType: Text.NativeRendering - anchors.right: parent.right - anchors.top: parent.top - } - } - Label { - id: t - text: title - color: nightmode ? (read ? "#888" : "#ddd") : (read ? "gray" : "black") - font.pointSize: textFontSize - textFormat: Text.PlainText - wrapMode: Text.WrapAnywhere - renderType: Text.NativeRendering - width: parent.width - elide: Text.ElideRight - maximumLineCount: 1 - - } - Label { - id: e - text: excerpt - font.pointSize: smallfontSize - //textFormat: Text.RichText - color: nightmode ? "#888" : "gray" - wrapMode: Text.WrapAnywhere - renderType: Text.NativeRendering - width: parent.width - elide: Text.ElideRight - maximumLineCount: 1 - } - } - } - - Rectangle { - anchors.top: parent.bottom - width: parent.width - height: 1 - color: nightmode ? "#222" : "lightgray" - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - parent.parent.parent.currentIndex = index - } - } -} diff --git a/qml/Sidebar.qml b/qml/Sidebar.qml deleted file mode 100644 index 84de4cb..0000000 --- a/qml/Sidebar.qml +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -import QtQuick 2.0 -import TTRSS 1.0 -import QtQuick.Controls 1.3 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Styles 1.3 - -ScrollView { - id: item - - property Server server - property Content content - property Post previousPost - property int textFontSize: 14 - property bool nightmode - - style: ScrollViewStyle { - transientScrollBars: true - } - - function next() { - if(listView.count > listView.currentIndex) { - listView.currentIndex++; - } - } - - function previous() { - if(listView.currentIndex > 0) { - listView.currentIndex--; - } - } - - onWidthChanged: { - // Hide sidebar if smaller than 200px wide - if(width < 200) { - width = 0; - } - } - - Rectangle { - width: 1 - color: app.nightmode ? "#111" : "lightgray" - anchors.right: parent.right - anchors.top: parent.top - height: parent.height - } - - ListView { - id: listView - - focus: true - anchors.fill: parent - spacing: 1 - model: item.server.posts - - delegate: Component { - PostListItem { - textFontSize: item.textFontSize - nightmode: app.nightmode - width: listView.width - } - } - - highlightFollowsCurrentItem: false - highlight: Component { - Rectangle { - width: listView.currentItem.width -1 - height: listView.currentItem.height - color: nightmode ? "#15539e" : "lightblue" - y: listView.currentItem.y - } - - } - - onCurrentItemChanged: { - if(previousPost) { - if(!previousPost.dontChangeRead) { - previousPost.read = true; - } else { - previousPost.dontChangeRead = false; - } - } - - item.content.post = server.posts[currentIndex] - previousPost = item.content.post - } - } -} diff --git a/qml/TheMenuBar.qml b/qml/TheMenuBar.qml deleted file mode 100644 index 34c0310..0000000 --- a/qml/TheMenuBar.qml +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -import QtQuick.Controls 1.2 -import QtQuick.Window 2.0 -import QtQuick 2.0 -import TTRSS 1.0 - -MenuBar { - id: menuBar - property bool loggedIn: false - property ServerLogin serverLogin - property Server server - property Sidebar sidebar - property Content content - property bool visible: true - property var oldVisibility - - Menu { - visible: menuBar.visible - title: qsTr("File") - MenuItem { - text: qsTr("Close &Window") - shortcut: "Ctrl+W" - onTriggered: Qt.quit() - } - MenuItem { - text: qsTr("Exit") - shortcut: "Ctrl+Q" - onTriggered: Qt.quit() - } - } - - Menu { - visible: menuBar.visible - title: qsTr("Action") - MenuItem { - text: qsTr("Reload") - shortcut: "R" - enabled: loggedIn - onTriggered: server.reload() - } - MenuItem { - text: qsTr("Set &Unread") - shortcut: "U" - enabled: loggedIn - onTriggered: { - content.post.dontChangeRead = true - content.post.read = false - } - } - MenuItem { - text: qsTr("Next") - shortcut: "J" - enabled: loggedIn - onTriggered: sidebar.next() - } - MenuItem { - text: qsTr("Previous") - shortcut: "K" - enabled: loggedIn - onTriggered: sidebar.previous() - } - MenuItem { - text: qsTr("Open in Browser") - shortcut: "N" - enabled: loggedIn - onTriggered: Qt.openUrlExternally(content.post.link) - } - MenuItem { - text: qsTr("Log Out") - enabled: loggedIn - onTriggered: serverLogin.logout() - } - } - - Menu { - visible: menuBar.visible - title: qsTr("View") - MenuItem { - text: qsTr("Night mode") - shortcut: "1" - onTriggered: app.toggleNightmode() - } - MenuItem { - text: qsTr("Zoom In") - shortcut: "Ctrl++" - enabled: loggedIn - onTriggered: app.zoomIn() - } - MenuItem { - text: qsTr("Zoom Out") - shortcut: "Ctrl+-" - enabled: loggedIn - onTriggered: app.zoomOut() - } - MenuItem { - text: qsTr("Reset") - shortcut: "Ctrl+0" - enabled: loggedIn - onTriggered: app.zoomReset() - } - MenuItem { - text: qsTr("Fullscreen") - shortcut: "F11" - enabled: loggedIn - onTriggered: { - if(app.visibility == Window.FullScreen) { - app.visibility = oldVisibility - } else { - oldVisibility = app.visibility - app.showFullScreen() - } - - } - } - } - - Menu { - visible: menuBar.visible - title: qsTr("Help") - MenuItem { - text: qsTr("About") - onTriggered: Qt.openUrlExternally("http://jeena.net/feedthemonkey/index.html"); - } - } - -} diff --git a/qml/main.qml b/qml/main.qml deleted file mode 100644 index 0b6074b..0000000 --- a/qml/main.qml +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -import QtQuick 2.3 -import QtQuick.Controls 1.3 -import QtQuick.Window 2.0 -import QtQuick.Layouts 1.1 -import QtQuick.Dialogs 1.1 -import Qt.labs.settings 1.0 -import TTRSS 1.0 - -ApplicationWindow { - id: app - title: "FeedTheMonkey" - visible: true - color: nightmode ? "#2d2d2d" : "#eee" - - minimumWidth: 480 - minimumHeight: 320 - - width: 800 - height: 640 - x: 200 - y: 200 - - property Server server: server - property Sidebar sidebar: sidebar - property Content content: content - - property variant fontSizes: [7,9,11,13,15,17,19,21,23,25,27,29,31] - property int defaultTextFontSizeIndex: 3 - property int textFontSizeIndex: defaultTextFontSizeIndex - property int textFontSize: fontSizes[textFontSizeIndex] - property bool nightmode: false - property bool showMenuBar: false - - menuBar: TheMenuBar { - id: menu - serverLogin: serverLogin - server: server - sidebar: sidebar - content: content - visible: app.showMenuBar - __contentItem.visible: visible - } - - Settings { - id: settings - category: "window" - property alias x: app.x - property alias y: app.y - property alias width: app.width - property alias height: app.height - property alias sidebarWidth: sidebar.width - property alias textFontSizeIndex: app.textFontSizeIndex - property alias nightmode: app.nightmode - } - - function loggedIn() { - if(serverLogin.loggedIn()) { - menu.loggedIn = true; - contentView.visible = true - login.visible = false; - server.initialize(serverLogin.serverUrl, serverLogin.sessionId); - } else { - menu.loggedIn = false - contentView.visible = false - login.visible = true - server.loggedOut() - content.loggedOut() - } - } - - function toggleNightmode() { - app.nightmode = !app.nightmode - } - - function zoomIn() { - if(textFontSizeIndex + 1 < fontSizes.length) { - textFontSize = fontSizes[++textFontSizeIndex] - } - } - - function zoomOut() { - if(textFontSizeIndex - 1 > 0) { - textFontSize = fontSizes[--textFontSizeIndex] - } - } - - function zoomReset() { - textFontSizeIndex = defaultTextFontSizeIndex - textFontSize = fontSizes[textFontSizeIndex] - } - - function removeHTML(str) { - forEscapingHTML.text = str - return forEscapingHTML.getText(0, forEscapingHTML.length) - } - - function showNextPost() { - sidebar.next() - } - - function showPreviousPost() { - sidebar.previous() - } - - function keyPressed(event) { - switch (event.key) { - case Qt.Key_Right: - case Qt.Key_J: - case Qt.Key_j: - sidebar.next() - break - case Qt.Key_Left: - case Qt.Key_K: - case Qt.Key_k: - sidebar.previous() - break - case Qt.Key_1: - toggleNightmode() - break - case Qt.Key_Home: - content.scrollUp() - break - case Qt.Key_End: - content.scrollDown() - break - case Qt.Key_PageUp: - content.scrollUp(content.pageJump) - break - case Qt.Key_PageDown: - case Qt.Key_Space: - content.scrollDown(content.pageJump) - break - case Qt.Key_Down: - content.scrollDown(content.scrollJump) - break - case Qt.Key_Up: - content.scrollUp(content.scrollJump) - break - case Qt.Key_Enter: - case Qt.Key_Return: - Qt.openUrlExternally(content.post.link) - break - default: - break - } - } - - SplitView { - id: contentView - anchors.fill: parent - orientation: Qt.Horizontal - visible: serverLogin.loggedIn() - focus: true - handleDelegate: Rectangle { - width: 1 - color: app.nightmode ? "#333" : "#aaa" - } - - Sidebar { - id: sidebar - content: content - server: server - - implicitWidth: 300 - textFontSize: app.textFontSize - nightmode: app.nightmode - } - - Content { - id: content - app: app - - Layout.minimumWidth: 200 - implicitWidth: 624 - textFontSize: app.textFontSize - nightmode: app.nightmode - } - - Keys.onPressed: keyPressed(event) - Keys.onReleased: { - switch (event.key) { - case Qt.Key_Alt: - app.showMenuBar = !app.showMenuBar - break - default: - break - } - } - } - - Login { - id: login - anchors.fill: parent - visible: !serverLogin.loggedIn() - - function login() { - serverLogin.login(serverUrl, userName, password) - } - - } - - MessageDialog { - id: loginErrorAlert - title: "A login error occured" - text: serverLogin.loginError - onAccepted: visible = false - } - - ServerLogin { - id: serverLogin - onSessionIdChanged: app.loggedIn() - onLoginErrorChanged: { - console.log("loginError:", loginError) - if(loginError.length > 0) { - loginErrorAlert.visible = true - } - } - } - - Server { - id: server - } - - TextArea { - id: forEscapingHTML - visible: false - textFormat: TextEdit.RichText - } - - Component.onCompleted: { - if(serverLogin.loggedIn()) { - loggedIn(); - } - } -} diff --git a/qml/qml.qrc b/qml/qml.qrc deleted file mode 100644 index c0ff3c6..0000000 --- a/qml/qml.qrc +++ /dev/null @@ -1,10 +0,0 @@ - - - main.qml - TheMenuBar.qml - Content.qml - Login.qml - PostListItem.qml - Sidebar.qml - - diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 48475bb..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "tinytinyrsslogin.h" -#include "tinytinyrss.h" -#include "post.h" - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - app.setOrganizationName("Jeena"); - app.setOrganizationDomain("jeena.net"); - app.setApplicationName("FeedTheMonkey"); - - QtWebEngine::initialize(); - - qmlRegisterType("TTRSS", 1, 0, "ServerLogin"); - qmlRegisterType("TTRSS", 1, 0, "Server"); - qmlRegisterType("TTRSS", 1, 0, "Post"); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); - - return app.exec(); -} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/src/post.cpp b/src/post.cpp deleted file mode 100644 index 2d3179b..0000000 --- a/src/post.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#include "post.h" -#include -#include -#include - -Post::Post(QObject *parent) : QObject(parent) -{ - -} - -Post::Post(QJsonObject post, QObject *parent) : QObject(parent) -{ - mTitle = html2text(post.value("title").toString().trimmed()); - mFeedTitle = html2text(post.value("feed_title").toString().trimmed()); - mId = post.value("id").toInt(); - mFeedId = post.value("feed_id").toString().trimmed(); - mAuthor = post.value("author").toString().trimmed(); - QUrl url(post.value("link").toString().trimmed()); - mLink = url; - QDateTime timestamp; - timestamp.setTime_t(post.value("updated").toInt()); - mDate = timestamp; - mContent = post.value("content").toString().trimmed(); - mExcerpt = html2text(post.value("excerpt").toString().remove(QRegExp("<[^>]*>")).replace("…", " ...").trimmed().replace("(\\s+)", " ").replace("\n", "")); - mStarred = post.value("marked").toBool(); - mRead = !post.value("unread").toBool(); - mDontChangeRead = false; - - QJsonDocument doc(post); - QString result(doc.toJson(QJsonDocument::Indented)); - mJsonString = result; -} - -Post::~Post() -{ - -} - -void Post::setRead(bool r) -{ - if(mRead == r) return; - - mRead = r; - emit readChanged(mRead); -} - -void Post::setDontChangeRead(bool r) -{ - if(mDontChangeRead == r) return; - - mDontChangeRead = r; - emit dontChangeReadChanged(mDontChangeRead); -} - -QString Post::html2text(const QString htmlString) -{ - QTextDocument doc; - doc.setHtml(htmlString); - return doc.toPlainText(); -} diff --git a/src/post.h b/src/post.h deleted file mode 100644 index 56ab9ff..0000000 --- a/src/post.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#ifndef POST_H -#define POST_H - -#include -#include -#include -#include - -class Post : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString title READ title CONSTANT) - Q_PROPERTY(QString feedTitle READ feedTitle CONSTANT) - Q_PROPERTY(int id READ id CONSTANT) - Q_PROPERTY(QString feedId READ feedId CONSTANT) - Q_PROPERTY(QString author READ author CONSTANT) - Q_PROPERTY(QUrl link READ link CONSTANT) - Q_PROPERTY(QDateTime date READ date CONSTANT) - Q_PROPERTY(QString content READ content CONSTANT) - Q_PROPERTY(QString excerpt READ excerpt CONSTANT) - Q_PROPERTY(bool starred READ starred NOTIFY starredChanged) - Q_PROPERTY(bool read READ read WRITE setRead NOTIFY readChanged) - Q_PROPERTY(bool dontChangeRead READ dontChangeRead WRITE setDontChangeRead NOTIFY dontChangeReadChanged) - Q_PROPERTY(QString jsonString READ jsonString CONSTANT) - -public: - Post(QObject *parent = 0); - Post(QJsonObject post, QObject *parent = 0); - ~Post(); - QString title() const { return mTitle; } - QString feedTitle() const { return mFeedTitle; } - int id() const { return mId; } - QString feedId() const { return mFeedId; } - QString author() const { return mAuthor; } - QUrl link() const { return mLink; } - QDateTime date() const { return mDate; } - QString content() const { return mContent; } - QString excerpt() const { return mExcerpt; } - bool starred() const { return mStarred; } - bool read() { return mRead; } - void setRead(bool r); - bool dontChangeRead() const { return mDontChangeRead; } - void setDontChangeRead(bool r); - QString jsonString() const { return mJsonString; } - -signals: - void starredChanged(bool); - void readChanged(bool); - void dontChangeReadChanged(bool); - -public slots: - -private: - QString mTitle; - QString mFeedTitle; - int mId; - QString mFeedId; - QString mAuthor; - QUrl mLink; - QDateTime mDate; - QString mContent; - QString mExcerpt; - bool mStarred; - bool mRead; - bool mDontChangeRead; - QString mJsonString; - QString html2text(const QString htmlString); -}; - -#endif // POST_H diff --git a/src/tinytinyrss.cpp b/src/tinytinyrss.cpp deleted file mode 100644 index 4806c04..0000000 --- a/src/tinytinyrss.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#include "tinytinyrss.h" -#include -#include -#include -#include - -TinyTinyRSS::TinyTinyRSS(QObject *parent) : - QObject(parent) -{ - qRegisterMetaType >(); - - mNetworkManager = new QNetworkAccessManager(this); - mPosts = QList(); -} - -TinyTinyRSS::~TinyTinyRSS() -{ - mPosts.clear(); - delete mNetworkManager; -} - -void TinyTinyRSS::initialize(const QString serverUrl, const QString sessionId) -{ - mServerUrl = serverUrl; - mSessionId = sessionId; - reload(); -} - -void TinyTinyRSS::reload() -{ - QVariantMap opts; - opts.insert("show_excerpt", false); - opts.insert("view_mode", "unread"); - opts.insert("show_content", true); - opts.insert("feed_id", -4); - opts.insert("skip", 0); - - doOperation("getHeadlines", opts, [this] (const QJsonObject &json) { - - mPosts.clear(); - - QJsonArray posts = json.value("content").toArray(); - for(int i = 0; i < posts.count(); i++) - { - QJsonObject postJson = posts.at(i).toObject(); - Post *post = new Post(postJson, this); - connect(post, SIGNAL(readChanged(bool)), this, SLOT(onPostReadChanged(bool))); - mPosts.append(post); - } - - emit postsChanged(mPosts); - }); -} - -void TinyTinyRSS::loggedOut() -{ - mServerUrl = nullptr; - mSessionId = nullptr; - mPosts.clear(); - emit postsChanged(mPosts); -} - -void TinyTinyRSS::doOperation(QString operation, QVariantMap opts, std::function callback) -{ - QVariantMap options; - options.insert("sid", mSessionId); - options.insert("op", operation); - - QMapIterator i(opts); - while (i.hasNext()) { - i.next(); - options.insert(i.key(), i.value()); - } - - QJsonObject jsonobj = QJsonObject::fromVariantMap(options); - QJsonDocument json = QJsonDocument(jsonobj); - - QNetworkRequest request(mServerUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - QNetworkReply *reply = mNetworkManager->post(request, json.toJson()); - - connect(reply, &QNetworkReply::finished, [callback, reply] () { - if (reply) { - if (reply->error() == QNetworkReply::NoError) { - QString jsonString = QString(reply->readAll()); - QJsonDocument json = QJsonDocument::fromJson(jsonString.toUtf8()); - callback(json.object()); - } else { - int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - //do some error management - qWarning() << "HTTP error: " << httpStatus; - } - reply->deleteLater(); - } - }); -} - -void TinyTinyRSS::onPostReadChanged(bool r) -{ - Post *post = (Post *)sender(); - - updateArticle(post->id(), 2, !r, [post] (const QJsonObject &) { - // not doing anything with this yet. - }); -} - -void TinyTinyRSS::updateArticle(int articleId, int field, bool trueFalse, std::function callback) -{ - QVariantMap opts; - opts.insert("article_ids", articleId); - opts.insert("field", field); - opts.insert("mode", trueFalse ? 1 : 0); - - doOperation("updateArticle", opts, callback); -} - -QQmlListProperty TinyTinyRSS::posts() -{ - return QQmlListProperty(this, mPosts); -} - -int TinyTinyRSS::postsCount() const -{ - return mPosts.count(); -} - -Post *TinyTinyRSS::post(int index) const -{ - return mPosts.at(index); -} diff --git a/src/tinytinyrss.h b/src/tinytinyrss.h deleted file mode 100644 index 2e85464..0000000 --- a/src/tinytinyrss.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#ifndef TINYTINYRSS_H -#define TINYTINYRSS_H - -#include -#include -#include -#include -#include -#include - -#include - -#include "post.h" - -class TinyTinyRSS : public QObject -{ - Q_OBJECT - Q_PROPERTY(QQmlListProperty posts READ posts NOTIFY postsChanged) - -public: - TinyTinyRSS(QObject *parent = 0); - ~TinyTinyRSS(); - - Q_INVOKABLE void initialize(const QString serverUrl, const QString sessionId); - Q_INVOKABLE void reload(); - Q_INVOKABLE void loggedOut(); - - - QQmlListProperty posts(); - int postsCount() const; - Post *post(int) const; - -signals: - void postsChanged(QList); - -private slots: - void onPostReadChanged(bool); - -private: - void doOperation(QString operation, QVariantMap opts, std::function callback); - void updateArticle(int articleId, int field, bool trueFalse, std::function callback); - - QString mServerUrl; - QString mSessionId; - QList mPosts; - QNetworkAccessManager *mNetworkManager; -}; - -#endif // TINYTINYRSS_H diff --git a/src/tinytinyrsslogin.cpp b/src/tinytinyrsslogin.cpp deleted file mode 100644 index 2648e7a..0000000 --- a/src/tinytinyrsslogin.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#include "tinytinyrsslogin.h" -#include -#include -#include -#include - -#define APP_URL "net.jeena" -#define APP_NAME "FeedTheMonkey" - -TinyTinyRSSLogin::TinyTinyRSSLogin(QObject *parent) : - QObject(parent) -{ - mNetworkManager = new QNetworkAccessManager(this); - - QSettings settings; - mSessionId = settings.value("sessionId").toString(); - mServerUrl = settings.value("serverUrl").toString(); -} - -TinyTinyRSSLogin::~TinyTinyRSSLogin() -{ - delete mNetworkManager; -} - -bool TinyTinyRSSLogin::loggedIn() -{ - return !mSessionId.isEmpty(); -} - -void TinyTinyRSSLogin::login(const QString serverUrl, const QString user, const QString password) -{ - mServerUrl = QUrl(serverUrl + "/api/"); - - QVariantMap options; - options.insert("op", "login"); - options.insert("user", user); - options.insert("password", password); - - QJsonObject jsonobj = QJsonObject::fromVariantMap(options); - QJsonDocument json = QJsonDocument(jsonobj); - - QNetworkRequest request(mServerUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - QNetworkReply *reply = mNetworkManager->post(request, json.toJson()); - connect(reply, SIGNAL(finished()), this, SLOT(reply())); -} - -void TinyTinyRSSLogin::logout() -{ - if(mSessionId.length() > 0 && mServerUrl.toString().length() > 0) { - QVariantMap options; - options.insert("op", "logout"); - options.insert("sid", mSessionId); - - QJsonObject jsonobj = QJsonObject::fromVariantMap(options); - QJsonDocument json = QJsonDocument(jsonobj); - - QNetworkRequest request(mServerUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - QNetworkReply *reply = mNetworkManager->post(request, json.toJson()); - connect(reply, SIGNAL(finished()), this, SLOT(reply())); - } -} - -void TinyTinyRSSLogin::reply() -{ - QNetworkReply *reply = qobject_cast(sender()); - - if (reply) { - - if (reply->error() == QNetworkReply::NoError) { - - QString jsonString = QString(reply->readAll()); - QJsonDocument json = QJsonDocument::fromJson(jsonString.toUtf8()); - if(json.object().value("content").toObject().value("error").toString().length() > 0) { - - mLoginError = json.object().value("content").toObject().value("error").toString(); - qWarning() << mLoginError; - emit loginErrorChanged(mLoginError); - - if(mLoginError == "NOT_LOGGED_IN") { - mSessionId = nullptr; - mServerUrl = nullptr; - - QSettings settings; - settings.remove("sessionId"); - settings.remove("serverUrl"); - settings.sync(); - - emit sessionIdChanged(mSessionId); - } - - } else { - mSessionId = json.object().value("content").toObject().value("session_id").toString(); - - emit sessionIdChanged(mSessionId); - - QSettings settings; - settings.setValue("sessionId", mSessionId); - settings.setValue("serverUrl", mServerUrl); - settings.sync(); - } - } else { - mLoginError = "HTTP error: " - + reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString() - + " :: " - + reply->errorString(); - qWarning() << mLoginError; - - emit loginErrorChanged(mLoginError); - } - reply->deleteLater(); - } -} diff --git a/src/tinytinyrsslogin.h b/src/tinytinyrsslogin.h deleted file mode 100644 index 5c21887..0000000 --- a/src/tinytinyrsslogin.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of FeedTheMonkey. - * - * Copyright 2015 Jeena - * - * FeedTheMonkey is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * FeedTheMonkey is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with FeedTheMonkey. If not, see . - */ - -#ifndef TINYTINYRSSLOGIN_H -#define TINYTINYRSSLOGIN_H - -#include -#include -#include -#include - -class TinyTinyRSSLogin : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString sessionId READ sessionId NOTIFY sessionIdChanged) - Q_PROPERTY(QUrl serverUrl READ serverUrl) - Q_PROPERTY(QString loginError READ loginError NOTIFY loginErrorChanged) - -public: - TinyTinyRSSLogin(QObject *parent = 0); - ~TinyTinyRSSLogin(); - QString sessionId() const { return mSessionId; } - QUrl serverUrl() const { return mServerUrl; } - QString loginError() const { return mLoginError; } - - Q_INVOKABLE bool loggedIn(); - Q_INVOKABLE void login(const QString serverUrl, const QString user, const QString password); - Q_INVOKABLE void logout(); - -signals: - void sessionIdChanged(QString); - void loginErrorChanged(QString); - -private slots: - void reply(); - -private: - QString mSessionId; - QUrl mServerUrl; - QString mLoginError; - QNetworkAccessManager *mNetworkManager; -}; - -#endif // TINYTINYRSSLOGIN_H