From 0ff355737c911e24fcf0404d083fa1c69f6b4a57 Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Mon, 10 Feb 2014 19:09:51 +0100 Subject: [PATCH] Cleanup episode events, mark episodes as old, fresh episodes fix --- common/GPodderCore.qml | 14 ++----- common/GPodderEpisodeListModel.qml | 40 +++++++++++++------- main.py | 61 ++++++++++++++++++------------ touch/EpisodeItem.qml | 11 ++++-- touch/EpisodesPage.qml | 10 +++++ touch/FreshEpisodes.qml | 29 +++----------- touch/IconMenuItem.qml | 3 +- touch/PodcastItem.qml | 18 ++++++++- touch/PodcastsPage.qml | 2 +- touch/StartPage.qml | 28 +++++++------- touch/icons/icons.js | 3 ++ 11 files changed, 126 insertions(+), 93 deletions(-) diff --git a/common/GPodderCore.qml b/common/GPodderCore.qml index aa778fb..d8cd5fa 100644 --- a/common/GPodderCore.qml +++ b/common/GPodderCore.qml @@ -28,16 +28,13 @@ Python { property string progname: 'gpodder' property bool ready: false property bool refreshing: false - signal downloading(int episode_id) signal downloadProgress(int episode_id, real progress) signal playbackProgress(int episode_id, real progress) - signal downloaded(int episode_id) - signal deleted(int episode_id) - signal isNewChanged(int episode_id, bool is_new) - signal stateChanged(int episode_id, int state) signal podcastListChanged() signal updatingPodcast(int podcast_id) signal updatedPodcast(var podcast) + signal episodeListChanged(int podcast_id) + signal updatedEpisode(var episode) Component.onCompleted: { setHandler('hello', function (coreversion, uiversion) { @@ -47,17 +44,14 @@ Python { console.log('Python ' + py.pythonVersion()); }); - setHandler('downloading', py.downloading); setHandler('download-progress', py.downloadProgress); setHandler('playback-progress', py.playbackProgress); - setHandler('downloaded', py.downloaded); - setHandler('deleted', py.deleted); - setHandler('is-new-changed', py.isNewChanged); - setHandler('state-changed', py.stateChanged); setHandler('podcast-list-changed', py.podcastListChanged); setHandler('updating-podcast', py.updatingPodcast); setHandler('updated-podcast', py.updatedPodcast); setHandler('refreshing', function(v) { py.refreshing = v; }); + setHandler('episode-list-changed', py.episodeListChanged); + setHandler('updated-episode', py.updatedEpisode); addImportPath(Qt.resolvedUrl('../..')); diff --git a/common/GPodderEpisodeListModel.qml b/common/GPodderEpisodeListModel.qml index aef3528..06a351a 100644 --- a/common/GPodderEpisodeListModel.qml +++ b/common/GPodderEpisodeListModel.qml @@ -26,7 +26,22 @@ import 'constants.js' as Constants ListModel { id: episodeListModel + property var podcast_id + function loadEpisodes(podcast_id) { + episodeListModel.podcast_id = podcast_id; + reload(); + } + + function loadFreshEpisodes(callback) { + episodeListModel.podcast_id = -1; + py.call('main.get_fresh_episodes', [], function (episodes) { + Util.updateModelFrom(episodeListModel, episodes); + callback(); + }); + } + + function reload() { py.call('main.load_episodes', [podcast_id], function (episodes) { Util.updateModelFrom(episodeListModel, episodes); }); @@ -43,21 +58,18 @@ ListModel { Util.updateModelWith(episodeListModel, 'id', episode_id, {'playbackProgress': progress}); } - onDownloaded: { - Util.updateModelWith(episodeListModel, 'id', episode_id, - {'progress': 0, 'downloadState': Constants.state.downloaded}); + onUpdatedEpisode: { + for (var i=0; i 0) ? titleLabel.color : Constants.colors.download icon: Icons.cloud_download - visible: downloadState != Constants.state.downloaded + enabled: downloadState != Constants.state.downloaded onClicked: { episodeList.selectedIndex = -1; py.call('main.download_episode', [id]); @@ -74,7 +74,7 @@ Item { text: 'Delete' color: (episodeItem.isPlaying || progress > 0) ? titleLabel.color : Constants.colors.destructive icon: Icons.trash - visible: downloadState != Constants.state.deleted + enabled: downloadState != Constants.state.deleted onClicked: { var ctx = { py: py, id: id }; pgst.showConfirmation('Delete episode', Icons.trash, function () { @@ -96,6 +96,7 @@ Item { color: titleLabel.color icon: Icons.article onClicked: pgst.loadPage('EpisodeDetail.qml', {episode_id: id, title: title}); + enabled: hasShownotes } } } @@ -175,8 +176,10 @@ Item { return Constants.colors.download; } else if (episodeItem.opened) { return Constants.colors.highlight; - } else if (isNew) { + } else if (isNew && downloadState == Constants.state.downloaded) { return Constants.colors.highlight; + } else if (isNew) { + return Constants.colors.fresh; } else { return Constants.colors.text; } @@ -202,7 +205,7 @@ Item { } visible: downloadState == Constants.state.downloaded - icon: Icons.cd + icon: Icons.folder } } } diff --git a/touch/EpisodesPage.qml b/touch/EpisodesPage.qml index 7fc004f..cd43ed8 100644 --- a/touch/EpisodesPage.qml +++ b/touch/EpisodesPage.qml @@ -49,6 +49,16 @@ SlidePage { } } + PullMenuItem { + text: 'Mark all as old' + icon: Icons.eye + color: Constants.colors.text + onClicked: { + py.call('main.mark_episodes_as_old', [episodesPage.podcast_id]); + episodesPage.unPull(); + } + } + PullMenuItem { text: 'Unsubscribe' icon: Icons.trash diff --git a/touch/FreshEpisodes.qml b/touch/FreshEpisodes.qml index 997c170..611a0ba 100644 --- a/touch/FreshEpisodes.qml +++ b/touch/FreshEpisodes.qml @@ -20,6 +20,7 @@ import QtQuick 2.0 +import 'common' import 'common/util.js' as Util SlidePage { @@ -27,8 +28,7 @@ SlidePage { property bool ready: false Component.onCompleted: { - py.call('main.get_fresh_episodes', [], function (episodes) { - Util.updateModelFrom(freshEpisodesListModel, episodes); + freshEpisodesListModel.loadFreshEpisodes(function () { freshEpisodes.ready = true; }); } @@ -39,33 +39,16 @@ SlidePage { } PListView { - id: freshEpisodesList + id: episodeList + property int selectedIndex: -1 title: 'Fresh episodes' - model: ListModel { id: freshEpisodesListModel } + model: GPodderEpisodeListModel { id: freshEpisodesListModel } section.property: 'published' section.delegate: SectionHeader { text: section } - delegate: EpisodeItem { - onClicked: py.call('main.download_episode', [id]); - - Connections { - target: py - onDownloadProgress: { - if (episode_id == id) { - freshEpisodesListModel.setProperty(index, 'progress', progress); - } - } - onDownloaded: { - if (id == episode_id) { - freshEpisodesListModel.remove(index); - } - } - } - - //pgst.loadPage('EpisodeDetail.qml', {episode_id: id, title: title}); - } + delegate: EpisodeItem { } } } diff --git a/touch/IconMenuItem.qml b/touch/IconMenuItem.qml index 5db0b8f..474f6c1 100644 --- a/touch/IconMenuItem.qml +++ b/touch/IconMenuItem.qml @@ -27,6 +27,7 @@ ButtonArea { property alias text: label.text property color color: Constants.colors.secondaryHighlight + property color _real_color: enabled ? color : Constants.colors.placeholder property alias icon: icon.icon property alias size: icon.size property bool alwaysShowText: false @@ -48,7 +49,7 @@ ButtonArea { id: label font.pixelSize: 15 * pgst.scalef visible: parent.pressed || parent.alwaysShowText - color: parent.pressed ? Qt.darker(iconMenuItem.color, 1.1) : iconMenuItem.color + color: parent.pressed ? Qt.darker(iconMenuItem._real_color, 1.1) : iconMenuItem._real_color anchors { bottom: icon.top diff --git a/touch/PodcastItem.qml b/touch/PodcastItem.qml index 690d377..ba614db 100644 --- a/touch/PodcastItem.qml +++ b/touch/PodcastItem.qml @@ -20,6 +20,8 @@ import QtQuick 2.0 +import 'common/constants.js' as Constants + ButtonArea { id: podcastItem @@ -58,12 +60,24 @@ ButtonArea { left: cover.right leftMargin: 10 * pgst.scalef rightMargin: 10 * pgst.scalef - right: parent.right + right: downloadsLabel.left verticalCenter: parent.verticalCenter } elide: Text.ElideRight text: title + color: newEpisodes ? Constants.colors.fresh : Constants.colors.text + } + + PLabel { + id: downloadsLabel + anchors { + right: parent.right + rightMargin: 10 * pgst.scalef + verticalCenter: parent.verticalCenter + } + + text: downloaded ? downloaded : '' + color: Constants.colors.text } } - diff --git a/touch/PodcastsPage.qml b/touch/PodcastsPage.qml index d1b1394..a5e230b 100644 --- a/touch/PodcastsPage.qml +++ b/touch/PodcastsPage.qml @@ -42,7 +42,7 @@ SlidePage { PullMenuItem { text: 'Refresh feeds' - icon: Icons.reload + icon: Icons.loop_alt2 onClicked: { podcastsPage.unPull(); py.call('main.check_for_episodes'); diff --git a/touch/StartPage.qml b/touch/StartPage.qml index 854957b..3999e28 100644 --- a/touch/StartPage.qml +++ b/touch/StartPage.qml @@ -116,35 +116,35 @@ SlidePage { StartPageButton { id: freshEpisodesPage + enabled: freshEpisodesRepeater.count > 0 title: py.refreshing ? 'Refreshing feeds' : 'Fresh episodes' onClicked: pgst.loadPage('FreshEpisodes.qml'); Row { + id: freshEpisodesRow + anchors.bottom: parent.bottom - anchors.bottomMargin: 50 * pgst.scalef + anchors.bottomMargin: 20 * pgst.scalef anchors.leftMargin: 20 * pgst.scalef anchors.left: parent.left spacing: 10 * pgst.scalef + PLabel { + color: Constants.colors.placeholder + text: 'No fresh episodes' + visible: freshEpisodesRepeater.count == 0 + } + Repeater { id: freshEpisodesRepeater - Image { + CoverArt { source: modelData.coverart - sourceSize { width: 80 * pgst.scalef; height: 80 * pgst.scalef } + text: modelData.title + width: 80 * pgst.scalef height: 80 * pgst.scalef - - PLabel { - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.bottom - margins: 5 * pgst.scalef - } - - text: modelData.newEpisodes - } } } } @@ -165,7 +165,7 @@ SlidePage { PIcon { id: refresher - icon: Icons.reload + icon: Icons.loop_alt2 color: Constants.colors.highlight anchors { diff --git a/touch/icons/icons.js b/touch/icons/icons.js index 3aecfa3..e7605e9 100644 --- a/touch/icons/icons.js +++ b/touch/icons/icons.js @@ -13,3 +13,6 @@ var arrow_left = '\u2190'; var arrow_right = '\u2192'; var last = '\ue04d'; var aperture = '\ue026'; +var eye = '\ue025'; +var loop_alt2 = '\ue033'; +var folder = '\ue065';