diff --git a/touch/EpisodeListView.qml b/touch/EpisodeListView.qml new file mode 100644 index 0000000..f8948db --- /dev/null +++ b/touch/EpisodeListView.qml @@ -0,0 +1,53 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2013, 2014, Thomas Perl + * + * 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' + + +PListView { + id: episodeList + + property int selectedIndex: -1 + + PScrollIntoView { id: scrollIntoView } + + onSelectedIndexChanged: { + if (selectedIndex === count - 1) { + scrollIntoView.begin(episodeList); + } + } + + model: GPodderEpisodeListModel { id: episodeListModel } + + PBusyIndicator { + visible: !episodeListModel.ready + anchors.centerIn: parent + } + + PPlaceholder { + // TODO: If filter is "all", say "No episodes" + text: 'No episodes found' + visible: episodeList.count === 0 && episodeListModel.ready + } + + delegate: EpisodeItem { } +} diff --git a/touch/EpisodeQueryPage.qml b/touch/EpisodeQueryPage.qml index b6985d0..70ae4b8 100644 --- a/touch/EpisodeQueryPage.qml +++ b/touch/EpisodeQueryPage.qml @@ -35,35 +35,20 @@ SlidePage { EpisodeQueryControl { id: queryControl - model: episodesListModel + model: episodeList.model title: 'Select filter' } Component.onCompleted: { - episodesListModel.setQuery(episodesListModel.queries.Fresh); - episodesListModel.reload(); + episodeList.model.setQuery(episodeList.model.queries.Fresh); + episodeList.model.reload(); } - PBusyIndicator { - visible: !episodesListModel.ready - anchors.centerIn: parent - } - - PListView { + EpisodeListView { id: episodeList - property int selectedIndex: -1 title: 'Episodes' - PPlaceholder { - text: 'No episodes found' - visible: episodeList.count === 0 && episodesListModel.ready - } - - model: GPodderEpisodeListModel { id: episodesListModel } - section.property: 'section' section.delegate: SectionHeader { text: section } - - delegate: EpisodeItem { } } } diff --git a/touch/EpisodesPage.qml b/touch/EpisodesPage.qml index 299a746..1dac9a6 100644 --- a/touch/EpisodesPage.qml +++ b/touch/EpisodesPage.qml @@ -31,9 +31,6 @@ SlidePage { property int podcast_id property string title - width: parent.width - height: parent.height - hasMenuButton: true menuButtonLabel: 'Settings' onMenuButtonClicked: { @@ -65,29 +62,19 @@ SlidePage { Component.onCompleted: { - episodeListModel.podcast_id = podcast_id; - episodeListModel.setQuery(episodeListModel.queries.All); - episodeListModel.reload(); + episodeList.model.podcast_id = podcast_id; + episodeList.model.setQuery(episodeList.model.queries.All); + episodeList.model.reload(); } EpisodeQueryControl { id: queryControl - model: episodeListModel + model: episodeList.model title: 'Select filter' } - PListView { + EpisodeListView { id: episodeList - property int selectedIndex: -1 title: episodesPage.title - model: GPodderEpisodeListModel { id: episodeListModel } - - PPlaceholder { - text: 'No episodes' - visible: episodeList.count === 0 - } - - delegate: EpisodeItem { } } } - diff --git a/touch/PScrollIntoView.qml b/touch/PScrollIntoView.qml new file mode 100644 index 0000000..3e40199 --- /dev/null +++ b/touch/PScrollIntoView.qml @@ -0,0 +1,54 @@ + +/** + * + * gPodder QML UI Reference Implementation + * Copyright (c) 2014, Thomas Perl + * + * 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 + + +Timer { + id: scrollTimer + interval: 10 + repeat: true + + function begin(flickable_) { + flickable = flickable_; + lastHeight = flickable.contentHeight; + repeatLimit = defaultRepeatLimit; + scrollTimer.start(); + } + + property var flickable + property int defaultRepeatLimit: 10 + property int repeatLimit: defaultRepeatLimit + property real lastHeight: 0 + + onTriggered: { + flickable.contentY = flickable.contentHeight - flickable.height; + flickable.returnToBounds(); + + repeatLimit = repeatLimit - 1; + lastHeight = flickable.contentHeight; + + if (repeatLimit <= 0 && lastHeight === flickable.contentHeight) { + stop(); + } + } +}