diff --git a/ui/app/AppLayouts/Browser/BrowserLayout.qml b/ui/app/AppLayouts/Browser/BrowserLayout.qml
index 7770038458..d2176925b0 100644
--- a/ui/app/AppLayouts/Browser/BrowserLayout.qml
+++ b/ui/app/AppLayouts/Browser/BrowserLayout.qml
@@ -32,6 +32,13 @@ Rectangle {
property var downloads: []
}
+ function removeDownloadFromModel(index) {
+ downloadModel.downloads = downloadModel.downloads.filter(function (el) {
+ return el.id !== downloadModel.downloads[index].id;
+ });
+ downloadModel.remove(index);
+ }
+
Layout.fillHeight: true
Layout.fillWidth: true
@@ -631,7 +638,7 @@ Rectangle {
}
function onDownloadRequested(download) {
- downloadBar.visible = true
+ downloadBar.isVisible = true
downloadView.append(download);
download.accept();
}
diff --git a/ui/app/AppLayouts/Browser/DownloadBar.qml b/ui/app/AppLayouts/Browser/DownloadBar.qml
index 1073fd1d21..f66ba9f00f 100644
--- a/ui/app/AppLayouts/Browser/DownloadBar.qml
+++ b/ui/app/AppLayouts/Browser/DownloadBar.qml
@@ -4,11 +4,11 @@ import "../../../shared"
import "../../../shared/status"
import "../../../imports"
-//downloadModel.downloads[index].receivedBytes
-
Rectangle {
+ property bool isVisible: false
+
id: root
- visible: false
+ visible: isVisible && !!listView.count
color: Style.current.background
width: parent.width
height: 56
@@ -61,7 +61,7 @@ Rectangle {
icon.name: "browser/close"
iconColor: Style.current.textColor
onClicked: {
- root.visible = false
+ root.isVisible = false
}
}
}
diff --git a/ui/app/AppLayouts/Browser/DownloadElement.qml b/ui/app/AppLayouts/Browser/DownloadElement.qml
index 37ecf642d7..2a0d5e5add 100644
--- a/ui/app/AppLayouts/Browser/DownloadElement.qml
+++ b/ui/app/AppLayouts/Browser/DownloadElement.qml
@@ -1,14 +1,44 @@
import QtQuick 2.1
+import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import "../../../shared"
import "../../../shared/status"
import "../../../imports"
-Item {
- id: downloadElement
+Rectangle {
+ property bool downloadComplete: {
+ return !!downloadModel.downloads && !!downloadModel.downloads[index] && downloadModel.downloads[index].receivedBytes >= downloadModel.downloads[index].totalBytes
+ }
+ property bool isCanceled: false
+ property bool hovered: false
+
+ id: root
width: 272
height: 40
+ border.width: 0
+ color: hovered ? Style.current.backgroundHover : Style.current.transparent
+ radius: Style.current.radius
+
+ function openFile() {
+ Qt.openUrlExternally(`file://${downloadDirectory}/${downloadFileName}`)
+ removeDownloadFromModel(index)
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ hoverEnabled: true
+ onEntered: {
+ root.hovered = true
+ }
+ onExited: {
+ root.hovered = false
+ }
+ onClicked: {
+ openFile()
+ }
+ }
Loader {
id: iconLoader
@@ -17,10 +47,10 @@ Item {
anchors.leftMargin: Style.current.smallPadding
active: root.visible
sourceComponent: {
- if (!downloadModel.downloads || !downloadModel.downloads[index] || downloadModel.downloads[index].receivedBytes < downloadModel.downloads[index].totalBytes) {
- return loadingImageComponent
+ if (downloadComplete || !downloadModel.downloads[index] || downloadModel.downloads[index].isPaused || isCanceled) {
+ return fileImageComponent
}
- return fileImageComponent
+ return loadingImageComponent
}
Component {
@@ -34,10 +64,9 @@ Item {
width: 24
height: 24
ColorOverlay {
- enabled: false
anchors.fill: parent
source: parent
- color: Style.current.darkGrey
+ color: downloadComplete ? Style.current.transparent : Style.current.darkGrey
}
}
}
@@ -49,7 +78,8 @@ Item {
elide: Text.ElideRight
anchors.left: iconLoader.right
anchors.right: optionsBtn.left
- anchors.top: parent.top
+ anchors.top: downloadComplete ? undefined : parent.top
+ anchors.verticalCenter: downloadComplete ? parent.verticalCenter : undefined
minimumPixelSize: 13
anchors.leftMargin: Style.current.smallPadding
anchors.topMargin: 2
@@ -57,8 +87,17 @@ Item {
StyledText {
id: progressText
+ visible: !downloadComplete
color: Style.current.secondaryText
- text: `${downloadModel.downloads[index] ? downloadModel.downloads[index].receivedBytes / 1000000 : 0}/${downloadModel.downloads[index] ? downloadModel.downloads[index].totalBytes / 1000000 : 0} MB` //"14.4/109 MB, 26 sec left"
+ text: {
+ if (isCanceled) {
+ return qsTr("Cancelled")
+ }
+ if (downloadModel.downloads[index] && downloadModel.downloads[index].isPaused) {
+ return qsTr("Paused")
+ }
+ return `${downloadModel.downloads[index] ? (downloadModel.downloads[index].receivedBytes / 1000000).toFixed(2) : 0}/${downloadModel.downloads[index] ? (downloadModel.downloads[index].totalBytes / 1000000).toFixed(2) : 0} MB` //"14.4/109 MB, 26 sec left"
+ }
elide: Text.ElideRight
anchors.left: iconLoader.right
anchors.right: optionsBtn.left
@@ -74,6 +113,70 @@ Item {
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
icon.name: "dots-icon"
+ onClicked: {
+ downloadMenu.x = optionsBtn.x
+ downloadMenu.open()
+ }
+ }
+
+ // TODO Move this outside?
+ PopupMenu {
+ id: downloadMenu
+ y: -height - Style.current.smallPadding
+
+ Action {
+ enabled: downloadComplete
+ icon.source: "../../img/browser/file.svg"
+ icon.width: 16
+ icon.height: 16
+ text: qsTr("Open")
+ onTriggered: openFile()
+ }
+ Action {
+ icon.source: "../../img/add_watch_only.svg"
+ icon.width: 13
+ icon.height: 9
+ text: qsTr("Show in folder")
+ // TODO check if this works in Windows and Mac
+ onTriggered: Qt.openUrlExternally("file://" + downloadDirectory)
+ }
+ Action {
+ enabled: !downloadComplete && !!downloadModel.downloads[index] && !downloadModel.downloads[index].isPaused
+ icon.source: "../../img/browser/pause.svg"
+ icon.width: 16
+ icon.height: 16
+ text: qsTr("Pause")
+ onTriggered: {
+ downloadModel.downloads[index].pause()
+ }
+ }
+ Action {
+ enabled: !downloadComplete && !!downloadModel.downloads[index] && downloadModel.downloads[index].isPaused
+ icon.source: "../../img/browser/play.svg"
+ icon.width: 16
+ icon.height: 16
+ text: qsTr("Resume")
+ onTriggered: {
+ downloadModel.downloads[index].resume()
+ }
+ }
+
+ Separator {
+ visible: !downloadComplete
+ }
+
+ Action {
+ enabled: !downloadComplete
+ icon.source: "../../img/block-icon.svg"
+ icon.width: 13
+ icon.height: 13
+ text: qsTr("Cancel")
+ onTriggered: {
+ downloadModel.downloads[index].cancel()
+ isCanceled = true
+ }
+ icon.color: Style.current.red
+ }
}
}
diff --git a/ui/app/AppLayouts/Browser/DownloadView.qml b/ui/app/AppLayouts/Browser/DownloadView.qml
index b1dee6dd27..efc4e56e9b 100644
--- a/ui/app/AppLayouts/Browser/DownloadView.qml
+++ b/ui/app/AppLayouts/Browser/DownloadView.qml
@@ -96,7 +96,7 @@ Rectangle {
}
Label {
id: label
- text: downloadModel.downloads[index].downloadDirectory + "/" + downloadModel.downloads[index].downloadFileName
+ text: downloadDirectory + "/" + downloadFileName
anchors {
verticalCenter: cancelButton.verticalCenter
left: parent.left
@@ -112,10 +112,7 @@ Rectangle {
download.cancel();
- downloadModel.downloads = downloadModel.downloads.filter(function (el) {
- return el.id !== download.id;
- });
- downloadModel.remove(index);
+ removeDownloadFromModel(index)
}
}
}
diff --git a/ui/app/img/browser/pause.svg b/ui/app/img/browser/pause.svg
new file mode 100644
index 0000000000..63df28447d
--- /dev/null
+++ b/ui/app/img/browser/pause.svg
@@ -0,0 +1,4 @@
+
diff --git a/ui/app/img/browser/play.svg b/ui/app/img/browser/play.svg
new file mode 100644
index 0000000000..6718a9ba71
--- /dev/null
+++ b/ui/app/img/browser/play.svg
@@ -0,0 +1,3 @@
+
diff --git a/ui/shared/Separator.qml b/ui/shared/Separator.qml
index 463239b14c..5f538da593 100644
--- a/ui/shared/Separator.qml
+++ b/ui/shared/Separator.qml
@@ -4,7 +4,7 @@ import "../imports"
Rectangle {
id: separator
width: parent.width
- height: 1
+ height: visible ? 1 : 0
color: Style.current.border
anchors.topMargin: Style.current.padding
}