226 lines
6.0 KiB
QML
226 lines
6.0 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
|
|
import KomplexHub
|
|
import KomplexHub.Controls
|
|
import KomplexHub.Kero
|
|
import KomplexHubPlugin
|
|
|
|
Item
|
|
{
|
|
property string query
|
|
readonly property bool searchable: true
|
|
property int resultsPerRow: (resultsContainer.width - (Constants.largeMargin * 2)) / (resultWidth + Constants.mediumMargin)
|
|
property int rows: ((resultsContainer.height - (Constants.largeMargin * 2)) / (resultHeight + Constants.mediumMargin))
|
|
property int resultsPerPage: resultsPerRow * rows
|
|
property int emptyWidth: (resultsContainer.width - (Constants.largeMargin * 2)) - (resultsPerRow * (resultWidth + Constants.mediumMargin))
|
|
property int resultWidth: 256
|
|
property int resultHeight: 245
|
|
|
|
id: videoSearchPageRoot
|
|
|
|
VideoSearchModel
|
|
{
|
|
id: searchModel
|
|
query: videoSearchPageRoot.query
|
|
resultsPerPage: videoSearchPageRoot.resultsPerPage
|
|
}
|
|
|
|
Rectangle
|
|
{
|
|
anchors.fill: parent
|
|
color: palette.base
|
|
|
|
Rectangle
|
|
{
|
|
id: resultsContainer
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: buttonBoxLayout.top
|
|
|
|
color: "transparent"
|
|
|
|
ScrollView
|
|
{
|
|
id: resultsView
|
|
anchors.fill: parent
|
|
|
|
RowLayout
|
|
{
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
anchors.top: parent.top
|
|
anchors.margins: Constants.largeMargin
|
|
|
|
Item
|
|
{
|
|
Layout.fillHeight: true
|
|
Layout.preferredWidth: emptyWidth / 2
|
|
Layout.maximumWidth: emptyWidth / 2
|
|
}
|
|
|
|
GridLayout
|
|
{
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
|
|
columns: videoSearchPageRoot.resultsPerRow
|
|
columnSpacing: Constants.mediumMargin
|
|
rowSpacing: Constants.mediumMargin
|
|
|
|
Repeater
|
|
{
|
|
model: searchModel
|
|
|
|
delegate: Item {
|
|
width: resultWidth
|
|
height: resultHeight
|
|
|
|
required property string uuid
|
|
required property string author
|
|
required property string authorId
|
|
required property string authorUrl
|
|
required property string thumbnail
|
|
|
|
SearchResultItem
|
|
{
|
|
anchors.fill: parent
|
|
title: parent.author
|
|
author: parent.author
|
|
description: "Video provided by Pexels"
|
|
thumbnail: parent.thumbnail
|
|
uuid: parent.uuid
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout
|
|
{
|
|
id: buttonBoxLayout
|
|
height: 35
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
anchors.margins: Constants.largeMargin
|
|
|
|
SquareButton
|
|
{
|
|
Layout.fillHeight: true
|
|
Layout.preferredWidth: 128
|
|
|
|
icon.source: "qrc:/images/icons/icons8-back.svg"
|
|
icon.height: 16
|
|
icon.width: 16
|
|
text: qsTr("Previous")
|
|
enabled: searchModel.hasPreviousPage
|
|
|
|
onTriggered: () => searchModel.previousPage()
|
|
}
|
|
|
|
Item { Layout.fillWidth: true }
|
|
|
|
SquareButton
|
|
{
|
|
Layout.fillHeight: true
|
|
Layout.preferredWidth: 128
|
|
|
|
icon.source: "qrc:/images/icons/icons8-next.svg"
|
|
icon.height: 16
|
|
icon.width: 16
|
|
text: qsTr("Next")
|
|
enabled: searchModel.hasNextPage
|
|
|
|
onTriggered: () => searchModel.nextPage()
|
|
}
|
|
}
|
|
}
|
|
|
|
KeroErrorAvatar
|
|
{
|
|
id: errorOverlay
|
|
|
|
anchors.fill: parent
|
|
opacity: 0
|
|
}
|
|
|
|
KeroNoResultsAvatar
|
|
{
|
|
id: noResultsOverlay
|
|
|
|
anchors.fill: parent
|
|
opacity: 0
|
|
}
|
|
|
|
KeroLoadingAnimation
|
|
{
|
|
id: loadingOverlay
|
|
|
|
anchors.fill: parent
|
|
opacity: 0
|
|
}
|
|
|
|
states: [
|
|
State
|
|
{
|
|
name: "loading"
|
|
when: searchModel.state == VideoSearchModel.Loading
|
|
|
|
PropertyChanges
|
|
{
|
|
target: loadingOverlay
|
|
opacity: 1
|
|
}
|
|
PropertyChanges
|
|
{
|
|
target: resultsView
|
|
opacity: 0
|
|
}
|
|
},
|
|
State
|
|
{
|
|
name: "empty"
|
|
when: searchModel.totalResults === 0
|
|
|
|
PropertyChanges
|
|
{
|
|
target: noResultsOverlay
|
|
opacity: 1
|
|
}
|
|
PropertyChanges
|
|
{
|
|
target: resultsView
|
|
opacity: 0
|
|
}
|
|
PropertyChanges
|
|
{
|
|
target: buttonBoxLayout
|
|
visible: false
|
|
}
|
|
},
|
|
State
|
|
{
|
|
name: "error"
|
|
when: searchModel.state == VideoSearchModel.Error
|
|
|
|
PropertyChanges
|
|
{
|
|
target: errorOverlay
|
|
opacity: 1
|
|
}
|
|
PropertyChanges
|
|
{
|
|
target: resultsView
|
|
opacity: 0
|
|
}
|
|
}
|
|
]
|
|
}
|