Warning, /multimedia/audiotube/src/contents/ui/MaximizedPlayerPage.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2020-2022 Devin Lin <devin@kde.org>
0002 //
0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 
0005 import QtQuick 2.15
0006 import QtQuick.Effects
0007 import QtQuick.Controls 2.15
0008 import QtQuick.Layouts 1.15
0009 
0010 import QtMultimedia
0011 
0012 import org.kde.kirigami 2.19 as Kirigami
0013 import org.kde.kirigamiaddons.components 1.0 as Components
0014 import org.kde.ytmusic 1.0
0015 
0016 import "dialogs"
0017 
0018 Item {
0019     id: root
0020 
0021     required property var info // VideoInfoExtractor object
0022     required property var audio // Audio object
0023     required property string thumbnail
0024     readonly property bool isWidescreen: width >= Kirigami.Units.gridUnit * 50
0025 
0026     signal requestClose()
0027 
0028     onWidthChanged: {sideDrawer.Layout.minimumWidth = -1}
0029 
0030     // background image
0031 
0032     Item {
0033         id: bg
0034         anchors.fill: parent
0035         clip: true
0036 
0037         Rectangle {
0038             anchors.fill: parent
0039             color: Qt.rgba(25, 25, 30, 1)
0040         }
0041 
0042         Image {
0043             scale: 1.8
0044             anchors.fill: parent
0045             asynchronous: true
0046 
0047             source: root.thumbnail
0048             fillMode: Image.PreserveAspectCrop
0049 
0050             sourceSize.width: 512
0051             sourceSize.height: 512
0052         }
0053     }
0054     MultiEffect {
0055         source: bg
0056         anchors.fill: bg
0057 
0058         brightness: -0.25
0059         saturation: 0.5
0060 
0061         blurEnabled: true
0062         autoPaddingEnabled: false
0063         blur: 1.0
0064         blurMax: 40
0065         blurMultiplier: 3.0
0066     }
0067 
0068     Rectangle {
0069         anchors.fill: parent
0070         gradient: Gradient{
0071             GradientStop { position: 0.0; color: "transparent" }
0072             GradientStop { position: 1.1; color: "black"  }
0073         }
0074     }
0075 
0076     // content
0077     RowLayout {
0078         anchors.fill: parent
0079 
0080         ColumnLayout {
0081             id: mainContent
0082             Layout.fillWidth: true
0083             // hide arrow button
0084             ToolButton {
0085                 id: closeButton
0086 
0087                 Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
0088                 Layout.maximumHeight: parent.height
0089                 Layout.preferredHeight: Kirigami.Units.gridUnit * 3
0090                 Layout.maximumWidth: parent.height
0091                 Layout.preferredWidth: Kirigami.Units.gridUnit * 3
0092                 Layout.topMargin: Kirigami.Units.smallSpacing
0093 
0094                 icon.name: "arrow-down"
0095                 icon.color: "white"
0096                 Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0097                 Kirigami.Theme.inherit: false
0098                 onClicked: root.requestClose()
0099                 text: i18n("Close Maximized Player")
0100                 display: ToolButton.IconOnly
0101 
0102                 ToolTip.text: text
0103                 ToolTip.delay: Kirigami.Units.toolTipDelay
0104                 ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0105             }
0106 
0107             SwipeView {
0108                 interactive: false
0109                 Layout.fillHeight: true
0110                 Layout.fillWidth: true
0111                 clip:true
0112                 id: swipeView
0113                 property double specWidth: {
0114                     let allowedWidth = root.width - Kirigami.Units.largeSpacing * 4;
0115                     let allowedHeight = root.height - Kirigami.Units.largeSpacing * 16 - (closeButton.height + bottomPlayerControls.height);
0116                     if (allowedWidth > allowedHeight) {
0117                         return allowedHeight;
0118                     } else {
0119                         return allowedWidth;
0120                     }
0121                 }
0122                 Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
0123                 Layout.preferredHeight: specWidth
0124 
0125                 // music art
0126                 Flickable {
0127                     flickableDirection: Flickable.HorizontalFlick
0128                     clip: true
0129                     contentWidth: coverArt.width
0130                     contentHeight: coverArt.height
0131                     height: swipeView.height
0132                     width: applicationWindow().width-sideDrawer.width
0133                     onFlickEnded:{
0134 
0135                         if(horizontalVelocity<0){
0136                             UserPlaylistModel.next()
0137                         }
0138                         else{
0139                             if(UserPlaylistModel.canSkipBack){
0140                                 UserPlaylistModel.previous()
0141                             }
0142                         }
0143                     }
0144                     Item {
0145                         height: swipeView.height
0146                         width: applicationWindow().width-sideDrawer.width
0147                         Kirigami.ShadowedRectangle {
0148                            id: coverArt
0149                            x: 4
0150                            anchors.centerIn: parent
0151                            width: swipeView.specWidth
0152                            height: swipeView.specWidth
0153 
0154                            visible: root.thumbnail.toString() !== ""
0155 
0156                             color: "transparent"
0157                             radius: 10
0158                             shadow.size: 15
0159                             shadow.xOffset: 5
0160                             shadow.yOffset: 5
0161                             shadow.color: Qt.rgba(0, 0, 0, 0.2)
0162                             RoundedImage {
0163                                 source: root.thumbnail
0164                                 height: parent.height
0165                                 width: height
0166                                 radius: 10
0167                             }
0168                         }
0169                     }
0170                 }
0171 
0172                 ColumnLayout {
0173                     width: swipeView.width
0174                     height: swipeView.height
0175                     ScrollView {
0176                         Layout.maximumWidth: 900
0177                         contentWidth: -1
0178                         contentHeight: lyrics.implicitHeight
0179                         Layout.fillWidth: true
0180                         Layout.fillHeight: true
0181                         Layout.alignment: Qt.AlignHCenter
0182                         clip: true
0183 
0184                         //contentY: audio.position / audio.duration
0185 
0186                         Label {
0187                             id: lyrics
0188                             padding: 20
0189                             text: UserPlaylistModel.lyrics
0190                             color: "white"
0191                         }
0192                     }
0193                 }
0194             }
0195 
0196             ColumnLayout {
0197                 id: bottomPlayerControls
0198                 Layout.topMargin: Kirigami.Units.largeSpacing
0199                 Layout.leftMargin: Kirigami.Units.gridUnit * 2
0200                 Layout.rightMargin: Kirigami.Units.gridUnit * 2
0201                 Layout.bottomMargin: Kirigami.Units.gridUnit * 0.5
0202 
0203                 // song name
0204                 Label {
0205                     id: mainLabel
0206                     text: info.title ? info.title : i18n("No media playing")
0207 
0208                     Layout.fillWidth: true
0209 
0210                     horizontalAlignment: Text.AlignHCenter
0211                     elide: Text.ElideRight
0212                     maximumLineCount: 1
0213                     // Hardcoded because the footerbar blur always makes a dark-ish
0214                     // background, so we don't want to use a color scheme color that
0215                     // might also be dark
0216                     color: "white"
0217                     font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.5
0218                     font.weight: Font.Bold
0219                     font.bold: true
0220                 }
0221 
0222                 // song artist
0223                 Kirigami.Heading {
0224                     id: authorLabel
0225                     text: info.artist ? info.artist : info.channel
0226                     color: Kirigami.Theme.disabledTextColor
0227 
0228                     Layout.fillWidth: true
0229                     Layout.maximumWidth:600
0230                     Layout.alignment: Qt.AlignHCenter
0231                     horizontalAlignment: Text.AlignHCenter
0232                     elide: Text.ElideRight
0233                     maximumLineCount: 1
0234                     // Hardcoded because the footerbar blur always makes a dark-ish
0235                     // background, so we don't want to use a color scheme color that
0236                     // might also be dark
0237                     opacity: 0.9
0238                     font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.3
0239                     font.bold: true
0240                     Layout.bottomMargin: Kirigami.Units.gridUnit
0241                 }
0242                 RowLayout {
0243                     Layout.topMargin: Kirigami.Units.gridUnit
0244 
0245                     id: controlButtonBox
0246                     Layout.alignment: Qt.AlignHCenter
0247                     Layout.fillHeight: true
0248                     spacing: 2
0249 
0250 
0251                     Button {
0252                         id: skipBackwardButton
0253                         focusPolicy: Qt.TabFocus
0254                         implicitHeight: 40
0255                         implicitWidth: 40
0256 
0257                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0258                         Kirigami.Theme.inherit: false
0259 
0260                         enabled: UserPlaylistModel.canSkipBack
0261                         onClicked: UserPlaylistModel.previous()
0262                         contentItem: Item{
0263                             Kirigami.Icon {
0264                                 anchors.centerIn:parent
0265                                 source:"media-skip-backward"
0266                                 color: "white"
0267                                 width: Kirigami.Units.gridUnit
0268                                 height: Kirigami.Units.gridUnit
0269 
0270                             }
0271                         }
0272                         background: Kirigami.ShadowedRectangle{
0273                             border.color: Kirigami.Theme.hoverColor
0274                             border.width: skipBackwardButton.activeFocus? 1 :0
0275                             corners.topLeftRadius: 7
0276                             corners.bottomLeftRadius: 7
0277 
0278 
0279                             color: if (parent.down){
0280                                     Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3)
0281                                 }else if(parent.hovered){
0282                                     Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7)
0283                                 }else{
0284                                     Qt.rgba(1, 1, 1, 0.2)
0285                                 }
0286                         }
0287                     }
0288 
0289                     Button {
0290                         id: playPauseButton
0291                         focusPolicy: Qt.TabFocus
0292                         implicitHeight: 40
0293                         implicitWidth: 60
0294                         enabled: info.title
0295                         onClicked: audio.playbackState === MediaPlayer.PlayingState ? audio.pause() : audio.play()
0296                         contentItem: Item{
0297                             Kirigami.Icon {
0298                                 anchors.centerIn:parent
0299                                 source: audio.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start"
0300                                 color: "white"
0301                                 width: Kirigami.Units.gridUnit
0302                                 height: Kirigami.Units.gridUnit
0303                             }
0304                         }
0305                         background: Kirigami.ShadowedRectangle{
0306                             border.color: Kirigami.Theme.hoverColor
0307                             border.width: playPauseButton.activeFocus? 1 :0
0308                             color: if (parent.down){
0309                                     Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3)
0310                                 }else if(parent.hovered){
0311                                     Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7)
0312                                 }else{
0313                                     Qt.rgba(1, 1, 1, 0.2)
0314                                 }
0315                         }
0316                     }
0317 
0318                     Button {
0319                         id: skipForwardButton
0320                         focusPolicy: Qt.TabFocus
0321                         implicitHeight: 40
0322                         implicitWidth: 40
0323                         Layout.rightMargin:isWidescreen?0:10
0324 
0325                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0326                         Kirigami.Theme.inherit: false
0327 
0328                         enabled: UserPlaylistModel.canSkip
0329                         onClicked: UserPlaylistModel.next()
0330                         contentItem: Item{
0331                             Kirigami.Icon {
0332                                 anchors.centerIn:parent
0333                                 source:"media-skip-forward"
0334                                 color: "white"
0335                                 width: Kirigami.Units.gridUnit
0336                                 height: Kirigami.Units.gridUnit
0337 
0338                             }
0339                         }
0340                         background: Kirigami.ShadowedRectangle{
0341                             border.color: Kirigami.Theme.hoverColor
0342                             border.width: skipForwardButton.activeFocus? 1 :0
0343                             corners.topRightRadius: 7
0344                             corners.bottomRightRadius: 7
0345                             color: if (parent.down){
0346                                     Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3)
0347                                 }else if(parent.hovered){
0348                                     Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7)
0349                                 }else{
0350                                     Qt.rgba(1, 1, 1, 0.2)
0351                                 }
0352                         }
0353                     }
0354                 }
0355                 // slider row
0356                 RowLayout {
0357                     Layout.topMargin: Kirigami.Units.gridUnit
0358                     spacing: Kirigami.Units.smallSpacing
0359 
0360                     Label {
0361                         Layout.alignment: Qt.AlignVCenter
0362                         color: "white"
0363                         visible: info.title
0364                         text: PlayerUtils.formatTimestamp(audio.position)
0365                     }
0366 
0367                     Slider {
0368                         Layout.alignment: Qt.AlignVCenter
0369                         Layout.fillWidth: true
0370                         from: 0
0371                         to: audio.duration
0372                         value: audio.position
0373                         enabled: audio.seekable
0374                         onMoved: {
0375                             console.log("Value:", value);
0376                             audio.position = Math.floor(value);
0377                         }
0378 
0379                         Behavior on value {
0380                             NumberAnimation {
0381                                 duration: 1000
0382                             }
0383                         }
0384                     }
0385 
0386                     Label {
0387                         Layout.alignment: Qt.AlignVCenter
0388                         color: "white"
0389                         visible: info.title
0390                         text: PlayerUtils.formatTimestamp(audio.duration)
0391                     }
0392                 }
0393 
0394                 RowLayout {
0395                     Layout.topMargin: Kirigami.Units.largeSpacing
0396                     Layout.fillWidth: true
0397                     // ensure white icons
0398                     Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0399                     Kirigami.Theme.inherit: false
0400                     Item {
0401                         width: queueButton.width
0402                         visible: wideScreen
0403                     }
0404 
0405                     Item { Layout.fillWidth: true}
0406 
0407                     ToolButton {
0408                         id: favouriteButton
0409                         readonly property QtObject favouriteWatcher: Library.favouriteWatcher(info.videoId)
0410                         Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
0411                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0412                         Layout.maximumWidth: height
0413                         Layout.preferredWidth: height
0414                         onClicked: {
0415                             if (favouriteWatcher) {
0416                                 if (favouriteWatcher.isFavourite) {
0417                                     Library.removeFavourite(info.videoId)
0418                                     // This would insert slightly ugly data into the database, but let's hope the song is already saved
0419                                 } else {
0420                                     let index = UserPlaylistModel.index(UserPlaylistModel.currentIndex, 0)
0421                                     let videoId = UserPlaylistModel.data(index, UserPlaylistModel.VideoId)
0422                                     let title = UserPlaylistModel.data(index, UserPlaylistModel.Title)
0423                                     let artist = UserPlaylistModel.data(index, UserPlaylistModel.Artists)
0424                                     let album = UserPlaylistModel.data(index, UserPlaylistModel.Album)
0425                                     Library.addFavourite(videoId, title, artist, album)
0426                                 }
0427                             }
0428                         }
0429                         text: favouriteWatcher ? (favouriteWatcher.isFavourite ? i18n("Remove from Favourites") : i18n("Add to Favourites")) : i18n("Add to Favourites")
0430                         icon.name: favouriteWatcher ? (favouriteWatcher.isFavourite ? "starred-symbolic" : "non-starred-symbolic") : "non-starred-symbolic"
0431                         enabled: favouriteWatcher
0432                         icon.color: "white"
0433                         display: AbstractButton.IconOnly
0434 
0435                         ToolTip.text: text
0436                         ToolTip.delay: Kirigami.Units.toolTipDelay
0437                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0438 
0439                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0440                         Kirigami.Theme.inherit: false
0441                     }
0442 
0443                     ToolButton {
0444                         id: volumeButtonSmallScreen
0445                         Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0446                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0447                         Layout.maximumWidth: height
0448                         Layout.preferredWidth: height
0449                         visible: !isWidescreen
0450                         enabled: !isWidescreen
0451 
0452                         icon.name: muteButton.icon.name
0453 
0454                         text: i18n("Open Volume Drawer")
0455                         display: AbstractButton.IconOnly
0456                         ToolTip.text: text
0457                         ToolTip.delay: Kirigami.Units.toolTipDelay
0458                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0459 
0460                         onClicked:{
0461                             if(!volumeDrawer.opened){
0462                                 volumeDrawer.open()
0463                             }
0464                             else{
0465                                 volumeDrawer.close()
0466                             }
0467                         }
0468                         Components.BottomDrawer {
0469                             id: volumeDrawer
0470 
0471                             parent: applicationWindow().overlay
0472 
0473                             drawerContentItem: RowLayout {
0474                                 ToolButton {
0475                                     Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0476                                     Layout.maximumWidth: height
0477                                     Layout.preferredWidth: height
0478 
0479                                     icon.name: muteButton.icon.name
0480                                     checkable: true
0481                                     checked: muteButton.checked
0482                                     text: muteButton.text
0483                                     display: muteButton.display
0484 
0485                                     ToolTip.text: text
0486                                     ToolTip.delay: Kirigami.Units.toolTipDelay
0487                                     ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0488 
0489                                     onClicked: {
0490                                         if(audio.muted)
0491                                         {
0492                                             muteButton.unmuteAudio()
0493                                         }
0494                                         else
0495                                         {
0496                                             muteButton.muteAudio()
0497                                         }
0498                                     }
0499                                 }
0500 
0501                                 Slider {
0502                                     id: slider
0503                                     value: volumeSlider.value
0504                                     opacity: volumeSlider.opacity
0505                                     wheelEnabled: true
0506 
0507                                     Layout.fillWidth: true
0508                                     Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0509 
0510                                     onMoved: {
0511                                         volumeSlider.value = value
0512                                         volumeSlider.valueChanged()
0513                                     }
0514                                 }
0515 
0516                                 Label {
0517                                     Layout.preferredHeight: slider.height
0518                                     Layout.preferredWidth: Kirigami.Units.gridUnit * 2.5
0519 
0520                                     text: volumeLabel.text
0521                                 }
0522                             }
0523                         }
0524                     }
0525 
0526                     ToolButton {
0527                         id: muteButton
0528 
0529                         function muteAudio() {
0530                             audioOutput.muted = true
0531                             volumeSlider.opacity = 0.5
0532                             checked = true
0533                         }
0534                         function unmuteAudio() {
0535                             audioOutput.muted = false
0536                             volumeSlider.opacity = 1
0537                             checked = false
0538                         }
0539 
0540                         Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0541                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0542                         Layout.maximumWidth: height
0543                         Layout.preferredWidth: height
0544 
0545                         onClicked: {
0546                             if(audioOutput.muted) {
0547                                 unmuteAudio()
0548                             }
0549                             else {
0550                                 muteAudio()
0551                             }
0552                         }
0553 
0554                         icon.name: audioOutput.muted ? "audio-volume-muted" : (volumeSlider.value < .33 ? "audio-volume-low" : (volumeSlider.value < .66 ? "audio-volume-medium" : "audio-volume-high"))
0555                         icon.color: "white"
0556 
0557                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0558                         Kirigami.Theme.inherit: false
0559 
0560                         checkable: true
0561                         visible: isWidescreen
0562                         enabled: isWidescreen
0563                         text: audioOutput.muted ? i18n("Unmute Audio") : i18n("Mute Audio")
0564                         display: AbstractButton.IconOnly
0565 
0566                         ToolTip.text: text
0567                         ToolTip.delay: Kirigami.Units.toolTipDelay
0568                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0569                     }
0570 
0571                     Slider {
0572                         id: volumeSlider
0573                         enabled: isWidescreen
0574                         visible: isWidescreen
0575 
0576                         property real volume: PlayerUtils.convertVolume(value)
0577 
0578                         Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0579                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0580                         Layout.preferredWidth: 2*Layout.preferredHeight
0581 
0582                         value: 1.0
0583                         from: 0.0
0584                         to: 1.0
0585                         wheelEnabled: true
0586 
0587                         onMoved: {
0588                             audioOutput.volume = volumeSlider.volume
0589                             if (volumeSlider.value === 0) {
0590                                 muteButton.muteAudio()
0591                             } else {
0592                                 muteButton.unmuteAudio()
0593                             }
0594                         }
0595                     }
0596 
0597                     Label {
0598                         id: volumeLabel
0599 
0600                         enabled: isWidescreen
0601                         visible: isWidescreen
0602                         text: i18n("%1%", Math.round(volumeSlider.value*100))
0603 
0604                         Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0605                         Layout.preferredWidth: Kirigami.Units.gridUnit * 2.5
0606                     }
0607 
0608                     ToolButton {
0609                         property bool lyricsShown: false
0610                         id: lyricsButton
0611                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0612                         Layout.maximumWidth: height
0613                         Layout.preferredWidth: height
0614                         checked: lyricsShown
0615                         onClicked: {
0616                                 if (!lyricsShown)
0617                                     swipeView.setCurrentIndex(1)
0618                                 else{
0619                                     swipeView.setCurrentIndex(0)
0620                                 }
0621                                 lyricsShown = !lyricsShown
0622                         }
0623                         Connections {
0624                             target: UserPlaylistModel
0625                             function onNoLyrics() {
0626                                 if(lyricsButton.lyricsShown) {
0627                                     lyricsButton.clicked()
0628                                 }
0629                             }
0630                         }
0631                         enabled: UserPlaylistModel.lyrics
0632                         text: lyricsShown ? i18n("Hide Lyrics") : i18n("Show Lyrics")
0633                         icon.name: "view-media-lyrics"
0634                         icon.color: "white"
0635                         display: AbstractButton.IconOnly
0636 
0637                         ToolTip.text: text
0638                         ToolTip.delay: Kirigami.Units.toolTipDelay
0639                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0640 
0641                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0642                         Kirigami.Theme.inherit: false
0643                     }
0644                     ToolButton {
0645 
0646                         id: shareButton
0647                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0648                         Layout.maximumWidth: height
0649                         Layout.preferredWidth: height
0650                         onClicked: openShareMenu(info.title, UserPlaylistModel.webUrl)
0651 
0652                         text: i18n("Share Song")
0653                         icon.name: "emblem-shared-symbolic"
0654                         icon.color: "white"
0655                         display: AbstractButton.IconOnly
0656 
0657                         ToolTip.text: text
0658                         ToolTip.delay: Kirigami.Units.toolTipDelay
0659                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0660 
0661                         enabled: info.title
0662 
0663                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0664                         Kirigami.Theme.inherit: false
0665                     }
0666 
0667                     PlaylistDialog {
0668                         id: playlistsDialog
0669                     }
0670                     ToolButton {
0671                         id: addToPlaylistButton
0672                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0673                         Layout.maximumWidth: height
0674                         Layout.preferredWidth: height
0675                         enabled: info.videoId
0676 
0677                         onClicked: {
0678                             let index = UserPlaylistModel.index(UserPlaylistModel.currentIndex, 0)
0679                             let videoId = UserPlaylistModel.data(index, UserPlaylistModel.VideoId)
0680                             let title = UserPlaylistModel.data(index, UserPlaylistModel.Title)
0681                             let artist = UserPlaylistModel.data(index, UserPlaylistModel.Artists)
0682                             let album = UserPlaylistModel.data(index, UserPlaylistModel.Album)
0683                             playlistsDialog.videoId = videoId
0684                             playlistsDialog.songTitle = title
0685                             playlistsDialog.artists = artist
0686                             playlistsDialog.album = album
0687 
0688                             playlistsDialog.open()
0689                         }
0690 
0691                         icon.name: "media-playlist-append"
0692                         icon.color: "white"
0693                         text: i18n("Add to a local playlist")
0694                         display: AbstractButton.IconOnly
0695 
0696                         ToolTip.text: text
0697                         ToolTip.delay: Kirigami.Units.toolTipDelay
0698                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0699 
0700                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0701                         Kirigami.Theme.inherit: false
0702                     }
0703                     Item {
0704                         Layout.fillWidth: true
0705                         visible: wideScreen
0706                     }
0707 
0708                     ToolButton {
0709                         id: queueButton
0710                         Layout.alignment: Qt.AlignRight
0711                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0712                         Layout.maximumWidth: height
0713                         Layout.preferredWidth: height
0714                         checked: !sideDrawer.collapsed && wideScreen
0715                         enabled: playListView.count != 0 || !sideDrawer.collapsed
0716 
0717                         onClicked: {
0718                             if (wideScreen) {
0719                                 if (!sideDrawer.collapsed)
0720                                     collapse.running = true
0721                                 else{
0722                                     sideDrawer.visible=true
0723                                     show.running = true
0724                                 }
0725                                 sideDrawer.collapsed = !sideDrawer.collapsed
0726                             }else{queueDrawer.open()}
0727                             checked = !sideDrawer.collapsed && wideScreen
0728                         }
0729 
0730                         text: checked ? i18n("Hide Queue") : i18n("Show Queue")
0731                         display: AbstractButton.IconOnly
0732 
0733                         ToolTip.text: text
0734                         ToolTip.delay: Kirigami.Units.toolTipDelay
0735                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0736 
0737                         icon.name: "amarok_playlist"
0738                         icon.color: "white"
0739 
0740                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0741                         Kirigami.Theme.inherit: false
0742                     }
0743 
0744                     Item {
0745                         Layout.fillWidth: true
0746                         visible: !wideScreen
0747                     }
0748 
0749                 }
0750             }
0751         }
0752 
0753         Item {
0754             onWidthChanged: if(!wideScreen) {collapse.running=true; collapsed=true; queueButton.checked=false}
0755             property bool collapsed: true
0756             id: sideDrawer
0757             Layout.fillWidth: true
0758             Layout.maximumWidth: -1
0759             Layout.preferredWidth: Math.max(350, root.width/3)
0760 
0761             Layout.fillHeight: true
0762             visible: false
0763             NumberAnimation on Layout.maximumWidth {
0764                 id: collapse
0765                 easing.type: Easing.OutCubic
0766                 running: false
0767                 from: Math.min(sideDrawer.Layout.preferredWidth, sideDrawer.Layout.maximumWidth); to: 0
0768                 onFinished: { sideDrawer.visible=false}
0769             }
0770             NumberAnimation on Layout.maximumWidth {
0771                 id: show
0772                 easing.type: Easing.OutCubic
0773                 running: false
0774                 from: 0; to: Math.min(sideDrawer.Layout.preferredWidth, root.width - mainContent.Layout.minimumWidth)
0775                 //onFinished: { sideDrawer.visible=false}
0776             }
0777             Kirigami.Separator{
0778                 color: "white"
0779                 opacity: 0.3
0780                 height: parent.height
0781                 anchors.left: parent.left
0782 
0783             }
0784             Rectangle{
0785                 anchors.fill: parent
0786                 color: "white"
0787                 opacity: 0.2
0788             }
0789 
0790             MouseArea {
0791                 id: queueResizer
0792 
0793                 anchors.horizontalCenter: parent.left
0794                 anchors.top: parent.top
0795                 anchors.bottom: parent.bottom
0796                 width: Kirigami.Units.gridUnit
0797 
0798                 cursorShape: Qt.SplitHCursor
0799                 onPositionChanged: {
0800                     if(Math.max(sideDrawer.width - (mouse.x - width/2), queueFooter.Layout.minimumWidth) + mainContent.Layout.minimumWidth < root.width){
0801                         sideDrawer.Layout.preferredWidth = sideDrawer.Layout.minimumWidth = sideDrawer.Layout.maximumWidth = Math.max(sideDrawer.width - (mouse.x - width/2), queueFooter.Layout.minimumWidth)
0802                     }
0803                 }
0804             }
0805 
0806             ColumnLayout {
0807                 spacing: 0
0808                 anchors.fill: parent
0809                 ScrollView {
0810                     id: playListScrollView
0811 
0812                     contentWidth: availableWidth
0813 
0814                     Layout.fillWidth: true
0815                     Layout.fillHeight: true
0816                         Layout.leftMargin:10
0817                     ListView {
0818                         id: playListView
0819 
0820                         reuseItems: true
0821 
0822                         spacing: 5
0823                         rightMargin: 10
0824                         topMargin:10
0825                         bottomMargin: 10
0826                         clip: true
0827                         contentWidth: playListScrollView.contentWidth - rightMargin - leftMargin
0828 
0829                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
0830                         Kirigami.Theme.inherit: false
0831 
0832                         BusyIndicator {
0833                             anchors.centerIn: parent
0834                             visible: UserPlaylistModel.loading || UserPlaylistModel.loading
0835                         }
0836 
0837                         model: UserPlaylistModel
0838 
0839                         moveDisplaced: Transition {
0840                             YAnimator {
0841                                 duration: Kirigami.Units.mediumDuration
0842                                 easing.type: Easing.InOutQuad
0843                             }
0844                         }
0845 
0846                         delegate: Item{
0847                             //listItemDragHandle requires queueEntry to be a child of the delegate, and not the delegate itself
0848                             id: delegateItem
0849 
0850                             required property string title
0851                             required property string videoId
0852                             required property string artists
0853                             required property bool isCurrent
0854                             required property int index
0855                             width: queueEntry.implicitWidth
0856                             height: queueEntry.implicitHeight
0857 
0858                             ItemDelegate {
0859                                 id: queueEntry
0860 
0861                                 width: playListView.contentWidth
0862 
0863                                 background: Rectangle{
0864                                     radius: 7
0865                                     color:
0866                                     if (parent.down){
0867                                         Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.3)
0868                                     }else if(parent.hovered){
0869                                         Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7)
0870                                     }else if(parent.highlighted){
0871                                         Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.hoverColor, "transparent", 0.7)
0872                                     }else{
0873                                         Qt.rgba(0, 0, 0, 0.4)
0874                                     }
0875 
0876                                     border.color:
0877                                     if (parent.down){
0878                                         Kirigami.Theme.hoverColor
0879                                     }else if(parent.hovered){
0880                                         Kirigami.Theme.hoverColor
0881                                     }else{
0882                                         Qt.rgba(1, 1, 1, 0)
0883                                     }
0884 
0885                                     border.width: 1
0886                                 }
0887                                 highlighted: isCurrent
0888                                 onClicked: UserPlaylistModel.skipTo(videoId)
0889                                 contentItem: RowLayout {
0890                                     id: contentLayout
0891 
0892                                     Item {
0893                                         width: handle.width
0894                                         height: handle.height
0895                                         Kirigami.ListItemDragHandle {
0896                                             id: handle
0897                                             Layout.fillHeight: true
0898                                             listItem: queueEntry
0899                                             listView: playListView
0900                                             onMoveRequested: UserPlaylistModel.moveRow(oldIndex, newIndex)
0901                                         }
0902                                         Rectangle {
0903                                             anchors.fill: handle
0904                                             layer.enabled: true
0905                                             layer.effect: MultiEffect {
0906                                                 maskSource: handle
0907                                                 maskEnabled: true
0908                                             }
0909                                         }
0910                                     }
0911                                     ThumbnailSource {
0912                                         id: delegateThumbnailSource
0913                                         videoId: delegateItem.videoId
0914                                     }
0915                                     RoundedImage {
0916                                         source: delegateThumbnailSource.cachedPath
0917                                         Layout.margins: 2.5
0918                                         height: column.implicitHeight
0919                                         width: column.implicitHeight
0920                                         radius: 5
0921                                     }
0922 
0923                                     ColumnLayout {
0924                                         id: column
0925                                         Layout.margins: 5
0926 
0927                                         Layout.fillWidth: true
0928                                         Layout.fillHeight: true
0929 
0930                                         Kirigami.Heading {
0931                                             elide: Text.ElideRight
0932                                             Layout.fillWidth: true
0933                                             level: 2
0934                                             text: title
0935 
0936                                             MouseArea {
0937                                                 anchors.fill: parent
0938                                                 hoverEnabled: true
0939                                                 ToolTip.text: parent.text
0940                                                 ToolTip.delay: Kirigami.Units.toolTipDelay
0941                                                 ToolTip.visible: parent.truncated ? (Kirigami.Settings.isMobile ? containsPress : containsMouse) : false
0942                                             }
0943                                         }
0944 
0945                                         Label {
0946                                             elide: Text.ElideRight
0947                                             Layout.fillWidth: true
0948                                             color: Kirigami.Theme.disabledTextColor
0949                                             text: artists
0950                                         }
0951 
0952                                     }
0953                                     ToolButton {
0954                                         text: i18n("Remove Track")
0955                                         icon.name: "list-remove"
0956                                         icon.color: "white"
0957                                         display: AbstractButton.IconOnly
0958                                         onClicked: UserPlaylistModel.remove(delegateItem.videoId)
0959                                     }
0960                                 }
0961                             }
0962                         }
0963                     }
0964                 }
0965 
0966 
0967                 Kirigami.Separator {
0968                     color: "white"
0969                     opacity: 0.3
0970                     Layout.fillWidth: true
0971                 }
0972 
0973                 RowLayout {
0974                     id: queueFooter
0975 
0976                     Layout.margins: Kirigami.Units.gridUnit * 0.5
0977                     enabled: playListView.count != 0
0978                     Item {
0979                         Layout.fillWidth: true
0980                     }
0981 
0982                     ToolButton {
0983                         id: clearPlaylistButton
0984 
0985                         Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
0986                         Layout.maximumWidth: height
0987                         Layout.preferredWidth: height
0988 
0989                         text: i18n("Clear Queue")
0990                         icon {
0991                             name: "edit-clear-all"
0992                             color: "white"
0993                         }
0994                         display: AbstractButton.IconOnly
0995 
0996                         ToolTip.text: text
0997                         ToolTip.delay: Kirigami.Units.toolTipDelay
0998                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
0999 
1000                         onClicked: UserPlaylistModel.clearExceptCurrent()
1001 
1002                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
1003                         Kirigami.Theme.inherit: false
1004                     }
1005 
1006                     ToolButton {
1007                         id: shuffleButton
1008                         Layout.preferredHeight: Math.round(Kirigami.Units.gridUnit * 2.5)
1009                         Layout.maximumWidth: height
1010                         Layout.preferredWidth: height
1011 
1012                         onClicked: UserPlaylistModel.shufflePlaylist()
1013 
1014                         text: i18n("Shuffle Queue")
1015 
1016                         ToolTip.text: text
1017                         ToolTip.delay: Kirigami.Units.toolTipDelay
1018                         ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
1019 
1020                         icon {
1021                             name: "media-playlist-shuffle"
1022                             color: "white"
1023                         }
1024                         display: AbstractButton.IconOnly
1025                         Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
1026                         Kirigami.Theme.inherit: false
1027                     }
1028 
1029                     Item {
1030                         Layout.fillWidth: true
1031                     }
1032                 }
1033             }
1034         }
1035 
1036         Components.BottomDrawer {
1037             id: queueDrawer
1038 
1039             parent: applicationWindow().overlay
1040 
1041             onClosed:{sideDrawer.collapsed=true}
1042             height: applicationWindow().height-50
1043             interactive: true
1044 
1045             headerContentItem: RowLayout {
1046                 Kirigami.Heading {
1047                     text: i18n("Upcoming Songs")
1048                     elide: Qt.ElideRight
1049                     Layout.margins: 0
1050                     Layout.fillWidth: true
1051                 }
1052                 Item {
1053                     Layout.fillWidth: true
1054                 }
1055                 ToolButton {
1056                     Layout.topMargin: 0
1057                     Layout.bottomMargin: 0
1058                     Layout.maximumWidth: height
1059                     Layout.preferredWidth: height
1060                     text: clearPlaylistButton.text
1061 
1062                     ToolTip.text: text
1063                     ToolTip.delay: Kirigami.Units.toolTipDelay
1064                     ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
1065 
1066                     icon.name: "edit-clear-all"
1067                     display: clearPlaylistButton.display
1068                     onClicked: {
1069                         UserPlaylistModel.clearExceptCurrent()
1070                     }
1071                     enabled: playListView.count != 0
1072                 }
1073 
1074                 ToolButton {
1075                     Layout.topMargin: 0
1076                     Layout.bottomMargin: 0
1077                     Layout.maximumWidth: height
1078                     Layout.preferredWidth: height
1079                     icon.name: "media-playlist-shuffle"
1080                     text: shuffleButton.text
1081                     display: shuffleButton.display
1082 
1083                     ToolTip.text: text
1084                     ToolTip.delay: Kirigami.Units.toolTipDelay
1085                     ToolTip.visible: Kirigami.Settings.isMobile ? pressed : hovered
1086 
1087                     onClicked: {
1088                         UserPlaylistModel.shufflePlaylist()
1089                     }
1090                     enabled: playListView.count != 0
1091                 }
1092             }
1093 
1094             drawerContentItem: ScrollView {
1095                 ListView {
1096                     id: drawerListView
1097                     topMargin: 10
1098                     clip: true
1099 
1100                     reuseItems: true
1101 
1102                     BusyIndicator {
1103                         anchors.centerIn: parent
1104                         visible: UserPlaylistModel.loading || UserPlaylistModel.loading
1105                     }
1106 
1107                     model: UserPlaylistModel
1108 
1109                     moveDisplaced: Transition {
1110                         YAnimator {
1111                             duration: Kirigami.Units.mediumDuration
1112                             easing.type: Easing.InOutQuad
1113                         }
1114                     }
1115 
1116                     delegate: Item {
1117                         id: drawerDelegateItem
1118                         required property string title
1119                         required property string videoId
1120                         required property string artists
1121                         required property bool isCurrent
1122                         required property int index
1123 
1124                         width: drawerListView.width
1125                         height: drawerQueueEntry.height
1126 
1127                         ItemDelegate {
1128                             id: drawerQueueEntry
1129 
1130                             width: parent.width
1131 
1132                             highlighted: drawerDelegateItem.isCurrent
1133                             onClicked: {
1134                                 queueDrawer.close()
1135                                 UserPlaylistModel.skipTo(drawerDelegateItem.videoId)
1136                             }
1137                             contentItem: RowLayout {
1138                                 Layout.fillWidth: true
1139                                 Item {
1140                                     width: drawerHandle.width
1141                                     height: drawerHandle.height
1142                                     Kirigami.ListItemDragHandle {
1143                                         id: drawerHandle
1144                                         Layout.fillHeight: true
1145                                         listItem: drawerQueueEntry
1146                                         listView: drawerListView
1147                                         onMoveRequested: UserPlaylistModel.moveRow(oldIndex, newIndex)
1148                                     }
1149 
1150                                     Rectangle {
1151                                         anchors.fill: drawerHandle
1152                                         layer.enabled: true
1153                                         layer.effect: MultiEffect {
1154                                             maskSource: drawerHandle
1155                                             maskEnabled: true
1156                                         }
1157                                     }
1158                                 }
1159                                 ThumbnailSource {
1160                                     id: drawerDelegateThumbnailSource
1161                                     videoId: drawerDelegateItem.videoId
1162                                 }
1163                                 RoundedImage {
1164                                     source: drawerDelegateThumbnailSource.cachedPath
1165 
1166                                     height: 50
1167                                     width: height
1168                                     radius: 5
1169                                 }
1170 
1171                                 ColumnLayout {
1172                                     Layout.margins: 5
1173                                     Layout.fillWidth: true
1174                                     Kirigami.Heading {
1175                                         elide: Text.ElideRight
1176                                         Layout.fillWidth: true
1177                                         level: 2
1178                                         text: drawerDelegateItem.title
1179 
1180                                         MouseArea {
1181                                             anchors.fill: parent
1182                                             hoverEnabled: true
1183                                             ToolTip.text: parent.text
1184                                             ToolTip.delay: Kirigami.Units.toolTipDelay
1185                                             ToolTip.visible: parent.truncated ? (Kirigami.Settings.isMobile ? containsPress : containsMouse) : false
1186                                         }
1187                                     }
1188 
1189                                     Label {
1190                                         elide: Text.ElideRight
1191                                         Layout.fillWidth: true
1192                                         color: Kirigami.Theme.disabledTextColor
1193                                         text: drawerDelegateItem.artists
1194                                     }
1195                                 }
1196 
1197                                 ToolButton {
1198                                     text: i18n("Remove Track")
1199                                     icon.name: "list-remove"
1200                                     display: AbstractButton.IconOnly
1201                                     onClicked: UserPlaylistModel.remove(drawerDelegateItem.videoId)
1202                                 }
1203                             }
1204                         }
1205                     }
1206                 }
1207             }
1208         }
1209     }
1210 }