mirror of https://github.com/KDE/kasts.git
Add mobile bottom navbar, use Titles toolbar on mobile, and add blurred image background to mobile player
This commit is contained in:
parent
f861f4e802
commit
e16c40d57c
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.4
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
|
import org.kde.kasts 1.0
|
||||||
|
|
||||||
|
Kirigami.NavigationTabBar {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias toolbarHeight: root.implicitHeight
|
||||||
|
property bool transparentBackground: false
|
||||||
|
|
||||||
|
shadow: false
|
||||||
|
|
||||||
|
actions: [
|
||||||
|
Kirigami.Action {
|
||||||
|
iconName: "view-media-playlist"
|
||||||
|
text: i18n("Queue")
|
||||||
|
checked: "QueuePage" === SettingsManager.lastOpenedPage
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("QueuePage");
|
||||||
|
SettingsManager.lastOpenedPage = "QueuePage"; // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
iconName: "bookmarks"
|
||||||
|
text: i18n("Subscriptions")
|
||||||
|
checked: "FeedListPage" === SettingsManager.lastOpenedPage
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("FeedListPage");
|
||||||
|
SettingsManager.lastOpenedPage = "FeedListPage"; // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
iconName: "rss"
|
||||||
|
text: i18n("Episodes")
|
||||||
|
checked: "EpisodeListPage" === SettingsManager.lastOpenedPage
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("EpisodeListPage")
|
||||||
|
SettingsManager.lastOpenedPage = "EpisodeListPage" // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
iconName: "settings-configure"
|
||||||
|
text: i18n("Settings")
|
||||||
|
checked: "SettingsPage" === SettingsManager.lastOpenedPage
|
||||||
|
onTriggered: {
|
||||||
|
applicationWindow().pageStack.clear()
|
||||||
|
applicationWindow().pageStack.push("qrc:/SettingsPage.qml", {}, {
|
||||||
|
title: i18n("Settings")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -26,12 +26,21 @@ Kirigami.ScrollablePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.main: Kirigami.Action {
|
actions.main: Kirigami.Action {
|
||||||
|
iconName: "download"
|
||||||
|
text: i18n("Downloads")
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("DownloadListPage")
|
||||||
|
SettingsManager.lastOpenedPage = "DownloadListPage" // for persistency
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.left: Kirigami.Action {
|
||||||
iconName: "view-filter"
|
iconName: "view-filter"
|
||||||
text: i18n("Filter")
|
text: i18n("Filter")
|
||||||
onTriggered: filterTypeOverlay.open();
|
onTriggered: filterTypeOverlay.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.left: Kirigami.Action {
|
actions.right: Kirigami.Action {
|
||||||
iconName: "view-refresh"
|
iconName: "view-refresh"
|
||||||
text: i18n("Refresh All Podcasts")
|
text: i18n("Refresh All Podcasts")
|
||||||
onTriggered: refreshing = true
|
onTriggered: refreshing = true
|
||||||
|
|
|
@ -33,14 +33,22 @@ Kirigami.ScrollablePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.main: Kirigami.Action {
|
actions.main: Kirigami.Action {
|
||||||
text: i18n("Add Podcast")
|
visible: Kirigami.Settings.isMobile
|
||||||
iconName: "list-add"
|
text: i18n("Discover")
|
||||||
|
iconName: "search"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
addSheet.open()
|
applicationWindow().pageStack.push("qrc:/DiscoverPage.qml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contextualActions: [
|
contextualActions: [
|
||||||
|
Kirigami.Action {
|
||||||
|
text: i18n("Add Podcast")
|
||||||
|
iconName: "list-add"
|
||||||
|
onTriggered: {
|
||||||
|
addSheet.open()
|
||||||
|
}
|
||||||
|
},
|
||||||
Kirigami.Action {
|
Kirigami.Action {
|
||||||
text: i18n("Refresh All Podcasts")
|
text: i18n("Refresh All Podcasts")
|
||||||
iconName: "view-refresh"
|
iconName: "view-refresh"
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14 as Controls
|
import QtQuick.Controls 2.14 as Controls
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import org.kde.kirigami 2.14 as Kirigami
|
import org.kde.kirigami 2.14 as Kirigami
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@ Flickable {
|
||||||
|
|
||||||
property bool isMaximized: contentY === contentHeight / 2
|
property bool isMaximized: contentY === contentHeight / 2
|
||||||
|
|
||||||
|
property int contentToPlayerSpacing: 0
|
||||||
|
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
NumberAnimation on contentY {
|
NumberAnimation on contentY {
|
||||||
|
@ -51,6 +54,10 @@ Flickable {
|
||||||
onReleased: footerBar.resetToBoundsOnFlick()
|
onReleased: footerBar.resetToBoundsOnFlick()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
toClose.restart();
|
||||||
|
}
|
||||||
|
|
||||||
function resetToBoundsOnFlick() {
|
function resetToBoundsOnFlick() {
|
||||||
if (!atYBeginning || !atYEnd) {
|
if (!atYBeginning || !atYEnd) {
|
||||||
if (footerBar.verticalVelocity > 0) {
|
if (footerBar.verticalVelocity > 0) {
|
||||||
|
@ -90,8 +97,11 @@ Flickable {
|
||||||
// a cover for content underneath the panel
|
// a cover for content underneath the panel
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: coverUnderneath
|
id: coverUnderneath
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||||
|
Kirigami.Theme.inherit: false
|
||||||
|
color: Kirigami.Theme.backgroundColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,23 +111,52 @@ Flickable {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
height: root.height + root.miniplayerSize
|
height: root.height + root.miniplayerSize + contentToPlayerSpacing
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
MinimizedPlayerControls {
|
Controls.Control {
|
||||||
id: playControlItem
|
implicitHeight: root.miniplayerSize + contentToPlayerSpacing
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: root.miniplayerSize
|
padding: 0
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
focus: true
|
background: Image {
|
||||||
|
opacity: 0.2
|
||||||
|
source: AudioManager.entry.cachedImage
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: HueSaturation {
|
||||||
|
cached: true
|
||||||
|
|
||||||
|
lightness: 0.7
|
||||||
|
saturation: 0.9
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: FastBlur {
|
||||||
|
cached: true
|
||||||
|
radius: 64
|
||||||
|
transparentBorder: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MinimizedPlayerControls {
|
||||||
|
id: playControlItem
|
||||||
|
height: root.miniplayerSize
|
||||||
|
focus: true
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerControls {
|
PlayerControls {
|
||||||
id: mobileTrackPlayer
|
id: mobileTrackPlayer
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.margins: Kirigami.Units.largeSpacing * 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
*/
|
*/
|
||||||
|
@ -8,25 +9,20 @@ import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14 as Controls
|
import QtQuick.Controls 2.14 as Controls
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
import QtMultimedia 5.15
|
import QtMultimedia 5.15
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import org.kde.kirigami 2.12 as Kirigami
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
|
|
||||||
import org.kde.kasts 1.0
|
import org.kde.kasts 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property int miniplayerheight: Kirigami.Units.gridUnit * 3
|
property int miniplayerheight: Math.round(Kirigami.Units.gridUnit * 3)
|
||||||
property int progressbarheight: Kirigami.Units.gridUnit / 6
|
property int progressbarheight: Kirigami.Units.gridUnit / 6
|
||||||
property int buttonsize: Kirigami.Units.gridUnit * 2
|
property int buttonsize: Kirigami.Units.gridUnit * 1.5
|
||||||
height: miniplayerheight + progressbarheight
|
height: miniplayerheight
|
||||||
|
|
||||||
visible: AudioManager.entry
|
visible: AudioManager.entry
|
||||||
|
|
||||||
// Set background
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
}
|
|
||||||
|
|
||||||
// progress bar for limited width (phones)
|
// progress bar for limited width (phones)
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: miniprogressbar
|
id: miniprogressbar
|
||||||
|
@ -41,44 +37,50 @@ Item {
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: footerrowlayout
|
id: footerrowlayout
|
||||||
anchors.topMargin: miniprogressbar.height
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Item {
|
spacing: 0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
// press feedback
|
||||||
|
color: (trackClick.pressed || trackClick.containsMouse) ? Qt.rgba(0, 0, 0, 0.05) : "transparent"
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
ImageWithFallback {
|
ImageWithFallback {
|
||||||
imageSource: AudioManager.entry.cachedImage
|
imageSource: AudioManager.entry.cachedImage
|
||||||
Layout.preferredHeight: miniplayerheight
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: miniplayerheight
|
Layout.preferredWidth: height
|
||||||
}
|
}
|
||||||
|
|
||||||
// track information
|
// track information
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillHeight: true
|
Layout.maximumHeight: parent.height
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
id: mainLabel
|
id: mainLabel
|
||||||
text: AudioManager.entry.title
|
text: AudioManager.entry.title
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
//font.weight: Font.Bold
|
|
||||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1
|
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1
|
||||||
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
|
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
id: feedLabel
|
id: feedLabel
|
||||||
text: AudioManager.entry.feed.name
|
text: AudioManager.entry.feed.name
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
@ -101,9 +103,10 @@ Item {
|
||||||
icon.height: parent.parent.buttonsize
|
icon.height: parent.parent.buttonsize
|
||||||
icon.width: parent.parent.buttonsize
|
icon.width: parent.parent.buttonsize
|
||||||
flat: true
|
flat: true
|
||||||
Layout.fillHeight: true
|
Layout.preferredHeight: parent.parent.miniplayerheight - Kirigami.Units.smallSpacing * 2
|
||||||
Layout.maximumHeight: parent.parent.miniplayerheight
|
Layout.preferredWidth: height
|
||||||
Layout.maximumWidth: height
|
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||||
|
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||||
onClicked: AudioManager.playbackState === Audio.PlayingState ? AudioManager.pause() : AudioManager.play()
|
onClicked: AudioManager.playbackState === Audio.PlayingState ? AudioManager.pause() : AudioManager.play()
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
*/
|
*/
|
||||||
|
@ -21,16 +22,47 @@ Kirigami.Page {
|
||||||
clip: true
|
clip: true
|
||||||
Layout.margins: 0
|
Layout.margins: 0
|
||||||
|
|
||||||
padding: 0
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
topPadding: 0
|
||||||
bottomPadding: Kirigami.Units.gridUnit
|
bottomPadding: Kirigami.Units.gridUnit
|
||||||
|
|
||||||
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||||
|
Kirigami.Theme.inherit: false
|
||||||
|
|
||||||
|
background: Image {
|
||||||
|
opacity: 0.2
|
||||||
|
source: AudioManager.entry.cachedImage
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: HueSaturation {
|
||||||
|
cached: true
|
||||||
|
|
||||||
|
lightness: 0.7
|
||||||
|
saturation: 0.9
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: FastBlur {
|
||||||
|
cached: true
|
||||||
|
radius: 100
|
||||||
|
transparentBorder: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: playerControlsColumn
|
id: playerControlsColumn
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin:0
|
anchors.topMargin: Kirigami.Units.largeSpacing * 2
|
||||||
|
anchors.bottomMargin: Kirigami.Units.largeSpacing * 2
|
||||||
|
|
||||||
Controls.Button {
|
Controls.Button {
|
||||||
id: swipeUpButton
|
id: swipeUpButton
|
||||||
property int swipeUpButtonSize: Kirigami.Units.gridUnit * 2
|
property int swipeUpButtonSize: Kirigami.Units.iconSizes.smallMedium
|
||||||
icon.name: "arrow-down"
|
icon.name: "arrow-down"
|
||||||
icon.height: swipeUpButtonSize
|
icon.height: swipeUpButtonSize
|
||||||
icon.width: swipeUpButtonSize
|
icon.width: swipeUpButtonSize
|
||||||
|
@ -39,97 +71,118 @@ Kirigami.Page {
|
||||||
Layout.topMargin: 0
|
Layout.topMargin: 0
|
||||||
onClicked: toClose.restart()
|
onClicked: toClose.restart()
|
||||||
}
|
}
|
||||||
|
|
||||||
Controls.SwipeView {
|
Controls.SwipeView {
|
||||||
id: swipeView
|
id: swipeView
|
||||||
|
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
Layout.preferredHeight: parent.height - media.height - indicator.height - swipeUpButton.height
|
Layout.preferredHeight: parent.height - media.height - indicator.height - indicator.Layout.bottomMargin - swipeUpButton.height
|
||||||
Layout.margins: 0
|
Layout.margins: 0
|
||||||
Item {
|
|
||||||
property int textMargin: Kirigami.Units.gridUnit // margin above and below the text below the image
|
Controls.Control {
|
||||||
ImageWithFallback {
|
leftPadding: Kirigami.Units.largeSpacing * 2
|
||||||
id: coverImage
|
rightPadding: Kirigami.Units.largeSpacing * 2
|
||||||
imageSource: AudioManager.entry ? AudioManager.entry.cachedImage : "no-image"
|
|
||||||
imageFillMode: Image.PreserveAspectCrop
|
contentItem: Item {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
property int textMargin: Kirigami.Units.gridUnit // margin above and below the text below the image
|
||||||
anchors.top: parent.top
|
ImageWithFallback {
|
||||||
anchors.topMargin: Math.max(0, parent.height - (height + imageLabels.height + 2*parent.textMargin))/2
|
id: coverImage
|
||||||
height: Math.min(Math.min(parent.height, Kirigami.Units.iconSizes.enormous * 3) - (imageLabels.height + 2 * parent.textMargin),
|
imageSource: AudioManager.entry ? AudioManager.entry.cachedImage : "no-image"
|
||||||
Math.min(parent.width, Kirigami.Units.iconSizes.enormous * 3))
|
imageFillMode: Image.PreserveAspectCrop
|
||||||
width: height
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
fractionalRadius: 1 / 20
|
anchors.top: parent.top
|
||||||
}
|
anchors.topMargin: Math.max(0, parent.height - (height + imageLabels.height + 2*parent.textMargin))/2
|
||||||
ColumnLayout {
|
height: Math.min(Math.min(parent.height, Kirigami.Units.iconSizes.enormous * 3) - (imageLabels.height + 2 * parent.textMargin),
|
||||||
id: imageLabels
|
Math.min(parent.width, Kirigami.Units.iconSizes.enormous * 3))
|
||||||
anchors.top: coverImage.bottom
|
width: height
|
||||||
anchors.left: parent.left
|
fractionalRadius: 1 / 20
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: parent.textMargin
|
|
||||||
Controls.Label {
|
|
||||||
text: AudioManager.entry ? AudioManager.entry.title : i18n("No Title")
|
|
||||||
elide: Text.ElideRight
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.maximumWidth: parent.width
|
|
||||||
}
|
}
|
||||||
Controls.Label {
|
|
||||||
text: AudioManager.entry ? AudioManager.entry.feed.name : i18n("No Podcast Title")
|
|
||||||
elide: Text.ElideRight
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.maximumWidth: parent.width
|
|
||||||
opacity: 0.6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Flickable {
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
contentHeight: description.height
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: description
|
id: imageLabels
|
||||||
width: parent.width
|
anchors.top: coverImage.bottom
|
||||||
Kirigami.Heading {
|
anchors.left: parent.left
|
||||||
text: AudioManager.entry ? AudioManager.entry.title : i18n("No Track Title")
|
anchors.right: parent.right
|
||||||
level: 3
|
anchors.topMargin: parent.textMargin
|
||||||
wrapMode: Text.WordWrap
|
Controls.Label {
|
||||||
Layout.fillWidth: true
|
text: AudioManager.entry ? AudioManager.entry.title : i18n("No Title")
|
||||||
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
elide: Text.ElideRight
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.maximumWidth: parent.width
|
||||||
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
id: text
|
text: AudioManager.entry ? AudioManager.entry.feed.name : i18n("No Podcast Title")
|
||||||
text: AudioManager.entry ? AudioManager.entry.content : i18n("No Track Loaded")
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignTop
|
Layout.alignment: Qt.AlignHCenter
|
||||||
baseUrl: AudioManager.entry ? AudioManager.entry.baseUrl : ""
|
Layout.maximumWidth: parent.width
|
||||||
textFormat: Text.RichText
|
opacity: 0.6
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
onLinkActivated: Qt.openUrlExternally(link)
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item {
|
|
||||||
Kirigami.PlaceholderMessage {
|
|
||||||
visible: chapterList.count === 0
|
|
||||||
|
|
||||||
width: parent.width
|
Controls.Control {
|
||||||
anchors.centerIn: parent
|
leftPadding: Kirigami.Units.largeSpacing * 2
|
||||||
|
rightPadding: Kirigami.Units.largeSpacing * 2
|
||||||
|
|
||||||
text: i18n("No chapter marks found.")
|
contentItem: Item {
|
||||||
}
|
Flickable {
|
||||||
ListView {
|
anchors.fill: parent
|
||||||
id: chapterList
|
anchors.leftMargin: playerControlsColumn.anchors.margins
|
||||||
model: ChapterModel {
|
clip: true
|
||||||
enclosureId: AudioManager.entry.id
|
contentHeight: description.height
|
||||||
enclosurePath: AudioManager.entry.enclosure.path
|
ColumnLayout {
|
||||||
|
id: description
|
||||||
|
width: parent.width
|
||||||
|
Kirigami.Heading {
|
||||||
|
text: AudioManager.entry ? AudioManager.entry.title : i18n("No Track Title")
|
||||||
|
level: 3
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||||
|
}
|
||||||
|
Controls.Label {
|
||||||
|
id: text
|
||||||
|
text: AudioManager.entry ? AudioManager.entry.content : i18n("No Track Loaded")
|
||||||
|
verticalAlignment: Text.AlignTop
|
||||||
|
baseUrl: AudioManager.entry ? AudioManager.entry.baseUrl : ""
|
||||||
|
textFormat: Text.RichText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
clip: true
|
}
|
||||||
visible: chapterList.count !== 0
|
}
|
||||||
anchors.fill: parent
|
|
||||||
delegate: ChapterListDelegate {
|
Controls.Control {
|
||||||
entry: AudioManager.entry
|
leftPadding: Kirigami.Units.largeSpacing * 2
|
||||||
|
rightPadding: Kirigami.Units.largeSpacing * 2
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
Kirigami.PlaceholderMessage {
|
||||||
|
visible: chapterList.count === 0
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
text: i18n("No chapters found.")
|
||||||
|
}
|
||||||
|
ListView {
|
||||||
|
id: chapterList
|
||||||
|
model: ChapterModel {
|
||||||
|
enclosureId: AudioManager.entry.id
|
||||||
|
enclosurePath: AudioManager.entry.enclosure.path
|
||||||
|
}
|
||||||
|
clip: true
|
||||||
|
visible: chapterList.count !== 0
|
||||||
|
anchors.fill: parent
|
||||||
|
delegate: ChapterListDelegate {
|
||||||
|
entry: AudioManager.entry
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,19 +194,20 @@ Kirigami.Page {
|
||||||
count: swipeView.count
|
count: swipeView.count
|
||||||
currentIndex: swipeView.currentIndex
|
currentIndex: swipeView.currentIndex
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.bottomMargin: Kirigami.Units.gridUnit
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: media
|
id: media
|
||||||
|
|
||||||
implicitHeight: mediaControls.height
|
implicitHeight: mediaControls.height
|
||||||
|
Layout.leftMargin: Kirigami.Units.largeSpacing * 2
|
||||||
|
Layout.rightMargin: Kirigami.Units.largeSpacing * 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: 0
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mediaControls
|
id: mediaControls
|
||||||
|
|
||||||
//implicitHeight: controls.height
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: 0
|
anchors.margins: 0
|
||||||
|
@ -161,7 +215,8 @@ Kirigami.Page {
|
||||||
Controls.Slider {
|
Controls.Slider {
|
||||||
enabled: AudioManager.entry
|
enabled: AudioManager.entry
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: 0
|
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||||
|
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||||
padding: 0
|
padding: 0
|
||||||
from: 0
|
from: 0
|
||||||
to: AudioManager.duration
|
to: AudioManager.duration
|
||||||
|
@ -170,16 +225,20 @@ Kirigami.Page {
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: controls
|
id: controls
|
||||||
Layout.margins: 0
|
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||||
|
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
padding: Kirigami.Units.largeSpacing
|
padding: Kirigami.Units.largeSpacing
|
||||||
text: AudioManager.formattedPosition
|
text: AudioManager.formattedPosition
|
||||||
|
font: Kirigami.Theme.smallFont
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
Layout.preferredHeight: endLabel.implicitHeight
|
Layout.preferredHeight: endLabel.implicitHeight
|
||||||
Layout.preferredWidth: endLabel.implicitWidth
|
Layout.preferredWidth: endLabel.implicitWidth
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
|
@ -190,6 +249,7 @@ Kirigami.Page {
|
||||||
text: (SettingsManager.toggleRemainingTime) ?
|
text: (SettingsManager.toggleRemainingTime) ?
|
||||||
"-" + AudioManager.formattedLeftDuration
|
"-" + AudioManager.formattedLeftDuration
|
||||||
: AudioManager.formattedDuration
|
: AudioManager.formattedDuration
|
||||||
|
font: Kirigami.Theme.smallFont
|
||||||
|
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
@ -199,7 +259,11 @@ Kirigami.Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
id: bottomRow
|
||||||
|
Layout.leftMargin: Kirigami.Units.largeSpacing
|
||||||
|
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||||
Layout.maximumWidth: Number.POSITIVE_INFINITY //TODO ?
|
Layout.maximumWidth: Number.POSITIVE_INFINITY //TODO ?
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: 0
|
Layout.margins: 0
|
||||||
|
@ -207,8 +271,9 @@ Kirigami.Page {
|
||||||
|
|
||||||
// Make button width scale properly on narrow windows instead of overflowing
|
// Make button width scale properly on narrow windows instead of overflowing
|
||||||
property int buttonSize: Math.min(playButton.implicitWidth, ((playerControlsColumn.width - 4 * spacing) / 5 - playButton.leftPadding - playButton.rightPadding))
|
property int buttonSize: Math.min(playButton.implicitWidth, ((playerControlsColumn.width - 4 * spacing) / 5 - playButton.leftPadding - playButton.rightPadding))
|
||||||
property int iconSize: Kirigami.Units.gridUnit * 2
|
property int iconSize: Kirigami.Units.gridUnit * 1.5
|
||||||
|
|
||||||
|
// left section
|
||||||
Controls.Button {
|
Controls.Button {
|
||||||
// Use contentItem and a Label because using plain "text"
|
// Use contentItem and a Label because using plain "text"
|
||||||
// does not rescale automatically if the text changes
|
// does not rescale automatically if the text changes
|
||||||
|
@ -221,49 +286,56 @@ Kirigami.Page {
|
||||||
playbackRateDialog.open()
|
playbackRateDialog.open()
|
||||||
}
|
}
|
||||||
flat: true
|
flat: true
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
padding: 0
|
padding: 0
|
||||||
implicitWidth: playButton.width
|
implicitWidth: playButton.width
|
||||||
implicitHeight: playButton.height
|
implicitHeight: playButton.height
|
||||||
}
|
}
|
||||||
Controls.Button {
|
|
||||||
icon.name: "media-seek-backward"
|
// middle section
|
||||||
icon.height: parent.iconSize
|
RowLayout {
|
||||||
icon.width: parent.iconSize
|
spacing: Kirigami.Units.largeSpacing
|
||||||
flat: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.preferredWidth: parent.buttonSize
|
Controls.Button {
|
||||||
onClicked: AudioManager.skipBackward()
|
icon.name: "media-seek-backward"
|
||||||
enabled: AudioManager.canSkipBackward
|
icon.height: bottomRow.iconSize
|
||||||
}
|
icon.width: bottomRow.iconSize
|
||||||
Controls.Button {
|
flat: true
|
||||||
id: playButton
|
Layout.alignment: Qt.AlignRight
|
||||||
icon.name: AudioManager.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
|
Layout.preferredWidth: bottomRow.buttonSize
|
||||||
icon.height: parent.iconSize
|
onClicked: AudioManager.skipBackward()
|
||||||
icon.width: parent.iconSize
|
enabled: AudioManager.canSkipBackward
|
||||||
flat: true
|
}
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Controls.Button {
|
||||||
Layout.preferredWidth: parent.buttonSize
|
id: playButton
|
||||||
onClicked: AudioManager.playbackState === Audio.PlayingState ? AudioManager.pause() : AudioManager.play()
|
icon.name: AudioManager.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
|
||||||
enabled: AudioManager.canPlay
|
icon.height: bottomRow.iconSize
|
||||||
}
|
icon.width: bottomRow.iconSize
|
||||||
Controls.Button {
|
flat: true
|
||||||
icon.name: "media-seek-forward"
|
Layout.alignment: Qt.AlignHCenter
|
||||||
icon.height: parent.iconSize
|
Layout.preferredWidth: bottomRow.buttonSize
|
||||||
icon.width: parent.iconSize
|
onClicked: AudioManager.playbackState === Audio.PlayingState ? AudioManager.pause() : AudioManager.play()
|
||||||
flat: true
|
enabled: AudioManager.canPlay
|
||||||
Layout.alignment: Qt.AlignHCenter
|
}
|
||||||
Layout.preferredWidth: parent.buttonSize
|
Controls.Button {
|
||||||
onClicked: AudioManager.skipForward()
|
icon.name: "media-seek-forward"
|
||||||
enabled: AudioManager.canSkipForward
|
icon.height: bottomRow.iconSize
|
||||||
|
icon.width: bottomRow.iconSize
|
||||||
|
flat: true
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
Layout.preferredWidth: bottomRow.buttonSize
|
||||||
|
onClicked: AudioManager.skipForward()
|
||||||
|
enabled: AudioManager.canSkipForward
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// right section
|
||||||
Controls.Button {
|
Controls.Button {
|
||||||
icon.name: "media-skip-forward"
|
icon.name: "media-skip-forward"
|
||||||
icon.height: parent.iconSize
|
icon.height: bottomRow.iconSize
|
||||||
icon.width: parent.iconSize
|
icon.width: bottomRow.iconSize
|
||||||
flat: true
|
flat: true
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignRight
|
||||||
Layout.preferredWidth: parent.buttonSize
|
Layout.preferredWidth: bottomRow.buttonSize
|
||||||
onClicked: AudioManager.next()
|
onClicked: AudioManager.next()
|
||||||
enabled: AudioManager.canGoNext
|
enabled: AudioManager.canGoNext
|
||||||
}
|
}
|
||||||
|
|
211
src/qml/main.qml
211
src/qml/main.qml
|
@ -8,6 +8,7 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14 as Controls
|
import QtQuick.Controls 2.14 as Controls
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
import org.kde.kirigami 2.14 as Kirigami
|
import org.kde.kirigami 2.14 as Kirigami
|
||||||
import org.kde.kasts.solidextras 1.0
|
import org.kde.kasts.solidextras 1.0
|
||||||
|
@ -21,18 +22,33 @@ Kirigami.ApplicationWindow {
|
||||||
minimumWidth: Kirigami.Units.gridUnit * 17
|
minimumWidth: Kirigami.Units.gridUnit * 17
|
||||||
minimumHeight: Kirigami.Units.gridUnit * 20
|
minimumHeight: Kirigami.Units.gridUnit * 20
|
||||||
|
|
||||||
property var miniplayerSize: Kirigami.Units.gridUnit * 3 + Kirigami.Units.gridUnit / 6
|
property var miniplayerSize: Math.round(Kirigami.Units.gridUnit * 3) + Kirigami.Units.gridUnit / 6
|
||||||
property int bottomMessageSpacing: Kirigami.Settings.isMobile ? Kirigami.Units.largeSpacing * 9 + ( AudioManager.entry ? ( footerLoader.item.contentY == 0 ? miniplayerSize : 0 ) : 0 ) : Kirigami.Units.largeSpacing * 2
|
property int bottomMessageSpacing: {
|
||||||
|
if (Kirigami.Settings.isMobile) {
|
||||||
|
return Kirigami.Units.largeSpacing + ( AudioManager.entry ? ( footerLoader.item.contentY == 0 ? miniplayerSize : 0 ) : 0 ) + (root.footer.height);
|
||||||
|
} else {
|
||||||
|
return Kirigami.Units.largeSpacing * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
property int originalWidth: Kirigami.Units.gridUnit * 10
|
property int originalWidth: Kirigami.Units.gridUnit * 10
|
||||||
property var lastFeed: ""
|
property var lastFeed: ""
|
||||||
property string currentPage: ""
|
property string currentPage: ""
|
||||||
|
|
||||||
property bool isWidescreen: root.width >= root.height
|
property bool isWidescreen: root.width >= root.height
|
||||||
onIsWidescreenChanged: {
|
onIsWidescreenChanged: {
|
||||||
if (!Kirigami.Settings.isMobile) {
|
changeNavigation(!isWidescreen);
|
||||||
changeNavigation(!isWidescreen);
|
}
|
||||||
|
|
||||||
|
function changeNavigation(isNarrow) {
|
||||||
|
if (isNarrow) {
|
||||||
|
globalDrawer.collapsed = true
|
||||||
|
globalDrawer.width = Layout.implicitWidth
|
||||||
|
} else {
|
||||||
|
globalDrawer.collapsed = false
|
||||||
|
globalDrawer.width = originalWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPage(page) {
|
function getPage(page) {
|
||||||
switch (page) {
|
switch (page) {
|
||||||
case "QueuePage": return "qrc:/QueuePage.qml";
|
case "QueuePage": return "qrc:/QueuePage.qml";
|
||||||
|
@ -55,8 +71,10 @@ Kirigami.ApplicationWindow {
|
||||||
currentPage = SettingsManager.lastOpenedPage
|
currentPage = SettingsManager.lastOpenedPage
|
||||||
pageStack.initialPage = getPage(SettingsManager.lastOpenedPage)
|
pageStack.initialPage = getPage(SettingsManager.lastOpenedPage)
|
||||||
|
|
||||||
// move mobile handles to toolbar
|
if (Kirigami.Settings.isMobile) {
|
||||||
pageStack.globalToolBar.canContainHandles = true;
|
pageStack.globalToolBar.style = Kirigami.ApplicationHeaderStyle.ToolBar;
|
||||||
|
pageStack.globalToolBar.showNavigationButtons = Kirigami.ApplicationHeaderStyle.ShowBackButton;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete played enclosures if set in settings
|
// Delete played enclosures if set in settings
|
||||||
if (SettingsManager.autoDeleteOnPlayed == 2) {
|
if (SettingsManager.autoDeleteOnPlayed == 2) {
|
||||||
|
@ -73,93 +91,78 @@ Kirigami.ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
globalDrawer: Kirigami.GlobalDrawer {
|
globalDrawer: sidebar.item
|
||||||
isMenu: false
|
Loader {
|
||||||
modal: Kirigami.Settings.isMobile
|
id: sidebar
|
||||||
collapsible: !Kirigami.Settings.isMobile
|
active: !Kirigami.Settings.isMobile || root.isWidescreen
|
||||||
header: Kirigami.AbstractApplicationHeader {
|
sourceComponent: Kirigami.GlobalDrawer {
|
||||||
visible: !Kirigami.Settings.isMobile
|
width: 200
|
||||||
}
|
modal: false
|
||||||
|
isMenu: false
|
||||||
|
collapsible: !Kirigami.Settings.isMobile
|
||||||
|
header: Kirigami.AbstractApplicationHeader {}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||||
if (!Kirigami.Settings.isMobile) {
|
Kirigami.Theme.inherit: false
|
||||||
Kirigami.Theme.colorSet = Kirigami.Theme.Window;
|
|
||||||
Kirigami.Theme.inherit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// make room at the bottom for miniplayer
|
actions: [
|
||||||
handle.anchors.bottomMargin: (( AudioManager.entry && Kirigami.Settings.isMobile ) ? (footerLoader.item.contentY == 0 ? miniplayerSize : 0) : 0) + Kirigami.Units.smallSpacing
|
Kirigami.Action {
|
||||||
handleVisible: Kirigami.Settings.isMobile ? !AudioManager.entry || footerLoader.item.contentY === 0 : false
|
text: i18n("Queue")
|
||||||
showHeaderWhenCollapsed: true
|
iconName: "source-playlist"
|
||||||
actions: [
|
checked: currentPage == "QueuePage"
|
||||||
Kirigami.Action {
|
onTriggered: {
|
||||||
text: i18n("Queue")
|
pushPage("QueuePage")
|
||||||
iconName: "source-playlist"
|
SettingsManager.lastOpenedPage = "QueuePage" // for persistency
|
||||||
checked: currentPage == "QueuePage"
|
}
|
||||||
onTriggered: {
|
},
|
||||||
pushPage("QueuePage")
|
Kirigami.Action {
|
||||||
SettingsManager.lastOpenedPage = "QueuePage" // for persistency
|
text: i18n("Discover")
|
||||||
|
iconName: "search"
|
||||||
|
checked: currentPage == "DiscoverPage"
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("DiscoverPage")
|
||||||
|
SettingsManager.lastOpenedPage = "DiscoverPage" // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: i18n("Episodes")
|
||||||
|
iconName: "rss"
|
||||||
|
checked: currentPage == "EpisodeListPage"
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("EpisodeListPage")
|
||||||
|
SettingsManager.lastOpenedPage = "EpisodeListPage" // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: i18n("Subscriptions")
|
||||||
|
iconName: "bookmarks"
|
||||||
|
checked: currentPage == "FeedListPage"
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("FeedListPage")
|
||||||
|
SettingsManager.lastOpenedPage = "FeedListPage" // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: i18n("Downloads")
|
||||||
|
iconName: "download"
|
||||||
|
checked: currentPage == "DownloadListPage"
|
||||||
|
onTriggered: {
|
||||||
|
pushPage("DownloadListPage")
|
||||||
|
SettingsManager.lastOpenedPage = "DownloadListPage" // for persistency
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
text: i18n("Settings")
|
||||||
|
iconName: "settings-configure"
|
||||||
|
checked: currentPage == "SettingsPage"
|
||||||
|
onTriggered: {
|
||||||
|
root.pageStack.layers.clear()
|
||||||
|
root.pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, {
|
||||||
|
title: i18n("Settings")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
Kirigami.Action {
|
|
||||||
text: i18n("Discover")
|
|
||||||
iconName: "search"
|
|
||||||
checked: currentPage == "DiscoverPage"
|
|
||||||
onTriggered: {
|
|
||||||
pushPage("DiscoverPage")
|
|
||||||
SettingsManager.lastOpenedPage = "DiscoverPage" // for persistency
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Kirigami.Action {
|
|
||||||
text: i18n("Episodes")
|
|
||||||
iconName: "rss"
|
|
||||||
checked: currentPage == "EpisodeListPage"
|
|
||||||
onTriggered: {
|
|
||||||
pushPage("EpisodeListPage")
|
|
||||||
SettingsManager.lastOpenedPage = "EpisodeListPage" // for persistency
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Kirigami.Action {
|
|
||||||
text: i18n("Subscriptions")
|
|
||||||
iconName: "bookmarks"
|
|
||||||
checked: currentPage == "FeedListPage"
|
|
||||||
onTriggered: {
|
|
||||||
pushPage("FeedListPage")
|
|
||||||
SettingsManager.lastOpenedPage = "FeedListPage" // for persistency
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Kirigami.Action {
|
|
||||||
text: i18n("Downloads")
|
|
||||||
iconName: "download"
|
|
||||||
checked: currentPage == "DownloadListPage"
|
|
||||||
onTriggered: {
|
|
||||||
pushPage("DownloadListPage")
|
|
||||||
SettingsManager.lastOpenedPage = "DownloadListPage" // for persistency
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Kirigami.Action {
|
|
||||||
text: i18n("Settings")
|
|
||||||
iconName: "settings-configure"
|
|
||||||
checked: currentPage == "SettingsPage"
|
|
||||||
onTriggered: {
|
|
||||||
root.pageStack.layers.clear()
|
|
||||||
root.pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, {
|
|
||||||
title: i18n("Settings")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeNavigation(isNarrow) {
|
|
||||||
if(isNarrow) {
|
|
||||||
globalDrawer.collapsed = true
|
|
||||||
globalDrawer.width = Layout.implicitWidth
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
globalDrawer.collapsed = false
|
|
||||||
globalDrawer.width = originalWidth
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,9 +193,7 @@ Kirigami.ApplicationWindow {
|
||||||
active: !Kirigami.Settings.isMobile
|
active: !Kirigami.Settings.isMobile
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
sourceComponent: HeaderBar {
|
sourceComponent: HeaderBar { focus: true }
|
||||||
focus: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create space at the bottom to show miniplayer without it hiding stuff
|
// create space at the bottom to show miniplayer without it hiding stuff
|
||||||
|
@ -209,8 +210,32 @@ Kirigami.ApplicationWindow {
|
||||||
sourceComponent: FooterBar {
|
sourceComponent: FooterBar {
|
||||||
contentHeight: root.height * 2
|
contentHeight: root.height * 2
|
||||||
focus: true
|
focus: true
|
||||||
|
contentToPlayerSpacing: footer.active ? footer.item.height + 1 : 0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: footerShadowLoader
|
||||||
|
active: footer.active && !footerLoader.active
|
||||||
|
anchors.fill: footer
|
||||||
|
|
||||||
|
sourceComponent: RectangularGlow {
|
||||||
|
glowRadius: 5
|
||||||
|
spread: 0.3
|
||||||
|
color: Qt.rgba(0.0, 0.0, 0.0, 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: Loader {
|
||||||
|
visible: active
|
||||||
|
active: Kirigami.Settings.isMobile && !root.isWidescreen
|
||||||
|
sourceComponent: BottomToolbar {
|
||||||
|
transparentBackground: footerLoader.active
|
||||||
|
opacity: (!footerLoader.item || footerLoader.item.contentY === 0) ? 1 : 0
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: Kirigami.Units.shortDuration }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification that shows the progress of feed updates
|
// Notification that shows the progress of feed updates
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<file alias="NetworkSettingsPage.qml">qml/Settings/NetworkSettingsPage.qml</file>
|
<file alias="NetworkSettingsPage.qml">qml/Settings/NetworkSettingsPage.qml</file>
|
||||||
<file alias="StorageSettingsPage.qml">qml/Settings/StorageSettingsPage.qml</file>
|
<file alias="StorageSettingsPage.qml">qml/Settings/StorageSettingsPage.qml</file>
|
||||||
<file alias="SynchronizationSettingsPage.qml">qml/Settings/SynchronizationSettingsPage.qml</file>
|
<file alias="SynchronizationSettingsPage.qml">qml/Settings/SynchronizationSettingsPage.qml</file>
|
||||||
|
<file alias="BottomToolbar.qml">qml/BottomToolbar.qml</file>
|
||||||
<file>qtquickcontrols2.conf</file>
|
<file>qtquickcontrols2.conf</file>
|
||||||
<file alias="logo.svg">../kasts.svg</file>
|
<file alias="logo.svg">../kasts.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
|
Loading…
Reference in New Issue