General update

This commit is contained in:
Digital Artifex
2026-06-22 01:59:33 -04:00
parent 7854a3f440
commit 5a150c29f9
44 changed files with 2397 additions and 835 deletions
+1
View File
@@ -18,6 +18,7 @@ qt6_add_qml_module(KomplexHubContent
"pages/UserProfilePage.qml"
"pages/WallpaperSettingsPage.qml"
QML_FILES pages/VideoSearchPage.qml
QML_FILES views/ImageView.qml
)
+4 -6
View File
@@ -317,21 +317,19 @@ Rectangle {
}
}
KeroBuildingAnimation {
KeroBuildingAnimation
{
id: buildingOverlay
anchors.fill: parent
visible: false
}
KeroLoadingAnimation {
KeroLoadingAnimation
{
id: loadingAnimation
anchors.fill: parent
// OpacityAnimator on opacity {
// duration: 150
// }
visible: opacity > 0
opacity: 0
}
+47 -4
View File
@@ -1,4 +1,4 @@
import QtQuick
import QtQuick 2.15
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Effects
@@ -20,18 +20,54 @@ Item {
{
id: newestPacksModel
resultsPerPage: homePageRoot.resultsPerRow
onStateChanged: () =>
{
if(state == NewestPacksModel.Loading)
{
console.log("Newest packs loading")
}
else if(state == NewestPacksModel.Idle)
{
console.log("Newest packs finished")
}
}
}
FeaturedImagesModel
{
id: featuredImagesModel
resultsPerPage: homePageRoot.resultsPerRow
onStateChanged: () =>
{
if(state == FeaturedImagesModel.Loading)
{
console.log("Featured Images loading")
}
else if(state == FeaturedImagesModel.Idle)
{
console.log("Featured Images finished")
}
}
}
FeaturedVideosModel
{
id: featuredVideosModel
resultsPerPage: homePageRoot.resultsPerRow
onStateChanged: () =>
{
if(state == FeaturedVideosModel.Loading)
{
console.log("Featured Videos loading")
}
else if(state == FeaturedVideosModel.Idle)
{
console.log("Featured Videos finished")
}
}
}
Rectangle
@@ -210,10 +246,11 @@ Item {
{
anchors.fill: parent
title: parent.author
author: qsTr("Pexels Images")
description: parent.description
thumbnail: parent.thumbnail
uuid: parent.uuid
pexels: true
}
}
}
@@ -312,10 +349,9 @@ Item {
{
anchors.fill: parent
title: parent.author
author: parent.author
description: "Video provided by Pexels"
thumbnail: parent.thumbnail
uuid: parent.uuid
pexels: true
}
}
}
@@ -357,6 +393,13 @@ Item {
}
}
Component.onCompleted: () =>
{
featuredImagesModel.nextPage()
featuredVideosModel.nextPage()
newestPacksModel.nextPage()
}
KeroLoadingAnimation
{
id: loadingAnimation
+22 -196
View File
@@ -9,217 +9,43 @@ 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: rootItem
id: imageSearchPageRoot
property string query
readonly property bool searchable: paginator.searchable
ImageSearchModel
{
id: searchModel
query: imageSearchPageRoot.query
resultsPerPage: imageSearchPageRoot.resultsPerPage
query: rootItem.query
resultsPerPage: paginator.resultsPerPage
}
Rectangle
PaginatorGrid
{
id: paginator
anchors.fill: parent
color: palette.base
model: searchModel
loading: model.state === ImageSearchModel.Loading
Rectangle
delegate: Item
{
id: resultsContainer
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: buttonBoxLayout.top
width: 256
height: 245
required property string author
required property string description
required property string uuid
required property string thumbnail
required property string authorId
color: "transparent"
ScrollView
SearchResultItem
{
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: imageSearchPageRoot.resultsPerRow
columnSpacing: Constants.mediumMargin
rowSpacing: Constants.mediumMargin
Repeater
{
model: searchModel
delegate: Item
{
width: 256
height: 245
required property string author
required property string description
required property string uuid
required property string thumbnail
required property string authorId
SearchResultItem
{
anchors.fill: parent
title: parent.author
author: qsTr("Pexels Images")
description: parent.description
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()
title: parent.author
description: parent.description
thumbnail: parent.thumbnail
uuid: parent.uuid
}
}
}
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 == ImageSearchModel.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 == ImageSearchModel.Error
PropertyChanges
{
target: errorOverlay
opacity: 1
}
PropertyChanges
{
target: resultsView
opacity: 0
}
}
]
}
+34 -63
View File
@@ -3,76 +3,47 @@ import QtQuick.Controls
import KomplexHub
import KomplexHub.Controls
import KomplexHub.Kero
import KomplexHubPlugin
Item {
id: imageSearchPageRoot
Item
{
id: rootItem
SearchResultList {
id: searchResultList
anchors.fill: parent
color: palette.base
property string query
readonly property bool searchable: paginator.searchable
VideoSearchModel
{
id: searchModel
query: rootItem.query
resultsPerPage: paginator.resultsPerPage
}
KeroErrorAvatar {
id: errorOverlay
PaginatorGrid
{
id: paginator
anchors.fill: parent
opacity: 0
}
model: searchModel
loading: model.state === VideoSearchModel.Loading
KeroNoResultsAvatar {
id: noResultsOverlay
delegate: Item
{
width: 256
height: 245
required property string author
required property string description
required property string uuid
required property string thumbnail
required property string authorId
anchors.fill: parent
opacity: 0
}
KeroLoadingAnimation {
id: loadingOverlay
anchors.fill: parent
opacity: 0
}
states: [
State {
name: "loading"
when: searchResultList.state === "loading"
PropertyChanges {
target: loadingOverlay
opacity: 1
}
PropertyChanges {
target: resultsView
opacity: 0
}
},
State {
name: "empty"
when: searchResultList.state === "empty"
PropertyChanges {
target: noResultsOverlay
opacity: 1
}
PropertyChanges {
target: resultsView
opacity: 0
}
},
State {
name: "error"
when: searchResultList.state === "error"
PropertyChanges {
target: errorOverlay
opacity: 1
}
PropertyChanges {
target: resultsView
opacity: 0
SearchResultItem
{
anchors.fill: parent
title: parent.author
description: parent.description
thumbnail: parent.thumbnail
uuid: parent.uuid
}
}
]
}
}
+22 -196
View File
@@ -9,217 +9,43 @@ 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: rootItem
id: videoSearchPageRoot
property string query
readonly property bool searchable: paginator.searchable
VideoSearchModel
{
id: searchModel
query: videoSearchPageRoot.query
resultsPerPage: videoSearchPageRoot.resultsPerPage
query: rootItem.query
resultsPerPage: paginator.resultsPerPage
}
Rectangle
PaginatorGrid
{
id: paginator
anchors.fill: parent
color: palette.base
model: searchModel
loading: model.state === VideoSearchModel.Loading
Rectangle
delegate: Item
{
id: resultsContainer
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: buttonBoxLayout.top
width: 256
height: 245
required property string author
required property string description
required property string uuid
required property string thumbnail
required property string authorId
color: "transparent"
ScrollView
SearchResultItem
{
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()
title: parent.author
description: parent.description
thumbnail: parent.thumbnail
uuid: parent.uuid
}
}
}
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
}
}
]
}
+98
View File
@@ -0,0 +1,98 @@
import QtQuick 2.15
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Effects
import KomplexHub
import KomplexHub.Controls
import KomplexHub.Kero
import KomplexHubPlugin
Item
{
property string uuid
property string author
property string authorUrl
property string description
property string thumbnail
property string portrait
property string landscape
property string small
property string original
property string medium
property string large
property string extraLarge
property string portraitSize
property string landscapeSize
property string smallSize
property string originalSize
property string mediumSize
property string largeSize
property string extraLargeSize
property int imageHeight
property int imageWidth
id: rootItem
Rectangle
{
anchors.fill: parent
color: palette.base
ColumnLayout
{
anchors.fill: parent
anchors.margins: Constants.largeMargin
spacing: Constants.largeMargin
RowLayout
{
Layout.fillWidth: true
/** Spacer **/
Item { Layout.fillWidth: true }
Image
{
width: imageWidth
height: imageHeight
transform: Image.PreserveAspectFit
source: "qrc:/images/icons/pexels-icon-filled-256.svg"
}
/** Spacer **/
Item { Layout.fillWidth: true }
}
Text
{
id: titleText
text: rootItem.author
font.bold: true
font.pixelSize: Constants.h3Font.pixelSize
Layout.fillWidth: true
}
Text
{
id: descriptionText
text: rootItem.description
font.pointSize: Constants.h4Font.pixelSize
}
Image
{
width: 64
height: 64
transform: Image.PreserveAspectFit
source: "qrc:/images/icons/pexels-icon-filled-256.svg"
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
}
}
}
}