Files

278 lines
12 KiB
QML

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()
}
}
}
}
}
}