Warning, /plasma-bigscreen/youtube-voice-application/ui/delegates/ListVideoCard.qml is written in an unsupported language. File is not indexed.

0001 import QtQuick 2.9
0002 import QtQuick.Layouts 1.4
0003 import QtGraphicalEffects 1.0
0004 import QtQuick.Controls 2.3
0005 import org.kde.kirigami 2.8 as Kirigami
0006 import Mycroft 1.0 as Mycroft
0007 
0008 ItemDelegate {
0009     id: delegate
0010     
0011     readonly property Flickable listView: {
0012         var candidate = parent;
0013         while (candidate) {
0014             if (candidate instanceof Flickable) {
0015                 return candidate;
0016             }
0017             candidate = candidate.parent;
0018         }
0019         return null;
0020     }
0021     readonly property bool isCurrent: {
0022         listView.currentIndex == index && activeFocus && !listView.moving
0023     }
0024 
0025     property int borderSize: Kirigami.Units.smallSpacing
0026     property int baseRadius: 3
0027 
0028     z: isCurrent ? 2 : 0
0029 
0030     leftPadding: Kirigami.Units.largeSpacing * 2
0031     topPadding: Kirigami.Units.largeSpacing * 2
0032     rightPadding: Kirigami.Units.largeSpacing * 2
0033     bottomPadding: Kirigami.Units.largeSpacing * 2
0034 
0035     leftInset: Kirigami.Units.largeSpacing
0036     topInset: Kirigami.Units.largeSpacing
0037     rightInset: Kirigami.Units.largeSpacing
0038     bottomInset: Kirigami.Units.largeSpacing
0039     
0040     implicitWidth: listView.cellWidth
0041     height: parent.height
0042     
0043     background: Item {
0044         id: background
0045         
0046         Rectangle {
0047             id: frame
0048             anchors.fill: parent
0049             color: Kirigami.Theme.backgroundColor
0050             radius: delegate.baseRadius
0051         }
0052     }
0053 
0054 
0055     contentItem: ColumnLayout {
0056         spacing: Kirigami.Units.smallSpacing
0057 
0058         Item {
0059             id: imgRoot
0060             //clip: true
0061             Layout.alignment: Qt.AlignTop
0062             Layout.fillWidth: true
0063             Layout.topMargin: -delegate.topPadding + delegate.topInset + extraBorder
0064             Layout.leftMargin: -delegate.leftPadding + delegate.leftInset + extraBorder
0065             Layout.rightMargin: -delegate.rightPadding + delegate.rightInset + extraBorder
0066             // Any width times 0.5625 is a 16:9 ratio
0067             // Adding baseRadius is needed to prevent the bottom from being rounded
0068             Layout.preferredHeight: width * 0.5625 + delegate.baseRadius
0069             // FIXME: another thing copied from AbstractDelegate
0070             property real extraBorder: 0
0071 
0072             layer.enabled: true
0073             layer.effect: OpacityMask {
0074                 cached: true
0075                 maskSource: Rectangle {
0076                     x: imgRoot.x;
0077                     y: imgRoot.y
0078                     width: imgRoot.width
0079                     height: imgRoot.height
0080                     radius: delegate.baseRadius
0081                 }
0082             }
0083 
0084             Image {
0085                 id: img
0086                 source: modelData.videoImage
0087                 anchors {
0088                     fill: parent
0089                     // To not round under
0090                     bottomMargin: delegate.baseRadius
0091                 }
0092                 opacity: 1
0093                 fillMode: Image.PreserveAspectCrop
0094 
0095                 Rectangle {
0096                     id: videoDurationTime
0097                     anchors.bottom: parent.bottom
0098                     anchors.bottomMargin: Kirigami.Units.largeSpacing
0099                     anchors.right: parent.right
0100                     anchors.rightMargin: Kirigami.Units.largeSpacing
0101                     // FIXME: kind of hacky to get the padding around the text right
0102                     width: durationText.width + Kirigami.Units.largeSpacing
0103                     height: Kirigami.Units.gridUnit
0104                     radius: delegate.baseRadius
0105                     color: Qt.rgba(0, 0, 0, 0.8)
0106 
0107                     Label {
0108                         id: durationText
0109                         anchors.centerIn: parent
0110                         text: modelData.videoDuration
0111                         color: Kirigami.Theme.textColor
0112                     }
0113                 }
0114             }
0115             
0116             states: [
0117                 State {
0118                     when: delegate.isCurrent
0119                     PropertyChanges {
0120                         target: imgRoot
0121                         extraBorder: delegate.borderSize
0122                     }
0123                 },
0124                 State {
0125                     when: !delegate.isCurrent
0126                     PropertyChanges {
0127                         target: imgRoot
0128                         extraBorder: 0
0129                     }
0130                 }
0131             ]
0132             transitions: Transition {
0133                 onRunningChanged: {
0134                     // Optimize when animating the thumbnail
0135                     img.smooth = !running
0136                 }
0137                 NumberAnimation {
0138                     property: "extraBorder"
0139                     duration: Kirigami.Units.longDuration
0140                     easing.type: Easing.InOutQuad
0141                 }
0142             }
0143         }
0144 
0145         ColumnLayout {
0146             Layout.fillWidth: true
0147             Layout.fillHeight: true
0148             // Compensate for blank space created from not rounding thumbnail bottom corners
0149             Layout.topMargin: -delegate.baseRadius
0150             Layout.alignment: Qt.AlignLeft | Qt.AlignTop
0151             spacing: Kirigami.Units.smallSpacing
0152 
0153             Kirigami.Heading {
0154                 id: videoLabel
0155                 Layout.fillWidth: true
0156                 Layout.alignment: Qt.AlignLeft | Qt.AlignTop
0157                 wrapMode: Text.Wrap
0158                 level: 3
0159                 //verticalAlignment: Text.AlignVCenter
0160                 maximumLineCount: 1
0161                 elide: Text.ElideRight
0162                 color: Kirigami.Theme.textColor
0163                 Component.onCompleted: {
0164                     text = modelData.videoTitle
0165                 }
0166             }
0167 
0168             Label {
0169                 id: videoChannelName
0170                 Layout.fillWidth: true
0171                 wrapMode: Text.WordWrap
0172                 Layout.alignment: Qt.AlignLeft | Qt.AlignTop
0173                 maximumLineCount: 1
0174                 elide: Text.ElideRight
0175                 color: Kirigami.Theme.textColor
0176                 text: modelData.videoChannel
0177             }
0178 
0179             RowLayout {
0180                 Layout.fillWidth: true
0181 
0182                 Label {
0183                     id: videoViews
0184                     Layout.alignment: Qt.AlignLeft
0185                     Layout.rightMargin: Kirigami.Units.largeSpacing
0186                     elide: Text.ElideRight
0187                     color: Kirigami.Theme.textColor
0188                     text: modelData.videoViews
0189                 }
0190 
0191                 Label {
0192                     id: videoUploadDate
0193                     Layout.fillWidth: true
0194                     Layout.alignment: Qt.AlignRight | Qt.AlignTop
0195                     horizontalAlignment: Text.AlignRight
0196                     elide: Text.ElideRight
0197                     color: Kirigami.Theme.textColor
0198                     text: modelData.videoUploadDate
0199                 }
0200             }
0201         }
0202     }
0203 
0204     onClicked: {
0205         listView.forceActiveFocus()
0206         listView.currentIndex = index
0207         busyIndicatorPop.open()
0208         Mycroft.MycroftController.sendRequest("aiix.youtube-skill.playvideo_id", {vidID: modelData.videoID, vidTitle: modelData.videoTitle, vidImage: modelData.videoImage, vidChannel: modelData.videoChannel, vidViews: modelData.videoViews, vidUploadDate: modelData.videoUploadDate, vidDuration: modelData.videoDuration})
0209     }
0210 }