Files
harbour-calibreweb/qml/pages/BookDetailPage.qml
T

177 lines
5.1 KiB
QML

import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
property var bookData: ({})
property string coverSource: ""
property bool downloading: false
property string downloadError: ""
SilicaFlickable {
anchors.fill: parent
contentHeight: column.height + Theme.paddingLarge
Column {
id: column
width: parent.width
PageHeader { title: bookData.title }
Image {
id: cover
anchors.horizontalCenter: parent.horizontalCenter
width: Math.min(parent.width * 0.45, 260)
height: width * 1.5
fillMode: Image.PreserveAspectFit
source: page.coverSource
visible: source.length > 0
}
Label {
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: bookData.authors
color: Theme.secondaryColor
wrapMode: Text.Wrap
visible: text.length > 0
}
Label {
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: bookData.summary
wrapMode: Text.Wrap
font.pixelSize: Theme.fontSizeSmall
visible: text.length > 0
}
SectionHeader { text: "Formati" }
Repeater {
model: bookData.formats
delegate: ListItem {
id: formatItem
contentHeight: Theme.itemSizeMedium
enabled: !page.downloading
Label {
anchors.left: parent.left
anchors.leftMargin: Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
text: modelData.format
+ (modelData.size > 0 ? " (" + formatSize(modelData.size) + ")" : "")
color: formatItem.highlighted ? Theme.highlightColor : Theme.primaryColor
}
onClicked: startDownload(modelData)
}
}
Label {
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: page.downloadError
color: Theme.errorColor
wrapMode: Text.Wrap
visible: text.length > 0
}
Item { width: 1; height: Theme.paddingLarge }
}
}
Column {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
visible: page.downloading
height: Theme.itemSizeMedium
ProgressBar {
id: progressBar
anchors.left: parent.left
anchors.right: parent.right
value: 0
minimumValue: 0
maximumValue: 1
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: "Download in corso…"
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeSmall
}
}
Toast {
id: toast
}
function formatSize(bytes) {
if (bytes <= 0)
return ""
if (bytes < 1048576)
return Math.round(bytes / 1024) + " KB"
return (bytes / 1048576).toFixed(1) + " MB"
}
function resolveUrl(u) {
if (u.indexOf("http://") === 0 || u.indexOf("https://") === 0)
return u
var base = appSettings.baseUrl
return base + (u.charAt(0) === "/" ? u : "/" + u)
}
function sanitizeFileName(s) {
return s.replace(/[\\/:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
}
function startDownload(format) {
if (page.downloading)
return
var ext = format.format.toLowerCase()
var dest = appSettings.downloadDir + "/"
+ sanitizeFileName(bookData.title) + "." + ext
page.downloading = true
page.downloadError = ""
progressBar.value = 0
progressBar.maximumValue = format.size > 0 ? format.size : 1
downloader.download(resolveUrl(format.url), dest)
}
Component.onCompleted: {
if (bookData.coverUrl && bookData.coverUrl.length > 0)
apiClient.fetchImage(bookData.coverUrl, "detail:" + bookData.id)
}
Connections {
target: apiClient
onImageReady: {
if (id === "detail:" + bookData.id)
page.coverSource = localPath
}
}
Connections {
target: downloader
onProgress: {
if (!page.downloading)
return
progressBar.value = received
if (total > 0)
progressBar.maximumValue = total
}
onFinished: {
page.downloading = false
if (ok) {
page.downloadError = ""
toast.show("Salvato in " + path)
} else {
page.downloadError = "Errore: " + error
}
}
}
}