Client OPDS per Calibre Web (Sailfish OS): core C++ testato, UI Silica, packaging RPM
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user