Clean up and initialized everything for v3 written in Rust and GTK
This commit just removes all the Qt and QML code and sets up everything as preperation for the rewrite in Rust and GTK. There is no new code yet, just a hello world, but the structure is there.
This commit is contained in:
parent
4b804873a6
commit
88a97bb555
24 changed files with 33 additions and 1639 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
||||||
.DS_Store
|
#Added by cargo
|
||||||
FeedTheMonkey.pro.user*
|
|
||||||
build
|
/target
|
||||||
|
|
6
Cargo.lock
generated
Normal file
6
Cargo.lock
generated
Normal file
|
@ -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"
|
||||||
|
|
14
Cargo.toml
Normal file
14
Cargo.toml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "feedthemonkey"
|
||||||
|
version = "3.0.0"
|
||||||
|
authors = ["Jeena <hello@jeena.net>"]
|
||||||
|
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]
|
|
@ -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
|
|
21
README.md
21
README.md
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
# FeedTheMonkey
|
# FeedTheMonkey
|
||||||
|
|
||||||
<img align=right src="http://jeena.net/feedthemonkey/feedthemonkey-icon.png" width='256' alt='Icon'>
|
<img align=right src="http://jeena.net/feedthemonkey/feedthemonkey-icon.png" width='256' alt='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
|
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.
|
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
|
It is written in Rust and GTK. You need to have an account on a TinyTinyRSS server.
|
||||||
to have Qt 5.6 installed to be able to compile and have a account on a TinyTinyRSS server.
|
|
||||||
|
|
||||||
## Installation
|
## 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.
|
TBD
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Keyboard shortcuts
|
## Keyboard shortcuts
|
||||||
|
|
||||||
|
@ -33,13 +28,11 @@ The keyboard shortcuts are inspired by other feed readers which are inspired by
|
||||||
`Ctrl -` zoom out
|
`Ctrl -` zoom out
|
||||||
`Ctrl 0` reset zoom
|
`Ctrl 0` reset zoom
|
||||||
|
|
||||||
On macOS use `Cmd` instead of `Ctrl`.
|
|
||||||
|
|
||||||
## Trivia
|
## Trivia
|
||||||
|
|
||||||
This is version 2 of FeedTheMonkey, you can find version 1 which was written in PyQt in the v1 branch
|
This is version 3 of FeedTheMonkey, you can find version 1 which was written
|
||||||
of this repo. My goal is to make this usable on many different targets, for now it is only for
|
in PyQt in the v1 branch of this repo and version 2 which was written in C++
|
||||||
the use on a desktop computer but I'd like to see it on a mobile device too.
|
and Qt/QML in the v2 branch.
|
||||||
|
|
||||||
## Screenshot
|
## 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.
|
This file is part of FeedTheMonkey.
|
||||||
|
|
||||||
Copyright 2015-2017 Jeena
|
Copyright 2020 Jeena
|
||||||
|
|
||||||
FeedTheMonkey is free software: you can redistribute it and/or modify
|
FeedTheMonkey is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<RCC>
|
|
||||||
<qresource prefix="/html">
|
|
||||||
<file>content.css</file>
|
|
||||||
<file>content.html</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<RCC>
|
|
||||||
<qresource prefix="/misc">
|
|
||||||
<file>feedthemonkey.xpm</file>
|
|
||||||
<file>Icon.icns</file>
|
|
||||||
<file>feedthemonkey.desktop</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
|
@ -1,25 +0,0 @@
|
||||||
# Maintainer: Jeena <hello@jeena.net>
|
|
||||||
|
|
||||||
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"
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
|
|
116
qml/Content.qml
116
qml/Content.qml
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
106
qml/Sidebar.qml
106
qml/Sidebar.qml
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
254
qml/main.qml
254
qml/main.qml
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
10
qml/qml.qrc
10
qml/qml.qrc
|
@ -1,10 +0,0 @@
|
||||||
<RCC>
|
|
||||||
<qresource prefix="/qml">
|
|
||||||
<file>main.qml</file>
|
|
||||||
<file>TheMenuBar.qml</file>
|
|
||||||
<file>Content.qml</file>
|
|
||||||
<file>Login.qml</file>
|
|
||||||
<file>PostListItem.qml</file>
|
|
||||||
<file>Sidebar.qml</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
49
src/main.cpp
49
src/main.cpp
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QQmlApplicationEngine>
|
|
||||||
#include <qdebug.h>
|
|
||||||
#include <QMetaType>
|
|
||||||
#include <QtQml>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QtWebEngine/qtwebengineglobal.h>
|
|
||||||
|
|
||||||
#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<TinyTinyRSSLogin>("TTRSS", 1, 0, "ServerLogin");
|
|
||||||
qmlRegisterType<TinyTinyRSS>("TTRSS", 1, 0, "Server");
|
|
||||||
qmlRegisterType<Post>("TTRSS", 1, 0, "Post");
|
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
3
src/main.rs
Normal file
3
src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
79
src/post.cpp
79
src/post.cpp
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "post.h"
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QTextDocument>
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
89
src/post.h
89
src/post.h
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef POST_H
|
|
||||||
#define POST_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QDate>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
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
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tinytinyrss.h"
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QJsonArray>
|
|
||||||
|
|
||||||
TinyTinyRSS::TinyTinyRSS(QObject *parent) :
|
|
||||||
QObject(parent)
|
|
||||||
{
|
|
||||||
qRegisterMetaType<QList<Post *> >();
|
|
||||||
|
|
||||||
mNetworkManager = new QNetworkAccessManager(this);
|
|
||||||
mPosts = QList<Post *>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<void (const QJsonObject &json)> callback)
|
|
||||||
{
|
|
||||||
QVariantMap options;
|
|
||||||
options.insert("sid", mSessionId);
|
|
||||||
options.insert("op", operation);
|
|
||||||
|
|
||||||
QMapIterator<QString, QVariant> 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<void (const QJsonObject &json)> callback)
|
|
||||||
{
|
|
||||||
QVariantMap opts;
|
|
||||||
opts.insert("article_ids", articleId);
|
|
||||||
opts.insert("field", field);
|
|
||||||
opts.insert("mode", trueFalse ? 1 : 0);
|
|
||||||
|
|
||||||
doOperation("updateArticle", opts, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
QQmlListProperty<Post> TinyTinyRSS::posts()
|
|
||||||
{
|
|
||||||
return QQmlListProperty<Post>(this, mPosts);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TinyTinyRSS::postsCount() const
|
|
||||||
{
|
|
||||||
return mPosts.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
Post *TinyTinyRSS::post(int index) const
|
|
||||||
{
|
|
||||||
return mPosts.at(index);
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TINYTINYRSS_H
|
|
||||||
#define TINYTINYRSS_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QList>
|
|
||||||
#include <QQmlListProperty>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "post.h"
|
|
||||||
|
|
||||||
class TinyTinyRSS : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(QQmlListProperty<Post> 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<Post> posts();
|
|
||||||
int postsCount() const;
|
|
||||||
Post *post(int) const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void postsChanged(QList<Post *>);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onPostReadChanged(bool);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void doOperation(QString operation, QVariantMap opts, std::function<void (const QJsonObject &json)> callback);
|
|
||||||
void updateArticle(int articleId, int field, bool trueFalse, std::function<void (const QJsonObject &json)> callback);
|
|
||||||
|
|
||||||
QString mServerUrl;
|
|
||||||
QString mSessionId;
|
|
||||||
QList<Post*> mPosts;
|
|
||||||
QNetworkAccessManager *mNetworkManager;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // TINYTINYRSS_H
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tinytinyrsslogin.h"
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
#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<QNetworkReply*>(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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TINYTINYRSSLOGIN_H
|
|
||||||
#define TINYTINYRSSLOGIN_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QMetaType>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
|
|
||||||
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
|
|
Loading…
Add table
Add a link
Reference in a new issue