Merge lp:~nik90/podbird/7-mark-episode-listened into lp:podbird

Proposed by Nekhelesh Ramananthan
Status: Merged
Merged at revision: 51
Proposed branch: lp:~nik90/podbird/7-mark-episode-listened
Merge into: lp:podbird
Prerequisite: lp:~nik90/podbird/6-hide-listened-episodes
Diff against target: 671 lines (+263/-200)
6 files modified
app/podbird.qml (+16/-1)
app/podcasts.js (+84/-1)
app/ui/ActionButton.qml (+1/-2)
app/ui/EpisodesPage.qml (+130/-100)
app/ui/PodcastsTab.qml (+6/-82)
po/com.mikeasoft.podbird.pot (+26/-14)
To merge this branch: bzr merge lp:~nik90/podbird/7-mark-episode-listened
Reviewer Review Type Date Requested Status
Michael Sheldon Needs Fixing
Review via email: mp+254726@code.launchpad.net

Description of the change

Added a action button which allows a user to mark an episode as listened/unlistened.

To post a comment you must log in.
58. By Nekhelesh Ramananthan

merged prerequisite lp:~nik90/podbird/6-hide-listened-episodes

59. By Nekhelesh Ramananthan

Merged prerequisite lp:~nik90/podbird/6-hide-listened-episodes

60. By Nekhelesh Ramananthan

Made popover more dynamic

61. By Nekhelesh Ramananthan

merge prerequisite

62. By Nekhelesh Ramananthan

merged prerequisite

63. By Nekhelesh Ramananthan

Added support for the new queued variable

64. By Nekhelesh Ramananthan

Merged prerequisite

65. By Nekhelesh Ramananthan

Fixed incorrect merge

66. By Nekhelesh Ramananthan

merged prerequisite

67. By Nekhelesh Ramananthan

merged

68. By Nekhelesh Ramananthan

merged prerequisite

69. By Nekhelesh Ramananthan

Missed setting queued status during refresh model function call in podcasts tab

70. By Nekhelesh Ramananthan

Added missing ?

71. By Nekhelesh Ramananthan

Check for new episodes before auto-downloading episodes. Also optimized podcast removal feature

72. By Nekhelesh Ramananthan

merged prerequisite

73. By Nekhelesh Ramananthan

Merged prerequisite

Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

The text for the new popups is unreadable when using the dark theme, is this fixed in another branch?

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Yeah I fixed it in 9-whatsnewpage if I remember correctly.

Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

Okay, in that case the only other thing I see that's a bit off about this is the duplication of updateEpisodes(), there seems to be three implementations of this in EpisodesPage.qml PodcastsTab.qml and now also in podcast.js; it'd seem to make sense to remove the versions in the QML files and only use the one that this branch adds to podcast.js

review: Needs Fixing
74. By Nekhelesh Ramananthan

merged lp:podbird

75. By Nekhelesh Ramananthan

Removed duplicate updateEpisode() functions by using a generic one

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/podbird.qml'
2--- app/podbird.qml 2015-04-16 18:59:52 +0000
3+++ app/podbird.qml 2015-04-18 21:07:50 +0000
4@@ -44,9 +44,24 @@
5 Component.onDestruction: {
6 console.log("[LOG]: Download cancelled");
7 downloader.cancel();
8+ var db = Podcasts.init()
9+ db.transaction(function (tx) {
10+ tx.executeSql('UPDATE Episode SET queued=0 WHERE queued=1');
11+ })
12 }
13
14+ // Blank function required inorder to call the generic updateEpisodes() functions
15+ // which requires refreshModel() argument which doesn't apply here.
16+ function blankFunction() {}
17+
18 Component.onCompleted: {
19+ var db = Podcasts.init()
20+ db.transaction(function (tx) {
21+ tx.executeSql('UPDATE Episode SET queued=0 WHERE queued=1');
22+ })
23+
24+ Podcasts.updateEpisodes(blankFunction)
25+
26 var today = new Date()
27 // Only perform cleanup of old episodes once a day
28 if (Math.floor((today - settings.lastCheck)/86400000) >= 1 && settings.retentionDays !== -1) {
29@@ -111,7 +126,7 @@
30 var db = Podcasts.init();
31 var finalLocation = fileManager.saveDownload(path);
32 db.transaction(function (tx) {
33- tx.executeSql("UPDATE Episode SET downloadedfile=? WHERE guid=?", [finalLocation, downloadingGuid]);
34+ tx.executeSql("UPDATE Episode SET downloadedfile=?, queued=0 WHERE guid=?", [finalLocation, downloadingGuid]);
35 queue.shift();
36 if (queue.length > 0) {
37 downloadingGuid = queue[0][0];
38
39=== modified file 'app/podcasts.js'
40--- app/podcasts.js 2015-04-10 02:46:46 +0000
41+++ app/podcasts.js 2015-04-18 21:07:50 +0000
42@@ -21,7 +21,7 @@
43
44 db.transaction(function(tx) {
45 tx.executeSql('CREATE TABLE IF NOT EXISTS Podcast(artist TEXT, name TEXT, description TEXT, feed TEXT, image TEXT, lastupdate TIMESTAMP)');
46- tx.executeSql('CREATE TABLE IF NOT EXISTS Episode(guid TEXT, podcast INTEGER, name TEXT, subtitle TEXT, description TEXT, duration INTEGER, audiourl TEXT, downloadedfile TEXT, published TIMESTAMP, listened BOOLEAN, queued BOOLEAN, position INTEGER, FOREIGN KEY(podcast) REFERENCES Podcast(rowid))');
47+ tx.executeSql('CREATE TABLE IF NOT EXISTS Episode(guid TEXT, podcast INTEGER, name TEXT, subtitle TEXT, description TEXT, duration INTEGER, audiourl TEXT, downloadedfile TEXT, published TIMESTAMP, queued BOOLEAN, listened BOOLEAN, position INTEGER, FOREIGN KEY(podcast) REFERENCES Podcast(rowid))');
48 });
49
50 /*
51@@ -48,6 +48,89 @@
52 });
53 }
54
55+function updateEpisodes(refreshModel) {
56+ console.log("[LOG]: Checking for new episodes")
57+
58+ var db = Podcasts.init();
59+ db.transaction(function(tx) {
60+ var rs = tx.executeSql("SELECT rowid, feed FROM Podcast");
61+ tx.executeSql("UPDATE Podcast SET lastupdate=CURRENT_TIMESTAMP");
62+ var xhr = [];
63+ for(var i = 0; i < rs.rows.length; i++) {
64+ (function (i) {
65+ xhr[i] = new XMLHttpRequest;
66+ var url = rs.rows.item(i).feed;
67+ var pid = rs.rows.item(i).rowid;
68+ xhr[i].open("GET", url);
69+ xhr[i].onreadystatechange = function() {
70+ if (xhr[i].readyState === XMLHttpRequest.DONE) {
71+ var e = xhr[i].responseXML.documentElement;
72+ for(var h = 0; h < e.childNodes.length; h++) {
73+ if(e.childNodes[h].nodeName === "channel") {
74+ var c = e.childNodes[h];
75+ for(var j = 0; j < c.childNodes.length; j++) {
76+ if(c.childNodes[j].nodeName === "item") {
77+ var t = c.childNodes[j];
78+ var track = {}
79+ for(var k = 0; k < t.childNodes.length; k++) {
80+ try {
81+ var nodeName = t.childNodes[k].nodeName.toLowerCase();
82+ if (nodeName === "title") track['name'] = t.childNodes[k].childNodes[0].nodeValue;
83+ else if (nodeName === "description") track['description'] = t.childNodes[k].childNodes[0].nodeValue;
84+ else if (nodeName === "guid") track['guid'] = t.childNodes[k].childNodes[0].nodeValue;
85+ else if (nodeName === "pubdate") track['published'] = new Date(t.childNodes[k].childNodes[0].nodeValue).getTime();
86+ else if (nodeName === "duration") {
87+ var dur = t.childNodes[k].childNodes[0].nodeValue.split(":");
88+ if (dur.length === 1) {
89+ track['duration'] = parseInt(dur[0]);
90+ } else if (dur.length === 2) {
91+ track['duration'] = parseInt(dur[0]) * 60 + parseInt(dur[1]);
92+ } else if (dur.length === 3) {
93+ track['duration'] = parseInt(dur[0]) * 3600 + parseInt(dur[1]) * 60 + parseInt(dur[2]);
94+ }
95+ } else if (nodeName === "enclosure") {
96+ var el = t.childNodes[k];
97+ for (var l = 0; l < el.attributes.length; l++) {
98+ if(el.attributes[l].nodeName === "url") track['audiourl'] = el.attributes[l].nodeValue;
99+ }
100+ }
101+ } catch(err) {
102+ console.debug("Error: " + err.message);
103+ }
104+ }
105+ if (!track.hasOwnProperty("guid")) {
106+ track['guid'] = track.audiourl;
107+ }
108+
109+ db.transaction(function(tx2) {
110+ var ers = tx2.executeSql("SELECT rowid FROM Episode WHERE guid=?", [track.guid]);
111+ if (ers.rows.length === 0) {
112+ tx2.executeSql("INSERT INTO Episode(podcast, name, description, audiourl, guid, listened, queued, duration, published) VALUES(?, ?, ? , ?, ?, ?, ?, ?, ?)", [pid,
113+ track.name,
114+ track.description,
115+ track.audiourl,
116+ track.guid,
117+ false,
118+ false,
119+ track.duration,
120+ track.published]);
121+ }
122+ });
123+ }
124+ }
125+ }
126+ }
127+ }
128+ refreshModel();
129+ }
130+ xhr[i].send();
131+ })(i);
132+ }
133+ });
134+
135+ console.log("[LOG]: Finished checking for new episodes..")
136+}
137+
138 function getTimeDiff(time) {
139 var hours, minutes;
140 time = Math.floor(time / 60)
141
142=== modified file 'app/ui/ActionButton.qml'
143--- app/ui/ActionButton.qml 2015-04-02 12:14:26 +0000
144+++ app/ui/ActionButton.qml 2015-04-18 21:07:50 +0000
145@@ -22,7 +22,7 @@
146 AbstractButton {
147 id: abstractButton
148
149- property string iconName
150+ property alias iconName: _icon.name
151 property alias color: _icon.color
152
153 Rectangle {
154@@ -36,7 +36,6 @@
155 width: units.gu(2.5)
156 height: width
157 anchors.centerIn: parent
158- name: abstractButton.iconName
159 color: podbird.theme.baseIcon
160 }
161 }
162
163=== modified file 'app/ui/EpisodesPage.qml'
164--- app/ui/EpisodesPage.qml 2015-04-18 17:08:56 +0000
165+++ app/ui/EpisodesPage.qml 2015-04-18 21:07:50 +0000
166@@ -210,6 +210,120 @@
167 }
168 }
169
170+ Component {
171+ id: popoverComponent
172+
173+ Popover {
174+ id: popover
175+
176+ property bool queued: false
177+ property bool listened: false
178+ property string downloadedfile: ""
179+ property string guid: ""
180+ property string audiourl: ""
181+ property int index: -1
182+
183+ contentWidth: mainColumn.width
184+
185+ Column {
186+ id: mainColumn
187+
188+ width: Math.max(download.width, listen.width)
189+ anchors.top: parent.top
190+
191+ ListItem.Empty {
192+ id: download
193+
194+ width: Math.max(row.width, row2.width)
195+
196+ Row {
197+ id: row
198+
199+ spacing: units.gu(3)
200+ anchors.left: parent.left
201+ anchors.leftMargin: units.gu(2)
202+ anchors.verticalCenter: parent.verticalCenter
203+ width: downloadIcon.width + downloadText.implicitWidth + row.spacing + units.gu(4)
204+
205+ Icon {
206+ id: downloadIcon
207+ width: height
208+ height: downloadText.height
209+ name: popover.downloadedfile ? "delete" : (popover.queued && downloader.downloadingGuid !== popover.guid ? "history" : "save")
210+ }
211+
212+ Label {
213+ id: downloadText
214+ text: popover.downloadedfile ? i18n.tr("Delete local file")
215+ : (popover.queued && downloader.downloadingGuid !== popover.guid ? i18n.tr("Episode queued for download")
216+ : i18n.tr("Download episode"))
217+ }
218+ }
219+
220+ enabled: downloader.downloadingGuid !== popover.guid
221+ onClicked: {
222+ var db = Podcasts.init();
223+ if (popover.downloadedfile) {
224+ fileManager.deleteFile(popover.downloadedfile);
225+ db.transaction(function (tx) {
226+ tx.executeSql("UPDATE Episode SET downloadedfile = NULL WHERE guid = ?", [popover.guid]);
227+ });
228+ episodeModel.setProperty(popover.index, "downloadedfile", "")
229+ } else {
230+ db.transaction(function (tx) {
231+ tx.executeSql("UPDATE Episode SET queued=1 WHERE guid = ?", [popover.guid]);
232+ });
233+ episodeModel.setProperty(popover.index, "queued", 1)
234+ downloader.addDownload(popover.guid, popover.audiourl);
235+ }
236+ PopupUtils.close(popover)
237+ }
238+ }
239+
240+ ListItem.Empty {
241+ id: listen
242+
243+ showDivider: false
244+ width: Math.max(row.width, row2.width)
245+
246+ Row {
247+ id: row2
248+
249+ spacing: units.gu(3)
250+ anchors.left: parent.left
251+ anchors.leftMargin: units.gu(2)
252+ anchors.verticalCenter: parent.verticalCenter
253+ width: listenIcon.width + listenText.implicitWidth + row2.spacing + units.gu(4)
254+
255+ Icon {
256+ id: listenIcon
257+ width: height
258+ height: listenText.height
259+ name: popover.listened ? "view-collapse" : "select"
260+ }
261+
262+ Label {
263+ id: listenText
264+ text: popover.listened ? "Mark episode unlistened" : "Mark episode listened"
265+ }
266+ }
267+
268+ onClicked: {
269+ var db = Podcasts.init();
270+ db.transaction(function (tx) {
271+ if (popover.listened)
272+ tx.executeSql("UPDATE Episode SET listened=0 WHERE guid=?", [popover.guid])
273+ else
274+ tx.executeSql("UPDATE Episode SET listened=1 WHERE guid=?", [popover.guid])
275+ refreshModel();
276+ });
277+ PopupUtils.close(popover)
278+ }
279+ }
280+ }
281+ }
282+ }
283+
284 EmptyState {
285 anchors.centerIn: parent
286 anchors.verticalCenterOffset: Qt.inputMethod.visible ? units.gu(4) : 0
287@@ -409,31 +523,22 @@
288 }
289
290 ActionButton {
291- id: downloadButton
292+ id: contextualMenu
293
294 width: units.gu(5)
295 height: units.gu(4)
296
297- property bool queued: false
298-
299- iconName: model.downloadedfile ? "delete" : (queued && downloader.downloadingGuid !== model.guid ? "history" : "save")
300- enabled: downloader.downloadingGuid !== model.guid
301- color: downloader.downloadingGuid === model.guid ? podbird.theme.focusText
302- : podbird.theme.baseText
303-
304+ iconName: "contextual-menu"
305+ color: progressBar.visible || listItem.expanded ? podbird.theme.focusText
306+ : podbird.theme.baseIcon
307 onClicked: {
308- if (model.downloadedfile) {
309- fileManager.deleteFile(model.downloadedfile);
310- var db = Podcasts.init();
311- db.transaction(function (tx) {
312- tx.executeSql("UPDATE Episode SET downloadedfile = NULL WHERE guid = ?", [model.guid]);
313- });
314- episodeModel.setProperty(index, "downloadedfile", "")
315- downloadButton.queued = false
316- } else {
317- downloadButton.queued = true;
318- downloader.addDownload(model.guid, model.audiourl);
319- }
320+ var popover = PopupUtils.open(popoverComponent, contextualMenu)
321+ popover.queued = Qt.binding(function() { return model.queued })
322+ popover.listened = Qt.binding(function() { return model.listened })
323+ popover.guid = Qt.binding(function() { return model.guid })
324+ popover.audiourl = Qt.binding(function() { return model.audiourl })
325+ popover.downloadedfile = Qt.binding(function() { return episodeModel.get(index).downloadedfile })
326+ popover.index = Qt.binding(function() { return index })
327 }
328 }
329
330@@ -520,7 +625,7 @@
331
332 PullToRefresh {
333 refreshing: episodesUpdating
334- onRefresh: updateEpisodes();
335+ onRefresh: updateEpisodesDatabase();
336 }
337 }
338
339@@ -546,92 +651,17 @@
340 for(i = 0; i < rs.rows.length; i++) {
341 episode = rs.rows.item(i);
342 if (!episode.listened) {
343- episodeModel.insert(newCount, {"guid" : episode.guid, "listened" : episode.listened, "published": episode.published, "name" : episode.name, "description" : episode.description, "duration" : episode.duration, "position" : episode.position, "downloadedfile" : episode.downloadedfile, "image" : img, "artist" : artist, "audiourl" : episode.audiourl});
344+ episodeModel.insert(newCount, {"guid" : episode.guid, "listened" : episode.listened, "published": episode.published, "name" : episode.name, "description" : episode.description, "duration" : episode.duration, "position" : episode.position, "downloadedfile" : episode.downloadedfile, "image" : img, "artist" : artist, "audiourl" : episode.audiourl, "queued": episode.queued});
345 newCount++;
346 } else if (!podbird.settings.hideListened) {
347- episodeModel.insert(i,{"guid" : episode.guid, "listened" : episode.listened, "published": episode.published, "name" : episode.name, "description" : episode.description, "duration" : episode.duration, "position" : episode.position, "downloadedfile" : episode.downloadedfile, "image" : img, "artist" : artist, "audiourl" : episode.audiourl});
348+ episodeModel.insert(i,{"guid" : episode.guid, "listened" : episode.listened, "published": episode.published, "name" : episode.name, "description" : episode.description, "duration" : episode.duration, "position" : episode.position, "downloadedfile" : episode.downloadedfile, "image" : img, "artist" : artist, "audiourl" : episode.audiourl, "queued": episode.queued});
349 }
350 }
351 });
352 }
353
354- function updateEpisodes() {
355- var db = Podcasts.init();
356+ function updateEpisodesDatabase() {
357 episodesUpdating = true;
358- db.transaction(function(tx) {
359- var rs = tx.executeSql("SELECT rowid, feed FROM Podcast");
360- tx.executeSql("UPDATE Podcast SET lastupdate=CURRENT_TIMESTAMP");
361- var xhr = [];
362- for(var i = 0; i < rs.rows.length; i++) {
363- (function (i) {
364- xhr[i] = new XMLHttpRequest;
365- var url = rs.rows.item(i).feed;
366- var pid = rs.rows.item(i).rowid;
367- xhr[i].open("GET", url);
368- xhr[i].onreadystatechange = function() {
369- if (xhr[i].readyState === XMLHttpRequest.DONE) {
370- var e = xhr[i].responseXML.documentElement;
371- for(var h = 0; h < e.childNodes.length; h++) {
372- if(e.childNodes[h].nodeName === "channel") {
373- var c = e.childNodes[h];
374- for(var j = 0; j < c.childNodes.length; j++) {
375- if(c.childNodes[j].nodeName === "item") {
376- var t = c.childNodes[j];
377- var track = {}
378- for(var k = 0; k < t.childNodes.length; k++) {
379- try {
380- var nodeName = t.childNodes[k].nodeName.toLowerCase();
381- if (nodeName === "title") track['name'] = t.childNodes[k].childNodes[0].nodeValue;
382- else if (nodeName === "description") track['description'] = t.childNodes[k].childNodes[0].nodeValue;
383- else if (nodeName === "guid") track['guid'] = t.childNodes[k].childNodes[0].nodeValue;
384- else if (nodeName === "pubdate") track['published'] = new Date(t.childNodes[k].childNodes[0].nodeValue).getTime();
385- else if (nodeName === "duration") {
386- var dur = t.childNodes[k].childNodes[0].nodeValue.split(":");
387- if (dur.length === 1) {
388- track['duration'] = parseInt(dur[0]);
389- } else if (dur.length === 2) {
390- track['duration'] = parseInt(dur[0]) * 60 + parseInt(dur[1]);
391- } else if (dur.length === 3) {
392- track['duration'] = parseInt(dur[0]) * 3600 + parseInt(dur[1]) * 60 + parseInt(dur[2]);
393- }
394- } else if (nodeName === "enclosure") {
395- var el = t.childNodes[k];
396- for (var l = 0; l < el.attributes.length; l++) {
397- if(el.attributes[l].nodeName === "url") track['audiourl'] = el.attributes[l].nodeValue;
398- }
399- }
400- } catch(err) {
401- console.debug(err.message);
402- }
403- }
404- if (!track.hasOwnProperty("guid")) {
405- track['guid'] = track.audiourl;
406- }
407-
408- db.transaction(function(tx2) {
409- var ers = tx2.executeSql("SELECT rowid FROM Episode WHERE guid=?", [track.guid]);
410- if (ers.rows.length === 0) {
411- tx2.executeSql("INSERT INTO Episode(podcast, name, description, audiourl, guid, listened, duration, published) VALUES(?, ?, ? , ?, ?, ?, ?, ?)", [pid,
412- track.name,
413- track.description,
414- track.audiourl,
415- track.guid,
416- false,
417- track.duration,
418- track.published]);
419- }
420- });
421- }
422- }
423- }
424- }
425- }
426- refreshModel();
427- }
428- xhr[i].send();
429-
430- })(i);
431- }
432- });
433+ Podcasts.updateEpisodes(refreshModel)
434 }
435 }
436
437=== modified file 'app/ui/PodcastsTab.qml'
438--- app/ui/PodcastsTab.qml 2015-04-02 23:21:55 +0000
439+++ app/ui/PodcastsTab.qml 2015-04-18 21:07:50 +0000
440@@ -218,7 +218,7 @@
441 }
442 tx.executeSql("DELETE FROM Episode WHERE podcast=?", [model.id]);
443 tx.executeSql("DELETE FROM Podcast WHERE rowid=?", [model.id]);
444- refreshModel()
445+ podcastModel.remove(index, 1);
446 });
447 }
448
449@@ -292,7 +292,7 @@
450
451 PullToRefresh {
452 refreshing: episodesUpdating
453- onRefresh: updateEpisodes();
454+ onRefresh: updateEpisodesDatabase();
455 }
456 }
457 Scrollbar {
458@@ -311,7 +311,7 @@
459 var rs2 = tx.executeSql("SELECT Count(*) AS epcount FROM Episode WHERE podcast=? AND NOT listened", [rs.rows.item(i).rowid]);
460 podcastModel.append({"id" : podcast.rowid, "name" : podcast.name, "artist" : podcast.artist, "image" : podcast.image, "episodeCount" : rs2.rows.item(0).epcount});
461 if (podcast.lastupdate === null && !episodesUpdating) {
462- updateEpisodes();
463+ updateEpisodesDatabase();
464 }
465 }
466 });
467@@ -359,7 +359,7 @@
468 Podcasts.subscribe(artist, name, feed, image);
469 imageDownloader.feed = feed;
470 imageDownloader.download(image);
471- updateEpisodes();
472+ updateEpisodesDatabase();
473 } else {
474 PopupUtils.open(subscribeFailedDialog);
475 feedUrlField.text = feed
476@@ -371,85 +371,9 @@
477 xhr.send();
478 }
479
480- function updateEpisodes() {
481- var db = Podcasts.init();
482+ function updateEpisodesDatabase() {
483 episodesUpdating = true;
484- db.transaction(function(tx) {
485- var rs = tx.executeSql("SELECT rowid, feed FROM Podcast");
486- tx.executeSql("UPDATE Podcast SET lastupdate=CURRENT_TIMESTAMP");
487- var xhr = [];
488- for(var i = 0; i < rs.rows.length; i++) {
489- (function (i) {
490- xhr[i] = new XMLHttpRequest;
491- var url = rs.rows.item(i).feed;
492- var pid = rs.rows.item(i).rowid;
493- xhr[i].open("GET", url);
494- xhr[i].onreadystatechange = function() {
495- if (xhr[i].readyState === XMLHttpRequest.DONE) {
496- var e = xhr[i].responseXML.documentElement;
497- for(var h = 0; h < e.childNodes.length; h++) {
498- if(e.childNodes[h].nodeName === "channel") {
499- var c = e.childNodes[h];
500- for(var j = 0; j < c.childNodes.length; j++) {
501- if(c.childNodes[j].nodeName === "item") {
502- var t = c.childNodes[j];
503- var track = {}
504- for(var k = 0; k < t.childNodes.length; k++) {
505- try {
506- var nodeName = t.childNodes[k].nodeName.toLowerCase();
507- if (nodeName === "title") track['name'] = t.childNodes[k].childNodes[0].nodeValue;
508- else if (nodeName === "description") track['description'] = t.childNodes[k].childNodes[0].nodeValue;
509- else if (nodeName === "guid") track['guid'] = t.childNodes[k].childNodes[0].nodeValue;
510- else if (nodeName === "pubdate") track['published'] = new Date(t.childNodes[k].childNodes[0].nodeValue).getTime();
511- else if (nodeName === "duration") {
512- var dur = t.childNodes[k].childNodes[0].nodeValue.split(":");
513- if (dur.length === 1) {
514- track['duration'] = parseInt(dur[0]);
515- } else if (dur.length === 2) {
516- track['duration'] = parseInt(dur[0]) * 60 + parseInt(dur[1]);
517- } else if (dur.length === 3) {
518- track['duration'] = parseInt(dur[0]) * 3600 + parseInt(dur[1]) * 60 + parseInt(dur[2]);
519- }
520- } else if (nodeName === "enclosure") {
521- var el = t.childNodes[k];
522- for (var l = 0; l < el.attributes.length; l++) {
523- if(el.attributes[l].nodeName === "url") track['audiourl'] = el.attributes[l].nodeValue;
524- }
525- }
526- } catch(err) {
527- console.debug(err.message);
528- }
529- }
530- if (!track.hasOwnProperty("guid")) {
531- track['guid'] = track.audiourl;
532- }
533-
534- db.transaction(function(tx2) {
535- var ers = tx2.executeSql("SELECT rowid FROM Episode WHERE guid=?", [track.guid]);
536- if (ers.rows.length === 0) {
537- tx2.executeSql("INSERT INTO Episode(podcast, name, description, audiourl, guid, listened, duration, published) VALUES(?, ?, ? , ?, ?, ?, ?, ?)", [pid,
538- track.name,
539- track.description,
540- track.audiourl,
541- track.guid,
542- false,
543- track.duration,
544- track.published]);
545- }
546- });
547- }
548- }
549- }
550- }
551- }
552- refreshModel();
553- }
554- xhr[i].send();
555-
556- })(i);
557- }
558- });
559+ Podcasts.updateEpisodes(refreshModel)
560 }
561-
562 }
563
564
565=== modified file 'po/com.mikeasoft.podbird.pot'
566--- po/com.mikeasoft.podbird.pot 2015-04-18 16:58:54 +0000
567+++ po/com.mikeasoft.podbird.pot 2015-04-18 21:07:50 +0000
568@@ -8,7 +8,7 @@
569 msgstr ""
570 "Project-Id-Version: \n"
571 "Report-Msgid-Bugs-To: \n"
572-"POT-Creation-Date: 2015-04-18 17:56+0100\n"
573+"POT-Creation-Date: 2015-04-18 23:04+0200\n"
574 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
575 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
576 "Language-Team: LANGUAGE <LL@li.org>\n"
577@@ -18,11 +18,11 @@
578 "Content-Transfer-Encoding: 8bit\n"
579 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
580
581-#: ../app/podbird.qml:174
582+#: ../app/podbird.qml:187
583 msgid "Find New Podcasts"
584 msgstr ""
585
586-#: ../app/podbird.qml:188
587+#: ../app/podbird.qml:201
588 msgid "Settings"
589 msgstr ""
590
591@@ -63,7 +63,7 @@
592 #: ../app/settings/DownloadSetting.qml:34
593 #: ../app/settings/DownloadSetting.qml:35
594 #: ../app/settings/DownloadSetting.qml:36
595-#: ../app/settings/DownloadSetting.qml:37 ../app/ui/EpisodesPage.qml:337
596+#: ../app/settings/DownloadSetting.qml:37 ../app/ui/EpisodesPage.qml:451
597 #, qt-format
598 msgid "%1 episode"
599 msgid_plural "%1 episodes"
600@@ -120,42 +120,54 @@
601 msgid "Cancel"
602 msgstr ""
603
604-#: ../app/ui/EpisodesPage.qml:218
605+#: ../app/ui/EpisodesPage.qml:257
606+msgid "Delete local file"
607+msgstr ""
608+
609+#: ../app/ui/EpisodesPage.qml:258
610+msgid "Episode queued for download"
611+msgstr ""
612+
613+#: ../app/ui/EpisodesPage.qml:259
614+msgid "Download episode"
615+msgstr ""
616+
617+#: ../app/ui/EpisodesPage.qml:332
618 msgid "No more episodes"
619 msgstr ""
620
621-#: ../app/ui/EpisodesPage.qml:218
622+#: ../app/ui/EpisodesPage.qml:332
623 msgid "No episodes found"
624 msgstr ""
625
626-#: ../app/ui/EpisodesPage.qml:219
627+#: ../app/ui/EpisodesPage.qml:333
628 msgid "All episodes have been listened to."
629 msgstr ""
630
631-#: ../app/ui/EpisodesPage.qml:219
632+#: ../app/ui/EpisodesPage.qml:333
633 msgid "No episodes found matching the search term."
634 msgstr ""
635
636-#: ../app/ui/EpisodesPage.qml:241
637+#: ../app/ui/EpisodesPage.qml:355
638 #, no-c-format, qt-format
639 msgid "%1 hr %2 min"
640 msgstr ""
641
642-#: ../app/ui/EpisodesPage.qml:250
643+#: ../app/ui/EpisodesPage.qml:364
644 #, no-c-format, qt-format
645 msgid "%1 hr"
646 msgstr ""
647
648-#: ../app/ui/EpisodesPage.qml:258
649+#: ../app/ui/EpisodesPage.qml:372
650 #, no-c-format, qt-format
651 msgid "%1 min"
652 msgstr ""
653
654-#: ../app/ui/EpisodesPage.qml:290
655+#: ../app/ui/EpisodesPage.qml:404
656 msgid "Unheard"
657 msgstr ""
658
659-#: ../app/ui/EpisodesPage.qml:290
660+#: ../app/ui/EpisodesPage.qml:404
661 msgid "Listened"
662 msgstr ""
663
664@@ -359,6 +371,6 @@
665 msgid "Finish"
666 msgstr ""
667
668-#: /home/mike/src/build-podbird-Ubuntu_Device3_GCC_armhf_ubuntu_sdk_14_10_utopic-Default/po/Podbird.desktop.in.h:1
669+#: /home/krnekhelesh/Documents/Ubuntu-Projects/MP-Reviews/builddir/build-7-mark-episode-listened-UbuntuSDK_for_armhf_GCC_ubuntu_sdk_14_10_utopic-Default/po/Podbird.desktop.in.h:1
670 msgid "Podbird"
671 msgstr ""

Subscribers

People subscribed via source and target branches