Merge lp:~ahayzen/music-app/refactor-split-content-hub-url-handler-metrics into lp:music-app

Proposed by Andrew Hayzen
Status: Merged
Approved by: Victor Thompson
Approved revision: 843
Merged at revision: 846
Proposed branch: lp:~ahayzen/music-app/refactor-split-content-hub-url-handler-metrics
Merge into: lp:music-app
Diff against target: 816 lines (+425/-312)
7 files modified
app/components/CMakeLists.txt (+1/-0)
app/components/Helpers/CMakeLists.txt (+4/-0)
app/components/Helpers/ContentHubHelper.qml (+208/-0)
app/components/Helpers/UriHandlerHelper.qml (+97/-0)
app/components/Helpers/UserMetricsHelper.qml (+56/-0)
app/components/WorkerWaiter.qml (+48/-0)
app/music-app.qml (+11/-312)
To merge this branch: bzr merge lp:~ahayzen/music-app/refactor-split-content-hub-url-handler-metrics
Reviewer Review Type Date Requested Status
Victor Thompson Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+249887@code.launchpad.net

Commit message

* Split content-hub, uri-handler and metrics into Helpers

Description of the change

* Split content-hub, uri-handler and metrics into Helpers

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)
842. By Andrew Hayzen

* Merge of lp:music-app/refactor

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
Victor Thompson (vthompson) wrote :

This looks good and I haven't found any issues. I think it might be best to rename MetricHelper as UserMetricsHelper. Even though the component is called "Metric" I think naming the helper so it matches the library being used makes things more clear. The other helpers have names that describe their content quite clearly.

review: Needs Information
843. By Andrew Hayzen

* Rename MetricHelper.qml to UserMetricsHelper.qml

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
Victor Thompson (vthompson) wrote :

lgtm! Thanks! :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/components/CMakeLists.txt'
2--- app/components/CMakeLists.txt 2015-02-16 20:27:40 +0000
3+++ app/components/CMakeLists.txt 2015-03-09 00:13:54 +0000
4@@ -1,6 +1,7 @@
5 add_subdirectory(Delegates)
6 add_subdirectory(Dialog)
7 add_subdirectory(HeadState)
8+add_subdirectory(Helpers)
9 add_subdirectory(Flickables)
10 add_subdirectory(ListItemActions)
11 add_subdirectory(ViewButton)
12
13=== added directory 'app/components/Helpers'
14=== added file 'app/components/Helpers/CMakeLists.txt'
15--- app/components/Helpers/CMakeLists.txt 1970-01-01 00:00:00 +0000
16+++ app/components/Helpers/CMakeLists.txt 2015-03-09 00:13:54 +0000
17@@ -0,0 +1,4 @@
18+# make the qml files visible on qtcreator
19+file(GLOB HELPERS_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
20+
21+add_custom_target(com_ubuntu_music_HELPERS_QMLFiles ALL SOURCES ${HELPERS_QML_FILES})
22
23=== added file 'app/components/Helpers/ContentHubHelper.qml'
24--- app/components/Helpers/ContentHubHelper.qml 1970-01-01 00:00:00 +0000
25+++ app/components/Helpers/ContentHubHelper.qml 2015-03-09 00:13:54 +0000
26@@ -0,0 +1,208 @@
27+/*
28+ * Copyright (C) 2014, 2015
29+ * Andrew Hayzen <ahayzen@gmail.com>
30+ * Daniel Holm <d.holmen@gmail.com>
31+ * Victor Thompson <victor.thompson@gmail.com>
32+ *
33+ * This program is free software; you can redistribute it and/or modify
34+ * it under the terms of the GNU General Public License as published by
35+ * the Free Software Foundation; version 3.
36+ *
37+ * This program is distributed in the hope that it will be useful,
38+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
39+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40+ * GNU General Public License for more details.
41+ *
42+ * You should have received a copy of the GNU General Public License
43+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
44+ */
45+
46+import QtQuick 2.3
47+import Ubuntu.Components 1.1
48+import Ubuntu.Components.Popups 1.0
49+import Ubuntu.Content 0.1
50+
51+
52+Item {
53+ property var activeTransfer
54+ property int importId: 0
55+ property list<ContentItem> importItems
56+ property bool processing: contentHubWaitForFile !== -1
57+
58+ ContentTransferHint {
59+ anchors {
60+ fill: parent
61+ }
62+ activeTransfer: parent.activeTransfer
63+ }
64+
65+ Connections {
66+ id: contentHub
67+ target: ContentHub
68+
69+ property var searchPaths: []
70+
71+ onImportRequested: {
72+ activeTransfer = transfer;
73+
74+ if (activeTransfer.state === ContentTransfer.Charged) {
75+ importItems = activeTransfer.items;
76+
77+ var processId = importId++;
78+
79+ console.debug("Triggering content-hub import ID", processId);
80+
81+ searchPaths = [];
82+
83+ var err = [];
84+ var path;
85+ var res;
86+ var success = true;
87+ var url;
88+
89+ for (var i=0; i < importItems.length; i++) {
90+ url = importItems[i].url.toString()
91+ console.debug("Triggered content-hub import for item", url)
92+
93+ // fixed path allows for apparmor protection
94+ path = "~/Music/Imported/" + Qt.formatDateTime(new Date(), "yyyy/MM/dd/hhmmss") + "-" + url.split("/").pop()
95+ res = contentHub.importFile(importItems[i], path)
96+
97+ if (res !== true) {
98+ success = false;
99+ err.push(url.split("/").pop() + " " + res)
100+ }
101+ }
102+
103+
104+ if (success === true) {
105+ if (contentHubWaitForFile.processId === -1) {
106+ contentHubWaitForFile.dialog = PopupUtils.open(Qt.resolvedUrl("../Dialog/ContentHubWaitDialog.qml"), mainView)
107+ contentHubWaitForFile.searchPaths = contentHub.searchPaths;
108+ contentHubWaitForFile.processId = processId;
109+ contentHubWaitForFile.start();
110+
111+ // Stop queue loading in bg
112+ queueLoaderWorker.canLoad = false
113+ } else {
114+ contentHubWaitForFile.searchPaths.push.apply(contentHubWaitForFile.searchPaths, contentHub.searchPaths);
115+ contentHubWaitForFile.count = 0;
116+ contentHubWaitForFile.restart();
117+ }
118+ }
119+ else {
120+ var errordialog = PopupUtils.open(Qt.resolvedUrl("../Dialog/ContentHubErrorDialog.qml"), mainView)
121+ errordialog.errorText = err.join("\n")
122+ }
123+ }
124+ }
125+
126+ function importFile(contentItem, path) {
127+ var contentUrl = contentItem.url.toString()
128+
129+ if (path.indexOf("~/Music/Imported/") !== 0) {
130+ console.debug("Invalid dest (not in ~/Music/Imported/)")
131+
132+ // TRANSLATORS: This string represents that the target destination filepath does not start with ~/Music/Imported/
133+ return i18n.tr("Filepath must start with") + " ~/Music/Imported/"
134+ }
135+ else {
136+ // extract /home/$USER (or $HOME) from contentitem url
137+ var homepath = contentUrl.substring(7).split("/");
138+
139+ if (homepath[1] === "home") {
140+ homepath.splice(3, homepath.length - 3)
141+ homepath = homepath.join("/")
142+ }
143+ else {
144+ console.debug("/home/$USER not detecting in contentItem assuming /home/phablet/")
145+ homepath = "/home/phablet"
146+ }
147+
148+ console.debug("Move:", contentUrl, "to", path)
149+
150+ // Extract filename from path and replace ~ with $HOME
151+ var dir = path.split("/")
152+ var filename = dir.pop()
153+ dir = dir.join("/").replace("~/", homepath + "/")
154+
155+ if (filename === "") {
156+ console.debug("Invalid dest (filename blank)")
157+
158+ // TRANSLATORS: This string represents that a blank filepath destination has been used
159+ return i18n.tr("Filepath must be a file")
160+ }
161+ else if (!contentItem.move(dir, filename)) {
162+ console.debug("Move failed! DIR:", dir, "FILE:", filename)
163+
164+ // TRANSLATORS: This string represents that there was failure moving the file to the target destination
165+ return i18n.tr("Failed to move file")
166+ }
167+ else {
168+ contentHub.searchPaths.push(dir + "/" + filename)
169+ return true
170+ }
171+ }
172+ }
173+ }
174+
175+ Timer {
176+ id: contentHubWaitForFile
177+ interval: 1000
178+ triggeredOnStart: false
179+ repeat: true
180+
181+ property var dialog: null
182+ property var searchPaths
183+ property int count: 0
184+ property int processId: -1
185+
186+ function stopTimer() {
187+ processId = -1;
188+ count = 0;
189+ stop();
190+
191+ PopupUtils.close(dialog)
192+ }
193+
194+ onTriggered: {
195+ var found = true
196+ var i;
197+ var model;
198+
199+ for (i=0; i < searchPaths.length; i++) {
200+ model = musicStore.lookup(searchPaths[i])
201+
202+ console.debug("MusicStore model from lookup", JSON.stringify(model))
203+
204+ if (!model) {
205+ found = false
206+ }
207+ }
208+
209+ if (!found) {
210+ count++;
211+
212+ if (count >= 10) { // wait for 10s
213+ stopTimer();
214+
215+ console.debug("File(s) were not found", JSON.stringify(searchPaths))
216+ PopupUtils.open(Qt.resolvedUrl("../Dialog/ContentHubNotFoundDialog.qml"), mainView)
217+ }
218+ }
219+ else {
220+ stopTimer();
221+
222+ trackQueue.clear();
223+
224+ for (i=0; i < searchPaths.length; i++) {
225+ model = musicStore.lookup(searchPaths[i])
226+
227+ trackQueue.append(makeDict(model));
228+ }
229+
230+ trackQueueClick(0);
231+ }
232+ }
233+ }
234+}
235
236=== added file 'app/components/Helpers/UriHandlerHelper.qml'
237--- app/components/Helpers/UriHandlerHelper.qml 1970-01-01 00:00:00 +0000
238+++ app/components/Helpers/UriHandlerHelper.qml 2015-03-09 00:13:54 +0000
239@@ -0,0 +1,97 @@
240+/*
241+ * Copyright (C) 2013, 2014, 2015
242+ * Andrew Hayzen <ahayzen@gmail.com>
243+ * Daniel Holm <d.holmen@gmail.com>
244+ * Victor Thompson <victor.thompson@gmail.com>
245+ *
246+ * This program is free software; you can redistribute it and/or modify
247+ * it under the terms of the GNU General Public License as published by
248+ * the Free Software Foundation; version 3.
249+ *
250+ * This program is distributed in the hope that it will be useful,
251+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
252+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
253+ * GNU General Public License for more details.
254+ *
255+ * You should have received a copy of the GNU General Public License
256+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
257+ */
258+
259+import QtQuick 2.3
260+import Ubuntu.Components 1.1
261+import "../"
262+
263+
264+Item {
265+ id: uriHandler
266+
267+ Connections {
268+ target: UriHandler
269+
270+ onOpened: {
271+ for (var i=0; i < uris.length; i++) {
272+ console.debug("URI=" + uris[i])
273+ uriHandler.process(uris[i], i === 0);
274+ }
275+ }
276+ }
277+
278+ function processAlbum(uri) {
279+ selectedAlbum = true;
280+ var split = uri.split("/");
281+
282+ if (split.length < 2) {
283+ console.debug("Unknown artist-album " + uri + ", skipping")
284+ return;
285+ }
286+
287+ // Filter by artist and album
288+ songsAlbumArtistModel.albumArtist = decodeURIComponent(split[0]);
289+ songsAlbumArtistModel.album = decodeURIComponent(split[1]);
290+ }
291+
292+ function processFile(uri, play) {
293+ // Stop queue loading in the background
294+ queueLoaderWorker.canLoad = false
295+
296+ if (queueLoaderWorker.processing > 0) {
297+ waitForWorker.workerStop(queueLoaderWorker, processFile, [uri, play])
298+ return;
299+ }
300+
301+ uri = decodeURIComponent(uri);
302+
303+ // Lookup track in songs model
304+ var track = musicStore.lookup(decodeURIComponent(uri));
305+
306+ if (!track) {
307+ console.debug("Unknown file " + uri + ", skipping")
308+ return;
309+ }
310+
311+ if (play) {
312+ // clear play queue
313+ trackQueue.clear()
314+ }
315+
316+ // enqueue
317+ trackQueue.append(makeDict(track));
318+
319+ // play first URI
320+ if (play) {
321+ trackQueueClick(trackQueue.model.count - 1);
322+ }
323+ }
324+
325+ function process(uri, play) {
326+ if (uri.indexOf("album:///") === 0) {
327+ processAlbum(uri.substring(9));
328+ } else if (uri.indexOf("file://") === 0) {
329+ processFile(uri.substring(7), play);
330+ } else if (uri.indexOf("music://") === 0) {
331+ processFile(uri.substring(8), play);
332+ } else {
333+ console.debug("Unsupported URI " + uri + ", skipping")
334+ }
335+ }
336+}
337
338=== added file 'app/components/Helpers/UserMetricsHelper.qml'
339--- app/components/Helpers/UserMetricsHelper.qml 1970-01-01 00:00:00 +0000
340+++ app/components/Helpers/UserMetricsHelper.qml 2015-03-09 00:13:54 +0000
341@@ -0,0 +1,56 @@
342+/*
343+ * Copyright (C) 2013, 2014, 2015
344+ * Andrew Hayzen <ahayzen@gmail.com>
345+ * Daniel Holm <d.holmen@gmail.com>
346+ * Victor Thompson <victor.thompson@gmail.com>
347+ *
348+ * This program is free software; you can redistribute it and/or modify
349+ * it under the terms of the GNU General Public License as published by
350+ * the Free Software Foundation; version 3.
351+ *
352+ * This program is distributed in the hope that it will be useful,
353+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
354+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
355+ * GNU General Public License for more details.
356+ *
357+ * You should have received a copy of the GNU General Public License
358+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
359+ */
360+
361+import QtQuick 2.3
362+import Ubuntu.Components 1.1
363+import UserMetrics 0.1
364+
365+
366+Item {
367+ // UserMetrics to show Music stuff on welcome screen
368+ Metric {
369+ id: songsMetric
370+ name: "music-metrics"
371+ // TRANSLATORS: this refers to a number of songs greater than one. The actual number will be prepended to the string automatically (plural forms are not yet fully supported in usermetrics, the library that displays that string)
372+ format: "<b>%1</b> " + i18n.tr("songs played today")
373+ emptyFormat: i18n.tr("No songs played today")
374+ domain: "com.ubuntu.music"
375+ }
376+
377+ // Connections for usermetrics
378+ Connections {
379+ id: userMetricPlayerConnection
380+ target: player
381+ property bool songCounted: false
382+
383+ onSourceChanged: {
384+ songCounted = false
385+ }
386+
387+ onPositionChanged: {
388+ // Increment song count on Welcome screen if song has been
389+ // playing for over 10 seconds.
390+ if (player.position > 10000 && !songCounted) {
391+ songCounted = true
392+ songsMetric.increment()
393+ console.debug("Increment UserMetrics")
394+ }
395+ }
396+ }
397+}
398
399=== added file 'app/components/WorkerWaiter.qml'
400--- app/components/WorkerWaiter.qml 1970-01-01 00:00:00 +0000
401+++ app/components/WorkerWaiter.qml 2015-03-09 00:13:54 +0000
402@@ -0,0 +1,48 @@
403+/*
404+ * Copyright (C) 2014, 2015
405+ * Andrew Hayzen <ahayzen@gmail.com>
406+ * Daniel Holm <d.holmen@gmail.com>
407+ * Victor Thompson <victor.thompson@gmail.com>
408+ *
409+ * This program is free software; you can redistribute it and/or modify
410+ * it under the terms of the GNU General Public License as published by
411+ * the Free Software Foundation; version 3.
412+ *
413+ * This program is distributed in the hope that it will be useful,
414+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
415+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
416+ * GNU General Public License for more details.
417+ *
418+ * You should have received a copy of the GNU General Public License
419+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
420+ */
421+
422+import QtQuick 2.3
423+import Ubuntu.Components 1.1
424+
425+
426+Timer { // A timer to wait for a worker to stop
427+ id: waitForWorker
428+ interval: 16
429+ repeat: true
430+
431+ property var func
432+ property var params // don't use args/arguments as they are already defined/internal
433+ property WorkerScript worker
434+
435+ onTriggered: {
436+ if (worker.processing === 0) {
437+ stop()
438+ func.apply(this, params)
439+ }
440+ }
441+
442+ // Waits until the worker has stopped and then calls the func(*params)
443+ function workerStop(worker, func, params)
444+ {
445+ waitForWorker.func = func
446+ waitForWorker.params = params
447+ waitForWorker.worker = worker
448+ start()
449+ }
450+}
451
452=== modified file 'app/music-app.qml'
453--- app/music-app.qml 2015-03-06 02:27:26 +0000
454+++ app/music-app.qml 2015-03-09 00:13:54 +0000
455@@ -19,18 +19,15 @@
456
457 import QtQuick 2.3
458 import Ubuntu.Components 1.1
459-import Ubuntu.Components.Popups 1.0
460-import Ubuntu.Components.ListItems 1.0 as ListItem
461-import Ubuntu.Content 0.1
462 import Ubuntu.MediaScanner 0.1
463 import Qt.labs.settings 1.0
464 import QtMultimedia 5.0
465 import QtQuick.LocalStorage 2.0
466 import QtGraphicalEffects 1.0
467-import UserMetrics 0.1
468 import "logic/meta-database.js" as Library
469 import "logic/playlists.js" as Playlists
470 import "components"
471+import "components/Helpers"
472 import "ui"
473
474 MainView {
475@@ -180,291 +177,16 @@
476
477 actions: [nextAction, playsAction, prevAction, stopAction, backAction]
478
479- // signal to open new URIs
480- Connections {
481+ UriHandlerHelper {
482 id: uriHandler
483- target: UriHandler
484-
485- function processAlbum(uri) {
486- selectedAlbum = true;
487- var split = uri.split("/");
488-
489- if (split.length < 2) {
490- console.debug("Unknown artist-album " + uri + ", skipping")
491- return;
492- }
493-
494- // Filter by artist and album
495- songsAlbumArtistModel.albumArtist = decodeURIComponent(split[0]);
496- songsAlbumArtistModel.album = decodeURIComponent(split[1]);
497- }
498-
499- function processFile(uri, play) {
500- // Stop queue loading in the background
501- queueLoaderWorker.canLoad = false
502-
503- if (queueLoaderWorker.processing > 0) {
504- waitForWorker.workerStop(queueLoaderWorker, processFile, [uri, play])
505- return;
506- }
507-
508- uri = decodeURIComponent(uri);
509-
510- // Lookup track in songs model
511- var track = musicStore.lookup(decodeURIComponent(uri));
512-
513- if (!track) {
514- console.debug("Unknown file " + uri + ", skipping")
515- return;
516- }
517-
518- if (play) {
519- // clear play queue
520- trackQueue.clear()
521- }
522-
523- // enqueue
524- trackQueue.append(makeDict(track));
525-
526- // play first URI
527- if (play) {
528- trackQueueClick(trackQueue.model.count - 1);
529- }
530- }
531-
532- function process(uri, play) {
533- if (uri.indexOf("album:///") === 0) {
534- uriHandler.processAlbum(uri.substring(9));
535- }
536- else if (uri.indexOf("file://") === 0) {
537- uriHandler.processFile(uri.substring(7), play);
538- }
539- else if (uri.indexOf("music://") === 0) {
540- uriHandler.processFile(uri.substring(8), play);
541- }
542- else {
543- console.debug("Unsupported URI " + uri + ", skipping")
544- }
545- }
546-
547- onOpened: {
548- for (var i=0; i < uris.length; i++) {
549- console.debug("URI=" + uris[i])
550-
551- uriHandler.process(uris[i], i === 0);
552- }
553- }
554- }
555-
556- // Content hub support
557- property list<ContentItem> importItems
558- property var activeTransfer
559- property int importId: 0
560-
561- ContentTransferHint {
562- anchors {
563- fill: parent
564- }
565- activeTransfer: parent.activeTransfer
566- }
567-
568- Connections {
569+ }
570+
571+ ContentHubHelper {
572 id: contentHub
573- target: ContentHub
574- onImportRequested: {
575- activeTransfer = transfer;
576- if (activeTransfer.state === ContentTransfer.Charged) {
577- importItems = activeTransfer.items;
578-
579- var processId = importId++;
580-
581- console.debug("Triggering content-hub import ID", processId);
582-
583- searchPaths = [];
584-
585- var err = [];
586- var path;
587- var res;
588- var success = true;
589- var url;
590-
591- for (var i=0; i < importItems.length; i++) {
592- url = importItems[i].url.toString()
593- console.debug("Triggered content-hub import for item", url)
594-
595- // fixed path allows for apparmor protection
596- path = "~/Music/Imported/" + Qt.formatDateTime(new Date(), "yyyy/MM/dd/hhmmss") + "-" + url.split("/").pop()
597- res = contentHub.importFile(importItems[i], path)
598-
599- if (res !== true) {
600- success = false;
601- err.push(url.split("/").pop() + " " + res)
602- }
603- }
604-
605-
606- if (success === true) {
607- if (contentHubWaitForFile.processId === -1) {
608- contentHubWaitForFile.dialog = PopupUtils.open(Qt.resolvedUrl("components/Dialog/ContentHubWaitDialog.qml"), mainView)
609- contentHubWaitForFile.searchPaths = contentHub.searchPaths;
610- contentHubWaitForFile.processId = processId;
611- contentHubWaitForFile.start();
612-
613- // Stop queue loading in bg
614- queueLoaderWorker.canLoad = false
615- } else {
616- contentHubWaitForFile.searchPaths.push.apply(contentHubWaitForFile.searchPaths, contentHub.searchPaths);
617- contentHubWaitForFile.count = 0;
618- contentHubWaitForFile.restart();
619- }
620- }
621- else {
622- var errordialog = PopupUtils.open(Qt.resolvedUrl("components/Dialog/ContentHubErrorDialog.qml"), mainView)
623- errordialog.errorText = err.join("\n")
624- }
625- }
626- }
627-
628- property var searchPaths: []
629-
630- function importFile(contentItem, path) {
631- var contentUrl = contentItem.url.toString()
632-
633- if (path.indexOf("~/Music/Imported/") !== 0) {
634- console.debug("Invalid dest (not in ~/Music/Imported/)")
635-
636- // TRANSLATORS: This string represents that the target destination filepath does not start with ~/Music/Imported/
637- return i18n.tr("Filepath must start with") + " ~/Music/Imported/"
638- }
639- else {
640- // extract /home/$USER (or $HOME) from contentitem url
641- var homepath = contentUrl.substring(7).split("/");
642-
643- if (homepath[1] === "home") {
644- homepath.splice(3, homepath.length - 3)
645- homepath = homepath.join("/")
646- }
647- else {
648- console.debug("/home/$USER not detecting in contentItem assuming /home/phablet/")
649- homepath = "/home/phablet"
650- }
651-
652- console.debug("Move:", contentUrl, "to", path)
653-
654- // Extract filename from path and replace ~ with $HOME
655- var dir = path.split("/")
656- var filename = dir.pop()
657- dir = dir.join("/").replace("~/", homepath + "/")
658-
659- if (filename === "") {
660- console.debug("Invalid dest (filename blank)")
661-
662- // TRANSLATORS: This string represents that a blank filepath destination has been used
663- return i18n.tr("Filepath must be a file")
664- }
665- else if (!contentItem.move(dir, filename)) {
666- console.debug("Move failed! DIR:", dir, "FILE:", filename)
667-
668- // TRANSLATORS: This string represents that there was failure moving the file to the target destination
669- return i18n.tr("Failed to move file")
670- }
671- else {
672- contentHub.searchPaths.push(dir + "/" + filename)
673- return true
674- }
675- }
676- }
677- }
678-
679- Timer {
680- id: contentHubWaitForFile
681- interval: 1000
682- triggeredOnStart: false
683- repeat: true
684-
685- property var dialog: null
686- property var searchPaths
687- property int count: 0
688- property int processId: -1
689-
690- function stopTimer() {
691- processId = -1;
692- count = 0;
693- stop();
694-
695- PopupUtils.close(dialog)
696- }
697-
698- onTriggered: {
699- var found = true
700- var i;
701- var model;
702-
703- for (i=0; i < searchPaths.length; i++) {
704- model = musicStore.lookup(searchPaths[i])
705-
706- console.debug("MusicStore model from lookup", JSON.stringify(model))
707-
708- if (!model) {
709- found = false
710- }
711- }
712-
713- if (!found) {
714- count++;
715-
716- if (count >= 10) { // wait for 10s
717- stopTimer();
718-
719- console.debug("File(s) were not found", JSON.stringify(searchPaths))
720- PopupUtils.open(Qt.resolvedUrl("components/Dialog/ContentHubNotFoundDialog.qml"), mainView)
721- }
722- }
723- else {
724- stopTimer();
725-
726- trackQueue.clear();
727-
728- for (i=0; i < searchPaths.length; i++) {
729- model = musicStore.lookup(searchPaths[i])
730-
731- trackQueue.append(makeDict(model));
732- }
733-
734- trackQueueClick(0);
735- }
736- }
737- }
738-
739- // UserMetrics to show Music stuff on welcome screen
740- Metric {
741- id: songsMetric
742- name: "music-metrics"
743- // TRANSLATORS: this refers to a number of songs greater than one. The actual number will be prepended to the string automatically (plural forms are not yet fully supported in usermetrics, the library that displays that string)
744- format: "<b>%1</b> " + i18n.tr("songs played today")
745- emptyFormat: i18n.tr("No songs played today")
746- domain: "com.ubuntu.music"
747- }
748-
749- // Connections for usermetrics
750- Connections {
751- id: userMetricPlayerConnection
752- target: player
753- property bool songCounted: false
754-
755- onSourceChanged: {
756- songCounted = false
757- }
758-
759- onPositionChanged: {
760- // Increment song count on Welcome screen if song has been
761- // playing for over 10 seconds.
762- if (player.position > 10000 && !songCounted) {
763- songCounted = true
764- songsMetric.increment()
765- console.debug("Increment UserMetrics")
766- }
767- }
768+ }
769+
770+ UserMetricsHelper {
771+ id: userMetrics
772 }
773
774 // Design stuff
775@@ -486,31 +208,8 @@
776 }
777 }
778
779- // A timer to wait for a worker to stop
780- Timer {
781+ WorkerWaiter {
782 id: waitForWorker
783- interval: 16
784- repeat: true
785-
786- property var func
787- property var params // don't use args/arguments as they are already defined/internal
788- property WorkerScript worker
789-
790- onTriggered: {
791- if (worker.processing === 0) {
792- stop()
793- func.apply(this, params)
794- }
795- }
796-
797- // Waits until the worker has stopped and then calls the func(*params)
798- function workerStop(worker, func, params)
799- {
800- waitForWorker.func = func
801- waitForWorker.params = params
802- waitForWorker.worker = worker
803- start()
804- }
805 }
806
807 // Run on startup
808@@ -1252,7 +951,7 @@
809 id: emptyPageLoader
810 // Do not be active if content-hub is importing due to the models resetting
811 // this then causes the empty page loader to partially run then showing a blank header
812- active: noMusic && !firstRun && contentHubWaitForFile.processId === -1
813+ active: noMusic && !firstRun && !contentHub.processing
814 anchors {
815 fill: parent
816 }

Subscribers

People subscribed via source and target branches