Merge lp:~ahayzen/music-app/trackqueue-speedup into lp:music-app/trusty

Proposed by Andrew Hayzen on 2014-08-24
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
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing on 2014-08-24
Music App Developers 2014-08-24 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.

To post a comment you must log in.
review: Needs Fixing (continuous-integration)
566. By Andrew Hayzen on 2014-08-24

* Merge of trunk

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.

http://youtu.be/43IZ7jI5QbY

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 on 2014-08-24

* Merge of trunk

565. By Andrew Hayzen on 2014-08-24

* Use worker loaded trackQueueUI infront of trackQueue

564. By Andrew Hayzen on 2014-08-12

* Disable trackQueue from now playing page

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'LibraryListModel.qml'
--- LibraryListModel.qml 2014-08-20 17:35:52 +0000
+++ LibraryListModel.qml 2014-08-24 23:27:56 +0000
@@ -34,6 +34,10 @@
34 property bool canLoad: true34 property bool canLoad: true
35 property bool preLoadComplete: false35 property bool preLoadComplete: false
3636
37 property alias onlyAppend: worker.onlyAppend
38 property alias list: worker.list
39 property alias workerCompleted: worker.completed
40
37 onCanLoadChanged: {41 onCanLoadChanged: {
38 /* If canLoad has been set back to true then check if there are any42 /* If canLoad has been set back to true then check if there are any
39 remaining items to load in the model */43 remaining items to load in the model */
@@ -58,9 +62,19 @@
58 property int i: 062 property int i: 0
59 property var list: null63 property var list: null
6064
65 property bool onlyAppend: false
66
61 onListChanged: {67 onListChanged: {
62 reset();68 if (onlyAppend) {
63 clear();69 if (canLoad) {
70 process()
71 }
72
73 onlyAppend = false
74 } else {
75 reset();
76 clear();
77 }
64 }78 }
6579
66 onMessage: {80 onMessage: {
6781
=== modified file 'MusicNowPlaying.qml'
--- MusicNowPlaying.qml 2014-08-20 17:35:52 +0000
+++ MusicNowPlaying.qml 2014-08-24 23:27:56 +0000
@@ -55,8 +55,6 @@
55 return;55 return;
56 }56 }
5757
58 queuelist.currentIndex = player.currentIndex;
59
60 customdebug("MusicQueue update currentIndex: " + player.source);58 customdebug("MusicQueue update currentIndex: " + player.source);
6159
62 // Always jump to current track60 // Always jump to current track
@@ -70,14 +68,24 @@
70 // If the toolbar is shown, the page is now playing and snaptrack is enabled68 // If the toolbar is shown, the page is now playing and snaptrack is enabled
71 if (shown && currentPage === nowPlaying && Settings.getSetting("snaptrack") === "1")69 if (shown && currentPage === nowPlaying && Settings.getSetting("snaptrack") === "1")
72 {70 {
73 // Then position the view at the current index71
74 queuelist.positionViewAtIndex(queuelist.currentIndex, ListView.Beginning);72 // Only jump if the item has been created otherwise jump on load
73 if (queuelist.count >= player.currentIndex && trackQueueUI.workerCompleted) {
74 // Then position the view at the current index
75 queuelist.positionViewAtIndex(player.currentIndex, ListView.Beginning);
76 } else {
77 queuelist.jumpOnLoad = player.currentIndex
78 }
75 }79 }
76 }80 }
7781
78 function positionAt(index) {82 function positionAt(index) {
79 queuelist.positionViewAtIndex(index, ListView.Beginning);83 if (queuelist.count >= index && trackQueueUI.workerCompleted) {
80 queuelist.contentY -= header.height;84 queuelist.positionViewAtIndex(index, ListView.Beginning);
85 queuelist.contentY -= header.height;
86 } else {
87 queuelist.jumpOnLoad = index
88 }
81 }89 }
8290
83 ListView {91 ListView {
@@ -86,7 +94,7 @@
86 anchors.fill: parent94 anchors.fill: parent
87 anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight95 anchors.bottomMargin: musicToolbar.mouseAreaOffset + musicToolbar.minimizedHeight
88 delegate: queueDelegate96 delegate: queueDelegate
89 model: trackQueue.model97 model: trackQueueUI.model
90 highlightFollowsCurrentItem: false98 highlightFollowsCurrentItem: false
91 state: "normal"99 state: "normal"
92 states: [100 states: [
@@ -113,21 +121,39 @@
113 property int currentHeight: units.gu(40)121 property int currentHeight: units.gu(40)
114 property int transitionDuration: 250 // transition length of animations122 property int transitionDuration: 250 // transition length of animations
115123
124 property int jumpOnLoad: -1
125
116 onCountChanged: {126 onCountChanged: {
117 customdebug("Queue: Now has: " + queuelist.count + " tracks")127 customdebug("Queue: Now has: " + queuelist.count + " tracks" + " " + jumpOnLoad)
128
129 if (jumpOnLoad < count && jumpOnLoad !== -1) { // < due to count being +1 to index
130 positionAtAfterDelay.start()
131 }
118 }132 }
119133
120 onMovementStarted: {134 onMovementStarted: {
121 musicToolbar.hideToolbar();135 musicToolbar.hideToolbar();
122 }136 }
123137
138 Timer {
139 id: positionAtAfterDelay
140 interval: 250
141 repeat: false
142 onTriggered: {
143 // Then position the view at the current index
144 queuelist.positionViewAtIndex(queuelist.jumpOnLoad, ListView.Beginning);
145
146 queuelist.jumpOnLoad = -1
147 }
148 }
149
124 Component {150 Component {
125 id: queueDelegate151 id: queueDelegate
126 ListItemWithActions {152 ListItemWithActions {
127 id: queueListItem153 id: queueListItem
128 color: "transparent"154 color: "transparent"
129 height: queuelist.normalHeight155 height: queuelist.normalHeight
130 state: queuelist.currentIndex == index && !reordering ? "current" : ""156 state: player.currentIndex == index && !reordering ? "current" : ""
131157
132 leftSideAction: Remove {158 leftSideAction: Remove {
133 onTriggered: {159 onTriggered: {
@@ -143,7 +169,7 @@
143 player.currentIndex -= 1;169 player.currentIndex -= 1;
144 }170 }
145171
146 queuelist.model.remove(index);172 trackQueueUI.remove(index);
147 }173 }
148 }174 }
149 reorderable: true175 reorderable: true
@@ -161,8 +187,7 @@
161 onReorder: {187 onReorder: {
162 console.debug("Move: ", from, to);188 console.debug("Move: ", from, to);
163189
164 queuelist.model.move(from, to, 1);190 trackQueueUI.move(from, to, 1);
165
166191
167 // Maintain currentIndex with current song192 // Maintain currentIndex with current song
168 if (from === player.currentIndex) {193 if (from === player.currentIndex) {
169194
=== modified file 'MusicSearch.qml'
--- MusicSearch.qml 2014-08-21 19:32:12 +0000
+++ MusicSearch.qml 2014-08-24 23:27:56 +0000
@@ -173,8 +173,8 @@
173 onItemClicked: {173 onItemClicked: {
174 console.debug("Debug: "+title+" added to queue")174 console.debug("Debug: "+title+" added to queue")
175 // now play this track, but keep current queue175 // now play this track, but keep current queue
176 trackQueue.append(model)176 trackQueue.appendItem(makeDict(model))
177 trackQueueClick(trackQueue.model.count - 1);177 trackQueueClick(trackQueue.count - 1);
178 onDoneClicked: PopupUtils.close(searchTrack)178 onDoneClicked: PopupUtils.close(searchTrack)
179 }179 }
180180
181181
=== modified file 'MusicToolbar.qml'
--- MusicToolbar.qml 2014-08-21 19:32:12 +0000
+++ MusicToolbar.qml 2014-08-24 23:27:56 +0000
@@ -223,7 +223,7 @@
223223
224 /* Clicking in the area shows the queue */224 /* Clicking in the area shows the queue */
225 function trigger() {225 function trigger() {
226 if (trackQueue.model.count !== 0 && currentPage !== nowPlaying) {226 if (trackQueue.count !== 0 && currentPage !== nowPlaying) {
227 tabs.pushNowPlaying();227 tabs.pushNowPlaying();
228 }228 }
229 else if (currentPage === nowPlaying) {229 else if (currentPage === nowPlaying) {
@@ -244,7 +244,7 @@
244 elide: Text.ElideRight244 elide: Text.ElideRight
245 fontSize: "medium"245 fontSize: "medium"
246 objectName: "playercontroltitle"246 objectName: "playercontroltitle"
247 text: trackQueue.model.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle247 text: trackQueue.count === 0 ? "" : player.currentMetaTitle === "" ? player.currentMetaFile : player.currentMetaTitle
248 }248 }
249249
250 /* Artist of track */250 /* Artist of track */
@@ -259,7 +259,7 @@
259 color: styleMusic.playerControls.labelColor259 color: styleMusic.playerControls.labelColor
260 elide: Text.ElideRight260 elide: Text.ElideRight
261 fontSize: "small"261 fontSize: "small"
262 text: trackQueue.model.count === 0 ? "" : player.currentMetaArtist262 text: trackQueue.count === 0 ? "" : player.currentMetaArtist
263 }263 }
264264
265 /* Album of track */265 /* Album of track */
@@ -274,7 +274,7 @@
274 color: styleMusic.playerControls.labelColor274 color: styleMusic.playerControls.labelColor
275 elide: Text.ElideRight275 elide: Text.ElideRight
276 fontSize: "small"276 fontSize: "small"
277 text: trackQueue.model.count === 0 ? "" : player.currentMetaAlbum277 text: trackQueue.count === 0 ? "" : player.currentMetaAlbum
278 }278 }
279 }279 }
280280
@@ -318,11 +318,11 @@
318 anchors.verticalCenter: parent.verticalCenter318 anchors.verticalCenter: parent.verticalCenter
319 height: units.gu(6)319 height: units.gu(6)
320 objectName: "previousshape"320 objectName: "previousshape"
321 opacity: trackQueue.model.count === 0 ? .4 : 1321 opacity: trackQueue.count === 0 ? .4 : 1
322 width: height322 width: height
323323
324 function trigger() {324 function trigger() {
325 if (trackQueue.model.count === 0) {325 if (trackQueue.count === 0) {
326 return;326 return;
327 }327 }
328328
@@ -409,7 +409,7 @@
409 return;409 return;
410 }410 }
411411
412 if (trackQueue.model.count === 0) {412 if (trackQueue.count === 0) {
413 playRandomSong();413 playRandomSong();
414 }414 }
415 else {415 else {
@@ -442,11 +442,11 @@
442 anchors.verticalCenter: parent.verticalCenter442 anchors.verticalCenter: parent.verticalCenter
443 height: units.gu(6)443 height: units.gu(6)
444 objectName: "forwardshape"444 objectName: "forwardshape"
445 opacity: trackQueue.model.count === 0 ? .4 : 1445 opacity: trackQueue.count === 0 ? .4 : 1
446 width: height446 width: height
447447
448 function trigger() {448 function trigger() {
449 if (trackQueue.model.count === 0 || emptyPage.noMusic) {449 if (trackQueue.count === 0 || emptyPage.noMusic) {
450 return;450 return;
451 }451 }
452452
@@ -569,7 +569,7 @@
569 anchors.verticalCenter: parent.verticalCenter569 anchors.verticalCenter: parent.verticalCenter
570 color: "transparent"570 color: "transparent"
571 height: units.gu(1);571 height: units.gu(1);
572 state: trackQueue.model.count === 0 ? "disabled" : "enabled"572 state: trackQueue.count === 0 ? "disabled" : "enabled"
573573
574 states: [574 states: [
575 State {575 State {
@@ -716,7 +716,7 @@
716 id: musicToolbarPlayerControls716 id: musicToolbarPlayerControls
717 anchors.fill: parent717 anchors.fill: parent
718 color: styleMusic.playerControls.backgroundColor718 color: styleMusic.playerControls.backgroundColor
719 state: trackQueue.model.count === 0 ? "disabled" : "enabled"719 state: trackQueue.count === 0 ? "disabled" : "enabled"
720 states: [720 states: [
721 State {721 State {
722 name: "disabled"722 name: "disabled"
@@ -746,7 +746,7 @@
746 id: disabledPlayerControlsGroup746 id: disabledPlayerControlsGroup
747 anchors.fill: parent747 anchors.fill: parent
748 color: "transparent"748 color: "transparent"
749 visible: trackQueue.model.count === 0749 visible: trackQueue.count === 0
750750
751 Label {751 Label {
752 id: noSongsInQueueLabel752 id: noSongsInQueueLabel
@@ -779,7 +779,7 @@
779 return;779 return;
780 }780 }
781781
782 if (trackQueue.model.count === 0) {782 if (trackQueue.count === 0) {
783 playRandomSong();783 playRandomSong();
784 }784 }
785 else {785 else {
@@ -861,7 +861,7 @@
861 id: enabledPlayerControlsGroup861 id: enabledPlayerControlsGroup
862 anchors.fill: parent862 anchors.fill: parent
863 color: "transparent"863 color: "transparent"
864 visible: trackQueue.model.count !== 0864 visible: trackQueue.count !== 0
865865
866 /* Settings button */866 /* Settings button */
867 // TODO: Enable settings when it is practical867 // TODO: Enable settings when it is practical
@@ -911,7 +911,7 @@
911 return;911 return;
912 }912 }
913913
914 if (trackQueue.model.count === 0) {914 if (trackQueue.count === 0) {
915 playRandomSong();915 playRandomSong();
916 }916 }
917 else {917 else {
918918
=== modified file 'Player.qml'
--- Player.qml 2014-08-22 00:26:30 +0000
+++ Player.qml 2014-08-24 23:27:56 +0000
@@ -59,12 +59,12 @@
59 }59 }
6060
61 Connections {61 Connections {
62 target: trackQueue.model62 target: trackQueue
63 onCountChanged: {63 onCountChanged: {
64 if (trackQueue.model.count === 1) {64 if (trackQueue.count === 1) {
65 player.currentIndex = 0;65 player.currentIndex = 0;
66 player.source = Qt.resolvedUrl(trackQueue.model.get(0).filename)66 player.source = Qt.resolvedUrl(trackQueue.get(0).filename)
67 } else if (trackQueue.model.count === 0) {67 } else if (trackQueue.count === 0) {
68 player.currentMetaFile = ""68 player.currentMetaFile = ""
69 player.source = ""69 player.source = ""
70 }70 }
@@ -79,7 +79,7 @@
79 return;79 return;
80 }80 }
8181
82 if (trackQueue.model.count == 0)82 if (trackQueue.count == 0)
83 {83 {
84 customdebug("No tracks in queue.");84 customdebug("No tracks in queue.");
85 return;85 return;
@@ -91,26 +91,26 @@
91 var newIndex;91 var newIndex;
9292
93 console.log("currentIndex: " + currentIndex)93 console.log("currentIndex: " + currentIndex)
94 console.log("trackQueue.count: " + trackQueue.model.count)94 console.log("trackQueue.count: " + trackQueue.count)
9595
96 // Do not shuffle if repeat is off and there is only one track in the queue96 // Do not shuffle if repeat is off and there is only one track in the queue
97 if (shuffle && !(trackQueue.model.count === 1 && !repeat)) {97 if (shuffle && !(trackQueue.count === 1 && !repeat)) {
98 var now = new Date();98 var now = new Date();
99 var seed = now.getSeconds();99 var seed = now.getSeconds();
100100
101 // trackQueue must be above 1 otherwise an infinite loop will occur101 // trackQueue must be above 1 otherwise an infinite loop will occur
102 do {102 do {
103 newIndex = (Math.floor((trackQueue.model.count)103 newIndex = (Math.floor((trackQueue.count)
104 * Math.random(seed)));104 * Math.random(seed)));
105 } while (newIndex === currentIndex && trackQueue.model.count > 1)105 } while (newIndex === currentIndex && trackQueue.count > 1)
106 } else {106 } else {
107 if ((currentIndex < trackQueue.model.count - 1 && direction === 1 )107 if ((currentIndex < trackQueue.count - 1 && direction === 1 )
108 || (currentIndex > 0 && direction === -1)) {108 || (currentIndex > 0 && direction === -1)) {
109 newIndex = currentIndex + direction109 newIndex = currentIndex + direction
110 } else if(direction === 1 && (repeat || fromControls)) {110 } else if(direction === 1 && (repeat || fromControls)) {
111 newIndex = 0111 newIndex = 0
112 } else if(direction === -1 && (repeat || fromControls)) {112 } else if(direction === -1 && (repeat || fromControls)) {
113 newIndex = trackQueue.model.count - 1113 newIndex = trackQueue.count - 1
114 }114 }
115 else115 else
116 {116 {
@@ -120,11 +120,11 @@
120 }120 }
121121
122 if (startPlaying) { // only start the track if told122 if (startPlaying) { // only start the track if told
123 playSong(trackQueue.model.get(newIndex).filename, newIndex)123 playSong(trackQueue.get(newIndex).filename, newIndex)
124 }124 }
125 else {125 else {
126 currentIndex = newIndex126 currentIndex = newIndex
127 source = Qt.resolvedUrl(trackQueue.model.get(newIndex).filename)127 source = Qt.resolvedUrl(trackQueue.get(newIndex).filename)
128 }128 }
129 }129 }
130130
@@ -184,7 +184,7 @@
184 player.stop()184 player.stop()
185 }185 }
186 else {186 else {
187 var obj = trackQueue.model.get(player.currentIndex);187 var obj = trackQueue.get(player.currentIndex);
188 currentMetaAlbum = obj.album;188 currentMetaAlbum = obj.album;
189 currentMetaArtist = obj.author;189 currentMetaArtist = obj.author;
190 currentMetaFile = obj.filename;190 currentMetaFile = obj.filename;
191191
=== modified file 'common/ListItemActions/AddToQueue.qml'
--- common/ListItemActions/AddToQueue.qml 2014-08-20 17:35:52 +0000
+++ common/ListItemActions/AddToQueue.qml 2014-08-24 23:27:56 +0000
@@ -26,6 +26,6 @@
2626
27 onTriggered: {27 onTriggered: {
28 console.debug("Debug: Add track to queue: " + model)28 console.debug("Debug: Add track to queue: " + model)
29 trackQueue.append(model)29 trackQueue.appendItem(makeDict(model))
30 }30 }
31}31}
3232
=== modified file 'music-app.qml'
--- music-app.qml 2014-08-22 00:26:30 +0000
+++ music-app.qml 2014-08-24 23:27:56 +0000
@@ -236,15 +236,15 @@
236236
237 if (play) {237 if (play) {
238 // clear play queue238 // clear play queue
239 trackQueue.model.clear()239 trackQueue.clearItems()
240 }240 }
241241
242 // enqueue242 // enqueue
243 trackQueue.append(makeDict(track));243 trackQueue.appendItem(makeDict(track));
244244
245 // play first URI245 // play first URI
246 if (play) {246 if (play) {
247 trackQueueClick(trackQueue.model.count - 1);247 trackQueueClick(trackQueue.count - 1);
248 }248 }
249 }249 }
250250
@@ -394,7 +394,7 @@
394 else {394 else {
395 stopTimer();395 stopTimer();
396396
397 trackQueue.model.clear();397 trackQueue.clearItems();
398398
399 trackQueue.append(makeDict(model));399 trackQueue.append(makeDict(model));
400 trackQueueClick(0);400 trackQueueClick(0);
@@ -637,9 +637,13 @@
637 model = model.linkLibraryListModel;637 model = model.linkLibraryListModel;
638 }638 }
639639
640 var list = []
641
640 for (var i=0; i < model.rowCount; i++) {642 for (var i=0; i < model.rowCount; i++) {
641 trackQueue.model.append(makeDict(model.get(i, model.RoleModelData)));643 list.push(makeDict(model.get(i, model.RoleModelData)));
642 }644 }
645
646 trackQueue.appendList(list)
643 }647 }
644648
645 // Converts an duration in ms to a formated string ("minutes:seconds")649 // Converts an duration in ms to a formated string ("minutes:seconds")
@@ -679,14 +683,14 @@
679 if (!clear) {683 if (!clear) {
680 // If same track and on now playing page then toggle684 // If same track and on now playing page then toggle
681 if (musicToolbar.currentPage === nowPlaying &&685 if (musicToolbar.currentPage === nowPlaying &&
682 trackQueue.model.get(player.currentIndex) !== undefined &&686 trackQueue.get(player.currentIndex) !== undefined &&
683 Qt.resolvedUrl(trackQueue.model.get(player.currentIndex).filename) === file) {687 Qt.resolvedUrl(trackQueue.get(player.currentIndex).filename) === file) {
684 player.toggle()688 player.toggle()
685 return;689 return;
686 }690 }
687 }691 }
688692
689 trackQueue.model.clear(); // clear the old model693 trackQueue.clearItems(); // clear the old model
690694
691 addQueueFromModel(model);695 addQueueFromModel(model);
692696
@@ -709,7 +713,7 @@
709 player.toggle();713 player.toggle();
710 }714 }
711 else {715 else {
712 player.playSong(trackQueue.model.get(index).filename, index);716 player.playSong(trackQueue.get(index).filename, index);
713 }717 }
714718
715 // Show the Now Playing page and make sure the track is visible719 // Show the Now Playing page and make sure the track is visible
@@ -721,7 +725,7 @@
721725
722 function playRandomSong(shuffle)726 function playRandomSong(shuffle)
723 {727 {
724 trackQueue.model.clear();728 trackQueue.clearItems();
725729
726 var now = new Date();730 var now = new Date();
727 var seed = now.getSeconds();731 var seed = now.getSeconds();
@@ -853,13 +857,67 @@
853 }857 }
854858
855 // list of tracks on startup. This is just during development859 // list of tracks on startup. This is just during development
856 LibraryListModel {860 ListModel {
857 id: trackQueue861 id: trackQueue
858862
859 function append(listElement)863 /* Pretent to be like a mediascanner2 listmodel */
860 {864 property alias rowCount: trackQueue.count
861 model.append(makeDict(listElement))865
862 console.debug(JSON.stringify(makeDict(listElement)));866 function appendItem(item) {
867 append(item)
868
869 trackQueueUI.liveList.push(item)
870 trackQueueUI.onlyAppend = true
871 trackQueueUI.list = trackQueueUI.liveList
872 }
873
874 function appendList(list)
875 {
876 for (var i=0; i < list.length; i++) {
877 append(list[i])
878 }
879
880 trackQueueUI.liveList = list
881 trackQueueUI.list = list
882
883 console.debug(JSON.stringify(list));
884 }
885
886 function clearItems()
887 {
888 clear()
889
890 trackQueueUI.clear()
891 trackQueueUI.liveList = []
892 trackQueueUI.list = []
893 }
894 }
895
896 LibraryListModel {
897 id: trackQueueUI
898 canLoad: true
899
900 property var liveList: null
901
902 function move(from, to, count)
903 {
904 trackQueue.move(from, to, count)
905 model.move(from, to, count)
906
907 // list.splice(to, 0, *list.splice(from, count))
908
909 var args = [to, 0];
910 args.push.apply(args, liveList.splice(from, count))
911
912 liveList.splice.apply(liveList, args)
913 }
914
915 function remove(index)
916 {
917 trackQueue.remove(index)
918 model.remove(index)
919
920 liveList.splice(index, 1)
863 }921 }
864 }922 }
865923
@@ -910,7 +968,7 @@
910 onClicked: {968 onClicked: {
911 console.debug("Debug: Add track to queue: " + JSON.stringify(chosenElement))969 console.debug("Debug: Add track to queue: " + JSON.stringify(chosenElement))
912 PopupUtils.close(trackPopover)970 PopupUtils.close(trackPopover)
913 trackQueue.append(chosenElement)971 trackQueue.appendItem(makeDict(chosenElement))
914 }972 }
915 }973 }
916 ListItem.Standard {974 ListItem.Standard {

Subscribers

People subscribed via source and target branches

to status/vote changes: