Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
abd653ef1c
|
|||
|
9db9ed67d8
|
|||
|
990457042a
|
|||
|
2a5e66d68c
|
|||
|
1826209521
|
|||
|
3d0655edd1
|
|||
|
69743883d7
|
|||
|
100c6da3cf
|
|||
|
b64834084e
|
|||
|
a58fdfadc6
|
|||
|
da24f34bb4
|
|||
|
e9bc016fbb
|
|||
|
6947a65f75
|
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "KomplexHubPlugin/3rdparty/qtkeychain"]
|
||||||
|
path = KomplexHubPlugin/3rdparty/qtkeychain
|
||||||
|
url = https://github.com/frankosterfeld/qtkeychain.git
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
;This file is used to denote what files have generative content
|
||||||
|
;Format: {file, class, model/version, ["message"]}
|
||||||
|
|
||||||
|
;Kero
|
||||||
|
{
|
||||||
|
images/kero/kero_build_1.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_build_2.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_build_3.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_build_4.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_build_error.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_choice.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_hello.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_login.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_no_results.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_run_1.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_run_2.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_run_3.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_run_4.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_warning.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
images/kero/kero_success.png,
|
||||||
|
placeholders,
|
||||||
|
chatgpt5
|
||||||
|
}
|
||||||
+15
-3
@@ -20,13 +20,25 @@ set(QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY}
|
|||||||
FORCE
|
FORCE
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(Qt6 6.8 REQUIRED COMPONENTS Core Gui Widgets Qml Quick QuickControls2 QuickTimeline ShaderTools Concurrent)
|
find_package(
|
||||||
|
Qt6 6.8
|
||||||
|
REQUIRED COMPONENTS
|
||||||
|
Core
|
||||||
|
Gui
|
||||||
|
Widgets
|
||||||
|
Qml
|
||||||
|
Quick
|
||||||
|
QuickControls2
|
||||||
|
QuickTimeline
|
||||||
|
ShaderTools
|
||||||
|
Concurrent
|
||||||
|
)
|
||||||
|
|
||||||
qt_standard_project_setup()
|
qt_standard_project_setup()
|
||||||
|
|
||||||
qt_add_executable(${CMAKE_PROJECT_NAME}
|
qt_add_executable(${CMAKE_PROJECT_NAME}
|
||||||
README.md
|
|
||||||
LICENSE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_resources(${CMAKE_PROJECT_NAME} "configuration"
|
qt_add_resources(${CMAKE_PROJECT_NAME} "configuration"
|
||||||
PREFIX "/"
|
PREFIX "/"
|
||||||
FILES
|
FILES
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Imported 3D assets and components imported from bundles will be created in this folder.
|
|
||||||
@@ -18,6 +18,9 @@ qt6_add_qml_module(KomplexHubContent
|
|||||||
"pages/UserProfilePage.qml"
|
"pages/UserProfilePage.qml"
|
||||||
"pages/WallpaperSettingsPage.qml"
|
"pages/WallpaperSettingsPage.qml"
|
||||||
"pages/VideoSearchPage.qml"
|
"pages/VideoSearchPage.qml"
|
||||||
|
QML_FILES pages/FeaturedVideosPage.qml
|
||||||
|
QML_FILES pages/FeaturedPacksPage.qml
|
||||||
|
QML_FILES pages/FeaturedImagesPage.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import KomplexHub
|
||||||
|
import KomplexHub.Controls
|
||||||
|
import KomplexHub.Kero
|
||||||
|
import KomplexHubPlugin
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
readonly property bool searchable: false
|
||||||
|
property bool popup: false
|
||||||
|
property int resultWidth: 256
|
||||||
|
property int resultHeight: 245
|
||||||
|
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
FeaturedImagesModel
|
||||||
|
{
|
||||||
|
id: imagesModel
|
||||||
|
resultsPerPage: paginator.resultsPerPage
|
||||||
|
// windowSize: 80
|
||||||
|
}
|
||||||
|
|
||||||
|
PaginatorGrid
|
||||||
|
{
|
||||||
|
id: paginator
|
||||||
|
anchors.fill: parent
|
||||||
|
model: imagesModel
|
||||||
|
loading: imagesModel.state === FeaturedImagesModel.Loading
|
||||||
|
visible: opacity > 0.01
|
||||||
|
|
||||||
|
delegate: ItemDelegate
|
||||||
|
{
|
||||||
|
id: resultDelegate
|
||||||
|
|
||||||
|
width: resultWidth
|
||||||
|
height: resultHeight
|
||||||
|
|
||||||
|
required property string uuid
|
||||||
|
required property string author
|
||||||
|
required property string authorId
|
||||||
|
required property string authorUrl
|
||||||
|
required property string thumbnail
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
SearchResultItem
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
author: parent.author
|
||||||
|
description: qsTr("No description available")
|
||||||
|
thumbnail: parent.thumbnail
|
||||||
|
uuid: parent.uuid
|
||||||
|
pexels: true
|
||||||
|
selected: paginator.currentIndex === parent.index
|
||||||
|
|
||||||
|
onTriggered: () => paginator.currentIndex = parent.index
|
||||||
|
|
||||||
|
onViewMoreTriggered: () =>
|
||||||
|
{
|
||||||
|
showVideoPopup(parent.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: popupContainer
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity > 0.01
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
ImageView
|
||||||
|
{
|
||||||
|
id: imageDetailsPopup
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Behavior on opacity
|
||||||
|
{
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity
|
||||||
|
{
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: () =>
|
||||||
|
{
|
||||||
|
imagesModel.nextPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showVideoPopup(index)
|
||||||
|
{
|
||||||
|
imagesModel.setItem(index)
|
||||||
|
imageDetailsPopup.author = searchModel.data(searchModel.index(index,0), ImageSearchModel.AuthorRole)
|
||||||
|
imageDetailsPopup.authorUrl = searchModel.data(searchModel.index(index,0), ImageSearchModel.AuthorUrlRole)
|
||||||
|
imageDetailsPopup.uuid = searchModel.data(searchModel.index(index,0), ImageSearchModel.UuidRole)
|
||||||
|
imageDetailsPopup.thumbnail = searchModel.data(searchModel.index(index,0), ImageSearchModel.ThumbnailRole)
|
||||||
|
imageDetailsPopup.modelIndex = index
|
||||||
|
imageDetailsPopup.model = searchModel.itemModel
|
||||||
|
imageDetailsPopup.opacity = 1
|
||||||
|
paginator.opacity = 0
|
||||||
|
popupContainer.opacity = 1
|
||||||
|
rootItem.popup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopup()
|
||||||
|
{
|
||||||
|
imageDetailsPopup.opacity = 0
|
||||||
|
popupContainer.opacity = 0
|
||||||
|
paginator.opacity = 1
|
||||||
|
rootItem.popup = false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import KomplexHub
|
||||||
|
import KomplexHub.Controls
|
||||||
|
import KomplexHub.Kero
|
||||||
|
import KomplexHubPlugin
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
readonly property bool searchable: false
|
||||||
|
property bool popup: false
|
||||||
|
property int resultWidth: 256
|
||||||
|
property int resultHeight: 245
|
||||||
|
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
FeaturedPacksModel
|
||||||
|
{
|
||||||
|
id: packsModel
|
||||||
|
resultsPerPage: paginator.resultsPerPage
|
||||||
|
// windowSize: 80
|
||||||
|
}
|
||||||
|
|
||||||
|
PaginatorGrid
|
||||||
|
{
|
||||||
|
id: paginator
|
||||||
|
anchors.fill: parent
|
||||||
|
model: packsModel
|
||||||
|
loading: packsModel.state === FeaturedPacksModel.Loading
|
||||||
|
visible: opacity > 0.01
|
||||||
|
|
||||||
|
delegate: ItemDelegate
|
||||||
|
{
|
||||||
|
id: resultDelegate
|
||||||
|
|
||||||
|
width: resultWidth
|
||||||
|
height: resultHeight
|
||||||
|
|
||||||
|
required property string uuid
|
||||||
|
required property string author
|
||||||
|
required property string authorId
|
||||||
|
required property string authorUrl
|
||||||
|
required property string thumbnail
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
SearchResultItem
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
author: parent.author
|
||||||
|
description: qsTr("No description available")
|
||||||
|
thumbnail: parent.thumbnail
|
||||||
|
uuid: parent.uuid
|
||||||
|
pexels: true
|
||||||
|
selected: paginator.currentIndex === parent.index
|
||||||
|
|
||||||
|
onTriggered: () => paginator.currentIndex = parent.index
|
||||||
|
|
||||||
|
onViewMoreTriggered: () =>
|
||||||
|
{
|
||||||
|
showVideoPopup(parent.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: popupContainer
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity > 0.01
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
PackView
|
||||||
|
{
|
||||||
|
id: packDetailsPopup
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Behavior on opacity
|
||||||
|
{
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity
|
||||||
|
{
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: () =>
|
||||||
|
{
|
||||||
|
packsModel.nextPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showVideoPopup(index)
|
||||||
|
{
|
||||||
|
packsModel.setItem(index)
|
||||||
|
packDetailsPopup.author = searchModel.data(searchModel.index(index,0), VideoSearchModel.AuthorRole)
|
||||||
|
packDetailsPopup.authorUrl = searchModel.data(searchModel.index(index,0), VideoSearchModel.AuthorUrlRole)
|
||||||
|
packDetailsPopup.uuid = searchModel.data(searchModel.index(index,0), VideoSearchModel.UuidRole)
|
||||||
|
packDetailsPopup.thumbnail = searchModel.data(searchModel.index(index,0), VideoSearchModel.ThumbnailRole)
|
||||||
|
packDetailsPopup.modelIndex = index
|
||||||
|
packDetailsPopup.model = searchModel.itemModel
|
||||||
|
packDetailsPopup.opacity = 1
|
||||||
|
paginator.opacity = 0
|
||||||
|
popupContainer.opacity = 1
|
||||||
|
rootItem.popup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopup()
|
||||||
|
{
|
||||||
|
packDetailsPopup.opacity = 0
|
||||||
|
popupContainer.opacity = 0
|
||||||
|
paginator.opacity = 1
|
||||||
|
rootItem.popup = false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import KomplexHub
|
||||||
|
import KomplexHub.Controls
|
||||||
|
import KomplexHub.Kero
|
||||||
|
import KomplexHubPlugin
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
readonly property bool searchable: false
|
||||||
|
property bool popup: false
|
||||||
|
property int resultWidth: 256
|
||||||
|
property int resultHeight: 245
|
||||||
|
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
FeaturedVideosModel
|
||||||
|
{
|
||||||
|
id: videosModel
|
||||||
|
resultsPerPage: paginator.resultsPerPage
|
||||||
|
windowSize: 80
|
||||||
|
}
|
||||||
|
|
||||||
|
PaginatorGrid
|
||||||
|
{
|
||||||
|
id: paginator
|
||||||
|
anchors.fill: parent
|
||||||
|
model: videosModel
|
||||||
|
loading: videosModel.state === FeaturedVideosModel.Loading
|
||||||
|
visible: opacity > 0.01
|
||||||
|
|
||||||
|
delegate: ItemDelegate
|
||||||
|
{
|
||||||
|
id: resultDelegate
|
||||||
|
|
||||||
|
width: resultWidth
|
||||||
|
height: resultHeight
|
||||||
|
|
||||||
|
required property string uuid
|
||||||
|
required property string author
|
||||||
|
required property string authorId
|
||||||
|
required property string authorUrl
|
||||||
|
required property string thumbnail
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
SearchResultItem
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
author: parent.author
|
||||||
|
description: qsTr("No description available")
|
||||||
|
thumbnail: parent.thumbnail
|
||||||
|
uuid: parent.uuid
|
||||||
|
pexels: true
|
||||||
|
selected: paginator.currentIndex === parent.index
|
||||||
|
|
||||||
|
onTriggered: () => paginator.currentIndex = parent.index
|
||||||
|
|
||||||
|
onViewMoreTriggered: () =>
|
||||||
|
{
|
||||||
|
showVideoPopup(parent.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: popupContainer
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity > 0.01
|
||||||
|
color: palette.base
|
||||||
|
|
||||||
|
VideoView
|
||||||
|
{
|
||||||
|
id: videoDetailsPopup
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Behavior on opacity
|
||||||
|
{
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity
|
||||||
|
{
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: () =>
|
||||||
|
{
|
||||||
|
videosModel.nextPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showVideoPopup(index)
|
||||||
|
{
|
||||||
|
videosModel.setItem(index)
|
||||||
|
videoDetailsPopup.author = searchModel.data(searchModel.index(index,0), VideoSearchModel.AuthorRole)
|
||||||
|
videoDetailsPopup.authorUrl = searchModel.data(searchModel.index(index,0), VideoSearchModel.AuthorUrlRole)
|
||||||
|
videoDetailsPopup.uuid = searchModel.data(searchModel.index(index,0), VideoSearchModel.UuidRole)
|
||||||
|
videoDetailsPopup.thumbnail = searchModel.data(searchModel.index(index,0), VideoSearchModel.ThumbnailRole)
|
||||||
|
videoDetailsPopup.modelIndex = index
|
||||||
|
videoDetailsPopup.model = searchModel.itemModel
|
||||||
|
videoDetailsPopup.opacity = 1
|
||||||
|
paginator.opacity = 0
|
||||||
|
popupContainer.opacity = 1
|
||||||
|
rootItem.popup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopup()
|
||||||
|
{
|
||||||
|
videoDetailsPopup.opacity = 0
|
||||||
|
popupContainer.opacity = 0
|
||||||
|
paginator.opacity = 1
|
||||||
|
rootItem.popup = false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -116,6 +116,11 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onViewMoreTriggered: () =>
|
||||||
|
{
|
||||||
|
showFeaturedPacksPage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text
|
Text
|
||||||
@@ -168,6 +173,11 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onViewMoreTriggered: () =>
|
||||||
|
{
|
||||||
|
showFeaturedImagesPage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text
|
Text
|
||||||
@@ -215,6 +225,11 @@ Item
|
|||||||
onViewMoreTriggered:() => showVideoPopup(parent.index)
|
onViewMoreTriggered:() => showVideoPopup(parent.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onViewMoreTriggered: () =>
|
||||||
|
{
|
||||||
|
showFeaturedVideosPage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* spacer */
|
/* spacer */
|
||||||
@@ -301,6 +316,51 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FeaturedVideosPage
|
||||||
|
{
|
||||||
|
id: featuredVideosPage
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity > 0.01
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FeaturedPacksPage
|
||||||
|
{
|
||||||
|
id: featuredPacksPage
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity > 0.01
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FeaturedImagesPage
|
||||||
|
{
|
||||||
|
id: featuredImagesPage
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
visible: opacity > 0.01
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation
|
||||||
|
{
|
||||||
|
duration: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "loading"
|
name: "loading"
|
||||||
@@ -364,6 +424,27 @@ Item
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
function showFeaturedVideosPage()
|
||||||
|
{
|
||||||
|
resultsLayout.opacity = 0
|
||||||
|
featuredVideosPage.opacity = 1
|
||||||
|
popup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function showFeaturedPacksPage()
|
||||||
|
{
|
||||||
|
resultsLayout.opacity = 0
|
||||||
|
featuredPacksPage.opacity = 1
|
||||||
|
popup = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function showFeaturedImagesPage()
|
||||||
|
{
|
||||||
|
resultsLayout.opacity = 0
|
||||||
|
featuredImagesPage.opacity = 1
|
||||||
|
popup = true
|
||||||
|
}
|
||||||
|
|
||||||
function showImagePopup(index)
|
function showImagePopup(index)
|
||||||
{
|
{
|
||||||
viewMoreImagePopup.author = imagesModel.data(imagesModel.index(index,0), FeaturedImagesModel.AuthorRole)
|
viewMoreImagePopup.author = imagesModel.data(imagesModel.index(index,0), FeaturedImagesModel.AuthorRole)
|
||||||
@@ -415,6 +496,25 @@ Item
|
|||||||
|
|
||||||
function closePopup()
|
function closePopup()
|
||||||
{
|
{
|
||||||
|
if(featuredVideosPage.popup)
|
||||||
|
{
|
||||||
|
featuredVideosPage.closePopup()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(featuredImagesPage.popup)
|
||||||
|
{
|
||||||
|
featuredImagesPage.closePopup()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(featuredPacksPage.popup)
|
||||||
|
{
|
||||||
|
featuredPacksPage.closePopup()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
featuredVideosPage.opacity = 0
|
||||||
|
featuredImagesPage.opacity = 0
|
||||||
|
featuredPacksPage.opacity = 0
|
||||||
viewMoreImagePopup.opacity = 0
|
viewMoreImagePopup.opacity = 0
|
||||||
viewMoreVideoPopup.opacity = 0
|
viewMoreVideoPopup.opacity = 0
|
||||||
viewMoreWallpaperPopup.opacity = 0
|
viewMoreWallpaperPopup.opacity = 0
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ Item
|
|||||||
|
|
||||||
property Component delegate
|
property Component delegate
|
||||||
|
|
||||||
|
signal viewMoreTriggered()
|
||||||
|
|
||||||
id: rootItem
|
id: rootItem
|
||||||
|
|
||||||
Item
|
Item
|
||||||
@@ -162,6 +164,8 @@ Item
|
|||||||
icon.source: "qrc:/images/icons/icons8-forward.svg"
|
icon.source: "qrc:/images/icons/icons8-forward.svg"
|
||||||
icon.height: 24
|
icon.height: 24
|
||||||
icon.width: 24
|
icon.width: 24
|
||||||
|
|
||||||
|
onTriggered: () => viewMoreTriggered()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
Submodule KomplexHubPlugin/3rdparty/qtkeychain added at 087369387c
@@ -19,23 +19,17 @@ qt_add_qml_module(
|
|||||||
newestpacksmodel.cpp
|
newestpacksmodel.cpp
|
||||||
common/komplex_global.h
|
common/komplex_global.h
|
||||||
common/slidingcachecontroller.h
|
common/slidingcachecontroller.h
|
||||||
common/paginator.h
|
|
||||||
common/coreservices.h
|
common/coreservices.h
|
||||||
common/coreservices.cpp
|
common/coreservices.cpp
|
||||||
common/logging.h
|
common/logging.h
|
||||||
common/fetchresult.h
|
common/fetchresult.h
|
||||||
|
paginators/paginator.h
|
||||||
paginators/newestpackspaginator.h
|
paginators/newestpackspaginator.h
|
||||||
paginators/featuredpackspaginator.h
|
paginators/featuredpackspaginator.h
|
||||||
paginators/featuredimagespaginator.h
|
paginators/featuredimagespaginator.h
|
||||||
paginators/wallpaperpaginator.h
|
paginators/wallpaperpaginator.h
|
||||||
paginators/packsearchpaginator.h
|
paginators/packsearchpaginator.h
|
||||||
paginators/imagesearchpaginator.h
|
paginators/imagesearchpaginator.h
|
||||||
paginators/newestshaderspaginator.h
|
|
||||||
paginators/newestcubemapspaginator.h
|
|
||||||
paginators/featuredshaderspaginator.h
|
|
||||||
paginators/featuredcubemapspaginator.h
|
|
||||||
paginators/searchshaderspaginator.h
|
|
||||||
paginators/searchcubemapspaginator.h
|
|
||||||
paginators/videosearchpaginator.h
|
paginators/videosearchpaginator.h
|
||||||
featuredpacksmodel.h
|
featuredpacksmodel.h
|
||||||
featuredpacksmodel.cpp
|
featuredpacksmodel.cpp
|
||||||
@@ -60,7 +54,11 @@ qt_add_qml_module(
|
|||||||
common/exceptions.h
|
common/exceptions.h
|
||||||
common/shadertoymetadata.h
|
common/shadertoymetadata.h
|
||||||
common/shaderpack.h
|
common/shaderpack.h
|
||||||
SOURCES packcompiler.h packcompiler.cpp
|
packcompiler.h
|
||||||
|
packcompiler.cpp
|
||||||
|
SOURCES common/userservices.h
|
||||||
|
SOURCES common/userservices.cpp
|
||||||
|
SOURCES common/qwallet.h common/qwallet.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(
|
target_compile_definitions(
|
||||||
@@ -69,9 +67,12 @@ target_compile_definitions(
|
|||||||
KOMPLEX_PLUGIN
|
KOMPLEX_PLUGIN
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(3rdparty/qtkeychain)
|
||||||
|
|
||||||
target_link_libraries(KomplexHubPlugin PRIVATE
|
target_link_libraries(KomplexHubPlugin PRIVATE
|
||||||
Qt${QT_VERSION_MAJOR}::Core
|
Qt${QT_VERSION_MAJOR}::Core
|
||||||
Qt${QT_VERSION_MAJOR}::Gui
|
Qt${QT_VERSION_MAJOR}::Gui
|
||||||
|
qt6keychain
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_ASAN)
|
if(ENABLE_ASAN)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "coreservices.h"
|
#include "coreservices.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
QNetworkAccessManager *CoreServices::s_networkAccessManager = new QNetworkAccessManager();
|
QNetworkAccessManager *CoreServices::s_networkAccessManager = nullptr;
|
||||||
QMutex CoreServices::s_networkAccessMutex;
|
QMutex CoreServices::s_networkAccessMutex;
|
||||||
QSharedPointer<QNetworkAccessManager> CoreServices::s_networkAccessPointer;
|
QSharedPointer<QNetworkAccessManager> CoreServices::s_networkAccessPointer;
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ auto CoreServices::networkAccessManager() -> QWeakPointer<QNetworkAccessManager>
|
|||||||
|
|
||||||
if(!s_networkAccessPointer)
|
if(!s_networkAccessPointer)
|
||||||
{
|
{
|
||||||
s_networkAccessManager = new QNetworkAccessManager;
|
s_networkAccessManager = new QNetworkAccessManager(QCoreApplication::instance());
|
||||||
s_networkAccessManager->setAutoDeleteReplies(true);
|
s_networkAccessManager->setAutoDeleteReplies(true);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef EXCEPTIONS_H
|
#ifndef EXCEPTIONS_H
|
||||||
#define EXCEPTIONS_H
|
#define EXCEPTIONS_H
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -13,20 +31,22 @@ struct KOMPLEX_EXPORT Exception : std::exception
|
|||||||
const quint16 errorCode;
|
const quint16 errorCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NetworkException : Exception
|
struct KOMPLEX_EXPORT NetworkException : Exception
|
||||||
{
|
{
|
||||||
NetworkException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
NetworkException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||||
};
|
};
|
||||||
struct FileException : Exception
|
struct KOMPLEX_EXPORT FileException : Exception
|
||||||
{
|
{
|
||||||
FileException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
FileException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||||
};
|
};
|
||||||
struct SqlException : Exception
|
struct KOMPLEX_EXPORT SqlException : Exception
|
||||||
{
|
{
|
||||||
SqlException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
SqlException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||||
};
|
};
|
||||||
|
struct KOMPLEX_EXPORT WalletException : Exception
|
||||||
|
{
|
||||||
|
WalletException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||||
|
};
|
||||||
struct KOMPLEX_EXPORT ShaderCompilerException : Exception
|
struct KOMPLEX_EXPORT ShaderCompilerException : Exception
|
||||||
{
|
{
|
||||||
ShaderCompilerException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
ShaderCompilerException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef IMAGECACHE_H
|
#ifndef IMAGECACHE_H
|
||||||
#define IMAGECACHE_H
|
#define IMAGECACHE_H
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#ifndef KOMPLEX_GLOBAL_H
|
#ifndef KOMPLEX_GLOBAL_H
|
||||||
#define KOMPLEX_GLOBAL_H
|
#define KOMPLEX_GLOBAL_H
|
||||||
#include <QtTypes>
|
#include <QtTypes>
|
||||||
|
#include <QString>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#ifdef KOMPLEX_PLUGIN
|
#ifdef KOMPLEX_PLUGIN
|
||||||
@@ -36,35 +37,46 @@
|
|||||||
#ifdef KOMPLEX_LOCAL_DEV
|
#ifdef KOMPLEX_LOCAL_DEV
|
||||||
#define KOMPLEX_API_HOST "https://komplexapi.hlab"
|
#define KOMPLEX_API_HOST "https://komplexapi.hlab"
|
||||||
#else
|
#else
|
||||||
#define KOMPLEX_API_HOST "https://api.komplex.dev"
|
inline const QString KOMPLEX_API_HOST = QStringLiteral("https://api.komplex.dev");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KOMPLEX_API_VERSION "v2"
|
inline const QString KOMPLEX_API_VERSION = QStringLiteral("v2");
|
||||||
|
|
||||||
#define KOMPLEX_ENDPOINT_IMAGES_SEARCH "images/search"
|
inline const QString KOMPLEX_ENDPOINT_IMAGES_SEARCH = QStringLiteral("images/search");
|
||||||
#define KOMPLEX_ENDPOINT_IMAGES_FEATURED "featured/images"
|
inline const QString KOMPLEX_ENDPOINT_IMAGES_FEATURED = QStringLiteral("featured/images");
|
||||||
#define KOMPLEX_ENDPOINT_IMAGES_ITEM "images/item"
|
inline const QString KOMPLEX_ENDPOINT_IMAGES_ITEM = QStringLiteral("images/item");
|
||||||
|
|
||||||
#define KOMPLEX_ENDPOINT_VIDEOS_SEARCH "videos/search"
|
inline const QString KOMPLEX_ENDPOINT_VIDEOS_SEARCH = QStringLiteral("videos/search");
|
||||||
#define KOMPLEX_ENDPOINT_VIDEOS_FEATURED "featured/videos"
|
inline const QString KOMPLEX_ENDPOINT_VIDEOS_FEATURED = QStringLiteral("featured/videos");
|
||||||
#define KOMPLEX_ENDPOINT_VIDEOS_ITEM "videos/item"
|
inline const QString KOMPLEX_ENDPOINT_VIDEOS_ITEM = QStringLiteral("videos/item");
|
||||||
|
|
||||||
#define KOMPLEX_ENDPOINT_SHADERS_SEARCH "shaders/search"
|
inline const QString KOMPLEX_ENDPOINT_SHADERS_SEARCH = QStringLiteral("shaders/search");
|
||||||
#define KOMPLEX_ENDPOINT_SHADERS_FEATURED "shaders/featured"
|
inline const QString KOMPLEX_ENDPOINT_SHADERS_FEATURED = QStringLiteral("shaders/featured");
|
||||||
#define KOMPLEX_ENDPOINT_SHADERS_ITEM "shaders/item"
|
inline const QString KOMPLEX_ENDPOINT_SHADERS_ITEM = QStringLiteral("shaders/item");
|
||||||
#define KOMPLEX_ENDPOINT_SHADERS_NEWEST "shaders/newest"
|
inline const QString KOMPLEX_ENDPOINT_SHADERS_NEWEST = QStringLiteral("shaders/newest");
|
||||||
|
|
||||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_SEARCH "cubemaps/search"
|
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_SEARCH = QStringLiteral("cubemaps/search");
|
||||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_FEATURED "cubemaps/featured"
|
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_FEATURED = QStringLiteral("cubemaps/featured");
|
||||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_ITEM "cubemaps/item"
|
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_ITEM = QStringLiteral("cubemaps/item");
|
||||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_NEWEST "cubemaps/newest"
|
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_NEWEST = QStringLiteral("cubemaps/newest");
|
||||||
|
|
||||||
#define KOMPLEX_ENDPOINT_PACKS_SEARCH "packs/search"
|
inline const QString KOMPLEX_ENDPOINT_PACKS_SEARCH = QStringLiteral("packs/search");
|
||||||
#define KOMPLEX_ENDPOINT_PACKS_FEATURED "packs/featured"
|
inline const QString KOMPLEX_ENDPOINT_PACKS_FEATURED = QStringLiteral("packs/featured");
|
||||||
#define KOMPLEX_ENDPOINT_PACKS_ITEM "packs/item"
|
inline const QString KOMPLEX_ENDPOINT_PACKS_ITEM = QStringLiteral("packs/item");
|
||||||
#define KOMPLEX_ENDPOINT_PACKS_NEWEST "packs/newest"
|
inline const QString KOMPLEX_ENDPOINT_PACKS_NEWEST = QStringLiteral("packs/newest");
|
||||||
|
|
||||||
inline static qsizetype nullsize = std::numeric_limits<qsizetype>::min();
|
inline const QString KOMPLEX_ENDPOINT_USER_AUTH = QStringLiteral("user/auth");
|
||||||
inline static std::chrono::milliseconds KOMPLEX_RATE_LIMIT(500);
|
|
||||||
|
inline const qsizetype nullsize = std::numeric_limits<qsizetype>::min();
|
||||||
|
inline const std::chrono::milliseconds KOMPLEX_RATE_LIMIT(500);
|
||||||
|
inline const QString KOMPLEX_KEYCHAIN_PASSWORD_KEY = QStringLiteral
|
||||||
|
(
|
||||||
|
"com.digitalartifex.komplex.keychain.password"
|
||||||
|
);
|
||||||
|
|
||||||
|
inline const QString KOMPLEX_KEYCHAIN_TOKEN_KEY = QStringLiteral
|
||||||
|
(
|
||||||
|
"com.digitalartifex.komplex.keychain.token"
|
||||||
|
);
|
||||||
|
|
||||||
#endif // KOMPLEX_GLOBAL_H
|
#endif // KOMPLEX_GLOBAL_H
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
#include "qwallet.h"
|
||||||
|
#include "../3rdparty/qtkeychain/qtkeychain/keychain.h"
|
||||||
|
|
||||||
|
auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray>
|
||||||
|
{
|
||||||
|
return QtConcurrent::run
|
||||||
|
(
|
||||||
|
[this, service(service), key(key)]() -> QByteArray
|
||||||
|
{
|
||||||
|
QEventLoop loop;
|
||||||
|
QByteArray value;
|
||||||
|
|
||||||
|
auto readCredentialJob = new QKeychain::ReadPasswordJob(service);
|
||||||
|
readCredentialJob->setAutoDelete(true);
|
||||||
|
readCredentialJob->setKey(key);
|
||||||
|
|
||||||
|
QObject::connect
|
||||||
|
(
|
||||||
|
readCredentialJob,
|
||||||
|
&QKeychain::ReadPasswordJob::finished,
|
||||||
|
this,
|
||||||
|
[this, key, &loop, &value](QKeychain::Job *job)
|
||||||
|
{
|
||||||
|
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||||
|
if (j->error() == QKeychain::NoError)
|
||||||
|
{
|
||||||
|
value = j->binaryData();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_errorString = qPrintable(j->errorString());
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
loop.quit();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
readCredentialJob->start();
|
||||||
|
loop.exec();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto QWallet::write(const QString &service, const QString &key, const QByteArray &value) -> QFuture<void>
|
||||||
|
{
|
||||||
|
return QtConcurrent::run
|
||||||
|
(
|
||||||
|
[this, service(service), key(key), value(value)]() -> void
|
||||||
|
{
|
||||||
|
QEventLoop loop;
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
auto writeCredentialJob = new QKeychain::WritePasswordJob(service);
|
||||||
|
writeCredentialJob->setAutoDelete(true);
|
||||||
|
writeCredentialJob->setKey(key);
|
||||||
|
writeCredentialJob->setBinaryData(value);
|
||||||
|
|
||||||
|
QObject::connect
|
||||||
|
(
|
||||||
|
writeCredentialJob,
|
||||||
|
&QKeychain::WritePasswordJob::finished,
|
||||||
|
this,
|
||||||
|
[this, key, &loop, &success](QKeychain::Job *job)
|
||||||
|
{
|
||||||
|
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||||
|
if (j->error() != QKeychain::NoError)
|
||||||
|
{
|
||||||
|
setErrorString(qPrintable(j->errorString()));
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
loop.quit();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
writeCredentialJob->start();
|
||||||
|
loop.exec();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto QWallet::remove(const QString &service, const QString &key) -> QFuture<void>
|
||||||
|
{
|
||||||
|
return QtConcurrent::run
|
||||||
|
(
|
||||||
|
[this, service(service), key(key)]() -> void
|
||||||
|
{
|
||||||
|
QEventLoop loop;
|
||||||
|
bool value;
|
||||||
|
|
||||||
|
auto deleteCredentialJob = new QKeychain::DeletePasswordJob(service);
|
||||||
|
deleteCredentialJob->setAutoDelete(true);
|
||||||
|
deleteCredentialJob->setKey(key);
|
||||||
|
|
||||||
|
QObject::connect
|
||||||
|
(
|
||||||
|
deleteCredentialJob,
|
||||||
|
&QKeychain::DeletePasswordJob::finished,
|
||||||
|
this,
|
||||||
|
[this, key, &loop, &value](QKeychain::Job *job)
|
||||||
|
{
|
||||||
|
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||||
|
if (j->error() != QKeychain::NoError)
|
||||||
|
{
|
||||||
|
m_errorString = qPrintable(j->errorString());
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
loop.quit();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
deleteCredentialJob->start();
|
||||||
|
loop.exec();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWallet::QWallet(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QWallet::~QWallet()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
auto QWallet::errorString() const -> const QString &
|
||||||
|
{
|
||||||
|
return m_errorString;
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
#ifndef QWALLET_H
|
||||||
|
#define QWALLET_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
|
||||||
|
#include "komplex_global.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The QWallet class
|
||||||
|
* QWallet is a QFuture wrapper for QtKeychain to make interaction with the keychain easier
|
||||||
|
*/
|
||||||
|
class KOMPLEX_EXPORT QWallet : QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QWallet(QObject *parent = nullptr);
|
||||||
|
~QWallet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief read
|
||||||
|
* Reads the provided key from the system keychain/wallet
|
||||||
|
* @param service
|
||||||
|
* Service name of the application making the request
|
||||||
|
* @param key
|
||||||
|
* Key to read
|
||||||
|
* @return
|
||||||
|
* QFuture for the binary value
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
auto read(const QString &service, const QString &key) const -> QFuture<QByteArray>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief write
|
||||||
|
* Writes the provided value to the system kaychain/wallet
|
||||||
|
* @param service
|
||||||
|
* Service name of the application making the request
|
||||||
|
* @param key
|
||||||
|
* Key to read
|
||||||
|
* @param value
|
||||||
|
* Binary data to store
|
||||||
|
* @return
|
||||||
|
* QFuture
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
auto write(const QString &service, const QString &key, const QByteArray &value) -> QFuture<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief write
|
||||||
|
* Removes the provided value from the system kaychain/wallet
|
||||||
|
* @param service
|
||||||
|
* Service name of the application making the request
|
||||||
|
* @param key
|
||||||
|
* Key to read
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
auto remove(const QString &service, const QString &key) -> QFuture<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief errorString
|
||||||
|
* String describing the last encountered error.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
auto errorString() const -> const QString &;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief setErrorString
|
||||||
|
* Sets the error string
|
||||||
|
* @param errorString
|
||||||
|
*/
|
||||||
|
auto setErrorString(const QString &errorString) const -> void;
|
||||||
|
|
||||||
|
mutable QString m_errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QWALLET_H
|
||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef SHADERPACK_H
|
#ifndef SHADERPACK_H
|
||||||
#define SHADERPACK_H
|
#define SHADERPACK_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef SHADERTOYMETADATA_H
|
#ifndef SHADERTOYMETADATA_H
|
||||||
#define SHADERTOYMETADATA_H
|
#define SHADERTOYMETADATA_H
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|||||||
@@ -337,6 +337,13 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qsizetype windowSize = this->windowSize();
|
||||||
|
|
||||||
|
if(windowSize == 0)
|
||||||
|
{
|
||||||
|
windowSize = SLIDING_CACHE_WINDOW_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
while (index >= m_windowOffset + (SLIDING_CACHE_WINDOW_SIZE - SLIDING_CACHE_PREFETCH_THRESHOLD))
|
while (index >= m_windowOffset + (SLIDING_CACHE_WINDOW_SIZE - SLIDING_CACHE_PREFETCH_THRESHOLD))
|
||||||
{
|
{
|
||||||
if(!slideForward())
|
if(!slideForward())
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#include "userservices.h"
|
||||||
|
#include "coreservices.h"
|
||||||
|
|
||||||
|
UserServices::UserServices(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
m_wallet = new QWallet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
UserServices::~UserServices()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
auto UserServices::setUserCredentials(const UserCredentials &credentials) -> void
|
||||||
|
{
|
||||||
|
s_userCredentials = credentials;
|
||||||
|
Q_EMIT userCredentialsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto UserServices::errorString() const -> const QString &
|
||||||
|
{
|
||||||
|
return m_errorString;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto UserServices::setErrorString(const QString &errorString) -> void
|
||||||
|
{
|
||||||
|
if (m_errorString == errorString)
|
||||||
|
return;
|
||||||
|
m_errorString = errorString;
|
||||||
|
emit errorStringChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto UserServices::instance() const -> QWeakPointer<UserServices>
|
||||||
|
{
|
||||||
|
if(!s_pointer)
|
||||||
|
{
|
||||||
|
s_instance = new UserServices(QCoreApplication::instance());
|
||||||
|
s_pointer = QSharedPointer<UserServices>
|
||||||
|
(
|
||||||
|
s_instance,
|
||||||
|
&UserServices::deleteLater
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_pointer.toWeakRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto UserServices::userCredentials() -> const UserCredentials &
|
||||||
|
{
|
||||||
|
return s_userCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto UserServices::login(const QString &username, const QByteArray &password) -> QFuture<UserCredentials>
|
||||||
|
{
|
||||||
|
return QtConcurrent::run
|
||||||
|
(
|
||||||
|
[this, username = std::move(username), password = std::move(password)] () -> UserCredentials
|
||||||
|
{
|
||||||
|
QSharedPointer<QNetworkAccessManager> manager = CoreServices::networkAccessManager().toStrongRef();
|
||||||
|
|
||||||
|
if(!manager)
|
||||||
|
{
|
||||||
|
Q_EMIT loginFailed();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkRequest request
|
||||||
|
(
|
||||||
|
QUrl
|
||||||
|
(
|
||||||
|
QStringLiteral("%1/%2/%3").arg
|
||||||
|
(
|
||||||
|
KOMPLEX_API_HOST,
|
||||||
|
KOMPLEX_API_VERSION,
|
||||||
|
KOMPLEX_ENDPOINT_USER_AUTH
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
QJsonObject loginRootObject
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QString("username"),
|
||||||
|
QJsonValue::fromVariant(username.toUtf8())
|
||||||
|
},
|
||||||
|
{
|
||||||
|
QString("password"),
|
||||||
|
QJsonValue::fromVariant(password.toBase64())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QJsonDocument loginDocument(loginRootObject);
|
||||||
|
|
||||||
|
QNetworkReply *reply = manager->post(request, loginDocument.toJson(QJsonDocument::Compact));
|
||||||
|
|
||||||
|
while(!reply->isFinished())
|
||||||
|
{
|
||||||
|
std::chrono::milliseconds(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(reply->error() != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
setErrorString(reply->errorString());
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QJsonDocument document = QJsonDocument::fromJson(data, &parseError);
|
||||||
|
|
||||||
|
if(parseError.error != QJsonParseError::NoError)
|
||||||
|
{
|
||||||
|
setErrorString(parseError.errorString());
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject rootObject;
|
||||||
|
|
||||||
|
if(!rootObject.value("success").toBool())
|
||||||
|
{
|
||||||
|
QJsonObject dataObject = rootObject.value(QStringLiteral("data")).toObject();
|
||||||
|
|
||||||
|
setErrorString
|
||||||
|
(
|
||||||
|
QStringLiteral("Login failure (%1): %2").arg
|
||||||
|
(
|
||||||
|
dataObject.value(QStringLiteral("errorCode")).toString(),
|
||||||
|
dataObject.value(QStringLiteral("message")).toString()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UserCredentials credentials
|
||||||
|
{
|
||||||
|
.username = username.toUtf8(),
|
||||||
|
.sessionToken = rootObject.value
|
||||||
|
(
|
||||||
|
QStringLiteral("jwt")
|
||||||
|
).toString().toUtf8(),
|
||||||
|
.expiry = QDateTime::currentDateTime()
|
||||||
|
};
|
||||||
|
|
||||||
|
setUserCredentials(credentials);
|
||||||
|
|
||||||
|
Q_EMIT loginComplete();
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include "komplex_global.h"
|
||||||
|
#include "qwallet.h"
|
||||||
|
|
||||||
|
struct UserCredentials
|
||||||
|
{
|
||||||
|
QByteArray username;
|
||||||
|
QByteArray sessionToken;
|
||||||
|
QDateTime expiry;
|
||||||
|
|
||||||
|
UserCredentials &operator = (const UserCredentials &other)
|
||||||
|
{
|
||||||
|
username = other.username;
|
||||||
|
sessionToken = other.sessionToken;
|
||||||
|
expiry = other.expiry;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid()
|
||||||
|
{
|
||||||
|
return !username.isEmpty() && username.isValidUtf8() &&
|
||||||
|
!sessionToken.isEmpty() && sessionToken.isValidUtf8();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class KOMPLEX_EXPORT UserServices : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
auto instance() const -> QWeakPointer<UserServices>;
|
||||||
|
static auto userCredentials() -> const UserCredentials &;
|
||||||
|
auto login(const QString &username, const QByteArray &password) -> QFuture<UserCredentials>;
|
||||||
|
|
||||||
|
auto errorString() const -> const QString &;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
auto loginComplete() -> void;
|
||||||
|
auto loginFailed() -> void;
|
||||||
|
auto userCredentialsChanged() -> void;
|
||||||
|
|
||||||
|
auto errorStringChanged() -> void;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline static UserServices *s_instance = nullptr;
|
||||||
|
inline static QSharedPointer<UserServices> s_pointer;
|
||||||
|
|
||||||
|
explicit UserServices(QObject *parent);
|
||||||
|
~UserServices();
|
||||||
|
|
||||||
|
auto setUserCredentials(const UserCredentials &credentials) -> void;
|
||||||
|
auto setErrorString(const QString &errorString) -> void;
|
||||||
|
|
||||||
|
QWallet *m_wallet = nullptr;
|
||||||
|
QString m_errorString;
|
||||||
|
inline static UserCredentials s_userCredentials;
|
||||||
|
Q_PROPERTY(UserCredentials userCredentials READ userCredentials NOTIFY userCredentialsChanged FINAL)
|
||||||
|
Q_PROPERTY(QString errorString READ errorString WRITE setErrorString NOTIFY errorStringChanged FINAL)
|
||||||
|
};
|
||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef VIDEOCACHE_H
|
#ifndef VIDEOCACHE_H
|
||||||
#define VIDEOCACHE_H
|
#define VIDEOCACHE_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef DOWNLOADMANAGER_H
|
#ifndef DOWNLOADMANAGER_H
|
||||||
#define DOWNLOADMANAGER_H
|
#define DOWNLOADMANAGER_H
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,6 @@ auto FeaturedImagesModel::resultsPerPage() const -> qsizetype
|
|||||||
|
|
||||||
auto FeaturedImagesModel::setResultsPerPage(qsizetype resultsPerPage) -> void
|
auto FeaturedImagesModel::setResultsPerPage(qsizetype resultsPerPage) -> void
|
||||||
{
|
{
|
||||||
|
|
||||||
if(m_paginator != nullptr)
|
if(m_paginator != nullptr)
|
||||||
{
|
{
|
||||||
QFuture<void> future = QtConcurrent::run
|
QFuture<void> future = QtConcurrent::run
|
||||||
|
|||||||
@@ -248,7 +248,6 @@ signals:
|
|||||||
auto stateChanged() -> void;
|
auto stateChanged() -> void;
|
||||||
auto errorStringChanged() -> void;
|
auto errorStringChanged() -> void;
|
||||||
auto resultsPerPageChanged() -> void;
|
auto resultsPerPageChanged() -> void;
|
||||||
|
|
||||||
auto pageChanged() -> void;
|
auto pageChanged() -> void;
|
||||||
auto totalResultsChanged() -> void;
|
auto totalResultsChanged() -> void;
|
||||||
auto totalPagesChanged() -> void;
|
auto totalPagesChanged() -> void;
|
||||||
|
|||||||
@@ -205,6 +205,24 @@ auto FeaturedVideosModel::itemModel() const -> VideoItemModel*
|
|||||||
return m_itemModel;
|
return m_itemModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto FeaturedVideosModel::windowSize() const -> qsizetype
|
||||||
|
{
|
||||||
|
if(m_paginator == nullptr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_paginator->windowSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto FeaturedVideosModel::setWindowSize(qsizetype size) -> void
|
||||||
|
{
|
||||||
|
if(m_paginator != nullptr)
|
||||||
|
{
|
||||||
|
m_paginator->setWindowSize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto FeaturedVideosModel::roleNames() const -> QHash<int, QByteArray>
|
auto FeaturedVideosModel::roleNames() const -> QHash<int, QByteArray>
|
||||||
{
|
{
|
||||||
return m_dataRoles;
|
return m_dataRoles;
|
||||||
|
|||||||
@@ -217,6 +217,20 @@ public:
|
|||||||
|
|
||||||
VideoItemModel *itemModel() const;
|
VideoItemModel *itemModel() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief windowSize
|
||||||
|
* Paginator cache size
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
auto windowSize() const -> qsizetype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setWindowSize
|
||||||
|
* Set the paginator cache size
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
auto setWindowSize(qsizetype size) -> void;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief setErrorString
|
* @brief setErrorString
|
||||||
@@ -243,7 +257,7 @@ signals:
|
|||||||
auto stateChanged() -> void;
|
auto stateChanged() -> void;
|
||||||
auto errorStringChanged() -> void;
|
auto errorStringChanged() -> void;
|
||||||
auto resultsPerPageChanged() -> void;
|
auto resultsPerPageChanged() -> void;
|
||||||
|
auto windowSizeChanged() -> void;
|
||||||
auto pageChanged() -> void;
|
auto pageChanged() -> void;
|
||||||
auto totalResultsChanged() -> void;
|
auto totalResultsChanged() -> void;
|
||||||
auto totalPagesChanged() -> void;
|
auto totalPagesChanged() -> void;
|
||||||
@@ -314,6 +328,7 @@ private:
|
|||||||
Q_PROPERTY(qsizetype totalPages READ totalPages NOTIFY totalPagesChanged FINAL)
|
Q_PROPERTY(qsizetype totalPages READ totalPages NOTIFY totalPagesChanged FINAL)
|
||||||
Q_PROPERTY(qsizetype page READ page NOTIFY pageChanged FINAL)
|
Q_PROPERTY(qsizetype page READ page NOTIFY pageChanged FINAL)
|
||||||
Q_PROPERTY(VideoItemModel *itemModel READ itemModel CONSTANT FINAL)
|
Q_PROPERTY(VideoItemModel *itemModel READ itemModel CONSTANT FINAL)
|
||||||
|
Q_PROPERTY(qsizetype windowSize READ windowSize WRITE setWindowSize NOTIFY windowSizeChanged FINAL)
|
||||||
};
|
};
|
||||||
Q_DECLARE_METATYPE(FeaturedVideosModel)
|
Q_DECLARE_METATYPE(FeaturedVideosModel)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Komplex Wallpaper Engine
|
||||||
|
* Copyright (C) 2026 @DigitalArtifex
|
||||||
|
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
#ifndef PACKCOMPILER_H
|
#ifndef PACKCOMPILER_H
|
||||||
#define PACKCOMPILER_H
|
#define PACKCOMPILER_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Komplex Wallpaper Engine
|
|
||||||
* Copyright (C) 2026 @DigitalArtifex
|
|
||||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
#ifndef FEATUREDCUBEMAPSPAGINATOR_H
|
|
||||||
#define FEATUREDCUBEMAPSPAGINATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "wallpaperpaginator.h"
|
|
||||||
|
|
||||||
class KOMPLEX_EXPORT FeaturedCubemapsPaginator : public WallpaperPaginator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit FeaturedCubemapsPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
|
||||||
{
|
|
||||||
setUri(
|
|
||||||
QString::fromUtf8(KOMPLEX_ENDPOINT_CUBEMAPS_FEATURED)
|
|
||||||
);
|
|
||||||
|
|
||||||
controller()->setWindowSize(20);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FEATUREDCUBEMAPSPAGINATOR_H
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Komplex Wallpaper Engine
|
|
||||||
* Copyright (C) 2026 @DigitalArtifex
|
|
||||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
#ifndef FEATUREDSHADERSPAGINATOR_H
|
|
||||||
#define FEATUREDSHADERSPAGINATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "wallpaperpaginator.h"
|
|
||||||
|
|
||||||
class KOMPLEX_EXPORT FeaturedShadersPaginator : public WallpaperPaginator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit FeaturedShadersPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
|
||||||
{
|
|
||||||
setUri(
|
|
||||||
QString::fromUtf8(KOMPLEX_ENDPOINT_SHADERS_FEATURED)
|
|
||||||
);
|
|
||||||
|
|
||||||
controller()->setWindowSize(20);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FEATUREDSHADERSPAGINATOR_H
|
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/paginator.h"
|
|
||||||
#include "common/imagecache.h"
|
#include "common/imagecache.h"
|
||||||
#include "common/coreservices.h"
|
#include "common/coreservices.h"
|
||||||
|
#include "paginator.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The ImagePaginator class
|
* @brief The ImagePaginator class
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Komplex Wallpaper Engine
|
|
||||||
* Copyright (C) 2026 @DigitalArtifex
|
|
||||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
#ifndef NEWESTCUBEMAPSPAGINATOR_H
|
|
||||||
#define NEWESTCUBEMAPSPAGINATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "wallpaperpaginator.h"
|
|
||||||
|
|
||||||
class KOMPLEX_EXPORT NewestCubemapsPaginator : public WallpaperPaginator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit NewestCubemapsPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
|
||||||
{
|
|
||||||
setUri(
|
|
||||||
QString::fromUtf8(KOMPLEX_ENDPOINT_CUBEMAPS_NEWEST)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // NEWESTCUBEMAPSPAGINATOR_H
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Komplex Wallpaper Engine
|
|
||||||
* Copyright (C) 2026 @DigitalArtifex
|
|
||||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
#ifndef NEWESTSHADERSPAGINATOR_H
|
|
||||||
#define NEWESTSHADERSPAGINATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "wallpaperpaginator.h"
|
|
||||||
|
|
||||||
class KOMPLEX_EXPORT NewestShadersPaginator : public WallpaperPaginator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit NewestShadersPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
|
||||||
{
|
|
||||||
setUri(
|
|
||||||
QString::fromUtf8(KOMPLEX_ENDPOINT_SHADERS_NEWEST)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // NEWESTSHADERSPAGINATOR_H
|
|
||||||
@@ -27,8 +27,8 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonParseError>
|
#include <QJsonParseError>
|
||||||
|
|
||||||
#include "komplex_global.h"
|
#include "common/komplex_global.h"
|
||||||
#include "slidingcachecontroller.h"
|
#include "common/slidingcachecontroller.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The PaginationNotifier class
|
* @brief The PaginationNotifier class
|
||||||
@@ -120,6 +120,7 @@ public:
|
|||||||
* @brief resultsPerPage
|
* @brief resultsPerPage
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto resultsPerPage() const -> qsizetype
|
auto resultsPerPage() const -> qsizetype
|
||||||
{
|
{
|
||||||
return m_resultsPerPage;
|
return m_resultsPerPage;
|
||||||
@@ -204,6 +205,7 @@ public:
|
|||||||
* @brief data
|
* @brief data
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto data() const -> const QList<T>
|
auto data() const -> const QList<T>
|
||||||
{
|
{
|
||||||
if(boundaryCheck(m_resultsPerPage))
|
if(boundaryCheck(m_resultsPerPage))
|
||||||
@@ -219,6 +221,7 @@ public:
|
|||||||
* @brief count
|
* @brief count
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto count() const -> qsizetype
|
auto count() const -> qsizetype
|
||||||
{
|
{
|
||||||
if(m_offset == nullsize)
|
if(m_offset == nullsize)
|
||||||
@@ -240,6 +243,7 @@ public:
|
|||||||
* @param index
|
* @param index
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto at(qsizetype index) const -> const T&
|
auto at(qsizetype index) const -> const T&
|
||||||
{
|
{
|
||||||
return m_cacheController.at(m_offset + index);
|
return m_cacheController.at(m_offset + index);
|
||||||
@@ -251,6 +255,7 @@ public:
|
|||||||
* The total number of results as reported by the controller
|
* The total number of results as reported by the controller
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto totalResults() const -> qsizetype
|
auto totalResults() const -> qsizetype
|
||||||
{
|
{
|
||||||
return m_cacheController.totalCount();
|
return m_cacheController.totalCount();
|
||||||
@@ -261,6 +266,7 @@ public:
|
|||||||
* Calculates the current page
|
* Calculates the current page
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto page() const -> qsizetype
|
auto page() const -> qsizetype
|
||||||
{
|
{
|
||||||
return std::floor(
|
return std::floor(
|
||||||
@@ -273,6 +279,7 @@ public:
|
|||||||
* Calculates the total number of pages available
|
* Calculates the total number of pages available
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
auto totalPages() const -> qsizetype
|
auto totalPages() const -> qsizetype
|
||||||
{
|
{
|
||||||
return std::ceil(
|
return std::ceil(
|
||||||
@@ -280,6 +287,22 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setWindowSize
|
||||||
|
* Sets the controller window size
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
auto setWindowSize(qsizetype size) -> void
|
||||||
|
{
|
||||||
|
m_cacheController.setWindowSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
auto windowSize() const -> qsizetype
|
||||||
|
{
|
||||||
|
return m_cacheController.windowSize();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
auto queryable() const -> bool
|
auto queryable() const -> bool
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Komplex Wallpaper Engine
|
|
||||||
* Copyright (C) 2026 @DigitalArtifex
|
|
||||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
#ifndef SEARCHCUBEMAPSPAGINATOR_H
|
|
||||||
#define SEARCHCUBEMAPSPAGINATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "wallpaperpaginator.h"
|
|
||||||
|
|
||||||
class KOMPLEX_EXPORT SearchCubemapsPaginator : public WallpaperPaginator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SearchCubemapsPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
|
||||||
{
|
|
||||||
setUri(
|
|
||||||
QString::fromUtf8(KOMPLEX_ENDPOINT_CUBEMAPS_SEARCH)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SEARCHCUBEMAPSPAGINATOR_H
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Komplex Wallpaper Engine
|
|
||||||
* Copyright (C) 2026 @DigitalArtifex
|
|
||||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
#ifndef SEARCHSHADERSPAGINATOR_H
|
|
||||||
#define SEARCHSHADERSPAGINATOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "wallpaperpaginator.h"
|
|
||||||
|
|
||||||
class KOMPLEX_EXPORT SearchShadersPaginator : public WallpaperPaginator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SearchShadersPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
|
||||||
{
|
|
||||||
setUri(
|
|
||||||
QString::fromUtf8(KOMPLEX_ENDPOINT_SHADERS_SEARCH)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SEARCHSHADERSPAGINATOR_H
|
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/paginator.h"
|
|
||||||
#include "common/videocache.h"
|
#include "common/videocache.h"
|
||||||
#include "common/coreservices.h"
|
#include "common/coreservices.h"
|
||||||
|
#include "paginator.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The VideoPaginator class
|
* @brief The VideoPaginator class
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/paginator.h"
|
|
||||||
#include "common/wallpapercache.h"
|
#include "common/wallpapercache.h"
|
||||||
#include "common/coreservices.h"
|
#include "common/coreservices.h"
|
||||||
|
#include "paginator.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The WallpaperPaginator class
|
* @brief The WallpaperPaginator class
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Komplex AI Usage Policy (Draft)
|
||||||
|
|
||||||
|
| Applies To | Effective Date | Revision Date |
|
||||||
|
| ------ | --- | --- |
|
||||||
|
| Internal & Contributors | August 12, 2026 | August 12, 2026 |
|
||||||
|
|
||||||
|
This policy may be updated in the future. The updated date will be reflected on this file.
|
||||||
|
|
||||||
|
## Applies to
|
||||||
|
This policy applies to contributors to Komplex and all associated repositories under the Komplex project umbrella.
|
||||||
|
It outlines how artificial intelligence (AI) tools and systems may be used responsibly in the context of this project.
|
||||||
|
|
||||||
|
Our goal is to encourage innovation and productivity while protecting our users, contributors, community, and the integrity of our open source projects. We want to enable employees and contractors to understand what is, and is not, acceptable, and enable the wider community to understand and have trust in how we operate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
This policy applies to any use of AI tools that can materially influence repository outputs, including:
|
||||||
|
- Generative AI (e.g., image, text and code assistants)
|
||||||
|
- AI-assisted development tools (e.g., code completion and refactoring assistants)
|
||||||
|
- Tools that can generate diffs, patches, or substantial edits
|
||||||
|
- Tools that can draft or summarize issues, bug reports, or diagnostics
|
||||||
|
- Tools that can generate translations files and reports
|
||||||
|
- Agenic automation of project tasks
|
||||||
|
|
||||||
|
## Guiding principles
|
||||||
|
1. Human responsibility: Humans remain accountable for decisions, code, and outputs.
|
||||||
|
2. Transparency: If AI materially contributes to the output, disclose it clearly and concisely in pull requests, commit messages, or accompanying documentation where appropriate.
|
||||||
|
3. Safety and quality: AI-generated suggestions must be reviewed and validated by humans before being adopted.
|
||||||
|
4. Integrity and authorship: AI must not be used to bypass authorship, review, or verification requirements.
|
||||||
|
5. Community and ecosystem trust: AI must not be used to mislead reviewers or circumvent project quality standards.
|
||||||
|
|
||||||
|
## Prohibited uses of AI
|
||||||
|
AI tools may not be used for:
|
||||||
|
- Agentic generation of code, patches, diffs, or substantial edits intended to become part of the repository.
|
||||||
|
- Produce a complete file replacement, complete module, or end-to-end implementation of a feature.
|
||||||
|
- Generate bug report details or where the bug report content would be primarily AI-authored.
|
||||||
|
|
||||||
|
### “Agentic” Automation
|
||||||
|
You may not use AI tools that can take actions on your behalf without intentional invocation. For example browsing, running commands, editing files and repositories, or opening pull requests automatically.
|
||||||
|
|
||||||
|
### Misrepresentation and undisclosed material contribution
|
||||||
|
Misrepresentation of AI-assisted work as human-authored where disclosure is required by this policy is subject to enforcement policies.
|
||||||
|
|
||||||
|
## Acceptable uses of AI
|
||||||
|
AI tools may be used to:
|
||||||
|
- Assist with writing or refactoring code, provided the resulting code changes are implemented, reviewed and verified by a human contributor.
|
||||||
|
- Generating support documentation that is based on human-authored doxygen comments.
|
||||||
|
- Help with debugging by reviewing code, generating hypotheses and proposing targeted experiments to identify root cause in existing code.
|
||||||
|
- Translate a human-authored bug report into another language, or reformat a human-authored report for clarity.
|
||||||
|
- Translate and generate application translation files (including strings and localized resources), subject to human review.
|
||||||
|
- Generate images and icons when used only as placeholders, with the intention to replace them with project-approved assets.
|
||||||
|
|
||||||
|
All acceptable uses are subject to change.
|
||||||
|
|
||||||
|
### Bug Reports
|
||||||
|
You must write the factual and investigative aspects of bug reports yourself.
|
||||||
|
For reporting AI may be used only to:
|
||||||
|
- Reformat or rewrite for clarity while preserving the original factual content
|
||||||
|
- Help translate the human-authored report into a different structure, language, or style
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
- You must implement changes yourself.
|
||||||
|
- You must verify changes via tests, linting/type checks, and/or manual validation consistent with project standards.
|
||||||
|
- Do not copy/paste AI-generated patches as the final solution.
|
||||||
|
|
||||||
|
### Media placeholders
|
||||||
|
AI-generated images/icons may be used only as placeholders with the intention to replace them.
|
||||||
|
|
||||||
|
- Placeholder files must be clearly marked in the AI_ASSETS file.
|
||||||
|
- Placeholders should be replaced when possible, but may require artist contribution and may not always be immediately feasible.
|
||||||
|
|
||||||
|
### Qt Translation Files
|
||||||
|
- AI may be used to generate translation files.
|
||||||
|
- AI generated translation files must be noted in AI_ASSETS
|
||||||
|
|
||||||
|
## Transparency and disclosure
|
||||||
|
When disclosing the use of AI generated assets, you must disclose:
|
||||||
|
- The file name and path relative to the project root
|
||||||
|
- Which allowed category was used (e.g., translation file generation, bug report translation, placeholder media)
|
||||||
|
- What tool/version was used for generation
|
||||||
|
- Optionally can include a short message about the asset
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
Failure to comply with this policy may result in:
|
||||||
|
|
||||||
|
- Requesting changes to bring contributions back into compliance
|
||||||
|
- Rejection of pull requests
|
||||||
|
- Removal of contributor privileges where applicable
|
||||||
|
- Escalation to maintainers for further action
|
||||||
|
|
||||||
|
## Policy values statement
|
||||||
|
AI is a tool, not a substitute for responsibility. In Komplex, AI may be used to increase productivity and assist with debugging, review, translation, and placeholders, but humans must remain accountable for the correctness, safety, and authorship of repository outputs.
|
||||||
Reference in New Issue
Block a user