Add Ubuntu Touch UI
This commit is contained in:
parent
935c136816
commit
8f95fc7566
14 changed files with 1500 additions and 0 deletions
2
main.cpp
2
main.cpp
|
|
@ -118,6 +118,8 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
|
|||
|
||||
#if defined(Q_OS_SAILFISH)
|
||||
viewer->setSource(SailfishApp::pathTo("qml/sailfish/harbour-ttrss.qml"));
|
||||
#elif defined(Q_OS_UBUNTU_TOUCH)
|
||||
viewer->setSource(QStringLiteral("qml/ttrss/ubuntu-touch/main.qml"));
|
||||
#else
|
||||
viewer->setMainQmlFile(QLatin1String("qml/harmattan/main.qml"));
|
||||
#endif
|
||||
|
|
|
|||
86
qml/ttrss/ubuntu-touch/Categories.qml
Normal file
86
qml/ttrss/ubuntu-touch/Categories.qml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 1.1
|
||||
|
||||
Page {
|
||||
id: categoriesPage
|
||||
title: qsTr("Tiny Tiny RSS Reader")
|
||||
|
||||
UbuntuListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
|
||||
model: categories
|
||||
|
||||
/* TODO
|
||||
PullDownMenu {
|
||||
//AboutItem {}
|
||||
SettingsItem {}
|
||||
MenuItem {
|
||||
text: qsTr("Logout")
|
||||
visible: pageStack.depth == 1
|
||||
onClicked: {
|
||||
pageStack.replace(Qt.resolvedUrl("MainPage.qml"), { doAutoLogin: false })
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Update")
|
||||
enabled: !network.loading
|
||||
onClicked: {
|
||||
categories.update()
|
||||
}
|
||||
}
|
||||
ToggleShowAllItem {
|
||||
onUpdateView: {
|
||||
categories.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pullToRefresh {
|
||||
enabled: true
|
||||
onRefresh: categories.update()
|
||||
refreshing: network.loading
|
||||
}
|
||||
|
||||
delegate: CategoryDelegate {
|
||||
onClicked: {
|
||||
categories.selectedIndex = index
|
||||
showCategory(categories.getSelectedItem())
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: listView.count == 0
|
||||
text: network.loading ?
|
||||
qsTr("Loading") :
|
||||
rootWindow.showAll ? qsTr("No categories to display") : qsTr("No categories have unread items")
|
||||
}
|
||||
ActivityIndicator {
|
||||
running: listView.count != 0 && network.loading
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Scrollbar {
|
||||
flickableItem: listView
|
||||
}
|
||||
}
|
||||
|
||||
function showCategory(categoryModel) {
|
||||
if (categoryModel != null) {
|
||||
pageStack.push(Qt.resolvedUrl("Feeds.qml"), {
|
||||
category: categoryModel
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
21
qml/ttrss/ubuntu-touch/CategoryDelegate.qml
Normal file
21
qml/ttrss/ubuntu-touch/CategoryDelegate.qml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 0.1
|
||||
import Ubuntu.Components.ListItems 0.1 as ListItem
|
||||
|
||||
ListItem.SingleValue {
|
||||
id: listItem
|
||||
|
||||
text: model.title
|
||||
value: model.unreadcount
|
||||
}
|
||||
36
qml/ttrss/ubuntu-touch/FeedDelegate.qml
Normal file
36
qml/ttrss/ubuntu-touch/FeedDelegate.qml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 0.1
|
||||
import Ubuntu.Components.ListItems 0.1 as ListItem
|
||||
|
||||
ListItem.Empty {
|
||||
id: listItem
|
||||
|
||||
property int value
|
||||
|
||||
SubtitledLabel {
|
||||
anchors.leftMargin: units.gu(1)
|
||||
anchors.right: countLabel.left
|
||||
iconSource: model.icon
|
||||
bold: model.unreadcount > 0
|
||||
text: model.title
|
||||
}
|
||||
|
||||
Label {
|
||||
id: countLabel
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: model.unreadcount
|
||||
anchors.rightMargin: units.gu(1)
|
||||
}
|
||||
}
|
||||
253
qml/ttrss/ubuntu-touch/FeedItem.qml
Normal file
253
qml/ttrss/ubuntu-touch/FeedItem.qml
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 1.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string title: ""
|
||||
property string url: ""
|
||||
property string date: ""
|
||||
property bool marked: false
|
||||
property bool unread: true
|
||||
property bool rss: false
|
||||
property bool isCat: false
|
||||
property variant labels
|
||||
property var attachments
|
||||
property string content: ""
|
||||
property Item flickable: flick
|
||||
|
||||
Flickable {
|
||||
id: flick
|
||||
anchors.fill: parent
|
||||
contentHeight: content.height
|
||||
interactive: true
|
||||
clip: true
|
||||
|
||||
/* TODO
|
||||
PullDownMenu {
|
||||
// AboutItem {}
|
||||
// SettingsItem {}
|
||||
MenuItem {
|
||||
text: qsTr("Open in Web Browser")
|
||||
enabled: url && (url != "")
|
||||
onClicked: Qt.openUrlExternally(url)
|
||||
}
|
||||
MenuItem {
|
||||
text: panel.open ? qsTr("Hide Dock") : qsTr("Open Dock")
|
||||
enabled: !panel.moving
|
||||
onClicked: panel.open ? panel.hide() : panel.show()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// PushUpMenu {
|
||||
// MenuItem {
|
||||
// text: qsTr("Scroll to top")
|
||||
// onClicked: flick.scrollToTop()
|
||||
// visible: flick.contentHeight >= flick.height
|
||||
// }
|
||||
// MenuItem {
|
||||
// text: qsTr("Open Dock")
|
||||
// visible: !panel.open
|
||||
// onClicked: panel.show()
|
||||
// }
|
||||
// }
|
||||
|
||||
Column {
|
||||
id: content
|
||||
width: parent.width
|
||||
spacing: 2
|
||||
|
||||
Label {
|
||||
text: title
|
||||
fontSize: "large"
|
||||
font.bold: true
|
||||
wrapMode: Text.Wrap
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: date
|
||||
fontSize: "small"
|
||||
textFormat: Text.PlainText
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: Theme.paddingLarge
|
||||
}
|
||||
|
||||
color: Theme.secondaryColor
|
||||
}
|
||||
RescalingRichText {
|
||||
id: itemView
|
||||
width: parent.width
|
||||
text: parseContent(root.content, root.attachments)
|
||||
fontSize: Theme.fontSizeSmall
|
||||
color: Theme.primaryColor
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scrollbar {
|
||||
flickableItem: flick
|
||||
}
|
||||
|
||||
ActivityIndicator {
|
||||
running: network.loading
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
/* TODO
|
||||
DockedPanel {
|
||||
id: panel
|
||||
|
||||
width: parent.width
|
||||
height: Theme.itemSizeMedium
|
||||
open: true
|
||||
|
||||
dock: Dock.Bottom
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
|
||||
IconButton {
|
||||
icon.source: "image://theme/icon-m-previous"
|
||||
enabled: previousId !== false
|
||||
onClicked: {
|
||||
feedItems.selectPrevious()
|
||||
pageStack.replace("FeedItem.qml", { isCat: root.isCat })
|
||||
//showFeedItem()
|
||||
}
|
||||
}
|
||||
IconButton {
|
||||
id: rssSwitch
|
||||
icon.source: "../../resources/ic_rss_"+(rss?"enabled":"disabled")+".png"
|
||||
//checked: rss
|
||||
onClicked: {
|
||||
feedItems.togglePublished()
|
||||
rss = !rss
|
||||
}
|
||||
}
|
||||
IconButton {
|
||||
id: markedSwitch
|
||||
icon.source: "../../resources/ic_star_"+(marked?"enabled":"disabled")+".png"
|
||||
//checked: marked
|
||||
onClicked: {
|
||||
feedItems.toggleStar()
|
||||
marked = !marked
|
||||
}
|
||||
}
|
||||
IconButton {
|
||||
id: unreadSwitch
|
||||
icon.source: "../../resources/ic_"+(unread?"unread":"read")+".png"
|
||||
//checked: unread
|
||||
onClicked: {
|
||||
feedItems.toggleRead()
|
||||
unread = !unread
|
||||
}
|
||||
}
|
||||
IconButton {
|
||||
icon.source: "image://theme/icon-m-next"
|
||||
enabled: nextId !== false
|
||||
onClicked: {
|
||||
feedItems.selectNext()
|
||||
pageStack.replace("FeedItem.qml", { isCat: root.isCat })
|
||||
//showFeedItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function computeAttachmentsCode(attachments) {
|
||||
if (attachments.count === 0) return ""
|
||||
|
||||
var attachmentsCode = ""
|
||||
|
||||
for (var i = 0; i < attachments.count; i++) {
|
||||
var a = attachments.get(i)
|
||||
var url = a.content_url
|
||||
var isImage = (a.content_type.indexOf("image") === 0 ||
|
||||
/jpe?g$/i.test(url) ||
|
||||
/png$/i.test(url))
|
||||
|
||||
console.log("URL: " + url + " isImage: " + isImage)
|
||||
var attachmentLabel = ""
|
||||
if (isImage) {
|
||||
attachmentLabel = "<img src=\"" + url + "\" style=\"max-width: 100%; height: auto\"/>"
|
||||
} else {
|
||||
attachmentLabel = a.title ? a.title : url.replace(/^.*[\/]/g, '')
|
||||
}
|
||||
attachmentsCode += "<a href=\"" + url + "\">" + attachmentLabel + "</a>"
|
||||
}
|
||||
|
||||
return attachmentsCode
|
||||
}
|
||||
|
||||
function parseContent(rawContent, attachments) {
|
||||
var attachmentsCode = computeAttachmentsCode(attachments)
|
||||
|
||||
var content = rawContent.replace('target="_blank"', '')
|
||||
|
||||
if (!settings.displayImages) {
|
||||
// remove images
|
||||
var image_regex = /<img\s[^>]*>/gi;
|
||||
content = content.replace(image_regex, "")
|
||||
} else if (settings.stripInvisibleImg) {
|
||||
// remove images with a height or width of 0 or 1
|
||||
var height_regex = /<img\s[^>]*height="[01]"[^>]*>/gi;
|
||||
content = content.replace(height_regex, "")
|
||||
|
||||
var width_regex = /<img\s[^>]*width="[01]"[^>]*>/gi;
|
||||
content = content.replace(width_regex, "")
|
||||
}
|
||||
|
||||
if (!content.match(/<body>/gi)) {
|
||||
// not yet html, detect urls
|
||||
console.log('doing link detection on ' + content)
|
||||
var regex = /(([a-z]+:\/\/)?(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi;
|
||||
content = content.replace(regex, "<a href='$1'>$1</a> ")
|
||||
if (attachmentsCode) {
|
||||
content += attachmentsCode
|
||||
}
|
||||
} else {
|
||||
if (attachmentsCode) {
|
||||
var regex =/(<\/body>)/gi
|
||||
content = content.replace(regex, attachmentsCode + "$1")
|
||||
}
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: itemView
|
||||
property: "fontSize"
|
||||
value: settings.webviewFontSize
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
itemView.fontSize = settings.webviewFontSize
|
||||
}
|
||||
|
||||
|
||||
// MenuItem {
|
||||
// text: qsTr("Share")
|
||||
// enabled: url && (url != "")
|
||||
// onClicked: QMLUtils.share(url, pageTitle);
|
||||
// }
|
||||
// SettingsItem {}
|
||||
// AboutItem {}
|
||||
}
|
||||
86
qml/ttrss/ubuntu-touch/FeedItemDelegate.qml
Normal file
86
qml/ttrss/ubuntu-touch/FeedItemDelegate.qml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 0.1
|
||||
import Ubuntu.Components.ListItems 0.1 as ListItem
|
||||
|
||||
ListItem.Empty {
|
||||
id: listItem
|
||||
|
||||
|
||||
onClicked: root.clicked()
|
||||
|
||||
SubtitledLabel {
|
||||
text: model.title
|
||||
subText: model.subtitle
|
||||
iconSource: (settings.displayIcons && feed.isCat) ? model.icon : ''
|
||||
bold: model.unread
|
||||
}
|
||||
/*
|
||||
Row {
|
||||
spacing: Theme.paddingMedium
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: (icon.visible ? icon.width : 0) + Theme.paddingMedium
|
||||
Image {
|
||||
source: "../../resources/ic_star_enabled.png"
|
||||
visible: model.marked
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
opacity: 0.5
|
||||
}
|
||||
Image {
|
||||
source: "../../resources/ic_rss_enabled.png"
|
||||
visible: model.rss
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* TODO
|
||||
Component {
|
||||
id: contextMenu
|
||||
ContextMenu {
|
||||
MenuItem {
|
||||
id: toggleStarMenuItem
|
||||
text: model.marked ? qsTr("Unstar") : qsTr("Star")
|
||||
onClicked: {
|
||||
feedItems.toggleStar()
|
||||
} }
|
||||
MenuItem {
|
||||
id: togglePublishedMenuItem
|
||||
text: model.rss ? qsTr("Unpublish") : qsTr("Publish")
|
||||
onClicked: {
|
||||
feedItems.togglePublished()
|
||||
} }
|
||||
MenuItem {
|
||||
id: toggleReadMenuItem
|
||||
text: model.unread ? qsTr("Mark read") : qsTr("Mark Unread")
|
||||
onClicked: {
|
||||
feedItems.toggleRead()
|
||||
} }
|
||||
MenuItem {
|
||||
id: openInBrowserMenuItem
|
||||
text: qsTr("Open in Web Browser")
|
||||
visible: model.url && model.url != ""
|
||||
onClicked: {
|
||||
var item = feedItems.getSelectedItem()
|
||||
Qt.openUrlExternally(item.url)
|
||||
}
|
||||
|
||||
}
|
||||
Component.onCompleted: {
|
||||
feedItems.selectedIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
79
qml/ttrss/ubuntu-touch/FeedItemSwipe.qml
Normal file
79
qml/ttrss/ubuntu-touch/FeedItemSwipe.qml
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 1.1
|
||||
|
||||
Page {
|
||||
id: root
|
||||
|
||||
property bool isCat: false
|
||||
property var model
|
||||
property int currentIndex: -1
|
||||
property alias currentItem: listView.currentItem
|
||||
|
||||
anchors.fill: parent
|
||||
title: currentItem ? currentItem.title : ""
|
||||
flickable: currentItem ? currentItem.flickable : null
|
||||
|
||||
head.actions: [
|
||||
Action {
|
||||
iconSource: "../resources/ic_star_"+(currentItem.marked?"enabled":"disabled")+".png"
|
||||
onTriggered: {
|
||||
feedItems.toggleStar()
|
||||
}
|
||||
},
|
||||
Action {
|
||||
iconSource: "../resources/ic_"+(currentItem.unread?"unread":"read")+".png"
|
||||
onTriggered: {
|
||||
feedItems.toggleRead()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
orientation: ListView.Horizontal
|
||||
snapMode: ListView.SnapOneItem
|
||||
highlightFollowsCurrentItem: true
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
cacheBuffer: 0
|
||||
|
||||
delegate: FeedItem {
|
||||
title: model.title
|
||||
url: model.url
|
||||
date: model.date
|
||||
labels: model.labels
|
||||
marked: model.marked
|
||||
unread: model.unread
|
||||
rss: model.rss
|
||||
attachments: model.attachments
|
||||
content: model.content
|
||||
|
||||
width: listView.width
|
||||
height: listView.height
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
feedItems.selectedIndex = currentIndex
|
||||
if (currentItem && settings.autoMarkRead && currentItem.unread) {
|
||||
console.log("marking item as read")
|
||||
feedItems.toggleRead()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
listView.model = root.model
|
||||
listView.currentIndex = root.currentIndex
|
||||
}
|
||||
}
|
||||
144
qml/ttrss/ubuntu-touch/FeedItems.qml
Normal file
144
qml/ttrss/ubuntu-touch/FeedItems.qml
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 1.1
|
||||
import Ubuntu.Components.ListItems 1.0 as ListItem
|
||||
|
||||
Page {
|
||||
id: feeditemsPage
|
||||
property variant feed
|
||||
|
||||
title: feed.title
|
||||
|
||||
Component.onCompleted: {
|
||||
feedItems.feed = feeditemsPage.feed
|
||||
feedItems.hasMoreItems = false
|
||||
feedItems.continuation = 0
|
||||
feedItems.clear()
|
||||
var ttrss = rootWindow.getTTRSS()
|
||||
ttrss.setShowAll(settings.showAll)
|
||||
feedItems.update()
|
||||
// FIXME workaround for https://bugs.launchpad.net/bugs/1404884
|
||||
pullToRefresh.enabled = true
|
||||
}
|
||||
|
||||
head {
|
||||
sections {
|
||||
model: [ qsTr("Unread"), qsTr("All") ]
|
||||
selectedIndex: settings.showAll ? 1 : 0
|
||||
onSelectedIndexChanged: {
|
||||
var ttrss = rootWindow.getTTRSS()
|
||||
var showAll = (feeditemsPage.head.sections.selectedIndex == 1)
|
||||
if (showAll != settings.showAll) {
|
||||
ttrss.setShowAll(showAll)
|
||||
settings.showAll = showAll
|
||||
feedItems.continuation = 0
|
||||
feedItems.hasMoreItems = false
|
||||
feedItems.clear()
|
||||
feedItems.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
model: feedItems
|
||||
|
||||
PullToRefresh {
|
||||
id: pullToRefresh
|
||||
enabled: false
|
||||
onRefresh: feedItems.update()
|
||||
refreshing: network.loading
|
||||
}
|
||||
|
||||
/* TODO
|
||||
PullDownMenu {
|
||||
// AboutItem {}
|
||||
// SettingsItem {}
|
||||
MenuItem {
|
||||
text: qsTr("Update")
|
||||
enabled: !network.loading
|
||||
onClicked: {
|
||||
feedItems.continuation = 0
|
||||
feedItems.hasMoreItems = false
|
||||
feedItems.clear()
|
||||
feedItems.update()
|
||||
}
|
||||
}
|
||||
ToggleShowAllItem {
|
||||
onUpdateView: {
|
||||
feedItems.continuation = 0
|
||||
feedItems.hasMoreItems = false
|
||||
feedItems.clear()
|
||||
feedItems.update()
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr('Mark all read')
|
||||
onClicked: {
|
||||
feedItems.catchUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
section {
|
||||
property: 'date'
|
||||
|
||||
delegate: ListItem.Caption {
|
||||
text: section
|
||||
}
|
||||
}
|
||||
|
||||
delegate: FeedItemDelegate {
|
||||
onClicked: {
|
||||
feedItems.selectedIndex = index
|
||||
pageStack.push(Qt.resolvedUrl("FeedItemSwipe.qml"), {
|
||||
model: feedItems,
|
||||
currentIndex: index,
|
||||
isCat: feed.isCat
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: listView.count == 0
|
||||
text: network.loading ?
|
||||
qsTr("Loading") :
|
||||
rootWindow.showAll ? qsTr("No items in feed") : qsTr("No unread items in feed")
|
||||
}
|
||||
ActivityIndicator {
|
||||
running: network.loading
|
||||
anchors.centerIn: parent
|
||||
onRunningChanged: {
|
||||
/* We want to show this activity indicator just for the first
|
||||
* time, as a workaround for
|
||||
* https://bugs.launchpad.net/bugs/1404884. So, once the
|
||||
* initial loading has completed, we disable this item */
|
||||
if (!running) visible = false
|
||||
}
|
||||
}
|
||||
Scrollbar {
|
||||
flickableItem: listView
|
||||
}
|
||||
}
|
||||
|
||||
function showFeed(feedModel) {
|
||||
if (feedModel != null) {
|
||||
pageStack.push(Qt.resolvedUrl("FeedItems.qml"), {
|
||||
feed: feedModel
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
149
qml/ttrss/ubuntu-touch/Feeds.qml
Normal file
149
qml/ttrss/ubuntu-touch/Feeds.qml
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 1.1
|
||||
|
||||
Page {
|
||||
id: feedsPage
|
||||
property variant category
|
||||
|
||||
title: category.title
|
||||
|
||||
Component.onCompleted: {
|
||||
feeds.category = feedsPage.category
|
||||
feeds.clear()
|
||||
var ttrss = rootWindow.getTTRSS()
|
||||
ttrss.setShowAll(settings.showAll)
|
||||
feeds.update()
|
||||
}
|
||||
|
||||
head {
|
||||
sections {
|
||||
model: [ qsTr("Unread"), qsTr("All") ]
|
||||
selectedIndex: settings.showAll ? 1 : 0
|
||||
onSelectedIndexChanged: {
|
||||
var ttrss = rootWindow.getTTRSS()
|
||||
var showAll = (feedsPage.head.sections.selectedIndex == 1)
|
||||
if (showAll != settings.showAll) {
|
||||
ttrss.setShowAll(showAll)
|
||||
settings.showAll = showAll
|
||||
feeds.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
model: feeds
|
||||
|
||||
PullToRefresh {
|
||||
enabled: true
|
||||
onRefresh: feeds.update()
|
||||
refreshing: network.loading
|
||||
}
|
||||
|
||||
/* TODO
|
||||
PullDownMenu {
|
||||
//AboutItem {}
|
||||
SettingsItem {}
|
||||
MenuItem {
|
||||
text: qsTr("Add subscription")
|
||||
onClicked: {
|
||||
var dialog = pageStack.push(Qt.resolvedUrl("AddSubscription.qml"), {
|
||||
categoryId: feedsPage.category.categoryId
|
||||
})
|
||||
dialog.accepted.connect(function(){
|
||||
var ttrss = rootWindow.getTTRSS()
|
||||
ttrss.subscribe(dialog.selectedId,
|
||||
dialog.src,
|
||||
function(result) {
|
||||
switch (result) {
|
||||
case 0:
|
||||
notification.show(qsTr('Already subscribed to Feed'))
|
||||
break
|
||||
case 1:
|
||||
//notification.show(qsTr('Feed added'))
|
||||
feeds.update()
|
||||
categories.update()
|
||||
break
|
||||
case 2:
|
||||
notification.show(qsTr('Invalid URL'))
|
||||
break
|
||||
case 3:
|
||||
notification.show(qsTr('URL content is HTML, no feeds available'))
|
||||
break
|
||||
case 4:
|
||||
notification.show(qsTr('URL content is HTML which contains multiple feeds'))
|
||||
break
|
||||
case 5:
|
||||
notification.show(qsTr('Couldn\'t download the URL content'))
|
||||
break
|
||||
case 5:
|
||||
notification.show(qsTr('Content is an invalid XML'))
|
||||
break
|
||||
default:
|
||||
notification.show(qsTr('An error occured while subscribing to the feed'))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Logout")
|
||||
visible: pageStack.depth == 1
|
||||
onClicked: {
|
||||
pageStack.replace(Qt.resolvedUrl("MainPage.qml"), { doAutoLogin: false })
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Update")
|
||||
enabled: !network.loading
|
||||
onClicked: {
|
||||
feeds.update()
|
||||
}
|
||||
}
|
||||
ToggleShowAllItem {
|
||||
onUpdateView: {
|
||||
feeds.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
delegate: FeedDelegate {
|
||||
onClicked: {
|
||||
feeds.selectedIndex = index
|
||||
showFeed(model)
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: listView.count == 0
|
||||
text: network.loading ?
|
||||
qsTr("Loading") :
|
||||
rootWindow.showAll ? qsTr("No feeds in category") : qsTr("Category has no unread items")
|
||||
}
|
||||
Scrollbar {
|
||||
flickableItem: listView
|
||||
}
|
||||
}
|
||||
|
||||
function showFeed(feedModel) {
|
||||
if (feedModel != null) {
|
||||
pageStack.push(Qt.resolvedUrl("FeedItems.qml"), {
|
||||
feed: feedModel
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
247
qml/ttrss/ubuntu-touch/MainPage.qml
Normal file
247
qml/ttrss/ubuntu-touch/MainPage.qml
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
import QtQuick 2.0
|
||||
import Ubuntu.Components 0.1
|
||||
import Ubuntu.Keyboard 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
anchors.margins: units.gu(1)
|
||||
property bool doAutoLogin: true
|
||||
|
||||
Flickable {
|
||||
contentHeight: contentcontainer.height
|
||||
contentWidth: parent.width
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: osk.top
|
||||
|
||||
/* TODO
|
||||
PullDownMenu {
|
||||
AboutItem {}
|
||||
SettingsItem {}
|
||||
MenuItem {
|
||||
text: qsTr("No Account Yet?")
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("http://tt-rss.org/redmine/projects/tt-rss/wiki");
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Column {
|
||||
id: contentcontainer
|
||||
width: parent.width
|
||||
spacing: units.gu(1)
|
||||
|
||||
Image {
|
||||
width: 256
|
||||
height: 256
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
source: "../resources/ttrss256.png"
|
||||
|
||||
anchors.bottomMargin: Theme.paddingLarge
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
Label {
|
||||
id: serverLabel
|
||||
text: qsTr("Server:")
|
||||
width: parent.width
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
}
|
||||
TextField {
|
||||
id: server
|
||||
text: ""
|
||||
width: parent.width
|
||||
enabled: !network.loading
|
||||
inputMethodHints: Qt.ImhUrlCharactersOnly + Qt.ImhNoPredictiveText
|
||||
KeyNavigation.tab: username
|
||||
Keys.onReturnPressed: username.forceActiveFocus()
|
||||
InputMethod.extensions: { "enterKeyText": qsTr("Next") }
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
Label {
|
||||
id: usernameLabel
|
||||
text: qsTr("Username:")
|
||||
width: parent.width
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
}
|
||||
TextField {
|
||||
id: username
|
||||
text: ""
|
||||
width: parent.width
|
||||
enabled: !network.loading
|
||||
inputMethodHints: Qt.ImhNoPredictiveText + Qt.ImhNoAutoUppercase
|
||||
KeyNavigation.tab: password
|
||||
KeyNavigation.backtab: server
|
||||
Keys.onReturnPressed: password.forceActiveFocus()
|
||||
InputMethod.extensions: { "enterKeyText": qsTr("Next") }
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
Label {
|
||||
id: passwordLabel
|
||||
text: qsTr("Password:")
|
||||
width: parent.width
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
}
|
||||
TextField {
|
||||
id: password
|
||||
echoMode: TextInput.Password
|
||||
width: parent.width
|
||||
enabled: !network.loading
|
||||
KeyNavigation.backtab: username
|
||||
Keys.onReturnPressed: root.submit()
|
||||
InputMethod.extensions: { "enterKeyText": qsTr("Login") }
|
||||
}
|
||||
}
|
||||
CheckBox {
|
||||
text: qsTr('Ignore SSL Errors')
|
||||
visible: server.text.substring(0, 5) === "https"
|
||||
checked: settings.ignoreSSLErrors
|
||||
onCheckedChanged: settings.ignoreSSLErrors = checked
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: clearButton.height
|
||||
Button {
|
||||
id: clearButton
|
||||
text: qsTr("Clear")
|
||||
width: Math.floor(parent.width / 2) - units.gu(1)
|
||||
onClicked: {
|
||||
server.text = ''
|
||||
username.text = ''
|
||||
password.text = ''
|
||||
|
||||
settings.httpauthusername = ''
|
||||
settings.httpauthpassword = ''
|
||||
settings.servername = server.text
|
||||
settings.username = username.text
|
||||
settings.password = password.text
|
||||
}
|
||||
enabled: !network.loading
|
||||
}
|
||||
Button {
|
||||
id: loginButton
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Login")
|
||||
width: Math.floor(parent.width / 2) - units.gu(1)
|
||||
onClicked: root.submit()
|
||||
enabled: !network.loading
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ActivityIndicator {
|
||||
id: busyindicator1
|
||||
running: network.loading
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: osk
|
||||
height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
function enableLoginBox(focus) {
|
||||
if(focus) {
|
||||
password.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
function submit() {
|
||||
// check the servername for httpauth data and set/extract those
|
||||
var httpauthregex = /(https?:\/\/)?(\w+):(\w+)@(\w.+)/
|
||||
var servername = server.text
|
||||
var regexres = servername.match(httpauthregex)
|
||||
if (regexres !== null) {
|
||||
server.text = (regexres[1]?regexres[1]:'') + regexres[4]
|
||||
settings.httpauthusername = regexres[2]
|
||||
settings.httpauthpassword = regexres[3]
|
||||
}
|
||||
|
||||
settings.servername = server.text
|
||||
settings.username = username.text
|
||||
settings.password = password.text
|
||||
|
||||
startLogin();
|
||||
}
|
||||
|
||||
function startLogin() {
|
||||
var ttrss = rootWindow.getTTRSS();
|
||||
ttrss.clearState();
|
||||
ttrss.setLoginDetails(username.text, password.text, server.text);
|
||||
// BUGFIX since somehow the silica QML Image can not display images coming from a secure line
|
||||
if (settings.ignoreSSLErrors && server.text.substring(0, 5) === "https")
|
||||
ttrss.setProxy("http://proxy.cnlpete.de/proxy.php?url=")
|
||||
if (settings.httpauthusername != '' && settings.httpauthpassword != '') {
|
||||
ttrss.setHttpAuthInfo(settings.httpauthusername, settings.httpauthpassword);
|
||||
console.log('doing http basic auth with username ' + settings.httpauthusername)
|
||||
}
|
||||
ttrss.login(loginSuccessfull);
|
||||
}
|
||||
|
||||
function loginSuccessfull(retcode, text) {
|
||||
if(retcode) {
|
||||
//login failed....don't autlogin
|
||||
settings.autologin = false
|
||||
|
||||
//Let the user know
|
||||
// loginErrorDialog.text = text;
|
||||
// loginErrorDialog.open();
|
||||
}
|
||||
else {
|
||||
//Login succeeded, auto login next Time
|
||||
settings.autologin = true
|
||||
rootWindow.getTTRSS().updateConfig(configSuccessfull);
|
||||
}
|
||||
}
|
||||
|
||||
function configSuccessfull(retcode, text) {
|
||||
if(retcode) {
|
||||
//Let the user know
|
||||
// loginErrorDialog.text = text;
|
||||
// loginErrorDialog.open();
|
||||
}
|
||||
else {
|
||||
categories.update()
|
||||
pageStack.clear()
|
||||
//Now show the categories View
|
||||
if (settings.useAllFeedsOnStartup) {
|
||||
var ttrss = rootWindow.getTTRSS()
|
||||
pageStack.push("Feeds.qml", {
|
||||
category: {
|
||||
categoryId: ttrss.constants['categories']['ALL'],
|
||||
title: constant.allFeeds,
|
||||
unreadcount: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
else
|
||||
pageStack.push(Qt.resolvedUrl('Categories.qml'))
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
server.text = settings.servername
|
||||
username.text = settings.username
|
||||
password.text = settings.password
|
||||
|
||||
if (settings.autologin && settings.useAutologin && doAutoLogin)
|
||||
startLogin();
|
||||
}
|
||||
}
|
||||
101
qml/ttrss/ubuntu-touch/RescalingRichText.qml
Normal file
101
qml/ttrss/ubuntu-touch/RescalingRichText.qml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/* Copyright (C) 2013 Martin Grimme <martin.grimme _AT_ gmail.com>
|
||||
*
|
||||
* This file was apapted from Tidings
|
||||
* Copyright (C) 2013 Martin Grimme <martin.grimme _AT_ gmail.com>
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
/* Pretty fancy element for displaying rich text fitting the width.
|
||||
*
|
||||
* Images are scaled down to fit the width, or, technically speaking, the
|
||||
* rich text content is actually scaled down so the images fit, while the
|
||||
* font size is scaled up to keep the original font size.
|
||||
*/
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string text
|
||||
property alias color: contentText.color
|
||||
property real fontSize: Theme.fontSizeSmall
|
||||
|
||||
property string _RICHTEXT_STYLESHEET_PREAMBLE: "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><style>a { text-decoration: none; color: '" + Theme.highlightColor + "' }</style></head><body>";
|
||||
property string _RICHTEXT_STYLESHEET_APPENDIX: "</body></html>";
|
||||
|
||||
property real scaling: 1
|
||||
|
||||
signal linkActivated(string link)
|
||||
|
||||
height: contentText.height * scaling
|
||||
clip: true
|
||||
|
||||
onWidthChanged: {
|
||||
rescaleTimer.restart()
|
||||
}
|
||||
|
||||
Text {
|
||||
id: layoutText
|
||||
|
||||
visible: false
|
||||
width: parent.width
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
textFormat: Text.RichText
|
||||
|
||||
text: "<style>* { font-size: 1px }</style>" + parent.text
|
||||
|
||||
onContentWidthChanged: {
|
||||
console.log("contentWidth: " + contentWidth)
|
||||
rescaleTimer.restart()
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: contentText
|
||||
|
||||
width: Math.max(1, parent.width) / scaling
|
||||
scale: scaling
|
||||
|
||||
transformOrigin: Item.TopLeft
|
||||
font.pixelSize: parent.fontSize / scaling
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
textFormat: Text.RichText
|
||||
smooth: true
|
||||
|
||||
// text: _RICHTEXT_STYLESHEET_PREAMBLE + parent.text + _RICHTEXT_STYLESHEET_APPENDIX
|
||||
|
||||
onLinkActivated: {
|
||||
root.linkActivated(link)
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: rescaleTimer
|
||||
interval: 100
|
||||
|
||||
onTriggered: {
|
||||
var contentWidth = Math.floor(layoutText.contentWidth + 0.0)
|
||||
scaling = Math.min(1, parent.width / contentWidth)
|
||||
console.log("scaling: " + scaling)
|
||||
|
||||
// force reflow
|
||||
// contentText.text = contentText.text + " "
|
||||
contentText.text = _RICHTEXT_STYLESHEET_PREAMBLE + parent.text + _RICHTEXT_STYLESHEET_APPENDIX
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
75
qml/ttrss/ubuntu-touch/SubtitledLabel.qml
Normal file
75
qml/ttrss/ubuntu-touch/SubtitledLabel.qml
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//Copyright Hauke Schade, 2012-2014
|
||||
//
|
||||
//This file is part of TTRss.
|
||||
//
|
||||
//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 (on a Maemo/Meego system there is a copy
|
||||
//in /usr/share/common-licenses. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
import QtQuick 2.0
|
||||
import Ubuntu.Components 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias text: titleLabel.text
|
||||
property alias subText: subLabel.text
|
||||
property alias iconSource: icon.source
|
||||
property bool bold: false
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
UbuntuShape {
|
||||
id: iconShape
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: visible ? roundBaseTwo(parent.height) : 0
|
||||
height: width
|
||||
visible: icon.source.toString()
|
||||
image: Image {
|
||||
id:icon
|
||||
}
|
||||
|
||||
function roundBaseTwo(n) {
|
||||
var i = 2
|
||||
while (i * 2 <= n) i *= 2
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "noSub"
|
||||
when: !subLabel.text
|
||||
AnchorChanges {
|
||||
target: titleLabel
|
||||
anchors.top: undefined
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: titleLabel
|
||||
anchors.left: iconShape.right
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
font.bold: root.bold
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Label {
|
||||
id: subLabel
|
||||
anchors.left: iconShape.right
|
||||
anchors.right: parent.right
|
||||
anchors.top: titleLabel.bottom
|
||||
fontSize: "x-small"
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: 2
|
||||
}
|
||||
}
|
||||
136
qml/ttrss/ubuntu-touch/main.qml
Normal file
136
qml/ttrss/ubuntu-touch/main.qml
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
import QtQuick 2.0
|
||||
import Ubuntu.Components 0.1
|
||||
import "../models/tinytinyrss.js" as TTRss
|
||||
import "../models" 1.0
|
||||
|
||||
/*!
|
||||
brief MainView with a Label and Button elements.
|
||||
*/
|
||||
|
||||
MainView {
|
||||
id: rootWindow
|
||||
applicationName: "ttrss"
|
||||
|
||||
width: units.gu(45)
|
||||
height: units.gu(75)
|
||||
useDeprecatedToolbar: false
|
||||
|
||||
PageStack {
|
||||
id: pageStack
|
||||
Component.onCompleted: push(mainPage)
|
||||
|
||||
MainPage {
|
||||
id: mainPage
|
||||
}
|
||||
}
|
||||
|
||||
function getTTRSS() {
|
||||
return TTRss;
|
||||
}
|
||||
|
||||
property bool showAll: false
|
||||
|
||||
Constants{ id: constant }
|
||||
|
||||
CategoryModel {
|
||||
id: categories
|
||||
}
|
||||
FeedModel {
|
||||
id: feeds
|
||||
|
||||
onFeedUnreadChanged: {
|
||||
var op = function(x) { return x - oldAmount + feed.unreadcount }
|
||||
categories.updateUnreadCountForId(feed.categoryId, op)
|
||||
//console.log("updating category with id: " + feed.categoryId + " op is " + op(0))
|
||||
|
||||
// update the 'All Feeds' Category
|
||||
categories.updateUnreadCountForId(TTRss.constants['categories']['ALL'], op)
|
||||
//console.log("updating special cat with id: " + TTRss.constants['categories']['ALL'] + " op is " + op(0))
|
||||
|
||||
// if there is an 'all feed items' update that aswell
|
||||
if (feeds.count > 1) {
|
||||
var m = feeds.get(0)
|
||||
|
||||
if (m.isCat) { // just check to be sure
|
||||
|
||||
if (feed.isCat && m.feedId == feed.feedId && feed.unreadcount == 0) {
|
||||
// we can not determine where to substract, but when all is 0, we can update accordingly
|
||||
for (var i = 1; i < feeds.count; i++) {
|
||||
feeds.setProperty(i, "unreadcount", 0)
|
||||
}
|
||||
}
|
||||
else {
|
||||
feeds.setProperty(0, "unreadcount", op(m.unreadcount))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FeedItemModel {
|
||||
id: feedItems
|
||||
|
||||
onItemUnreadChanged: {
|
||||
var op = item.unread ?
|
||||
function(x) { return x + 1 } :
|
||||
function(x) { return x - 1 }
|
||||
|
||||
// update the feed's category
|
||||
feeds.updateUnreadCountForId(item.feedId, op)
|
||||
//console.log("updating feed with id: " + item.feedId + " op is " + op(0))
|
||||
|
||||
// update special for all feeditems category
|
||||
categories.updateUnreadCountForId(
|
||||
TTRss.constants['categories']['SPECIAL'],
|
||||
op)
|
||||
//console.log("updating special cat with id: " + TTRss.constants['categories']['SPECIAL'] + " op is " + op(0))
|
||||
|
||||
// if the item is new, update 'special feeds' for 'fresh articles'
|
||||
// TODO
|
||||
if (item.unread && false)
|
||||
categories.updateUnreadCountForId(
|
||||
TTRss.constants['categories']['SPECIAL'],
|
||||
op)
|
||||
|
||||
// if item was is starred/published, update special feeds aswell
|
||||
if (item.rss)
|
||||
categories.updateUnreadCountForId(
|
||||
TTRss.constants['categories']['SPECIAL'],
|
||||
op)
|
||||
if (item.marked)
|
||||
categories.updateUnreadCountForId(
|
||||
TTRss.constants['categories']['SPECIAL'],
|
||||
op)
|
||||
|
||||
// maybe check if currently viewing special feeds and update published
|
||||
// not nesseccary because this is updated by mark unread
|
||||
}
|
||||
onItemPublishedChanged: {
|
||||
var op = item.rss ?
|
||||
function(x) { return x + 1 } :
|
||||
function(x) { return x - 1 }
|
||||
|
||||
// if the item is unread, update 'special feeds'
|
||||
if (item.unread)
|
||||
categories.updateUnreadCountForId(
|
||||
TTRss.constants['categories']['SPECIAL'],
|
||||
op)
|
||||
|
||||
// maybe check if currently viewing special feeds and update published
|
||||
// not nesseccary because this is updated by mark unread
|
||||
}
|
||||
onItemStarChanged: {
|
||||
var op = item.marked ?
|
||||
function(x) { return x + 1 } :
|
||||
function(x) { return x - 1 }
|
||||
|
||||
// if the item is unread, update 'special feeds'
|
||||
if (item.unread)
|
||||
categories.updateUnreadCountForId(
|
||||
TTRss.constants['categories']['SPECIAL'],
|
||||
op)
|
||||
|
||||
// maybe check if currently viewing special feeds and update starred
|
||||
// not nesseccary because this is updated by mark unread
|
||||
}
|
||||
}
|
||||
}
|
||||
85
ttrss-ubuntu.pro
Normal file
85
ttrss-ubuntu.pro
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
VERSION = 0.4.3
|
||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||
|
||||
DEFINES += Q_OS_UBUNTU_TOUCH
|
||||
|
||||
TARGET = ttrss-ubuntu-touch
|
||||
DEFINES += TARGET=\\\"it.mardy.ttrss\\\"
|
||||
|
||||
QT += quick qml
|
||||
|
||||
target.path = /usr/bin
|
||||
INSTALLS += target
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
|
||||
OTHER_FILES += \
|
||||
$$files(qml/ttrss/ubuntu-touch/*.qml)
|
||||
|
||||
qml_2.files = qml/ttrss/models
|
||||
qml_2.path = $$INSTALL_ROOT/usr/share/$$TARGET/qml
|
||||
qml_3.files = qml/ttrss/resources
|
||||
qml_3.path = $$INSTALL_ROOT/usr/share/$$TARGET/qml
|
||||
INSTALLS += qml_2 qml_3
|
||||
|
||||
icon.files = images/$${TARGET}.png
|
||||
icon.path = /usr/share/icons/hicolor/86x86/apps
|
||||
INSTALLS += icon
|
||||
|
||||
desktop.files = $${TARGET}.desktop
|
||||
desktop.path = /usr/share/applications
|
||||
INSTALLS += desktop
|
||||
|
||||
RESOURCES += \
|
||||
harmattan.qrc
|
||||
|
||||
HEADERS += \
|
||||
settings.hh \
|
||||
mynetworkmanager.hh \
|
||||
qmlutils.hh
|
||||
|
||||
SOURCES += main.cpp \
|
||||
settings.cpp \
|
||||
mynetworkmanager.cpp \
|
||||
qmlutils.cpp
|
||||
|
||||
OTHER_FILES += rpm/$${TARGET}.spec \
|
||||
rpm/$${TARGET}.yaml \
|
||||
$$files(rpm/*) \
|
||||
$$files(qml/ttrss/harmattan/*)
|
||||
|
||||
TS_FILE = $${_PRO_FILE_PWD_}/i18n/$${TARGET}.ts
|
||||
|
||||
# Translation source directories
|
||||
TRANSLATION_SOURCE_CANDIDATES = $${_PRO_FILE_PWD_}/src $${_PRO_FILE_PWD_}/qml
|
||||
for(dir, TRANSLATION_SOURCE_CANDIDATES) {
|
||||
exists($$dir) {
|
||||
TRANSLATION_SOURCES += $$dir
|
||||
}
|
||||
}
|
||||
|
||||
# The target would really be $$TS_FILE, but we use a non-file target to emulate .PHONY
|
||||
update_translations.target = update_translations
|
||||
update_translations.commands += mkdir -p translations && lupdate $${TRANSLATION_SOURCES} -ts $${TS_FILE}
|
||||
QMAKE_EXTRA_TARGETS += update_translations
|
||||
PRE_TARGETDEPS += update_translations
|
||||
|
||||
build_translations.target = build_translations
|
||||
build_translations.commands += lrelease $${_PRO_FILE_}
|
||||
QMAKE_EXTRA_TARGETS += build_translations
|
||||
POST_TARGETDEPS += build_translations
|
||||
|
||||
#qm.files = $$replace(TRANSLATIONS, .ts, .qm)
|
||||
#qm.path = /usr/share/$${TARGET}/translations
|
||||
#qm.CONFIG += no_check_exist
|
||||
|
||||
#INSTALLS += qm
|
||||
|
||||
TRANSLATIONS += i18n/qml-translation.cs.ts \
|
||||
i18n/qml-translation.de.ts \
|
||||
i18n/qml-translation.en.ts \
|
||||
i18n/qml-translation.es.ts \
|
||||
i18n/qml-translation.fr.ts \
|
||||
i18n/qml-translation.ro.ts \
|
||||
i18n/qml-translation.ru.ts \
|
||||
i18n/qml-translation.zh_CN.ts
|
||||
Loading…
Add table
Reference in a new issue