git.iko.soy/maciek134/podphoenix
on main help sign in
* Reintroduce position saving and fix switching between episodes

* Make ordering of episode trail actions consistent across episode page and episode tab * Remove deletion of uncollected downloads, as the new UDM API provides us with notifications for these when we start up again

commit4e202646fca3be6f20d913a778f082a90c3d29dc authorMichael Sheldon <michael.sheldon@canonical.com> dateSun 1 Jan 2017, 14:28 (10 years ago) parentd24137b
8 files changed+108−47
app/podbird.qml+55−8 app/podcasts.js+14−2 app/ui/EpisodesPage.qml+2−2 app/ui/EpisodesTab.qml+25−24 app/ui/FullPlayingView.qml+9−3 app/ui/PlayerControls.qml+1−2 app/ui/Queue.qml+1 backend/modules/Podbird/filemanager.cpp+1−6
app/podbird.qml+55−8
@@ -245,6 +245,7 @@ MainView {
245245 artist: "",
246246 image: "",
247247 guid: "",
248+ position: 0,
248249 }
249250
250251 source = source.toString()
@@ -255,26 +256,50 @@ MainView {
255256 function toggle() {
256257 if (playbackState === MediaPlayer.PlayingState) {
257258 pause()
259+ // Save the current position when we pause
260+ savePosition()
258261 } else {
259262 play()
263+ // Clear the last saved position when we start playing again
264+ clearPosition()
260265 }
261266 }
262267
263− function playEpisode(guid, image, name, artist, url) {
268+ function savePosition() {
269+ if (currentGuid) {
270+ var db = Podcasts.init()
271+ db.transaction(function (tx) {
272+ tx.executeSql("UPDATE Episode SET position=? WHERE guid=?", [player.position, currentGuid])
273+ tx.executeSql("UPDATE Queue SET position=? WHERE guid=?", [player.position, currentGuid])
274+ })
275+ }
276+ }
277+
278+ function clearPosition() {
279+ if (currentGuid) {
280+ var db = Podcasts.init()
281+ db.transaction(function (tx) {
282+ tx.executeSql("UPDATE Episode SET position=NULL WHERE guid=?", [currentGuid])
283+ })
284+ }
285+ }
286+
287+ function playEpisode(guid, image, name, artist, url, position) {
264288 // Clear current queue
265289 player.playlist.clear()
266290 Podcasts.clearQueue()
267291
268292 // Add episode to queue
269− Podcasts.addItemToQueue(guid, image, name, artist, url)
293+ Podcasts.addItemToQueue(guid, image, name, artist, url, position)
270294 player.playlist.addItem(url)
271−
295+
272296 // Play episode
297+ pendingSeek = position
273298 player.play()
274299 }
275300
276− function addEpisodeToQueue(guid, image, name, artist, url) {
277− Podcasts.addItemToQueue(guid, image, name, artist, url)
301+ function addEpisodeToQueue(guid, image, name, artist, url, position) {
302+ Podcasts.addItemToQueue(guid, image, name, artist, url, position)
278303 player.playlist.addItem(url)
279304
280305 // If added episode is the first one in the queue, then set the current metadata
@@ -286,11 +311,13 @@ MainView {
286311 currentArtist = artist
287312 currentImage = image
288313 currentUrl = url
314+ pendingSeek = position
289315 }
290316 }
291317
292318 property bool endOfMedia: false
293319 property double progress: 0
320+ property int pendingSeek: 0
294321
295322 playlist: Playlist {
296323 playbackMode: Playlist.Sequential
@@ -305,11 +332,28 @@ MainView {
305332 currentArtist = meta.artist
306333 currentImage = meta.image
307334 currentGuid = meta.guid
335+ player.pendingSeek = meta.position
336+ }
337+ }
338+
339+ onPlaybackStateChanged: {
340+ if (playbackState === MediaPlayer.PlayingState && pendingSeek !== 0) {
341+ player.seek(pendingSeek)
342+ player.clearPosition()
343+ pendingSeek = 0;
308344 }
309345 }
310346
311347 onStatusChanged: {
312− if (status === MediaPlayer.EndOfMedia) {
348+ if (status === MediaPlayer.Loading) {
349+ if (playbackState === MediaPlayer.PlayingState && pendingSeek !== 0) {
350+ player.seek(pendingSeek)
351+ player.clearPosition()
352+ pendingSeek = 0;
353+ } else {
354+ play()
355+ }
356+ } else if (status === MediaPlayer.EndOfMedia) {
313357 console.log("[LOG]: End of Media. Stopping.")
314358 endOfMedia = true
315359 stop()
@@ -325,14 +369,17 @@ MainView {
325369 // Play then pause otherwise when we come from EndOfMedia
326370 // it calls next() until EndOfMedia again.
327371 play()
372+ pause()
328373 }
329−
330− pause()
331374 }
332375
333376 // Always reset endOfMedia
334377 endOfMedia = false
335378 }
379+
380+ Component.onDestruction: {
381+ savePosition()
382+ }
336383 }
337384
338385 PageStack {
app/podcasts.js+14−2
@@ -49,6 +49,16 @@ function init() {
4949 tx.executeSql('UPDATE Episode SET favourited=?', [false]);
5050 });
5151 }
52+
53+ /*
54+ Schema Upgrade to v1.3 which adds position information to the episode queue
55+ */
56+ if (db.version === "1.2") {
57+ console.log("Upgrading database from %1 -> v1.3".arg(db.version))
58+ db.changeVersion("1.2", "1.3", function(tx) {
59+ tx.executeSql('ALTER TABLE Queue ADD position INTEGER');
60+ });
61+ }
5262 } catch(ex) {
5363 console.log(ex)
5464 }
@@ -57,12 +67,12 @@ function init() {
5767}
5868
5969// Function to add item to queue
60−function addItemToQueue(guid, image, name, artist, url) {
70+function addItemToQueue(guid, image, name, artist, url, position) {
6171 var db = init()
6272
6373 db.transaction(function(tx) {
6474 var ind = getNextIndex(tx);
65− var rs = tx.executeSql("INSERT OR REPLACE INTO Queue (ind, guid, image, name, artist, url) VALUES (?, ?, ?, ?, ?, ?)", [ind, guid, image, name, artist, url]);
75+ var rs = tx.executeSql("INSERT OR REPLACE INTO Queue (ind, guid, image, name, artist, url, position) VALUES (?, ?, ?, ?, ?, ?, ?)", [ind, guid, image, name, artist, url, position]);
6676 if (rs.rowsAffected > 0) {
6777 console.log("[LOG]: QUEUE add OK")
6878 console.log("[LOG]: URL Added to queue: " + url)
@@ -103,6 +113,7 @@ function lookup(source) {
103113 artist: "",
104114 image: "",
105115 guid: "",
116+ position: 0,
106117 }
107118
108119 db.transaction(function(tx) {
@@ -114,6 +125,7 @@ function lookup(source) {
114125 meta.artist = episode.artist
115126 meta.image = episode.image
116127 meta.guid = episode.guid
128+ meta.position = episode.position
117129 break
118130 }
119131 }
app/ui/EpisodesPage.qml+2−2
@@ -234,7 +234,7 @@ Page {
234234 var index = episodeList.ViewItems.selectedIndices[i]
235235 if (episodeModel.get(index).audiourl) {
236236 var url = episodeModel.get(index).downloadedfile ? "file://" + episodeModel.get(index).downloadedfile : episodeModel.get(index).audiourl
237− player.addEpisodeToQueue(episodeModel.get(index).guid, episodeModel.get(index).image, episodeModel.get(index).name, episodeModel.get(index).artist, url)
237+ player.addEpisodeToQueue(episodeModel.get(index).guid, episodeModel.get(index).image, episodeModel.get(index).name, episodeModel.get(index).artist, url, episodeModel.get(index).position)
238238 }
239239 }
240240
@@ -646,7 +646,7 @@ Page {
646646 text: i18n.tr("Add to playlist")
647647 onTriggered: {
648648 var url = model.downloadedfile ? "file://" + model.downloadedfile : model.audiourl
649− player.addEpisodeToQueue(model.guid, model.image, model.name, model.artist, url)
649+ player.addEpisodeToQueue(model.guid, model.image, model.name, model.artist, url, model.position)
650650 }
651651 },
652652
app/ui/EpisodesTab.qml+25−24
@@ -275,7 +275,7 @@ Tab {
275275 var index = episodeList.ViewItems.selectedIndices[i]
276276 if (episodesModel.get(index).audiourl) {
277277 var url = episodesModel.get(index).downloadedfile ? "file://" + episodesModel.get(index).downloadedfile : episodesModel.get(index).audiourl
278− player.addEpisodeToQueue(episodesModel.get(index).guid, episodesModel.get(index).image, episodesModel.get(index).name, episodesModel.get(index).artist, url)
278+ player.addEpisodeToQueue(episodesModel.get(index).guid, episodesModel.get(index).image, episodesModel.get(index).name, episodesModel.get(index).artist, url, episodesModel.get(index).position)
279279 }
280280 }
281281
@@ -578,6 +578,26 @@ Tab {
578578
579579 trailingActions: ListItemActions {
580580 actions: [
581+ Action {
582+ iconName: model.listened ? "view-collapse" : "select"
583+ onTriggered: {
584+ var db = Podcasts.init();
585+ db.transaction(function (tx) {
586+ if (model.listened) {
587+ tx.executeSql("UPDATE Episode SET listened=0 WHERE guid=?", [model.guid])
588+ episodesModel.setProperty(model.index, "listened", 0)
589+ }
590+ else {
591+ tx.executeSql("UPDATE Episode SET listened=1 WHERE guid=?", [model.guid])
592+ episodesModel.setProperty(model.index, "listened", 1)
593+ if (episodesPageHeaderSections.selectedIndex === 0) {
594+ episodesModel.remove(model.index, 1)
595+ }
596+ }
597+ });
598+ }
599+ },
600+
581601 Action {
582602 iconName: model.downloadedfile ? "delete" : (model.queued && downloader.downloadingGuid !== model.guid ? "history" : "save")
583603 onTriggered: {
@@ -605,31 +625,11 @@ Tab {
605625 }
606626 },
607627
608− Action {
609− iconName: model.listened ? "view-collapse" : "select"
610− onTriggered: {
611− var db = Podcasts.init();
612− db.transaction(function (tx) {
613− if (model.listened) {
614− tx.executeSql("UPDATE Episode SET listened=0 WHERE guid=?", [model.guid])
615− episodesModel.setProperty(model.index, "listened", 0)
616− }
617− else {
618− tx.executeSql("UPDATE Episode SET listened=1 WHERE guid=?", [model.guid])
619− episodesModel.setProperty(model.index, "listened", 1)
620− if (episodesPageHeaderSections.selectedIndex === 0) {
621− episodesModel.remove(model.index, 1)
622− }
623− }
624− });
625− }
626− },
627−
628628 Action {
629629 iconName: "add-to-playlist"
630630 onTriggered: {
631631 var url = model.downloadedfile ? "file://" + model.downloadedfile : model.audiourl
632− player.addEpisodeToQueue(model.guid, model.image, model.name, model.artist, url)
632+ player.addEpisodeToQueue(model.guid, model.image, model.name, model.artist, url, model.position)
633633 }
634634 },
635635
@@ -669,8 +669,9 @@ Tab {
669669 selected = !selected
670670 } else {
671671 if (currentGuid !== model.guid) {
672− currentUrl = model.downloadedfile ? "file://" + model.downloadedfile : model.audiourl;
673− player.playEpisode(model.guid, model.image, model.name, model.artist, currentUrl)
672+ player.savePosition()
673+ currentUrl = model.downloadedfile ? "file://" + model.downloadedfile : model.audiourl
674+ player.playEpisode(model.guid, model.image, model.name, model.artist, currentUrl, model.position)
674675 }
675676 }
676677 }
app/ui/FullPlayingView.qml+9−3
@@ -181,7 +181,10 @@ Item {
181181 anchors.verticalCenter: parent.verticalCenter
182182 enabled: player.playlist.canGoPrevious
183183 opacity: enabled ? 1.0 : 0.4
184− onClicked: player.playlist.previous()
184+ onClicked: {
185+ player.savePosition()
186+ player.playlist.previous()
187+ }
185188
186189 Icon {
187190 id: mediaBackwardIcon
@@ -233,7 +236,7 @@ Item {
233236 width: units.gu(10)
234237 height: width
235238 opacity: playButton.pressed ? 0.4 : 1.0
236− onClicked: player.playbackState === MediaPlayer.PlayingState ? player.pause() : player.play()
239+ onClicked: player.toggle()
237240
238241 Icon {
239242 id: playIcon
@@ -288,7 +291,10 @@ Item {
288291 anchors.verticalCenter: parent.verticalCenter
289292 enabled: player.playlist.canGoNext
290293 opacity: enabled ? 1.0 : 0.4
291− onClicked: player.playlist.next()
294+ onClicked: {
295+ player.savePosition()
296+ player.playlist.next()
297+ }
292298
293299 Icon {
294300 id: mediaForwardIcon
app/ui/PlayerControls.qml+1−2
@@ -97,8 +97,7 @@ Rectangle {
9797 visible: playButton.pressed
9898 }
9999
100− onClicked: player.playbackState === MediaPlayer.PlayingState ? player.pause()
101− : player.play()
100+ onClicked: player.toggle()
102101
103102 Icon {
104103 color: "white"
app/ui/Queue.qml+1
@@ -83,6 +83,7 @@ ListView {
8383 if (player.playlist.currentIndex === index) {
8484 player.toggle()
8585 } else {
86+ player.savePosition()
8687 player.playlist.currentIndex = index
8788 }
8889 }
backend/modules/Podbird/filemanager.cpp+1−6
@@ -27,12 +27,7 @@ FileManager::FileManager(QObject *parent):
2727 QObject(parent),
2828 m_podcastDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QDir::separator() + "podcasts")
2929{
30− // Remove any downloads that haven't been collected previously (because we were closed before they finished)
31− QString downloadManagerPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QDir::separator() + "ubuntu-download-manager" + QDir::separator() + "com.mikeasoft.podbird";
32− QDir downloadDir(downloadManagerPath);
33− if (downloadDir.exists()) {
34− downloadDir.removeRecursively();
35− }
30+
3631}
3732
3833FileManager::~FileManager() {