Merge lp:~nik90/podbird/7-mark-episode-listened into lp:podbird
- 7-mark-episode-listened
- Merge into trunk
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 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Sheldon | Needs Fixing | ||
Review via email: mp+254726@code.launchpad.net |
Commit message
Description of the change
Added a action button which allows a user to mark an episode as listened/
- 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
Nekhelesh Ramananthan (nik90) wrote : | # |
Yeah I fixed it in 9-whatsnewpage if I remember correctly.
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
- 74. By Nekhelesh Ramananthan
-
merged lp:podbird
- 75. By Nekhelesh Ramananthan
-
Removed duplicate updateEpisode() functions by using a generic one
Preview Diff
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 "" |
The text for the new popups is unreadable when using the dark theme, is this fixed in another branch?