Caching improvements

This commit is contained in:
Muki 2017-01-23 18:15:42 +01:00
parent ca444a80e9
commit af88b35088
19 changed files with 413 additions and 240 deletions

View file

@ -75,6 +75,8 @@ Page {
Image {
id: icon
anchors { left: parent.left }
width: 1.2*Theme.iconSizeSmall
height: 1.2*Theme.iconSizeSmall
source: iconSource
}

View file

@ -1,5 +1,68 @@
/*
Copyright (C) 2017 Michal Kosciesza <michal@mkiol.net>
This file is part of Kaktus.
Kaktus 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.
Kaktus 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 Kaktus. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
Item {
Image {
id: root
property int maxWidth: 0
property int minWidth: 0
property string orgSource: ""
property bool cached: true
fillMode: Image.PreserveAspectFit
width: sourceSize.width >= maxWidth ? maxWidth : sourceSize.width
enabled: status === Image.Ready &&
(minWidth === 0 || (sourceSize.width > minWidth && sourceSize.height > minWidth))
visible: opacity > 0 && enabled
opacity: enabled ? 1.0 : 0.0
Behavior on opacity {
NumberAnimation { duration: 200 }
}
onOrgSourceChanged: {
if (orgSource !== "") {
if (cached) {
var cachedUrl = app._cache.getUrlbyUrl(orgSource)
if (cachedUrl === "") {
if (!settings.offlineMode && dm.online) {
cached = false
source = orgSource
}
} else {
source = cachedUrl
}
} else {
source = orgSource
}
} else {
source = ""
}
}
onStatusChanged: {
if (cached && orgSource !== "" && status===Image.Error &&
!settings.offlineMode && dm.online) {
cached = false
source = orgSource
}
}
}

View file

@ -50,6 +50,15 @@ Page {
model: VisualItemModel {
SectionHeader {
text: qsTr("Version %1").arg("2.5.2")
}
LogItem {
title: 'Bug fixes'
description: "Some bugs related to caching process have been fixed.";
}
SectionHeader {
text: qsTr("Version %1").arg("2.5.1")
}

View file

@ -80,24 +80,6 @@ ListItem {
onMenuOpenChanged: { if(menuOpen) app.hideBar() }
Component.onCompleted: {
var r = feedTitle.length>0 ? (Math.abs(feedTitle.charCodeAt(0)-65)/57)%1 : 1;
var g = feedTitle.length>1 ? (Math.abs(feedTitle.charCodeAt(1)-65)/57)%1 : 1;
var b = feedTitle.length>2 ? (Math.abs(feedTitle.charCodeAt(2)-65)/57)%1 : 1;
var colorBg = Qt.rgba(r,g,b,0.9);
var colorFg = (r+g+b)>1.5 ? Theme.highlightDimmerColor : Theme.primaryColor;
iconPlaceholder.color = colorBg;
iconPlaceholderLabel.color = colorFg;
if (defaultIcon)
icon.source = "image://icons/icon-m-friend?" + colorFg;
else
icon.source = root.feedIcon !== "" ? cache.getUrlbyUrl(root.feedIcon) : "";
}
function getUrlbyUrl(url){return cache.getUrlbyUrl(url)}
menu: last ? null : settings.iconContextMenu ? iconContextMenu : contextMenu
onHiddenChanged: {
@ -233,20 +215,19 @@ ListItem {
Item {
id: titleItem
anchors.left: parent.left; anchors.right: parent.right;
//anchors.leftMargin: Theme.paddingLarge
anchors.left: parent.left; anchors.right: parent.right
anchors.rightMargin: star.width
height: Math.max(titleLabel.height, icon.height+Theme.paddingSmall, iconPlaceholder.height+Theme.paddingSmall)
//color: "red"
height: Math.max(titleLabel.height, icon.height+Theme.paddingSmall, icon.height+Theme.paddingSmall)
// Title
Label {
id: titleLabel
//anchors.right: parent.right; anchors.left: icon.visible ? icon.right : parent.left;
anchors.right: parent.right; anchors.left: icon.visible ? icon.right : iconPlaceholder.visible ? iconPlaceholder.right : parent.left
//anchors.leftMargin: icon.visible ? Theme.paddingMedium : Theme.paddingLarge
anchors.leftMargin: showIcon ? Theme.paddingMedium : Theme.paddingLarge
anchors {
right: parent.right
left: icon.visible ? icon.right : parent.left
leftMargin: showIcon ? Theme.paddingMedium : Theme.paddingLarge
}
font.pixelSize: Theme.fontSizeMedium
font.family: Theme.fontFamilyHeading
font.bold: !root.read || root.readlater
@ -267,69 +248,37 @@ ListItem {
}
}
// Feed Icon
Rectangle {
id: iconPlaceholder
width: visible ? 1.2*Theme.iconSizeSmall : 0
height: width
anchors.left: parent.left;
anchors.top: titleLabel.top; anchors.topMargin: Theme.paddingSmall
y: Theme.paddingMedium
visible: (root.defaultIcon || !icon.visible) && root.showIcon
Label {
id: iconPlaceholderLabel
anchors.centerIn: parent
text: feedTitle.substring(0,1).toUpperCase()
visible: !root.defaultIcon
}
}
Rectangle {
anchors.fill: icon
color: "white"
visible: icon.visible && !root.defaultIcon
}
Image {
FeedIcon {
id: icon
visible: root.showIcon
showPlaceholder: !root.defaultIcon
showBackground: true
source: root.feedIcon
text: root.feedTitle
anchors {
left: parent.left
top: titleLabel.top
topMargin: Theme.paddingSmall
}
width: visible ? 1.2*Theme.iconSizeSmall: 0
height: width
anchors.left: parent.left;
anchors.top: titleLabel.top; anchors.topMargin: Theme.paddingSmall
visible: status!=Image.Error && status!=Image.Null && root.showIcon
}
}
Image {
CachedImage {
id: entryImage
anchors.left: parent.left;
fillMode: Image.PreserveAspectFit
width: root.landscapeMode ? 0 : sourceSize.width>=root.width ? root.width : sourceSize.width
enabled: root.landscapeMode ? false : source!="" && status==Image.Ready &&
sourceSize.width > Theme.iconSizeMedium &&
sourceSize.height > Theme.iconSizeMedium
visible: opacity>0
opacity: enabled ? 1.0 : 0.0
Behavior on opacity { FadeAnimation {} }
source: {
if (root.image!="") {
return settings.offlineMode ? getUrlbyUrl(root.image) : dm.online ? root.image : getUrlbyUrl(root.image);
} else {
return "";
}
}
anchors.left: parent.left
maxWidth: root.width
minWidth: Theme.iconSizeMedium
orgSource: root.image
}
Label {
id: contentLabel
anchors.left: parent.left; anchors.right: parent.right;
anchors.leftMargin: Theme.paddingLarge; anchors.rightMargin: Theme.paddingLarge
//text: root.landscapeMode ? root.contentall : root.content
text: root.content
wrapMode: Text.Wrap
//textFormat: root.landscapeMode ? Text.StyledText : Text.PlainText
textFormat: Text.PlainText
font.pixelSize: Theme.fontSizeSmall
visible: root.content!="" && !root.landscapeMode

View file

@ -1,5 +1,56 @@
/*
Copyright (C) 2017 Michal Kosciesza <michal@mkiol.net>
This file is part of Kaktus.
Kaktus 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.
Kaktus 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 Kaktus. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
Item {
id: root
property bool showPlaceholder: false
property bool showBackground: false
property alias backgroundColor: background.color
property alias text: placeholder.text
property alias source: icon.orgSource
Rectangle {
// icon background
id: background
enabled: root.showBackground && !placeholder.visible && icon.enabled
anchors.fill: parent
color: "white"
visible: opacity > 0 && enabled
opacity: enabled ? 1.0 : 0.0
Behavior on opacity {
NumberAnimation { duration: 200 }
}
}
CachedImage {
// feed icon
id: icon
anchors.fill: parent
}
IconPlaceholder {
// placeholder
id: placeholder
visible: root.showPlaceholder && !icon.enabled
anchors.fill: parent
}
}

View file

@ -62,7 +62,6 @@ Page {
PageMenu {
id: menu
//showAbout: settings.viewMode==2 ? true : false
showAbout: true
}
@ -73,28 +72,12 @@ Page {
delegate: ListItem {
id: listItem
property bool last: model.uid=="last"
property bool last: model.uid==="last"
property bool defaultIcon: model.icon === "http://s.theoldreader.com/icons/user_icon.png"
Component.onCompleted: {
var r = title.length>0 ? (Math.abs(title.charCodeAt(0)-65)/57)%1 : 1;
var g = title.length>1 ? (Math.abs(title.charCodeAt(1)-65)/57)%1 : 1;
var b = title.length>2 ? (Math.abs(title.charCodeAt(2)-65)/57)%1 : 1;
var colorBg = Qt.rgba(r,g,b,0.9);
var colorFg = (r+g+b)>1.5 ? Theme.highlightDimmerColor : Theme.primaryColor;
imagePlaceholder.color = colorBg;
imagePlaceholderLabel.color = colorFg;
if (defaultIcon)
image.source = "image://icons/icon-m-friend?" + colorFg;
else
image.source = model.icon !== "" ? cache.getUrlbyUrl(model.icon) : "";
}
enabled: !last
contentHeight: last ?
app.orientation==Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape :
app.orientation===Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape :
Math.max(item.height, image.height) + 2 * Theme.paddingMedium
Rectangle {
@ -109,36 +92,59 @@ Page {
}
}
Column {
FeedIcon {
id: image
visible: !listItem.last
y: Theme.paddingMedium
anchors.left: parent.left
showPlaceholder: true
showBackground: !listItem.defaultIcon
source: listItem.defaultIcon ? "image://icons/icon-m-friend" : model.icon
text: model.title
width: visible ? 1.2*Theme.iconSizeSmall : 0
height: width
}
Label {
id: item
visible: !listItem.last
wrapMode: Text.AlignLeft
y: Theme.paddingMedium
anchors {
left: image.visible ? image.right : parent.left
right: unreadbox.visible ? unreadbox.left : parent.right
verticalCenter: parent.verticalCenter
leftMargin: Theme.paddingLarge
rightMargin: Theme.paddingLarge
}
font.pixelSize: Theme.fontSizeMedium
text: model.title
color: listItem.down ?
(model.unread ? Theme.highlightColor : Theme.secondaryHighlightColor) :
(model.unread ? Theme.primaryColor : Theme.secondaryColor)
}
/*Column {
id: item
spacing: 0.5*Theme.paddingSmall
anchors.verticalCenter: parent.verticalCenter
anchors.left: image.visible ? image.right : imagePlaceholder.right
//anchors.left: image.visible ? image.right : Theme.fontSizeMedium
anchors.right: unreadbox.visible ? unreadbox.left : parent.right
visible: !listItem.last
Label {
id: itemLabel
wrapMode: Text.AlignLeft
anchors.left: parent.left; anchors.right: parent.right;
anchors.leftMargin: Theme.paddingLarge; anchors.rightMargin: Theme.paddingLarge
font.pixelSize: Theme.fontSizeMedium
text: title
color: listItem.down ?
(model.unread ? Theme.highlightColor : Theme.secondaryHighlightColor) :
(model.unread ? Theme.primaryColor : Theme.secondaryColor)
}
}
}*/
Rectangle {
id: unreadbox
anchors.right: parent.right; anchors.rightMargin: Theme.paddingLarge
y: Theme.paddingSmall
anchors {
right: parent.right
rightMargin: Theme.paddingLarge
}
width: unreadlabel.width + 2 * Theme.paddingSmall
height: unreadlabel.height + 2 * Theme.paddingSmall
color: Theme.rgba(Theme.highlightBackgroundColor, 0.2)
radius: 5
visible: model.unread!=0 && !listItem.last
visible: model.unread!==0 && !listItem.last
Label {
id: unreadlabel
@ -146,39 +152,6 @@ Page {
text: model.unread
color: Theme.highlightColor
}
}
Rectangle {
id: imagePlaceholder
width: visible ? 1.2*Theme.iconSizeSmall : 0
height: width
anchors.left: parent.left
y: Theme.paddingMedium
visible: listItem.defaultIcon || (!image.visible && !listItem.last)
Label {
id: imagePlaceholderLabel
anchors.centerIn: parent
text: title.substring(0,1).toUpperCase()
visible: !listItem.defaultIcon
}
}
Rectangle {
// Image white background
anchors.fill: image
visible: image.visible && !listItem.defaultIcon
color: "white"
}
Image {
id: image
width: visible ? 1.2*Theme.iconSizeSmall : 0
height: width
anchors.left: parent.left
visible: status!=Image.Error && status!=Image.Null && !listItem.last
y: Theme.paddingMedium
}
onClicked: {

View file

@ -1,5 +1,57 @@
/*
Copyright (C) 2017 Michal Kosciesza <michal@mkiol.net>
This file is part of Kaktus.
Kaktus 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.
Kaktus 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 Kaktus. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
Item {
Rectangle {
id: root
property string text
//Source: http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
function hash(text, index) {
var hash = 0, i, chr, len
if (text.length === 0 || text.length < index) return hash
for (i = index, len = text.length; i < len; i++) {
chr = text.charCodeAt(i)
hash = ((hash << 5) - hash) + chr
}
return Math.abs(hash)%255
}
Component.onCompleted: {
var r = text.length>0 ? hash(text,0)/255 : 1
var g = text.length>1 ? hash(text,1)/255 : 1
var b = text.length>2 ? hash(text,2)/255 : 1
var colorBg = Qt.rgba(r,g,b,0.8)
var colorFg = (r+g+b)>1.5 ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
color = colorBg
label.color = colorFg
}
Label {
id: label
text: root.text.substring(0,1).toUpperCase()
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: Theme.fontSizeLarge
anchors.fill: parent
}
}

View file

@ -31,19 +31,19 @@ Page {
allowedOrientations: {
switch (settings.allowedOrientations) {
case 1:
return Orientation.Portrait;
return Orientation.Portrait
case 2:
return Orientation.Landscape;
return Orientation.Landscape
}
return Orientation.Landscape | Orientation.Portrait;
return Orientation.Landscape | Orientation.Portrait
}
ActiveDetector {
onActivated: {
tabModel.updateFlags();
tabModel.updateFlags()
}
onInit: {
bar.flick = listView;
bar.flick = listView
}
}
@ -101,36 +101,37 @@ Page {
}
}
Column {
Label {
id: item
spacing: 0.5*Theme.paddingSmall
anchors.verticalCenter: parent.verticalCenter
anchors.left: image.visible ? image.right : imagePlaceholder.right
anchors.right: unreadbox.visible ? unreadbox.left : parent.right
visible: !listItem.last
Label {
wrapMode: Text.AlignLeft
anchors.left: parent.left; anchors.right: parent.right;
anchors.leftMargin: Theme.paddingLarge; anchors.rightMargin: Theme.paddingLarge
font.pixelSize: Theme.fontSizeMedium
color: listItem.down ?
(model.unread ? Theme.highlightColor : Theme.secondaryHighlightColor) :
(model.unread ? Theme.primaryColor : Theme.secondaryColor)
text: listItem.title
wrapMode: Text.AlignLeft
y: Theme.paddingMedium
anchors {
left: image.visible ? image.right : parent.left
right: unreadbox.visible ? unreadbox.left : parent.right
verticalCenter: parent.verticalCenter
leftMargin: Theme.paddingLarge
rightMargin: Theme.paddingLarge
}
font.pixelSize: Theme.fontSizeMedium
color: listItem.down ?
(model.unread ? Theme.highlightColor : Theme.secondaryHighlightColor) :
(model.unread ? Theme.primaryColor : Theme.secondaryColor)
text: listItem.title
}
Rectangle {
id: unreadbox
anchors.right: parent.right; anchors.rightMargin: Theme.paddingLarge
y: Theme.paddingSmall
anchors {
right: parent.right
rightMargin: Theme.paddingLarge
}
width: unreadlabel.width + 3 * Theme.paddingSmall
height: unreadlabel.height + 2 * Theme.paddingSmall
color: Theme.rgba(Theme.highlightBackgroundColor, 0.2)
radius: 5
visible: model.unread!=0 && !listItem.last
visible: model.unread !==0 && !listItem.last
Label {
id: unreadlabel
@ -140,48 +141,28 @@ Page {
}
}
Rectangle {
id: imagePlaceholder
width: visible ? 1.2*Theme.iconSizeSmall : 0
height: width
anchors.left: parent.left
y: Theme.paddingMedium
visible: !image.visible && !listItem.last
Label {
id: imagePlaceholderLabel
anchors.centerIn: parent
text: listItem.title.substring(0,1).toUpperCase()
}
Component.onCompleted: {
var r = listItem.title.length>0 ? (Math.abs(listItem.title.charCodeAt(0)-65)/57)%1 : 1;
var g = listItem.title.length>1 ? (Math.abs(listItem.title.charCodeAt(1)-65)/57)%1 : 1;
var b = listItem.title.length>2 ? (Math.abs(listItem.title.charCodeAt(2)-65)/57)%1 : 1;
imagePlaceholder.color = Qt.rgba(r,g,b,0.9);
imagePlaceholderLabel.color = (r+g+b)>1.5 ? Theme.highlightDimmerColor : Theme.primaryColor;
}
}
Image {
FeedIcon {
id: image
visible: !listItem.last
y: Theme.paddingMedium
anchors.left: parent.left
showPlaceholder: true
showBackground: false
source: listItem.imageSource
text: listItem.title
width: visible ? 1.2*Theme.iconSizeSmall : 0
height: width
anchors.left: parent.left; //anchors.leftMargin: Theme.paddingLarge
visible: status!=Image.Error && status!=Image.Null && !listItem.last
y: Theme.paddingMedium
source: listItem.imageSource
}
onClicked: {
if (!listItem.last) {
if (settings.viewMode == 0) {
utils.setFeedModel(uid);
pageStack.push(Qt.resolvedUrl("FeedPage.qml"),{"title": model.uid=="subscriptions" ? qsTr("Subscriptions") : model.uid=="friends" ? qsTr("Following") : model.uid=="global.uncategorized" ? qsTr("Uncategorized") : title, "index": model.index});
pageStack.push(Qt.resolvedUrl("FeedPage.qml"),{"title": model.uid==="subscriptions" ? qsTr("Subscriptions") : model.uid=="friends" ? qsTr("Following") : model.uid=="global.uncategorized" ? qsTr("Uncategorized") : title, "index": model.index});
}
if (settings.viewMode == 1) {
utils.setEntryModel(uid);
pageStack.push(Qt.resolvedUrl("EntryPage.qml"),{"title": model.uid=="subscriptions" ? qsTr("Subscriptions") : model.uid=="friends" ? qsTr("Following") : model.uid=="global.uncategorized" ? qsTr("Uncategorized") : title, "readlater": false});
pageStack.push(Qt.resolvedUrl("EntryPage.qml"),{"title": model.uid==="subscriptions" ? qsTr("Subscriptions") : model.uid=="friends" ? qsTr("Following") : model.uid=="global.uncategorized" ? qsTr("Uncategorized") : title, "readlater": false});
}
}
}

View file

@ -27,11 +27,11 @@ ApplicationWindow {
property bool progress: false
property int oldViewMode
property bool isTablet: Screen.sizeCategory === Screen.Large || Screen.sizeCategory === Screen.ExtraLarge
property bool isNetvibes: settings.signinType >= 0 && settings.signinType < 10
property bool isOldReader: settings.signinType >= 10 && settings.signinType < 20
property bool isFeedly: settings.signinType >= 20 && settings.signinType < 30
readonly property bool isTablet: Screen.sizeCategory === Screen.Large || Screen.sizeCategory === Screen.ExtraLarge
readonly property bool isNetvibes: settings.signinType >= 0 && settings.signinType < 10
readonly property bool isOldReader: settings.signinType >= 10 && settings.signinType < 20
readonly property bool isFeedly: settings.signinType >= 20 && settings.signinType < 30
readonly property variant _cache: cache
cover: CoverPage {}

View file

@ -8,6 +8,13 @@
# * date Author's Name <author's email> version-release
# - Summary of changes
* Sat Jan 22 2016 Michal Kosciesza 2.5.2-1
- Caching improvements
- Minor UI improvements
* Sat Dec 23 2016 Michal Kosciesza 2.5.1-3
- RU translations update
* Thu Dec 22 2016 Michal Kosciesza 2.5.1-2
- DE & RU translations update

View file

@ -13,8 +13,8 @@ Name: harbour-kaktus
%{!?qtc_make:%define qtc_make make}
%{?qtc_builddir:%define _builddir %qtc_builddir}
Summary: Kaktus
Version: 2.5.1
Release: 2
Version: 2.5.2
Release: 1
Group: Qt/Qt
License: LICENSE
URL: https://github.com/mkiol/kaktus

View file

@ -1,7 +1,7 @@
Name: harbour-kaktus
Summary: Kaktus
Version: 2.5.1
Release: 2
Version: 2.5.2
Release: 1
# The contents of the Group field should be one of the groups listed here:
# http://gitorious.org/meego-developer-tools/spectacle/blobs/master/data/GROUPS
Group: Qt/Qt

View file

@ -438,6 +438,29 @@ void CacheServer::handle(QHttpRequest *req, QHttpResponse *resp)
return;
}*/
/*if (parts[1] == "rssdata" && parts.length() > 2) {
qDebug() << "handle, path=" << req->url().path();
Settings *s = Settings::instance();
QString id = parts[2];
QString content = s->db->readEntryContentById(id);
QString style = "";//img {max-width: 100% !important; max-height: device-height !important;}";
content = "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>" +
(style.isEmpty() ? "" : "<style>" + style + "</style>") +
"</head><body>" + content + "</body></html>";
content = "<!DOCTYPE html>\n<html><head><meta content='width=device-width, initial-scale=1.0' name='viewport'>" +
(style.isEmpty() ? "" : "<style>" + style + "</style>") +
"</head><body>" + content + "</body></html>";
resp->setHeader("Content-Type", "text/html");
resp->setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
resp->setHeader("Pragma", "no-cache");
resp->writeHead(200);
resp->end(content.toUtf8());
return;
}*/
FilteringWorker *worker = new FilteringWorker();
QObject::connect(this, SIGNAL(startWorker(QHttpRequest*,QHttpResponse*)), worker, SLOT(start(QHttpRequest*,QHttpResponse*)));
QObject::connect(worker, SIGNAL(finished()), this, SLOT(handleFinish()));
@ -478,12 +501,28 @@ QString CacheServer::getUrlbyUrl(const QString &url)
{
//qDebug() << "getUrlbyUrl, url=" << url << "hash=" << Utils::hash(url);
// If url is "image://" will not be hashed
if (url.isEmpty() || url.startsWith("image://")) {
if (url.isEmpty()) {
return url;
}
return "http://localhost:" + QString::number(port) + "/" + Utils::hash(url);
// If url is "image://" will not be hashed
if (url.startsWith("image://")) {
return url;
}
// If url is "http://localhost" will not be hashed
if (url.startsWith("http://localhost")) {
return url;
}
QString filename = Utils::hash(url);
Settings *s = Settings::instance();
if (!QFile::exists(s->getDmCacheDir() + "/" + filename)) {
qWarning() << "File " << filename << "does not exists!";
return "";
}
return "http://localhost:" + QString::number(port) + "/" + filename;
}
QByteArray CacheServer::getDataUrlByUrl(const QString &url)

View file

@ -1557,6 +1557,29 @@ QString DatabaseManager::readEntryImageById(const QString &id)
return "";
}
QString DatabaseManager::readEntryContentById(const QString &id)
{
if (db.isOpen()) {
QSqlQuery query(db);
bool ret = query.exec(QString("SELECT content FROM entries WHERE id='%1';")
.arg(id));
if (!ret) {
qWarning() << "SQL Error!" << query.lastQuery();checkError(query.lastError());
}
while(query.next()) {
return query.value(0).toString();
}
} else {
qWarning() << "DB is not open!";
}
return "";
}
QList<QString> DatabaseManager::readModuleIdByStream(const QString &id)
{
QList<QString> list;

View file

@ -238,6 +238,7 @@ public:
QList<StreamModuleTab> readStreamModuleTabListWithoutDate();
QString readEntryImageById(const QString &id);
QString readEntryContentById(const QString &id);
QString readLatestEntryIdByDashboard(const QString &id);
QString readLatestEntryIdByTab(const QString &id);

View file

@ -29,6 +29,8 @@
#endif
#ifdef ANDROID
#include <QQmlApplicationEngine>
#include <QtWebView>
#include <QColor>
#endif
#include "iconprovider.h"
@ -44,9 +46,9 @@ static const char *APP_NAME = "Kaktus";
static const char *AUTHOR = "Michal Kosciesza <michal@mkiol.net>";
static const char *PAGE = "https://github.com/mkiol/kaktus";
#ifdef KAKTUS_LIGHT
static const char *VERSION = "2.5.1 (light edition)";
static const char *VERSION = "2.5.2 (light edition)";
#else
static const char *VERSION = "2.5.1";
static const char *VERSION = "2.5.2";
#endif
@ -62,10 +64,15 @@ int main(int argc, char *argv[])
#ifdef ANDROID
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
QtWebView::initialize();
QScopedPointer<QQmlApplicationEngine> engine(new QQmlApplicationEngine());
QQmlContext *context = engine->rootContext();
QString translationsDirPath = "";
//TODO
QString translationsDirPath = ""; //TODO
#endif
Utils utils;
#ifdef ANDROID
utils.setStatusBarColor(QColor("#00796b"));
#endif
app->setApplicationName(APP_NAME);
@ -96,8 +103,6 @@ int main(int argc, char *argv[])
DownloadManager dm; settings->dm = &dm;
CacheServer cache(&db); settings->cache = &cache;
Utils utils;
QObject::connect(engine.data(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
NetworkAccessManagerFactory NAMfactory(settings->getDmUserAgent());

View file

@ -142,7 +142,7 @@ void Settings::setShowBroadcast(bool value)
bool Settings::getShowBroadcast()
{
return settings.value("showbroadcast", true).toBool();
return settings.value("showbroadcast", false).toBool();
}
void Settings::setOfflineMode(bool value)
@ -695,7 +695,6 @@ void Settings::setFontSize(int value)
float Settings::getZoom()
{
float size = settings.value("zoom", 1.0).toFloat();
//size = static_cast<float>(static_cast<int>(size*100+0.5))/100.0;
return size < 0.5 ? 0.5 : size > 2.0 ? 2.0 : size;
}
@ -705,8 +704,6 @@ void Settings::setZoom(float value)
if (value < 0.5 || value > 2.0)
return;
//value = static_cast<float>(static_cast<int>(value*100+0.5))/100.0;
if (getZoom() != value) {
settings.setValue("zoom", value);
emit zoomChanged();

View file

@ -24,6 +24,9 @@
#include <QCryptographicHash>
#include <QRegExp>
#ifdef SAILFISH
#include <sailfishapp.h>
#endif
#ifdef ANDROID
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtGui/QGuiApplication>
@ -125,6 +128,15 @@ void Utils::showNotification(const QString &title, const QString &text)
"(Ljava/lang/String;Ljava/lang/String;)V",
jTitle.object<jstring>(), jText.object<jstring>());
}
void Utils::setStatusBarColor(const QColor &color)
{
int acolor = (color.alpha() << 24) | (color.red() << 16) | (color.green() << 8) | color.blue();
QAndroidJniObject::callStaticMethod<void>("net/mkiol/kaktus/KaktusActivity",
"setStatusBarColor",
"(I)V", acolor);
}
#endif
#ifdef BB10
@ -134,6 +146,29 @@ void Utils::launchBrowser(const QString &url)
}
#endif
QString Utils::readAsset(const QString &path)
{
#ifdef BB10
QFile file("app/native/assets/" + path);
#endif
#ifdef ANDROID
QFile file(":/" + path);
#endif
#ifdef SAILFISH
QFile file(SailfishApp::pathTo(path).toLocalFile());
#endif
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Could not open" << path << "for reading: " << file.errorString();
file.close();
return "";
}
QString data = QString(file.readAll());
file.close();
return data;
}
void Utils::copyToClipboard(const QString &text)
{
#ifdef BB10
@ -201,10 +236,9 @@ QString Utils::formatHtml(const QString & data, bool offline, const QString & st
content.remove(rxSizes);
}
if (!style.isEmpty())
content = "<style>" + style + "</style>" + content;
content = "<html><head><meta name=\"viewport\" content=\"initial-scale=1.0\"></head><body>" + content + "</body></html>";
content = "<html><head><meta name=\"viewport\" content=\"width=device-width, maximum-scale=1.0, initial-scale=1.0\">" +
(style.isEmpty() ? "" : "<style>" + style + "</style>") +
"</head><body>" + content + "</body></html>";
return content;
}
@ -234,21 +268,6 @@ bool Utils::removeDir(const QString &dirName)
}
#ifdef BB10
QString Utils::readAsset(const QString &path)
{
QFile file("app/native/assets/" + path);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Could not open" << path << "for reading: " << file.errorString();
file.close();
return "";
}
QString data = QString(file.readAll());
file.close();
return data;
}
// Source: http://hecgeek.blogspot.com/2014/10/blackberry-10-multiple-os-versions-from.html
bool Utils::checkOSVersion(int major, int minor, int patch, int build)
{

View file

@ -31,6 +31,7 @@
#ifdef ANDROID
#include <QScreen>
#include <QColor>
#endif
#ifdef BB10
@ -70,6 +71,7 @@ public:
Q_INVOKABLE void resetFetcher(int type);
//Q_INVOKABLE bool isOnline();
Q_INVOKABLE QString formatHtml(const QString &data, bool offline, const QString &style = QString());
Q_INVOKABLE QString readAsset(const QString &path);
static QString hash(const QString &url);
static int monthsTo(const QDate &from, const QDate &to);
@ -84,6 +86,7 @@ public:
Q_INVOKABLE int pt(float value);
Q_INVOKABLE int sp(float value);
Q_INVOKABLE void showNotification(const QString &title, const QString &text);
Q_INVOKABLE void setStatusBarColor(const QColor &color);
#endif
#ifdef BB10
@ -101,7 +104,6 @@ public:
Q_INVOKABLE float titleTextFontSize();
Q_INVOKABLE QString titleTextFontFamily();*/
Q_INVOKABLE void launchBrowser(const QString &url);
Q_INVOKABLE QString readAsset(const QString &path);
#endif
public slots: