206 lines
6.5 KiB
QML
206 lines
6.5 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15 as Controls
|
|
import QtQuick.Layouts 1.15
|
|
|
|
import org.kde.kirigami 2.20 as Kirigami
|
|
|
|
import BigScreenTube 1.0
|
|
|
|
Controls.Pane
|
|
{
|
|
anchors {
|
|
fill: parent
|
|
margins: 32
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: Kirigami.Theme.backgroundColor
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
searchText.forceActiveFocus()
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
|
|
Kirigami.Heading {
|
|
Layout.fillWidth: true
|
|
level: 1
|
|
text: qsTr("Search videos")
|
|
font.weight: Font.Light
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: searchText
|
|
topPadding: 16
|
|
bottomPadding: 16
|
|
placeholderText: qsTr("Search videos...")
|
|
focus: true
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Keys.onReturnPressed: {
|
|
searchController.searchVideo(text)
|
|
}
|
|
|
|
KeyNavigation.down: videoListView
|
|
}
|
|
|
|
Rectangle {
|
|
id: searchResultContainer
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
|
|
color: Kirigami.Theme.backgroundColor
|
|
|
|
Controls.ScrollIndicator {
|
|
id: videoListScroll
|
|
active: true
|
|
width: 12
|
|
anchors {
|
|
top: searchResultContainer.top
|
|
right: searchResultContainer.right
|
|
bottom: searchResultContainer.bottom
|
|
}
|
|
}
|
|
|
|
Keys.onEscapePressed: {
|
|
searchText.forceActiveFocus()
|
|
}
|
|
|
|
Keys.onBackPressed: {
|
|
searchText.forceActiveFocus()
|
|
}
|
|
|
|
ListView {
|
|
id: videoListView
|
|
// Model contains info to be displayed
|
|
model: searchController.model
|
|
// Delegate is how the information will be presented in the ListView
|
|
|
|
anchors.fill: parent
|
|
spacing: Kirigami.Units.largeSpacing
|
|
anchors.rightMargin: 15
|
|
|
|
clip: true
|
|
|
|
Controls.ScrollIndicator.vertical: videoListScroll
|
|
|
|
preferredHighlightBegin: currentItem ? height / 2 - currentItem.height / 2 : 0
|
|
preferredHighlightEnd: currentItem ? height / 2 + currentItem.height / 2 : height
|
|
highlightRangeMode: ListView.ApplyRange
|
|
|
|
|
|
Controls.BusyIndicator {
|
|
id: searchSpinner
|
|
running: false
|
|
|
|
anchors {
|
|
horizontalCenter: parent.horizontalCenter
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
delegate: Rectangle {
|
|
color: (videoListView.currentIndex == index && videoListView.activeFocus) ? Kirigami.Theme.activeBackgroundColor : Qt.lighter(Kirigami.Theme.backgroundColor, 1.2)
|
|
|
|
width: parent ? parent.width : 0
|
|
radius: 4
|
|
|
|
// height + margins
|
|
implicitHeight: delegateLayout.implicitHeight + 20
|
|
|
|
RowLayout {
|
|
id: delegateLayout
|
|
anchors {
|
|
left: parent.left
|
|
top: parent.top
|
|
right: parent.right
|
|
bottom: parent.bottom
|
|
margins: 10
|
|
}
|
|
|
|
spacing: Kirigami.Units.largeSpacing
|
|
|
|
Rectangle {
|
|
height: 180
|
|
width: 320
|
|
color: "transparent"
|
|
|
|
Image {
|
|
source: thumbnailUrl
|
|
fillMode: Image.PreserveAspectFit
|
|
anchors.fill: parent
|
|
}
|
|
|
|
Image {
|
|
source: "images/play.svg"
|
|
fillMode: Image.PreserveAspectFit
|
|
anchors {
|
|
horizontalCenter: parent.horizontalCenter
|
|
verticalCenter: parent.verticalCenter
|
|
}
|
|
opacity: 0.7
|
|
sourceSize.width: 150
|
|
sourceSize.height: 150
|
|
visible: videoListView.currentIndex == index && videoListView.activeFocus
|
|
}
|
|
|
|
}
|
|
|
|
// Layout for positioning elements vertically
|
|
ColumnLayout {
|
|
Kirigami.Heading {
|
|
Layout.fillWidth: true
|
|
level: 1
|
|
text: title
|
|
color: Kirigami.Theme.textColor
|
|
}
|
|
|
|
Kirigami.Heading {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
level: 2
|
|
text: programName
|
|
color: Kirigami.Theme.textColor
|
|
}
|
|
|
|
// Labels contain text
|
|
Controls.Label {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Published") + " " + new Date(published * 1000).toLocaleDateString()
|
|
color: Kirigami.Theme.textColor
|
|
}
|
|
}
|
|
}
|
|
|
|
Keys.onReturnPressed: {
|
|
console.log("Selecting video")
|
|
appStack.push("VideoPage.qml", {videoTitle: title, videoSource: sourceUrl})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SearchController {
|
|
id: searchController
|
|
|
|
property var signals: Connections {
|
|
function onSearchLoaded() {
|
|
searchSpinner.running = false
|
|
videoListView.forceActiveFocus()
|
|
videoListView.currentIndex = 0
|
|
}
|
|
|
|
function onSearchStart() {
|
|
searchSpinner.running = true
|
|
}
|
|
|
|
function onSearchError() {
|
|
showPassiveNotification(qsTr("Network error occured during search"))
|
|
}
|
|
}
|
|
}
|
|
}
|