This commit is contained in:
ItsLemmy
2025-11-15 15:57:05 -05:00
parent 3685b8c9f7
commit 131d3a095e
4 changed files with 299 additions and 274 deletions
+1 -1
View File
@@ -739,7 +739,7 @@ Singleton {
if (parsed.general && parsed.general.dimDesktop === true) { if (parsed.general && parsed.general.dimDesktop === true) {
// Check if dimmerOpacity exists in raw JSON (not adapter default) // Check if dimmerOpacity exists in raw JSON (not adapter default)
var dimmerOpacityInJson = parsed.general.dimmerOpacity var dimmerOpacityInJson = parsed.general.dimmerOpacity
// If dimmerOpacity wasn't explicitly set in JSON or was 0, set it to 0.8 (80% dimming) // If dimmerOpacity wasn't explicitly set in JSON or was 0, set it to 0.8 (80% dimming)
if (dimmerOpacityInJson === undefined || dimmerOpacityInJson === 0) { if (dimmerOpacityInJson === undefined || dimmerOpacityInJson === 0) {
adapter.general.dimmerOpacity = 0.8 adapter.general.dimmerOpacity = 0.8
@@ -27,7 +27,7 @@ Popup {
} }
return 0 return 0
} }
y: { y: {
if (anchorItem) { if (anchorItem) {
var itemPos = anchorItem.mapToItem(parent, 0, 0) var itemPos = anchorItem.mapToItem(parent, 0, 0)
@@ -43,19 +43,19 @@ Popup {
anchorItem = item anchorItem = item
open() open()
Qt.callLater(() => { Qt.callLater(() => {
// Try to focus the first input if available // Try to focus the first input if available
if (resolutionWidthInput.inputItem) { if (resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.forceActiveFocus() resolutionWidthInput.inputItem.forceActiveFocus()
} }
}) })
} }
onOpened: { onOpened: {
Qt.callLater(() => { Qt.callLater(() => {
if (resolutionWidthInput.inputItem) { if (resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.forceActiveFocus() resolutionWidthInput.inputItem.forceActiveFocus()
} }
}) })
} }
function hide() { function hide() {
@@ -153,22 +153,33 @@ Popup {
NComboBox { NComboBox {
id: sortingComboBox id: sortingComboBox
Layout.fillWidth: true Layout.fillWidth: true
model: [ model: [{
{ "key": "date_added", "name": I18n.tr("wallpaper.panel.sorting.date_added") }, "key": "date_added",
{ "key": "relevance", "name": I18n.tr("wallpaper.panel.sorting.relevance") }, "name": I18n.tr("wallpaper.panel.sorting.date_added")
{ "key": "random", "name": I18n.tr("wallpaper.panel.sorting.random") }, }, {
{ "key": "views", "name": I18n.tr("wallpaper.panel.sorting.views") }, "key": "relevance",
{ "key": "favorites", "name": I18n.tr("wallpaper.panel.sorting.favorites") }, "name": I18n.tr("wallpaper.panel.sorting.relevance")
{ "key": "toplist", "name": I18n.tr("wallpaper.panel.sorting.toplist") } }, {
] "key": "random",
"name": I18n.tr("wallpaper.panel.sorting.random")
}, {
"key": "views",
"name": I18n.tr("wallpaper.panel.sorting.views")
}, {
"key": "favorites",
"name": I18n.tr("wallpaper.panel.sorting.favorites")
}, {
"key": "toplist",
"name": I18n.tr("wallpaper.panel.sorting.toplist")
}]
currentKey: Settings.data.wallpaper.wallhavenSorting || "date_added" currentKey: Settings.data.wallpaper.wallhavenSorting || "date_added"
onSelected: key => { onSelected: key => {
Settings.data.wallpaper.wallhavenSorting = key Settings.data.wallpaper.wallhavenSorting = key
if (typeof WallhavenService !== "undefined") { if (typeof WallhavenService !== "undefined") {
WallhavenService.sorting = key WallhavenService.sorting = key
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1) WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1)
} }
} }
} }
} }
@@ -188,18 +199,21 @@ Popup {
NComboBox { NComboBox {
id: orderComboBox id: orderComboBox
Layout.fillWidth: true Layout.fillWidth: true
model: [ model: [{
{ "key": "desc", "name": I18n.tr("wallpaper.panel.order.desc") }, "key": "desc",
{ "key": "asc", "name": I18n.tr("wallpaper.panel.order.asc") } "name": I18n.tr("wallpaper.panel.order.desc")
] }, {
"key": "asc",
"name": I18n.tr("wallpaper.panel.order.asc")
}]
currentKey: Settings.data.wallpaper.wallhavenOrder || "desc" currentKey: Settings.data.wallpaper.wallhavenOrder || "desc"
onSelected: key => { onSelected: key => {
Settings.data.wallpaper.wallhavenOrder = key Settings.data.wallpaper.wallhavenOrder = key
if (typeof WallhavenService !== "undefined") { if (typeof WallhavenService !== "undefined") {
WallhavenService.order = key WallhavenService.order = key
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1) WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1)
} }
} }
} }
} }
@@ -218,19 +232,24 @@ Popup {
NComboBox { NComboBox {
id: purityComboBox id: purityComboBox
Layout.fillWidth: true Layout.fillWidth: true
model: [ model: [{
{ "key": "111", "name": I18n.tr("wallpaper.panel.purity.all") }, "key": "111",
{ "key": "100", "name": I18n.tr("wallpaper.panel.purity.sfw") }, "name": I18n.tr("wallpaper.panel.purity.all")
{ "key": "010", "name": I18n.tr("wallpaper.panel.purity.sketchy") } }, {
] "key": "100",
"name": I18n.tr("wallpaper.panel.purity.sfw")
}, {
"key": "010",
"name": I18n.tr("wallpaper.panel.purity.sketchy")
}]
currentKey: Settings.data.wallpaper.wallhavenPurity currentKey: Settings.data.wallpaper.wallhavenPurity
onSelected: key => { onSelected: key => {
Settings.data.wallpaper.wallhavenPurity = key Settings.data.wallpaper.wallhavenPurity = key
if (typeof WallhavenService !== "undefined") { if (typeof WallhavenService !== "undefined") {
WallhavenService.purity = key WallhavenService.purity = key
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1) WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1)
} }
} }
} }
} }
@@ -440,8 +459,8 @@ Popup {
property bool checked: false property bool checked: false
signal toggled(bool checked) signal toggled(bool checked)
onToggled: checked => { onToggled: checked => {
categoriesRow.updateCategories(checked, categoriesRow.getCategoryValue(1), categoriesRow.getCategoryValue(2)) categoriesRow.updateCategories(checked, categoriesRow.getCategoryValue(1), categoriesRow.getCategoryValue(2))
} }
} }
QtObject { QtObject {
@@ -449,8 +468,8 @@ Popup {
property bool checked: false property bool checked: false
signal toggled(bool checked) signal toggled(bool checked)
onToggled: checked => { onToggled: checked => {
categoriesRow.updateCategories(categoriesRow.getCategoryValue(0), checked, categoriesRow.getCategoryValue(2)) categoriesRow.updateCategories(categoriesRow.getCategoryValue(0), checked, categoriesRow.getCategoryValue(2))
} }
} }
QtObject { QtObject {
@@ -458,8 +477,8 @@ Popup {
property bool checked: false property bool checked: false
signal toggled(bool checked) signal toggled(bool checked)
onToggled: checked => { onToggled: checked => {
categoriesRow.updateCategories(categoriesRow.getCategoryValue(0), categoriesRow.getCategoryValue(1), checked) categoriesRow.updateCategories(categoriesRow.getCategoryValue(0), categoriesRow.getCategoryValue(1), checked)
} }
} }
} }
} }
@@ -489,12 +508,15 @@ Popup {
NComboBox { NComboBox {
id: resolutionModeComboBox id: resolutionModeComboBox
Layout.fillWidth: true Layout.fillWidth: true
model: [ model: [{
{ "key": "atleast", "name": I18n.tr("wallpaper.panel.resolution.atleast") }, "key": "atleast",
{ "key": "exact", "name": I18n.tr("wallpaper.panel.resolution.exact") } "name": I18n.tr("wallpaper.panel.resolution.atleast")
] }, {
"key": "exact",
"name": I18n.tr("wallpaper.panel.resolution.exact")
}]
currentKey: Settings.data.wallpaper.wallhavenResolutionMode || "atleast" currentKey: Settings.data.wallpaper.wallhavenResolutionMode || "atleast"
Connections { Connections {
target: Settings.data.wallpaper target: Settings.data.wallpaper
function onWallhavenResolutionModeChanged() { function onWallhavenResolutionModeChanged() {
@@ -503,11 +525,11 @@ Popup {
} }
} }
} }
onSelected: key => { onSelected: key => {
Settings.data.wallpaper.wallhavenResolutionMode = key Settings.data.wallpaper.wallhavenResolutionMode = key
updateResolution(false) updateResolution(false)
} }
} }
} }
@@ -521,7 +543,7 @@ Popup {
placeholderText: "Width" placeholderText: "Width"
inputMethodHints: Qt.ImhDigitsOnly inputMethodHints: Qt.ImhDigitsOnly
text: Settings.data.wallpaper.wallhavenResolutionWidth || "" text: Settings.data.wallpaper.wallhavenResolutionWidth || ""
Component.onCompleted: { Component.onCompleted: {
if (resolutionWidthInput.inputItem) { if (resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.focusPolicy = Qt.StrongFocus resolutionWidthInput.inputItem.focusPolicy = Qt.StrongFocus
@@ -529,14 +551,14 @@ Popup {
resolutionWidthInput.inputItem.activeFocusOnPress = true resolutionWidthInput.inputItem.activeFocusOnPress = true
} }
} }
// Ensure focus when clicked // Ensure focus when clicked
onActiveFocusChanged: { onActiveFocusChanged: {
if (activeFocus && resolutionWidthInput.inputItem) { if (activeFocus && resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.forceActiveFocus() resolutionWidthInput.inputItem.forceActiveFocus()
} }
} }
Connections { Connections {
target: Settings.data.wallpaper target: Settings.data.wallpaper
function onWallhavenResolutionWidthChanged() { function onWallhavenResolutionWidthChanged() {
@@ -545,7 +567,7 @@ Popup {
} }
} }
} }
onEditingFinished: { onEditingFinished: {
Settings.data.wallpaper.wallhavenResolutionWidth = text Settings.data.wallpaper.wallhavenResolutionWidth = text
updateResolution(false) updateResolution(false)
@@ -565,21 +587,21 @@ Popup {
placeholderText: "Height" placeholderText: "Height"
inputMethodHints: Qt.ImhDigitsOnly inputMethodHints: Qt.ImhDigitsOnly
text: Settings.data.wallpaper.wallhavenResolutionHeight || "" text: Settings.data.wallpaper.wallhavenResolutionHeight || ""
Component.onCompleted: { Component.onCompleted: {
if (resolutionHeightInput.inputItem) { if (resolutionHeightInput.inputItem) {
resolutionHeightInput.inputItem.focusPolicy = Qt.StrongFocus resolutionHeightInput.inputItem.focusPolicy = Qt.StrongFocus
resolutionHeightInput.inputItem.activeFocusOnPress = true resolutionHeightInput.inputItem.activeFocusOnPress = true
} }
} }
// Ensure focus when clicked // Ensure focus when clicked
onActiveFocusChanged: { onActiveFocusChanged: {
if (activeFocus && resolutionHeightInput.inputItem) { if (activeFocus && resolutionHeightInput.inputItem) {
resolutionHeightInput.inputItem.forceActiveFocus() resolutionHeightInput.inputItem.forceActiveFocus()
} }
} }
Connections { Connections {
target: Settings.data.wallpaper target: Settings.data.wallpaper
function onWallhavenResolutionHeightChanged() { function onWallhavenResolutionHeightChanged() {
@@ -588,7 +610,7 @@ Popup {
} }
} }
} }
onEditingFinished: { onEditingFinished: {
Settings.data.wallpaper.wallhavenResolutionHeight = text Settings.data.wallpaper.wallhavenResolutionHeight = text
updateResolution(false) updateResolution(false)
@@ -614,20 +636,19 @@ Popup {
WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity
WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting
WallhavenService.order = Settings.data.wallpaper.wallhavenOrder WallhavenService.order = Settings.data.wallpaper.wallhavenOrder
// Update resolution settings (without triggering search) // Update resolution settings (without triggering search)
updateResolution(false) updateResolution(false)
// Refresh the wallpaper search with current settings // Refresh the wallpaper search with current settings
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1) WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1)
// Close the popup after applying (delay to prevent click propagation) // Close the popup after applying (delay to prevent click propagation)
Qt.callLater(() => { Qt.callLater(() => {
root.hide() root.hide()
}) })
} }
} }
} }
} }
} }
+185 -183
View File
@@ -278,7 +278,7 @@ SmartPanel {
id: searchInput id: searchInput
placeholderText: Settings.data.wallpaper.useWallhaven ? I18n.tr("placeholders.search-wallhaven") : I18n.tr("placeholders.search-wallpapers") placeholderText: Settings.data.wallpaper.useWallhaven ? I18n.tr("placeholders.search-wallhaven") : I18n.tr("placeholders.search-wallpapers")
Layout.fillWidth: true Layout.fillWidth: true
property bool initializing: true property bool initializing: true
Component.onCompleted: { Component.onCompleted: {
// Initialize text based on current mode // Initialize text based on current mode
@@ -292,11 +292,11 @@ SmartPanel {
searchInput.inputItem.forceActiveFocus() searchInput.inputItem.forceActiveFocus()
} }
// Mark initialization as complete after a short delay // Mark initialization as complete after a short delay
Qt.callLater(function() { Qt.callLater(function () {
searchInput.initializing = false searchInput.initializing = false
}) })
} }
Connections { Connections {
target: Settings.data.wallpaper target: Settings.data.wallpaper
function onUseWallhavenChanged() { function onUseWallhavenChanged() {
@@ -375,50 +375,53 @@ SmartPanel {
NComboBox { NComboBox {
id: sourceComboBox id: sourceComboBox
Layout.fillWidth: true Layout.fillWidth: true
model: [ model: [{
{ "key": "local", "name": I18n.tr("wallpaper.panel.source.local") }, "key": "local",
{ "key": "wallhaven", "name": I18n.tr("wallpaper.panel.source.wallhaven") } "name": I18n.tr("wallpaper.panel.source.local")
] }, {
"key": "wallhaven",
"name": I18n.tr("wallpaper.panel.source.wallhaven")
}]
currentKey: Settings.data.wallpaper.useWallhaven ? "wallhaven" : "local" currentKey: Settings.data.wallpaper.useWallhaven ? "wallhaven" : "local"
property bool skipNextSelected: false property bool skipNextSelected: false
Component.onCompleted: { Component.onCompleted: {
// Skip the first onSelected if it fires during initialization // Skip the first onSelected if it fires during initialization
skipNextSelected = true skipNextSelected = true
Qt.callLater(function() { Qt.callLater(function () {
skipNextSelected = false skipNextSelected = false
}) })
} }
onSelected: key => { onSelected: key => {
if (skipNextSelected) { if (skipNextSelected) {
return return
} }
var useWallhaven = (key === "wallhaven") var useWallhaven = (key === "wallhaven")
Settings.data.wallpaper.useWallhaven = useWallhaven Settings.data.wallpaper.useWallhaven = useWallhaven
// Update search input text based on mode // Update search input text based on mode
if (useWallhaven) { if (useWallhaven) {
searchInput.text = Settings.data.wallpaper.wallhavenQuery || "" searchInput.text = Settings.data.wallpaper.wallhavenQuery || ""
} else { } else {
searchInput.text = wallpaperPanel.filterText || "" searchInput.text = wallpaperPanel.filterText || ""
} }
if (useWallhaven && typeof WallhavenService !== "undefined") { if (useWallhaven && typeof WallhavenService !== "undefined") {
// Update service properties when switching to Wallhaven // Update service properties when switching to Wallhaven
// Don't search here - Component.onCompleted will handle it when the component is created // Don't search here - Component.onCompleted will handle it when the component is created
// This prevents duplicate searches // This prevents duplicate searches
WallhavenService.categories = Settings.data.wallpaper.wallhavenCategories WallhavenService.categories = Settings.data.wallpaper.wallhavenCategories
WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity
WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting
WallhavenService.order = Settings.data.wallpaper.wallhavenOrder WallhavenService.order = Settings.data.wallpaper.wallhavenOrder
// Update resolution settings // Update resolution settings
wallpaperPanel.updateWallhavenResolution() wallpaperPanel.updateWallhavenResolution()
// If the view is already initialized, trigger a new search when switching to it // If the view is already initialized, trigger a new search when switching to it
if (wallhavenView && wallhavenView.initialized && !WallhavenService.fetching) { if (wallhavenView && wallhavenView.initialized && !WallhavenService.fetching) {
wallhavenView.loading = true wallhavenView.loading = true
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1) WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1)
} }
} }
} }
} }
// Settings button (only visible for Wallhaven) // Settings button (only visible for Wallhaven)
@@ -862,7 +865,7 @@ SmartPanel {
initialized = true initialized = true
return return
} }
// We're the first one - claim the search // We're the first one - claim the search
initialized = true initialized = true
WallhavenService.initialSearchScheduled = true WallhavenService.initialSearchScheduled = true
@@ -870,7 +873,7 @@ SmartPanel {
WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity
WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting
WallhavenService.order = Settings.data.wallpaper.wallhavenOrder WallhavenService.order = Settings.data.wallpaper.wallhavenOrder
// Initialize resolution settings // Initialize resolution settings
var width = Settings.data.wallpaper.wallhavenResolutionWidth || "" var width = Settings.data.wallpaper.wallhavenResolutionWidth || ""
var height = Settings.data.wallpaper.wallhavenResolutionHeight || "" var height = Settings.data.wallpaper.wallhavenResolutionHeight || ""
@@ -888,14 +891,13 @@ SmartPanel {
WallhavenService.minResolution = "" WallhavenService.minResolution = ""
WallhavenService.resolutions = "" WallhavenService.resolutions = ""
} }
// Now check if we can actually search (fetching check is in WallhavenService.search) // Now check if we can actually search (fetching check is in WallhavenService.search)
loading = true loading = true
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1) WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1)
} }
} }
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: Style.marginM spacing: Style.marginM
@@ -918,182 +920,182 @@ SmartPanel {
model: wallpapers || [] model: wallpapers || []
property int columns: (screen.width > 1920) ? 5 : 4 property int columns: (screen.width > 1920) ? 5 : 4
property int itemSize: cellWidth property int itemSize: cellWidth
cellWidth: Math.floor((width - leftMargin - rightMargin) / columns) cellWidth: Math.floor((width - leftMargin - rightMargin) / columns)
cellHeight: Math.floor(itemSize * 0.7) + Style.marginXS + Style.fontSizeXS + Style.marginM cellHeight: Math.floor(itemSize * 0.7) + Style.marginXS + Style.fontSizeXS + Style.marginM
leftMargin: Style.marginS leftMargin: Style.marginS
rightMargin: Style.marginS rightMargin: Style.marginS
topMargin: Style.marginS topMargin: Style.marginS
bottomMargin: Style.marginS bottomMargin: Style.marginS
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (currentIndex >= 0) { if (currentIndex >= 0) {
let row = Math.floor(currentIndex / columns) let row = Math.floor(currentIndex / columns)
let itemY = row * cellHeight let itemY = row * cellHeight
let viewportTop = contentY let viewportTop = contentY
let viewportBottom = viewportTop + height let viewportBottom = viewportTop + height
if (itemY < viewportTop) { if (itemY < viewportTop) {
contentY = Math.max(0, itemY - cellHeight) contentY = Math.max(0, itemY - cellHeight)
} else if (itemY + cellHeight > viewportBottom) { } else if (itemY + cellHeight > viewportBottom) {
contentY = itemY + cellHeight - height + cellHeight contentY = itemY + cellHeight - height + cellHeight
}
} }
} }
}
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Space) { if (event.key === Qt.Key_Return || event.key === Qt.Key_Space) {
if (currentIndex >= 0 && currentIndex < wallpapers.length) { if (currentIndex >= 0 && currentIndex < wallpapers.length) {
let wallpaper = wallpapers[currentIndex] let wallpaper = wallpapers[currentIndex]
if (typeof WallhavenService !== "undefined") { if (typeof WallhavenService !== "undefined") {
WallhavenService.downloadWallpaper(wallpaper, function (success, localPath) { WallhavenService.downloadWallpaper(wallpaper, function (success, localPath) {
if (success) { if (success) {
if (Settings.data.wallpaper.setWallpaperOnAllMonitors) { if (Settings.data.wallpaper.setWallpaperOnAllMonitors) {
WallpaperService.changeWallpaper(localPath, undefined) WallpaperService.changeWallpaper(localPath, undefined)
} else { } else {
WallpaperService.changeWallpaper(localPath, screen.name) WallpaperService.changeWallpaper(localPath, screen.name)
}
} }
} })
}) }
} }
event.accepted = true
} }
event.accepted = true
} }
}
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded policy: ScrollBar.AsNeeded
parent: wallhavenGridView parent: wallhavenGridView
x: wallhavenGridView.mirrored ? 0 : wallhavenGridView.width - width x: wallhavenGridView.mirrored ? 0 : wallhavenGridView.width - width
y: 0 y: 0
height: wallhavenGridView.height height: wallhavenGridView.height
property color handleColor: Qt.alpha(Color.mHover, 0.8) property color handleColor: Qt.alpha(Color.mHover, 0.8)
property color handleHoverColor: handleColor property color handleHoverColor: handleColor
property color handlePressedColor: handleColor property color handlePressedColor: handleColor
property real handleWidth: 6 property real handleWidth: 6
property real handleRadius: Style.radiusM property real handleRadius: Style.radiusM
contentItem: Rectangle { contentItem: Rectangle {
implicitWidth: parent.handleWidth implicitWidth: parent.handleWidth
implicitHeight: 100 implicitHeight: 100
radius: parent.handleRadius radius: parent.handleRadius
color: parent.pressed ? parent.handlePressedColor : parent.hovered ? parent.handleHoverColor : parent.handleColor color: parent.pressed ? parent.handlePressedColor : parent.hovered ? parent.handleHoverColor : parent.handleColor
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1.0 : 0.0 opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1.0 : 0.0
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: Style.animationFast duration: Style.animationFast
}
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
} }
} }
Behavior on color { background: Rectangle {
ColorAnimation { implicitWidth: parent.handleWidth
duration: Style.animationFast implicitHeight: 100
}
}
}
background: Rectangle {
implicitWidth: parent.handleWidth
implicitHeight: 100
color: Color.transparent
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0.0
radius: parent.handleRadius / 2
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
}
}
delegate: ColumnLayout {
id: wallhavenItem
required property var modelData
required property int index
property string thumbnailUrl: (modelData && typeof WallhavenService !== "undefined") ? WallhavenService.getThumbnailUrl(modelData, "large") : ""
property string wallpaperId: (modelData && modelData.id) ? modelData.id : ""
width: wallhavenGridView.itemSize
spacing: Style.marginXS
Rectangle {
id: imageContainer
Layout.fillWidth: true
Layout.preferredHeight: Math.round(wallhavenGridView.itemSize * 0.67)
color: Color.transparent
Image {
id: img
source: thumbnailUrl
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: true
smooth: true
sourceSize.width: Math.round(wallhavenGridView.itemSize * 0.67)
sourceSize.height: Math.round(wallhavenGridView.itemSize * 0.67)
}
Rectangle {
anchors.fill: parent
color: Color.transparent color: Color.transparent
border.color: wallhavenGridView.currentIndex === index ? Color.mHover : Color.mSurface opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0.0
border.width: Math.max(1, Style.borderL * 1.5) radius: parent.handleRadius / 2
}
Rectangle {
anchors.fill: parent
color: Color.mSurface
opacity: hoverHandler.hovered || wallhavenGridView.currentIndex === index ? 0 : 0.3
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: Style.animationFast duration: Style.animationFast
} }
} }
} }
}
HoverHandler { delegate: ColumnLayout {
id: hoverHandler id: wallhavenItem
}
TapHandler { required property var modelData
onTapped: { required property int index
wallhavenGridView.currentIndex = index property string thumbnailUrl: (modelData && typeof WallhavenService !== "undefined") ? WallhavenService.getThumbnailUrl(modelData, "large") : ""
if (typeof WallhavenService !== "undefined") { property string wallpaperId: (modelData && modelData.id) ? modelData.id : ""
WallhavenService.downloadWallpaper(modelData, function (success, localPath) {
if (success) { width: wallhavenGridView.itemSize
if (Settings.data.wallpaper.setWallpaperOnAllMonitors) { spacing: Style.marginXS
WallpaperService.changeWallpaper(localPath, undefined)
} else { Rectangle {
WallpaperService.changeWallpaper(localPath, screen.name) id: imageContainer
Layout.fillWidth: true
Layout.preferredHeight: Math.round(wallhavenGridView.itemSize * 0.67)
color: Color.transparent
Image {
id: img
source: thumbnailUrl
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: true
smooth: true
sourceSize.width: Math.round(wallhavenGridView.itemSize * 0.67)
sourceSize.height: Math.round(wallhavenGridView.itemSize * 0.67)
}
Rectangle {
anchors.fill: parent
color: Color.transparent
border.color: wallhavenGridView.currentIndex === index ? Color.mHover : Color.mSurface
border.width: Math.max(1, Style.borderL * 1.5)
}
Rectangle {
anchors.fill: parent
color: Color.mSurface
opacity: hoverHandler.hovered || wallhavenGridView.currentIndex === index ? 0 : 0.3
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
}
HoverHandler {
id: hoverHandler
}
TapHandler {
onTapped: {
wallhavenGridView.currentIndex = index
if (typeof WallhavenService !== "undefined") {
WallhavenService.downloadWallpaper(modelData, function (success, localPath) {
if (success) {
if (Settings.data.wallpaper.setWallpaperOnAllMonitors) {
WallpaperService.changeWallpaper(localPath, undefined)
} else {
WallpaperService.changeWallpaper(localPath, screen.name)
}
} }
} })
}) }
} }
} }
} }
}
NText { NText {
text: wallpaperId || I18n.tr("wallpaper.unknown") text: wallpaperId || I18n.tr("wallpaper.unknown")
color: hoverHandler.hovered || wallhavenGridView.currentIndex === index ? Color.mOnSurface : Color.mOnSurfaceVariant color: hoverHandler.hovered || wallhavenGridView.currentIndex === index ? Color.mOnSurface : Color.mOnSurfaceVariant
pointSize: Style.fontSizeXS pointSize: Style.fontSizeXS
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: Style.marginS Layout.leftMargin: Style.marginS
Layout.rightMargin: Style.marginS Layout.rightMargin: Style.marginS
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight elide: Text.ElideRight
}
} }
} }
}
// Loading overlay - fills same space as GridView to prevent jumping // Loading overlay - fills same space as GridView to prevent jumping
Rectangle { Rectangle {
+17 -15
View File
@@ -106,7 +106,7 @@ Singleton {
currentResults = response.data currentResults = response.data
currentMeta = response.meta || {} currentMeta = response.meta || {}
lastPage = currentMeta.last_page || 1 lastPage = currentMeta.last_page || 1
// Store seed for random sorting // Store seed for random sorting
if (currentMeta.seed) { if (currentMeta.seed) {
seed = currentMeta.seed seed = currentMeta.seed
@@ -183,45 +183,48 @@ Singleton {
var url = getWallpaperUrl(wallpaper) var url = getWallpaperUrl(wallpaper)
if (!url) { if (!url) {
Logger.e("Wallhaven", "No URL available for wallpaper", wallpaper.id) Logger.e("Wallhaven", "No URL available for wallpaper", wallpaper.id)
if (callback) callback(false, "") if (callback)
callback(false, "")
return return
} }
var wallpaperId = wallpaper.id var wallpaperId = wallpaper.id
// Get the user's wallpaper directory // Get the user's wallpaper directory
var wallpaperDir = Settings.preprocessPath(Settings.data.wallpaper.directory) var wallpaperDir = Settings.preprocessPath(Settings.data.wallpaper.directory)
if (!wallpaperDir || wallpaperDir === "") { if (!wallpaperDir || wallpaperDir === "") {
wallpaperDir = Settings.defaultWallpapersDirectory wallpaperDir = Settings.defaultWallpapersDirectory
} }
// Ensure directory ends with / // Ensure directory ends with /
if (!wallpaperDir.endsWith("/")) { if (!wallpaperDir.endsWith("/")) {
wallpaperDir += "/" wallpaperDir += "/"
} }
var localPath = wallpaperDir + "wallhaven_" + wallpaperId + ".jpg" var localPath = wallpaperDir + "wallhaven_" + wallpaperId + ".jpg"
Logger.d("Wallhaven", "Downloading wallpaper", wallpaperId, "to", localPath) Logger.d("Wallhaven", "Downloading wallpaper", wallpaperId, "to", localPath)
// Use curl or wget to download the file, ensuring directory exists first // Use curl or wget to download the file, ensuring directory exists first
var downloadProcess = Qt.createQmlObject(` var downloadProcess = Qt.createQmlObject(`
import QtQuick import QtQuick
import Quickshell.Io import Quickshell.Io
Process { Process {
id: downloadProcess id: downloadProcess
command: ["sh", "-c", "mkdir -p '` + wallpaperDir + `' && (curl -L -s -o '` + localPath + `' '` + url + `' || wget -q -O '` + localPath + `' '` + url + `')"] command: ["sh", "-c", "mkdir -p '` + wallpaperDir + `' && (curl -L -s -o '` + localPath + `' '` + url + `' || wget -q -O '` + localPath + `' '` + url + `')"]
} }
`, root, "DownloadProcess_" + wallpaperId) `, root, "DownloadProcess_" + wallpaperId)
downloadProcess.exited.connect(function (exitCode) { downloadProcess.exited.connect(function (exitCode) {
if (exitCode === 0) { if (exitCode === 0) {
Logger.i("Wallhaven", "Wallpaper downloaded:", localPath) Logger.i("Wallhaven", "Wallpaper downloaded:", localPath)
wallpaperDownloaded(wallpaperId, localPath) wallpaperDownloaded(wallpaperId, localPath)
if (callback) callback(true, localPath) if (callback)
callback(true, localPath)
} else { } else {
Logger.e("Wallhaven", "Failed to download wallpaper, exit code:", exitCode) Logger.e("Wallhaven", "Failed to download wallpaper, exit code:", exitCode)
if (callback) callback(false, "") if (callback)
callback(false, "")
} }
downloadProcess.destroy() downloadProcess.destroy()
}) })
@@ -254,4 +257,3 @@ Singleton {
} }
} }
} }