/* * This file is part of the Flowee project * Copyright (C) 2024 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick import QtQuick.Layouts import "../Flowee" as Flowee import "../mobile"; import Flowee.org.pay.blocks as Blocks; /** * This QML is used as a plugin from the main app, with the main goal to check if * blocks need to be doawnloaded. * * To start the process, set the wantedHeight property to non zero. * When we are done, we will hide ourselves (set visible to false) */ Item { id: root anchors.left: parent.left anchors.right: parent.right implicitHeight: { var h = titleLabel.height; if (busyIndicator.visible) h += busyIndicator.height + 10 if (errorLabel.visible) h += errorLabel.height + 6; if (downloadProgress.visible) h += downloadProgress.height + 6; if (netErrorLabel.visible) h += netErrorLabel.height + 6 + retryButton.height + 6 return h; } /// the blockheight that is needed by the caller. property alias wantedHeight: testData.wantedHeight Blocks.Checker { // This object is representing the CPP class BlockHeadersChecker id: testData onStatusChanged: { if (status === Blocks.Checker.NoDownloadNeeded || status === Blocks.Checker.Success) root.visible = false; } } Flowee.Label { id: titleLabel text: testData.status === Blocks.Checker.Verifying ? qsTr("Processing") : qsTr("Downloading Headers") anchors.horizontalCenter: parent.horizontalCenter } Item { id: busyIndicator width: 50 height: 50 anchors.horizontalCenter: parent.horizontalCenter anchors.top: titleLabel.bottom anchors.topMargin: 10 visible: testData.status === Blocks.Checker.Checking || testData.status === Blocks.Checker.Downloading || testData.status === Blocks.Checker.Verifying Repeater { model: 6 Item { x: busyIndicator.width / 2 y: busyIndicator.height / 2 width: 12 height: 1 rotation: index * 360 / 6 transformOrigin: Item.TopLeft Behavior on width { NumberAnimation { } } onVisibleChanged: width = visible ? 12 : 16 Rectangle { x: parent.width y: - height / 2 width: 14 height: 14 radius: 7 color: palette.text } } } Behavior on rotation { NumberAnimation { id: animator } } Timer { running: parent.visible repeat: true interval: 400 onTriggered: { if (busyIndicator.rotation < 1) { // first run-through animator.duration = interval; busyIndicator.rotation = 59; } else { // this jumps back. animator.duration = 0; busyIndicator.rotation = 0; // and then does the animation again. animator.duration = interval; busyIndicator.rotation = 59; } } } } Flowee.Label { id: errorLabel anchors.horizontalCenter: parent.horizontalCenter anchors.top: titleLabel.bottom anchors.topMargin: 6 text: "Disk related failure" // honestly so rare that it makes no sense to translate. visible: testData.status == Blocks.Checker.DiskFailure } Flowee.Progressbar { id: downloadProgress width: parent.width anchors.horizontalCenter: parent.horizontalCenter anchors.top: busyIndicator.bottom anchors.topMargin: 6 opacity: testData.status === Blocks.Checker.Downloading ? 1 : 0 visible: opacity > 0 progress: { let total = testData.totalDownload; if (total === 0) // not started yet. return 0; let cur = testData.bytesDownloaded; return cur / total; } Behavior on opacity { OpacityAnimator { } } } Flowee.Label { id: netErrorLabel text: qsTr("Download Unsuccessful") visible: testData.status === Blocks.Checker.NetworkFailure anchors.top: titleLabel.bottom anchors.topMargin: 6 color: mainWindow.errorRed } Flowee.Button { id: retryButton text: qsTr("Retry") visible: testData.status === Blocks.Checker.NetworkFailure anchors.top: netErrorLabel.bottom anchors.topMargin: 6 anchors.right: parent.right onClicked: testData.restart(); } }