import QtQuick 2.0 import Sailfish.Silica 1.0 Page { id: page property string feedUrl property string pageTitle property string nextUrl: "" property bool loading: false property bool loadingMore: false property string errorMessage: "" SilicaListView { id: listView anchors.fill: parent header: PageHeader { title: page.pageTitle } model: feedModel clip: true delegate: ListItem { id: item contentHeight: Theme.itemSizeMedium Image { id: coverThumb anchors.left: parent.left anchors.leftMargin: Theme.horizontalPageMargin anchors.verticalCenter: parent.verticalCenter width: Theme.itemSizeMedium * 0.68 height: Theme.itemSizeMedium * 0.92 fillMode: Image.PreserveAspectFit visible: source.length > 0 && !model.isNav source: model.coverSource } Column { anchors.left: model.isNav ? parent.left : coverThumb.right anchors.leftMargin: Theme.horizontalPageMargin anchors.right: parent.right anchors.rightMargin: Theme.horizontalPageMargin anchors.verticalCenter: parent.verticalCenter Label { width: parent.width text: model.entryTitle color: item.highlighted ? Theme.highlightColor : Theme.primaryColor truncationMode: TruncationMode.Elide } Label { width: parent.width text: model.entryAuthors color: Theme.secondaryColor font.pixelSize: Theme.fontSizeSmall truncationMode: TruncationMode.Elide visible: text.length > 0 && !model.isNav } } Icon { anchors.right: parent.right anchors.rightMargin: Theme.horizontalPageMargin anchors.verticalCenter: parent.verticalCenter source: "image://theme/icon-m-right" visible: model.isNav } onClicked: { if (model.isNav) { pageStack.push(Qt.resolvedUrl("FeedPage.qml"), { feedUrl: model.entryLink, pageTitle: model.entryTitle }) } else { pageStack.push(Qt.resolvedUrl("BookDetailPage.qml"), { bookData: model.entryData }) } } } footer: Item { width: parent.width height: page.nextUrl.length > 0 ? Theme.itemSizeSmall : 0 BusyIndicator { anchors.centerIn: parent running: page.loadingMore size: BusyIndicatorSize.Small } } PullDownMenu { MenuItem { text: "Aggiorna" onClicked: reload() } MenuItem { text: "Impostazioni" onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml")) } } ViewPlaceholder { enabled: feedModel.count === 0 && !page.loading text: page.errorMessage.length > 0 ? page.errorMessage : "Nessun risultato" } BusyIndicator { anchors.centerIn: parent running: page.loading size: BusyIndicatorSize.Large } onContentYChanged: tryLoadMore() onCountChanged: tryLoadMore() } ListModel { id: feedModel } function reload() { feedModel.clear() page.nextUrl = "" loadFeed(page.feedUrl) } function loadFeed(url) { page.loading = true page.errorMessage = "" apiClient.getFeed(url) } function loadMore() { page.loadingMore = true apiClient.getFeed(page.nextUrl) } function tryLoadMore() { if (page.nextUrl.length === 0 || page.loadingMore || page.loading) return if (listView.contentY + listView.height >= listView.contentHeight - Theme.itemSizeMedium * 2) loadMore() } onNextUrlChanged: tryLoadMore() Component.onCompleted: loadFeed(feedUrl) Connections { target: apiClient onFeedReady: { if (pageStack.currentPage !== page) return page.loading = false page.loadingMore = false for (var i = 0; i < entries.length; i++) { var e = entries[i] var isNav = e.isNavigation feedModel.append({ entryTitle: e.title, entryAuthors: e.authors, entryLink: e.linkUrl, isNav: isNav, entryData: e, coverSource: "", coverId: e.id }) if (!isNav && e.coverUrl.length > 0) apiClient.fetchImage(e.coverUrl, e.id) } page.nextUrl = nextUrl if (feedModel.count === 0 && page.errorMessage.length === 0) page.errorMessage = "Nessun risultato" } onFeedError: { page.loading = false page.loadingMore = false page.errorMessage = message } onImageReady: function(imageId, localPath) { for (var i = 0; i < feedModel.count; i++) { if (feedModel.get(i).coverId === imageId) { feedModel.setProperty(i, "coverSource", localPath) break } } } } }