@@ -96,6 +96,40 @@ var kArtShapeHolderCode = 'Item { \n\
102+var kAudioButtonCode = 'AbstractButton { \n\
103+ id: audioButton; \n\
104+ anchors.fill: %1; \n\
107+ readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
109+ anchors.fill: parent; \n\
110+ visible: parent.pressed; \n\
111+ radius: "medium"; \n\
112+ borderSource: "radius_pressed.sci" \n\
115+ anchors.fill: parent; \n\
116+ anchors.margins: parent.height > units.gu(5) ? units.gu(2) : units.gu(0); \n\
118+ name: DashAudioPlayer.isCurrentSource(parent.source) && DashAudioPlayer.playing ? "media-playback-pause" : "media-playback-start"; \n\
121+ if (DashAudioPlayer.isCurrentSource(source)) { \n\
122+ if (DashAudioPlayer.playing) { \n\
123+ DashAudioPlayer.pause(); \n\
125+ DashAudioPlayer.play(); \n\
128+ DashAudioPlayer.playSource(source); \n\
99var kOverlayLoaderCode = 'Loader { \n\
133var kOverlayLoaderCode = 'Loader { \n\
100 id: overlayLoader; \n\
134 id: overlayLoader; \n\
101 anchors { \n\
135 anchors { \n\
@@ -300,6 +334,22 @@ var kSummaryLabelCode = 'Label { \n\
300 color: %3; \n\
334 color: %3; \n\
337+// %1 is used as bottom anchor of audio progress bar
338+// %2 is used as left anchor of audio progress bar
339+// %3 is used as text color
340+var kAudioProgressBarCode = 'CardAudioProgress { \n\
341+ id: audioProgressBar; \n\
342+ duration: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["duration"]) || 0; \n\
343+ source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
347+ right: parent.right; \n\
348+ margins: units.gu(1); \n\
303function cardString(template, components) {
353function cardString(template, components) {
304 var code;
354 var code;
305 code = 'AbstractButton { \n\
355 code = 'AbstractButton { \n\
@@ -333,6 +383,19 @@ function cardString(template, components) {
333 var hasSubtitle = hasTitle && components["subtitle"] || false;
383 var hasSubtitle = hasTitle && components["subtitle"] || false;
334 var hasHeaderRow = hasMascot && hasTitle;
384 var hasHeaderRow = hasMascot && hasTitle;
335 var hasAttributes = hasTitle && components["attributes"]["field"] || false;
385 var hasAttributes = hasTitle && components["attributes"]["field"] || false;
386+ var isAudio = template["quickPreviewType"] === "audio";
389+ // For now we only support audio cards with [optional] art, title, subtitle
390+ // in horizontal mode
391+ // Anything else makes it behave not like an audio card
392+ if (hasSummary) isAudio = false;
393+ if (!isHorizontal) isAudio = false;
394+ if (hasMascot) isAudio = false;
395+ if (hasEmblem) isAudio = false;
396+ if (headerAsOverlay) isAudio = false;
397+ if (hasAttributes) isAudio = false;
337 if (hasBackground) {
400 if (hasBackground) {
338 code += kBackgroundLoaderCode;
401 code += kBackgroundLoaderCode;
@@ -388,17 +451,22 @@ function cardString(template, components) {
388 topMargin: units.gu(1);\n';
451 topMargin: units.gu(1);\n';
391 var headerLeftAnchor;
455 var headerLeftAnchor;
392 var headerLeftAnchorHasMargin = false;
456 var headerLeftAnchorHasMargin = false;
393 if (isHorizontal && hasArt) {
457 if (isHorizontal && hasArt) {
394 headerLeftAnchor = 'left: artShapeHolder.right; \n\
458 headerLeftAnchor = 'left: artShapeHolder.right; \n\
395 leftMargin: units.gu(1);\n';
459 leftMargin: units.gu(1);\n';
396 headerLeftAnchorHasMargin = true;
460 headerLeftAnchorHasMargin = true;
461+ } else if (isHorizontal && isAudio) {
462+ headerLeftAnchor = 'left: audioButton.right; \n\
463+ leftMargin: units.gu(1);\n';
464+ headerLeftAnchorHasMargin = true;
398 headerLeftAnchor = 'left: parent.left;\n';
466 headerLeftAnchor = 'left: parent.left;\n';
401− var touchdownOnArtShape = !hasBackground && hasArt && !hasMascot && !hasSummary;
469+ var touchdownOnArtShape = !hasBackground && hasArt && !hasMascot && !hasSummary && !isAudio;
403 if (hasHeaderRow) {
471 if (hasHeaderRow) {
404 code += 'readonly property int headerHeight: row.height;\n'
472 code += 'readonly property int headerHeight: row.height;\n'
@@ -412,6 +480,14 @@ function cardString(template, components) {
413 code += 'readonly property int headerHeight: attributesRow.height;\n'
481 code += 'readonly property int headerHeight: attributesRow.height;\n'
483+ } else if (isAudio) {
485+ code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + audioProgressBar.height + audioProgressBar.anchors.topMargin;\n'
486+ } else if (hasTitle) {
487+ code += 'readonly property int headerHeight: titleLabel.height + audioProgressBar.height + audioProgressBar.anchors.topMargin;\n'
489+ code += 'readonly property int headerHeight: audioProgressBar.height;\n'
415 } else if (hasSubtitle) {
491 } else if (hasSubtitle) {
416 code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
492 code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
417 } else if (hasTitle) {
493 } else if (hasTitle) {
@@ -593,6 +669,30 @@ function cardString(template, components) {
593 code += mascotShapeCode + mascotCode + titleSubtitleCode;
669 code += mascotShapeCode + mascotCode + titleSubtitleCode;
673+ var audioProgressBarLeftAnchor = 'audioButton.right';
674+ var audioProgressBarBottomAnchor = 'audioButton.bottom';
675+ var audioProgressBarTextColor = 'root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText';
677+ code += kAudioProgressBarCode.arg(audioProgressBarBottomAnchor)
678+ .arg(audioProgressBarLeftAnchor)
679+ .arg(audioProgressBarTextColor);
681+ var audioButtonAnchorsFill;
682+ var audioButtonWidth;
683+ var audioButtonHeight;
685+ audioButtonAnchorsFill = 'artShapeHolder';
686+ audioButtonWidth = 'undefined';
687+ audioButtonHeight = 'undefined';
689+ audioButtonAnchorsFill = 'undefined';
690+ audioButtonWidth = 'height';
691+ audioButtonHeight = '(root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1)';
693+ code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight);
596 if (hasSummary) {
696 if (hasSummary) {
597 var summaryTopAnchor;
697 var summaryTopAnchor;
598 if (isHorizontal && hasArt) summaryTopAnchor = 'artShapeHolder.bottom';
698 if (isHorizontal && hasArt) summaryTopAnchor = 'artShapeHolder.bottom';
@@ -631,6 +731,8 @@ function cardString(template, components) {
631 var implicitHeight = 'implicitHeight: ';
731 var implicitHeight = 'implicitHeight: ';
632 if (hasSummary) {
732 if (hasSummary) {
633 implicitHeight += 'summary.y + summary.height + units.gu(1);\n';
733 implicitHeight += 'summary.y + summary.height + units.gu(1);\n';
734+ } else if (isAudio) {
735+ implicitHeight += 'audioButton.height;\n';
634 } else if (hasHeaderRow) {
736 } else if (hasHeaderRow) {
635 implicitHeight += 'row.y + row.height + units.gu(1);\n';
737 implicitHeight += 'row.y + row.height + units.gu(1);\n';
636 } else if (hasMascot) {
738 } else if (hasMascot) {