Warning, /multimedia/kasts/src/qml/FeedDetailsPage.qml is written in an unsupported language. File is not indexed.

0001 /**
0002  * SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
0003  * SPDX-FileCopyrightText: 2021-2022 Bart De Vries <bart@mogwai.be>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006  */
0007 
0008 import QtQuick
0009 import QtQuick.Controls as Controls
0010 import QtQuick.Layouts
0011 
0012 import org.kde.kirigami as Kirigami
0013 
0014 import org.kde.kasts
0015 
0016 Kirigami.ScrollablePage {
0017     id: page
0018 
0019     LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
0020     LayoutMirroring.childrenInherit: true
0021 
0022     property QtObject feed;
0023     property bool isSubscribed: true
0024     property var subscribeAction: undefined // this is only used if instantiated from the discoverpage
0025 
0026     property bool showMoreInfo: false
0027 
0028     title: i18n("Podcast Details")
0029 
0030     Keys.onPressed: (event) => {
0031         if (event.matches(StandardKey.Find)) {
0032             searchActionButton.checked = true;
0033         }
0034     }
0035 
0036     supportsRefreshing: true
0037 
0038     onRefreshingChanged: {
0039         if (refreshing) {
0040             updateFeed.run()
0041         }
0042     }
0043 
0044     // Overlay dialog box showing options what to do on metered connections
0045     ConnectionCheckAction {
0046         id: updateFeed
0047 
0048         function action() {
0049             feed.refresh()
0050         }
0051 
0052         function abortAction() {
0053             page.refreshing = false
0054         }
0055     }
0056 
0057     // Make sure that this feed is also showing as "refreshing" on FeedListPage
0058     Connections {
0059         target: feed
0060         function onRefreshingChanged(refreshing) {
0061             if(!refreshing)
0062                 page.refreshing = refreshing
0063         }
0064     }
0065 
0066     actions: Kirigami.Action {
0067         id: searchActionButton
0068         icon.name: "search"
0069         text: i18nc("@action:intoolbar", "Search")
0070         checkable: true
0071         enabled: page.feed.entries ? true : false
0072         visible: enabled
0073     }
0074 
0075     header: Loader {
0076         anchors.right: parent.right
0077         anchors.left: parent.left
0078 
0079         active: searchActionButton.checked
0080         visible: active
0081 
0082         sourceComponent: SearchBar {
0083             proxyModel: page.feed.entries ? page.feed.entries : emptyListModel
0084             parentKey: searchActionButton
0085         }
0086     }
0087 
0088     ListModel {
0089         id: emptyListModel
0090         readonly property var filterType: AbstractEpisodeProxyModel.NoFilter
0091     }
0092 
0093     GenericEntryListView {
0094         id: entryList
0095         reuseItems: true
0096         currentIndex: -1
0097 
0098         model: page.feed.entries ? page.feed.entries : emptyListModel
0099         delegate: GenericEntryDelegate {
0100             listViewObject: entryList
0101         }
0102 
0103         header: ColumnLayout {
0104             id: headerColumn
0105             height: (isSubscribed && entryList.count > 0) ? implicitHeight : entryList.height
0106             width: entryList.width
0107             spacing: 0
0108 
0109             Kirigami.Theme.inherit: false
0110             Kirigami.Theme.colorSet: Kirigami.Theme.Window
0111 
0112             GenericHeader {
0113                 id: headerImage
0114                 Layout.fillWidth: true
0115 
0116                 property string authors: isSubscribed ? feed.authors : feed.author
0117 
0118                 image: isSubscribed ? feed.cachedImage : feed.image
0119                 title: isSubscribed ? feed.name : feed.title
0120                 subtitle: authors ? i18nc("by <author(s)>", "by %1", authors) : undefined
0121             }
0122 
0123             // header actions
0124             Controls.Control {
0125                 Layout.fillWidth: true
0126 
0127                 leftPadding: Kirigami.Units.largeSpacing
0128                 rightPadding: Kirigami.Units.largeSpacing
0129                 bottomPadding: Kirigami.Units.smallSpacing
0130                 topPadding: Kirigami.Units.smallSpacing
0131 
0132                 background: Rectangle {
0133                     Kirigami.Theme.inherit: false
0134                     Kirigami.Theme.colorSet: Kirigami.Theme.Header
0135                     color: Kirigami.Theme.backgroundColor
0136                 }
0137 
0138                 contentItem: Kirigami.ActionToolBar {
0139                     id: feedToolBar
0140                     alignment: Qt.AlignLeft
0141                     background: Item {}
0142 
0143                     // HACK: ActionToolBar loads buttons dynamically, and so the
0144                     // height calculation changes the position
0145                     onHeightChanged: entryList.contentY = entryList.originY
0146 
0147                     actions: [
0148                         Kirigami.Action {
0149                             visible: isSubscribed
0150                             icon.name: "view-refresh"
0151                             text: i18n("Refresh Podcast")
0152                             onTriggered: page.refreshing = true
0153                         },
0154                         Kirigami.Action {
0155                             icon.name: "kt-add-feeds"
0156                             text: enabled ? i18n("Subscribe") : i18n("Subscribed")
0157                             enabled: !DataManager.feedExists(feed.url)
0158                             visible: !isSubscribed
0159                             onTriggered: {
0160                                 DataManager.addFeed(feed.url);
0161                                 enabled = false;
0162                                 // Also disable button on discoverpage
0163                                 if (subscribeAction !== undefined) {
0164                                     subscribeAction.enabled = false;
0165                                 }
0166                             }
0167                         },
0168                         Kirigami.Action {
0169                             icon.name: "documentinfo"
0170                             text: i18n("Show Details")
0171                             checkable: true
0172                             checked: showMoreInfo
0173                             onCheckedChanged: {
0174                                 showMoreInfo = checked;
0175                             }
0176                         }
0177                     ]
0178 
0179                     // add the default actions through onCompleted to add them
0180                     // to the ones defined above
0181                     Component.onCompleted: {
0182                         if (isSubscribed) {
0183                             for (var i in entryList.defaultActionList) {
0184                                 feedToolBar.actions.push(entryList.defaultActionList[i]);
0185                             }
0186                         }
0187                     }
0188                 }
0189             }
0190 
0191             Kirigami.Separator { Layout.fillWidth: true }
0192 
0193             // podcast description
0194             Controls.Control {
0195                 Layout.fillHeight: !isSubscribed
0196                 Layout.fillWidth: true
0197                 leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
0198                 rightPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
0199                 topPadding: Kirigami.Units.largeSpacing
0200                 bottomPadding: Kirigami.Units.largeSpacing
0201 
0202                 // HACK: opening more info changes the position of the header
0203                 onHeightChanged: entryList.contentY = entryList.originY
0204 
0205                 background: Rectangle {
0206                     color: Kirigami.Theme.backgroundColor
0207                 }
0208 
0209                 contentItem: ColumnLayout {
0210                     spacing: Kirigami.Units.smallSpacing
0211 
0212                     Controls.Label {
0213                         Layout.fillWidth: true
0214                         Layout.alignment: Qt.AlignTop
0215                         textFormat: page.showMoreInfo ? TextEdit.RichText : Text.StyledText
0216                         maximumLineCount: page.showMoreInfo ? undefined : 2
0217                         elide: Text.ElideRight
0218                         text: feed.description
0219                         font.pointSize: Kirigami.Theme.defaultFont.pointSize
0220                         wrapMode: Text.WordWrap
0221                         color: Kirigami.Theme.textColor
0222                         lineHeight: 1.2
0223                     }
0224 
0225                     Item {
0226                         Layout.fillWidth: true
0227                         Layout.alignment: Qt.AlignTop
0228                         Layout.preferredHeight: Math.max(feedUrlLayout.height, feedUrlCopyButton.width)
0229                         visible: page.showMoreInfo
0230                         height: visible ? implicitHeight : 0
0231                         RowLayout {
0232                             id: feedUrlLayout
0233                             anchors.left: parent.left
0234                             anchors.right: feedUrlCopyButton.left
0235                             anchors.verticalCenter: parent.verticalCenter
0236                             spacing: Kirigami.Units.smallSpacing
0237                             TextEdit {
0238                                 Layout.alignment: Qt.AlignTop
0239                                 readOnly: true
0240                                 textFormat:TextEdit.RichText
0241                                 text: i18n("Podcast URL:")
0242                                 wrapMode: TextEdit.Wrap
0243                                 color: Kirigami.Theme.textColor
0244                             }
0245                             TextEdit {
0246                                 id: feedUrl
0247                                 Layout.alignment: Qt.AlignTop
0248                                 readOnly: true
0249                                 selectByMouse: !Kirigami.Settings.isMobile
0250                                 textFormat:TextEdit.RichText
0251                                 text: "<a href='%1'>%1</a>".arg(feed.url)
0252                                 wrapMode: TextEdit.Wrap
0253                                 Layout.fillWidth: true
0254                                 color: Kirigami.Theme.textColor
0255                             }
0256                         }
0257                         Controls.Button {
0258                             id: feedUrlCopyButton
0259                             anchors.right: parent.right
0260                             anchors.top: parent.top
0261                             anchors.leftMargin: Kirigami.Units.smallSpacing
0262                             icon.name: "edit-copy"
0263 
0264                             onClicked: {
0265                                 feedUrl.selectAll();
0266                                 feedUrl.copy();
0267                                 feedUrl.deselect();
0268                             }
0269                         }
0270                     }
0271                     RowLayout {
0272                         Layout.fillWidth: true
0273                         Layout.alignment: Qt.AlignTop
0274                         visible: page.showMoreInfo
0275                         height: visible ? implicitHeight : 0
0276                         spacing: Kirigami.Units.smallSpacing
0277                         TextEdit {
0278                             Layout.alignment: Qt.AlignTop
0279                             readOnly: true
0280                             textFormat: TextEdit.RichText
0281                             text: i18n("Weblink:")
0282                             wrapMode: TextEdit.Wrap
0283                             color: Kirigami.Theme.textColor
0284                         }
0285 
0286                         TextEdit {
0287                             readOnly: true
0288                             Layout.alignment: Qt.AlignTop
0289                             selectByMouse: !Kirigami.Settings.isMobile
0290                             textFormat:TextEdit.RichText
0291                             text: "<a href='%1'>%1</a>".arg(feed.link)
0292                             onLinkActivated: (link) => {
0293                                 Qt.openUrlExternally(link);
0294                             }
0295                             wrapMode: Text.WordWrap
0296                             Layout.fillWidth: true
0297                             color: Kirigami.Theme.textColor
0298                         }
0299                     }
0300                     TextEdit {
0301                         Layout.alignment: Qt.AlignTop
0302                         Layout.fillWidth: true
0303                         visible: isSubscribed && page.showMoreInfo
0304                         height: visible ? implicitHeight : 0
0305 
0306                         readOnly: true
0307                         selectByMouse: !Kirigami.Settings.isMobile
0308                         textFormat:TextEdit.RichText
0309                         text: isSubscribed ? i18n("Subscribed since: %1", feed.subscribed.toLocaleString(Qt.locale(), Locale.ShortFormat)) : ""
0310                         wrapMode: Text.WordWrap
0311                         color: Kirigami.Theme.textColor
0312                     }
0313                     TextEdit {
0314                         Layout.alignment: Qt.AlignTop
0315                         Layout.fillWidth: true
0316                         visible: isSubscribed && page.showMoreInfo
0317                         height: visible ? implicitHeight : 0
0318 
0319                         readOnly: true
0320                         selectByMouse: !Kirigami.Settings.isMobile
0321                         textFormat:TextEdit.RichText
0322                         text: isSubscribed ? i18n("Last updated: %1", feed.lastUpdated.toLocaleString(Qt.locale(), Locale.ShortFormat)) : ""
0323                         wrapMode: Text.WordWrap
0324                         color: Kirigami.Theme.textColor
0325                     }
0326                     TextEdit {
0327                         Layout.alignment: Qt.AlignTop
0328                         Layout.fillWidth: true
0329                         visible: isSubscribed && page.showMoreInfo
0330                         height: visible ? implicitHeight : 0
0331 
0332                         readOnly: true
0333                         selectByMouse: !Kirigami.Settings.isMobile
0334                         textFormat:TextEdit.RichText
0335                         text: i18np("1 Episode", "%1 Episodes", feed.entryCount) + ", " + i18np("1 Unplayed", "%1 Unplayed", feed.unreadEntryCount)
0336                         wrapMode: Text.WordWrap
0337                         color: Kirigami.Theme.textColor
0338                     }
0339 
0340                     Item { Layout.fillHeight: true }
0341                 }
0342             }
0343 
0344             Kirigami.Separator { Layout.fillWidth: true }
0345 
0346             Item {
0347                 Layout.fillHeight: true
0348                 Layout.fillWidth: true
0349                 height: visible ? implicitHeight : 0
0350                 visible: entryList.count === 0 && isSubscribed
0351 
0352                 Kirigami.PlaceholderMessage {
0353                     anchors.centerIn: parent
0354 
0355                     width: Kirigami.Units.gridUnit * 20
0356 
0357                     text: feed.errorId === 0 ? i18n("No episodes available") : i18n("Error (%1): %2", feed.errorId, feed.errorString)
0358                     icon.name: feed.errorId === 0 ? "" : "data-error"
0359                 }
0360             }
0361         }
0362 
0363         FilterInlineMessage {
0364             proxyModel: page.feed.entries ? page.feed.entries : emptyListModel
0365         }
0366     }
0367 }