import QtQuick import QtQuick.Layouts import QtQuick.Controls as QQC2 import org.kde.plasma.plasmoid import org.kde.plasma.core as PlasmaCore import org.kde.plasma.components 3.0 as PC3 import org.kde.kirigami as Kirigami import "../lib" as Credentials PlasmoidItem { id: root property string favoriteIds: String(Plasmoid.configuration.favoritePodcastIds || "") property int maxEpisodes: Number(Plasmoid.configuration.maxEpisodes || 8) property int refreshSeconds: Number(Plasmoid.configuration.refreshIntervalSec || 900) property bool favoritesOnly: Boolean(Plasmoid.configuration.favoritesOnly) Credentials.IlPostApiClient { id: api } Plasmoid.title: i18n("Podcast de Il Post") Plasmoid.icon: "audio-x-generic" Plasmoid.backgroundHints: PlasmaCore.Types.DefaultBackground preferredRepresentation: fullRepresentation switchWidth: 320 switchHeight: 360 function refresh() { api.refresh(root.favoriteIds, root.maxEpisodes, root.favoritesOnly) } onFavoriteIdsChanged: if (api.authenticated) refresh() onMaxEpisodesChanged: if (api.authenticated) refresh() onFavoritesOnlyChanged: if (api.authenticated) refresh() Component.onCompleted: api.restore() Connections { target: api function onAuthenticatedChanged() { if (api.authenticated) root.refresh() } } Timer { interval: Math.max(120, root.refreshSeconds) * 1000 repeat: true running: api.authenticated onTriggered: root.refresh() } compactRepresentation: Component { Item { implicitWidth: Kirigami.Units.iconSizes.smallMedium implicitHeight: Kirigami.Units.iconSizes.smallMedium Kirigami.Icon { anchors.fill: parent source: Plasmoid.icon color: api.authenticated ? Kirigami.Theme.textColor : Kirigami.Theme.disabledTextColor } MouseArea { anchors.fill: parent onClicked: Plasmoid.expanded = !Plasmoid.expanded } } } fullRepresentation: Component { Item { implicitWidth: 380 implicitHeight: 430 Layout.minimumWidth: 300 Connections { target: api function onLoginSucceeded() { passwordField.clear() } } Layout.minimumHeight: 260 Layout.preferredWidth: 380 Layout.preferredHeight: 430 ColumnLayout { anchors.fill: parent anchors.margins: Kirigami.Units.smallSpacing spacing: Kirigami.Units.smallSpacing RowLayout { Layout.fillWidth: true PC3.Label { text: i18n("Podcast de Il Post") font.bold: true font.pointSize: Kirigami.Theme.defaultFont.pointSize + 2 Layout.fillWidth: true elide: Text.ElideRight } PC3.Button { icon.name: "view-refresh" display: QQC2.AbstractButton.IconOnly enabled: !api.loading && api.authenticated onClicked: root.refresh() QQC2.ToolTip.text: i18n("Aggiorna") QQC2.ToolTip.visible: hovered } } PC3.Label { Layout.fillWidth: true visible: api.statusMessage.length > 0 text: api.statusMessage color: api.authenticated ? Kirigami.Theme.disabledTextColor : Kirigami.Theme.negativeTextColor elide: Text.ElideRight } ColumnLayout { visible: !api.authenticated Layout.fillWidth: true spacing: Kirigami.Units.smallSpacing PC3.Label { Layout.fillWidth: true text: i18n("Accedi per visualizzare gli episodi. La password sarà salvata solo in KWallet.") wrapMode: Text.WordWrap } QQC2.TextField { id: emailField Layout.fillWidth: true placeholderText: i18n("Username / email Il Post") inputMethodHints: Qt.ImhEmailCharactersOnly enabled: !api.loading } QQC2.TextField { id: passwordField Layout.fillWidth: true placeholderText: i18n("Password") echoMode: TextInput.Password enabled: !api.loading onAccepted: loginButton.clicked() } PC3.Button { id: loginButton Layout.fillWidth: true text: api.loading ? i18n("Accesso…") : i18n("Accedi e salva in KWallet") enabled: !api.loading && emailField.text.length > 0 && passwordField.text.length > 0 onClicked: api.login(emailField.text, passwordField.text) } } QQC2.ScrollView { visible: api.authenticated Layout.fillWidth: true Layout.fillHeight: true clip: true ListView { id: episodeList anchors.fill: parent spacing: Kirigami.Units.smallSpacing model: api.episodes delegate: Rectangle { required property var modelData width: episodeList.width implicitHeight: episodeColumn.implicitHeight + 16 radius: 5 color: modelData.favorite ? Qt.rgba(0.25, 0.45, 0.25, 0.16) : Kirigami.Theme.backgroundColor border.color: modelData.favorite ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.disabledTextColor border.width: 1 RowLayout { id: episodeRow anchors.fill: parent anchors.margins: 8 spacing: Kirigami.Units.smallSpacing Item { Layout.preferredWidth: 64 Layout.preferredHeight: 64 Layout.alignment: Qt.AlignTop Image { id: coverImage anchors.fill: parent source: modelData.podcastImage || "" asynchronous: true cache: true fillMode: Image.PreserveAspectCrop smooth: true mipmap: true visible: status === Image.Ready } Kirigami.Icon { anchors.centerIn: parent width: 36 height: 36 source: "audio-x-generic" visible: !coverImage.visible } Rectangle { anchors.fill: parent color: "transparent" border.width: 1 border.color: Kirigami.Theme.disabledTextColor opacity: 0.45 } } ColumnLayout { id: episodeColumn Layout.fillWidth: true spacing: 2 RowLayout { Layout.fillWidth: true PC3.Label { text: modelData.podcastTitle || i18n("Podcast") color: modelData.favorite ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.disabledTextColor font.bold: true font.pointSize: Kirigami.Theme.defaultFont.pointSize - 1 Layout.fillWidth: true elide: Text.ElideRight } PC3.Label { visible: modelData.favorite text: i18n("Preferito") color: Kirigami.Theme.positiveTextColor font.pointSize: Kirigami.Theme.defaultFont.pointSize - 2 } } PC3.Label { Layout.fillWidth: true text: modelData.title || i18n("Senza titolo") font.bold: true wrapMode: Text.WordWrap } PC3.Label { Layout.fillWidth: true text: modelData.date ? new Date(modelData.date).toLocaleDateString(Qt.locale()) : "" color: Kirigami.Theme.disabledTextColor font.pointSize: Kirigami.Theme.defaultFont.pointSize - 2 } PC3.Button { visible: Boolean(modelData.audioUrl) text: i18n("Riproduci in Dragon Player") onClicked: api.playAudio(modelData.audioUrl) } } } } } } RowLayout { visible: api.authenticated Layout.fillWidth: true PC3.Label { text: i18n("%1 episodi · preferiti in cima", api.episodes.length) color: Kirigami.Theme.disabledTextColor Layout.fillWidth: true } PC3.Button { text: i18n("Disconnetti") onClicked: api.clearCredentials() } } } } } }