Merge lp:~vthompson/music-app/fix-1201702-implement-artists-tab into lp:music-app/trusty
- fix-1201702-implement-artists-tab
- Merge into trusty
Proposed by
Victor Thompson
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Daniel Holm | ||||
Approved revision: | 52 | ||||
Merged at revision: | 53 | ||||
Proposed branch: | lp:~vthompson/music-app/fix-1201702-implement-artists-tab | ||||
Merge into: | lp:music-app/trusty | ||||
Diff against target: |
420 lines (+200/-171) 4 files modified
LibraryListModel.qml (+15/-0) MusicArtists.qml (+167/-170) meta-database.js (+14/-0) music-app.qml (+4/-1) |
||||
To merge this branch: | bzr merge lp:~vthompson/music-app/fix-1201702-implement-artists-tab | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Holm | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Review via email: mp+175194@code.launchpad.net |
Commit message
Put together some initial functionality for the Albums tab.
Description of the change
Put together some initial functionality for the Albums tab.
To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
review:
Approve
(continuous-integration)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'LibraryListModel.qml' |
2 | --- LibraryListModel.qml 2013-07-15 21:58:50 +0000 |
3 | +++ LibraryListModel.qml 2013-07-17 04:18:23 +0000 |
4 | @@ -55,6 +55,21 @@ |
5 | } |
6 | } |
7 | |
8 | + function filterArtistTracks(artist) { |
9 | + // TODO: Currently clearing the model causes the ListView not to refresh when an artist is selected the second time. |
10 | + // However, without the call to clear(), each artist's tracks are appended to the ListView. |
11 | + // libraryModel.clear(); |
12 | + console.log("called LibraryListModel::filterArtistsTracks()") |
13 | + |
14 | + var library = Library.getArtistTracks(artist) |
15 | + |
16 | + for ( var key in library ) { |
17 | + var add = library[key]; |
18 | + console.log(JSON.stringify(add)) |
19 | + worker.sendMessage({'add': add, 'model': libraryModel}) |
20 | + } |
21 | + } |
22 | + |
23 | function filterAlbums() { |
24 | libraryModel.clear(); |
25 | console.log("called LibraryListModel::filterAlbums()") |
26 | |
27 | === modified file 'MusicArtists.qml' |
28 | --- MusicArtists.qml 2013-07-16 23:19:38 +0000 |
29 | +++ MusicArtists.qml 2013-07-17 04:18:23 +0000 |
30 | @@ -25,175 +25,172 @@ |
31 | import QtQuick.LocalStorage 2.0 |
32 | import "settings.js" as Settings |
33 | import "meta-database.js" as Library |
34 | -import "playing-list.js" as PlayingList |
35 | - |
36 | -Page { |
37 | - title: i18n.tr("Artists") |
38 | - |
39 | - tools: ToolbarItems { |
40 | - // Settings dialog |
41 | - ToolbarButton { |
42 | - objectName: "settingsaction" |
43 | - iconSource: Qt.resolvedUrl("images/settings.png") |
44 | - text: i18n.tr("Settings") |
45 | - |
46 | - onTriggered: { |
47 | - console.debug('Debug: Show settings') |
48 | - PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), mainView, |
49 | - { |
50 | - title: i18n.tr("Settings") |
51 | - } ) |
52 | - } |
53 | - } |
54 | - |
55 | - // Queue dialog |
56 | - ToolbarButton { |
57 | - objectName: "queuesaction" |
58 | - iconSource: Qt.resolvedUrl("images/folder.png") // change this icon later |
59 | - text: i18n.tr("Queue") |
60 | - |
61 | - onTriggered: { |
62 | - console.debug('Debug: Show queue') |
63 | - PopupUtils.open(Qt.resolvedUrl("QueueDialog.qml"), mainView, |
64 | - { |
65 | - title: i18n.tr("Queue") |
66 | - } ) |
67 | - } |
68 | - } |
69 | - } |
70 | - |
71 | - Component { |
72 | - id: highlight |
73 | - Rectangle { |
74 | - width: 5; height: 40 |
75 | - color: "#DD4814"; |
76 | - Behavior on y { |
77 | - SpringAnimation { |
78 | - spring: 3 |
79 | - damping: 0.2 |
80 | - } |
81 | - } |
82 | - } |
83 | - } |
84 | - |
85 | - ListView { |
86 | - id: artistlist |
87 | - width: parent.width |
88 | - anchors.top: parent.top |
89 | - anchors.bottom: parent.bottom |
90 | - anchors.bottomMargin: units.gu(8) |
91 | - highlight: highlight |
92 | - highlightFollowsCurrentItem: true |
93 | - model: artistModel.model |
94 | - delegate: artistDelegate |
95 | - |
96 | - Component { |
97 | - id: artistDelegate |
98 | - |
99 | - ListItem.Standard { |
100 | - id: track |
101 | - property string artist: model.artist |
102 | - property string album: model.album |
103 | - property string title: model.title |
104 | - property string cover: model.cover |
105 | - property string length: model.length |
106 | - property string file: model.file |
107 | - icon: cover === "" ? (file.match("\\.mp3") ? Qt.resolvedUrl("images/audio-x-mpeg.png") : Qt.resolvedUrl("images/audio-x-vorbis+ogg.png")) : "image://cover-art/"+file |
108 | - iconFrame: false |
109 | - Label { |
110 | - id: trackTitle |
111 | - wrapMode: Text.NoWrap |
112 | - maximumLineCount: 1 |
113 | - fontSize: "medium" |
114 | - anchors.left: parent.left |
115 | - anchors.leftMargin: units.gu(8) |
116 | - anchors.top: parent.top |
117 | - anchors.topMargin: 5 |
118 | - anchors.right: parent.right |
119 | - text: track.title == "" ? track.file : track.title |
120 | - } |
121 | - Label { |
122 | - id: trackArtistAlbum |
123 | - wrapMode: Text.NoWrap |
124 | - maximumLineCount: 2 |
125 | - fontSize: "small" |
126 | - anchors.left: parent.left |
127 | - anchors.leftMargin: units.gu(8) |
128 | - anchors.top: trackTitle.bottom |
129 | - anchors.right: parent.right |
130 | - text: artist == "" ? "" : artist + " - " + album |
131 | - } |
132 | - Label { |
133 | - id: trackDuration |
134 | - wrapMode: Text.NoWrap |
135 | - maximumLineCount: 2 |
136 | - fontSize: "small" |
137 | - anchors.left: parent.left |
138 | - anchors.leftMargin: units.gu(8) |
139 | - anchors.top: trackArtistAlbum.bottom |
140 | - anchors.right: parent.right |
141 | - visible: false |
142 | - text: "" |
143 | - } |
144 | - |
145 | - onFocusChanged: { |
146 | - if (focus == false) { |
147 | - selected = false |
148 | - } else { |
149 | - selected = false |
150 | - mainView.currentArtist = artist |
151 | - mainView.currentAlbum = album |
152 | - mainView.currentTracktitle = title |
153 | - mainView.currentFile = file |
154 | - mainView.currentCover = cover |
155 | - } |
156 | - } |
157 | - MouseArea { |
158 | - anchors.fill: parent |
159 | - onDoubleClicked: { |
160 | - } |
161 | - onPressAndHold: { |
162 | - trackQueue.append({"title": title, "artist": artist, "file": file}) |
163 | - } |
164 | - onClicked: { |
165 | - if (focus == false) { |
166 | - focus = true |
167 | - } |
168 | - console.log("fileName: " + file) |
169 | - if (tracklist.currentIndex == index) { |
170 | - if (player.playbackState === MediaPlayer.PlayingState) { |
171 | - player.pause() |
172 | - } else if (player.playbackState === MediaPlayer.PausedState) { |
173 | - player.play() |
174 | - } |
175 | - } else { |
176 | - player.stop() |
177 | - player.source = Qt.resolvedUrl(file) |
178 | - tracklist.currentIndex = index |
179 | - playing = PlayingList.indexOf(file) |
180 | - console.log("Playing click: "+player.source) |
181 | - console.log("Index: " + tracklist.currentIndex) |
182 | - player.play() |
183 | - } |
184 | - console.log("Source: " + player.source.toString()) |
185 | - console.log("Length: " + length.toString()) |
186 | - } |
187 | - } |
188 | - Component.onCompleted: { |
189 | - if (PlayingList.size() === 0) { |
190 | - player.source = file |
191 | - } |
192 | - |
193 | - if (!PlayingList.contains(file)) { |
194 | - console.log("Adding file:" + file) |
195 | - PlayingList.addItem(file, itemnum) |
196 | - console.log(itemnum) |
197 | - } |
198 | - console.log("Title:" + title + " Artist: " + artist) |
199 | - itemnum++ |
200 | - } |
201 | - } |
202 | - } |
203 | - } |
204 | + |
205 | +PageStack { |
206 | + id: pageStack |
207 | + anchors.fill: parent |
208 | + |
209 | + |
210 | + Page { |
211 | + id: mainpage |
212 | + title: i18n.tr("Artists") |
213 | + Component.onCompleted: { |
214 | + pageStack.push(mainpage) |
215 | + } |
216 | + |
217 | + tools: ToolbarItems { |
218 | + // Settings dialog |
219 | + ToolbarButton { |
220 | + objectName: "settingsaction" |
221 | + iconSource: Qt.resolvedUrl("images/settings.png") |
222 | + text: i18n.tr("Settings") |
223 | + |
224 | + onTriggered: { |
225 | + console.debug('Debug: Show settings') |
226 | + PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), mainView, |
227 | + { |
228 | + title: i18n.tr("Settings") |
229 | + } ) |
230 | + } |
231 | + } |
232 | + |
233 | + // Queue dialog |
234 | + ToolbarButton { |
235 | + objectName: "queuesaction" |
236 | + iconSource: Qt.resolvedUrl("images/folder.png") // change this icon later |
237 | + text: i18n.tr("Queue") |
238 | + |
239 | + onTriggered: { |
240 | + console.debug('Debug: Show queue') |
241 | + PopupUtils.open(Qt.resolvedUrl("QueueDialog.qml"), mainView, |
242 | + { |
243 | + title: i18n.tr("Queue") |
244 | + } ) |
245 | + } |
246 | + } |
247 | + } |
248 | + |
249 | + ListView { |
250 | + id: artistlist |
251 | + width: parent.width |
252 | + anchors.top: parent.top |
253 | + anchors.bottom: parent.bottom |
254 | + anchors.bottomMargin: units.gu(8) |
255 | + model: artistModel.model |
256 | + delegate: artistDelegate |
257 | + |
258 | + Component { |
259 | + id: artistDelegate |
260 | + |
261 | + ListItem.Standard { |
262 | + id: track |
263 | + property string artist: model.artist |
264 | + property string cover: model.cover |
265 | + icon: cover === "" ? (file.match("\\.mp3") ? Qt.resolvedUrl("images/audio-x-mpeg.png") : Qt.resolvedUrl("images/audio-x-vorbis+ogg.png")) : "image://cover-art/"+file |
266 | + iconFrame: false |
267 | + progression: true |
268 | + Label { |
269 | + id: trackArtistAlbum |
270 | + wrapMode: Text.NoWrap |
271 | + maximumLineCount: 2 |
272 | + fontSize: "large" |
273 | + anchors.left: parent.left |
274 | + anchors.leftMargin: units.gu(8) |
275 | + anchors.verticalCenter: parent.verticalCenter |
276 | + anchors.right: parent.right |
277 | + text: artist |
278 | + } |
279 | + |
280 | + onFocusChanged: { |
281 | + } |
282 | + MouseArea { |
283 | + anchors.fill: parent |
284 | + onDoubleClicked: { |
285 | + } |
286 | + onPressAndHold: { |
287 | + } |
288 | + onClicked: { |
289 | + artistTracksModel.filterArtistTracks(artist) |
290 | + pageStack.push(artistpage) |
291 | + } |
292 | + } |
293 | + Component.onCompleted: { |
294 | + } |
295 | + } |
296 | + } |
297 | + } |
298 | + } |
299 | + |
300 | + Page { |
301 | + id: artistpage |
302 | + title: i18n.tr("Tracks") |
303 | + |
304 | + ListView { |
305 | + id: artisttrackslist |
306 | + width: parent.width |
307 | + anchors.top: parent.top |
308 | + anchors.bottom: parent.bottom |
309 | + anchors.bottomMargin: units.gu(8) |
310 | + model: artistTracksModel.model |
311 | + delegate: artistTracksDelegate |
312 | + |
313 | + Component { |
314 | + id: artistTracksDelegate |
315 | + |
316 | + ListItem.Standard { |
317 | + id: track |
318 | + property string artist: model.artist |
319 | + property string album: model.album |
320 | + property string title: model.title |
321 | + property string cover: model.cover |
322 | + property string length: model.length |
323 | + property string file: model.file |
324 | + icon: cover === "" ? (file.match("\\.mp3") ? Qt.resolvedUrl("images/audio-x-mpeg.png") : Qt.resolvedUrl("images/audio-x-vorbis+ogg.png")) : "image://cover-art/"+file |
325 | + iconFrame: false |
326 | + progression: false |
327 | + Label { |
328 | + id: trackTitle |
329 | + wrapMode: Text.NoWrap |
330 | + maximumLineCount: 1 |
331 | + fontSize: "medium" |
332 | + anchors.left: parent.left |
333 | + anchors.leftMargin: units.gu(8) |
334 | + anchors.top: parent.top |
335 | + anchors.topMargin: 5 |
336 | + anchors.right: parent.right |
337 | + text: track.title == "" ? track.file : track.title |
338 | + } |
339 | + Label { |
340 | + id: trackArtistAlbum |
341 | + wrapMode: Text.NoWrap |
342 | + maximumLineCount: 2 |
343 | + fontSize: "small" |
344 | + anchors.left: parent.left |
345 | + anchors.leftMargin: units.gu(8) |
346 | + anchors.top: trackTitle.bottom |
347 | + anchors.right: parent.right |
348 | + text: artist == "" ? "" : artist + " - " + album |
349 | + } |
350 | + |
351 | + onFocusChanged: { |
352 | + } |
353 | + MouseArea { |
354 | + anchors.fill: parent |
355 | + onDoubleClicked: { |
356 | + } |
357 | + onPressAndHold: { |
358 | + } |
359 | + onClicked: { |
360 | + } |
361 | + } |
362 | + Component.onCompleted: { |
363 | + } |
364 | + } |
365 | + } |
366 | + } |
367 | + } |
368 | + |
369 | + |
370 | + |
371 | } |
372 | |
373 | |
374 | === modified file 'meta-database.js' |
375 | --- meta-database.js 2013-07-15 22:05:23 +0000 |
376 | +++ meta-database.js 2013-07-17 04:18:23 +0000 |
377 | @@ -150,6 +150,20 @@ |
378 | return res; |
379 | } |
380 | |
381 | +function getArtistTracks(artist) { |
382 | + var res = []; |
383 | + var db = getDatabase(); |
384 | + db.transaction( function(tx) { |
385 | + var rs = tx.executeSql("SELECT * FROM metadata WHERE artist=? ORDER BY artist ASC, album ASC, file ASC", [artist]); |
386 | + for(var i = 0; i < rs.rows.length; i++) { |
387 | + var dbItem = rs.rows.item(i); |
388 | + console.log("Artist:"+ dbItem.artist + ", Album:"+dbItem.album + ", Title:"+dbItem.title + ", File:"+dbItem.file + ", Art:"+dbItem.cover); |
389 | + res.push({artist:dbItem.artist, album:dbItem.album, title:dbItem.title, file:dbItem.file, cover:dbItem.cover, length:dbItem.length}); |
390 | + } |
391 | + }); |
392 | + return res; |
393 | +} |
394 | + |
395 | function getAlbums() { |
396 | var res = []; |
397 | var db = getDatabase(); |
398 | |
399 | === modified file 'music-app.qml' |
400 | --- music-app.qml 2013-07-16 01:09:42 +0000 |
401 | +++ music-app.qml 2013-07-17 04:18:23 +0000 |
402 | @@ -272,6 +272,9 @@ |
403 | LibraryListModel { |
404 | id: artistModel |
405 | } |
406 | + LibraryListModel { |
407 | + id: artistTracksModel |
408 | + } |
409 | |
410 | LibraryListModel { |
411 | id: albumModel |
412 | @@ -362,7 +365,7 @@ |
413 | Library.writeDb() |
414 | libraryModel.populate() |
415 | albumModel.filterAlbums() |
416 | - artistModel.populate() |
417 | + artistModel.filterArtists() |
418 | PlayingList.clear() |
419 | itemnum = 0 |
420 | timer.stop() |
PASSED: Continuous integration, rev:52 91.189. 93.70:8080/ job/music- app-ci/ 17/ 91.189. 93.70:8080/ job/music- app-precise- amd64-ci/ 11 91.189. 93.70:8080/ job/music- app-quantal- amd64-ci/ 17 91.189. 93.70:8080/ job/music- app-raring- amd64-ci/ 17 91.189. 93.70:8080/ job/music- app-saucy- amd64-ci/ 11
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/music- app-ci/ 17/rebuild
http://