Jelle Spijker 7be2da587b
Automatic abortRequest for each API request
Defensive programming

Contributes to: CURA-8587
2021-12-08 10:18:08 +01:00

233 lines
7.9 KiB
QML

// Copyright (c) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.15
import QtQuick.Controls 2.15
import UM 1.4 as UM
ListView
{
id: packages
width: parent.width
property string pageTitle
property var selectedPackage
property string searchInBrowserUrl
property bool bannerVisible
property var bannerIcon
property string bannerText
property string bannerReadMoreUrl
property var onRemoveBanner
property bool packagesManageableInListView
clip: true
Component.onCompleted: model.updatePackages()
Component.onDestruction: model.cleanUpAPIRequest()
spacing: UM.Theme.getSize("default_margin").height
section.property: "package.sectionTitle"
section.delegate: Rectangle
{
width: packages.width
height: sectionHeaderText.height + UM.Theme.getSize("default_margin").height
color: UM.Theme.getColor("detail_background")
Label
{
id: sectionHeaderText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
text: section
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
}
}
ScrollBar.vertical: ScrollBar
{
// Vertical ScrollBar, styled similarly to the scrollBar in the settings panel
id: verticalScrollBar
visible: packages.contentHeight > packages.height
background: Item{}
contentItem: Rectangle
{
id: scrollViewHandle
implicitWidth: UM.Theme.getSize("scrollbar").width
radius: Math.round(implicitWidth / 2)
color: verticalScrollBar.pressed ? UM.Theme.getColor("scrollbar_handle_down") : verticalScrollBar.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle")
Behavior on color { ColorAnimation { duration: 50; } }
}
}
delegate: MouseArea
{
id: cardMouseArea
width: parent ? parent.width : 0
height: childrenRect.height
hoverEnabled: true
onClicked:
{
packages.selectedPackage = model.package;
contextStack.push(packageDetailsComponent);
}
PackageCard
{
manageableInListView: packages.packagesManageableInListView
packageData: model.package
width: parent.width - UM.Theme.getSize("default_margin").width - UM.Theme.getSize("narrow_margin").width
color: cardMouseArea.containsMouse ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("main_background")
}
}
Component
{
id: packageDetailsComponent
PackageDetails
{
packageData: packages.selectedPackage
title: packages.pageTitle
}
}
//Wrapper item to add spacing between content and footer.
footer: Item
{
width: parent.width - UM.Theme.getSize("default_margin").width - UM.Theme.getSize("narrow_margin").width
height: model.hasFooter || packages.model.errorMessage != "" ? UM.Theme.getSize("card").height + packages.spacing : 0
visible: model.hasFooter || packages.model.errorMessage != ""
Button
{
id: loadMoreButton
width: parent.width
height: UM.Theme.getSize("card").height
anchors.bottom: parent.bottom
enabled: packages.model.hasMore && !packages.model.isLoading || packages.model.errorMessage != ""
onClicked: packages.model.updatePackages() //Load next page in plug-in list.
background: Rectangle
{
anchors.fill: parent
radius: UM.Theme.getSize("default_radius").width
color: UM.Theme.getColor("main_background")
}
Row
{
anchors.centerIn: parent
spacing: UM.Theme.getSize("thin_margin").width
states:
[
State
{
name: "Error"
when: packages.model.errorMessage != ""
PropertyChanges
{
target: errorIcon
visible: true
}
PropertyChanges
{
target: loadMoreIcon
visible: false
}
PropertyChanges
{
target: loadMoreLabel
text: catalog.i18nc("@button", "Failed to load packages:") + " " + packages.model.errorMessage + "\n" + catalog.i18nc("@button", "Retry?")
}
},
State
{
name: "Loading"
when: packages.model.isLoading
PropertyChanges
{
target: loadMoreIcon
source: UM.Theme.getIcon("ArrowDoubleCircleRight")
color: UM.Theme.getColor("action_button_disabled_text")
}
PropertyChanges
{
target: loadMoreLabel
text: catalog.i18nc("@button", "Loading")
color: UM.Theme.getColor("action_button_disabled_text")
}
},
State
{
name: "LastPage"
when: !packages.model.hasMore
PropertyChanges
{
target: loadMoreIcon
visible: false
}
PropertyChanges
{
target: loadMoreLabel
text: packages.model.count > 0 ? catalog.i18nc("@message", "No more results to load") : catalog.i18nc("@message", "No results found with current filter")
color: UM.Theme.getColor("action_button_disabled_text")
}
}
]
Item
{
width: (errorIcon.visible || loadMoreIcon.visible) ? UM.Theme.getSize("small_button_icon").width : 0
height: UM.Theme.getSize("small_button_icon").height
anchors.verticalCenter: loadMoreLabel.verticalCenter
UM.StatusIcon
{
id: errorIcon
anchors.fill: parent
status: UM.StatusIcon.Status.ERROR
visible: false
}
UM.RecolorImage
{
id: loadMoreIcon
anchors.fill: parent
source: UM.Theme.getIcon("ArrowDown")
color: UM.Theme.getColor("secondary_button_text")
RotationAnimator
{
target: loadMoreIcon
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
running: packages.model.isLoading
alwaysRunToEnd: true
}
}
}
Label
{
id: loadMoreLabel
text: catalog.i18nc("@button", "Load more")
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("secondary_button_text")
}
}
}
}
}