Merge lp:~ahayzen/music-app/trackqueue-speedup into lp:music-app/trusty
- trackqueue-speedup
- Merge into trusty
Status: | Work in progress |
---|---|
Proposed branch: | lp:~ahayzen/music-app/trackqueue-speedup |
Merge into: | lp:music-app/trusty |
Diff against target: |
557 lines (+159/-62) 7 files modified
LibraryListModel.qml (+16/-2) MusicNowPlaying.qml (+37/-12) MusicSearch.qml (+2/-2) MusicToolbar.qml (+15/-15) Player.qml (+14/-14) common/ListItemActions/AddToQueue.qml (+1/-1) music-app.qml (+74/-16) |
To merge this branch: | bzr merge lp:~ahayzen/music-app/trackqueue-speedup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Needs Fixing | |
Music App Developers | Pending | ||
Review via email: mp+232021@code.launchpad.net |
Commit message
* Use worker loaded trackQueueUI infront of trackQueue
Description of the change
* Use worker loaded trackQueueUI infront of trackQueue
BEFORE
* Go to a listview with many items (eg Songs tab) scroll to the bottom
* Select a track near the bottom
* Notice the UI freezes and there is noticeable lag until audio starts playing
AFTER
* Go to a listview with many items (eg Songs tab) scroll to the bottom
* Select a track near the bottom
* Notice the audio starts much faster and the UI is loaded as the data appears from the worker script, making it 'feel' more responsive
Note I had 300+ tracks in the Songs tab and this branch had a very positive affect on the performance, but it is also noticeable when selecting the last track in an album of 10+ tracks.
The performance increase is done by having two models for the trackQueue, one to hold the data that is always 'insync' (required for calculations of eg nextSong() etc) and another that is for the UI that loads items via the worker script as they appear into the first.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
- 566. By Andrew Hayzen
-
* Merge of trunk
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:566
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
I'm not sure this is working the way you intended it to. It doesn't really seem to speed things up consistently. I tried it once and it seemed to maybe be half a second faster, but it delayed jumping to the now playing item. Then I tried it again and recorded it. The N4 is running this branch and the N7 is running trunk. Note that the N4 is actually started first by a bit, and note how large the delay is until the now playing item is shown.
Victor Thompson (vthompson) wrote : | # |
Also note that this is with 841 tracks on each device.
Andrew Hayzen (ahayzen) wrote : | # |
I would expect the UI to be slower in certain situations, but I would expect the time until the audio starts to be faster. I'll see if I can tweak the UI loading to speed it up.
Unmerged revisions
- 566. By Andrew Hayzen
-
* Merge of trunk
- 565. By Andrew Hayzen
-
* Use worker loaded trackQueueUI infront of trackQueue
- 564. By Andrew Hayzen
-
* Disable trackQueue from now playing page
Preview Diff
1 | === modified file 'LibraryListModel.qml' | |||
2 | --- LibraryListModel.qml 2014-08-20 17:35:52 +0000 | |||
3 | +++ LibraryListModel.qml 2014-08-24 23:27:56 +0000 | |||
4 | @@ -34,6 +34,10 @@ | |||
5 | 34 | property bool canLoad: true | 34 | property bool canLoad: true |
6 | 35 | property bool preLoadComplete: false | 35 | property bool preLoadComplete: false |
7 | 36 | 36 | ||
8 | 37 | property alias onlyAppend: worker.onlyAppend | ||
9 | 38 | property alias list: worker.list | ||
10 | 39 | property alias workerCompleted: worker.completed | ||
11 | 40 | |||
12 | 37 | onCanLoadChanged: { | 41 | onCanLoadChanged: { |
13 | 38 | /* If canLoad has been set back to true then check if there are any | 42 | /* If canLoad has been set back to true then check if there are any |
14 | 39 | remaining items to load in the model */ | 43 | remaining items to load in the model */ |
15 | @@ -58,9 +62,19 @@ | |||
16 | 58 | property int i: 0 | 62 | property int i: 0 |
17 | 59 | property var list: null | 63 | property var list: null |
18 | 60 | 64 | ||
19 | 65 | property bool onlyAppend: false | ||
20 | 66 | |||
21 | 61 | onListChanged: { | 67 | onListChanged: { |
24 | 62 | reset(); | 68 | if (onlyAppend) { |
25 | 63 | clear(); | 69 | if (canLoad) { |
26 | 70 | process() | ||
27 | 71 | } | ||
28 | 72 | |||
29 | 73 | onlyAppend = false | ||
30 | 74 | } else { | ||
31 | 75 | reset(); | ||
32 | 76 | clear(); | ||
33 | 77 | } | ||
34 | 64 | } | 78 | } |
35 | 65 | 79 | ||
36 | 66 | onMessage: { | 80 | onMessage: { |
37 | 67 | 81 | ||
38 | === modified file 'MusicNowPlaying.qml' | |||
39 | --- MusicNowPlaying.qml 2014-08-20 17:35:52 +0000 | |||
40 | +++ MusicNowPlaying.qml 2014-08-24 23:27:56 +0000 | |||
41 | @@ -55,8 +55,6 @@ | |||
42 | 55 | return; | 55 | return; |
43 | 56 | } | 56 | } |
44 | 57 | 57 | ||
45 | 58 | queuelist.currentIndex = player.currentIndex; | ||
46 | 59 | |||
47 | 60 | customdebug("MusicQueue update currentIndex: " + player.source); | 58 | customdebug("MusicQueue update currentIndex: " + player.source); |
48 | 61 | 59 | ||
49 | 62 | // Always jump to current track | 60 | // Always jump to current track |
50 | @@ -70,14 +68,24 @@ | |||
51 | 70 | // If the toolbar is shown, the page is now playing and snaptrack is enabled | 68 | // If the toolbar is shown, the page is now playing and snaptrack is enabled |
52 | 71 | if (shown && currentPage === nowPlaying && Settings.getSetting("snaptrack") === "1") | 69 | if (shown && currentPage === nowPlaying && Settings.getSetting("snaptrack") === "1") |
53 | 72 | { | 70 | { |
56 | 73 | // Then position the view at the current index | 71 | |
57 | 74 | queuelist.positionViewAtIndex(queuelist.currentIndex, ListView.Beginning); | 72 | // Only jump if the item has been created otherwise jump on load |
58 | 73 | if (queuelist.count >= player.currentIndex && trackQueueUI.workerCompleted) { | ||
59 | 74 | // Then position the view at the current index | ||
60 | 75 | queuelist.positionViewAtIndex(player.currentIndex, ListView.Beginning); | ||
61 | 76 | } else { | ||
62 | 77 | queuelist.jumpOnLoad = player.currentIndex | ||
63 | 78 | } | ||
64 | 75 | } | 79 | } |
65 | 76 | } | 80 | } |
66 | 77 | 81 | ||
67 | 78 | function positionAt(index) { | 82 | function positionAt(index) { |
70 | 79 | queuelist.positionViewAtIndex(index, ListView.Beginning); | 83 | if (queuelist.count >= index && trackQueueUI.workerCompleted) { |
71 | 80 | queuelist.contentY -= header.height; | 84 | queuelist.positionViewAtIndex(index, ListView.Beginning); |
72 | 85 | queuelist.contentY -= header.height; | ||
73 | 86 | } else { | ||
74 | 87 | queuelist.jumpOnLoad = index | ||
75 | 88 | } | ||
76 | 81 | } | 89 | } |
77 | 82 | 90 | ||
78 | 83 | ListView { | 91 | ListView { |
79 | @@ -86,7 +94,7 @@ | |||
80 | 86 | anchors.fill: parent | 94 | anchors.fill: parent |
81 | 87 | anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight | 95 | anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight |
82 | 88 | delegate: queueDelegate | 96 | delegate: queueDelegate |
84 | 89 | model: trackQueue.model | 97 | model: trackQueueUI.model |
85 | 90 | highlightFollowsCurrentItem: false | 98 | highlightFollowsCurrentItem: false |
86 | 91 | state: "normal" | 99 | state: "normal" |
87 | 92 | states: [ | 100 | states: [ |
88 | @@ -113,21 +121,39 @@ | |||
89 | 113 | property int currentHeight: units.gu(40) | 121 | property int currentHeight: units.gu(40) |
90 | 114 | property int transitionDuration: 250 // transition length of animations | 122 | property int transitionDuration: 250 // transition length of animations |
91 | 115 | 123 | ||
92 | 124 | property int jumpOnLoad: -1 | ||
93 | 125 | |||
94 | 116 | onCountChanged: { | 126 | onCountChanged: { |
96 | 117 | customdebug("Queue: Now has: " + queuelist.count + " tracks") | 127 | customdebug("Queue: Now has: " + queuelist.count + " tracks" + " " + jumpOnLoad) |
97 | 128 | |||
98 | 129 | if (jumpOnLoad < count && jumpOnLoad !== -1) { // < due to count being +1 to index | ||
99 | 130 | positionAtAfterDelay.start() | ||
100 | 131 | } | ||
101 | 118 | } | 132 | } |
102 | 119 | 133 | ||
103 | 120 | onMovementStarted: { | 134 | onMovementStarted: { |
104 | 121 | musicToolbar.hideToolbar(); | 135 | musicToolbar.hideToolbar(); |
105 | 122 | } | 136 | } |
106 | 123 | 137 | ||
107 | 138 | Timer { | ||
108 | 139 | id: positionAtAfterDelay | ||
109 | 140 | interval: 250 | ||
110 | 141 | repeat: false | ||
111 | 142 | onTriggered: { | ||
112 | 143 | // Then position the view at the current index | ||
113 | 144 | queuelist.positionViewAtIndex(queuelist.jumpOnLoad, ListView.Beginning); | ||
114 | 145 | |||
115 | 146 | queuelist.jumpOnLoad = -1 | ||
116 | 147 | } | ||
117 | 148 | } | ||
118 | 149 | |||
119 | 124 | Component { | 150 | Component { |
120 | 125 | id: queueDelegate | 151 | id: queueDelegate |
121 | 126 | ListItemWithActions { | 152 | ListItemWithActions { |
122 | 127 | id: queueListItem | 153 | id: queueListItem |
123 | 128 | color: "transparent" | 154 | color: "transparent" |
124 | 129 | height: queuelist.normalHeight | 155 | height: queuelist.normalHeight |
126 | 130 | state: queuelist.currentIndex == index && !reordering ? "current" : "" | 156 | state: player.currentIndex == index && !reordering ? "current" : "" |
127 | 131 | 157 | ||
128 | 132 | leftSideAction: Remove { | 158 | leftSideAction: Remove { |
129 | 133 | onTriggered: { | 159 | onTriggered: { |
130 | @@ -143,7 +169,7 @@ | |||
131 | 143 | player.currentIndex -= 1; | 169 | player.currentIndex -= 1; |
132 | 144 | } | 170 | } |
133 | 145 | 171 | ||
135 | 146 | queuelist.model.remove(index); | 172 | trackQueueUI.remove(index); |
136 | 147 | } | 173 | } |
137 | 148 | } | 174 | } |
138 | 149 | reorderable: true | 175 | reorderable: true |
139 | @@ -161,8 +187,7 @@ | |||
140 | 161 | onReorder: { | 187 | onReorder: { |
141 | 162 | console.debug("Move: ", from, to); | 188 | console.debug("Move: ", from, to); |
142 | 163 | 189 | ||
145 | 164 | queuelist.model.move(from, to, 1); | 190 | trackQueueUI.move(from, to, 1); |
144 | 165 | |||
146 | 166 | 191 | ||
147 | 167 | // Maintain currentIndex with current song | 192 | // Maintain currentIndex with current song |
148 | 168 | if (from === player.currentIndex) { | 193 | if (from === player.currentIndex) { |
149 | 169 | 194 | ||
150 | === modified file 'MusicSearch.qml' | |||
151 | --- MusicSearch.qml 2014-08-21 19:32:12 +0000 | |||
152 | +++ MusicSearch.qml 2014-08-24 23:27:56 +0000 | |||
153 | @@ -173,8 +173,8 @@ | |||
154 | 173 | onItemClicked: { | 173 | onItemClicked: { |
155 | 174 | console.debug("Debug: "+title+" added to queue") | 174 | console.debug("Debug: "+title+" added to queue") |
156 | 175 | // now play this track, but keep current queue | 175 | // now play this track, but keep current queue |
159 | 176 | trackQueue.append(model) | 176 | trackQueue.appendItem(makeDict(model)) |
160 | 177 | trackQueueClick(trackQueue.model.count - 1); | 177 | trackQueueClick(trackQueue.count - 1); |
161 | 178 | onDoneClicked: PopupUtils.close(searchTrack) | 178 | onDoneClicked: PopupUtils.close(searchTrack) |
162 | 179 | } | 179 | } |
163 | 180 | 180 | ||
164 | 181 | 181 | ||
165 | === modified file 'MusicToolbar.qml' | |||
166 | --- MusicToolbar.qml 2014-08-21 19:32:12 +0000 | |||
167 | +++ MusicToolbar.qml 2014-08-24 23:27:56 +0000 | |||
168 | @@ -223,7 +223,7 @@ | |||
169 | 223 | 223 | ||
170 | 224 | /* Clicking in the area shows the queue */ | 224 | /* Clicking in the area shows the queue */ |
171 | 225 | function trigger() { | 225 | function trigger() { |
173 | 226 | if (trackQueue.model.count !== 0 && currentPage !== nowPlaying) { | 226 | if (trackQueue.count !== 0 && currentPage !== nowPlaying) { |
174 | 227 | tabs.pushNowPlaying(); | 227 | tabs.pushNowPlaying(); |
175 | 228 | } | 228 | } |
176 | 229 | else if (currentPage === nowPlaying) { | 229 | else if (currentPage === nowPlaying) { |
177 | @@ -244,7 +244,7 @@ | |||
178 | 244 | elide: Text.ElideRight | 244 | elide: Text.ElideRight |
179 | 245 | fontSize: "medium" | 245 | fontSize: "medium" |
180 | 246 | objectName: "playercontroltitle" | 246 | objectName: "playercontroltitle" |
182 | 247 | text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle | 247 | text: trackQueue.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle |
183 | 248 | } | 248 | } |
184 | 249 | 249 | ||
185 | 250 | /* Artist of track */ | 250 | /* Artist of track */ |
186 | @@ -259,7 +259,7 @@ | |||
187 | 259 | color: styleMusic.playerControls.labelColor | 259 | color: styleMusic.playerControls.labelColor |
188 | 260 | elide: Text.ElideRight | 260 | elide: Text.ElideRight |
189 | 261 | fontSize: "small" | 261 | fontSize: "small" |
191 | 262 | text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist | 262 | text: trackQueue.count === 0 ? "" : player.currentMetaArtist |
192 | 263 | } | 263 | } |
193 | 264 | 264 | ||
194 | 265 | /* Album of track */ | 265 | /* Album of track */ |
195 | @@ -274,7 +274,7 @@ | |||
196 | 274 | color: styleMusic.playerControls.labelColor | 274 | color: styleMusic.playerControls.labelColor |
197 | 275 | elide: Text.ElideRight | 275 | elide: Text.ElideRight |
198 | 276 | fontSize: "small" | 276 | fontSize: "small" |
200 | 277 | text: trackQueue.model.count === 0 ? "" : player.currentMetaAlbum | 277 | text: trackQueue.count === 0 ? "" : player.currentMetaAlbum |
201 | 278 | } | 278 | } |
202 | 279 | } | 279 | } |
203 | 280 | 280 | ||
204 | @@ -318,11 +318,11 @@ | |||
205 | 318 | anchors.verticalCenter: parent.verticalCenter | 318 | anchors.verticalCenter: parent.verticalCenter |
206 | 319 | height: units.gu(6) | 319 | height: units.gu(6) |
207 | 320 | objectName: "previousshape" | 320 | objectName: "previousshape" |
209 | 321 | opacity: trackQueue.model.count === 0 ? .4 : 1 | 321 | opacity: trackQueue.count === 0 ? .4 : 1 |
210 | 322 | width: height | 322 | width: height |
211 | 323 | 323 | ||
212 | 324 | function trigger() { | 324 | function trigger() { |
214 | 325 | if (trackQueue.model.count === 0) { | 325 | if (trackQueue.count === 0) { |
215 | 326 | return; | 326 | return; |
216 | 327 | } | 327 | } |
217 | 328 | 328 | ||
218 | @@ -409,7 +409,7 @@ | |||
219 | 409 | return; | 409 | return; |
220 | 410 | } | 410 | } |
221 | 411 | 411 | ||
223 | 412 | if (trackQueue.model.count === 0) { | 412 | if (trackQueue.count === 0) { |
224 | 413 | playRandomSong(); | 413 | playRandomSong(); |
225 | 414 | } | 414 | } |
226 | 415 | else { | 415 | else { |
227 | @@ -442,11 +442,11 @@ | |||
228 | 442 | anchors.verticalCenter: parent.verticalCenter | 442 | anchors.verticalCenter: parent.verticalCenter |
229 | 443 | height: units.gu(6) | 443 | height: units.gu(6) |
230 | 444 | objectName: "forwardshape" | 444 | objectName: "forwardshape" |
232 | 445 | opacity: trackQueue.model.count === 0 ? .4 : 1 | 445 | opacity: trackQueue.count === 0 ? .4 : 1 |
233 | 446 | width: height | 446 | width: height |
234 | 447 | 447 | ||
235 | 448 | function trigger() { | 448 | function trigger() { |
237 | 449 | if (trackQueue.model.count === 0 || emptyPage.noMusic) { | 449 | if (trackQueue.count === 0 || emptyPage.noMusic) { |
238 | 450 | return; | 450 | return; |
239 | 451 | } | 451 | } |
240 | 452 | 452 | ||
241 | @@ -569,7 +569,7 @@ | |||
242 | 569 | anchors.verticalCenter: parent.verticalCenter | 569 | anchors.verticalCenter: parent.verticalCenter |
243 | 570 | color: "transparent" | 570 | color: "transparent" |
244 | 571 | height: units.gu(1); | 571 | height: units.gu(1); |
246 | 572 | state: trackQueue.model.count === 0 ? "disabled" : "enabled" | 572 | state: trackQueue.count === 0 ? "disabled" : "enabled" |
247 | 573 | 573 | ||
248 | 574 | states: [ | 574 | states: [ |
249 | 575 | State { | 575 | State { |
250 | @@ -716,7 +716,7 @@ | |||
251 | 716 | id: musicToolbarPlayerControls | 716 | id: musicToolbarPlayerControls |
252 | 717 | anchors.fill: parent | 717 | anchors.fill: parent |
253 | 718 | color: styleMusic.playerControls.backgroundColor | 718 | color: styleMusic.playerControls.backgroundColor |
255 | 719 | state: trackQueue.model.count === 0 ? "disabled" : "enabled" | 719 | state: trackQueue.count === 0 ? "disabled" : "enabled" |
256 | 720 | states: [ | 720 | states: [ |
257 | 721 | State { | 721 | State { |
258 | 722 | name: "disabled" | 722 | name: "disabled" |
259 | @@ -746,7 +746,7 @@ | |||
260 | 746 | id: disabledPlayerControlsGroup | 746 | id: disabledPlayerControlsGroup |
261 | 747 | anchors.fill: parent | 747 | anchors.fill: parent |
262 | 748 | color: "transparent" | 748 | color: "transparent" |
264 | 749 | visible: trackQueue.model.count === 0 | 749 | visible: trackQueue.count === 0 |
265 | 750 | 750 | ||
266 | 751 | Label { | 751 | Label { |
267 | 752 | id: noSongsInQueueLabel | 752 | id: noSongsInQueueLabel |
268 | @@ -779,7 +779,7 @@ | |||
269 | 779 | return; | 779 | return; |
270 | 780 | } | 780 | } |
271 | 781 | 781 | ||
273 | 782 | if (trackQueue.model.count === 0) { | 782 | if (trackQueue.count === 0) { |
274 | 783 | playRandomSong(); | 783 | playRandomSong(); |
275 | 784 | } | 784 | } |
276 | 785 | else { | 785 | else { |
277 | @@ -861,7 +861,7 @@ | |||
278 | 861 | id: enabledPlayerControlsGroup | 861 | id: enabledPlayerControlsGroup |
279 | 862 | anchors.fill: parent | 862 | anchors.fill: parent |
280 | 863 | color: "transparent" | 863 | color: "transparent" |
282 | 864 | visible: trackQueue.model.count !== 0 | 864 | visible: trackQueue.count !== 0 |
283 | 865 | 865 | ||
284 | 866 | /* Settings button */ | 866 | /* Settings button */ |
285 | 867 | // TODO: Enable settings when it is practical | 867 | // TODO: Enable settings when it is practical |
286 | @@ -911,7 +911,7 @@ | |||
287 | 911 | return; | 911 | return; |
288 | 912 | } | 912 | } |
289 | 913 | 913 | ||
291 | 914 | if (trackQueue.model.count === 0) { | 914 | if (trackQueue.count === 0) { |
292 | 915 | playRandomSong(); | 915 | playRandomSong(); |
293 | 916 | } | 916 | } |
294 | 917 | else { | 917 | else { |
295 | 918 | 918 | ||
296 | === modified file 'Player.qml' | |||
297 | --- Player.qml 2014-08-22 00:26:30 +0000 | |||
298 | +++ Player.qml 2014-08-24 23:27:56 +0000 | |||
299 | @@ -59,12 +59,12 @@ | |||
300 | 59 | } | 59 | } |
301 | 60 | 60 | ||
302 | 61 | Connections { | 61 | Connections { |
304 | 62 | target: trackQueue.model | 62 | target: trackQueue |
305 | 63 | onCountChanged: { | 63 | onCountChanged: { |
307 | 64 | if (trackQueue.model.count === 1) { | 64 | if (trackQueue.count === 1) { |
308 | 65 | player.currentIndex = 0; | 65 | player.currentIndex = 0; |
311 | 66 | player.source = Qt.resolvedUrl(trackQueue.model.get(0).filename) | 66 | player.source = Qt.resolvedUrl(trackQueue.get(0).filename) |
312 | 67 | } else if (trackQueue.model.count === 0) { | 67 | } else if (trackQueue.count === 0) { |
313 | 68 | player.currentMetaFile = "" | 68 | player.currentMetaFile = "" |
314 | 69 | player.source = "" | 69 | player.source = "" |
315 | 70 | } | 70 | } |
316 | @@ -79,7 +79,7 @@ | |||
317 | 79 | return; | 79 | return; |
318 | 80 | } | 80 | } |
319 | 81 | 81 | ||
321 | 82 | if (trackQueue.model.count == 0) | 82 | if (trackQueue.count == 0) |
322 | 83 | { | 83 | { |
323 | 84 | customdebug("No tracks in queue."); | 84 | customdebug("No tracks in queue."); |
324 | 85 | return; | 85 | return; |
325 | @@ -91,26 +91,26 @@ | |||
326 | 91 | var newIndex; | 91 | var newIndex; |
327 | 92 | 92 | ||
328 | 93 | console.log("currentIndex: " + currentIndex) | 93 | console.log("currentIndex: " + currentIndex) |
330 | 94 | console.log("trackQueue.count: " + trackQueue.model.count) | 94 | console.log("trackQueue.count: " + trackQueue.count) |
331 | 95 | 95 | ||
332 | 96 | // Do not shuffle if repeat is off and there is only one track in the queue | 96 | // Do not shuffle if repeat is off and there is only one track in the queue |
334 | 97 | if (shuffle && !(trackQueue.model.count === 1 && !repeat)) { | 97 | if (shuffle && !(trackQueue.count === 1 && !repeat)) { |
335 | 98 | var now = new Date(); | 98 | var now = new Date(); |
336 | 99 | var seed = now.getSeconds(); | 99 | var seed = now.getSeconds(); |
337 | 100 | 100 | ||
338 | 101 | // trackQueue must be above 1 otherwise an infinite loop will occur | 101 | // trackQueue must be above 1 otherwise an infinite loop will occur |
339 | 102 | do { | 102 | do { |
341 | 103 | newIndex = (Math.floor((trackQueue.model.count) | 103 | newIndex = (Math.floor((trackQueue.count) |
342 | 104 | * Math.random(seed))); | 104 | * Math.random(seed))); |
344 | 105 | } while (newIndex === currentIndex && trackQueue.model.count > 1) | 105 | } while (newIndex === currentIndex && trackQueue.count > 1) |
345 | 106 | } else { | 106 | } else { |
347 | 107 | if ((currentIndex < trackQueue.model.count - 1 && direction === 1 ) | 107 | if ((currentIndex < trackQueue.count - 1 && direction === 1 ) |
348 | 108 | || (currentIndex > 0 && direction === -1)) { | 108 | || (currentIndex > 0 && direction === -1)) { |
349 | 109 | newIndex = currentIndex + direction | 109 | newIndex = currentIndex + direction |
350 | 110 | } else if(direction === 1 && (repeat || fromControls)) { | 110 | } else if(direction === 1 && (repeat || fromControls)) { |
351 | 111 | newIndex = 0 | 111 | newIndex = 0 |
352 | 112 | } else if(direction === -1 && (repeat || fromControls)) { | 112 | } else if(direction === -1 && (repeat || fromControls)) { |
354 | 113 | newIndex = trackQueue.model.count - 1 | 113 | newIndex = trackQueue.count - 1 |
355 | 114 | } | 114 | } |
356 | 115 | else | 115 | else |
357 | 116 | { | 116 | { |
358 | @@ -120,11 +120,11 @@ | |||
359 | 120 | } | 120 | } |
360 | 121 | 121 | ||
361 | 122 | if (startPlaying) { // only start the track if told | 122 | if (startPlaying) { // only start the track if told |
363 | 123 | playSong(trackQueue.model.get(newIndex).filename, newIndex) | 123 | playSong(trackQueue.get(newIndex).filename, newIndex) |
364 | 124 | } | 124 | } |
365 | 125 | else { | 125 | else { |
366 | 126 | currentIndex = newIndex | 126 | currentIndex = newIndex |
368 | 127 | source = Qt.resolvedUrl(trackQueue.model.get(newIndex).filename) | 127 | source = Qt.resolvedUrl(trackQueue.get(newIndex).filename) |
369 | 128 | } | 128 | } |
370 | 129 | } | 129 | } |
371 | 130 | 130 | ||
372 | @@ -184,7 +184,7 @@ | |||
373 | 184 | player.stop() | 184 | player.stop() |
374 | 185 | } | 185 | } |
375 | 186 | else { | 186 | else { |
377 | 187 | var obj = trackQueue.model.get(player.currentIndex); | 187 | var obj = trackQueue.get(player.currentIndex); |
378 | 188 | currentMetaAlbum = obj.album; | 188 | currentMetaAlbum = obj.album; |
379 | 189 | currentMetaArtist = obj.author; | 189 | currentMetaArtist = obj.author; |
380 | 190 | currentMetaFile = obj.filename; | 190 | currentMetaFile = obj.filename; |
381 | 191 | 191 | ||
382 | === modified file 'common/ListItemActions/AddToQueue.qml' | |||
383 | --- common/ListItemActions/AddToQueue.qml 2014-08-20 17:35:52 +0000 | |||
384 | +++ common/ListItemActions/AddToQueue.qml 2014-08-24 23:27:56 +0000 | |||
385 | @@ -26,6 +26,6 @@ | |||
386 | 26 | 26 | ||
387 | 27 | onTriggered: { | 27 | onTriggered: { |
388 | 28 | console.debug("Debug: Add track to queue: " + model) | 28 | console.debug("Debug: Add track to queue: " + model) |
390 | 29 | trackQueue.append(model) | 29 | trackQueue.appendItem(makeDict(model)) |
391 | 30 | } | 30 | } |
392 | 31 | } | 31 | } |
393 | 32 | 32 | ||
394 | === modified file 'music-app.qml' | |||
395 | --- music-app.qml 2014-08-22 00:26:30 +0000 | |||
396 | +++ music-app.qml 2014-08-24 23:27:56 +0000 | |||
397 | @@ -236,15 +236,15 @@ | |||
398 | 236 | 236 | ||
399 | 237 | if (play) { | 237 | if (play) { |
400 | 238 | // clear play queue | 238 | // clear play queue |
402 | 239 | trackQueue.model.clear() | 239 | trackQueue.clearItems() |
403 | 240 | } | 240 | } |
404 | 241 | 241 | ||
405 | 242 | // enqueue | 242 | // enqueue |
407 | 243 | trackQueue.append(makeDict(track)); | 243 | trackQueue.appendItem(makeDict(track)); |
408 | 244 | 244 | ||
409 | 245 | // play first URI | 245 | // play first URI |
410 | 246 | if (play) { | 246 | if (play) { |
412 | 247 | trackQueueClick(trackQueue.model.count - 1); | 247 | trackQueueClick(trackQueue.count - 1); |
413 | 248 | } | 248 | } |
414 | 249 | } | 249 | } |
415 | 250 | 250 | ||
416 | @@ -394,7 +394,7 @@ | |||
417 | 394 | else { | 394 | else { |
418 | 395 | stopTimer(); | 395 | stopTimer(); |
419 | 396 | 396 | ||
421 | 397 | trackQueue.model.clear(); | 397 | trackQueue.clearItems(); |
422 | 398 | 398 | ||
423 | 399 | trackQueue.append(makeDict(model)); | 399 | trackQueue.append(makeDict(model)); |
424 | 400 | trackQueueClick(0); | 400 | trackQueueClick(0); |
425 | @@ -637,9 +637,13 @@ | |||
426 | 637 | model = model.linkLibraryListModel; | 637 | model = model.linkLibraryListModel; |
427 | 638 | } | 638 | } |
428 | 639 | 639 | ||
429 | 640 | var list = [] | ||
430 | 641 | |||
431 | 640 | for (var i=0; i < model.rowCount; i++) { | 642 | for (var i=0; i < model.rowCount; i++) { |
433 | 641 | trackQueue.model.append(makeDict(model.get(i, model.RoleModelData))); | 643 | list.push(makeDict(model.get(i, model.RoleModelData))); |
434 | 642 | } | 644 | } |
435 | 645 | |||
436 | 646 | trackQueue.appendList(list) | ||
437 | 643 | } | 647 | } |
438 | 644 | 648 | ||
439 | 645 | // Converts an duration in ms to a formated string ("minutes:seconds") | 649 | // Converts an duration in ms to a formated string ("minutes:seconds") |
440 | @@ -679,14 +683,14 @@ | |||
441 | 679 | if (!clear) { | 683 | if (!clear) { |
442 | 680 | // If same track and on now playing page then toggle | 684 | // If same track and on now playing page then toggle |
443 | 681 | if (musicToolbar.currentPage === nowPlaying && | 685 | if (musicToolbar.currentPage === nowPlaying && |
446 | 682 | trackQueue.model.get(player.currentIndex) !== undefined && | 686 | trackQueue.get(player.currentIndex) !== undefined && |
447 | 683 | Qt.resolvedUrl(trackQueue.model.get(player.currentIndex).filename) === file) { | 687 | Qt.resolvedUrl(trackQueue.get(player.currentIndex).filename) === file) { |
448 | 684 | player.toggle() | 688 | player.toggle() |
449 | 685 | return; | 689 | return; |
450 | 686 | } | 690 | } |
451 | 687 | } | 691 | } |
452 | 688 | 692 | ||
454 | 689 | trackQueue.model.clear(); // clear the old model | 693 | trackQueue.clearItems(); // clear the old model |
455 | 690 | 694 | ||
456 | 691 | addQueueFromModel(model); | 695 | addQueueFromModel(model); |
457 | 692 | 696 | ||
458 | @@ -709,7 +713,7 @@ | |||
459 | 709 | player.toggle(); | 713 | player.toggle(); |
460 | 710 | } | 714 | } |
461 | 711 | else { | 715 | else { |
463 | 712 | player.playSong(trackQueue.model.get(index).filename, index); | 716 | player.playSong(trackQueue.get(index).filename, index); |
464 | 713 | } | 717 | } |
465 | 714 | 718 | ||
466 | 715 | // Show the Now Playing page and make sure the track is visible | 719 | // Show the Now Playing page and make sure the track is visible |
467 | @@ -721,7 +725,7 @@ | |||
468 | 721 | 725 | ||
469 | 722 | function playRandomSong(shuffle) | 726 | function playRandomSong(shuffle) |
470 | 723 | { | 727 | { |
472 | 724 | trackQueue.model.clear(); | 728 | trackQueue.clearItems(); |
473 | 725 | 729 | ||
474 | 726 | var now = new Date(); | 730 | var now = new Date(); |
475 | 727 | var seed = now.getSeconds(); | 731 | var seed = now.getSeconds(); |
476 | @@ -853,13 +857,67 @@ | |||
477 | 853 | } | 857 | } |
478 | 854 | 858 | ||
479 | 855 | // list of tracks on startup. This is just during development | 859 | // list of tracks on startup. This is just during development |
481 | 856 | LibraryListModel { | 860 | ListModel { |
482 | 857 | id: trackQueue | 861 | id: trackQueue |
483 | 858 | 862 | ||
488 | 859 | function append(listElement) | 863 | /* Pretent to be like a mediascanner2 listmodel */ |
489 | 860 | { | 864 | property alias rowCount: trackQueue.count |
490 | 861 | model.append(makeDict(listElement)) | 865 | |
491 | 862 | console.debug(JSON.stringify(makeDict(listElement))); | 866 | function appendItem(item) { |
492 | 867 | append(item) | ||
493 | 868 | |||
494 | 869 | trackQueueUI.liveList.push(item) | ||
495 | 870 | trackQueueUI.onlyAppend = true | ||
496 | 871 | trackQueueUI.list = trackQueueUI.liveList | ||
497 | 872 | } | ||
498 | 873 | |||
499 | 874 | function appendList(list) | ||
500 | 875 | { | ||
501 | 876 | for (var i=0; i < list.length; i++) { | ||
502 | 877 | append(list[i]) | ||
503 | 878 | } | ||
504 | 879 | |||
505 | 880 | trackQueueUI.liveList = list | ||
506 | 881 | trackQueueUI.list = list | ||
507 | 882 | |||
508 | 883 | console.debug(JSON.stringify(list)); | ||
509 | 884 | } | ||
510 | 885 | |||
511 | 886 | function clearItems() | ||
512 | 887 | { | ||
513 | 888 | clear() | ||
514 | 889 | |||
515 | 890 | trackQueueUI.clear() | ||
516 | 891 | trackQueueUI.liveList = [] | ||
517 | 892 | trackQueueUI.list = [] | ||
518 | 893 | } | ||
519 | 894 | } | ||
520 | 895 | |||
521 | 896 | LibraryListModel { | ||
522 | 897 | id: trackQueueUI | ||
523 | 898 | canLoad: true | ||
524 | 899 | |||
525 | 900 | property var liveList: null | ||
526 | 901 | |||
527 | 902 | function move(from, to, count) | ||
528 | 903 | { | ||
529 | 904 | trackQueue.move(from, to, count) | ||
530 | 905 | model.move(from, to, count) | ||
531 | 906 | |||
532 | 907 | // list.splice(to, 0, *list.splice(from, count)) | ||
533 | 908 | |||
534 | 909 | var args = [to, 0]; | ||
535 | 910 | args.push.apply(args, liveList.splice(from, count)) | ||
536 | 911 | |||
537 | 912 | liveList.splice.apply(liveList, args) | ||
538 | 913 | } | ||
539 | 914 | |||
540 | 915 | function remove(index) | ||
541 | 916 | { | ||
542 | 917 | trackQueue.remove(index) | ||
543 | 918 | model.remove(index) | ||
544 | 919 | |||
545 | 920 | liveList.splice(index, 1) | ||
546 | 863 | } | 921 | } |
547 | 864 | } | 922 | } |
548 | 865 | 923 | ||
549 | @@ -910,7 +968,7 @@ | |||
550 | 910 | onClicked: { | 968 | onClicked: { |
551 | 911 | console.debug("Debug: Add track to queue: " + JSON.stringify(chosenElement)) | 969 | console.debug("Debug: Add track to queue: " + JSON.stringify(chosenElement)) |
552 | 912 | PopupUtils.close(trackPopover) | 970 | PopupUtils.close(trackPopover) |
554 | 913 | trackQueue.append(chosenElement) | 971 | trackQueue.appendItem(makeDict(chosenElement)) |
555 | 914 | } | 972 | } |
556 | 915 | } | 973 | } |
557 | 916 | ListItem.Standard { | 974 | ListItem.Standard { |
FAILED: Continuous integration, rev:565 91.189. 93.70:8080/ job/music- app-ci/ 1073/ 91.189. 93.70:8080/ job/generic- mediumtests- utopic/ 1685/console 91.189. 93.70:8080/ job/music- app-utopic- amd64-ci/ 297/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/music- app-ci/ 1073/rebuild
http://