207 lines
6.8 KiB
QML
207 lines
6.8 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import KomplexHub
|
|
|
|
Item {
|
|
readonly property bool searchable: true
|
|
property int resultsPerPage: resultsPerRow * resultsPerColumn
|
|
property int resultsPerRow: width / (256 + Constants.largeMargin)
|
|
property int resultsPerColumn: height / (256 + Constants.largeMargin)
|
|
property int totalResults: 7
|
|
property int currentPage: 1
|
|
property color color: "transparent"
|
|
|
|
id: searchResultsPageRoot
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: searchResultsPageRoot.color
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: Constants.largeMargin
|
|
|
|
Component {
|
|
id: highlight
|
|
|
|
Rectangle {
|
|
width: view.cellWidth; height: view.cellHeight
|
|
color: "lightsteelblue";
|
|
radius: 5
|
|
x: view.currentItem.x
|
|
y: view.currentItem.y
|
|
Behavior on x { SpringAnimation { spring: 3; damping: 0.2 } }
|
|
Behavior on y { SpringAnimation { spring: 3; damping: 0.2 } }
|
|
}
|
|
}
|
|
|
|
//So the idea here is that the real query would request X number of results
|
|
// (say 50), but then the cache aggregator will paginate on the cache
|
|
// in a way that it would also account for the total number of results for
|
|
// the search term
|
|
|
|
//this is dummy data for the cache
|
|
WallpaperModelData {
|
|
property int totalResults: 17
|
|
property string term: ""
|
|
|
|
onTermChanged: () => {
|
|
//clear()
|
|
|
|
//this will be in the plugin
|
|
//query(0, 100, term)
|
|
}
|
|
|
|
id: wallpaperDataCache
|
|
|
|
//use the current search term to get the next chunk of data from the server
|
|
function extendCache() {
|
|
//this will be in the plugin
|
|
//query(count, 100, term)
|
|
}
|
|
}
|
|
|
|
ListModel {
|
|
property int index: 0
|
|
|
|
id: wallpaperCacheAggregator
|
|
|
|
//get the previous page data
|
|
function previous() {
|
|
searchResultsPageRoot.state = "loading"
|
|
index -= searchResultsPageRoot.resultsPerPage
|
|
|
|
if(index < 0)
|
|
index = 0
|
|
|
|
searchResultsPageRoot.currentPage -= 1
|
|
|
|
if(searchResultsPageRoot.currentPage < 1)
|
|
searchResultsPageRoot.currentPage = 1
|
|
|
|
searchResultsPageRoot.state = ""
|
|
aggregateCache()
|
|
}
|
|
|
|
//get the next page data
|
|
function next() {
|
|
searchResultsPageRoot.state = "loading"
|
|
|
|
index += searchResultsPageRoot.resultsPerPage
|
|
|
|
if(index >= searchResultsPageRoot.totalResults)
|
|
index = searchResultsPageRoot.totalResults - searchResultsPageRoot.resultsPerPage
|
|
|
|
searchResultsPageRoot.currentPage += 1
|
|
|
|
if(searchResultsPageRoot.currentPage > Math.ceil(searchResultsPageRoot.totalResults / searchResultsPageRoot.resultsPerPage))
|
|
searchResultsPageRoot.currentPage = Math.ceil(searchResultsPageRoot.totalResults / searchResultsPageRoot.resultsPerPage)
|
|
|
|
//download next chunk of data if we're at the end
|
|
if(index >= wallpaperDataCache.count)
|
|
wallpaperDataCache.extendCache()
|
|
|
|
searchResultsPageRoot.state = ""
|
|
aggregateCache()
|
|
}
|
|
|
|
//re-aggregate the current cache
|
|
function aggregateCache() {
|
|
clear()
|
|
|
|
for(var i = 0; i < searchResultsPageRoot.resultsPerPage && (index + i) < wallpaperDataCache.count; i++)
|
|
insert(i, wallpaperDataCache.get(index + i))
|
|
}
|
|
}
|
|
|
|
GridView {
|
|
id: resultsView
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
cellWidth: 256 + Constants.mediumMargin
|
|
cellHeight: 256 + Constants.mediumMargin
|
|
clip: true
|
|
model: wallpaperCacheAggregator
|
|
|
|
delegate: Rectangle {
|
|
required property string author
|
|
required property string description
|
|
required property string name
|
|
required property string thumbnail
|
|
required property string url
|
|
required property string uuid
|
|
|
|
SearchResultItem {
|
|
author: parent.author
|
|
description: parent.description
|
|
title: parent.name
|
|
thumbnail: parent.thumbnail
|
|
url: parent.url
|
|
uuid: parent.uuid
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: false
|
|
Layout.preferredHeight: 36
|
|
Layout.margins: Constants.largeMargin
|
|
|
|
SquareButton {
|
|
Layout.fillHeight: true
|
|
Layout.preferredWidth: 160
|
|
|
|
icon.source: "qrc:/images/icons/icons8-back.svg"
|
|
icon.height: 16
|
|
icon.width: 16
|
|
text: qsTr("Previous")
|
|
|
|
enabled: searchResultsPageRoot.currentPage > 1
|
|
|
|
onTriggered: () => {
|
|
wallpaperCacheAggregator.previous()
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
SquareButton {
|
|
Layout.fillHeight: true
|
|
Layout.preferredWidth: 160
|
|
|
|
icon.source: "qrc:/images/icons/icons8-next.svg"
|
|
icon.height: 16
|
|
icon.width: 16
|
|
text: qsTr("Next")
|
|
|
|
enabled: searchResultsPageRoot.currentPage < Math.ceil(searchResultsPageRoot.totalResults / searchResultsPageRoot.resultsPerPage)
|
|
|
|
onTriggered: () => {
|
|
wallpaperCacheAggregator.next()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
states: [
|
|
State {
|
|
name: "loading"
|
|
},
|
|
State {
|
|
name: "empty"
|
|
},
|
|
State {
|
|
name: "error"
|
|
}
|
|
]
|
|
|
|
onResultsPerPageChanged: () => wallpaperCacheAggregator.aggregateCache();
|
|
Component.onCompleted: () => wallpaperCacheAggregator.aggregateCache()
|
|
|
|
}
|