Merge lp:~music-app-dev/music-app/frankenstein-merge into lp:music-app/trusty

Proposed by Victor Thompson
Status: Merged
Approved by: Victor Thompson
Approved revision: 33
Merged at revision: 24
Proposed branch: lp:~music-app-dev/music-app/frankenstein-merge
Merge into: lp:music-app/trusty
Diff against target: 1700 lines (+780/-705)
9 files modified
FirstRun.qml (+0/-54)
MusicSettings.qml (+13/-7)
MusicTracks.qml (+627/-96)
QueueDialog.qml (+4/-4)
Toolbar.qml (+0/-103)
debian/changelog (+7/-1)
debian/install (+9/-1)
music-app.qml (+86/-439)
playing-list.js (+34/-0)
To merge this branch: bzr merge lp:~music-app-dev/music-app/frankenstein-merge
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Martin Mrazik (community) Approve
Daniel Holm Approve
Review via email: mp+167199@code.launchpad.net

Commit message

Merged my existing lp:ubuntu-music-app code into the trunk.
* Replaced current UI
* Replaced playback functionality and managment
* Added some UI (that wasn't in my upstream) so we can do context switching from a tracks view to a playlist view or artists/albums.
* Fixed shuffling behavoir and retrieving/setting of the shuffle parameter setting
* Currently the Queue will add items on "press and hold", but the tracks are not playable. As we move forward, the Queue should just be another ListView. The same will go for playlists.

Description of the change

Merged my existing lp:ubuntu-music-app code into the trunk.
* Replaced current UI
* Replaced playback functionality and managment
* Added some UI (that wasn't in my upstream) so we can do context switching from a tracks view to a playlist view or artists/albums.
* Fixed shuffling behavoir and retrieving/setting of the shuffle parameter setting
* Currently the Queue will add items on "press and hold", but the tracks are not playable. As we move forward, the Queue should just be another ListView. The same will go for playlists.

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)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel Holm (danielholm) :
review: Approve
Revision history for this message
Daniel Holm (danielholm) wrote :

I think I've fixed the error. Trying again.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Martin Mrazik (mrazik) wrote :

Mhm... This fails to land in a weird way but it looks like the changelog is badly formatted:
----snip----
bzrlib.plugins.builddeb.errors.UnparseableChangelog: There was an error parsing the changelog: Could not parse changelog: Badly formatted trailer line: -- Victor Thompson <email address hidden> Tue, 04 June 2013 11:45:00 -0400
-------

AFAICS there is a missing space after e-mail address:
      -- maintainer name <email address>[two spaces] date

It is weird the CI build passes but apparently that check is missing there.

review: Needs Fixing
Revision history for this message
Victor Thompson (vthompson) wrote :

Issue has been fixed. Maybe someone needs to put Jenkins in "needs review"

Revision history for this message
Martin Mrazik (mrazik) wrote :

Feel free to approve. Jenkins should pick it up now. Sorry for the hassle.

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
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=== removed file 'FirstRun.qml'
2--- FirstRun.qml 2013-05-31 13:58:43 +0000
3+++ FirstRun.qml 1970-01-01 00:00:00 +0000
4@@ -1,54 +0,0 @@
5-/*
6- * Copyleft Daniel Holm.
7- *
8- * Authors:
9- * Daniel Holm <d.holmen@gmail.com>
10- *
11- * This program is free software; you can redistribute it and/or modify
12- * it under the terms of the GNU General Public License as published by
13- * the Free Software Foundation; version 3.
14- *
15- * This program is distributed in the hope that it will be useful,
16- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18- * GNU General Public License for more details.
19- *
20- * You should have received a copy of the GNU General Public License
21- * along with this program. If not, see <http://www.gnu.org/licenses/>.
22- */
23-
24-import QtQuick 2.0
25-import Ubuntu.Components 0.1
26-import Ubuntu.Components.ListItems 0.1 as ListItem
27-import Ubuntu.Components.Popups 0.1
28-import QtQuick.LocalStorage 2.0
29-import "settings.js" as Settings
30-
31-Dialog {
32- id: root
33- title: i18n.tr("First Run")
34- text: i18n.tr("This appears to be your first run. Please set your music directory.")
35-
36- Row {
37- spacing: units.gu(2)
38- TextField {
39- id: musicDirField
40- placeholderText: "/home/username/Music"
41- hasClearButton: false
42- text: musicDir
43- }
44- }
45-
46- Button {
47- text: i18n.tr("Save")
48- color: "green"
49- onClicked: {
50- PopupUtils.close(root)
51- // set new music dir
52- Settings.initialize()
53- Settings.setSetting("currentfolder", musicDirField.text)
54- console.debug("Debug: Set new music dir to: "+musicDirField.text)
55- }
56- }
57-
58-}
59
60=== modified file 'MusicSettings.qml'
61--- MusicSettings.qml 2013-05-31 14:58:23 +0000
62+++ MusicSettings.qml 2013-06-05 04:48:28 +0000
63@@ -3,6 +3,7 @@
64 *
65 * Authors:
66 * Daniel Holm <d.holmen@gmail.com>
67+ * Victor Thompson <victor.thompson@gmail.com>
68 *
69 * This program is free software; you can redistribute it and/or modify
70 * it under the terms of the GNU General Public License as published by
71@@ -31,9 +32,13 @@
72 spacing: units.gu(2)
73 TextField {
74 id: musicDirField
75- placeholderText: "/home/username/Music"
76+ placeholderText: folderModel.homePath() + "/Music"
77 hasClearButton: false
78- text: musicDir
79+ text: Settings.getSetting("currentfolder")
80+
81+ onTextChanged: {
82+ Settings.setSetting("currentfolder", text)
83+ }
84 }
85 }
86
87@@ -45,8 +50,8 @@
88 width: units.gu(20)
89 }
90 Switch {
91- id: scrobbleSwitch
92- checked: shuffleState
93+ id: shuffleSwitch
94+ checked: Settings.getSetting("shuffle") === "1"
95 }
96 }
97
98@@ -97,7 +102,7 @@
99 Row {
100 ListItem.Subtitled {
101 text: "Music "+appVersion
102- subText: i18n.tr("By Daniel Holm, Sweden")
103+ subText: i18n.tr("By Daniel Holm (Sweden) and\nVictor Thompson (USA)")
104 }
105 }
106
107@@ -142,9 +147,10 @@
108 // set new music dir
109 Settings.initialize()
110 Settings.setSetting("currentfolder", musicDirField.text) // save music dir
111- Settings.setSetting("shuffle", scrobbleSwitch.checked) // save shuffle state
112+ Settings.setSetting("shuffle", shuffleSwitch.checked) // save shuffle state
113+ random = shuffleSwitch.checked
114 console.debug("Debug: Set new music dir to: "+musicDirField.text)
115- console.debug("Debug: Shuffle: "+scrobbleSwitch.checked)
116+ console.debug("Debug: Shuffle: "+ shuffleSwitch.checked)
117 }
118 }
119
120
121=== modified file 'MusicTracks.qml'
122--- MusicTracks.qml 2013-05-31 14:58:23 +0000
123+++ MusicTracks.qml 2013-06-05 04:48:28 +0000
124@@ -3,6 +3,7 @@
125 *
126 * Authors:
127 * Daniel Holm <d.holmen@gmail.com>
128+ * Victor Thompson <victor.thompson@gmail.com>
129 *
130 * This program is free software; you can redistribute it and/or modify
131 * it under the terms of the GNU General Public License as published by
132@@ -22,119 +23,649 @@
133 import Ubuntu.Components.ListItems 0.1
134 import Ubuntu.Components.Popups 0.1
135 import Ubuntu.Components.ListItems 0.1 as ListItem
136-import Qt.labs.folderlistmodel 1.0
137+import org.nemomobile.folderlistmodel 1.0
138 import QtMultimedia 5.0
139 import QtQuick.LocalStorage 2.0
140 import "settings.js" as Settings
141-import "meta-database.js" as MetaDB
142+import "meta-database.js" as Library
143+import "playing-list.js" as PlayingList
144+
145
146
147 PageStack {
148- id: singleTracksPageStack
149+ id: pageStack
150 anchors.fill: parent
151
152+ property bool needsUpdate: false
153+ property int filelistCurrentIndex: 0
154+ property int filelistCount: 0
155+
156+ onFilelistCurrentIndexChanged: {
157+ filelist.currentIndex = filelistCurrentIndex
158+ }
159+
160+ onNeedsUpdateChanged: {
161+ if (needsUpdate === true) {
162+ needsUpdate = false
163+ fileDurationProgressBackground.visible = true
164+ fileDurationProgressBackground_nowplaying.visible = true
165+ fileDurationProgress.width = units.gu(Math.floor((player.position*100)/player.duration) * .2) // 20 max
166+ fileDurationProgress_nowplaying.width = units.gu(Math.floor((player.position*100)/player.duration) * .4) // 40 max
167+ fileDurationBottom.text = Math.floor((player.position/1000) / 60).toString() + ":" + (
168+ Math.floor((player.position/1000) % 60)<10 ? "0"+Math.floor((player.position/1000) % 60).toString() :
169+ Math.floor((player.position/1000) % 60).toString())
170+ fileDurationBottom.text += " / "
171+ fileDurationBottom.text += Math.floor((player.duration/1000) / 60).toString() + ":" + (
172+ Math.floor((player.duration/1000) % 60)<10 ? "0"+Math.floor((player.duration/1000) % 60).toString() :
173+ Math.floor((player.duration/1000) % 60).toString())
174+ fileDurationBottom_nowplaying.text = fileDurationBottom.text
175+ }
176+ }
177+
178 Component.onCompleted: {
179- // initialize settings db
180+ pageStack.push(mainpage)
181 Settings.initialize()
182- console.debug("INITIALIZED Settings")
183-
184- // If there were no database
185+ console.debug("INITIALIZED")
186 if (Settings.getSetting("initialized") !== "true") {
187 // initialize settings
188 console.debug("reset settings")
189- Settings.setSetting("initialized", "true") // set that settings exists
190- Settings.setSetting("shuffle", "false") // set to not shuffle as default
191- Settings.setSetting("scrobble", "false") // no scrobble yet
192- Settings.setSetting("currentfolder", "/") // Music dir
193- // show dialog so that user can set the music dir manually, untill later
194- PopupUtils.open(Qt.resolvedUrl("FirstRun.qml"), pageLayout,
195- {
196- title: i18n.tr("First Run")
197- } )
198- }
199-
200- // Run as usual
201- else {
202- musicDir = Settings.getSetting("currentfolder")
203- shuffleState = Settings.getSetting("shuffle")
204- console.debug("Debug: Music dir set to: "+musicDir)
205- console.debug("Debug: Shuffle state is: "+shuffleState)
206- //console.debug("Debug: Scrobble state is: "+scrobbleState)
207- }
208-
209- // then go on to meta data db
210- MetaDB.initialize() // also create the metaDB
211- console.debug("INITIALIZED Meta data")
212- /*
213- if (Settings.getSetting("initialized") !== "true") {
214- // start adding tracks to db
215- title = getTrackInfo(file, title)
216- album = getTrackInfo(file, album)
217- year = getTrackInfo(file, year)
218- tracknr = getTrackInfo(file, tracknr)
219- length = getTrackInfo(file, length)
220- console.debug("file", "title", "artist", "album", "year", "tracknr", "length")
221- //MetaDB.setSetting("file", "title", "artist", "album", "year", "tracknr", "length")
222- }*/
223- }
224-
225-
226- width: units.gu(50)
227- height: units.gu(75)
228-
229- Page {
230- id: singleTracksPage
231-
232- // toolbar
233- tools: defaultToolbar
234-
235- Column {
236- anchors.centerIn: parent
237+ Settings.setSetting("initialized", "true")
238+ Settings.setSetting("currentfolder", folderModel.homePath() + "/Music")
239+ }
240+ random = Settings.getSetting("shuffle") == "1"
241+ filelist.currentIndex = -1
242+ }
243+
244+ Page {
245+ id: mainpage
246+
247+ title: i18n.tr("Music")
248+
249+ Component {
250+ id: highlight
251+ Rectangle {
252+ width: 5; height: 40
253+ color: "#DD4814";
254+ Behavior on y {
255+ SpringAnimation {
256+ spring: 3
257+ damping: 0.2
258+ }
259+ }
260+ }
261+ }
262+
263+ ListView {
264+ id: filelist
265+ width: parent.width
266+ height: parent.height - units.gu(8)
267+ anchors.top: tracksContext.bottom
268+ highlight: highlight
269+ highlightFollowsCurrentItem: true
270+ model: folderModel
271+ delegate: fileDelegate
272+ onCountChanged: {
273+ filelistCount = filelist.count
274+ }
275+ onCurrentIndexChanged: {
276+ filelistCurrentIndex = filelist.currentIndex
277+ console.log("filelist.currentIndex = " + filelist.currentIndex)
278+ }
279+
280+ Component {
281+ id: fileDelegate
282+ ListItem.Standard {
283+ id: file
284+ progression: model.isDir
285+ icon: !model.isDir ? (trackCover === "" ? (fileName.match("\\.mp3") ? Qt.resolvedUrl("images/audio-x-mpeg.png") : Qt.resolvedUrl("images/audio-x-vorbis+ogg.png")) : "image://cover-art/"+filePath) : Qt.resolvedUrl("images/folder.png")
286+ iconFrame: false
287+ Label {
288+ id: fileTitle
289+ width: 400
290+ wrapMode: Text.Wrap
291+ maximumLineCount: 1
292+ font.pixelSize: 16
293+ anchors.left: parent.left
294+ anchors.leftMargin: 75
295+ anchors.top: parent.top
296+ anchors.topMargin: 5
297+ text: trackTitle == "" ? fileName : trackTitle
298+ }
299+ Label {
300+ id: fileArtistAlbum
301+ width: 400
302+ wrapMode: Text.Wrap
303+ maximumLineCount: 2
304+ font.pixelSize: 12
305+ anchors.left: parent.left
306+ anchors.leftMargin: 75
307+ anchors.top: fileTitle.bottom
308+ text: trackArtist == "" ? "" : trackArtist + " - " + trackAlbum
309+ }
310+ Label {
311+ id: fileDuration
312+ width: 400
313+ wrapMode: Text.Wrap
314+ maximumLineCount: 2
315+ font.pixelSize: 12
316+ anchors.left: parent.left
317+ anchors.leftMargin: 75
318+ anchors.top: fileArtistAlbum.bottom
319+ visible: false
320+ text: ""
321+ }
322+
323+ onFocusChanged: {
324+ if (focus == false) {
325+ selected = false
326+ } else if (file.progression == false){
327+ selected = false
328+ fileArtistAlbumBottom.text = fileArtistAlbum.text
329+ fileTitleBottom.text = fileTitle.text
330+ fileArtistAlbumBottom_nowplaying.text = trackArtist == "" ? "" : trackArtist + "\n" + trackAlbum
331+ fileTitleBottom_nowplaying.text = fileTitle.text
332+ iconbottom.source = file.icon
333+ iconbottom_nowplaying.source = !model.isDir && trackCover !== "" ? "image://cover-art-full/" + filePath : "images/Blank_album.jpg"
334+ }
335+ }
336+ MouseArea {
337+ anchors.fill: parent
338+ onDoubleClicked: {
339+ }
340+ onPressAndHold: {
341+ if (!model.isDir) {
342+ trackQueue.append({"title": trackTitle, "artist": trackArtist, "file": filePath})
343+ }
344+ }
345+ onClicked: {
346+ if (focus == false) {
347+ focus = true
348+ }
349+ if (model.isDir) {
350+ PlayingList.clear()
351+ filelist.currentIndex = -1
352+ itemnum = 0
353+ playing = filelist.currentIndex
354+ console.log("Stored:" + Settings.getSetting("currentfolder"))
355+ folderModel.path = filePath
356+ } else {
357+ console.log("fileName: " + fileName)
358+ if (filelist.currentIndex == index) {
359+ if (player.playbackState === MediaPlayer.PlayingState) {
360+ playindicator.source = "images/play.png"
361+ player.pause()
362+ } else if (player.playbackState === MediaPlayer.PausedState) {
363+ playindicator.source = "images/pause.png"
364+ player.play()
365+ }
366+ } else {
367+ player.stop()
368+ player.source = Qt.resolvedUrl(filePath)
369+ filelist.currentIndex = index
370+ playing = PlayingList.indexOf(filePath)
371+ console.log("Playing click: "+player.source)
372+ console.log("Index: " + filelist.currentIndex)
373+ player.play()
374+ playindicator.source = "images/pause.png"
375+ }
376+ console.log("Source: " + player.source.toString())
377+ console.log("Length: " + trackLength.toString())
378+ }
379+ playindicator_nowplaying.source = playindicator.source
380+ }
381+ }
382+ Component.onCompleted: {
383+ if (!PlayingList.contains(filePath) && !model.isDir) {
384+ console.log("Adding file:" + filePath)
385+ PlayingList.addItem(filePath, itemnum)
386+ console.log(itemnum)
387+ }
388+ itemnum++
389+ }
390+ }
391+ }
392+ }
393+
394+ // context: albums? tracks?
395+ Rectangle {
396+ id: appContext
397+ anchors.top: mainpage.top
398+ height: units.gu(5)
399+ width: parent.width
400+ color: "#333333"
401+ MouseArea {
402+ id: tracksContextArea
403+ anchors.verticalCenter: parent.verticalCenter
404+ anchors.left: parent.left
405+ width: units.gu(10)
406+ height: units.gu(5)
407+ onClicked: {
408+ tracksContext.font.underline = true
409+ artistsContext.font.underline = false
410+ albumsContext.font.underline = false
411+ listsContext.font.underline = false
412+ }
413+ Label {
414+ id: tracksContext
415+ width: units.gu(15)
416+ wrapMode: Text.Wrap
417+ color: "#FFFFFF"
418+ maximumLineCount: 1
419+ font.pixelSize: 20
420+ anchors.verticalCenter: parent.verticalCenter
421+ anchors.left: parent.left
422+ anchors.leftMargin: units.gu(1)
423+ text: "Music"
424+ font.underline: true
425+ }
426+ }
427+ MouseArea {
428+ id: artistsContextArea
429+ anchors.verticalCenter: parent.verticalCenter
430+ anchors.left: tracksContextArea.right
431+ width: units.gu(10)
432+ height: units.gu(5)
433+ onClicked: {
434+ tracksContext.font.underline = false
435+ artistsContext.font.underline = true
436+ albumsContext.font.underline = false
437+ listsContext.font.underline = false
438+ }
439+ Label {
440+ id: artistsContext
441+ width: units.gu(10)
442+ wrapMode: Text.Wrap
443+ color: "#FFFFFF"
444+ maximumLineCount: 1
445+ font.pixelSize: 20
446+ anchors.verticalCenter: parent.verticalCenter
447+ anchors.left: parent.left
448+ text: "Artists"
449+ }
450+ }
451+ MouseArea {
452+ id: albumsContextArea
453+ anchors.verticalCenter: parent.verticalCenter
454+ anchors.left: artistsContextArea.right
455+ width: units.gu(10)
456+ height: units.gu(5)
457+ onClicked: {
458+ tracksContext.font.underline = false
459+ artistsContext.font.underline = false
460+ albumsContext.font.underline = true
461+ listsContext.font.underline = false
462+ }
463+ Label {
464+ id: albumsContext
465+ width: units.gu(15)
466+ wrapMode: Text.Wrap
467+ color: "#FFFFFF"
468+ maximumLineCount: 1
469+ font.pixelSize: 20
470+ anchors.verticalCenter: parent.verticalCenter
471+ anchors.left: parent.left
472+ text: "Albums"
473+ }
474+ }
475+ MouseArea {
476+ id: listsContextArea
477+ anchors.verticalCenter: parent.verticalCenter
478+ anchors.left: albumsContextArea.right
479+ width: units.gu(10)
480+ height: units.gu(5)
481+ onClicked: {
482+
483+ PopupUtils.open(Qt.resolvedUrl("QueueDialog.qml"), settingsArea,
484+ {
485+ title: i18n.tr("Queue")
486+ } )
487+ }
488+ Label {
489+ id: listsContext
490+ width: units.gu(15)
491+ wrapMode: Text.Wrap
492+ color: "#FFFFFF"
493+ maximumLineCount: 1
494+ font.pixelSize: 20
495+ anchors.verticalCenter: parent.verticalCenter
496+ anchors.left: parent.left
497+ text: "Queue"
498+ }
499+ }
500+ MouseArea {
501+ id: settingsArea
502+ anchors.verticalCenter: parent.verticalCenter
503+ anchors.left: listsContextArea.right
504+ anchors.right: parent.right
505+ height: units.gu(5)
506+ onClicked: {
507+ PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), settingsArea,
508+ {
509+ title: i18n.tr("Settings")
510+ } )
511+ }
512+ Image {
513+ id: settingsImage
514+ source: "images/settings.png"
515+ anchors.left: parent.left
516+ anchors.verticalCenter: parent.verticalCenter
517+ anchors.leftMargin: units.gu(1)
518+ }
519+ }
520+
521+ }
522+
523+ Rectangle {
524+ id: playerControls
525+ anchors.top: filelist.bottom
526+ height: units.gu(8)
527+ width: parent.width
528+ color: "#333333"
529+ UbuntuShape {
530+ id: forwardshape
531+ height: units.gu(5)
532+ width: units.gu(5)
533+ anchors.verticalCenter: parent.verticalCenter
534+ anchors.right: parent.right
535+ anchors.rightMargin: units.gu(2)
536+ radius: "none"
537+ image: Image {
538+ id: forwardindicator
539+ source: "images/forward.png"
540+ anchors.right: parent.right
541+ anchors.centerIn: parent
542+ opacity: .7
543+ }
544+ MouseArea {
545+ anchors.fill: parent
546+ onClicked: {
547+ playindicator.source = "images/pause.png"
548+ playindicator_nowplaying.source = playindicator.source
549+ nextSong()
550+ }
551+ }
552+ }
553+ UbuntuShape {
554+ id: playshape
555+ height: units.gu(5)
556+ width: units.gu(5)
557+ anchors.verticalCenter: parent.verticalCenter
558+ anchors.right: forwardshape.left
559+ anchors.rightMargin: units.gu(1)
560+ radius: "none"
561+ image: Image {
562+ id: playindicator
563+ source: "images/play.png"
564+ anchors.right: parent.right
565+ anchors.centerIn: parent
566+ opacity: .7
567+ }
568+ MouseArea {
569+ anchors.fill: parent
570+ onClicked: {
571+ if (player.playbackState === MediaPlayer.PlayingState) {
572+ playindicator.source = "images/play.png"
573+ player.pause()
574+ } else {
575+ playindicator.source = "images/pause.png"
576+ player.play()
577+ }
578+ playindicator_nowplaying.source = playindicator.source
579+ }
580+ }
581+ }
582+ Image {
583+ id: iconbottom
584+ source: ""
585+ anchors.left: parent.left
586+ anchors.top: parent.top
587+ anchors.topMargin: units.gu(1)
588+ anchors.leftMargin: units.gu(1)
589+
590+ MouseArea {
591+ anchors.fill: parent
592+ onClicked: {
593+ pageStack.push(nowPlaying)
594+ }
595+ }
596+ }
597+ Label {
598+ id: fileTitleBottom
599+ width: units.gu(30)
600+ wrapMode: Text.Wrap
601+ color: "#FFFFFF"
602+ maximumLineCount: 1
603+ font.pixelSize: 16
604+ anchors.left: iconbottom.right
605+ anchors.top: parent.top
606+ anchors.topMargin: units.gu(1)
607+ anchors.leftMargin: units.gu(1)
608+ text: ""
609+ }
610+ Label {
611+ id: fileArtistAlbumBottom
612+ width: units.gu(30)
613+ wrapMode: Text.Wrap
614+ color: "#FFFFFF"
615+ maximumLineCount: 1
616+ font.pixelSize: 12
617+ anchors.left: iconbottom.right
618+ anchors.top: fileTitleBottom.bottom
619+ anchors.leftMargin: units.gu(1)
620+ text: ""
621+ }
622+ Rectangle {
623+ id: fileDurationProgressContainer
624+ anchors.top: fileArtistAlbumBottom.bottom
625+ anchors.left: iconbottom.right
626+ anchors.topMargin: 2
627+ anchors.leftMargin: units.gu(1)
628+ width: units.gu(20)
629+ color: "#333333"
630+
631+ Rectangle {
632+ id: fileDurationProgressBackground
633+ anchors.top: parent.top
634+ anchors.topMargin: 2
635+ height: 1
636+ width: units.gu(20)
637+ color: "#FFFFFF"
638+ visible: false
639+ }
640+ Rectangle {
641+ id: fileDurationProgress
642+ anchors.top: parent.top
643+ height: 5
644+ width: 0
645+ color: "#DD4814"
646+ }
647+ }
648+ Label {
649+ id: fileDurationBottom
650+ anchors.top: fileArtistAlbumBottom.bottom
651+ anchors.left: fileDurationProgressContainer.right
652+ anchors.leftMargin: units.gu(1)
653+ width: units.gu(30)
654+ wrapMode: Text.Wrap
655+ color: "#FFFFFF"
656+ maximumLineCount: 1
657+ font.pixelSize: 12
658+ text: ""
659+ }
660+ }
661+ }
662+
663+ Page {
664+ id: nowPlaying
665+ visible: false
666+
667+ Rectangle {
668 anchors.fill: parent
669- ListView {
670- id: musicFolder
671- width: parent.width
672- height: parent.height
673- model: folderModel
674- //delegate: databaseDelegate
675- delegate: ListItem.Subtitled {
676- text: fileName
677- subText: "Artist: " // this should be selected from metaDB
678- Loader {
679- id: trackLoad
680- //onLoaded:
681- Component.onCompleted: {
682- console.debug("This one was found: "+index+"; "+fileName)
683- trackQueue.append({"title": playMusic.metaData.title, "artist": playMusic.metaData.albumArtist, "file": filePath}) // just for dev
684- /* Insert them to database
685- // start adding tracks to db
686- title = getTrackInfo(file, title)
687- album = getTrackInfo(file, album)
688- year = getTrackInfo(file, year)
689- tracknr = getTrackInfo(file, tracknr)
690- length = getTrackInfo(file, length)
691- console.debug("file", "title", "artist", "album", "year", "tracknr", "length")
692- //MetaDB.setSetting("file", "title", "artist", "album", "year", "tracknr", "length")
693- */
694+ height: units.gu(10)
695+ color: "#333333"
696+ Column {
697+ anchors.fill: parent
698+ anchors.bottomMargin: units.gu(10)
699+
700+ UbuntuShape {
701+ id: forwardshape_nowplaying
702+ height: 50
703+ width: 50
704+ anchors.bottom: parent.bottom
705+ anchors.left: playshape_nowplaying.right
706+ anchors.leftMargin: units.gu(2)
707+ radius: "none"
708+ image: Image {
709+ id: forwardindicator_nowplaying
710+ source: "images/forward.png"
711+ anchors.right: parent.right
712+ anchors.bottom: parent.bottom
713+ opacity: .7
714+ }
715+ MouseArea {
716+ anchors.fill: parent
717+ onClicked: {
718+ playindicator.source = "images/pause.png"
719+ playindicator_nowplaying.source = playindicator.source
720+ nextSong()
721+ }
722+ }
723+ }
724+ UbuntuShape {
725+ id: playshape_nowplaying
726+ height: 50
727+ width: 50
728+ anchors.bottom: parent.bottom
729+ anchors.horizontalCenter: parent.horizontalCenter
730+ radius: "none"
731+ image: Image {
732+ id: playindicator_nowplaying
733+ source: "images/play.png"
734+ anchors.right: parent.right
735+ anchors.bottom: parent.bottom
736+ opacity: .7
737+ }
738+ MouseArea {
739+ anchors.fill: parent
740+ onClicked: {
741+ if (player.playbackState === MediaPlayer.PlayingState) {
742+ playindicator.source = "images/play.png"
743+ player.pause()
744+ } else {
745+ playindicator.source = "images/pause.png"
746+ player.play()
747 }
748- }
749-
750- onClicked: {
751- playMusic.source = filePath
752- playMusic.play()
753- console.debug('Debug: User pressed '+filePath)
754- trackInfo.text = playMusic.metaData.albumArtist+" - "+playMusic.metaData.title // show track meta data
755- // cool animation
756- }
757- onPressAndHold: {
758- console.debug('Debug: '+filePath+' added to queue.')
759- trackQueue.append({"title": playMusic.metaData.title, "artist": playMusic.metaData.albumArtist, "file": filePath})
760- // cool animation
761- }
762+ playindicator_nowplaying.source = playindicator.source
763+ }
764+ }
765+ }
766+ UbuntuShape {
767+ id: backshape_nowplaying
768+ height: 50
769+ width: 50
770+ anchors.bottom: parent.bottom
771+ anchors.right: playshape_nowplaying.left
772+ anchors.rightMargin: units.gu(2)
773+ radius: "none"
774+ image: Image {
775+ id: backindicator_nowplaying
776+ source: "images/back.png"
777+ anchors.right: parent.right
778+ anchors.bottom: parent.bottom
779+ opacity: .7
780+ }
781+ MouseArea {
782+ anchors.fill: parent
783+ onClicked: {
784+ playindicator.source = "images/pause.png"
785+ playindicator_nowplaying.source = playindicator.source
786+ getSong(-1)
787+ }
788+ }
789+ }
790+
791+ Image {
792+ id: iconbottom_nowplaying
793+ source: ""
794+ width: 300
795+ height: 300
796+ anchors.horizontalCenter: parent.horizontalCenter
797+ anchors.top: parent.top
798+ anchors.topMargin: units.gu(1)
799+ anchors.leftMargin: units.gu(1)
800+
801+ MouseArea {
802+ anchors.fill: parent
803+ onClicked: {
804+ pageStack.pop(nowPlaying)
805+ }
806+ }
807+ }
808+ Label {
809+ id: fileTitleBottom_nowplaying
810+ width: units.gu(30)
811+ wrapMode: Text.Wrap
812+ color: "#FFFFFF"
813+ maximumLineCount: 1
814+ font.pixelSize: 24
815+ anchors.top: iconbottom_nowplaying.bottom
816+ anchors.topMargin: units.gu(2)
817+ anchors.left: parent.left
818+ anchors.leftMargin: units.gu(2)
819+ text: ""
820+ }
821+ Label {
822+ id: fileArtistAlbumBottom_nowplaying
823+ width: units.gu(30)
824+ wrapMode: Text.Wrap
825+ color: "#FFFFFF"
826+ maximumLineCount: 2
827+ font.pixelSize: 16
828+ anchors.left: parent.left
829+ anchors.top: fileTitleBottom_nowplaying.bottom
830+ anchors.leftMargin: units.gu(2)
831+ text: ""
832+ }
833+ Rectangle {
834+ id: fileDurationProgressContainer_nowplaying
835+ anchors.top: fileArtistAlbumBottom_nowplaying.bottom
836+ anchors.left: parent.left
837+ anchors.topMargin: units.gu(2)
838+ anchors.leftMargin: units.gu(2)
839+ width: units.gu(40)
840+ color: "#333333"
841+
842+ Rectangle {
843+ id: fileDurationProgressBackground_nowplaying
844+ anchors.top: parent.top
845+ anchors.topMargin: 4
846+ height: 1
847+ width: units.gu(40)
848+ color: "#FFFFFF"
849+ visible: false
850+ }
851+ Rectangle {
852+ id: fileDurationProgress_nowplaying
853+ anchors.top: parent.top
854+ height: 8
855+ width: 0
856+ color: "#DD4814"
857+ }
858+ }
859+ Label {
860+ id: fileDurationBottom_nowplaying
861+ anchors.top: fileDurationProgressContainer_nowplaying.bottom
862+ anchors.left: parent.left
863+ anchors.topMargin: units.gu(2)
864+ anchors.leftMargin: units.gu(2)
865+ width: units.gu(30)
866+ wrapMode: Text.Wrap
867+ color: "#FFFFFF"
868+ maximumLineCount: 1
869+ font.pixelSize: 16
870+ text: ""
871 }
872 }
873 }
874-
875 }
876-
877 }
878
879=== modified file 'QueueDialog.qml'
880--- QueueDialog.qml 2013-05-31 14:58:23 +0000
881+++ QueueDialog.qml 2013-06-05 04:48:28 +0000
882@@ -3,6 +3,7 @@
883 *
884 * Authors:
885 * Daniel Holm <d.holmen@gmail.com>
886+ * Victor Thompson <victor.thompson@gmail.com>
887 *
888 * This program is free software; you can redistribute it and/or modify
889 * it under the terms of the GNU General Public License as published by
890@@ -32,8 +33,7 @@
891 height: units.gu(50)
892 model: trackQueue
893 delegate: ListItem.Standard {
894- //text: artist+" - "+title
895- text: file
896+ text: artist+" - "+title
897 removable: true
898 onClicked: {
899 console.debug("Debug: Play "+file+" instead - now.")
900@@ -50,7 +50,7 @@
901 // Clean whole queue button
902 Button {
903 text: i18n.tr("Clear")
904- color: "orange"
905+ color: "#DD4814"
906 onClicked: {
907 console.debug("Debug: Track queue cleared.")
908 trackQueue.clear()
909@@ -61,7 +61,7 @@
910 // close dialog button
911 Button {
912 text: i18n.tr("Close")
913- color: "red"
914+ color: "#DD4814"
915 onClicked: {
916 PopupUtils.close(queueDialog)
917 }
918
919=== removed file 'Toolbar.qml'
920--- Toolbar.qml 2013-05-08 21:53:49 +0000
921+++ Toolbar.qml 1970-01-01 00:00:00 +0000
922@@ -1,103 +0,0 @@
923-/*
924- * Copyleft Daniel Holm.
925- *
926- * Authors:
927- * Daniel Holm <d.holmen@gmail.com>
928- *
929- * This program is free software; you can redistribute it and/or modify
930- * it under the terms of the GNU General Public License as published by
931- * the Free Software Foundation; version 3.
932- *
933- * This program is distributed in the hope that it will be useful,
934- * but WITHOUT ANY WARRANTY; without even the implied warranty of
935- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
936- * GNU General Public License for more details.
937- *
938- * You should have received a copy of the GNU General Public License
939- * along with this program. If not, see <http://www.gnu.org/licenses/>.
940- */
941-
942-import QtQuick 2.0
943-import Ubuntu.Components 0.1
944-import Ubuntu.Components.ListItems 0.1 as ListItem
945-import Ubuntu.Components.Popups 0.1
946-
947-Component {
948- // Share
949- Action {
950- id: shareTrack
951- objectName: "share"
952-
953- iconSource: Qt.resolvedUrl("images/icon_share@20.png")
954- text: i18n.tr("Share")
955-
956- onTriggered: {
957- console.debug('Debug: Share pressed')
958- }
959- }
960-
961- // prevous track
962- Action {
963- id: prevTrack
964- objectName: "prev"
965-
966- iconSource: Qt.resolvedUrl("images/prev.png")
967- text: i18n.tr("Previous")
968-
969- onTriggered: {
970- console.debug('Debug: Prev track pressed')
971- }
972- }
973-
974- // Play
975- Action {
976- id: playTrack
977- objectName: "play"
978-
979- iconSource: Qt.resolvedUrl("images/icon_play@20.png")
980- text: i18n.tr("Play")
981-
982- onTriggered: {
983- //trackStatus: 'pause' // this changes on press
984- onTrackStatusChange(playTrack.text)
985- }
986- }
987-
988- // Next track
989- Action {
990- id: nextTrack
991- objectName: "next"
992-
993- iconSource: Qt.resolvedUrl("images/next.png")
994- text: i18n.tr("Next")
995-
996- onTriggered: {
997- console.debug('Debug: next track pressed')
998- }
999- }
1000-
1001- // Queue
1002- Action {
1003- id: trackQueue
1004- objectName: "queuelist"
1005- iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
1006- text: i18n.tr("Queue")
1007- onTriggered: {
1008- PopupUtils.open(queueDialog, trackQueue)
1009- }
1010- }
1011-
1012- // Settings
1013- Action {
1014- objectName: "settings"
1015-
1016- iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
1017- text: i18n.tr("Settings")
1018-
1019- onTriggered: {
1020- console.debug('Debug: Settings pressed')
1021- // show settings page
1022- //page: MusicSettings { id: musicSettings }
1023- }
1024- }
1025-}
1026
1027=== modified file 'debian/changelog'
1028--- debian/changelog 2013-06-01 01:05:45 +0000
1029+++ debian/changelog 2013-06-05 04:48:28 +0000
1030@@ -1,5 +1,11 @@
1031+music-app (0.2) raring; urgency=low
1032+
1033+ * Merge of Daniel's and Victor's code
1034+
1035+ -- Victor Thompson <victor.thompson@gmail.com> Tue, 04 June 2013 11:45:00 -0400
1036+
1037 music-app (0.1) raring; urgency=low
1038
1039 * Initial Release.
1040
1041- -- "Michael <mhall119@ubuntu.com> Thu, 23 May 2013 17:10:45 -0400
1042+ -- Michael <mhall119@ubuntu.com> Thu, 23 May 2013 17:10:45 -0400
1043
1044=== modified file 'debian/install'
1045--- debian/install 2013-06-03 17:43:53 +0000
1046+++ debian/install 2013-06-05 04:48:28 +0000
1047@@ -1,4 +1,3 @@
1048-Toolbar.qml /usr/share/music-app
1049 MusicSettings.qml /usr/share/music-app
1050 music-app.qml /usr/share/music-app
1051 QueueDialog.qml /usr/share/music-app
1052@@ -16,5 +15,14 @@
1053 images/icon_settings@20.png /usr/share/music-app
1054 images/music.png /usr/share/music-app
1055 images/icon_play@20.png /usr/share/music-app
1056+images/settings@8.png /usr/share/music-app
1057+images/play.png /usr/share/music-app
1058+images/pause.png /usr/share/music-app
1059+images/forward.png /usr/share/music-app
1060+images/Blank_album.jpg /usr/share/music-app
1061+images/back.png /usr/share/music-app
1062+images/audio-x-mpeg.png /usr/share/music-app
1063+images/audio-x-vorbis+ogg.png /usr/share/music-app
1064+playing-list.js /usr/share/music-app
1065 meta-database.js /usr/share/music-app
1066 music-app.desktop /usr/share/applications
1067
1068=== added file 'images/Blank_album.jpg'
1069Binary files images/Blank_album.jpg 1970-01-01 00:00:00 +0000 and images/Blank_album.jpg 2013-06-05 04:48:28 +0000 differ
1070=== added file 'images/audio-x-mpeg.png'
1071Binary files images/audio-x-mpeg.png 1970-01-01 00:00:00 +0000 and images/audio-x-mpeg.png 2013-06-05 04:48:28 +0000 differ
1072=== added file 'images/audio-x-vorbis+ogg.png'
1073Binary files images/audio-x-vorbis+ogg.png 1970-01-01 00:00:00 +0000 and images/audio-x-vorbis+ogg.png 2013-06-05 04:48:28 +0000 differ
1074=== added file 'images/back.png'
1075Binary files images/back.png 1970-01-01 00:00:00 +0000 and images/back.png 2013-06-05 04:48:28 +0000 differ
1076=== added file 'images/forward.png'
1077Binary files images/forward.png 1970-01-01 00:00:00 +0000 and images/forward.png 2013-06-05 04:48:28 +0000 differ
1078=== added file 'images/pause.png'
1079Binary files images/pause.png 1970-01-01 00:00:00 +0000 and images/pause.png 2013-06-05 04:48:28 +0000 differ
1080=== added file 'images/play.png'
1081Binary files images/play.png 1970-01-01 00:00:00 +0000 and images/play.png 2013-06-05 04:48:28 +0000 differ
1082=== added file 'images/settings@8.png'
1083Binary files images/settings@8.png 1970-01-01 00:00:00 +0000 and images/settings@8.png 2013-06-05 04:48:28 +0000 differ
1084=== modified file 'music-app.qml'
1085--- music-app.qml 2013-06-03 17:43:53 +0000
1086+++ music-app.qml 2013-06-05 04:48:28 +0000
1087@@ -3,6 +3,7 @@
1088 *
1089 * Authors:
1090 * Daniel Holm <d.holmen@gmail.com>
1091+ * Victor Thompson <victor.thompson@gmail.com>
1092 *
1093 * This program is free software; you can redistribute it and/or modify
1094 * it under the terms of the GNU General Public License as published by
1095@@ -22,11 +23,12 @@
1096 import Ubuntu.Components.ListItems 0.1
1097 import Ubuntu.Components.Popups 0.1
1098 import Ubuntu.Components.ListItems 0.1 as ListItem
1099-import Qt.labs.folderlistmodel 1.0
1100+import org.nemomobile.folderlistmodel 1.0
1101 import QtMultimedia 5.0
1102 import QtQuick.LocalStorage 2.0
1103 import "settings.js" as Settings
1104-import "meta-database.js" as MetaDatabase
1105+import "meta-database.js" as Library
1106+import "playing-list.js" as PlayingList
1107
1108 MainView {
1109 objectName: i18n.tr("mainView")
1110@@ -34,156 +36,76 @@
1111
1112 width: units.gu(50)
1113 height: units.gu(75)
1114+ Component.onCompleted: {
1115+ header.visible = false
1116+ }
1117+
1118
1119 // VARIABLES
1120 property string musicName: i18n.tr("Music")
1121 property string musicDir: ""
1122- property string shuffleState: ""
1123- property string trackStatus: "stopped"
1124 property string appVersion: '0.5.2'
1125+ property int playing: 0
1126+ property int itemnum: 0
1127+ property bool random: false
1128+ property string artist
1129+ property string album
1130+ property string song
1131+ property string tracktitle
1132
1133 // FUNCTIONS
1134-
1135- // digg deeper in the music folder
1136- function subDirCheck(directory) {
1137- // populate listmodel with meta data of tracks
1138- }
1139-
1140- // What is the state of the playback?
1141- function stateChange() {
1142- // state was stopped (0)
1143- if (playMusic.playbackState == "0") {
1144- console.debug("Debug: Music was stopped. Playing")
1145- beenStopped() // run stop function
1146- playMusic.play() // then play
1147- }
1148-
1149- // if state was playing (1)
1150- else if (playMusic.playbackState == "1") {
1151- console.debug("Debug: Track was playing. Pause")
1152- playMusic.pause() // pause the music then
1153- }
1154-
1155- // if state is paused (2)
1156- else if (playMusic.playbackState == "2") {
1157- console.debug("Debug: Track was paused. Playing")
1158- playMusic.play() // resume then
1159- }
1160-
1161- updateUI()
1162- }
1163-
1164- // stop function
1165- function beenStopped() {
1166- console.debug("Debug: has a track been played before or did I just start?")
1167-
1168- // track was just paused or stopped. Resume previous track
1169- if (playMusic.source != "") {
1170- console.debug("Debug: Resume previous song: "+playMusic.source)
1171-
1172- updateUI()
1173- }
1174-
1175- // app just started, play random or first track in list, depending on shuffle on or off
1176- else {
1177- // is shuffle on?
1178- // if shuffle on {
1179- //}
1180- // Shuffle not activated
1181- //else {
1182- playMusic.source = trackQueue.get(0).file // this should play a dynamic track
1183- console.debug("Debug: First song is "+trackQueue.get(0).file)
1184- console.debug("Debug: I was just started. Play random track: "+playMusic.source)
1185-
1186- updateUI()
1187- //}
1188- }
1189- }
1190-
1191- // previous and next track function
1192- function nextTrack() {
1193- //check if any queued songs
1194- // if there are, play them
1195- if (trackQueue > 1) {
1196- console.debug() // print next songs filename
1197- playMusic.source = trackQueue.get(0).file
1198- playMusic.play()
1199- removedTrackQueue.append({"title": trackQueue.get(0).title, "artist": trackQueue.get(0).artist, "file": trackQueue.get(0).file}) // move the track to a list of preious tracks
1200- trackQueue.remove(index) // remove the track from queue
1201-
1202- updateUI()
1203- }
1204-
1205- // if not, play another
1206- else {
1207-
1208- // if shuffle, play random
1209- if (settings.shuffle == 1) {
1210- updateUI()
1211- }
1212-
1213- // if not shuffle, play next
1214- else {
1215- console.debug() // print next songs filename
1216- playMusic.source = trackQueue.get(0).file
1217- playMusic.play()
1218- removedTrackQueue.append({"title": trackQueue.get(0).title, "artist": trackQueue.get(0).artist, "file": trackQueue.get(0).file}) // move the track to a list of preious tracks
1219- trackQueue.remove(index) // remove the track from queue
1220-
1221- updateUI()
1222- }
1223- }
1224- }
1225-
1226- function previousTrack() {
1227- console.debug("Debug: Previous track was "+removedTrackQueue.get(removedTrackQueue.count).file)
1228- // play the previous track
1229- playMusic.source = removedTrackQueue.get(removedTrackQueue.count).file
1230- playMusic.play()
1231-
1232- updateUI()
1233- }
1234-
1235- // Get song title
1236- function getTrackInfo(source, type) {
1237- console.debug('Debug: Got it. Trying to get meta data from: '+source) // debug
1238- musicInfo.source = source
1239- musicInfo.pause()
1240-
1241- // if title
1242- if (type == "title") {
1243- return musicInfo.metaData.title
1244- }
1245-
1246- // if artist
1247- else if (type == "artist") {
1248- return musicInfo.metaData.albumArtist
1249- }
1250-
1251- // if album
1252- else if (type == "album") {
1253- return musicInfo.metaData.albumTitle
1254- }
1255-
1256- // year
1257- else if (type == "year") {
1258- return musicInfo.metaData.year
1259- }
1260-
1261- // cover
1262- else if (type == "cover") {
1263- // download cover art from last.fm
1264- // save the file in a app dir in HOME
1265- // return the value of the cover art file
1266- }
1267-
1268- // tracknr
1269- else if (type == "tracknr") {
1270- }
1271-
1272- // lenght
1273- else if (type == "length") {
1274- }
1275+ function previousSong() {
1276+ getSong(-1)
1277+ }
1278+ function nextSong() {
1279+ getSong(1)
1280+ }
1281+
1282+ function getSong(direction) {
1283+ if (random) {
1284+ var now = new Date();
1285+ var seed = now.getSeconds();
1286+ do {
1287+ var num = (Math.floor((PlayingList.size()) * Math.random(seed)));
1288+ console.log(num)
1289+ console.log(playing)
1290+ } while (num == playing && PlayingList.size() > 0)
1291+ player.source = Qt.resolvedUrl(PlayingList.getList()[num])
1292+ musicTracksPage.filelistCurrentIndex = PlayingList.at(num)
1293+ playing = num
1294+ console.log("MediaPlayer statusChanged, currentIndex: " + musicTracksPage.filelistCurrentIndex)
1295+ } else {
1296+ if ((playing < PlayingList.size() - 1 && direction === 1 )
1297+ || (playing > 0 && direction === -1)) {
1298+ console.log("playing: " + playing)
1299+ console.log("filelistCount: " + musicTracksPage.filelistCount)
1300+ console.log("PlayingList.size(): " + PlayingList.size())
1301+ playing += direction
1302+ if (playing === 0) {
1303+ musicTracksPage.filelistCurrentIndex = playing + (itemnum - PlayingList.size())
1304+ } else {
1305+ musicTracksPage.filelistCurrentIndex += direction
1306+ }
1307+ player.source = Qt.resolvedUrl(PlayingList.getList()[playing])
1308+ } else if(direction === 1) {
1309+ console.log("playing: " + playing)
1310+ console.log("filelistCount: " + musicTracksPage.filelistCount)
1311+ console.log("PlayingList.size(): " + PlayingList.size())
1312+ playing = 0
1313+ musicTracksPage.filelistCurrentIndex = playing + (musicTracksPage.filelistCount - PlayingList.size())
1314+ player.source = Qt.resolvedUrl(PlayingList.getList()[playing])
1315+ } else if(direction === -1) {
1316+ console.log("playing: " + playing)
1317+ console.log("filelistCount: " + musicTracksPage.filelistCount)
1318+ console.log("PlayingList.size(): " + PlayingList.size())
1319+ playing = PlayingList.size() - 1
1320+ musicTracksPage.filelistCurrentIndex = playing + (musicTracksPage.filelistCount - PlayingList.size())
1321+ player.source = Qt.resolvedUrl(PlayingList.getList()[playing])
1322+ }
1323+ console.log("MediaPlayer statusChanged, currentIndex: " + musicTracksPage.filelistCurrentIndex)
1324+ }
1325+ console.log("Playing: "+player.source)
1326+ player.play()
1327 }
1328
1329 // add track to database
1330@@ -198,67 +120,30 @@
1331 //length =
1332
1333 // push to database
1334- MetaDatabase.setMetadata(track, title, artist, album, cover, year, tracknr, length)
1335- }
1336-
1337- // progressbar
1338- function setProgressbar() {
1339- console.debug("Debug: change progressvalue to "+playMusic.duration)
1340- trackProgress.maximumValue = playMusic.duration
1341- }
1342-
1343- // update the UI things with meta data from track
1344- function updateUI() {
1345- playinTab.title = playMusic.metaData.title // show track title in tab header
1346- playTrack.iconSource = Qt.resolvedUrl("images/icon_pause@20.png") // change toolbar icon
1347- playTrack.text = i18n.tr("Pause") // change toolbar text
1348- trackInfo.text = playMusic.metaData.albumArtist+" - "+playMusic.metaData.title // show track meta data
1349-// coverArt.source = "HOMEDIR/.music-app/coverart/"+MetaDatabase.getMetadata(playMusic.source,"cover") // get cover art filename
1350-
1351- setProgressbar() // set progressbar
1352-
1353- console.debug("Debug: UI updated.")
1354- }
1355-
1356- // Music stuff
1357- Audio {
1358- id: playMusic
1359- source: ""
1360- /*
1361+ Library.setMetadata(track, title, artist, album, cover, year, tracknr, length)
1362+ }
1363+
1364+ MediaPlayer {
1365+ id: player
1366+ muted: false
1367 onStatusChanged: {
1368- if (status === Audio.EndOfMedia || 7 ) {
1369- console.log("Debug: Track ended. Play next.") //debug
1370- //nextTrack()
1371- }
1372- else {
1373- console.log("the Music Players status = " + playMusic.status)
1374+ if (status == MediaPlayer.EndOfMedia) {
1375+ nextSong()
1376 }
1377- }*/
1378- }
1379-
1380- // while playing
1381- Connections {
1382- target: playMusic
1383- onPlaying: {
1384- trackProgress.value = playMusic.position
1385- console.debug("Debug: change position to "+playMusic.position)
1386- }
1387- }
1388-
1389- // get file meta data
1390- Audio {
1391- id: musicInfo
1392- source: ""
1393- volume: 0.0
1394- //Keys.onSpacePressed: stateChange()
1395+ }
1396+
1397+ onPositionChanged: {
1398+ musicTracksPage.needsUpdate = true
1399+ }
1400 }
1401
1402 // set the folder from where the music is
1403 FolderListModel {
1404 id: folderModel
1405- folder: musicDir
1406- showDirs: false
1407- nameFilters: ["*.ogg","*.mp3","*.oga","*.wav"]
1408+ showDirectories: false
1409+ filterDirectories: false
1410+ nameFilters: ["*.mp3", "*.ogg", "*.flac", "*.wav", "*.oga"]
1411+ path: Settings.getSetting("initialized") === "true" && Settings.getSetting("currentfolder") !== "" ? Settings.getSetting("currentfolder") : homePath() + "/Music"
1412 }
1413
1414 /* this is how a queue looks like
1415@@ -283,244 +168,6 @@
1416 id: singleTracks
1417 }
1418
1419- // reusable toolbar
1420- ToolbarActions {
1421- id: defaultToolbar
1422-
1423- // Share
1424- Action {
1425- id: shareTrack
1426- objectName: "share"
1427-
1428- iconSource: Qt.resolvedUrl("images/icon_share@20.png")
1429- text: i18n.tr("Share")
1430-
1431- onTriggered: {
1432- console.debug('Debug: Share pressed')
1433- // just to debug other stuff for a while
1434- console.debug("Debug: change progress to "+playMusic.position)
1435- trackProgress.value = playMusic.position
1436- }
1437- }
1438-
1439- // prevous track
1440- Action {
1441- id: prevTrack
1442- objectName: "prev"
1443-
1444- iconSource: Qt.resolvedUrl("images/icon_prev@20.png")
1445- text: i18n.tr("Previous")
1446-
1447- onTriggered: {
1448- console.debug('Debug: Prev track pressed')
1449- //console.debug(removedTrackQueue.get(0).file) // print next songs filename
1450- //playMusic.source = removedTrackQueue.get(0).file
1451- //playMusic.play()
1452- previousTrack()
1453- }
1454- }
1455-
1456- // Play
1457- Action {
1458- id: playTrack
1459- objectName: "play"
1460-
1461- iconSource: Qt.resolvedUrl("images/icon_play@20.png")
1462- text: i18n.tr("Play")
1463-
1464- onTriggered: {
1465- console.debug("Debug: "+trackStatus+" pressed in toolbar.")
1466- console.debug(playMusic.playbackState)
1467- stateChange()
1468- }
1469- }
1470-
1471- // Next track
1472- Action {
1473- id: nextTrack
1474- objectName: "next"
1475-
1476- iconSource: Qt.resolvedUrl("images/icon_next@20.png")
1477- text: i18n.tr("Next")
1478-
1479- onTriggered: {
1480- console.debug('Debug: next track pressed')
1481- console.debug(trackQueue.get(0).file) // print next songs filename
1482- playMusic.source = trackQueue.get(0).file
1483- playMusic.play()
1484-
1485- // move track, which has been played from queue, to old queue so that prev button works
1486- removedTrackQueue.append({"title": trackQueue.get(0).title, "artist": trackQueue.get(0).artist, "file": trackQueue.get(0).file})
1487- trackQueue.remove(0)
1488- }
1489- }
1490-
1491- // Queue
1492- Action {
1493- id: trackQueueAction
1494- objectName: "queuelist"
1495- iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
1496- text: i18n.tr("Queue")
1497- onTriggered: {
1498- PopupUtils.open(Qt.resolvedUrl("QueueDialog.qml"), pageLayout,
1499- {
1500- title: i18n.tr("Queue")
1501- } )
1502- }
1503- }
1504-
1505- // Settings
1506- Action {
1507- id: settingsAction
1508- objectName: "settings"
1509-
1510- iconSource: Qt.resolvedUrl("images/icon_settings@20.png")
1511- text: i18n.tr("Settings")
1512-
1513- onTriggered: {
1514- console.debug('Debug: Settings pressed')
1515- // show settings page (not yet implemented)
1516- //dialog
1517- PopupUtils.open(Qt.resolvedUrl("MusicSettings.qml"), pageLayout,
1518- {
1519- title: i18n.tr("Settings")
1520- } )
1521- }
1522- }
1523- }
1524-
1525- Tabs {
1526- id: tabs
1527- anchors.fill: parent
1528-
1529- // First tab begins here - should be the primary tab
1530- Tab {
1531- id: playinTab
1532- objectName: "Tab1"
1533-
1534- title: musicName
1535-
1536- // Tab content begins here
1537- page: Page {
1538- id: playingPage
1539-
1540- // toolbar
1541- tools: defaultToolbar
1542-
1543- Column {
1544- id: pageLayout
1545-
1546- spacing: units.gu(1)
1547-
1548- Column {
1549- spacing: units.gu(1)
1550- // Album cover here
1551- UbuntuShape {
1552- id: trackCoverArt
1553- width: units.gu(50)
1554- height: units.gu(50)
1555- gradientColor: "blue" // test
1556- image: Image {
1557- id: coverArt
1558- source: "images/music.png"
1559- }
1560- }
1561- /*onClicked: {
1562- playMusic.pause()
1563- }
1564- onDoubbleTap: {
1565- nextTrack()
1566- }
1567- onPressAndHold: {
1568- playMusic.stop()
1569- }*/
1570- }
1571-
1572- // track progress
1573- Column {
1574- width: units.gu(50)
1575- ProgressBar {
1576- id: trackProgress
1577- minimumValue: 0
1578- maximumValue: 100
1579- value: 0
1580- }
1581- }
1582-
1583- // Track info
1584- Column {
1585- spacing: units.gu(1)
1586- Label {
1587- id: trackInfo
1588- text: "Stopped. Press play."
1589- //subText: "Artist: + Year:"
1590- }
1591- }
1592- }
1593-
1594-
1595- }
1596- }
1597-
1598-
1599- // Second tab begins here - artists here
1600- Tab {
1601- objectName: "Artists Tab"
1602-
1603- title: i18n.tr("Artists")
1604- page: Page {
1605- anchors.margins: units.gu(2)
1606-
1607- // foreach artist:
1608- ListItem.Standard {
1609- height: units.gu(4)
1610- // when pressed on this row, change to albums of artist
1611- Row {
1612- Label {
1613- text: i18n.tr("Artist 1")
1614- }
1615- }
1616- }
1617-
1618- // toolbar
1619- tools: defaultToolbar
1620-
1621- Column {
1622- anchors.centerIn: parent
1623- anchors.fill: parent
1624- }
1625- }
1626- }
1627-
1628- // Third tab begins here - albums here
1629- Tab {
1630- objectName: "Albums Tab"
1631-
1632- title: i18n.tr("Albums")
1633- page: Page {
1634- anchors.margins: units.gu(2)
1635-
1636- Column {
1637- anchors.centerIn: parent
1638- anchors.fill: parent
1639- }
1640-
1641- // toolbar
1642- tools: defaultToolbar
1643-
1644- Column {
1645- anchors.centerIn: parent
1646- }
1647- }
1648- }
1649-
1650- // Fourth tab - tracks in ~/Music
1651- Tab {
1652- objectName: "Tracks Tab"
1653-
1654- title: i18n.tr("Tracks")
1655- page: MusicTracks { id: musicTracksPage }
1656- } // 4th tab
1657-
1658- } // tabs
1659+ MusicTracks { id: musicTracksPage }
1660+
1661 } // main view
1662
1663=== added file 'playing-list.js'
1664--- playing-list.js 1970-01-01 00:00:00 +0000
1665+++ playing-list.js 2013-06-05 04:48:28 +0000
1666@@ -0,0 +1,34 @@
1667+//playing-list.js
1668+.pragma library
1669+var myArray = new Array()
1670+var myLocation = new Array()
1671+
1672+function getList() {
1673+ return myArray
1674+}
1675+
1676+function at(index) {
1677+ return myLocation[index]
1678+}
1679+
1680+function addItem(item, index) {
1681+ myArray.push(item)
1682+ myLocation.push(index)
1683+}
1684+
1685+function contains(item) {
1686+ return myArray.indexOf(item) !== -1
1687+}
1688+
1689+function indexOf(item) {
1690+ return myArray.indexOf(item)
1691+}
1692+
1693+function size() {
1694+ return myArray.length
1695+}
1696+
1697+function clear() {
1698+ myArray = []
1699+ myLocation = []
1700+}

Subscribers

People subscribed via source and target branches

to status/vote changes: