Merge branch 'labels' of git://github.com/michael-k/ttrss into michael-k-labels

This commit is contained in:
Hauke Schade 2014-10-28 19:56:22 +01:00
commit 79662069c1
6 changed files with 308 additions and 9 deletions

View file

@ -29,7 +29,7 @@ Rectangle {
width: text.width + MyTheme.paddingSmall + MyTheme.paddingSmall
height: text.height + MyTheme.paddingSmall
color: root.label.bgcolor
color: root.label.bg_color
radius: MyTheme.paddingSmall
anchors.margins: MyTheme.paddingSmall
Text {
@ -38,8 +38,8 @@ Rectangle {
horizontalCenter: root.horizontalCenter
}
id: text
text: root.label.text
color: root.label.fgcolor
text: root.label.caption
color: root.label.fg_color
font.pixelSize: MyTheme.fontSizeExtraSmall
}
MouseArea {

View file

@ -92,9 +92,9 @@ ListModel {
for (var l = 0; l < labelcount; l++) {
labels[l] = {
'id': parseInt(feeditems[feeditem].labels[l][0]),
'fgcolor': (feeditems[feeditem].labels[l][2] == "" ? "black" : feeditems[feeditem].labels[l][2]),
'bgcolor': (feeditems[feeditem].labels[l][3] == "" ? "white" : feeditems[feeditem].labels[l][3]),
'text': feeditems[feeditem].labels[l][1]
'caption': feeditems[feeditem].labels[l][1],
'fg_color': (feeditems[feeditem].labels[l][2] === "" ? "black" : feeditems[feeditem].labels[l][2]),
'bg_color': (feeditems[feeditem].labels[l][3] === "" ? "white" : feeditems[feeditem].labels[l][3])
}
}

View file

@ -912,6 +912,118 @@ function process_updateFeedUnread(callback, httpreq) {
}
}
/**
* Get the list of configured labels with a flag if a label is assigned to a
* specific article.
* @param {int} The id of the article.
* @param {function} A callback function with parameters boolean (indicating
* success), string (an optional error message), and array (the labels as
* objects).
*/
function getLabels(articleId, callback) {
if(responsesPending['getlabel'])
return;
if(!state['token']) {
requestsPending['getlabel'] = true;
processPendingRequests(callback)
return;
}
if (state['apilevel'] < 1) {
callback(false, "Retrieving labels isn't supported by API");
return;
}
responsesPending['getlabel'] = true
var params = {
'op': 'getLabels',
'sid': state['token'],
'article_id': articleId
}
networkCall(params, function(http) { process_getLabels(callback, http) });
}
/** @private */
function process_getLabels(callback, httpreq) {
var response = process_readyState(httpreq);
responsesPending['getlabel'] = false;
if (!response.successful) {
trace(1, "Get labels: " + response.errorMessage);
if (callback) {
callback(false, response.errorMessage);
}
return;
}
if(!processPendingRequests(callback) && callback) {
// This action is complete (as there's no other requests to do)
// Fire callback saying all ok
callback(true, "", response.content);
}
}
/**
* Assign an article to a label or remove article from it.
* @param {int} The id of the article.
* @param {int} The id of the label.
* @param {boolean} Assign to or remove from label.
* @param {function} A callback function with parameters boolean (indicating
* success) and string (an optional error message).
*/
function setLabel(articleId, labelId, assign, callback) {
if(responsesPending['setlabel'])
return;
if(!state['token']) {
requestsPending['setlabel'] = true;
processPendingRequests(callback)
return;
}
if (state['apilevel'] < 1) {
callback(false, "Assigning labels isn't supported by API");
return;
}
responsesPending['setlabel'] = true
var params = {
'op': 'setArticleLabel',
'sid': state['token'],
'article_ids': articleId,
'label_id': labelId,
'assign': assign
}
networkCall(params, function(http) { process_setLabel(callback, http) });
}
/** @private */
function process_setLabel(callback, httpreq) {
var response = process_readyState(httpreq);
responsesPending['setlabel'] = false;
if (!response.successful) {
trace(1, "Set label: " + response.errorMessage);
if (callback) {
callback(false, response.errorMessage);
}
return;
}
if(!processPendingRequests(callback) && callback) {
// This action is complete (as there's no other requests to do)
// Fire callback saying all ok
callback(true);
}
}
/**
* @private
* @return {boolean} Whether some pending stuff was found.

View file

@ -36,6 +36,7 @@ Page {
property bool nextId: false
property bool isCat: false
property var labels
property int itemId
anchors.margins: 0
@ -61,6 +62,25 @@ Page {
enabled: !panel.moving
onClicked: panel.open ? panel.hide() : panel.show()
}
MenuItem {
text: qsTr("Assign Labels")
onClicked: {
var ttrss = rootWindow.getTTRSS();
ttrss.getLabels(itemId, function(successful, errorMessage,
labels) {
if (successful) {
var params = {
articleId: root.itemId,
labels: labels,
headline: root.pageTitle,
feedItemPage: root
}
pageStack.push(Qt.resolvedUrl("LabelUpdater.qml"),
params);
}
})
}
}
}
Column {
@ -148,6 +168,8 @@ Page {
Grid {
spacing: Theme.paddingMedium
width: parent.width
visible: labels !== null && labels.count > 0
Repeater {
model: labels.count
LabelLabel {
@ -318,6 +340,7 @@ Page {
//unreadSwitch.checked = unread
rss = data.rss
//rssSwitch.checked = rss
itemId = data.id
previousId = feedItemModel.hasPrevious()
nextId = feedItemModel.hasNext()
@ -329,6 +352,39 @@ Page {
}
}
function updateLabels() {
var ttrss = rootWindow.getTTRSS();
ttrss.getLabels(itemId, function(successful, errorMessage, labels) {
if (!successful) {
// TODO do something with errorMessage
return
}
var item = feedItemModel.getSelectedItem()
if (!item || !item.labels) {
return
}
item.labels.clear()
var newLabels = []
for (var index = 0; index < labels.length; ++index) {
if (!labels[index].checked) {
continue
}
item.labels.append({
'id': parseInt(labels[index].id),
'caption': labels[index].caption,
'fg_color': (labels[index].fg_color === "" ? "black" : labels[index].fg_color),
'bg_color': (labels[index].bg_color === "" ? "white" : labels[index].bg_color)
})
}
root.labels = item.labels
})
}
Binding {
target: itemView
property: "fontSize"

View file

@ -29,7 +29,7 @@ Rectangle {
width: text.width + 2*Theme.paddingSmall
height: text.height
color: label !== null ? label.bgcolor : Theme.secondaryColor
color: label !== null ? label.bg_color : Theme.secondaryColor
radius: Theme.paddingSmall
Text {
@ -38,8 +38,8 @@ Rectangle {
horizontalCenter: parent.horizontalCenter
}
id: text
text: label !== null ? label.text : ""
color: label !== null ? label.fgcolor : Theme.highlightColor
text: label !== null ? label.caption : ""
color: label !== null ? label.fg_color : Theme.highlightColor
font.pixelSize: Theme.fontSizeExtraSmall
}
}

View file

@ -0,0 +1,131 @@
/*
* This file is part of TTRss, a Tiny Tiny RSS Reader App
* for MeeGo Harmattan and Sailfish OS.
* Copyright (C) 20122014 Hauke Schade
*
* TTRss is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* TTRss is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with TTRss; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see
* http://www.gnu.org/licenses/.
*/
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
property int articleId
property string headline
property var labels
property var feedItemPage
property bool initialization: true
property bool labelsChanged: false
SilicaListView {
id: listView
anchors.fill: page
anchors.leftMargin: Theme.paddingMedium
anchors.rightMargin: Theme.paddingMedium
model: page.labels
header: Column {
width: listView.width
height: header.height + info.height
PageHeader {
id: header
width: page.width
title: qsTr("Update Labels")
}
Label {
id: info
text: page.headline !== null ? page.headline : ""
width: parent.width
font.weight: Font.Bold
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
visible: page.headline !== null && page.headline !== ""
}
}
delegate: ListItem {
id: item
width: parent.width
property var label: page.labels[index]
Switch {
id: checkbox
checked: item.label.checked
anchors.verticalCenter: parent.verticalCenter
property bool noAPIcall: false
onCheckedChanged: {
if (page.initialization) {
return
}
if (checkbox.noAPIcall) {
checkbox.noAPIcall = false
return
}
page.labelsChanged = true
checkbox.busy = true
var ttrss = rootWindow.getTTRSS();
ttrss.setLabel(page.articleId, item.label.id,
checkbox.checked,
function(successful, errorMessage) {
checkbox.busy = false
if (!successful) {
checkbox.noAPIcall = true
checkbox.checked = !checkbox.checked
// TODO display errorMessage
}
})
}
}
LabelLabel {
label: item.label
anchors {
left: checkbox.right
verticalCenter: parent.verticalCenter
}
}
}
}
BusyIndicator {
visible: network.loading
running: visible
anchors {
horizontalCenter: page.horizontalCenter
verticalCenter: page.verticalCenter
}
size: BusyIndicatorSize.Large
}
Component.onCompleted: {
page.initialization = false
}
onStatusChanged: {
if (page.status === PageStatus.Deactivating && page.labelsChanged) {
feedItemPage.updateLabels()
}
}
}