Various bugfixes, support for filtering episode lists
This commit is contained in:
parent
431ca519d3
commit
0da88e3577
17 changed files with 421 additions and 45 deletions
|
@ -26,24 +26,66 @@ import 'constants.js' as Constants
|
|||
ListModel {
|
||||
id: episodeListModel
|
||||
|
||||
property var podcast_id
|
||||
property var podcast_id: -1
|
||||
|
||||
function loadEpisodes(podcast_id) {
|
||||
episodeListModel.podcast_id = podcast_id;
|
||||
reload();
|
||||
property var queries: ({
|
||||
All: '',
|
||||
Fresh: 'new or downloading',
|
||||
Downloaded: 'downloaded or downloading',
|
||||
HideDeleted: 'not deleted',
|
||||
Deleted: 'deleted',
|
||||
})
|
||||
|
||||
property var filters: ([
|
||||
{ label: 'All', query: episodeListModel.queries.All },
|
||||
{ label: 'Fresh', query: episodeListModel.queries.Fresh },
|
||||
{ label: 'Downloaded', query: episodeListModel.queries.Downloaded },
|
||||
{ label: 'Hide deleted', query: episodeListModel.queries.HideDeleted },
|
||||
{ label: 'Deleted', query: episodeListModel.queries.Deleted },
|
||||
])
|
||||
|
||||
property bool ready: false
|
||||
property int currentFilterIndex: -1
|
||||
property string currentCustomQuery: queries.All
|
||||
|
||||
function setQuery(query) {
|
||||
for (var i=0; i<filters.length; i++) {
|
||||
if (filters[i].query === query) {
|
||||
currentFilterIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
currentFilterIndex = -1;
|
||||
currentCustomQuery = query;
|
||||
}
|
||||
|
||||
function loadFreshEpisodes(callback) {
|
||||
function loadAllEpisodes(callback) {
|
||||
episodeListModel.podcast_id = -1;
|
||||
py.call('main.get_fresh_episodes', [], function (episodes) {
|
||||
Util.updateModelFrom(episodeListModel, episodes);
|
||||
callback();
|
||||
});
|
||||
reload(callback);
|
||||
}
|
||||
|
||||
function reload() {
|
||||
py.call('main.load_episodes', [podcast_id], function (episodes) {
|
||||
function loadEpisodes(podcast_id, callback) {
|
||||
episodeListModel.podcast_id = podcast_id;
|
||||
reload(callback);
|
||||
}
|
||||
|
||||
function reload(callback) {
|
||||
var query;
|
||||
|
||||
if (currentFilterIndex !== -1) {
|
||||
query = filters[currentFilterIndex].query;
|
||||
} else {
|
||||
query = currentCustomQuery;
|
||||
}
|
||||
|
||||
ready = false;
|
||||
py.call('main.load_episodes', [podcast_id, query], function (episodes) {
|
||||
Util.updateModelFrom(episodeListModel, episodes);
|
||||
episodeListModel.ready = true;
|
||||
if (callback !== undefined) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ var colors = {
|
|||
destructive: '#cf424f', /* destructive actions */
|
||||
|
||||
page: '#dddddd',
|
||||
dialogBackground: '#aa000000',
|
||||
text: '#333333', /* text color */
|
||||
highlight: '#433b67',
|
||||
secondaryHighlight: '#605885',
|
||||
|
|
39
main.py
39
main.py
|
@ -31,6 +31,7 @@ import gpodder
|
|||
|
||||
from gpodder.api import core
|
||||
from gpodder.api import util
|
||||
from gpodder.api import query
|
||||
|
||||
import logging
|
||||
import functools
|
||||
|
@ -55,6 +56,8 @@ def run_in_background_thread(f):
|
|||
|
||||
|
||||
class gPotherSide:
|
||||
ALL_PODCASTS = -1
|
||||
|
||||
def __init__(self):
|
||||
self.core = None
|
||||
self._checking_for_new_episodes = False
|
||||
|
@ -149,9 +152,26 @@ class gPotherSide:
|
|||
'hasShownotes': episode.description != '',
|
||||
}
|
||||
|
||||
def load_episodes(self, id):
|
||||
podcast = self._get_podcast_by_id(id)
|
||||
return [self.convert_episode(episode) for episode in podcast.episodes]
|
||||
def load_episodes(self, id=ALL_PODCASTS, eql=None):
|
||||
if id is not None and id != self.ALL_PODCASTS:
|
||||
podcasts = [self._get_podcast_by_id(id)]
|
||||
else:
|
||||
podcasts = self.core.model.get_podcasts()
|
||||
|
||||
if eql:
|
||||
filter_func = query.EQL(eql).filter
|
||||
else:
|
||||
filter_func = lambda episodes: episodes
|
||||
|
||||
result = []
|
||||
|
||||
for podcast in podcasts:
|
||||
result.extend(filter_func(podcast.episodes))
|
||||
|
||||
if id == self.ALL_PODCASTS:
|
||||
result.sort(key=lambda e: e.published, reverse=True)
|
||||
|
||||
return [self.convert_episode(episode) for episode in result]
|
||||
|
||||
def get_fresh_episodes_summary(self, count):
|
||||
summary = []
|
||||
|
@ -167,19 +187,9 @@ class gPotherSide:
|
|||
summary.sort(key=lambda e: e['newEpisodes'], reverse=True)
|
||||
return summary[:int(count)]
|
||||
|
||||
def get_fresh_episodes(self):
|
||||
fresh_episodes = []
|
||||
for podcast in self.core.model.get_podcasts():
|
||||
for episode in podcast.episodes:
|
||||
if episode.is_fresh():
|
||||
fresh_episodes.append(episode)
|
||||
|
||||
fresh_episodes.sort(key=lambda e: e.published, reverse=True)
|
||||
return [self.convert_episode(e) for e in fresh_episodes]
|
||||
|
||||
@run_in_background_thread
|
||||
def subscribe(self, url):
|
||||
url = util.normalize_feed_url(url)
|
||||
url = self.core.model.normalize_feed_url(url)
|
||||
# TODO: Check if subscription already exists
|
||||
self.core.model.load_podcast(url, create=True)
|
||||
self.core.save()
|
||||
|
@ -324,7 +334,6 @@ subscribe = gpotherside.subscribe
|
|||
unsubscribe = gpotherside.unsubscribe
|
||||
check_for_episodes = gpotherside.check_for_episodes
|
||||
get_stats = gpotherside.get_stats
|
||||
get_fresh_episodes = gpotherside.get_fresh_episodes
|
||||
get_fresh_episodes_summary = gpotherside.get_fresh_episodes_summary
|
||||
download_episode = gpotherside.download_episode
|
||||
delete_episode = gpotherside.delete_episode
|
||||
|
|
2
makefile
2
makefile
|
@ -13,7 +13,7 @@ dist/$(PROJECT)-$(VERSION).tar.gz:
|
|||
git archive --format=tar --prefix=$(PROJECT)-$(VERSION)/ $(VERSION) | gzip >$@
|
||||
|
||||
clean:
|
||||
find . -name '__pycache__' -exec rm {} +
|
||||
find . -name '__pycache__' -exec rm -rf {} +
|
||||
|
||||
distclean: clean
|
||||
rm -rf dist
|
||||
|
|
59
touch/Dialog.qml
Normal file
59
touch/Dialog.qml
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
/**
|
||||
*
|
||||
* gPodder QML UI Reference Implementation
|
||||
* Copyright (c) 2014, Thomas Perl <m@thp.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
import 'common/constants.js' as Constants
|
||||
|
||||
Rectangle {
|
||||
id: page
|
||||
color: Constants.colors.dialogBackground
|
||||
|
||||
default property alias children: contents.children
|
||||
property bool isDialog: true
|
||||
property int contentHeight: -1
|
||||
|
||||
function closePage() {
|
||||
stacking.startFadeOut();
|
||||
}
|
||||
|
||||
onXChanged: pgst.update(page, x)
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
DialogStacking { id: stacking }
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: page.closePage();
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: contents
|
||||
property int border: parent.width * 0.1
|
||||
width: parent.width - 2 * border
|
||||
property int maxHeight: parent.height - 4 * border
|
||||
height: ((page.contentHeight > 0 && page.contentHeight < maxHeight) ? page.contentHeight : maxHeight) * parent.opacity
|
||||
anchors.centerIn: parent
|
||||
color: Constants.colors.page
|
||||
clip: true
|
||||
}
|
||||
}
|
70
touch/DialogStacking.qml
Normal file
70
touch/DialogStacking.qml
Normal file
|
@ -0,0 +1,70 @@
|
|||
|
||||
/**
|
||||
*
|
||||
* gPodder QML UI Reference Implementation
|
||||
* Copyright (c) 2013, Thomas Perl <m@thp.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: stacking
|
||||
property variant page: parent
|
||||
|
||||
PropertyAnimation {
|
||||
id: fadeIn
|
||||
target: stacking.page
|
||||
property: 'opacity'
|
||||
to: 1
|
||||
duration: 500
|
||||
easing.type: Easing.OutCubic
|
||||
|
||||
onStopped: {
|
||||
pgst.loadPageInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
id: fadeOut
|
||||
target: stacking.page
|
||||
property: 'opacity'
|
||||
to: 0
|
||||
duration: 500
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
|
||||
function startFadeOut() {
|
||||
fadeOut.start();
|
||||
page.destroy(500);
|
||||
}
|
||||
|
||||
function fadeInAgain() {
|
||||
fadeIn.start();
|
||||
}
|
||||
|
||||
function stopAllAnimations() {
|
||||
fadeIn.stop();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (pgst.loadPageInProgress) {
|
||||
page.x = 0;
|
||||
page.opacity = 0;
|
||||
fadeIn.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
touch/EpisodeQueryControl.qml
Normal file
46
touch/EpisodeQueryControl.qml
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
/**
|
||||
*
|
||||
* gPodder QML UI Reference Implementation
|
||||
* Copyright (c) 2014, Thomas Perl <m@thp.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: episodeQueryControl
|
||||
|
||||
property var model
|
||||
property string title
|
||||
|
||||
function showSelectionDialog() {
|
||||
pgst.loadPage('SelectionDialog.qml', {
|
||||
title: episodeQueryControl.title,
|
||||
callback: function (index, result) {
|
||||
episodeQueryControl.model.currentFilterIndex = index;
|
||||
episodeQueryControl.model.reload();
|
||||
},
|
||||
items: function () {
|
||||
var labels = [];
|
||||
for (var i in episodeQueryControl.model.filters) {
|
||||
labels.push(episodeQueryControl.model.filters[i].label);
|
||||
}
|
||||
return labels;
|
||||
}(),
|
||||
selectedIndex: episodeQueryControl.model.currentFilterIndex,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -22,28 +22,42 @@ import QtQuick 2.0
|
|||
|
||||
import 'common'
|
||||
import 'common/util.js' as Util
|
||||
import 'common/constants.js' as Constants
|
||||
import 'icons/icons.js' as Icons
|
||||
|
||||
SlidePage {
|
||||
id: freshEpisodes
|
||||
property bool ready: false
|
||||
id: allEpisodesPage
|
||||
|
||||
EpisodeQueryControl {
|
||||
id: queryControl
|
||||
model: episodesListModel
|
||||
title: 'Select filter'
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
freshEpisodesListModel.loadFreshEpisodes(function () {
|
||||
freshEpisodes.ready = true;
|
||||
});
|
||||
episodesListModel.setQuery(episodesListModel.queries.Fresh);
|
||||
episodesListModel.reload();
|
||||
}
|
||||
|
||||
PBusyIndicator {
|
||||
visible: !freshEpisodes.ready
|
||||
visible: !episodesListModel.ready
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
PListView {
|
||||
id: episodeList
|
||||
property int selectedIndex: -1
|
||||
title: 'Fresh episodes'
|
||||
title: 'Episodes'
|
||||
headerHasIcon: true
|
||||
headerIconText: 'Filter'
|
||||
onHeaderIconClicked: queryControl.showSelectionDialog();
|
||||
|
||||
model: GPodderEpisodeListModel { id: freshEpisodesListModel }
|
||||
PPlaceholder {
|
||||
text: 'No episodes found'
|
||||
visible: episodeList.count === 0 && episodesListModel.ready
|
||||
}
|
||||
|
||||
model: GPodderEpisodeListModel { id: episodesListModel }
|
||||
|
||||
section.property: 'published'
|
||||
section.delegate: SectionHeader { text: section }
|
||||
|
@ -51,4 +65,3 @@ SlidePage {
|
|||
delegate: EpisodeItem { }
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,17 @@ SlidePage {
|
|||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Component.onCompleted: episodeListModel.loadEpisodes(podcast_id);
|
||||
Component.onCompleted: {
|
||||
episodeListModel.podcast_id = podcast_id;
|
||||
episodeListModel.setQuery(episodeListModel.queries.All);
|
||||
episodeListModel.reload();
|
||||
}
|
||||
|
||||
EpisodeQueryControl {
|
||||
id: queryControl
|
||||
model: episodeListModel
|
||||
title: 'Select filter'
|
||||
}
|
||||
|
||||
PullMenu {
|
||||
PullMenuItem {
|
||||
|
@ -81,6 +91,10 @@ SlidePage {
|
|||
title: episodesPage.title
|
||||
model: GPodderEpisodeListModel { id: episodeListModel }
|
||||
|
||||
headerHasIcon: true
|
||||
headerIconText: 'Filter'
|
||||
onHeaderIconClicked: queryControl.showSelectionDialog();
|
||||
|
||||
PPlaceholder {
|
||||
text: 'No episodes'
|
||||
visible: episodeList.count === 0
|
||||
|
|
|
@ -42,7 +42,11 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
children[index-1].opacity = x / width;
|
||||
if (page.isDialog) {
|
||||
children[index-1].opacity = 1;
|
||||
} else {
|
||||
children[index-1].opacity = x / width;
|
||||
}
|
||||
//children[index-1].pushPhase = x / width;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,19 @@ ListView {
|
|||
|
||||
property string title
|
||||
property real pushPhase: 0
|
||||
property bool headerHasIcon: false
|
||||
property string headerIconText
|
||||
|
||||
signal headerIconClicked()
|
||||
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
header: SlidePageHeader { title: pListView.title }
|
||||
|
||||
header: SlidePageHeader {
|
||||
title: pListView.title
|
||||
hasIcon: pListView.headerHasIcon
|
||||
iconText: pListView.headerIconText
|
||||
onIconClicked: pListView.headerIconClicked()
|
||||
}
|
||||
|
||||
PScrollDecorator { flickable: pListView }
|
||||
}
|
||||
|
|
|
@ -26,5 +26,5 @@ import 'common/constants.js' as Constants
|
|||
PLabel {
|
||||
anchors.centerIn: parent
|
||||
font.pixelSize: 40 * pgst.scalef
|
||||
color: Constants.colors.text
|
||||
color: Constants.colors.placeholder
|
||||
}
|
||||
|
|
84
touch/SelectionDialog.qml
Normal file
84
touch/SelectionDialog.qml
Normal file
|
@ -0,0 +1,84 @@
|
|||
|
||||
/**
|
||||
*
|
||||
* gPodder QML UI Reference Implementation
|
||||
* Copyright (c) 2014, Thomas Perl <m@thp.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
import 'common/constants.js' as Constants
|
||||
import 'icons/icons.js' as Icons
|
||||
|
||||
Dialog {
|
||||
id: selectionDialog
|
||||
|
||||
property string title: 'Dialog'
|
||||
property var callback: undefined
|
||||
property var items: ([])
|
||||
property var selectedIndex: -1
|
||||
|
||||
contentHeight: selectionDialogFlickable.contentHeight
|
||||
|
||||
Flickable {
|
||||
id: selectionDialogFlickable
|
||||
|
||||
anchors.fill: parent
|
||||
contentHeight: contentColumn.height
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
width: parent.width
|
||||
|
||||
SlidePageHeader {
|
||||
id: header
|
||||
color: Constants.colors.highlight
|
||||
title: selectionDialog.title
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: selectionDialog.items
|
||||
|
||||
delegate: ButtonArea {
|
||||
width: parent.width
|
||||
height: 60 * pgst.scalef
|
||||
|
||||
transparent: (index != selectionDialog.selectedIndex)
|
||||
|
||||
PLabel {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
margins: 20 * pgst.scalef
|
||||
}
|
||||
|
||||
text: modelData
|
||||
color: (index == selectionDialog.selectedIndex) ? Constants.colors.highlight : Constants.colors.text
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (selectionDialog.callback !== undefined) {
|
||||
selectionDialog.callback(index, modelData);
|
||||
}
|
||||
selectionDialog.closePage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PScrollDecorator { flickable: selectionDialogFlickable }
|
||||
}
|
|
@ -30,6 +30,7 @@ Rectangle {
|
|||
property alias hasPull: dragging.hasPull
|
||||
property alias canClose: dragging.canClose
|
||||
property real pullPhase: (x >= 0) ? 0 : (-x / (width / 4))
|
||||
property bool isDialog: false
|
||||
|
||||
function unPull() {
|
||||
stacking.fadeInAgain();
|
||||
|
|
|
@ -21,22 +21,45 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import 'common/constants.js' as Constants
|
||||
import 'icons/icons.js' as Icons
|
||||
|
||||
Item {
|
||||
id: slidePageHeader
|
||||
property alias title: label.text
|
||||
property alias color: label.color
|
||||
|
||||
property alias hasIcon: icon.visible
|
||||
property alias iconText: icon.text
|
||||
signal iconClicked()
|
||||
|
||||
width: parent.width
|
||||
height: Constants.layout.header.height * pgst.scalef
|
||||
|
||||
IconMenuItem {
|
||||
id: icon
|
||||
|
||||
visible: false
|
||||
enabled: visible
|
||||
|
||||
text: 'Search'
|
||||
icon: Icons.magnifying_glass
|
||||
color: label.color
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
onClicked: slidePageHeader.iconClicked()
|
||||
}
|
||||
|
||||
PLabel {
|
||||
id: label
|
||||
anchors {
|
||||
left: parent.left
|
||||
left: icon.right
|
||||
right: parent.right
|
||||
rightMargin: 20 * pgst.scalef
|
||||
leftMargin: 70 * pgst.scalef
|
||||
leftMargin: 20 * pgst.scalef
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
|
|
|
@ -134,10 +134,9 @@ SlidePage {
|
|||
|
||||
StartPageButton {
|
||||
id: freshEpisodes
|
||||
enabled: freshEpisodesRepeater.count > 0
|
||||
|
||||
title: py.refreshing ? 'Refreshing feeds' : 'Fresh episodes'
|
||||
onClicked: pgst.loadPage('FreshEpisodes.qml');
|
||||
title: py.refreshing ? 'Refreshing feeds' : 'Episodes'
|
||||
onClicked: pgst.loadPage('EpisodeQueryPage.qml');
|
||||
|
||||
Row {
|
||||
id: freshEpisodesRow
|
||||
|
|
|
@ -16,3 +16,4 @@ var aperture = '\ue026';
|
|||
var eye = '\ue025';
|
||||
var loop_alt2 = '\ue033';
|
||||
var folder = '\ue065';
|
||||
var magnifying_glass = '\ue074';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue