[Sailfish] Literals update and fixes
BIN
sailfish/images/z1.0/icon-m-filter-0.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
sailfish/images/z1.0/icon-m-filter-1.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
sailfish/images/z1.0/icon-m-filter-2.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
sailfish/images/z1.0/icon-m-night-selected.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
sailfish/images/z1.0/icon-m-night.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 830 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
sailfish/images/z1.25/icon-m-filter-0.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
sailfish/images/z1.25/icon-m-filter-1.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
sailfish/images/z1.25/icon-m-filter-2.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
sailfish/images/z1.25/icon-m-night-selected.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
sailfish/images/z1.25/icon-m-night.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 986 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
sailfish/images/z1.5-large/icon-m-filter-0.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
sailfish/images/z1.5-large/icon-m-filter-1.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
sailfish/images/z1.5-large/icon-m-filter-2.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
sailfish/images/z1.5-large/icon-m-night-selected.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
sailfish/images/z1.5-large/icon-m-night.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 924 B After Width: | Height: | Size: 913 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
sailfish/images/z1.5/icon-m-filter-0.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
sailfish/images/z1.5/icon-m-filter-1.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
sailfish/images/z1.5/icon-m-filter-2.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
sailfish/images/z1.5/icon-m-night-selected.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
sailfish/images/z1.5/icon-m-night.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
sailfish/images/z1.75/icon-m-filter-0.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
sailfish/images/z1.75/icon-m-filter-1.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
sailfish/images/z1.75/icon-m-filter-2.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
sailfish/images/z1.75/icon-m-night-selected.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
sailfish/images/z1.75/icon-m-night.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
sailfish/images/z2.0/icon-m-filter-0.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
sailfish/images/z2.0/icon-m-filter-1.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
sailfish/images/z2.0/icon-m-filter-2.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
sailfish/images/z2.0/icon-m-night-selected.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
sailfish/images/z2.0/icon-m-night.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2 KiB |
|
|
@ -98,7 +98,7 @@ Page {
|
|||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
notification.show(qsTr("Launching an external browser..."));
|
||||
notification.show(qsTr("Launching an external browser."));
|
||||
Qt.openUrlExternally(PAGE);
|
||||
}
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ Page {
|
|||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
notification.show(qsTr("Launching an external browser..."));
|
||||
notification.show(qsTr("Launching an external browser."));
|
||||
Qt.openUrlExternally("https://www.gnu.org/licenses/gpl-3.0.txt");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Page {
|
|||
model: ListModel {
|
||||
ListElement { name: "Netvibes"; iconSource: "nv.png"; type: 1}
|
||||
ListElement { name: "Old Reader"; iconSource: "oldreader.png"; type: 2}
|
||||
ListElement { name: "Feedly (comming soon)"; iconSource: "feedly.png"; type: 3}
|
||||
/*ListElement { name: "Feedly (comming soon)"; iconSource: "feedly.png"; type: 3}*/
|
||||
}
|
||||
|
||||
header: PageHeader {
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ Page {
|
|||
onLoadingChanged: {
|
||||
switch (loadRequest.status) {
|
||||
case WebView.LoadStartedStatus:
|
||||
proggressPanel.text = qsTr("Loading page content...");
|
||||
proggressPanel.text = qsTr("Loading page content");
|
||||
proggressPanel.open = true;
|
||||
break;
|
||||
case WebView.LoadSucceededStatus:
|
||||
|
|
@ -98,7 +98,6 @@ Page {
|
|||
break;
|
||||
case WebView.LoadFailedStatus:
|
||||
proggressPanel.open = false;
|
||||
//notification.show(qsTr("Failed to load page content :-("));
|
||||
break;
|
||||
default:
|
||||
proggressPanel.open = false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2014 Michal Kosciesza <michal@mkiol.net>
|
||||
Copyright (C) 2016 Michal Kosciesza <michal@mkiol.net>
|
||||
|
||||
This file is part of Kaktus.
|
||||
|
||||
|
|
@ -50,6 +50,45 @@ Page {
|
|||
|
||||
model: VisualItemModel {
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Version %1").arg("2.5.0")
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'Reader View'
|
||||
description: "Reader View is a feature that strips away clutter like buttons, ads and background images, and changes the page's layout for better readability. Reader View implementation in Kaktus is based on Readability.js library, the same that is used in Firefox browser.";
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'UI redesign'
|
||||
description: "Some options were moved from pull down menu to bootom bar and bottom bar has a new dark look.";
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'Unsynced data indicator'
|
||||
description: "When Kaktus has any unsynchronized data, indicator (red dot) is shown on the bottom bar.";
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'Smoother offline mode'
|
||||
description: "A few bugs were fixed and general offine mode experience has been improved.";
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'List filtering'
|
||||
description: "List of articles can be filtered to display all articles, unread and saved or only unread.";
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'Auto network mode'
|
||||
description: "Option to automatically enabling offline mode on network connection lost.";
|
||||
}
|
||||
|
||||
LogItem {
|
||||
title: 'Night View'
|
||||
description: "Night View reduces the brightness of websites by inverting colors (Heavily inspired and partially borrowed from harbour-webpirate project).";
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Version %1").arg("2.4.0")
|
||||
}
|
||||
|
|
@ -169,7 +208,7 @@ Page {
|
|||
description: 'Many improvements, like performance optimization and UI polishing were made.'
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
/*SectionHeader {
|
||||
text: qsTr("Version %1").arg("1.4")
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +252,7 @@ Page {
|
|||
title: 'Caching only on WiFi'
|
||||
description: 'Until now you could only enable or disable caching feature. '+
|
||||
'Now, you can also set caching to start only when phone is connected with WiFi.'
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
Item {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2014 Michal Kosciesza <michal@mkiol.net>
|
||||
Copyright (C) 2016 Michal Kosciesza <michal@mkiol.net>
|
||||
|
||||
This file is part of Kaktus.
|
||||
|
||||
|
|
@ -25,190 +25,280 @@ Item {
|
|||
|
||||
property bool open: false
|
||||
property bool openable: true
|
||||
property int showTime: 7000
|
||||
property int showTime: 5000
|
||||
|
||||
// view modes
|
||||
property bool vmOpen: false
|
||||
|
||||
// progress
|
||||
property bool busy: false
|
||||
property alias progressText: progressLabel.text
|
||||
property bool cancelable: true
|
||||
property real progress: 0.0
|
||||
signal cancelClicked
|
||||
|
||||
// flick show/hide
|
||||
property real barShowMoveWidth: 20
|
||||
property real barShowMoveWidthBack: height
|
||||
property Flickable flick: null
|
||||
|
||||
property bool isPortrait: app.orientation==Orientation.Portrait
|
||||
// other
|
||||
readonly property bool isPortrait: app.orientation === Orientation.Portrait
|
||||
readonly property color iconColor: Theme.secondaryColor
|
||||
readonly property int stdHeight: isPortrait ? Theme.itemSizeMedium : 0.8 * Theme.itemSizeMedium
|
||||
|
||||
height: Theme.itemSizeMedium
|
||||
height: root.stdHeight
|
||||
width: parent.width
|
||||
|
||||
clip: true
|
||||
onOpenChanged: {
|
||||
if (!open)
|
||||
progress = 0.0
|
||||
}
|
||||
|
||||
onBusyChanged: {
|
||||
//console.log("onBusyChanged:", busy)
|
||||
open = busy
|
||||
}
|
||||
|
||||
function show() {
|
||||
if (openable && pageStack.currentPage.showBar) {
|
||||
if (!open)
|
||||
root.open = true;
|
||||
timer.restart();
|
||||
if (!open) {
|
||||
root.open = true
|
||||
root.vmOpen = false
|
||||
}
|
||||
timer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
function showAndEnable() {
|
||||
openable = true
|
||||
show();
|
||||
show()
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (open) {
|
||||
root.open = false;
|
||||
timer.stop();
|
||||
if (open && !busy) {
|
||||
root.open = false
|
||||
root.vmOpen = false
|
||||
timer.stop()
|
||||
}
|
||||
}
|
||||
|
||||
function hideAndDisable() {
|
||||
hide();
|
||||
openable = false;
|
||||
hide()
|
||||
openable = false
|
||||
}
|
||||
|
||||
Item {
|
||||
Rectangle {
|
||||
id: bar
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: root.open ? 1.0 : 0.0
|
||||
visible: opacity > 0.0
|
||||
Behavior on opacity { FadeAnimation {duration: 300} }
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
color: "black"
|
||||
|
||||
property int off: 5
|
||||
property int size: vm0b.width + Theme.paddingMedium
|
||||
clip: true
|
||||
|
||||
Rectangle {
|
||||
id: leftRect
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top; anchors.bottom: parent.bottom
|
||||
color: Theme.highlightBackgroundColor
|
||||
width: settings.viewMode==0 ? 0 :
|
||||
settings.viewMode==1 ? 1 * bar.size - bar.off :
|
||||
settings.viewMode==3 ? 2 * bar.size - bar.off :
|
||||
settings.viewMode==4 ? 3 * bar.size - bar.off :
|
||||
settings.viewMode==5 ? 4 * bar.size - bar.off :
|
||||
settings.viewMode==6 ? 4 * bar.size - bar.off :
|
||||
5 * bar.size
|
||||
Behavior on width { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rightRect
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top; anchors.bottom: parent.bottom
|
||||
color: Theme.highlightBackgroundColor
|
||||
width: settings.viewMode==0 ? root.width - bar.size + bar.off :
|
||||
settings.viewMode==1 ? root.width - 2 * bar.size + bar.off :
|
||||
settings.viewMode==3 ? root.width - 3 * bar.size + bar.off :
|
||||
settings.viewMode==4 ? root.width - 4 * bar.size + bar.off :
|
||||
settings.viewMode==5 ? root.width - 5 * bar.size + bar.off :
|
||||
settings.viewMode==6 ? root.width - 5 * bar.size + bar.off :
|
||||
0
|
||||
Behavior on width { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.right: rightRect.left; anchors.left: leftRect.right
|
||||
anchors.bottom: parent.bottom;
|
||||
height: root.height/10
|
||||
color: Theme.highlightColor
|
||||
}
|
||||
Behavior on y {NumberAnimation { duration: 200; easing.type: Easing.OutQuad }}
|
||||
y: open ? 0 : height
|
||||
|
||||
MouseArea {
|
||||
enabled: bar.visible
|
||||
enabled: root.open
|
||||
anchors.fill: parent
|
||||
onClicked: root.hide()
|
||||
}
|
||||
|
||||
Item {
|
||||
property int off: -root.height/10
|
||||
anchors.left: parent.left; anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom; height: parent.height
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: root.vmOpen && !root.busy ? 1.0 : 0.0
|
||||
visible: opacity > 0.0
|
||||
Behavior on opacity { FadeAnimation {} }
|
||||
|
||||
IconButton {
|
||||
id: vm0b
|
||||
x: 0*(width+Theme.paddingMedium)
|
||||
y: ((parent.height-height)/2) + (highlighted ? parent.off : 0)
|
||||
icon.source: "image://icons/icon-m-vm0?"+Theme.highlightDimmerColor
|
||||
highlighted: settings.viewMode==0
|
||||
onClicked: {
|
||||
show();
|
||||
if (!app.progress && settings.viewMode!=0) {
|
||||
app.progress = true;
|
||||
settings.viewMode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm1b
|
||||
x: 1*(width+Theme.paddingMedium)
|
||||
y: ((parent.height-height)/2) + (highlighted ? parent.off : 0)
|
||||
icon.source: "image://icons/icon-m-vm1?"+Theme.highlightDimmerColor
|
||||
highlighted: settings.viewMode==1
|
||||
onClicked: {
|
||||
show();
|
||||
if (!app.progress && settings.viewMode!=1) {
|
||||
app.progress = true;
|
||||
settings.viewMode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm3b
|
||||
x: 2*(width+Theme.paddingMedium)
|
||||
y: ((parent.height-height)/2) + (highlighted ? parent.off : 0)
|
||||
icon.source: "image://icons/icon-m-vm3?"+Theme.highlightDimmerColor
|
||||
highlighted: settings.viewMode==3
|
||||
onClicked: {
|
||||
show();
|
||||
if (!app.progress && settings.viewMode!=3) {
|
||||
app.progress = true;
|
||||
settings.viewMode = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm4b
|
||||
x: 3*(width+Theme.paddingMedium)
|
||||
y: ((parent.height-height)/2) + (highlighted ? parent.off : 0)
|
||||
icon.source: "image://icons/icon-m-vm4?"+Theme.highlightDimmerColor
|
||||
highlighted: settings.viewMode==4
|
||||
onClicked: {
|
||||
show();
|
||||
if (!app.progress && settings.viewMode!=4) {
|
||||
app.progress = true;
|
||||
settings.viewMode = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm5b
|
||||
x: 4*(width+Theme.paddingMedium)
|
||||
visible: app.isNetvibes || (app.isOldReader && settings.showBroadcast) // Disabled for Feedly
|
||||
y: ((parent.height-height)/2) + (highlighted ? parent.off : 0)
|
||||
icon.source: app.isOldReader ? "image://icons/icon-m-vm6?"+(root.transparent ? Theme.primaryColor : Theme.highlightDimmerColor) :
|
||||
"image://icons/icon-m-vm5?"+(root.transparent ? Theme.primaryColor : Theme.highlightDimmerColor)
|
||||
highlighted: settings.viewMode==5 || settings.viewMode==6
|
||||
onClicked: {
|
||||
show();
|
||||
if (!app.progress && (settings.viewMode!=5 || settings.viewMode!=6)) {
|
||||
app.progress = true;
|
||||
if (settings.signinType >= 10)
|
||||
settings.viewMode = 6;
|
||||
else
|
||||
settings.viewMode = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
visible: pageStack.currentPage.objectName != ""
|
||||
anchors.right: parent.right; anchors.rightMargin: Theme.paddingSmall
|
||||
anchors.right: parent.right; anchors.rightMargin: Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://icons/icon-m-read?"+(root.transparent ? Theme.primaryColor : Theme.highlightDimmerColor)
|
||||
icon.source: "image://theme/icon-m-dismiss?"+root.iconColor
|
||||
onClicked: {
|
||||
show();
|
||||
show()
|
||||
root.vmOpen = !root.vmOpen
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.leftMargin: Theme.paddingMedium
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
spacing: Theme.paddingMedium * 0.8
|
||||
|
||||
IconButton {
|
||||
id: vm0b
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://icons/icon-m-vm0?"+root.iconColor
|
||||
highlighted: settings.viewMode==0
|
||||
onClicked: {
|
||||
show()
|
||||
root.vmOpen = false
|
||||
if (!app.progress && settings.viewMode!=0) {
|
||||
app.progress = true
|
||||
settings.viewMode = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm1b
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://icons/icon-m-vm1?"+root.iconColor
|
||||
highlighted: settings.viewMode==1
|
||||
onClicked: {
|
||||
show()
|
||||
root.vmOpen = false
|
||||
if (!app.progress && settings.viewMode!=1) {
|
||||
app.progress = true
|
||||
settings.viewMode = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm3b
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://icons/icon-m-vm3?"+root.iconColor
|
||||
highlighted: settings.viewMode==3
|
||||
onClicked: {
|
||||
show()
|
||||
root.vmOpen = false
|
||||
if (!app.progress && settings.viewMode!=3) {
|
||||
app.progress = true
|
||||
settings.viewMode = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm4b
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://icons/icon-m-vm4?"+root.iconColor
|
||||
highlighted: settings.viewMode==4
|
||||
onClicked: {
|
||||
show()
|
||||
root.vmOpen = false
|
||||
if (!app.progress && settings.viewMode!=4) {
|
||||
app.progress = true
|
||||
settings.viewMode = 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: vm5b
|
||||
visible: app.isNetvibes || (app.isOldReader && settings.showBroadcast) // Disabled for Feedly
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: app.isOldReader ? "image://icons/icon-m-vm6?"+root.iconColor :
|
||||
"image://icons/icon-m-vm5?"+root.iconColor
|
||||
highlighted: settings.viewMode==5 || settings.viewMode==6
|
||||
onClicked: {
|
||||
show()
|
||||
root.vmOpen = false
|
||||
if (!app.progress && (settings.viewMode!=5 || settings.viewMode!=6)) {
|
||||
app.progress = true
|
||||
if (settings.signinType >= 10)
|
||||
settings.viewMode = 6
|
||||
else
|
||||
settings.viewMode = 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: menu
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: !root.busy && !root.vmOpen && root.open ? 1.0 : 0.0
|
||||
visible: opacity > 0.0
|
||||
Behavior on opacity { FadeAnimation {} }
|
||||
|
||||
IconButton {
|
||||
id: vmIcon
|
||||
anchors.right: parent.right; anchors.rightMargin: Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
//icon.source: "image://theme/icon-m-menu?"+root.iconColor
|
||||
icon.source: "image://icons/icon-m-vm" + settings.viewMode + "?" + root.iconColor
|
||||
highlighted: root.vmOpen
|
||||
onClicked: {
|
||||
show()
|
||||
root.vmOpen = !root.vmOpen
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: refreshIcon
|
||||
anchors.right: vmIcon.left; anchors.rightMargin: Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://theme/icon-m-refresh?"+root.iconColor
|
||||
enabled: !fetcher.busy && !dm.busy && !dm.removerBusy && dm.online
|
||||
onClicked: {
|
||||
show()
|
||||
fetcher.update()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
x: parent.height/8
|
||||
y: parent.width/8
|
||||
visible: !db.synced
|
||||
width: Theme.paddingMedium
|
||||
height: Theme.paddingMedium
|
||||
radius: Theme.paddingMedium/2
|
||||
color: "red"
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
anchors.right: refreshIcon.left; anchors.rightMargin: Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
visible: opacity > 0.0
|
||||
Behavior on opacity { FadeAnimation {} }
|
||||
opacity: pageStack.currentPage.objectName === "entries" ? 1.0 : 0.0
|
||||
|
||||
icon.source: "image://icons/icon-m-filter-" + settings.filter + "?" + root.iconColor
|
||||
onClicked: {
|
||||
show()
|
||||
settings.filter = settings.filter === 2 ? 0 : settings.filter + 1
|
||||
}
|
||||
}
|
||||
|
||||
/*IconButton {
|
||||
id: networkIcon
|
||||
anchors.left: markallIcon.right; anchors.leftMargin: Theme.paddingMedium
|
||||
//anchors.left: parent.left; anchors.leftMargin: Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
enabled: !settings.offlineMode || (settings.offlineMode && dm.online)
|
||||
icon.source: "image://theme/icon-m-wlan" + (settings.offlineMode ? "-no-signal" : "") + "?" + root.iconColor
|
||||
onClicked: {
|
||||
show()
|
||||
if (settings.offlineMode) {
|
||||
if (dm.online)
|
||||
settings.offlineMode = false;
|
||||
else
|
||||
notification.show(qsTr("Can't switch to online mode because network is disconnected."));
|
||||
} else {
|
||||
settings.offlineMode = true;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
IconButton {
|
||||
id: markallIcon
|
||||
visible: pageStack.currentPage.objectName != ""
|
||||
anchors.left: parent.left; anchors.leftMargin: Theme.paddingMedium
|
||||
//anchors.left: networkIcon.right; anchors.leftMargin: Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon.source: "image://icons/icon-m-read?"+root.iconColor
|
||||
onClicked: {
|
||||
show()
|
||||
var remorse = pageStack.currentPage.remorse;
|
||||
var name = pageStack.currentPage.objectName;
|
||||
if (name == "tabs") {
|
||||
|
|
@ -246,13 +336,79 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: progressPanel
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: root.busy && root.open ? 1.0 : 0.0
|
||||
visible: opacity > 0.0
|
||||
Behavior on opacity { FadeAnimation {} }
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom; anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: root.progress * parent.width
|
||||
|
||||
/*gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: Theme.rgba(Theme.highlightColor, 0.4) }
|
||||
GradientStop { position: 1.0; color: Theme.rgba(Theme.highlightColor, 0.0) }
|
||||
}*/
|
||||
|
||||
color: Theme.highlightDimmerColor
|
||||
|
||||
Behavior on width {
|
||||
SmoothedAnimation {
|
||||
velocity: 480; duration: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: progressIcon
|
||||
height: 0.6*root.stdHeight; width: height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingMedium
|
||||
source: "image://theme/graphic-busyindicator-medium?"+root.iconColor
|
||||
RotationAnimation on rotation {
|
||||
loops: Animation.Infinite
|
||||
from: 0
|
||||
to: 360
|
||||
duration: 1200
|
||||
running: root.busy && Qt.application.active
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: progressLabel
|
||||
height: bar.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: progressIcon.right; anchors.right: root.cancelable ? closeButton.left : parent.right
|
||||
anchors.leftMargin: Theme.paddingMedium; anchors.rightMargin: Theme.paddingMedium
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.fontFamily
|
||||
color: root.iconColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: closeButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right; anchors.rightMargin: Theme.paddingMedium
|
||||
icon.source: "image://theme/icon-m-dismiss?"+root.iconColor
|
||||
onClicked: root.cancelClicked()
|
||||
visible: root.cancelable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
enabled: !bar.visible && pageStack.currentPage.showBar
|
||||
enabled: !root.open && pageStack.currentPage.showBar
|
||||
anchors.bottom: parent.bottom; anchors.left: parent.left; anchors.right: parent.right
|
||||
height: root.height/2
|
||||
onClicked: root.show();
|
||||
height: root.height/3
|
||||
onClicked: root.show()
|
||||
}
|
||||
|
||||
Timer {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ ListItem {
|
|||
property bool defaultIcon: feedIcon === "http://s.theoldreader.com/icons/user_icon.png"
|
||||
property color highlightedColor: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
|
||||
readonly property alias expandable: box.expandable
|
||||
|
||||
property bool expandedMode: settings.expandedMode
|
||||
|
||||
signal markedAsRead
|
||||
|
|
@ -74,6 +73,11 @@ ListItem {
|
|||
|
||||
enabled: !last && !daterow
|
||||
|
||||
contentHeight: last ?
|
||||
app.orientation === Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape :
|
||||
daterow ? dateRowbox.height :
|
||||
box.height + expander.height
|
||||
|
||||
onMenuOpenChanged: { if(menuOpen) app.hideBar() }
|
||||
|
||||
Component.onCompleted: {
|
||||
|
|
@ -96,11 +100,6 @@ ListItem {
|
|||
|
||||
menu: last ? null : settings.iconContextMenu ? iconContextMenu : contextMenu
|
||||
|
||||
contentHeight: last ?
|
||||
app.orientation==Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape :
|
||||
daterow ? dateRowbox.height :
|
||||
box.height + expander.height
|
||||
|
||||
onHiddenChanged: {
|
||||
if (hidden && expanded) {
|
||||
expanded = false;
|
||||
|
|
@ -309,14 +308,13 @@ ListItem {
|
|||
fillMode: Image.PreserveAspectFit
|
||||
width: root.landscapeMode ? 0 : sourceSize.width>=root.width ? root.width : sourceSize.width
|
||||
enabled: root.landscapeMode ? false : source!="" && status==Image.Ready &&
|
||||
settings.showTabIcons &&
|
||||
sourceSize.width > Theme.iconSizeMedium &&
|
||||
sourceSize.height > Theme.iconSizeMedium
|
||||
visible: opacity>0
|
||||
opacity: enabled ? 1.0 : 0.0
|
||||
Behavior on opacity { FadeAnimation {} }
|
||||
source: {
|
||||
if (settings.showTabIcons && root.image!="") {
|
||||
if (root.image!="") {
|
||||
return settings.offlineMode ? getUrlbyUrl(root.image) : dm.online ? root.image : getUrlbyUrl(root.image);
|
||||
} else {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -43,17 +43,10 @@ Page {
|
|||
property string expandedUid: ""
|
||||
property int expandedIndex: 0
|
||||
|
||||
function navigate(url) {
|
||||
var hcolor = Theme.highlightColor.toString().substr(1, 6);
|
||||
var shcolor = Theme.secondaryHighlightColor.toString().substr(1, 6);
|
||||
var imgWidth = settings.fontSize == 1 ? root.width/(1.5) : settings.fontSize == 2 ? root.width/(2.0) : root.width;
|
||||
return url+"?fontsize=18px&width="+imgWidth+"&highlightColor="+hcolor+"&secondaryHighlightColor="+shcolor+"&margin="+Theme.paddingMedium;
|
||||
}
|
||||
|
||||
function openInExaternalBrowser(index, link, uid) {
|
||||
entryModel.setData(index, "read", 1, "");
|
||||
notification.show(qsTr("Launching an external browser..."));
|
||||
Qt.openUrlExternally(settings.offlineMode ? navigate(cache.getUrlbyId(uid)) : link);
|
||||
notification.show(qsTr("Launching an external browser."));
|
||||
Qt.openUrlExternally(link);
|
||||
}
|
||||
|
||||
function setContentPane(delegate) {
|
||||
|
|
@ -203,8 +196,9 @@ Page {
|
|||
|
||||
PageMenu {
|
||||
id: menu
|
||||
showAbout: settings.viewMode>2 ? true : false
|
||||
showShowOnlyUnread: settings.viewMode!=4 && settings.viewMode!=6 && settings.viewMode!=7
|
||||
//showAbout: settings.viewMode>2 ? true : false
|
||||
showAbout: true
|
||||
//showShowOnlyUnread: settings.viewMode!=4 && settings.viewMode!=6 && settings.viewMode!=7
|
||||
}
|
||||
|
||||
header: PageHeader {
|
||||
|
|
@ -261,25 +255,25 @@ Page {
|
|||
function check() {
|
||||
// Not allowed while Syncing
|
||||
if (dm.busy || fetcher.busy || dm.removerBusy) {
|
||||
notification.show(qsTr("Please wait until current task is complete."));
|
||||
notification.show(qsTr("Wait until current task is complete."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Entry not cached and offline mode enabled
|
||||
if (settings.offlineMode && !model.cached) {
|
||||
notification.show(qsTr("Offline version not available."));
|
||||
notification.show(qsTr("Offline version is not available."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Switch to Offline mode if no network
|
||||
// Switch to offline mode if no network
|
||||
if (!settings.offlineMode && !dm.online) {
|
||||
if (model.cached) {
|
||||
// Entry cached
|
||||
notification.show(qsTr("Network connection is unavailable.\nSwitching to Offline mode."));
|
||||
notification.show(qsTr("Enabling offline mode because network is disconnected."));
|
||||
settings.offlineMode = true;
|
||||
} else {
|
||||
// Entry not cached
|
||||
notification.show(qsTr("Network connection is unavailable."));
|
||||
notification.show(qsTr("Network is disconnected."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -288,24 +282,17 @@ Page {
|
|||
}
|
||||
|
||||
function openEntryInViewer() {
|
||||
|
||||
// (!dm.online && settings.offlineMode) -> WORKAROUND for https://github.com/mkiol/kaktus/issues/14
|
||||
if (!dm.online && settings.offlineMode) {
|
||||
openInExaternalBrowser(model.index, model.link, model.uid);
|
||||
return;
|
||||
}
|
||||
|
||||
pageStack.push(Qt.resolvedUrl("WebPreviewPage.qml"),
|
||||
{"entryId": model.uid,
|
||||
"onlineUrl": delegate.onlineurl,
|
||||
"offlineUrl": delegate.offlineurl,
|
||||
"title": model.title,
|
||||
"stared": model.readlater==1,
|
||||
"stared": model.readlater===1,
|
||||
"liked": model.liked,
|
||||
"broadcast": model.broadcast,
|
||||
"index": model.index,
|
||||
"feedindex": root.index,
|
||||
"read" : model.read==1,
|
||||
"read" : model.read===1,
|
||||
"cached" : model.cached
|
||||
});
|
||||
}
|
||||
|
|
@ -313,7 +300,7 @@ Page {
|
|||
function showEntryFeedContent() {
|
||||
// Not allowed while Syncing
|
||||
if (dm.busy || fetcher.busy || dm.removerBusy) {
|
||||
notification.show(qsTr("Please wait until current task is complete."));
|
||||
notification.show(qsTr("Wait until current task is complete."));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -323,12 +310,12 @@ Page {
|
|||
"onlineUrl": delegate.onlineurl,
|
||||
"offlineUrl": delegate.offlineurl,
|
||||
"title": model.title,
|
||||
"stared": model.readlater==1,
|
||||
"stared": model.readlater===1,
|
||||
"liked": model.liked,
|
||||
"broadcast": model.broadcast,
|
||||
"index": model.index,
|
||||
"feedindex": root.index,
|
||||
"read" : model.read==1,
|
||||
"read" : model.read===1,
|
||||
"cached" : model.cached
|
||||
});
|
||||
}
|
||||
|
|
@ -495,7 +482,7 @@ Page {
|
|||
ViewPlaceholder {
|
||||
id: placeholder
|
||||
enabled: listView.count == 0
|
||||
text: fetcher.busy ? qsTr("Wait until Sync finish.") :
|
||||
text: fetcher.busy ? qsTr("Wait until sync finish") :
|
||||
settings.viewMode==4 ? app.isNetvibes || app.isFeedly ? qsTr("No saved items") : qsTr("No starred items") :
|
||||
settings.viewMode==6 ? qsTr("No liked items") : settings.showOnlyUnread ? qsTr("No unread items") : qsTr("No items")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,14 +69,13 @@ SilicaFlickable {
|
|||
fillMode: Image.PreserveAspectFit
|
||||
width: sourceSize.width>=root.width ? root.width : sourceSize.width
|
||||
enabled: source!="" && status==Image.Ready &&
|
||||
settings.showTabIcons &&
|
||||
sourceSize.width > Theme.iconSizeMedium &&
|
||||
sourceSize.height > Theme.iconSizeMedium
|
||||
visible: opacity>0
|
||||
opacity: enabled ? 1.0 : 0.0
|
||||
Behavior on opacity { FadeAnimation {} }
|
||||
source: {
|
||||
if (settings.showTabIcons && root.image!="") {
|
||||
if (root.image!="") {
|
||||
return settings.offlineMode ? getUrlbyUrl(root.image) : dm.online ? root.image : getUrlbyUrl(root.image);
|
||||
} else {
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ Page {
|
|||
function check() {
|
||||
// Not allowed while Syncing
|
||||
if (dm.busy || fetcher.busy || dm.removerBusy) {
|
||||
notification.show(qsTr("Please wait until current task is complete."));
|
||||
notification.show(qsTr("Wait until current task is complete."));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -68,11 +68,11 @@ Page {
|
|||
if (!settings.offlineMode && !dm.online) {
|
||||
if (cached) {
|
||||
// Entry cached
|
||||
notification.show(qsTr("Network connection is unavailable.\nSwitching to Offline mode."));
|
||||
notification.show(qsTr("Enabling offline mode because network is disconnected."));
|
||||
settings.offlineMode = true;
|
||||
} else {
|
||||
// Entry not cached
|
||||
notification.show(qsTr("Network connection is unavailable."));
|
||||
notification.show(qsTr("Network is disconnected."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ Page {
|
|||
|
||||
function openEntryInBrowser() {
|
||||
entryModel.setData(index, "read", 1, "");
|
||||
notification.show(qsTr("Launching an external browser..."));
|
||||
notification.show(qsTr("Launching an external browser."));
|
||||
Qt.openUrlExternally(settings.offlineMode ? offlineUrl : onlineUrl);
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ Page {
|
|||
}
|
||||
|
||||
onClipboardClicked: {
|
||||
notification.show(qsTr("URL copied to clipboard"));
|
||||
notification.show(qsTr("URL was copied to the clipboard."));
|
||||
Clipboard.text = root.onlineUrl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ Page {
|
|||
property int index
|
||||
|
||||
ActiveDetector {
|
||||
onActivated: { feedModel.updateFlags();}
|
||||
onInit: { bar.flick = listView; }
|
||||
onActivated: { feedModel.updateFlags() }
|
||||
onInit: { bar.flick = listView }
|
||||
}
|
||||
|
||||
RemorsePopup {
|
||||
|
|
@ -62,7 +62,8 @@ Page {
|
|||
|
||||
PageMenu {
|
||||
id: menu
|
||||
showAbout: settings.viewMode==2 ? true : false
|
||||
//showAbout: settings.viewMode==2 ? true : false
|
||||
showAbout: true
|
||||
}
|
||||
|
||||
header: PageHeader {
|
||||
|
|
@ -194,7 +195,7 @@ Page {
|
|||
MenuItem {
|
||||
id: readItem
|
||||
text: qsTr("Mark all as read")
|
||||
enabled: model.unread!=0
|
||||
enabled: model.unread!==0
|
||||
visible: enabled
|
||||
onClicked: {
|
||||
feedModel.markAsRead(model.index);
|
||||
|
|
@ -203,7 +204,7 @@ Page {
|
|||
MenuItem {
|
||||
id: unreadItem
|
||||
text: qsTr("Mark all as unread")
|
||||
enabled: model.read!=0 && settings.signinType<10
|
||||
enabled: model.read!==0 && settings.signinType<10
|
||||
visible: enabled
|
||||
onClicked: {
|
||||
feedModel.markAsUnread(model.index);
|
||||
|
|
@ -215,7 +216,7 @@ Page {
|
|||
ViewPlaceholder {
|
||||
id: placeholder
|
||||
enabled: listView.count == 0
|
||||
text: fetcher.busy ? qsTr("Wait until Sync finish.") : qsTr("No feeds")
|
||||
text: fetcher.busy ? qsTr("Wait until sync finish") : qsTr("No feeds")
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ Page {
|
|||
function check() {
|
||||
// Not allowed while Syncing
|
||||
if (dm.busy || fetcher.busy || dm.removerBusy) {
|
||||
notification.show(qsTr("Please wait until current task is complete."));
|
||||
notification.show(qsTr("Wait until current task is complete."));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -112,11 +112,11 @@ Page {
|
|||
if (!settings.offlineMode && !dm.online) {
|
||||
if (cached) {
|
||||
// Entry cached
|
||||
notification.show(qsTr("Network connection is unavailable.\nSwitching to offline mode."));
|
||||
notification.show(qsTr("Enabling offline mode because network is disconnected."));
|
||||
settings.offlineMode = true;
|
||||
} else {
|
||||
// Entry not cached
|
||||
notification.show(qsTr("Network connection is unavailable."));
|
||||
notification.show(qsTr("Network is disconnected."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -126,12 +126,12 @@ Page {
|
|||
|
||||
function openEntryInBrowser() {
|
||||
entryModel.setData(index, "read", 1, "");
|
||||
notification.show(qsTr("Launching an external browser..."));
|
||||
notification.show(qsTr("Launching an external browser."));
|
||||
Qt.openUrlExternally(settings.offlineMode ? offlineUrl : onlineUrl);
|
||||
}
|
||||
|
||||
function openUrlEntryInBrowser(url) {
|
||||
notification.show(qsTr("Launching an external browser..."));
|
||||
notification.show(qsTr("Launching an external browser."));
|
||||
Qt.openUrlExternally(url);
|
||||
}
|
||||
|
||||
|
|
@ -212,6 +212,7 @@ Page {
|
|||
initTheme()
|
||||
root.themeApply = false
|
||||
}
|
||||
postMessage("readability_apply_fixups")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -239,8 +240,8 @@ Page {
|
|||
experimental.preferences.javascriptEnabled: true
|
||||
experimental.preferences.navigatorQtObjectEnabled: true
|
||||
|
||||
onLoadingChanged: {
|
||||
/*console.log("onLoadingChanged:")
|
||||
/*onLoadingChanged: {
|
||||
console.log("onLoadingChanged:")
|
||||
console.log(" url: ", loadRequest.url)
|
||||
console.log(" status: ", loadRequest.status)
|
||||
console.log(" error string: ", loadRequest.errorString)
|
||||
|
|
@ -248,8 +249,8 @@ Page {
|
|||
|
||||
if (loadRequest.status === WebView.LoadSucceededStatus) {
|
||||
console.log(" LoadSucceededStatus")
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
experimental.userScripts: [
|
||||
Qt.resolvedUrl("js/ObjectOverrider.js"),
|
||||
|
|
@ -269,14 +270,23 @@ Page {
|
|||
return
|
||||
}
|
||||
|
||||
/*console.log("onNavigationRequested: ")
|
||||
console.log(" url:",request.url)
|
||||
console.log(" navigation type:", request.navigationType)
|
||||
console.log(" navigation LinkClickedNavigation:", request.navigationType === WebView.LinkClickedNavigation)
|
||||
console.log(" navigation FormSubmittedNavigation:", request.navigationType === WebView.FormSubmittedNavigation)
|
||||
console.log(" navigation BackForwardNavigation:", request.navigationType === WebView.BackForwardNavigation)
|
||||
console.log(" navigation ReloadNavigation:", request.navigationType === WebView.ReloadNavigation)
|
||||
console.log(" navigation FormResubmittedNavigation:", request.navigationType === WebView.FormResubmittedNavigation)
|
||||
console.log(" navigation OtherNavigation:", request.navigationType === WebView.OtherNavigation)
|
||||
console.log(" action:", request.action)*/
|
||||
|
||||
/*var url = "" + request.url
|
||||
if (url.indexOf("about:") === 0) {
|
||||
request.action = WebView.IgnoreRequest
|
||||
return
|
||||
}*/
|
||||
|
||||
//console.log("request.url: " + request.url)
|
||||
//console.log("onlineUrl: " + root.onlineUrl)
|
||||
if (request.url == root.onlineUrl || request.url == root.offlineUrl) {
|
||||
root.openEntryInViewer()
|
||||
request.action = WebView.IgnoreRequest
|
||||
|
|
@ -411,6 +421,15 @@ Page {
|
|||
}
|
||||
}
|
||||
|
||||
IconBarItem {
|
||||
text: qsTr("Copy URL")
|
||||
icon: "image://theme/icon-m-clipboard"
|
||||
onClicked: {
|
||||
notification.show(qsTr("URL was copied to the clipboard."));
|
||||
Clipboard.text = root.onlineUrl;
|
||||
}
|
||||
}
|
||||
|
||||
IconBarItem {
|
||||
text: qsTr("Increase font")
|
||||
icon: "image://icons/icon-m-fontup"
|
||||
|
|
@ -426,14 +445,5 @@ Page {
|
|||
root.updateZoom(-0.1)
|
||||
}
|
||||
}
|
||||
|
||||
IconBarItem {
|
||||
text: qsTr("Copy URL")
|
||||
icon: "image://theme/icon-m-clipboard"
|
||||
onClicked: {
|
||||
notification.show(qsTr("URL copied to clipboard"));
|
||||
Clipboard.text = root.onlineUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ Page {
|
|||
id: placeholder
|
||||
enabled: true
|
||||
text: settings.signedIn ?
|
||||
app.fetcherBusyStatus || dm.busy ? qsTr("Wait until Sync finish.") :
|
||||
qsTr("To do feeds synchronisation, pull down and select Sync.") :
|
||||
app.fetcherBusyStatus || dm.busy ? qsTr("Wait until sync finish") :
|
||||
qsTr("To do feeds synchronization, pull down and select sync.") :
|
||||
qsTr("You are not signed in to any account. Pull down to add one.")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,23 +28,29 @@ Item {
|
|||
|
||||
property bool open: false
|
||||
property bool openable: true
|
||||
property bool showable: true
|
||||
|
||||
property int showTime: 7000
|
||||
property real barShowMoveWidth: 20
|
||||
property Flickable flickable: null
|
||||
property bool shown: opacity == 1.0
|
||||
|
||||
|
||||
width: parent.width
|
||||
//height: isPortrait ? app.panelHeightPortrait : app.panelHeightLandscape
|
||||
height: Theme.itemSizeMedium
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
enabled: showable
|
||||
visible: showable
|
||||
|
||||
clip: true
|
||||
opacity: root.open ? 1.0 : 0.0
|
||||
Behavior on opacity { FadeAnimation {duration: 300} }
|
||||
|
||||
function show() {
|
||||
if (!showable)
|
||||
return
|
||||
if (!open) {
|
||||
root.open = true;
|
||||
flick.contentX = 0;
|
||||
|
|
@ -75,6 +81,7 @@ Item {
|
|||
}
|
||||
|
||||
MouseArea {
|
||||
enabled: root.showable
|
||||
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
||||
height: root.open ? parent.height : parent.height / 3
|
||||
onClicked: root.show();
|
||||
|
|
|
|||
|
|
@ -26,8 +26,11 @@ Item {
|
|||
property string icon: "image://icons/item"
|
||||
property alias enabled: iconButton.enabled
|
||||
property alias text: lbl.text
|
||||
property string theme: "invert"
|
||||
|
||||
//property bool barOpen: parent.open
|
||||
property string iconColor: theme === "black" ? Theme.primaryColor :
|
||||
theme === "invert" ? Theme.highlightDimmerColor :
|
||||
Theme.primaryColor
|
||||
|
||||
width: iconButton.width
|
||||
height: iconButton.height
|
||||
|
|
@ -52,7 +55,7 @@ Item {
|
|||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
color: bar.transparent ? Theme.highlightColor : Theme.highlightDimmerColor
|
||||
color: iconColor
|
||||
font.pixelSize: Theme.fontSizeTiny
|
||||
wrapMode: Text.Wrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
|
@ -60,10 +63,9 @@ Item {
|
|||
|
||||
IconButton {
|
||||
id: iconButton
|
||||
icon.source: root.icon + "?"+(root.transparent ? Theme.highlightColor : Theme.highlightDimmerColor)
|
||||
//onClicked: { if (root.barOpen){ root.clicked() } }
|
||||
//onDownChanged: { if (down && root.barOpen){ root.downed() } }
|
||||
icon.source: root.icon + "?" + iconColor
|
||||
onClicked: root.clicked()
|
||||
onDownChanged: { if (down){ root.downed() } }
|
||||
enabled: root.enabled
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ Item {
|
|||
property bool highlighted
|
||||
property alias text: label.text
|
||||
property alias icon: icon
|
||||
property string iconSource: "image://icons/icon-m-item"
|
||||
|
||||
signal clicked
|
||||
|
||||
|
|
@ -72,7 +73,7 @@ Item {
|
|||
|
||||
Image {
|
||||
id: icon
|
||||
source: "image://icons/icon-m-item"
|
||||
source: parent.iconSource + "?" + (parent.highlighted ? Theme.highlightColor : parent.enabled ? Theme.primaryColor : Theme.secondaryColor)
|
||||
height: Theme.iconSizeMedium
|
||||
width: Theme.iconSizeMedium
|
||||
anchors.right: parent.right
|
||||
|
|
|
|||
|
|
@ -44,15 +44,7 @@ Dialog {
|
|||
SilicaFlickable {
|
||||
anchors {left: parent.left; right: parent.right }
|
||||
anchors {top: parent.top; bottom: parent.bottom }
|
||||
anchors.bottomMargin: {
|
||||
var size = 0;
|
||||
var d = app.orientation===Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape;
|
||||
if (bar.open)
|
||||
size += d;
|
||||
if (progressPanel.open||progressPanelRemover.open||progressPanelDm.open)
|
||||
size += d;
|
||||
return size;
|
||||
}
|
||||
anchors.bottomMargin: app.barHeight
|
||||
clip: true
|
||||
contentHeight: content.height
|
||||
|
||||
|
|
|
|||
|
|
@ -43,15 +43,7 @@ Dialog {
|
|||
SilicaFlickable {
|
||||
anchors {left: parent.left; right: parent.right }
|
||||
anchors {top: parent.top; bottom: parent.bottom }
|
||||
anchors.bottomMargin: {
|
||||
var size = 0;
|
||||
var d = app.orientation===Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape;
|
||||
if (bar.open)
|
||||
size += d;
|
||||
if (progressPanel.open||progressPanelRemover.open||progressPanelDm.open)
|
||||
size += d;
|
||||
return size;
|
||||
}
|
||||
anchors.bottomMargin: app.barHeight
|
||||
clip: true
|
||||
contentHeight: content.height
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ PullDownMenu {
|
|||
|
||||
property bool showAbout: true
|
||||
property bool showSettings: true
|
||||
property bool showSync: true
|
||||
property bool showShowOnlyUnread: false
|
||||
//property bool showSync: true
|
||||
//property bool showShowOnlyUnread: false
|
||||
property bool showNetwork: true
|
||||
|
||||
MenuItem {
|
||||
|
|
@ -51,35 +51,36 @@ PullDownMenu {
|
|||
MenuItem {
|
||||
text: settings.offlineMode ? qsTr("Network mode: offline") : qsTr("Network mode: online")
|
||||
visible: root.showNetwork
|
||||
enabled: !settings.offlineMode || (settings.offlineMode && dm.online)
|
||||
|
||||
onClicked: {
|
||||
if (settings.offlineMode) {
|
||||
if (dm.online)
|
||||
settings.offlineMode = false;
|
||||
else
|
||||
notification.show(qsTr("Can't switch to Online mode.\nNetwork connection is unavailable."));
|
||||
notification.show(qsTr("Can't switch to online mode because network is disconnected."));
|
||||
} else {
|
||||
settings.offlineMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
/*MenuItem {
|
||||
text: settings.showOnlyUnread ? qsTr("Showing: only unread") : qsTr("Showing: all articles")
|
||||
enabled: root.showShowOnlyUnread
|
||||
visible: enabled
|
||||
onClicked: {
|
||||
settings.showOnlyUnread = !settings.showOnlyUnread;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
MenuItem {
|
||||
/*MenuItem {
|
||||
text: enabled ? qsTr("Sync") : qsTr("Busy...")
|
||||
visible: root.showSync
|
||||
|
||||
onClicked: fetcher.update()
|
||||
enabled: !fetcher.busy && !dm.busy && !dm.removerBusy
|
||||
}
|
||||
}*/
|
||||
|
||||
onActiveChanged: {
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -64,14 +64,6 @@ Item {
|
|||
color: Theme.highlightBackgroundColor
|
||||
}
|
||||
|
||||
/*Rectangle {
|
||||
height: 7
|
||||
anchors.left: parent.left; anchors.top: parent.top
|
||||
width: parent.width
|
||||
//color: Theme.rgba(Theme.highlightBackgroundColor, 0.5)
|
||||
color: Theme.rgba(Theme.highlightDimmerColor, 0.2)
|
||||
}*/
|
||||
|
||||
Image {
|
||||
anchors.left: parent.left; anchors.right: parent.right
|
||||
source: "image://theme/graphic-gradient-edge?"+Theme.highlightBackgroundColor
|
||||
|
|
@ -130,7 +122,7 @@ Item {
|
|||
id: closeButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
icon.source: "image://theme/icon-m-close?"+(root.transparent ? Theme.highlightColor : Theme.highlightDimmerColor)
|
||||
icon.source: "image://theme/icon-m-dismiss?"+(root.transparent ? Theme.highlightColor : Theme.highlightDimmerColor)
|
||||
onClicked: root.closeClicked()
|
||||
visible: root.cancelable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,8 +285,8 @@ Page {
|
|||
currentIndex: settings.offlineMode ? 1 : 0
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuItem { id: onlineMode; text: qsTr("Online") }
|
||||
MenuItem { id: offlineMode; text: qsTr("Offline") }
|
||||
MenuIconItem { text: qsTr("Online"); iconSource: "image://theme/icon-m-wlan" }
|
||||
MenuIconItem { text: qsTr("Offline"); iconSource: "image://theme/icon-m-wlan-no-signal" }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
|
|
@ -296,10 +296,21 @@ Page {
|
|||
settings.offlineMode = true;
|
||||
}
|
||||
|
||||
description: qsTr("In the offline mode, Kaktus will only use local cache to get web pages and images, so "+
|
||||
description: qsTr("In offline mode, Kaktus will only use local cache to get web pages and images, so "+
|
||||
"network connection won't be needed.")
|
||||
}
|
||||
|
||||
TextSwitch {
|
||||
text: qsTr("Auto network mode")
|
||||
description: qsTr("Network mode will be switched automatically on network connection lost or restore.")
|
||||
onCheckedChanged: {
|
||||
settings.autoOffline = checked;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
checked = settings.autoOffline;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
width: root.width
|
||||
label: qsTr("Cache articles")
|
||||
|
|
@ -319,6 +330,95 @@ Page {
|
|||
"and cached for access in the offline mode.")
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Web viewer")
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
width: root.width
|
||||
label: qsTr("Open link behaviour")
|
||||
currentIndex: settings.webviewNavigation
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Disabled") }
|
||||
MenuIconItem { text: qsTr("External browser"); iconSource: "image://icons/icon-m-browser" }
|
||||
MenuIconItem { text: qsTr("Web viewer"); iconSource: "image://icons/icon-m-webview" }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
settings.webviewNavigation = currentIndex;
|
||||
}
|
||||
|
||||
description: qsTr("Defines how navigation is handled inside built-in web viewer. Hyperlinks could be disabled, opened in an external browser or opened inside web viewer.")
|
||||
}
|
||||
|
||||
TextSwitchWithIcon {
|
||||
text: qsTr("Auto switch to Reader View")
|
||||
description: qsTr("Reader View is a feature that strips away clutter like buttons, ads and background images, and changes the page's layout for better readability. By enabling this option, Reader View will be automatically switch on when page is loaded in the web viewer.")
|
||||
iconSource: settings.readerMode ? "image://icons/icon-m-reader-selected" : "image://icons/icon-m-reader"
|
||||
onCheckedChanged: {
|
||||
settings.readerMode = checked;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
checked = settings.readerMode;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
width: root.width
|
||||
label: qsTr("Reader View theme")
|
||||
description: qsTr("Style of theme which will be used to display articles in Reader View.")
|
||||
currentIndex: {
|
||||
if (settings.readerTheme === "dark")
|
||||
return 0;
|
||||
if (settings.readerTheme === "light")
|
||||
return 1;
|
||||
}
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Dark") }
|
||||
MenuItem { text: qsTr("Light") }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
settings.readerTheme = "dark";
|
||||
break;
|
||||
case 1:
|
||||
settings.readerTheme = "light";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextSwitchWithIcon {
|
||||
text: qsTr("Auto switch to Night View")
|
||||
description: qsTr("Night View reduces the brightness of websites. By enabling this option, Night View will be automatically switch on when page is loaded in the web viewer.")
|
||||
iconSource: settings.nightMode ? "image://icons/icon-m-night-selected" : "image://icons/icon-m-night"
|
||||
onCheckedChanged: {
|
||||
settings.nightMode = checked;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
checked = settings.nightMode;
|
||||
}
|
||||
}
|
||||
|
||||
Slider {
|
||||
width: root.width
|
||||
minimumValue: 50
|
||||
maximumValue: 200
|
||||
value: Math.floor(settings.zoom * 100)
|
||||
label: qsTr("Viewer font size level")
|
||||
valueText: value + "%"
|
||||
stepSize: 10
|
||||
onValueChanged: settings.zoom = value/100
|
||||
onClicked: {
|
||||
// Default value
|
||||
value = 100;
|
||||
}
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("UI")
|
||||
}
|
||||
|
|
@ -504,7 +604,7 @@ Page {
|
|||
}
|
||||
}*/
|
||||
|
||||
/*ComboBox {
|
||||
ComboBox {
|
||||
width: root.width
|
||||
label: qsTr("View mode")
|
||||
currentIndex: {
|
||||
|
|
@ -518,16 +618,33 @@ Page {
|
|||
case 4:
|
||||
return 3;
|
||||
case 5:
|
||||
case 6:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: settings.getSigninType()<10 ? qsTr("Tabs & Feeds") : qsTr("Folders & Feeds") }
|
||||
MenuItem { text: settings.getSigninType()<10 ? qsTr("Only Folders") : qsTr("Only Folders") }
|
||||
MenuItem { text: qsTr("All feeds") }
|
||||
MenuItem { text: settings.getSigninType()<10 ? qsTr("Saved") : qsTr("Starred") }
|
||||
MenuItem { text: qsTr("Slow") }
|
||||
MenuIconItem {
|
||||
text: app.isNetvibes ? qsTr("Tabs, feeds & articles") : qsTr("Folders, feeds & articles")
|
||||
iconSource: "image://icons/icon-m-vm0"
|
||||
}
|
||||
MenuIconItem {
|
||||
text: app.isNetvibes ? qsTr("Tabs & articles") : qsTr("Folders & articles")
|
||||
iconSource: "image://icons/icon-m-vm1"
|
||||
}
|
||||
MenuIconItem {
|
||||
text: qsTr("All articles")
|
||||
iconSource: "image://icons/icon-m-vm3"
|
||||
}
|
||||
MenuIconItem {
|
||||
text: app.isNetvibes || app.isFeedly ? qsTr("Saved") : qsTr("Starred")
|
||||
iconSource: "image://icons/icon-m-vm4"
|
||||
}
|
||||
MenuIconItem {
|
||||
enabled: app.isNetvibes || (app.isOldReader && settings.showBroadcast)
|
||||
text: app.isNetvibes ? qsTr("Slow") : qsTr("Liked")
|
||||
iconSource: app.isNetvibes ? "image://icons/icon-m-vm5" : "image://icons/icon-m-vm6"
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
|
|
@ -541,10 +658,14 @@ Page {
|
|||
case 3:
|
||||
settings.viewMode = 4; break;
|
||||
case 4:
|
||||
settings.viewMode = 5; break;
|
||||
if (app.isNetvibes)
|
||||
settings.viewMode = 5;
|
||||
else
|
||||
settings.viewMode = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
width: root.width
|
||||
|
|
@ -588,37 +709,21 @@ Page {
|
|||
currentIndex: settings.clickBehavior
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuIconItem { text: qsTr("Built-in viewer"); icon.source: "image://icons/icon-m-webview" }
|
||||
MenuIconItem { text: qsTr("External browser"); icon.source: "image://icons/icon-m-browser" }
|
||||
MenuIconItem { text: qsTr("Feed content"); icon.source: "image://icons/icon-m-rss" }
|
||||
MenuIconItem { text: qsTr("Web viewer"); iconSource: "image://icons/icon-m-webview" }
|
||||
MenuIconItem { text: qsTr("External browser"); iconSource: "image://icons/icon-m-browser" }
|
||||
MenuIconItem { text: qsTr("Feed content"); iconSource: "image://icons/icon-m-rss" }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
settings.clickBehavior = currentIndex;
|
||||
}
|
||||
|
||||
description: qsTr("Defines the behavior for clicking on an article item. Article can be opened in the built-in viewer, opened in an external browser or full RSS feed content can be shown.")
|
||||
description: qsTr("Defines the behavior for clicking on an article item. Article can be opened in the built-in web viewer, opened in an external browser or full RSS feed content can be shown.")
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
width: root.width
|
||||
label: qsTr("Open link behaviour")
|
||||
currentIndex: settings.webviewNavigation
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Disabled") }
|
||||
MenuIconItem { text: qsTr("External browser"); icon.source: "image://icons/icon-m-browser" }
|
||||
MenuIconItem { text: qsTr("Built-in viewer"); icon.source: "image://icons/icon-m-webview" }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
settings.webviewNavigation = currentIndex;
|
||||
}
|
||||
|
||||
description: qsTr("Defines how navigation is handled inside built-in viewer. Hyperlinks could be disabled, opened in an external browser or opened inside viewer.")
|
||||
}
|
||||
|
||||
TextSwitch {
|
||||
/*TextSwitch {
|
||||
text: qsTr("Show only unread articles")
|
||||
onCheckedChanged: {
|
||||
settings.showOnlyUnread = checked;
|
||||
|
|
@ -626,62 +731,29 @@ Page {
|
|||
Component.onCompleted: {
|
||||
checked = settings.showOnlyUnread;
|
||||
}
|
||||
}
|
||||
|
||||
TextSwitchWithIcon {
|
||||
text: qsTr("Auto switch to Reader View")
|
||||
description: qsTr("Reader View is a feature that strips away clutter like buttons, ads and background images, and changes the page's layout for better readability.")
|
||||
iconSource: "image://icons/icon-m-reader"
|
||||
onCheckedChanged: {
|
||||
settings.readerMode = checked;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
checked = settings.readerMode;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
ComboBox {
|
||||
width: root.width
|
||||
label: qsTr("Reader View theme")
|
||||
description: qsTr("Style theme which will be used to display articles in Reader View.")
|
||||
currentIndex: {
|
||||
if (settings.readerTheme === "dark")
|
||||
return 0;
|
||||
if (settings.readerTheme === "light")
|
||||
return 1;
|
||||
}
|
||||
label: qsTr("List filtering")
|
||||
currentIndex: settings.filter
|
||||
|
||||
menu: ContextMenu {
|
||||
MenuItem { text: qsTr("Dark") }
|
||||
MenuItem { text: qsTr("Light") }
|
||||
MenuIconItem { text: qsTr("All articles"); iconSource: "image://icons/icon-m-filter-0" }
|
||||
MenuIconItem { text: app.isNetvibes || app.isFeedly ? qsTr("Unread or saved") : qsTr("Unread & starred"); iconSource: "image://icons/icon-m-filter-1" }
|
||||
MenuIconItem { text: qsTr("Only unread"); iconSource: "image://icons/icon-m-filter-2" }
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
settings.readerTheme = "dark";
|
||||
break;
|
||||
case 1:
|
||||
settings.readerTheme = "light";
|
||||
break;
|
||||
}
|
||||
settings.filter = currentIndex;
|
||||
}
|
||||
|
||||
description: app.isNetvibes || app.isFeedly ?
|
||||
qsTr("List of articles can be filtered to display all articles, unread and saved or only unread.") :
|
||||
qsTr("List of articles can be filtered to display all articles, unread and starred or only unread.")
|
||||
}
|
||||
|
||||
Slider {
|
||||
width: root.width
|
||||
minimumValue: 50
|
||||
maximumValue: 200
|
||||
value: Math.floor(settings.zoom * 100)
|
||||
label: qsTr("Viewer font size level")
|
||||
valueText: value + "%"
|
||||
stepSize: 10
|
||||
onValueChanged: settings.zoom = value/100
|
||||
onClicked: {
|
||||
// Default value
|
||||
value = 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TextSwitch {
|
||||
text: qsTr("Expanded items")
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ Page {
|
|||
MenuItem {
|
||||
id: readItem
|
||||
text: qsTr("Mark all as read")
|
||||
enabled: model.unread!=0
|
||||
enabled: model.unread!==0
|
||||
visible: enabled
|
||||
onClicked: {
|
||||
tabModel.markAsRead(model.index);
|
||||
|
|
@ -201,7 +201,7 @@ Page {
|
|||
MenuItem {
|
||||
id: unreadItem
|
||||
text: qsTr("Mark all as unread")
|
||||
enabled: model.read!=0 && settings.signinType<10
|
||||
enabled: model.read!==0 && settings.signinType<10
|
||||
visible: enabled
|
||||
onClicked: {
|
||||
tabModel.markAsUnread(model.index);
|
||||
|
|
@ -214,7 +214,7 @@ Page {
|
|||
ViewPlaceholder {
|
||||
id: placeholder
|
||||
enabled: listView.count < 1
|
||||
text: fetcher.busy ? qsTr("Wait until Sync finish.") :
|
||||
text: fetcher.busy ? qsTr("Wait until sync finish") :
|
||||
settings.signinType<10 ? qsTr("No tabs") : qsTr("No folders")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ ApplicationWindow {
|
|||
property int oldViewMode
|
||||
|
||||
property bool isTablet: Screen.sizeCategory === Screen.Large || Screen.sizeCategory === Screen.ExtraLarge
|
||||
//property bool isTablet: Screen.width > 540
|
||||
|
||||
property bool isNetvibes: settings.signinType >= 0 && settings.signinType < 10
|
||||
property bool isOldReader: settings.signinType >= 10 && settings.signinType < 20
|
||||
|
|
@ -38,6 +37,18 @@ ApplicationWindow {
|
|||
|
||||
Component.onCompleted: {
|
||||
db.init();
|
||||
|
||||
if (settings.autoOffline) {
|
||||
if (dm.online) {
|
||||
if (settings.offlineMode) {
|
||||
settings.offlineMode = false
|
||||
}
|
||||
} else {
|
||||
if (!settings.offlineMode) {
|
||||
settings.offlineMode = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hideBar() {
|
||||
|
|
@ -57,7 +68,6 @@ ApplicationWindow {
|
|||
// Reconnect fetcher
|
||||
if (typeof fetcher === 'undefined') {
|
||||
var type = settings.signinType;
|
||||
//console.log("settings.signinType:",type);
|
||||
|
||||
if (type < 10)
|
||||
reconnectFetcher(1);
|
||||
|
|
@ -129,8 +139,8 @@ ApplicationWindow {
|
|||
fetcher.cancel(); dm.cancel();
|
||||
db.init();
|
||||
} else {
|
||||
if(!settings.helpDone)
|
||||
guide.showDelayed();
|
||||
/*if(!settings.helpDone)
|
||||
guide.showDelayed();*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +159,7 @@ ApplicationWindow {
|
|||
console.log("DB error! code="+code);
|
||||
|
||||
if (code==511) {
|
||||
notification.show(qsTr("Something went wrong :-(\nRestart the app to rebuild cache data."));
|
||||
notification.show(qsTr("Restart the app to rebuild cache data."), qsTr("Something went wrong :-("));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -173,28 +183,40 @@ ApplicationWindow {
|
|||
target: dm
|
||||
|
||||
onProgress: {
|
||||
if (current > 0 && total != 0) {
|
||||
progressPanelDm.text = qsTr("Caching... %1 of %2").arg(current).arg(total);
|
||||
progressPanelDm.progress = current / total;
|
||||
/*if (current == total) {
|
||||
progressPanelDm.text = qsTr("All done!");
|
||||
}*/
|
||||
} else {
|
||||
progressPanelDm.text = qsTr("Caching...");
|
||||
if (!app.fetcherBusyStatus) {
|
||||
if (current > 0 && total != 0) {
|
||||
bar.progressText= qsTr("Caching... %1 of %2").arg(current).arg(total);
|
||||
bar.progress = current / total;
|
||||
} else {
|
||||
bar.progressText = qsTr("Caching...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onOnlineChanged: {
|
||||
if (settings.autoOffline) {
|
||||
if (dm.online) {
|
||||
if (settings.offlineMode) {
|
||||
//notification.show(qsTr("Enabling online mode because network is connected."));
|
||||
settings.offlineMode = false
|
||||
}
|
||||
} else {
|
||||
if (!settings.offlineMode) {
|
||||
//notification.show(qsTr("Enabling offline mode because network is disconnected."));
|
||||
settings.offlineMode = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onNetworkNotAccessible: {
|
||||
notification.show(qsTr("Download failed!\nNetwork connection is unavailable."));
|
||||
notification.show(qsTr("Download has failed because network is disconnected."));
|
||||
}
|
||||
|
||||
onRemoverProgressChanged: {
|
||||
progressPanelRemover.progress = current / total;
|
||||
bar.progress = current / total;
|
||||
bar.progressText = qsTr("Removing cache data... %1 of %2").arg(current).arg(total);
|
||||
}
|
||||
|
||||
/*onError: {
|
||||
console.log("DM error code:", code);
|
||||
}*/
|
||||
}
|
||||
|
||||
function reconnectFetcher(type) {
|
||||
|
|
@ -306,75 +328,74 @@ ApplicationWindow {
|
|||
|
||||
} else {
|
||||
// Unknown error
|
||||
notification.show(qsTr("Something went wrong :-(\nAn unknown error occurred."));
|
||||
notification.show(qsTr("An unknown error occurred."), qsTr("Something went wrong :-("));
|
||||
resetView();
|
||||
}
|
||||
}
|
||||
|
||||
function fetcherErrorCheckingCredentials() {
|
||||
notification.show(qsTr("The user name or password is incorrect!"));
|
||||
notification.show(qsTr("The user name or password is incorrect."));
|
||||
}
|
||||
|
||||
function fetcherCredentialsValid() {
|
||||
notification.show(qsTr("You are signed in!"));
|
||||
notification.show(qsTr("You are signed in."));
|
||||
}
|
||||
|
||||
function fetcherProgress(current, total) {
|
||||
//console.log("fetcherProgress", current, total);
|
||||
progressPanel.text = qsTr("Receiving data... ");
|
||||
progressPanel.progress = current / total;
|
||||
bar.progressText = qsTr("Receiving data... ");
|
||||
bar.progress = current / total;
|
||||
}
|
||||
|
||||
function fetcherUploadProgress(current, total) {
|
||||
//console.log("fetcherUploadProgress", current, total);
|
||||
progressPanel.text = qsTr("Sending data...");
|
||||
progressPanel.progress = current / total;
|
||||
bar.progressText = qsTr("Sending data...");
|
||||
bar.progress = current / total;
|
||||
}
|
||||
|
||||
function fetcherUploading() {
|
||||
//console.log("fetcherUploading");
|
||||
progressPanel.text = qsTr("Sending data...");
|
||||
bar.progressText = qsTr("Sending data...");
|
||||
}
|
||||
|
||||
function fetcherBusyChanged() {
|
||||
|
||||
console.log("fetcherBusyChanged:", fetcher.busy, app.fetcherBusyStatus)
|
||||
if (app.fetcherBusyStatus != fetcher.busy)
|
||||
app.fetcherBusyStatus = fetcher.busy;
|
||||
|
||||
switch(fetcher.busyType) {
|
||||
case 1:
|
||||
progressPanel.text = qsTr("Initiating...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Initiating...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
case 2:
|
||||
progressPanel.text = qsTr("Updating...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Updating...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
case 3:
|
||||
progressPanel.text = qsTr("Signing in...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Signing in...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
case 4:
|
||||
progressPanel.text = qsTr("Signing in...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Signing in...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
case 11:
|
||||
progressPanel.text = qsTr("Waiting for network...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Waiting for network...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
case 21:
|
||||
progressPanel.text = qsTr("Waiting for network...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Waiting for network...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
case 31:
|
||||
progressPanel.text = qsTr("Waiting for network...");
|
||||
progressPanel.progress = 0;
|
||||
bar.progressText = qsTr("Waiting for network...");
|
||||
bar.progress = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function fetcherCanceled() {
|
||||
//notification.show(qsTr("Syncing canceled!"));
|
||||
resetView();
|
||||
}
|
||||
|
||||
|
|
@ -382,103 +403,42 @@ ApplicationWindow {
|
|||
id: notification
|
||||
}
|
||||
|
||||
property int panelHeightPortrait: Theme.itemSizeMedium
|
||||
property int panelHeightLandscape: Theme.itemSizeMedium
|
||||
property int barHeightPortrait: Theme.itemSizeMedium
|
||||
property int barHeightLandscape: Theme.itemSizeMedium
|
||||
property int panelHeight: app.orientation==Orientation.Portrait ? app.panelHeightPortrait : app.panelHeightLandscape
|
||||
property int panelWidth: app.orientation==Orientation.Portrait ? Screen.width : Screen.height
|
||||
property int barHeight: app.orientation==Orientation.Portrait ? app.barHeightPortrait : app.barHeightLandscape
|
||||
property int barWidth: app.orientation==Orientation.Portrait ? Screen.width : Screen.height
|
||||
property int landscapeContentPanelWidth: isTablet ?
|
||||
app.orientation==Orientation.Portrait ? Screen.width-700 : Screen.height-700 :
|
||||
app.orientation==Orientation.Portrait ? Screen.width/2 : Screen.height/2
|
||||
|
||||
app.orientation==Orientation.Portrait ? Screen.width-700 : Screen.height-700 :
|
||||
app.orientation==Orientation.Portrait ? Screen.width/2 : Screen.height/2
|
||||
property int flickHeight: {
|
||||
var size = 0;
|
||||
var size = 0
|
||||
if (bar.open)
|
||||
size += barHeight;
|
||||
if (progressPanel.open||progressPanelRemover.open||progressPanelDm.open)
|
||||
size += panelHeight;
|
||||
size += bar.stdHeight
|
||||
return app.orientation==Orientation.Portrait ? Screen.height-size : Screen.width-size;
|
||||
}
|
||||
property int barX: {
|
||||
if (app.orientation==Orientation.Portrait)
|
||||
return 0;
|
||||
if (bar.open && (progressPanel.open||progressPanelRemover.open||progressPanelDm.open))
|
||||
return app.barHeightLandscape + app.panelHeightLandscape;
|
||||
return app.barHeightLandscape;
|
||||
}
|
||||
property int barY: {
|
||||
if (app.orientation==Orientation.Portrait) {
|
||||
if (bar.open && (progressPanel.open||progressPanelRemover.open||progressPanelDm.open))
|
||||
return Screen.height - (app.barHeightPortrait + app.panelHeightPortrait);
|
||||
return Screen.height - app.barHeightPortrait;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
property int panelX: app.orientation==Orientation.Portrait ? 0 : app.panelHeight
|
||||
property int panelY: app.orientation==Orientation.Portrait ? Screen.height-app.panelHeight : 0
|
||||
property int barX: app.orientation==Orientation.Portrait ? 0 : bar.height
|
||||
property int barY: app.orientation==Orientation.Portrait ? Screen.height - bar.height : 0
|
||||
readonly property alias barHeight: bar.height
|
||||
|
||||
ControlBar {
|
||||
id: bar
|
||||
busy: app.fetcherBusyStatus || dm.removerBusy || dm.busy
|
||||
rotation: app.orientation==Orientation.Portrait ? 0 : 90
|
||||
transformOrigin: Item.TopLeft
|
||||
height: app.barHeight
|
||||
width: app.barWidth
|
||||
width: app.panelWidth
|
||||
|
||||
onCancelClicked: {
|
||||
dm.cancel()
|
||||
fetcher.cancel()
|
||||
dm.removerCancel()
|
||||
}
|
||||
|
||||
onBusyChanged: {
|
||||
if (!busy)
|
||||
hide()
|
||||
}
|
||||
|
||||
y: app.barY
|
||||
x: app.barX
|
||||
}
|
||||
|
||||
ProgressPanel {
|
||||
id: progressPanelRemover
|
||||
open: dm.removerBusy
|
||||
onCloseClicked: dm.removerCancel();
|
||||
transparent: false
|
||||
|
||||
rotation: app.orientation==Orientation.Portrait ? 0 : 90
|
||||
transformOrigin: Item.TopLeft
|
||||
height: app.panelHeight
|
||||
width: app.panelWidth
|
||||
y: app.panelY
|
||||
x: app.panelX
|
||||
text: qsTr("Removing cache data...");
|
||||
Behavior on y { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
Behavior on x { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
}
|
||||
|
||||
ProgressPanel {
|
||||
id: progressPanelDm
|
||||
open: dm.busy && !app.fetcherBusyStatus
|
||||
onCloseClicked: dm.cancel();
|
||||
transparent: false
|
||||
|
||||
rotation: app.orientation==Orientation.Portrait ? 0 : 90
|
||||
transformOrigin: Item.TopLeft
|
||||
height: app.panelHeight
|
||||
width: app.panelWidth
|
||||
y: app.panelY
|
||||
x: app.panelX
|
||||
Behavior on y { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
Behavior on x { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
}
|
||||
|
||||
ProgressPanel {
|
||||
id: progressPanel
|
||||
open: app.fetcherBusyStatus
|
||||
onCloseClicked: fetcher.cancel();
|
||||
transparent: false
|
||||
|
||||
rotation: app.orientation==Orientation.Portrait ? 0 : 90
|
||||
transformOrigin: Item.TopLeft
|
||||
height: app.panelHeight
|
||||
width: app.panelWidth
|
||||
y: app.panelY
|
||||
x: app.panelX
|
||||
Behavior on y { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
Behavior on x { NumberAnimation { duration: 200;easing.type: Easing.OutQuad } }
|
||||
}
|
||||
|
||||
Guide {
|
||||
id: guide
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,6 @@
|
|||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
||||
//#include <QWebPage>
|
||||
//#include <QWebFrame>
|
||||
//#include <QWebElement>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QUrlQuery>
|
||||
#endif
|
||||
|
|
@ -196,70 +192,16 @@ bool FilteringWorker::filterArticle()
|
|||
return true;
|
||||
}
|
||||
|
||||
/*void FilteringWorker::advancedFilter()
|
||||
{
|
||||
QUrl url(item.baseUrl);
|
||||
|
||||
if (url.host().contains("reddit.com")) {
|
||||
QWebPage page;
|
||||
QWebFrame *frame = page.mainFrame();
|
||||
frame->setHtml(content);
|
||||
QWebElement el1 = frame->findFirstElement("div[role='banner']");
|
||||
if (!el1.isNull())
|
||||
el1.removeFromDocument();
|
||||
content = frame->toHtml();
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "-2";
|
||||
|
||||
if (url.host().contains("lightreading.com")) {
|
||||
QWebPage page;
|
||||
qDebug() << "-1";
|
||||
QWebFrame *frame = page.mainFrame();
|
||||
frame->setHtml(content);
|
||||
|
||||
qDebug() << "0";
|
||||
QWebElement el1 = frame->findFirstElement("article");
|
||||
if (!el1.isNull()) {
|
||||
qDebug() << "1";
|
||||
QWebElement el2 = frame->findFirstElement("div[name='msgqueue']");
|
||||
QWebElement body = frame->findFirstElement("body");
|
||||
if (!body.isNull()) {
|
||||
qDebug() << "2";
|
||||
body.removeFromDocument();
|
||||
QWebElement head = frame->findFirstElement("head");
|
||||
head.appendOutside(el2);
|
||||
head.appendOutside(el1);
|
||||
content = frame->toHtml();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
void FilteringWorker::filter()
|
||||
{
|
||||
QUrl url(item.baseUrl);
|
||||
bool dofilterArticle = true;
|
||||
if (url.host().contains("engadget.com")) {
|
||||
dofilterArticle = false;
|
||||
}
|
||||
|
||||
if (dofilterArticle)
|
||||
filterArticle();
|
||||
|
||||
QRegExp rxLinkAll("<link[^>]*>", Qt::CaseInsensitive);
|
||||
QRegExp rxScriptAll("<script[^>]*>((?!<\\/script>).)*<\\/script>", Qt::CaseInsensitive);
|
||||
QRegExp rxStyleAll("<style[^>]*>((?!<\\/style>).)*<\\/style>", Qt::CaseInsensitive);
|
||||
QRegExp rxStyle("\\s*style\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxClass("\\s*class\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
//QRegExp rxId("\\s*id\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxWidth("\\s*width\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxHeight("\\s*height\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxMetaViewport("<meta\\s[^>]*name\\s*=(\"viewport\"|'viewport')[^>]*>", Qt::CaseInsensitive);
|
||||
//QRegExp rxMetaAll("<meta[^>]*>", Qt::CaseInsensitive);
|
||||
//QRegExp rxFormAll("<form[^>]*>((?!<\\/form>).)*<\\/form>", Qt::CaseInsensitive);
|
||||
QRegExp rxInputAll("<input[^>]*>", Qt::CaseInsensitive);
|
||||
QRegExp rxTextareaAll("<textarea[^>]*>((?!<\\/textarea>).)*<\\/textarea>", Qt::CaseInsensitive);
|
||||
QRegExp rxObjectAll("<object[^>]*>((?!<\\/object>).)*<\\/object>", Qt::CaseInsensitive);
|
||||
|
|
@ -283,79 +225,30 @@ void FilteringWorker::filter()
|
|||
content.remove(rxNoscriptAll);
|
||||
content.remove(rxSelectAll);
|
||||
content.remove(rxNavAll);
|
||||
|
||||
// Applying Theme's style
|
||||
QUrl query = req->url();
|
||||
Settings *s = Settings::instance();
|
||||
QString style, fontsize, highlightColor, secondaryHighlightColor;
|
||||
int margin = 0;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
QUrlQuery urlQuery(query);
|
||||
if (urlQuery.hasQueryItem("fontsize"))
|
||||
fontsize = urlQuery.queryItemValue("fontsize");
|
||||
if (urlQuery.hasQueryItem("highlightColor"))
|
||||
highlightColor = urlQuery.queryItemValue("highlightColor");
|
||||
if (urlQuery.hasQueryItem("secondaryHighlightColor"))
|
||||
secondaryHighlightColor = urlQuery.queryItemValue("secondaryHighlightColor");
|
||||
if (urlQuery.hasQueryItem("margin"))
|
||||
margin = urlQuery.queryItemValue("margin").toInt();
|
||||
#else
|
||||
if (query.hasQueryItem("fontsize"))
|
||||
fontsize= query.queryItemValue("fontsize");
|
||||
if (query.hasQueryItem("highlightColor"))
|
||||
highlightColor = query.queryItemValue("highlightColor");
|
||||
if (query.hasQueryItem("secondaryHighlightColor"))
|
||||
secondaryHighlightColor = query.queryItemValue("secondaryHighlightColor");
|
||||
if (query.hasQueryItem("margin"))
|
||||
margin = query.queryItemValue("margin").toInt();
|
||||
#endif
|
||||
|
||||
QString initialScale = "1.0";
|
||||
|
||||
if (s->getOfflineTheme() == "white") {
|
||||
style = QString("<meta name='viewport' content='initial-scale=%6'>"
|
||||
"<style>a,h1,h2,h3,div,p,pre,code{word-wrap:break-word}body{margin:%5px;background:#FFF;font-family:sans-serif;font-size:%1;color:#323232;}figure{margin:0;padding:0;}a:link{color:#%2;}a:visited{color:#%4;}a:active{color:#%3;}img{max-width:100%;max-height:device-height;}</style></head>")
|
||||
.arg(fontsize).arg(highlightColor).arg(highlightColor).arg(secondaryHighlightColor).arg(margin).arg(initialScale);
|
||||
}
|
||||
|
||||
if (s->getOfflineTheme() == "black") {
|
||||
style = QString("<meta name='viewport' content='initial-scale=%6'>"
|
||||
"<style>a,h1,h2,h3,div,p,pre,code{word-wrap:break-word}body{margin:%5px;background:#141414;font-family:sans-serif;font-size:%1;color:#FFF;}figure{margin:0;padding:0;}a:link{color:#%2;}a:visited{color:#%4;}a:active{color:#%3;}img{max-width:100%;max-height:device-height;}</style></head>")
|
||||
.arg(fontsize).arg(highlightColor).arg(highlightColor).arg(secondaryHighlightColor).arg(margin).arg(initialScale);
|
||||
//qDebug() << style;
|
||||
}
|
||||
|
||||
QRegExp rxHeadEnd("</head>", Qt::CaseInsensitive);
|
||||
content.replace(rxHeadEnd,style);
|
||||
}
|
||||
|
||||
void FilteringWorker::filterOnline()
|
||||
{
|
||||
filter();
|
||||
//advancedFilter();
|
||||
|
||||
//QRegExp rxCss("<link\\s[^>]*rel\\s*=(\"stylesheet\"|'stylesheet')[^>]*href\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxImg("(<img\\s[^>]*)src\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
resolveRelativeUrls(rxImg);
|
||||
QRegExp rxA("(<a\\s[^>]*)href\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
resolveRelativeUrls(rxA);
|
||||
//QRegExp rxImg("(<img\\s[^>]*)src\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
//resolveRelativeUrls(rxImg);
|
||||
//QRegExp rxA("(<a\\s[^>]*)href\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
//resolveRelativeUrls(rxA);
|
||||
}
|
||||
|
||||
void FilteringWorker::filterOffline()
|
||||
{
|
||||
filter();
|
||||
|
||||
//QRegExp rxMetaAll("<meta[^>]*>", Qt::CaseInsensitive);
|
||||
//QRegExp rxA("(<a\\s[^>]*)href\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxUrl("url[\\s]*\\([^\\)]*\\)", Qt::CaseInsensitive);
|
||||
QRegExp rxImgAll("<img[^>]*>", Qt::CaseInsensitive);
|
||||
QRegExp rxFrame("(<iframe\\s[^>]*)src\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
||||
QRegExp rxBody("(<body[^>]*>)", Qt::CaseInsensitive);
|
||||
|
||||
//content.replace(rxA,"\\1href='#'");
|
||||
//removeUrls(content, rxA);
|
||||
content.replace(rxUrl,"http://0.0.0.0");
|
||||
content.replace(rxImgAll,"");
|
||||
content.replace(rxImgAll,""); content.remove("</img>", Qt::CaseInsensitive);
|
||||
content.replace(rxFrame,"\\1");
|
||||
|
||||
// Inserting image after <body> tag
|
||||
|
|
@ -363,8 +256,12 @@ void FilteringWorker::filterOffline()
|
|||
QString image = "";
|
||||
if(item.entryId!="")
|
||||
image = s->db->readEntryImageById(item.entryId);
|
||||
if (image!="") {
|
||||
content.replace(rxBody,QString("\\1<img src=\"%1\"/>").arg(s->cache->getUrlbyUrl(image)));
|
||||
if (!image.isEmpty()) {
|
||||
image = QString(CacheServer::getDataUrlByUrl(image));
|
||||
if (!image.isEmpty()) {
|
||||
content.replace(rxBody,QString("\\1<img id='_kaktus_img' src='%1'/>")
|
||||
.arg(image));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -524,65 +421,8 @@ void CacheServer::handleFinish()
|
|||
delete(worker);
|
||||
}
|
||||
|
||||
|
||||
/*#define HOST_FILTER 0x01 // => 0001
|
||||
#define REMOVE_FILTER 0x02 // => 0010
|
||||
|
||||
void CacheServer::resolveRelativeUrls(QString &content, const QRegExp &rx, const QUrl &baseUrl, int filter)
|
||||
{
|
||||
QStringList list = baseUrl.host().split(".");
|
||||
QString baseHost = list.at(list.length()-2);
|
||||
|
||||
int i = 1, pos = 0;
|
||||
QStringList caps;
|
||||
while ((pos = rx.indexIn(content, pos)) != -1) {
|
||||
QString cap = rx.cap(2); cap = cap.mid(1,cap.length()-2);
|
||||
caps.append(cap);
|
||||
pos += rx.matchedLength();
|
||||
++i;
|
||||
}
|
||||
|
||||
//qDebug() << filter << (filter & REMOVE_FILTER) ;
|
||||
|
||||
QStringList::iterator it = caps.begin();
|
||||
while (it != caps.end()) {
|
||||
QString cap = *it;
|
||||
QUrl capUrl(cap);
|
||||
|
||||
if ((filter & REMOVE_FILTER) != 0) {
|
||||
content.replace(cap, "");
|
||||
qDebug() << "removed cap=" << cap;
|
||||
} else if (capUrl.isRelative()) {
|
||||
content.replace(cap, baseUrl.resolved(capUrl).toString());
|
||||
} else {
|
||||
qDebug() << "filter, host=" << capUrl.host() << "base host=" << baseUrl.host();
|
||||
if ((filter & HOST_FILTER) != 0) {
|
||||
// Host filter => Removing URL if host not match base URL's host
|
||||
list = capUrl.host().split(".");
|
||||
if (list.length()>1) {
|
||||
QString capHost = list.at(list.length()-2);
|
||||
qDebug() << "filter, capHost=" << capHost << "baseHost=" << baseHost;
|
||||
if (capHost!=baseHost) {
|
||||
qDebug() << "replace";
|
||||
content.replace(cap, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*QString CacheServer::hash(const QString &url)
|
||||
{
|
||||
QByteArray data; data.append(url);
|
||||
return QString(QCryptographicHash::hash(data, QCryptographicHash::Md5).toHex());
|
||||
}*/
|
||||
|
||||
QString CacheServer::getUrlbyId(const QString &item)
|
||||
{
|
||||
//return "http://127.0.0.1:" + QString::number(port) + "/" + item;
|
||||
return "http://localhost:" + QString::number(port) + "/" + item;
|
||||
}
|
||||
|
||||
|
|
@ -595,10 +435,33 @@ QString CacheServer::getUrlbyUrl(const QString &url)
|
|||
return url;
|
||||
}
|
||||
|
||||
//return "http://127.0.0.1:" + QString::number(port) + "/" + Utils::hash(url);
|
||||
return "http://localhost:" + QString::number(port) + "/" + Utils::hash(url);
|
||||
}
|
||||
|
||||
QByteArray CacheServer::getDataUrlByUrl(const QString &url)
|
||||
{
|
||||
Settings *s = Settings::instance();
|
||||
|
||||
QString entryId = Utils::hash(url);
|
||||
DatabaseManager::CacheItem item = s->db->readCacheByEntry(entryId);
|
||||
|
||||
QString filename;
|
||||
if (item.id == "") {
|
||||
item = s->db->readCacheByFinalUrl(entryId);
|
||||
filename = entryId;
|
||||
} else {
|
||||
filename = item.finalUrl;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
if (!CacheServer::readFile(filename, data)) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QStringList ct = item.contentType.split(';');
|
||||
return QString("data:"+ct[0]+";base64,").toUtf8() + data.toBase64();
|
||||
}
|
||||
|
||||
QString CacheServer::getCacheUrlbyUrl(const QString &url)
|
||||
{
|
||||
// If url is "image://" will not be hashed
|
||||
|
|
|
|||
|
|
@ -69,13 +69,13 @@ class CacheServer : public QObject
|
|||
public:
|
||||
static bool readFile(const QString &filename, QByteArray &data);
|
||||
static QString getFileUrl(const QString &id);
|
||||
static QByteArray getDataUrlByUrl(const QString &item);
|
||||
|
||||
explicit CacheServer(QObject *parent = 0);
|
||||
~CacheServer();
|
||||
Q_INVOKABLE QString getUrlbyId(const QString &item);
|
||||
Q_INVOKABLE QString getUrlbyUrl(const QString &item);
|
||||
Q_INVOKABLE QString getCacheUrlbyUrl(const QString &item);
|
||||
//Q_INVOKABLE QByteArray getData(const QString &id);
|
||||
|
||||
public slots:
|
||||
void handle(QHttpRequest *req, QHttpResponse *resp);
|
||||
|
|
|
|||
|
|
@ -34,11 +34,16 @@
|
|||
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
class DatabaseManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY (bool synced READ isSynced NOTIFY syncedChanged)
|
||||
|
||||
public:
|
||||
static const int version = 23;
|
||||
|
||||
static const int dashboardsLimit = 100;
|
||||
static const int tabsLimit = 100;
|
||||
static const int streamLimit = 100;
|
||||
|
|
@ -172,6 +177,8 @@ public:
|
|||
Q_INVOKABLE void init();
|
||||
Q_INVOKABLE void newInit();
|
||||
|
||||
bool isSynced();
|
||||
|
||||
void cleanDashboards();
|
||||
void cleanTabs();
|
||||
void cleanModules();
|
||||
|
|
@ -235,7 +242,9 @@ public:
|
|||
|
||||
QList<Entry> readEntriesByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesUnreadByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesUnreadAndSavedByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesSlowUnreadByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesSlowUnreadAndSavedByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesSavedByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
//QList<Entry> readEntriesSaved(int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesSlowByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
|
|
@ -243,8 +252,10 @@ public:
|
|||
QList<Entry> readEntriesBroadcastByDashboard(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesByStream(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesUnreadByStream(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesUnreadAndSavedByStream(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesByTab(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesUnreadByTab(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesUnreadAndSavedByTab(const QString &id, int offset, int limit, bool ascOrder = false);
|
||||
QList<Entry> readEntriesCachedOlderThan(int cacheDate, int limit);
|
||||
QList<QString> readCacheFinalUrlOlderThan(int cacheDate, int limit);
|
||||
QList<QString> readCacheIdsOlderThan(int cacheDate, int limit);
|
||||
|
|
@ -320,8 +331,9 @@ signals:
|
|||
void empty();
|
||||
void notEmpty();
|
||||
|
||||
void syncedChanged();
|
||||
|
||||
private:
|
||||
static const QString version;
|
||||
QSqlDatabase db;
|
||||
QString dbFilePath;
|
||||
|
||||
|
|
@ -329,9 +341,9 @@ private:
|
|||
|
||||
bool openDB();
|
||||
bool createDB();
|
||||
bool alterDB_19to22();
|
||||
bool alterDB_20to22();
|
||||
bool alterDB_21to22();
|
||||
//bool alterDB_19to22();
|
||||
//bool alterDB_20to22();
|
||||
//bool alterDB_21to22();
|
||||
bool deleteDB();
|
||||
|
||||
bool createStructure();
|
||||
|
|
|
|||
|
|
@ -29,14 +29,42 @@
|
|||
#include "entrymodel.h"
|
||||
#include "utils.h"
|
||||
|
||||
EntryModelIniter::EntryModelIniter(QObject *parent) :
|
||||
QThread(parent), feedId()
|
||||
{}
|
||||
|
||||
void EntryModelIniter::init(EntryModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
this->feedId.clear();
|
||||
this->start(QThread::LowestPriority);
|
||||
}
|
||||
|
||||
void EntryModelIniter::init(EntryModel *model, const QString &feedId)
|
||||
{
|
||||
this->model = model;
|
||||
this->feedId = feedId;
|
||||
this->start(QThread::LowestPriority);
|
||||
}
|
||||
|
||||
void EntryModelIniter::run()
|
||||
{
|
||||
if (feedId.isEmpty())
|
||||
this->model->init();
|
||||
else
|
||||
this->model->init(feedId);
|
||||
|
||||
}
|
||||
|
||||
EntryModel::EntryModel(DatabaseManager *db, QObject *parent) :
|
||||
ListModel(new EntryItem, parent)
|
||||
ListModel(new EntryItem, parent), initer(parent)
|
||||
{
|
||||
_db = db;
|
||||
reInit = false;
|
||||
|
||||
Settings *s = Settings::instance();
|
||||
connect(s,SIGNAL(showOnlyUnreadChanged()),this,SLOT(init()));
|
||||
connect(s,SIGNAL(filterChanged()),this,SLOT(initInThread()));
|
||||
connect(&initer,SIGNAL(finished()),this,SLOT(initFinished()));
|
||||
connect(s,SIGNAL(showOldestFirstChanged()),this,SLOT(init()));
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +85,22 @@ void EntryModel::init()
|
|||
emit ready();
|
||||
}
|
||||
|
||||
void EntryModel::initInThread(const QString &feedId)
|
||||
{
|
||||
this->initer.init(this, feedId);
|
||||
}
|
||||
|
||||
void EntryModel::initInThread()
|
||||
{
|
||||
this->initer.init(this);
|
||||
}
|
||||
|
||||
void EntryModel::initFinished()
|
||||
{
|
||||
this->beginResetModel();
|
||||
this->endResetModel();
|
||||
}
|
||||
|
||||
/*int EntryModel::fixIndex(const QString &id)
|
||||
{
|
||||
int l = this->rowCount();
|
||||
|
|
@ -119,29 +163,37 @@ int EntryModel::createItems(int offset, int limit)
|
|||
switch (mode) {
|
||||
case 0:
|
||||
// View mode: Tabs->Feeds->Entries
|
||||
if (s->getShowOnlyUnread())
|
||||
if (s->getFilter() == 2)
|
||||
list = _db->readEntriesUnreadByStream(_feedId,offset,limit,ascOrder);
|
||||
else if (s->getFilter() == 1)
|
||||
list = _db->readEntriesUnreadAndSavedByStream(_feedId,offset,limit,ascOrder);
|
||||
else
|
||||
list = _db->readEntriesByStream(_feedId,offset,limit,ascOrder);
|
||||
break;
|
||||
case 1:
|
||||
// View mode: Tabs->Entries
|
||||
if (s->getShowOnlyUnread())
|
||||
if (s->getFilter() == 2)
|
||||
list = _db->readEntriesUnreadByTab(_feedId,offset,limit,ascOrder);
|
||||
else if (s->getFilter() == 1)
|
||||
list = _db->readEntriesUnreadAndSavedByTab(_feedId,offset,limit,ascOrder);
|
||||
else
|
||||
list = _db->readEntriesByTab(_feedId,offset,limit,ascOrder);
|
||||
break;
|
||||
case 2:
|
||||
// View mode: Feeds->Entries
|
||||
if (s->getShowOnlyUnread())
|
||||
if (s->getFilter() == 2)
|
||||
list = _db->readEntriesUnreadByStream(_feedId,offset,limit,ascOrder);
|
||||
else if (s->getFilter() == 1)
|
||||
list = _db->readEntriesUnreadAndSavedByStream(_feedId,offset,limit,ascOrder);
|
||||
else
|
||||
list = _db->readEntriesByStream(_feedId,offset,limit,ascOrder);
|
||||
break;
|
||||
case 3:
|
||||
// View mode: Entries
|
||||
if (s->getShowOnlyUnread())
|
||||
if (s->getFilter() == 2)
|
||||
list = _db->readEntriesUnreadByDashboard(s->getDashboardInUse(),offset,limit,ascOrder);
|
||||
else if (s->getFilter() == 1)
|
||||
list = _db->readEntriesUnreadAndSavedByDashboard(s->getDashboardInUse(),offset,limit,ascOrder);
|
||||
else
|
||||
list = _db->readEntriesByDashboard(s->getDashboardInUse(),offset,limit,ascOrder);
|
||||
break;
|
||||
|
|
@ -151,8 +203,10 @@ int EntryModel::createItems(int offset, int limit)
|
|||
break;
|
||||
case 5:
|
||||
// View mode: Slow
|
||||
if (s->getShowOnlyUnread())
|
||||
if (s->getFilter() == 2)
|
||||
list = _db->readEntriesSlowUnreadByDashboard(s->getDashboardInUse(),offset,limit,ascOrder);
|
||||
else if (s->getFilter() == 1)
|
||||
list = _db->readEntriesSlowUnreadAndSavedByDashboard(s->getDashboardInUse(),offset,limit,ascOrder);
|
||||
else
|
||||
list = _db->readEntriesSlowByDashboard(s->getDashboardInUse(),offset,limit,ascOrder);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,11 +25,29 @@
|
|||
#include <QByteArray>
|
||||
#include <QVariant>
|
||||
#include <QHash>
|
||||
#include <QThread>
|
||||
|
||||
#include "listmodel.h"
|
||||
#include "feedmodel.h"
|
||||
#include "databasemanager.h"
|
||||
|
||||
class EntryModel;
|
||||
|
||||
class EntryModelIniter : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EntryModelIniter(QObject *parent = 0);
|
||||
void init(EntryModel *model);
|
||||
void init(EntryModel *model, const QString &feedId);
|
||||
|
||||
private:
|
||||
QString feedId;
|
||||
EntryModel *model;
|
||||
void run();
|
||||
};
|
||||
|
||||
class EntryItem : public ListItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -139,6 +157,7 @@ public:
|
|||
|
||||
explicit EntryModel(DatabaseManager* db, QObject *parent = 0);
|
||||
void init(const QString &feedId);
|
||||
void initInThread(const QString &feedId);
|
||||
|
||||
Q_INVOKABLE void setData(int row, const QString &fieldName, QVariant newValue, QVariant newValue2);
|
||||
|
||||
|
|
@ -156,6 +175,8 @@ public:
|
|||
|
||||
public slots:
|
||||
void init();
|
||||
void initInThread();
|
||||
void initFinished();
|
||||
|
||||
signals:
|
||||
void ready();
|
||||
|
|
@ -164,6 +185,7 @@ private:
|
|||
static const int idsOnActionLimit = 100;
|
||||
DatabaseManager* _db;
|
||||
QString _feedId;
|
||||
EntryModelIniter initer;
|
||||
|
||||
int getDateRowId(int date);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ IconProvider::IconProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap)
|
|||
//qDebug() << "ratio:" << ratio;
|
||||
if (ratio == 0) {
|
||||
qWarning() << "Pixel ratio is 0, defaulting to 1.0.";
|
||||
themeDir = SailfishApp::pathTo("images/z1.5").toString(QUrl::RemoveScheme);
|
||||
themeDir = SailfishApp::pathTo("images/z1.0").toString(QUrl::RemoveScheme);
|
||||
} else if (ratio == 1.0) {
|
||||
themeDir = SailfishApp::pathTo("images/z1.0").toString(QUrl::RemoveScheme);
|
||||
} else if (ratio == 1.25) {
|
||||
|
|
|
|||
|
|
@ -39,9 +39,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.4.0 (light edition)";
|
||||
static const char *VERSION = "2.5.0 (light edition)";
|
||||
#else
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *VERSION = "2.5.0";
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
@ -61,6 +61,7 @@ int main(int argc, char *argv[])
|
|||
view->engine()->addImageProvider(QLatin1String("nvicons"), new NvIconProvider);
|
||||
|
||||
qRegisterMetaType<DatabaseManager::CacheItem>("CacheItem");
|
||||
//qmlRegisterMetaType<QQmlChangeSet>()
|
||||
|
||||
Settings* settings = Settings::instance();
|
||||
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ void Utils::setEntryModel(const QString &feedId)
|
|||
Settings *s = Settings::instance();
|
||||
|
||||
entryModel = new EntryModel(s->db);
|
||||
entryModel->init(feedId);
|
||||
entryModel->initInThread(feedId);
|
||||
|
||||
#ifdef BB10
|
||||
s->qml->setContextProperty("entryModel", entryModel);
|
||||
|
|
|
|||