Compare commits
22 Commits
63e45eb4d4
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
b4a1e1bbf4
|
|||
|
2fab4f209f
|
|||
|
6541cedc67
|
|||
|
f3adc14a6e
|
|||
|
7b25255126
|
|||
|
1aaff0cd02
|
|||
|
d60cdef637
|
|||
|
97c9ba30f0
|
|||
|
6e94484fac
|
|||
|
1d87abd5af
|
|||
|
0402b0902d
|
|||
|
ac65bbb3ab
|
|||
|
45f293a349
|
|||
|
fa3c6354cb
|
|||
|
f23aada9a5
|
|||
|
0fe189bfde
|
|||
|
bb90186932
|
|||
|
61231a890a
|
|||
|
8e95f66dc3
|
|||
|
b8d5670530
|
|||
|
700de7a757
|
|||
|
5ef7f54cfe
|
+3
-2
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.21.1)
|
||||
option(LINK_INSIGHT "Link Qt Insight Tracker library" ON)
|
||||
option(BUILD_QDS_COMPONENTS "Build design studio components" ON)
|
||||
|
||||
project(KomplexHub LANGUAGES CXX)
|
||||
project(KomplexHub VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
@@ -21,7 +21,7 @@ set(QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
find_package(
|
||||
Qt6 6.8
|
||||
Qt6
|
||||
REQUIRED COMPONENTS
|
||||
Core
|
||||
Gui
|
||||
@@ -38,6 +38,7 @@ qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(${CMAKE_PROJECT_NAME}
|
||||
)
|
||||
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES VERSION "1.0")
|
||||
|
||||
qt_add_resources(${CMAKE_PROJECT_NAME} "configuration"
|
||||
PREFIX "/"
|
||||
|
||||
@@ -18,10 +18,20 @@ qt6_add_qml_module(KomplexHubContent
|
||||
"pages/UserProfilePage.qml"
|
||||
"pages/WallpaperSettingsPage.qml"
|
||||
"pages/VideoSearchPage.qml"
|
||||
QML_FILES pages/FeaturedVideosPage.qml
|
||||
QML_FILES pages/FeaturedPacksPage.qml
|
||||
QML_FILES pages/FeaturedImagesPage.qml
|
||||
QML_FILES pages/NewestPacksPage.qml
|
||||
"pages/FeaturedVideosPage.qml"
|
||||
"pages/FeaturedPacksPage.qml"
|
||||
"pages/FeaturedImagesPage.qml"
|
||||
"pages/NewestPacksPage.qml"
|
||||
"views/CompletedView.qml"
|
||||
"views/DownloadView.qml"
|
||||
"views/ErrorView.qml"
|
||||
"views/ImageView.qml"
|
||||
"views/PackView.qml"
|
||||
"views/VideoView.qml"
|
||||
RESOURCES views/CMakeLists.txt
|
||||
RESOURCES pages/CMakeLists.txt
|
||||
)
|
||||
|
||||
add_subdirectory(pages)
|
||||
add_subdirectory(views)
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ Rectangle {
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Home"
|
||||
text: qsTr("Home")
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
@@ -109,7 +109,7 @@ Rectangle {
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Images"
|
||||
text: qsTr("Images")
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
@@ -132,7 +132,7 @@ Rectangle {
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Videos"
|
||||
text: qsTr("Videos")
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
@@ -155,7 +155,7 @@ Rectangle {
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Live"
|
||||
text: qsTr("Komplex")
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
@@ -178,7 +178,7 @@ Rectangle {
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Installed"
|
||||
text: qsTr("Installed")
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
@@ -207,7 +207,7 @@ Rectangle {
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Settings"
|
||||
text: qsTr("Settings")
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
@@ -369,7 +369,7 @@ Rectangle {
|
||||
|
||||
function isSearchPage()
|
||||
{
|
||||
return (
|
||||
return(
|
||||
pageLoader.item instanceof ImageSearchPage ||
|
||||
pageLoader.item instanceof LiveSearchPage ||
|
||||
pageLoader.item instanceof VideoSearchPage
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
qt_add_library(KomplexHubPages STATIC)
|
||||
qt6_add_qml_module(KomplexHubPages
|
||||
URI "KomplexHub.Pages"
|
||||
VERSION 1.0
|
||||
RESOURCE_PREFIX "/qt/qml"
|
||||
QML_FILES
|
||||
"HomePage.qml"
|
||||
"ImageSearchPage.qml"
|
||||
"InstalledWallpaperPage.qml"
|
||||
"LiveSearchPage.qml"
|
||||
"LoginPage.qml"
|
||||
"SettingsPage.qml"
|
||||
"UserProfilePage.qml"
|
||||
"WallpaperSettingsPage.qml"
|
||||
"VideoSearchPage.qml"
|
||||
"FeaturedVideosPage.qml"
|
||||
"FeaturedPacksPage.qml"
|
||||
"FeaturedImagesPage.qml"
|
||||
"NewestPacksPage.qml"
|
||||
)
|
||||
@@ -6,6 +6,8 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Rectangle
|
||||
{
|
||||
|
||||
@@ -6,6 +6,8 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Rectangle
|
||||
{
|
||||
@@ -134,6 +136,7 @@ Rectangle
|
||||
viewMoreWallpaperPopup.authorId = packsModel.data(packsModel.index(index,0), NewestPacksModel.AuthorIdRole)
|
||||
viewMoreWallpaperPopup.description = packsModel.data(packsModel.index(index,0), NewestPacksModel.DescriptionRole)
|
||||
viewMoreWallpaperPopup.thumbnail = packsModel.data(packsModel.index(index,0), NewestPacksModel.ThumbnailRole)
|
||||
viewMoreWallpaperPopup.uuid = packsModel.data(packsModel.index(index,0), NewestPacksModel.UuidRole)
|
||||
viewMoreWallpaperPopup.opacity = 1
|
||||
popupContainer.opacity = 1
|
||||
resultsLayout.opacity = 0
|
||||
|
||||
@@ -6,6 +6,8 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Rectangle
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHubContent
|
||||
|
||||
Item
|
||||
{
|
||||
@@ -111,7 +112,7 @@ Item
|
||||
color: palette.text
|
||||
font.pixelSize: Constants.h2Font.pixelSize
|
||||
font.bold: true
|
||||
text: qsTr("Featured Live Wallpapers")
|
||||
text: qsTr("Featured Komplex Wallpapers")
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
@@ -198,7 +199,7 @@ Item
|
||||
SearchResultItem
|
||||
{
|
||||
anchors.fill: parent
|
||||
title: parent.author
|
||||
author: parent.author
|
||||
description: parent.description
|
||||
thumbnail: parent.thumbnail
|
||||
uuid: parent.uuid
|
||||
@@ -220,13 +221,13 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
VerticalSpacer{ height: Constants.largeMargin; width: Constants.largeMargin }
|
||||
VerticalSpacer { height: Constants.largeMargin; width: Constants.largeMargin }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalSpacer{ height: Constants.largeMargin; width: Constants.largeMargin }
|
||||
VerticalSpacer { height: Constants.largeMargin; width: Constants.largeMargin }
|
||||
|
||||
Rectangle
|
||||
{
|
||||
@@ -257,8 +258,8 @@ Item
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Constants.largeMargin
|
||||
height: childrenRect.height
|
||||
|
||||
height: childrenRect.height
|
||||
color: palette.window
|
||||
|
||||
Column
|
||||
@@ -363,7 +364,7 @@ Item
|
||||
SearchResultItem
|
||||
{
|
||||
anchors.fill: parent
|
||||
title: parent.author
|
||||
author: parent.author
|
||||
thumbnail: parent.thumbnail
|
||||
uuid: parent.uuid
|
||||
pexels: true
|
||||
@@ -388,7 +389,6 @@ Item
|
||||
|
||||
VerticalSpacer{ height: Constants.largeMargin; width: Constants.largeMargin }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component.onCompleted: () =>
|
||||
@@ -422,7 +422,8 @@ Item
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
|
||||
Behavior on opacity {
|
||||
Behavior on opacity
|
||||
{
|
||||
NumberAnimation
|
||||
{
|
||||
duration: 250
|
||||
@@ -437,7 +438,8 @@ Item
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
|
||||
Behavior on opacity {
|
||||
Behavior on opacity
|
||||
{
|
||||
NumberAnimation
|
||||
{
|
||||
duration: 250
|
||||
@@ -452,7 +454,8 @@ Item
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
|
||||
Behavior on opacity {
|
||||
Behavior on opacity
|
||||
{
|
||||
NumberAnimation
|
||||
{
|
||||
duration: 250
|
||||
@@ -460,7 +463,8 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
Behavior on opacity
|
||||
{
|
||||
NumberAnimation
|
||||
{
|
||||
duration: 250
|
||||
@@ -478,7 +482,8 @@ Item
|
||||
anchors.fill: parent
|
||||
opacity: 0
|
||||
|
||||
Behavior on opacity {
|
||||
Behavior on opacity
|
||||
{
|
||||
NumberAnimation
|
||||
{
|
||||
duration: 250
|
||||
@@ -548,8 +553,10 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "loading"
|
||||
when: homePageRoot.loading
|
||||
|
||||
@@ -571,7 +578,8 @@ Item
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State {
|
||||
State
|
||||
{
|
||||
name: "idle"
|
||||
when: !popup && !loading
|
||||
|
||||
@@ -606,7 +614,8 @@ Item
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
transitions:
|
||||
[
|
||||
Transition
|
||||
{
|
||||
from: "loading"
|
||||
@@ -692,6 +701,8 @@ Item
|
||||
viewMoreWallpaperPopup.authorId = packsModel.data(packsModel.index(index,0), NewestPacksModel.AuthorIdRole)
|
||||
viewMoreWallpaperPopup.description = packsModel.data(packsModel.index(index,0), NewestPacksModel.DescriptionRole)
|
||||
viewMoreWallpaperPopup.thumbnail = packsModel.data(packsModel.index(index,0), NewestPacksModel.ThumbnailRole)
|
||||
viewMoreWallpaperPopup.name = packsModel.data(packsModel.index(index,0), NewestPacksModel.NameRole)
|
||||
viewMoreWallpaperPopup.uuid = packsModel.data(packsModel.index(index,0), NewestPacksModel.UuidRole)
|
||||
viewMoreWallpaperPopup.opacity = 1
|
||||
popupContainer.opacity = 1
|
||||
pageArea.opacity = 0
|
||||
|
||||
@@ -6,6 +6,8 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Item
|
||||
{
|
||||
|
||||
@@ -2,10 +2,13 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Item
|
||||
{
|
||||
@@ -109,6 +112,7 @@ Item
|
||||
viewMoreWallpaperPopup.authorId = searchModel.data(searchModel.index(index,0), PackSearchModel.AuthorIdRole)
|
||||
viewMoreWallpaperPopup.description = searchModel.data(searchModel.index(index,0), PackSearchModel.DescriptionRole)
|
||||
viewMoreWallpaperPopup.thumbnail = searchModel.data(searchModel.index(index,0), PackSearchModel.ThumbnailRole)
|
||||
viewMoreWallpaperPopup.uuid = searchModel.data(searchModel.index(index,0), PackSearchModel.UuidRole)
|
||||
viewMoreWallpaperPopup.opacity = 1
|
||||
popupContainer.opacity = 1
|
||||
paginator.opacity = 0
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Item {
|
||||
id: loginFormRoot
|
||||
|
||||
@@ -6,6 +6,8 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Rectangle
|
||||
{
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Item {
|
||||
readonly property bool searchable: false
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -6,6 +6,8 @@ import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
Item
|
||||
{
|
||||
|
||||
@@ -31,9 +31,12 @@ import QtQuick.Layouts
|
||||
//import org.kde.plasma.core as PlasmaCore
|
||||
import QtCore
|
||||
import Qt.labs.folderlistmodel 2.15
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Plugin
|
||||
import KomplexHub.Views
|
||||
import KomplexHub.Pages
|
||||
|
||||
//import com.github.digitalartifex.komplex 1.0 as Komplex
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
qt_add_library(KomplexHubViews STATIC)
|
||||
qt6_add_qml_module(KomplexHubViews
|
||||
URI "KomplexHub.Views"
|
||||
VERSION 1.0
|
||||
RESOURCE_PREFIX "/qt/qml"
|
||||
QML_FILES
|
||||
"CompletedView.qml"
|
||||
"DownloadView.qml"
|
||||
"ErrorView.qml"
|
||||
"ImageView.qml"
|
||||
"PackView.qml"
|
||||
"VideoView.qml"
|
||||
)
|
||||
@@ -51,12 +51,6 @@ Item
|
||||
}
|
||||
}
|
||||
}
|
||||
SquareButton
|
||||
{
|
||||
Layout.preferredWidth: 186
|
||||
Layout.fillHeight: true
|
||||
text: qsTr("Set Wallpaper")
|
||||
}
|
||||
}
|
||||
|
||||
VerticalSpacer {}
|
||||
@@ -55,7 +55,7 @@ Item
|
||||
ImageFrame
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
Layout.topMargin: Constants.largeMargin
|
||||
Layout.preferredHeight: width / 1.77777777778
|
||||
Layout.maximumWidth: 800
|
||||
@@ -73,7 +73,7 @@ Item
|
||||
elide: Text.ElideRight
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignLeft
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||
}
|
||||
|
||||
Text
|
||||
@@ -0,0 +1,309 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
|
||||
Item
|
||||
{
|
||||
property string uuid
|
||||
property string author
|
||||
property string authorId
|
||||
property string description
|
||||
property string thumbnail
|
||||
property string name
|
||||
|
||||
property int imageHeight
|
||||
property int imageWidth
|
||||
|
||||
id: rootItem
|
||||
|
||||
DownloadManager
|
||||
{
|
||||
id: downloadManager
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: pageView
|
||||
anchors.fill: parent
|
||||
color: palette.base
|
||||
|
||||
BackgroundImage
|
||||
{
|
||||
anchors.fill: parent
|
||||
source: rootItem.thumbnail
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.margins: Constants.largeMargin
|
||||
spacing: Constants.largeMargin
|
||||
|
||||
ImageFrame
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignHCenter
|
||||
Layout.topMargin: Constants.largeMargin
|
||||
Layout.preferredHeight: width / 1.77777777778
|
||||
Layout.maximumWidth: 800
|
||||
|
||||
source: rootItem.thumbnail
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: titleText
|
||||
text: rootItem.name
|
||||
color: palette.text
|
||||
font.bold: true
|
||||
font.pixelSize: Constants.h3Font.pixelSize
|
||||
elide: Text.ElideRight
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignLeft
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: descriptionText
|
||||
text: rootItem.description
|
||||
color: palette.text
|
||||
font.pointSize: Constants.h4Font.pixelSize
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: authorText
|
||||
text: qsTr("By: ") + rootItem.author
|
||||
color: palette.text
|
||||
font.pointSize: Constants.h5Font.pixelSize
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
horizontalAlignment: Qt.AlignRight
|
||||
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
/** Spacer **/
|
||||
Item
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 32
|
||||
}
|
||||
|
||||
RowLayout
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
SquareButton
|
||||
{
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredWidth: 128
|
||||
text: qsTr("Download")
|
||||
icon.source: "qrc:/images/icons/icons8-download.svg"
|
||||
|
||||
onTriggered: () => rootItem.download()
|
||||
}
|
||||
}
|
||||
|
||||
/** Spacer **/
|
||||
Item { Layout.fillWidth: true; Layout.fillHeight: true }
|
||||
|
||||
RowLayout
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
|
||||
Text {
|
||||
text: qsTr("Shaders Provided Courtesy of ShaderToy, Komplex and Their Respective Authors")
|
||||
elide: Text.ElideLeft
|
||||
color: palette.text
|
||||
font.bold: true
|
||||
font.pixelSize: Constants.h6Font.pixelSize
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
}
|
||||
|
||||
Image
|
||||
{
|
||||
transform: Image.PreserveAspectFit
|
||||
source: "qrc:/images/icons/pexels-icon-filled-256.svg"
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.preferredHeight: 32
|
||||
Layout.preferredWidth: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "downloading"
|
||||
when: downloadManager.state === DownloadManager.Downloading
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "complete"
|
||||
when: downloadManager.state === DownloadManager.Complete
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "error"
|
||||
when: downloadManager.state === DownloadManager.Error
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "idle"
|
||||
when: downloadManager.state === DownloadManager.Idle
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
DownloadView
|
||||
{
|
||||
id: downloadView
|
||||
anchors.fill: parent
|
||||
|
||||
manager: downloadManager
|
||||
thumbnail: rootItem.thumbnail
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
}
|
||||
|
||||
CompletedView
|
||||
{
|
||||
id: completedView
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
manager: downloadManager
|
||||
}
|
||||
|
||||
ErrorView
|
||||
{
|
||||
id: errorView
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
manager: downloadManager
|
||||
}
|
||||
|
||||
function download()
|
||||
{
|
||||
downloadManager.downloadPack(uuid)
|
||||
}
|
||||
|
||||
Component.onCompleted: () => downloadManager.reset()
|
||||
}
|
||||
@@ -21,17 +21,10 @@ Item
|
||||
property int imageWidth
|
||||
|
||||
visible: opacity > 0.01
|
||||
onVisibleChanged: () =>
|
||||
{
|
||||
if(!visible)
|
||||
{
|
||||
model = null
|
||||
}
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: model
|
||||
target: model ? model : null
|
||||
|
||||
function onRowCountChanged()
|
||||
{
|
||||
@@ -39,10 +32,16 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
DownloadManager
|
||||
{
|
||||
id: downloadManager
|
||||
}
|
||||
|
||||
id: rootItem
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: pageView
|
||||
anchors.fill: parent
|
||||
color: palette.base
|
||||
|
||||
@@ -119,6 +118,8 @@ Item
|
||||
Layout.preferredWidth: 128
|
||||
text: qsTr("Download")
|
||||
icon.source: "qrc:/images/icons/icons8-download.svg"
|
||||
|
||||
onTriggered: () => rootItem.download()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,5 +153,161 @@ Item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "downloading"
|
||||
when: downloadManager.state === DownloadManager.Downloading
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "complete"
|
||||
when: downloadManager.state === DownloadManager.Complete
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "error"
|
||||
when: downloadManager.state === DownloadManager.Error
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "idle"
|
||||
when: downloadManager.state === DownloadManager.Idle
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: pageView
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: downloadView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: completedView
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorView
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
DownloadView
|
||||
{
|
||||
id: downloadView
|
||||
anchors.fill: parent
|
||||
|
||||
manager: downloadManager
|
||||
thumbnail: rootItem.thumbnail
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
}
|
||||
|
||||
CompletedView
|
||||
{
|
||||
id: completedView
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
manager: downloadManager
|
||||
}
|
||||
|
||||
ErrorView
|
||||
{
|
||||
id: errorView
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: 0
|
||||
visible: opacity > 0.01
|
||||
manager: downloadManager
|
||||
}
|
||||
|
||||
function download()
|
||||
{
|
||||
downloadManager.downloadImage(author, authorUrl, downloadSelector.currentValue)
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,6 @@ qt6_add_qml_module(KomplexHubModule
|
||||
"WallpaperModelData.qml"
|
||||
)
|
||||
|
||||
set_target_properties(KomplexHubModule PROPERTIES VERSION "1.0")
|
||||
add_subdirectory("Controls")
|
||||
add_subdirectory("Kero")
|
||||
|
||||
@@ -63,7 +63,7 @@ QtObject {
|
||||
readonly property int normalAnimationDuration: 250
|
||||
readonly property int fastAnimationDuration: 125
|
||||
|
||||
property StudioApplication application: StudioApplication {
|
||||
fontPath: Qt.resolvedUrl("../KomplexHubContent/" + relativeFontDirectory)
|
||||
}
|
||||
// property StudioApplication application: StudioApplication {
|
||||
// fontPath: Qt.resolvedUrl("../KomplexHubContent/" + relativeFontDirectory)
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
### This file is automatically generated by Qt Design Studio.
|
||||
### Do not change
|
||||
|
||||
qt_add_library(KomplexHubModule_Controls STATIC)
|
||||
qt6_add_qml_module(KomplexHubModule_Controls
|
||||
qt_add_library(KomplexHubControls STATIC)
|
||||
qt6_add_qml_module(KomplexHubControls
|
||||
URI "KomplexHub.Controls"
|
||||
VERSION 1.0
|
||||
RESOURCE_PREFIX "/qt/qml"
|
||||
@@ -14,18 +14,12 @@ qt6_add_qml_module(KomplexHubModule_Controls
|
||||
"Throbber.qml"
|
||||
"SearchResultItem.qml"
|
||||
"SearchResultList.qml"
|
||||
QML_FILES PaginationBox.qml
|
||||
QML_FILES PaginatorGrid.qml
|
||||
QML_FILES HorizontalPaginator.qml
|
||||
QML_FILES ImageView.qml
|
||||
QML_FILES
|
||||
QML_FILES VideoView.qml
|
||||
QML_FILES PackView.qml
|
||||
QML_FILES VerticalSpacer.qml
|
||||
QML_FILES DownloadView.qml
|
||||
QML_FILES ImageFrame.qml
|
||||
QML_FILES BackgroundImage.qml
|
||||
QML_FILES CompletedView.qml
|
||||
QML_FILES ErrorView.qml
|
||||
"PaginationBox.qml"
|
||||
"PaginatorGrid.qml"
|
||||
"HorizontalPaginator.qml"
|
||||
"VerticalSpacer.qml"
|
||||
"ImageFrame.qml"
|
||||
"BackgroundImage.qml"
|
||||
)
|
||||
|
||||
#set_target_properties(KomplexHubControls PROPERTIES VERSION "1.0")
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHub.Plugin
|
||||
|
||||
Item
|
||||
{
|
||||
property string uuid
|
||||
property string author
|
||||
property string authorId
|
||||
property string description
|
||||
property string thumbnail
|
||||
|
||||
property int imageHeight
|
||||
property int imageWidth
|
||||
|
||||
id: rootItem
|
||||
|
||||
Rectangle
|
||||
{
|
||||
anchors.fill: parent
|
||||
color: palette.base
|
||||
|
||||
BackgroundImage
|
||||
{
|
||||
anchors.fill: parent
|
||||
source: rootItem.thumbnail
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.margins: Constants.largeMargin
|
||||
spacing: Constants.largeMargin
|
||||
|
||||
ImageFrame
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignHCenter
|
||||
Layout.topMargin: Constants.largeMargin
|
||||
Layout.preferredHeight: width / 1.77777777778
|
||||
Layout.maximumWidth: 800
|
||||
|
||||
source: rootItem.thumbnail
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: titleText
|
||||
text: rootItem.author
|
||||
color: palette.text
|
||||
font.bold: true
|
||||
font.pixelSize: Constants.h3Font.pixelSize
|
||||
elide: Text.ElideRight
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignLeft
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: descriptionText
|
||||
text: rootItem.description
|
||||
color: palette.text
|
||||
font.pointSize: Constants.h4Font.pixelSize
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
|
||||
Layout.alignment: Qt.AlignTop| Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
/** Spacer **/
|
||||
Item
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 32
|
||||
}
|
||||
|
||||
RowLayout
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
SquareButton
|
||||
{
|
||||
Layout.preferredHeight: 36
|
||||
Layout.preferredWidth: 128
|
||||
text: qsTr("Download")
|
||||
icon.source: "qrc:/images/icons/icons8-download.svg"
|
||||
}
|
||||
}
|
||||
|
||||
/** Spacer **/
|
||||
Item { Layout.fillWidth: true; Layout.fillHeight: true }
|
||||
|
||||
RowLayout
|
||||
{
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
|
||||
Text {
|
||||
text: qsTr("Shaders Provided Courtesy of ShaderToy and Their Respective Authors")
|
||||
elide: Text.ElideLeft
|
||||
color: palette.text
|
||||
font.bold: true
|
||||
font.pixelSize: Constants.h6Font.pixelSize
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
}
|
||||
|
||||
Image
|
||||
{
|
||||
transform: Image.PreserveAspectFit
|
||||
source: "qrc:/images/icons/pexels-icon-filled-256.svg"
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.preferredHeight: 32
|
||||
Layout.preferredWidth: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ Item {
|
||||
|
||||
width: 24
|
||||
height: 24
|
||||
transform: Image.PreserveAspectFit
|
||||
fillMode: Image.PreserveAspectFit
|
||||
opacity: 0.5
|
||||
source: "qrc:/images/icons/pexels-icon-filled-256.svg"
|
||||
|
||||
@@ -82,49 +82,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Rectangle
|
||||
// {
|
||||
// Layout.preferredWidth: 250
|
||||
// Layout.preferredHeight: 141
|
||||
// Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
// Layout.topMargin: 3
|
||||
|
||||
// border.color: palette.alternateBase.lighter(1.75)
|
||||
|
||||
// color: palette.base.lighter(1.25)
|
||||
|
||||
// // Throbber
|
||||
// // {
|
||||
// // anchors.fill: parent
|
||||
// // id: loadingThrobber
|
||||
// // visible: viewImage.status === Image.Loading
|
||||
// // }
|
||||
|
||||
// // Image
|
||||
// // {
|
||||
// // property int retries: 0
|
||||
// // id: viewImage
|
||||
// // anchors.fill: parent
|
||||
// // source: rootItem.thumbnail
|
||||
// // visible: !(status === Image.Loading)
|
||||
// // fillMode: Image.PreserveAspectCrop
|
||||
|
||||
// // onStatusChanged: () =>
|
||||
// // {
|
||||
// // // if(status === Image.Error)
|
||||
// // // {
|
||||
// // // if(retries <= 3)
|
||||
// // // {
|
||||
// // // ++retries
|
||||
// // // let src = source
|
||||
// // // source = ""
|
||||
// // // source = src
|
||||
// // // }
|
||||
// // // }
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
|
||||
Text
|
||||
{
|
||||
color: palette.text
|
||||
@@ -140,18 +97,6 @@ Item {
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
|
||||
Text
|
||||
{
|
||||
color: palette.text
|
||||
font.pixelSize: 12
|
||||
text: "By: " + rootItem.author
|
||||
leftPadding: 12
|
||||
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
|
||||
Layout.preferredWidth: 250
|
||||
visible: !rootItem.pexels
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
id: descriptionText
|
||||
@@ -171,6 +116,19 @@ Item {
|
||||
Layout.bottomMargin: 3
|
||||
}
|
||||
|
||||
Text
|
||||
{
|
||||
color: palette.text
|
||||
font.pixelSize: 12
|
||||
text: "By: " + rootItem.author
|
||||
leftPadding: Constants.mediumMargin
|
||||
rightPadding: Constants.mediumMargin
|
||||
horizontalAlignment: Qt.AlignRight
|
||||
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SquareButton
|
||||
{
|
||||
id: viewMoreButton
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
qt_add_library(KomplexHubModule_Kero STATIC)
|
||||
qt6_add_qml_module(KomplexHubModule_Kero
|
||||
qt_add_library(KomplexHubKero STATIC)
|
||||
qt6_add_qml_module(KomplexHubKero
|
||||
URI "KomplexHub.Kero"
|
||||
VERSION 1.0
|
||||
RESOURCE_PREFIX "/qt/qml"
|
||||
@@ -14,3 +14,4 @@ qt6_add_qml_module(KomplexHubModule_Kero
|
||||
"KeroHeader.qml"
|
||||
"KeroSuccessAvatar.qml"
|
||||
)
|
||||
#set_target_properties(KomplexHubKero PROPERTIES VERSION "1.0")
|
||||
@@ -6,7 +6,7 @@ import KomplexHub
|
||||
Item {
|
||||
property string title: qsTr("Warning")
|
||||
property string description: qsTr("Kero noticed there might be an issue")
|
||||
property color color: palette.window
|
||||
property color color: "transparent"
|
||||
|
||||
id: keroWarningAvatarRoot
|
||||
|
||||
|
||||
@@ -1,8 +1,34 @@
|
||||
find_package(
|
||||
Qt6
|
||||
REQUIRED COMPONENTS
|
||||
Core
|
||||
Gui
|
||||
GuiPrivate
|
||||
Widgets
|
||||
Qml
|
||||
Quick
|
||||
QuickControls2
|
||||
QuickTimeline
|
||||
ShaderTools
|
||||
ShaderToolsPrivate
|
||||
Concurrent
|
||||
)
|
||||
|
||||
find_package(
|
||||
OpenGL REQUIRED COMPONENTS OpenGL
|
||||
)
|
||||
|
||||
find_package(
|
||||
Vulkan REQUIRED COMPONENTS glslang SPIRV-Tools
|
||||
)
|
||||
|
||||
add_library(
|
||||
KomplexHubPlugin
|
||||
STATIC
|
||||
)
|
||||
|
||||
set_target_properties(KomplexHubPlugin PROPERTIES VERSION "1.0")
|
||||
|
||||
qt_add_qml_module(
|
||||
KomplexHubPlugin
|
||||
URI
|
||||
@@ -62,6 +88,7 @@ qt_add_qml_module(
|
||||
common/qwallet.cpp
|
||||
usermodel.h
|
||||
usermodel.cpp
|
||||
SOURCES
|
||||
)
|
||||
|
||||
target_compile_definitions(
|
||||
@@ -73,8 +100,13 @@ target_compile_definitions(
|
||||
add_subdirectory(3rdparty/qtkeychain)
|
||||
|
||||
target_link_libraries(KomplexHubPlugin PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt6::Core
|
||||
Qt6::Concurrent
|
||||
Qt6::Gui
|
||||
Qt6::GuiPrivate
|
||||
Qt6::ShaderTools
|
||||
Qt6::ShaderToolsPrivate
|
||||
Vulkan::Vulkan
|
||||
qt6keychain
|
||||
)
|
||||
|
||||
|
||||
@@ -19,36 +19,197 @@
|
||||
#ifndef EXCEPTIONS_H
|
||||
#define EXCEPTIONS_H
|
||||
#include <QString>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include "komplex_global.h"
|
||||
|
||||
struct KOMPLEX_EXPORT Exception : std::exception
|
||||
struct KOMPLEX_EXPORT network_exception : std::ios_base::failure
|
||||
{
|
||||
explicit Exception(const QString &message, quint16 errorCode = 0)
|
||||
: std::exception(), message(message), errorCode(errorCode){}
|
||||
network_exception(const std::string &message, const std::string &details, const std::error_code &code) :
|
||||
details(details),
|
||||
std::ios_base::failure(message, code) { }
|
||||
|
||||
const QString message;
|
||||
const quint16 errorCode;
|
||||
network_exception(const std::string &message, const std::error_code &code) :
|
||||
std::ios_base::failure(message, code) { }
|
||||
|
||||
network_exception(const QString &message, const QString &details, const std::error_code &code) :
|
||||
details(details.toStdString()),
|
||||
std::ios_base::failure(message.toStdString(), code) { }
|
||||
|
||||
network_exception(const QString &message, const int code = errno) :
|
||||
std::ios_base::failure
|
||||
(
|
||||
message.toStdString(),
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
) { }
|
||||
|
||||
const std::string details;
|
||||
};
|
||||
|
||||
struct KOMPLEX_EXPORT NetworkException : Exception
|
||||
struct KOMPLEX_EXPORT file_exception : std::filesystem::filesystem_error
|
||||
{
|
||||
NetworkException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
file_exception(const std::string &message, const std::string &details, const std::error_code &code) :
|
||||
details(details),
|
||||
std::filesystem::filesystem_error(message, code) { }
|
||||
|
||||
file_exception(const std::string &message, const std::error_code &code) :
|
||||
std::filesystem::filesystem_error(message, code) { }
|
||||
|
||||
file_exception(const std::string &message, const int code = errno) :
|
||||
std::filesystem::filesystem_error
|
||||
(
|
||||
message,
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
) { }
|
||||
|
||||
file_exception(const std::string &message, const std::string &details, const int code = errno) :
|
||||
details(details),
|
||||
std::filesystem::filesystem_error
|
||||
(
|
||||
message,
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
) { }
|
||||
|
||||
const std::string details;
|
||||
};
|
||||
struct KOMPLEX_EXPORT FileException : Exception
|
||||
|
||||
struct KOMPLEX_EXPORT sql_exception : std::ios_base::failure
|
||||
{
|
||||
FileException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
sql_exception(const std::string &message, const std::string &details, const std::error_code &code) :
|
||||
details(details),
|
||||
std::ios_base::failure(message, code) { }
|
||||
|
||||
sql_exception(const std::string &message, const std::error_code &code) :
|
||||
std::ios_base::failure(message, code) { }
|
||||
|
||||
sql_exception(const std::string &message, const int code = errno) :
|
||||
std::ios_base::failure
|
||||
(
|
||||
message,
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
) { }
|
||||
|
||||
const std::string details;
|
||||
};
|
||||
struct KOMPLEX_EXPORT SqlException : Exception
|
||||
|
||||
struct KOMPLEX_EXPORT wallet_exception : std::ios_base::failure
|
||||
{
|
||||
SqlException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
wallet_exception(const std::string &message, const std::string &details, const std::error_code &code) :
|
||||
details(details),
|
||||
std::ios_base::failure(message, code) { }
|
||||
|
||||
wallet_exception(const std::string &message, const std::error_code &code) :
|
||||
std::ios_base::failure(message, code) { }
|
||||
|
||||
wallet_exception(const std::string &message, const std::string &details, const int code = errno) :
|
||||
details(details),
|
||||
std::ios_base::failure
|
||||
(
|
||||
message,
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
) { }
|
||||
|
||||
wallet_exception(const std::string &message, const int code = errno) :
|
||||
std::ios_base::failure
|
||||
(
|
||||
message,
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
) { }
|
||||
|
||||
const std::string details;
|
||||
};
|
||||
struct KOMPLEX_EXPORT WalletException : Exception
|
||||
|
||||
struct KOMPLEX_EXPORT process_exception : std::runtime_error
|
||||
{
|
||||
WalletException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
process_exception(const std::string &message, const std::string &details, const std::error_code &code) :
|
||||
details(details),
|
||||
code(code),
|
||||
std::runtime_error(message) { }
|
||||
|
||||
process_exception(const std::string &message, const std::error_code &code) :
|
||||
code(code),
|
||||
std::runtime_error(message) { }
|
||||
|
||||
process_exception(const std::string &message, const int code = errno) :
|
||||
code
|
||||
(
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
),
|
||||
std::runtime_error
|
||||
(
|
||||
message
|
||||
) { }
|
||||
|
||||
process_exception(const std::string &message, const std::string &details, const int code = errno) :
|
||||
details(details),
|
||||
code
|
||||
(
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
),
|
||||
std::runtime_error (message) { }
|
||||
|
||||
const std::string details;
|
||||
const std::error_code code;
|
||||
};
|
||||
struct KOMPLEX_EXPORT ShaderCompilerException : Exception
|
||||
|
||||
namespace shader
|
||||
{
|
||||
ShaderCompilerException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
};
|
||||
struct KOMPLEX_EXPORT logic_error : std::logic_error
|
||||
{
|
||||
logic_error(const std::string &message, const std::string &details, const std::error_code &code) :
|
||||
details(details),
|
||||
code(code),
|
||||
std::logic_error(message) { }
|
||||
|
||||
logic_error(const std::string &message, const std::error_code &code) :
|
||||
code(code),
|
||||
std::logic_error(message) { }
|
||||
|
||||
logic_error(const std::string &message, const std::string &details = {}, const int code = errno) :
|
||||
code
|
||||
(
|
||||
std::error_code
|
||||
(
|
||||
code,
|
||||
std::system_category()
|
||||
)
|
||||
),
|
||||
std::logic_error(message) { }
|
||||
|
||||
const std::string details;
|
||||
const std::error_code code;
|
||||
};
|
||||
}
|
||||
#endif // EXCEPTIONS_H
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "qwallet.h"
|
||||
#include "../3rdparty/qtkeychain/qtkeychain/keychain.h"
|
||||
#include "common/exceptions.h"
|
||||
|
||||
auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray>
|
||||
{
|
||||
@@ -29,7 +30,11 @@ auto QWallet::read(const QString &service, const QString &key) const -> QFuture<
|
||||
else
|
||||
{
|
||||
m_errorString = qPrintable(j->errorString());
|
||||
throw std::exception();
|
||||
throw wallet_exception
|
||||
(
|
||||
QStringLiteral("Wallet read error").toStdString(),
|
||||
errorString().toStdString()
|
||||
);
|
||||
}
|
||||
|
||||
loop.quit();
|
||||
@@ -65,11 +70,15 @@ auto QWallet::write(const QString &service, const QString &key, const QByteArray
|
||||
this,
|
||||
[this, key, &loop, &success](QKeychain::Job *job)
|
||||
{
|
||||
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||
auto j = static_cast<QKeychain::WritePasswordJob*>(job);
|
||||
if (j->error() != QKeychain::NoError)
|
||||
{
|
||||
setErrorString(qPrintable(j->errorString()));
|
||||
throw std::exception();
|
||||
throw wallet_exception
|
||||
(
|
||||
QStringLiteral("Wallet write error").toStdString(),
|
||||
errorString().toStdString()
|
||||
);
|
||||
}
|
||||
|
||||
loop.quit();
|
||||
@@ -102,7 +111,7 @@ auto QWallet::remove(const QString &service, const QString &key) -> QFuture<void
|
||||
this,
|
||||
[this, key, &loop, &value](QKeychain::Job *job)
|
||||
{
|
||||
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||
auto j = static_cast<QKeychain::DeletePasswordJob*>(job);
|
||||
if (j->error() != QKeychain::NoError)
|
||||
{
|
||||
m_errorString = qPrintable(j->errorString());
|
||||
|
||||
@@ -79,10 +79,6 @@ DownloadManager::DownloadManager(QObject *parent)
|
||||
*/
|
||||
auto DownloadManager::downloadImage(const QString &author, const QString &authorId, const QString &description, const QUrl &url) -> void
|
||||
{
|
||||
// QFuture future = QtConcurrent::run
|
||||
// (
|
||||
// [this, url, author, authorId, description]()
|
||||
// {
|
||||
QNetworkRequest request(url);
|
||||
QString requestUrl = request.url().toString();
|
||||
QString id = QUuid::createUuidV7().toString(QUuid::WithoutBraces);
|
||||
@@ -109,6 +105,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
|
||||
metadata.setDescription(description);
|
||||
metadata.setName(QStringLiteral("Pexels Image (%1)").arg(id));
|
||||
metadata.setSource(QStringLiteral("./images/%1").arg(result.fileName()));
|
||||
metadata.setId(id);
|
||||
|
||||
QUrl packUri
|
||||
(
|
||||
@@ -133,7 +130,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
|
||||
|
||||
if(!packDirectory.mkpath(packUri.toLocalFile()))
|
||||
{
|
||||
throw FileException(QStringLiteral("Could not create directory"));
|
||||
throw file_exception(QStringLiteral("Could not create directory").toStdString());
|
||||
}
|
||||
|
||||
packDirectory.mkdir(QStringLiteral("images"));
|
||||
@@ -151,7 +148,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
|
||||
if(!packFile.open(QFile::ReadWrite))
|
||||
{
|
||||
setError(QStringLiteral("File Error"), packFile.errorString());
|
||||
throw FileException(packFile.errorString());
|
||||
throw file_exception(packFile.errorString().toStdString());
|
||||
}
|
||||
|
||||
QByteArray data = metadata.json().toJson(QJsonDocument::Indented);
|
||||
@@ -159,7 +156,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
|
||||
if(packFile.write(data) != data.length())
|
||||
{
|
||||
setError(QStringLiteral("File Error"), packFile.errorString());
|
||||
throw FileException(packFile.errorString());
|
||||
throw file_exception(packFile.errorString().toStdString());
|
||||
}
|
||||
|
||||
packFile.close();
|
||||
@@ -191,18 +188,26 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] (const NetworkException &e)
|
||||
[this] (const std::filesystem::filesystem_error &e)
|
||||
{
|
||||
reset();
|
||||
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.errorCode)), e.message);
|
||||
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.code().value())), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] (const FileException &e)
|
||||
[this] (const std::logic_error &e)
|
||||
{
|
||||
reset();
|
||||
setError(QStringLiteral("File Exception %1").arg(QString::number(e.errorCode)), e.message);
|
||||
setError(QStringLiteral("Logic Exception %1"), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] (const std::exception &e)
|
||||
{
|
||||
reset();
|
||||
setError(QStringLiteral("Logic Exception %1"), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
@@ -213,33 +218,35 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
|
||||
setError(QStringLiteral("Unknown Exception"), QString());
|
||||
}
|
||||
);
|
||||
|
||||
// downloadUri.waitForFinished();
|
||||
// }
|
||||
// );
|
||||
}
|
||||
|
||||
auto DownloadManager::downloadVideo(const QString &author, const QString &authorId, const QString &description, const QUrl &url) -> void
|
||||
auto DownloadManager::downloadVideo(const QString &author, const QString &authorId, const QUrl &url) -> void
|
||||
{
|
||||
QFuture future = QtConcurrent::run
|
||||
(
|
||||
[this, url, author, authorId, description]()
|
||||
{
|
||||
QNetworkRequest request(url);
|
||||
QString id = QUuid::createUuidV7().toString(QUuid::WithoutBraces);
|
||||
|
||||
QFuture<QUrl> downloadUri = download(request, id);
|
||||
setState(Downloading);
|
||||
|
||||
downloadUri
|
||||
if(m_downloadFuture.isRunning())
|
||||
{
|
||||
m_downloadFuture.cancelChain();
|
||||
}
|
||||
|
||||
m_downloadFuture = download(request, id, Get);
|
||||
|
||||
m_downloadFuture
|
||||
.then
|
||||
(
|
||||
[this, author, description, id](QUrl result) -> QUrl
|
||||
[this, author, id](QUrl result) -> QUrl
|
||||
{
|
||||
setState(Installing);
|
||||
|
||||
ShaderPack metadata;
|
||||
metadata.setAuthor(author);
|
||||
metadata.setDescription(description);
|
||||
metadata.setName(QStringLiteral("Pexels Video (%1)").arg(id));
|
||||
metadata.setType(ShaderPack::Video);
|
||||
metadata.setName(QStringLiteral("Pexels Video (%1)").arg(id));
|
||||
metadata.setSource(QStringLiteral("./videos/%1").arg(result.fileName()));
|
||||
metadata.setId(id);
|
||||
|
||||
QUrl packUri
|
||||
(
|
||||
@@ -250,9 +257,9 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
|
||||
)
|
||||
);
|
||||
|
||||
QUrl packImageUri
|
||||
QUrl packVideoUri
|
||||
(
|
||||
QStringLiteral("%1/%2/images/%3").arg
|
||||
QStringLiteral("%1/%2/videos/%3").arg
|
||||
(
|
||||
QStandardPaths::writableLocation(QStandardPaths::TempLocation),
|
||||
id,
|
||||
@@ -264,7 +271,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
|
||||
packDirectory.mkpath(packUri.toLocalFile());
|
||||
packDirectory.mkdir(QStringLiteral("images"));
|
||||
|
||||
QFile::rename(result.toLocalFile(), packImageUri.toLocalFile());
|
||||
QFile::rename(result.toLocalFile(), packVideoUri.toLocalFile());
|
||||
|
||||
QFile packFile
|
||||
(
|
||||
@@ -277,7 +284,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
|
||||
if(!packFile.open(QFile::ReadWrite))
|
||||
{
|
||||
setError(QStringLiteral("File Error"), packFile.errorString());
|
||||
throw FileException(packFile.errorString());
|
||||
throw file_exception(packFile.errorString().toStdString());
|
||||
}
|
||||
|
||||
QByteArray data = metadata.json().toJson(QJsonDocument::Compact);
|
||||
@@ -285,7 +292,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
|
||||
if(packFile.write(data) != data.length())
|
||||
{
|
||||
setError(QStringLiteral("File Error"), packFile.errorString());
|
||||
throw FileException(packFile.errorString());
|
||||
throw file_exception(packFile.errorString().toStdString());
|
||||
}
|
||||
|
||||
packFile.close();
|
||||
@@ -294,10 +301,18 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
|
||||
}
|
||||
)
|
||||
.then
|
||||
(
|
||||
[this](QUrl result) -> QUrl
|
||||
{
|
||||
return install(result);
|
||||
}
|
||||
)
|
||||
.then
|
||||
(
|
||||
[this](QUrl result)
|
||||
{
|
||||
install(result);
|
||||
setLastInstalledFile(result.toLocalFile());
|
||||
setState(Complete);
|
||||
}
|
||||
)
|
||||
.onCanceled
|
||||
@@ -308,22 +323,41 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] (const std::filesystem::filesystem_error &e)
|
||||
{
|
||||
reset();
|
||||
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.code().value())), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] (const std::logic_error &e)
|
||||
{
|
||||
reset();
|
||||
setError(QStringLiteral("Logic Exception %1"), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] (const std::exception &e)
|
||||
{
|
||||
reset();
|
||||
setError(QStringLiteral("Logic Exception %1"), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this] ()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
);
|
||||
setError(QStringLiteral("Unknown Exception"), QString());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
auto DownloadManager::downloadPack(const QString &id) -> void
|
||||
{
|
||||
QFuture aether = QtConcurrent::run
|
||||
(
|
||||
[this, id]()
|
||||
{
|
||||
QUrl downloadUrl = QUrl
|
||||
(
|
||||
QStringLiteral("%1/%2/%3").arg
|
||||
@@ -336,15 +370,18 @@ auto DownloadManager::downloadPack(const QString &id) -> void
|
||||
|
||||
QNetworkRequest request(downloadUrl);
|
||||
request.setRawHeader(QByteArray("uuid"), id.toUtf8());
|
||||
QString tempFile(QString("%1.tar.gz").arg(id));
|
||||
setState(Downloading);
|
||||
|
||||
QFuture<QUrl> downloadUri = download(request, id, Post);
|
||||
QFuture<QUrl> downloadUri = download(request, id, Post, tempFile);
|
||||
|
||||
downloadUri
|
||||
.then
|
||||
(
|
||||
[this](QUrl result) -> QUrl
|
||||
{
|
||||
return m_compiler->process(result).result();
|
||||
setState(Compiling);
|
||||
return m_compiler->build(result);
|
||||
}
|
||||
)
|
||||
.then
|
||||
@@ -356,26 +393,54 @@ auto DownloadManager::downloadPack(const QString &id) -> void
|
||||
)
|
||||
.then
|
||||
(
|
||||
[this] (QUrl result)
|
||||
[this](QUrl result)
|
||||
{
|
||||
setLastInstalledFile(result.toLocalFile());
|
||||
setState(Complete);
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this]()
|
||||
{
|
||||
reset();
|
||||
setError(m_compiler->errorTitle(), m_compiler->errorMessage());
|
||||
}
|
||||
)
|
||||
.onCanceled
|
||||
(
|
||||
[this]()
|
||||
[this, tempFile]()
|
||||
{
|
||||
QFile::remove(QStringLiteral("/tmp/") + tempFile);
|
||||
reset();
|
||||
}
|
||||
);
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this, tempFile] (const std::filesystem::filesystem_error &e)
|
||||
{
|
||||
QFile::remove(QStringLiteral("/tmp/") + tempFile);
|
||||
reset();
|
||||
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.code().value())), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this, tempFile] (const shader::logic_error &e)
|
||||
{
|
||||
QFile::remove(QStringLiteral("/tmp/") + tempFile);
|
||||
reset();
|
||||
setError(e.what(), QString::fromStdString(e.details));
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this, tempFile] (const std::exception &e)
|
||||
{
|
||||
QFile::remove(QStringLiteral("/tmp/") + tempFile);
|
||||
reset();
|
||||
setError(QStringLiteral("Exception %1"), e.what());
|
||||
}
|
||||
)
|
||||
.onFailed
|
||||
(
|
||||
[this, tempFile] ()
|
||||
{
|
||||
QFile::remove(QStringLiteral("/tmp/") + tempFile);
|
||||
reset();
|
||||
setError(QStringLiteral("Unknown Exception"), QString());
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -467,14 +532,11 @@ auto DownloadManager::setDownloadProgress(qreal progress) -> void
|
||||
|
||||
auto DownloadManager::install(const QUrl &uri) noexcept(false) -> QUrl
|
||||
{
|
||||
if(!uri.isLocalFile())
|
||||
{
|
||||
throw FileException(QStringLiteral("URI is not a local file"));
|
||||
}
|
||||
validateUri(uri);
|
||||
|
||||
QDir tempDirectory(uri.toLocalFile());
|
||||
|
||||
QUrl installLocation = QStringLiteral("%1/.local/share/komplex/packs/%2").arg
|
||||
QUrl installLocation = QStringLiteral("file://%1/.local/share/komplex/packs/%2").arg
|
||||
(
|
||||
QStandardPaths::writableLocation(QStandardPaths::HomeLocation),
|
||||
tempDirectory.dirName()
|
||||
@@ -496,43 +558,47 @@ auto DownloadManager::install(const QUrl &uri) noexcept(false) -> QUrl
|
||||
if(!m_moveProcess.waitForStarted(3000))
|
||||
{
|
||||
qWarning() << QStringLiteral("Could not start copy process: %1").arg(m_moveProcess.readAllStandardError());
|
||||
throw FileException(QStringLiteral("Could not start install process"));
|
||||
throw file_exception(QStringLiteral("Could not start install process").toStdString());
|
||||
}
|
||||
|
||||
if(!m_moveProcess.waitForFinished())
|
||||
{
|
||||
qWarning() << QStringLiteral("Copy process took longer than expected (>30s)");
|
||||
throw FileException(QStringLiteral("Install process took longer than expected (>30s)"));
|
||||
throw file_exception(QStringLiteral("Install process took longer than expected (>30s)").toStdString());
|
||||
}
|
||||
|
||||
return installLocation;
|
||||
}
|
||||
|
||||
auto DownloadManager::download(const QNetworkRequest &request, const QString &id, RequestType type) -> QFuture<QUrl>
|
||||
auto DownloadManager::download(const QNetworkRequest &request, const QString &id, RequestType type, const QString &filename) -> QFuture<QUrl>
|
||||
{
|
||||
return QtConcurrent::run
|
||||
(
|
||||
[this, request, id, type]() -> QUrl
|
||||
[this, request, id, type, _filename = filename]() -> QUrl
|
||||
{
|
||||
QEventLoop loop;
|
||||
QString filename = id;
|
||||
QString filename = _filename;
|
||||
|
||||
if(filename.isEmpty())
|
||||
if(filename.isEmpty() && !request.url().fileName().isEmpty())
|
||||
{
|
||||
filename = QUuid::createUuidV7().toString();
|
||||
filename = request.url().fileName();
|
||||
}
|
||||
else if(filename.isEmpty())
|
||||
{
|
||||
filename = id;
|
||||
}
|
||||
|
||||
QUrl downloadUri = QStringLiteral("file://%1/%2").arg
|
||||
(
|
||||
QStandardPaths::writableLocation(QStandardPaths::TempLocation),
|
||||
request.url().fileName()
|
||||
filename
|
||||
);
|
||||
|
||||
auto manager = CoreServices::networkAccessManager().toStrongRef();
|
||||
|
||||
if(manager == nullptr)
|
||||
{
|
||||
throw NetworkException
|
||||
throw network_exception
|
||||
{
|
||||
QStringLiteral("Network Manager reference has already been deleted")
|
||||
};
|
||||
@@ -542,7 +608,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
|
||||
|
||||
if(downloadFile.exists() && !downloadFile.remove())
|
||||
{
|
||||
throw FileException(downloadFile.errorString());
|
||||
throw file_exception(downloadFile.errorString().toStdString());
|
||||
}
|
||||
|
||||
QNetworkReply *reply = nullptr;
|
||||
@@ -567,7 +633,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
|
||||
{
|
||||
loop.quit();
|
||||
|
||||
throw NetworkException
|
||||
throw network_exception
|
||||
(
|
||||
QStringLiteral("Network Error %1").arg
|
||||
(
|
||||
@@ -595,17 +661,34 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
|
||||
reply,
|
||||
&QNetworkReply::readyRead,
|
||||
this,
|
||||
[this, downloadUri, reply]()
|
||||
[this, downloadUri]()
|
||||
{
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
QFile downloadFile(downloadUri.toLocalFile());
|
||||
|
||||
if(!downloadFile.open(QFile::ReadWrite | QFile::Append))
|
||||
{
|
||||
throw FileException(QStringLiteral("Could not open temp file location"));
|
||||
throw file_exception(QStringLiteral("Could not open temp file location").toStdString());
|
||||
}
|
||||
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
|
||||
if(reply == nullptr)
|
||||
{
|
||||
throw std::system_error
|
||||
{
|
||||
std::error_code
|
||||
(
|
||||
ENOENT,
|
||||
std::system_category()
|
||||
),
|
||||
QStringLiteral("Reply is not a qobject").toStdString()
|
||||
};
|
||||
}
|
||||
|
||||
quint64 bytes = reply->bytesAvailable();
|
||||
quint64 bytesWritten = downloadFile.write(reply->readAll()/*bytes)*/);
|
||||
QByteArray data = reply->readAll();
|
||||
quint64 bytesWritten = downloadFile.write(data/*bytes)*/);
|
||||
|
||||
downloadFile.close();
|
||||
}
|
||||
@@ -631,29 +714,61 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
|
||||
);
|
||||
}
|
||||
|
||||
auto DownloadManager::validateUri(const QUrl &uri) noexcept(false) -> void
|
||||
{
|
||||
if(!uri.isValid() || !uri.isLocalFile())
|
||||
{
|
||||
throw std::filesystem::filesystem_error
|
||||
(
|
||||
QStringLiteral("URI %1 is not a local file uri").arg
|
||||
(
|
||||
uri.toString()
|
||||
).toStdString(),
|
||||
std::error_code
|
||||
(
|
||||
ENOENT,
|
||||
std::system_category()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
auto DownloadManager::readShaderToyEntry(const QUrl &uri) noexcept(false) -> ShaderToyEntry
|
||||
{
|
||||
if(!uri.isLocalFile())
|
||||
{
|
||||
throw FileException(QStringLiteral("URI is not a local file"));
|
||||
}
|
||||
validateUri(uri);
|
||||
|
||||
QDir packDir(uri.toLocalFile());
|
||||
|
||||
if(!packDir.exists(QStringLiteral("pack.json")))
|
||||
{
|
||||
throw FileException(QStringLiteral("Pack file not found"));
|
||||
throw std::filesystem::filesystem_error
|
||||
(
|
||||
QStringLiteral("Pack file not found").arg
|
||||
(
|
||||
uri.toString()
|
||||
).toStdString(),
|
||||
std::error_code
|
||||
(
|
||||
ENOENT,
|
||||
std::system_category()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
QFile packFile(packDir.absoluteFilePath(QStringLiteral("pack.json")));
|
||||
|
||||
if(!packFile.open(QFile::ReadOnly))
|
||||
{
|
||||
throw FileException
|
||||
throw std::filesystem::filesystem_error
|
||||
(
|
||||
QStringLiteral("Could not open pack file: %1").arg
|
||||
QStringLiteral("Could not open pack file").arg
|
||||
(
|
||||
packFile.errorString()
|
||||
uri.toString()
|
||||
).toStdString(),
|
||||
std::error_code
|
||||
(
|
||||
errno,
|
||||
std::system_category()
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -665,11 +780,16 @@ auto DownloadManager::readShaderToyEntry(const QUrl &uri) noexcept(false) -> Sha
|
||||
|
||||
if(jsonError.error != QJsonParseError::NoError)
|
||||
{
|
||||
throw FileException
|
||||
throw std::filesystem::filesystem_error
|
||||
(
|
||||
QStringLiteral("Could parse pack file: %1").arg
|
||||
QStringLiteral("URI %1 is not a local file uri").arg
|
||||
(
|
||||
jsonError.errorString()
|
||||
uri.toString()
|
||||
).toStdString(),
|
||||
std::error_code
|
||||
(
|
||||
EIO,
|
||||
std::system_category()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,6 @@ public:
|
||||
(
|
||||
const QString &author,
|
||||
const QString &authorId,
|
||||
const QString &description,
|
||||
const QUrl &url
|
||||
) -> void;
|
||||
|
||||
@@ -144,8 +143,9 @@ signals:
|
||||
private:
|
||||
auto compile(const QUrl &uri) noexcept(false) -> QUrl;
|
||||
auto install(const QUrl &uri) noexcept(false) -> QUrl;
|
||||
auto download(const QNetworkRequest &request, const QString &id, RequestType type = Get) -> QFuture<QUrl>;
|
||||
auto download(const QNetworkRequest &request, const QString &id, RequestType type = Get, const QString &filename = QString()) -> QFuture<QUrl>;
|
||||
auto readShaderToyEntry(const QUrl &uri) noexcept(false) -> ShaderToyEntry;
|
||||
auto validateUri(const QUrl &uri) noexcept(false) -> void;
|
||||
|
||||
QString m_lastInstalledFile;
|
||||
|
||||
@@ -160,6 +160,7 @@ private:
|
||||
State m_state;
|
||||
|
||||
QMutex m_downloadMutex;
|
||||
QMutex m_fileMutex;
|
||||
|
||||
PackCompiler *m_compiler = nullptr;
|
||||
|
||||
|
||||
+416
-726
File diff suppressed because it is too large
Load Diff
+219
-93
@@ -36,6 +36,8 @@
|
||||
#include <qobject.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <QPainter>
|
||||
#include <QtShaderTools>
|
||||
#include <QtShaderTools/rhi/qshaderbaker.h>
|
||||
#include <QtConcurrent/qtconcurrentrun.h>
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qmargins.h>
|
||||
@@ -43,21 +45,42 @@
|
||||
#include <qtmetamacros.h>
|
||||
#include <qurl.h>
|
||||
#include "common/komplex_global.h"
|
||||
|
||||
#if __has_include("vulkan/vulkan_core.h")
|
||||
#define HAS_VULKAN
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#endif
|
||||
|
||||
#if __has_include("GL/gl.h")
|
||||
#define HAS_OPENGL
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
struct KOMPLEX_EXPORT BuildContext
|
||||
{
|
||||
QMap<QByteArray, QByteArray> commonData;
|
||||
QPromise<QUrl> promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The PackCompiler class
|
||||
* [1] Extract Pack (GZip)
|
||||
* [2] Verify directory is a pack and has shaders
|
||||
* [3] Load shader code
|
||||
* [4] Append Common and Global files, if they exist
|
||||
* [5] Add uniform and replace variable use
|
||||
* [6] Run C Preprocessor (cpp -P) to process macros
|
||||
* [7] Append version macro
|
||||
* [8] Compile with Qt Shader Baker
|
||||
* [3] Load Common shader code
|
||||
* [4] Walk the shader directory
|
||||
* [5] Load shader code
|
||||
* [6] Append type specific common code and global code
|
||||
* [7] Replace uniform variable use
|
||||
* [8] Add uniform header
|
||||
* [9] Add uniform footer
|
||||
* [10] Run preprocessor to process macros
|
||||
* [11] Append version macro
|
||||
* [12] Compile with QShaderBaker
|
||||
* [13] Save
|
||||
*/
|
||||
class KOMPLEX_EXPORT PackCompiler : public QObject
|
||||
class PackCompiler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
public:
|
||||
|
||||
enum State
|
||||
@@ -70,7 +93,6 @@ public:
|
||||
Q_ENUM(State)
|
||||
|
||||
explicit PackCompiler(QObject *parent = nullptr);
|
||||
~PackCompiler() override;
|
||||
|
||||
auto compilerOutput() const -> const QString & { return m_compilerOutput; }
|
||||
auto progress() -> qreal { return m_progress; }
|
||||
@@ -78,62 +100,11 @@ public:
|
||||
auto totalSteps() -> qint64 { return m_totalSteps; }
|
||||
auto errorTitle() const -> const QString & { return m_errorTitle; }
|
||||
auto errorMessage() const -> const QString & { return m_errorMessage; }
|
||||
auto reset() -> void;
|
||||
|
||||
auto process(const QUrl &uri) -> QFuture<QUrl>;
|
||||
|
||||
auto status() const -> const QString & { return m_status; }
|
||||
auto state() const -> State { return m_state; }
|
||||
auto reset() -> void;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief prepareShaders
|
||||
* Scans the pack's shader directory and sends each file to
|
||||
* prepareFile()
|
||||
* @param uri
|
||||
* Directory to prepare
|
||||
*/
|
||||
auto prepareShaders(const QUrl &uri) noexcept(false) -> void;
|
||||
|
||||
/**
|
||||
* @brief prepareFile
|
||||
* Prepares the individual file by appending the header, footer,
|
||||
* common files and replacing standard variable names
|
||||
* @param uri
|
||||
*/
|
||||
auto prepareFile(const QUrl &uri) noexcept(false) -> void;
|
||||
|
||||
/**
|
||||
* @brief validateDirectory
|
||||
*
|
||||
* @param uri
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
auto validateDirectory(const QUrl &uri) -> bool;
|
||||
|
||||
auto extract(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
|
||||
auto copyFile(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
|
||||
auto compile(const QUrl &uri) noexcept(false) -> void;
|
||||
auto preprocess(const QUrl &uri) noexcept(false) -> void;
|
||||
auto appendVersion(const QUrl &uri) noexcept(false) -> void;
|
||||
auto compileShader(const QUrl &uri) noexcept(false) -> void;
|
||||
auto loadCommonFragmentData(const QUrl &uri) -> QByteArray;
|
||||
auto loadCommonVertexData(const QUrl &uri) -> QByteArray;
|
||||
auto loadGlobalData(const QUrl &uri) -> QByteArray;
|
||||
|
||||
auto setError(const QString &title, const QString &message, const QUrl &uri = {}) -> void;
|
||||
auto setCompilerOutput(const QString &compilerOutput) -> void;
|
||||
auto setState(State state) -> void;
|
||||
auto setProgress(qreal progress) -> void;
|
||||
auto setTotalSteps(qint64 steps) -> void;
|
||||
auto setCurrentStep(qint64 step) -> void;
|
||||
|
||||
auto setStatus(const QString &status) -> void;
|
||||
|
||||
auto incrementCompileStep() -> void;
|
||||
|
||||
auto removeDirectory(const QUrl &uri) -> bool;
|
||||
auto build(const QUrl &uri) -> QUrl;
|
||||
|
||||
signals:
|
||||
auto compilerOutputChanged() -> void;
|
||||
@@ -144,15 +115,151 @@ signals:
|
||||
auto progressChanged() -> void;
|
||||
auto currentStepChanged() -> void;
|
||||
auto totalStepsChanged() -> void;
|
||||
|
||||
auto compileComplete(const QUrl &uri) -> void;
|
||||
|
||||
auto statusChanged() -> void;
|
||||
auto packReady(const QString &) -> void;
|
||||
auto errorStepChanged() -> void;
|
||||
auto errorRatingChanged() -> void;
|
||||
|
||||
private:
|
||||
//[1]
|
||||
/**
|
||||
* @brief extract
|
||||
* Extracts the packfile and deletes the source
|
||||
* @param uri of the tar.gz pack
|
||||
* @return uri of the extracted directory
|
||||
*/
|
||||
auto extract(const QUrl &uri) noexcept(false) -> const QUrl;
|
||||
|
||||
//[2]
|
||||
/**
|
||||
* @brief validatePack
|
||||
* Validates that the directory is a valid pack and has shaders to compile
|
||||
* @param uri of the directory provided by extract
|
||||
*/
|
||||
auto validatePack(const QUrl &uri) const noexcept(false) -> void;
|
||||
|
||||
//[3]
|
||||
/**
|
||||
* @brief loadCommonData
|
||||
* Loads the common and global shader code from the shader directory of the uri
|
||||
* @param uri
|
||||
*/
|
||||
auto loadCommonData(const QUrl &uri) -> QMap<QByteArray,QByteArray>;
|
||||
|
||||
//[4-5]
|
||||
/**
|
||||
* @brief processShaders
|
||||
* Walks the shader directory, loads the code and calls 6-13 for each
|
||||
* @param uri
|
||||
* @param context
|
||||
*/
|
||||
auto processShaders(const QUrl &uri, BuildContext *context) -> void;
|
||||
|
||||
//[6]
|
||||
/**
|
||||
* @brief appendCommonData
|
||||
* Appends the type specific common code to the shader data
|
||||
* @param data
|
||||
* Pointer to shader data
|
||||
* @param suffix
|
||||
* Shader file suffix
|
||||
* @param context
|
||||
* Pointer to build context object
|
||||
*/
|
||||
auto appendCommonData(QByteArray *data, const QByteArray &suffix, BuildContext *context) noexcept(true) -> void;
|
||||
|
||||
//[7]
|
||||
/**
|
||||
* @brief replaceUniformVariables
|
||||
* Replaces standard variables such as iFrame with their uniform buffer name
|
||||
* @param data
|
||||
* Pointer to the shader data
|
||||
*/
|
||||
auto replaceUniformVariables(QByteArray *data) noexcept(true) -> void;
|
||||
|
||||
//[8]
|
||||
/**
|
||||
* @brief appendUniformHeader
|
||||
* Adds header and uniform buffer to the shader data
|
||||
* @param data
|
||||
* Pointer to the shader data
|
||||
*/
|
||||
auto appendUniformHeader(QByteArray *data) noexcept(true) -> void;
|
||||
|
||||
//[9]
|
||||
/**
|
||||
* @brief appendUniformFooter
|
||||
* Adds the uniform footer to the shader data
|
||||
* @param data
|
||||
* Pointer to the shader data
|
||||
*/
|
||||
auto appendUniformFooter(QByteArray *data) noexcept(true) -> void;
|
||||
|
||||
//[10]
|
||||
/**
|
||||
* @brief preprocess
|
||||
* I have had issues with defines in code so passing it to a c/c++
|
||||
* preprocessor is required. I am now using clang for this as clang
|
||||
* is more modern and can use stdin
|
||||
* @param data
|
||||
*/
|
||||
auto preprocess(QByteArray *data) noexcept(false) -> void;
|
||||
|
||||
//[11]
|
||||
/**
|
||||
* @brief appendVersion
|
||||
* The version header confuses the preprocessor, so add it at the end
|
||||
* @param data
|
||||
*/
|
||||
auto appendVersion(QByteArray *data) noexcept(true) -> void;
|
||||
|
||||
//[12]
|
||||
/**
|
||||
* @brief compile
|
||||
* Compiles the shader data in memory and returns the shader object.
|
||||
* @param data
|
||||
* Shader data
|
||||
* @param filename
|
||||
* Filename of the shader
|
||||
* @param stage
|
||||
* Type of shader, based on suffix of original file
|
||||
* @return
|
||||
* Compiled shader object
|
||||
*/
|
||||
auto compile(const QByteArray &data, const QString &filename, const QShader::Stage stage) noexcept(false) -> QShader;
|
||||
|
||||
//[13]
|
||||
auto save(const QUrl &uri, const QShader &shader) noexcept(false) -> void;
|
||||
|
||||
//helpers
|
||||
auto validateUri(const QUrl &uri) const noexcept(false) -> void;
|
||||
auto run(const QString &command, const QStringList &arguments, const QByteArray &data = {}) noexcept(false) -> QByteArray;
|
||||
auto readFile(const QUrl &uri) noexcept(false) -> QByteArray;
|
||||
auto writeFile(const QUrl &uri, const QByteArray &data) noexcept(false) -> void;
|
||||
auto copyFile(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
|
||||
auto createDirectory(const QUrl &uri) noexcept(false) -> void;
|
||||
auto removeDirectory(const QUrl &uri) noexcept(false) -> void;
|
||||
auto getStageFromSuffix(const QString &suffix) const -> QShader::Stage;
|
||||
|
||||
auto setError(const QString &title, const QString &message, const QUrl &uri = {}) -> void;
|
||||
auto setCompilerOutput(const QString &compilerOutput) -> void;
|
||||
auto setState(State state) -> void;
|
||||
auto setProgress(qreal progress) -> void;
|
||||
auto setTotalSteps(qint64 steps) -> void;
|
||||
auto setCurrentStep(qint64 step) -> void;
|
||||
auto setStatus(const QString &status) -> void;
|
||||
auto incrementCompileStep() -> void;
|
||||
|
||||
#ifdef HAS_VULKAN
|
||||
auto vulkanVersion() const -> qint32;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_OPENGL
|
||||
auto openGlVersion() const -> qint32;
|
||||
#endif
|
||||
|
||||
//members
|
||||
static inline const QStringList m_updateVariables
|
||||
{
|
||||
QStringLiteral("iTime"),
|
||||
@@ -168,12 +275,51 @@ private:
|
||||
QStringLiteral("iChannelResolution")
|
||||
};
|
||||
|
||||
static inline const QStringList m_shaderNameFilters
|
||||
{
|
||||
QStringLiteral("*.frag"),
|
||||
QStringLiteral("*.vert"),
|
||||
QStringLiteral("*.tese"),
|
||||
QStringLiteral("*.tesc"),
|
||||
QStringLiteral("*.geom"),
|
||||
QStringLiteral("*.comp"),
|
||||
QStringLiteral("*.glsl")
|
||||
};
|
||||
|
||||
static inline const QMap<QString, QShader::Stage> m_shaderStages
|
||||
{
|
||||
{
|
||||
QStringLiteral("frag"),
|
||||
QShader::FragmentStage
|
||||
},
|
||||
{
|
||||
QStringLiteral("vert"),
|
||||
QShader::VertexStage
|
||||
},
|
||||
{
|
||||
QStringLiteral("tese"),
|
||||
QShader::TessellationEvaluationStage
|
||||
},
|
||||
{
|
||||
QStringLiteral("tesc"),
|
||||
QShader::TessellationControlStage
|
||||
},
|
||||
{
|
||||
QStringLiteral("geom"),
|
||||
QShader::GeometryStage
|
||||
},
|
||||
{
|
||||
QStringLiteral("comp"),
|
||||
QShader::ComputeStage
|
||||
}
|
||||
};
|
||||
|
||||
static inline const QByteArray m_version
|
||||
{
|
||||
R"(#version 450)"
|
||||
};
|
||||
|
||||
static inline const QString m_header
|
||||
static inline const QByteArray m_header
|
||||
{
|
||||
R"(layout(location = 0) in vec2 qt_TexCoord0;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
@@ -202,15 +348,19 @@ layout(binding = 4) uniform sampler2D iChannel3;
|
||||
vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy;)"
|
||||
};
|
||||
|
||||
static inline const QString m_footer
|
||||
static inline const QByteArray m_footer
|
||||
{
|
||||
R"(void main() {
|
||||
R"(
|
||||
void main() {
|
||||
vec4 color = vec4(0.0);
|
||||
mainImage(color, fragCoord);
|
||||
fragColor = color;
|
||||
})"
|
||||
};
|
||||
|
||||
QMap<QByteArray, QByteArray> m_commonData;
|
||||
QMap<QByteArray, QShaderBaker> m_shaders;
|
||||
|
||||
QString m_compilerOutput;
|
||||
QString m_errorMessage;
|
||||
QString m_errorTitle;
|
||||
@@ -224,34 +374,10 @@ vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.x
|
||||
|
||||
QMutex m_downloadMutex;
|
||||
|
||||
QFuture<QUrl> m_buildFuture;
|
||||
|
||||
static inline QList<QRegularExpression> m_variableExpressions;
|
||||
|
||||
static inline const QRegularExpression m_commonFragmentExpression = QRegularExpression
|
||||
(
|
||||
QString("^common\\.frag$"),
|
||||
QRegularExpression::CaseInsensitiveOption
|
||||
);
|
||||
|
||||
static inline const QRegularExpression m_commonVertexExpression = QRegularExpression
|
||||
(
|
||||
QString("^common\\.vert$"),
|
||||
QRegularExpression::CaseInsensitiveOption
|
||||
);
|
||||
|
||||
static inline const QRegularExpression m_fragmentExpression = QRegularExpression
|
||||
(
|
||||
QString("^.{1,}\\.frag$"),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::DotMatchesEverythingOption
|
||||
);
|
||||
|
||||
static inline const QRegularExpression m_vertexExpression = QRegularExpression
|
||||
(
|
||||
QString("^.{1,}\\.vert$"),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::DotMatchesEverythingOption
|
||||
);
|
||||
|
||||
Q_PROPERTY(QString compilerOutput READ compilerOutput WRITE setCompilerOutput NOTIFY compilerOutputChanged FINAL)
|
||||
Q_PROPERTY(QString errorTitle READ errorTitle NOTIFY errorTitleChanged FINAL)
|
||||
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged FINAL)
|
||||
|
||||
@@ -34,7 +34,10 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Most of the development of Komplex and it's associated apps will now happen here, instead of Github.
|
||||
<small>Note: Application style is based on your system theme. It will look different than it does in the screenshots. I am using a modified KVantum Glass, Blur and Neon Sunset Wallpaper Pack.</small>
|
||||
|
||||
## Development
|
||||
Most of the development of Komplex and applications under its project umbrella will now happen on https://git.digitalartifex.dev instead of Github.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -51,10 +54,11 @@ Most of the development of Komplex and it's associated apps will now happen here
|
||||
- Qt6 Shader Tools
|
||||
- CMake
|
||||
- clang
|
||||
- C Pre Processor (cpp)
|
||||
|
||||
#### Build
|
||||
```console
|
||||
$ git clone gitea@git.digitalartifex.dev:digitalartifex/komplex-hub.git
|
||||
$ git clone --recursive gitea@git.digitalartifex.dev:digitalartifex/komplex-hub.git
|
||||
$ mkdir build
|
||||
$ cmake -S ./ -B ./build/
|
||||
$ cmake --build ./build
|
||||
@@ -74,4 +78,110 @@ Content purchases will be processed through the website using Paypal as will art
|
||||
|
||||
## Status
|
||||
|
||||
This app is currently under development and is pre-alpha. The API is now being hosted on https://komplex.dev. However, there is no download functionality as of yet. BETA should be here within a few weeks.
|
||||
### Legend
|
||||
|
||||
| Status | Icon | Description |
|
||||
|-------|:-------:|--------|
|
||||
| Not started | ❌ | Either no work has been done yet or so little work that it is unusable in its current state.
|
||||
| In Progress | ✔ | *Some* work has been completed, but is not yet functional and/or feature complete
|
||||
| Complete | ✅ | Planned features completed
|
||||
|
||||
### API Status
|
||||
|
||||
| Feature | Status |
|
||||
|-------|:-------:|
|
||||
| Packs | ✔ | |
|
||||
| - Download Packs | ✅ | |
|
||||
| - Newest Packs | ✅ | |
|
||||
| - Featured Packs | ✔ | |
|
||||
| - Search Packs | ✅ | |
|
||||
| - Submit Packs | ✔ | |
|
||||
| - Thumbnails | ✅ | |
|
||||
| | | |
|
||||
| Cubemaps | ✔ | |
|
||||
| - Download Cubemaps | ✅ | |
|
||||
| - Newest Cubemaps | ✅ | |
|
||||
| - Featured Cubemaps | ✔ | |
|
||||
| - Search Cubemaps | ✅ | |
|
||||
| - Submit Cubemaps | ✔ | - |
|
||||
| | | |
|
||||
| Filter Shaders | ✔ | |
|
||||
| - Download Filter Shaders | ✅ | |
|
||||
| - Newest Filter Shaders | ✅ | |
|
||||
| - Featured Filter Shaders | ✔ | |
|
||||
| - Search Filter Shaders | ✅ | |
|
||||
| - Submit Filter Shaders | ✔ | - |
|
||||
| | | |
|
||||
| Images | ✅ | |
|
||||
| - Featured Images | ✅ | |
|
||||
| - Search Images | ✅ | |
|
||||
| | | |
|
||||
| Videos | ✅ | |
|
||||
| - Popular Videos | ✅ | |
|
||||
| - Search Videos | ✅ | |
|
||||
| | | |
|
||||
| Accounts | ✔ | |
|
||||
| - User Accounts | ✔ | |
|
||||
| - User Authentication | ✔ | |
|
||||
| - User Editing | ❌ | |
|
||||
| - User Configuration | ❌ | |
|
||||
| - User Media | ❌ | |
|
||||
| - Author Profiles | ❌ | |
|
||||
|
||||
### Media Hub Status
|
||||
|
||||
| Feature | Status |
|
||||
|-------|:-------:|
|
||||
| Spotlight/Homepage | ✔ | |
|
||||
| - Newest Packs | ✅ | |
|
||||
| - Featured Packs | ✔ | |
|
||||
| - Featured Images | ✅ | |
|
||||
| - Popular Videos | ✅ | |
|
||||
| - View More | ✅ | |
|
||||
| | | |
|
||||
| Media Search | ✅ | |
|
||||
| - Packs | ✅ | |
|
||||
| - Videos | ✅ | |
|
||||
| - Images | ✅ | |
|
||||
| | | |
|
||||
| Media Downloader | ✅ | |
|
||||
| - Packs | ✅ | |
|
||||
| - Videos | ✅ | |
|
||||
| - Images | ✅ | |
|
||||
| | | |
|
||||
| Detailed Views | ✅ | |
|
||||
| - Packs | ✅ | |
|
||||
| - Videos | ✅ | |
|
||||
| - Images | ✅ | |
|
||||
| | | |
|
||||
| App Management | ✔ | |
|
||||
| Installed Media Manager | ✔ | |
|
||||
| Settings Manager | ✅ | |
|
||||
| | | |
|
||||
| Account Management | ❌ | |
|
||||
| User Accounts | ❌ | |
|
||||
| - User Login | ❌ | |
|
||||
| - User Profile | ❌ | |
|
||||
| - Author Profile | ❌ | |
|
||||
| About Page | ✅ | |
|
||||
|
||||
### Pack Designer
|
||||
|
||||
| Feature | Status |
|
||||
|-------|:-------:|
|
||||
| All Design & Features | ❌ | |
|
||||
|
||||
### Site
|
||||
|
||||
| Feature | Status |
|
||||
|-------|:-------:|
|
||||
| Site Base | ✔ | |
|
||||
| Accounts | ✔ | |
|
||||
| Gallery | ❌ | |
|
||||
| Payment Gateway | ❌ | |
|
||||
| - Artist Payout | ❌ | |
|
||||
| - User Media Purchase | ❌ | |
|
||||
|
||||
This app is currently under development and is currently BETA1 and the new API is live. Please do expect bugs in pack compiling at this stage.
|
||||
|
||||
"Featured" Live wallpapers is currently a duplicated of "Newest". The featured endpoint will take manual curation, so this will take some time.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.0 MiB |
@@ -11,8 +11,8 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
KomplexHubModuleplugin
|
||||
KomplexHubContentplugin
|
||||
KomplexHubPluginplugin
|
||||
KomplexHubModule_Controlsplugin
|
||||
KomplexHubModule_Keroplugin
|
||||
KomplexHubControlsplugin
|
||||
KomplexHubKeroplugin
|
||||
Qt6::Quick
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
|
||||
Reference in New Issue
Block a user