Files
2026-05-28 21:45:21 +02:00

994 lines
30 KiB
QML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.UI
import qs.Widgets
Popup {
id: root
property ShellScreen screen
// Measure the ENV placeholder text at current font settings
TextMetrics {
id: envPlaceholderMetrics
text: I18n.tr("wallpaper.panel.apikey-managed-by-env")
font.pointSize: Style.fontSizeM
}
// Dynamic width: use measured ENV placeholder width + input padding, or fallback to 440
width: Math.max(440, Math.round(envPlaceholderMetrics.width + (Style.marginL * 4)), Math.round(contentColumn.implicitWidth + Style.margin2L))
height: Math.round(contentColumn.implicitHeight + Style.margin2L)
padding: Style.marginL
modal: true
dim: false
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
function showAt(item) {
open();
}
onOpened: {
// Center on screen after popup is opened and parent position is known
if (screen && parent) {
var parentPos = parent.mapToItem(null, 0, 0);
x = Math.round((screen.width - width) / 2 - parentPos.x);
y = Math.round((screen.height - height) / 2 - parentPos.y);
}
Qt.callLater(() => {
if (resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.forceActiveFocus();
}
});
}
function hide() {
close();
}
function updateResolution(triggerSearch) {
if (typeof WallhavenService === "undefined") {
return;
}
var width = Settings.data.wallpaper.wallhavenResolutionWidth || "";
var height = Settings.data.wallpaper.wallhavenResolutionHeight || "";
var mode = Settings.data.wallpaper.wallhavenResolutionMode || "atleast";
if (width && height) {
var resolution = width + "x" + height;
if (mode === "atleast") {
WallhavenService.minResolution = resolution;
WallhavenService.resolutions = "";
} else {
WallhavenService.minResolution = "";
WallhavenService.resolutions = resolution;
}
} else {
WallhavenService.minResolution = "";
WallhavenService.resolutions = "";
}
// Trigger new search with updated resolution only if requested
if (triggerSearch && Settings.data.wallpaper.useWallhaven) {
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1);
}
}
background: Rectangle {
id: backgroundRect
color: Color.mSurface
radius: Style.radiusL
border.color: Color.mOutline
border.width: Style.borderM
NDropShadow {
source: backgroundRect
}
}
contentItem: ColumnLayout {
id: contentColumn
spacing: Style.marginM
// Header
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NIcon {
icon: "settings"
pointSize: Style.fontSizeL
color: Color.mPrimary
}
NText {
text: I18n.tr("wallpaper.panel.wallhaven-settings-title")
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.fillWidth: true
}
NIconButton {
icon: "close"
tooltipText: I18n.tr("common.close")
baseSize: Style.baseWidgetSize * 0.8
onClicked: root.hide()
}
}
NDivider {
Layout.fillWidth: true
}
// API Key
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.apikey-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
NTextInput {
id: apiKeyInput
Layout.fillWidth: true
enabled: !WallhavenService.apiKeyManagedByEnv
placeholderText: WallhavenService.apiKeyManagedByEnv ? I18n.tr("wallpaper.panel.apikey-managed-by-env") : I18n.tr("wallpaper.panel.apikey-placeholder")
text: WallhavenService.apiKeyManagedByEnv ? "" : (Settings.data.wallpaper.wallhavenApiKey || "")
// Fix for password echo mode
Component.onCompleted: {
if (apiKeyInput.inputItem) {
apiKeyInput.inputItem.echoMode = TextInput.Password;
}
}
onEditingFinished: {
if (!WallhavenService.apiKeyManagedByEnv) {
Settings.data.wallpaper.wallhavenApiKey = text;
}
}
}
NText {
text: I18n.tr("wallpaper.panel.apikey-help")
color: Color.mOnSurfaceVariant
pointSize: Style.fontSizeS
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
}
NDivider {
Layout.fillWidth: true
}
// Sorting
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NText {
text: I18n.tr("wallpaper.panel.sorting-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
NComboBox {
id: sortingComboBox
Layout.fillWidth: true
Layout.minimumWidth: 200
model: [
{
"key": "date_added",
"name": I18n.tr("wallpaper.panel.sorting-date-added")
},
{
"key": "relevance",
"name": I18n.tr("wallpaper.panel.sorting-relevance")
},
{
"key": "random",
"name": I18n.tr("common.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 || "relevance"
onSelected: key => {
Settings.data.wallpaper.wallhavenSorting = key;
if (typeof WallhavenService !== "undefined") {
WallhavenService.sorting = key;
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1);
}
}
}
}
// Order
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
visible: sortingComboBox.currentKey !== "random"
NText {
text: I18n.tr("wallpaper.panel.order-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
NComboBox {
id: orderComboBox
Layout.fillWidth: true
Layout.minimumWidth: 200
model: [
{
"key": "desc",
"name": I18n.tr("wallpaper.panel.order-desc")
},
{
"key": "asc",
"name": I18n.tr("wallpaper.panel.order-asc")
}
]
currentKey: Settings.data.wallpaper.wallhavenOrder || "desc"
onSelected: key => {
Settings.data.wallpaper.wallhavenOrder = key;
if (typeof WallhavenService !== "undefined") {
WallhavenService.order = key;
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1);
}
}
}
}
// Purity selector
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NText {
text: I18n.tr("wallpaper.panel.purity-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
Item {
Layout.fillWidth: true
}
RowLayout {
id: purityRow
spacing: Style.marginL
function getPurityValue(index) {
var purity = Settings.data.wallpaper.wallhavenPurity || "100";
return purity.length > index && purity.charAt(index) === "1";
}
function updatePurity(sfw, sketchy, nsfw) {
var purity = (sfw ? "1" : "0") + (sketchy ? "1" : "0") + (nsfw ? "1" : "0");
Settings.data.wallpaper.wallhavenPurity = purity;
// Update checkboxes immediately
sfwToggle.checked = sfw;
sketchyToggle.checked = sketchy;
nsfwToggle.checked = nsfw;
if (typeof WallhavenService !== "undefined") {
WallhavenService.purity = purity;
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1);
}
}
Connections {
target: Settings.data.wallpaper
function onWallhavenPurityChanged() {
sfwToggle.checked = purityRow.getPurityValue(0);
sketchyToggle.checked = purityRow.getPurityValue(1);
nsfwToggle.checked = purityRow.getPurityValue(2);
}
function onWallhavenApiKeyChanged() {
// If API key is removed (and no ENV key), disable NSFW
if (!WallhavenService.apiKey && nsfwToggle.checked) {
nsfwToggle.toggled(false);
}
}
}
Component.onCompleted: {
sfwToggle.checked = purityRow.getPurityValue(0);
sketchyToggle.checked = purityRow.getPurityValue(1);
nsfwToggle.checked = purityRow.getPurityValue(2);
}
// SFW checkbox
Item {
Layout.preferredWidth: sfwCheckboxRow.implicitWidth
Layout.preferredHeight: sfwCheckboxRow.implicitHeight
RowLayout {
id: sfwCheckboxRow
anchors.fill: parent
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.purity-sfw")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
Rectangle {
id: sfwBox
implicitWidth: Math.round(Style.baseWidgetSize * 0.7)
implicitHeight: Math.round(Style.baseWidgetSize * 0.7)
radius: Style.radiusXS
color: sfwToggle.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NIcon {
visible: sfwToggle.checked
anchors.centerIn: parent
anchors.horizontalCenterOffset: -1
icon: "check"
color: Color.mOnPrimary
pointSize: Math.max(Style.fontSizeXS, sfwBox.width * 0.5)
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: sfwToggle.toggled(!sfwToggle.checked)
}
}
}
}
// Sketchy checkbox
Item {
Layout.preferredWidth: sketchyCheckboxRow.implicitWidth
Layout.preferredHeight: sketchyCheckboxRow.implicitHeight
RowLayout {
id: sketchyCheckboxRow
anchors.fill: parent
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.purity-sketchy")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
Rectangle {
id: sketchyBox
implicitWidth: Math.round(Style.baseWidgetSize * 0.7)
implicitHeight: Math.round(Style.baseWidgetSize * 0.7)
radius: Style.radiusXS
color: sketchyToggle.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NIcon {
visible: sketchyToggle.checked
anchors.centerIn: parent
anchors.horizontalCenterOffset: -1
icon: "check"
color: Color.mOnPrimary
pointSize: Math.max(Style.fontSizeXS, sketchyBox.width * 0.5)
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: sketchyToggle.toggled(!sketchyToggle.checked)
}
}
}
}
// NSFW checkbox
Item {
Layout.preferredWidth: nsfwCheckboxRow.implicitWidth
Layout.preferredHeight: nsfwCheckboxRow.implicitHeight
visible: WallhavenService.apiKey !== ""
RowLayout {
id: nsfwCheckboxRow
anchors.fill: parent
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.purity-nsfw")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
Rectangle {
id: nsfwBox
implicitWidth: Math.round(Style.baseWidgetSize * 0.7)
implicitHeight: Math.round(Style.baseWidgetSize * 0.7)
radius: Style.radiusXS
color: nsfwToggle.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NIcon {
visible: nsfwToggle.checked
anchors.centerIn: parent
anchors.horizontalCenterOffset: -1
icon: "check"
color: Color.mOnPrimary
pointSize: Math.max(Style.fontSizeXS, nsfwBox.width * 0.5)
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: nsfwToggle.toggled(!nsfwToggle.checked)
}
}
}
}
// Invisible objects for logic
QtObject {
id: sfwToggle
property bool checked: false
signal toggled(bool checked)
onToggled: checked => {
purityRow.updatePurity(checked, purityRow.getPurityValue(1), purityRow.getPurityValue(2));
}
}
QtObject {
id: sketchyToggle
property bool checked: false
signal toggled(bool checked)
onToggled: checked => {
purityRow.updatePurity(purityRow.getPurityValue(0), checked, purityRow.getPurityValue(2));
}
}
QtObject {
id: nsfwToggle
property bool checked: false
signal toggled(bool checked)
onToggled: checked => {
purityRow.updatePurity(purityRow.getPurityValue(0), purityRow.getPurityValue(1), checked);
}
}
}
}
// Aspect Ratio
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NText {
text: I18n.tr("wallpaper.panel.ratios-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
NComboBox {
id: ratioComboBox
Layout.fillWidth: true
Layout.minimumWidth: 200
model: [
{
"key": "",
"name": I18n.tr("wallpaper.panel.ratios-any")
},
{
"key": "landscape",
"name": I18n.tr("wallpaper.panel.ratios-all-wide")
},
{
"key": "portrait",
"name": I18n.tr("wallpaper.panel.ratios-all-portrait")
},
{
"key": "16x9",
"name": "16x9"
},
{
"key": "16x10",
"name": "16x10"
},
{
"key": "21x9",
"name": "21x9"
},
{
"key": "32x9",
"name": "32x9"
},
{
"key": "48x9",
"name": "48x9"
},
{
"key": "9x16",
"name": "9x16"
},
{
"key": "10x16",
"name": "10x16"
},
{
"key": "9x18",
"name": "9x18"
},
{
"key": "1x1",
"name": "1x1"
},
{
"key": "3x2",
"name": "3x2"
},
{
"key": "4x3",
"name": "4x3"
},
{
"key": "5x4",
"name": "5x4"
}
]
currentKey: Settings.data.wallpaper.wallhavenRatios || ""
onSelected: key => {
Settings.data.wallpaper.wallhavenRatios = key;
if (typeof WallhavenService !== "undefined") {
WallhavenService.ratios = key;
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1);
}
}
}
}
// Categories
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NText {
text: I18n.tr("wallpaper.panel.categories-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
Item {
Layout.fillWidth: true
}
RowLayout {
id: categoriesRow
spacing: Style.marginL
function getCategoryValue(index) {
var cats = Settings.data.wallpaper.wallhavenCategories || "111";
return cats.length > index && cats.charAt(index) === "1";
}
function updateCategories(general, anime, people) {
var categories = (general ? "1" : "0") + (anime ? "1" : "0") + (people ? "1" : "0");
Settings.data.wallpaper.wallhavenCategories = categories;
// Update checkboxes immediately
generalToggle.checked = general;
animeToggle.checked = anime;
peopleToggle.checked = people;
if (typeof WallhavenService !== "undefined") {
WallhavenService.categories = categories;
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery, 1);
}
}
Connections {
target: Settings.data.wallpaper
function onWallhavenCategoriesChanged() {
generalToggle.checked = categoriesRow.getCategoryValue(0);
animeToggle.checked = categoriesRow.getCategoryValue(1);
peopleToggle.checked = categoriesRow.getCategoryValue(2);
}
}
Component.onCompleted: {
generalToggle.checked = categoriesRow.getCategoryValue(0);
animeToggle.checked = categoriesRow.getCategoryValue(1);
peopleToggle.checked = categoriesRow.getCategoryValue(2);
}
// General checkbox
Item {
Layout.preferredWidth: generalCheckboxRow.implicitWidth
Layout.preferredHeight: generalCheckboxRow.implicitHeight
RowLayout {
id: generalCheckboxRow
anchors.fill: parent
spacing: Style.marginS
NText {
text: I18n.tr("common.general")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
Rectangle {
id: generalBox
implicitWidth: Math.round(Style.baseWidgetSize * 0.7)
implicitHeight: Math.round(Style.baseWidgetSize * 0.7)
radius: Style.radiusXS
color: generalToggle.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NIcon {
visible: generalToggle.checked
anchors.centerIn: parent
anchors.horizontalCenterOffset: -1
icon: "check"
color: Color.mOnPrimary
pointSize: Math.max(Style.fontSizeXS, generalBox.width * 0.5)
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: generalToggle.toggled(!generalToggle.checked)
}
}
}
}
// Anime checkbox
Item {
Layout.preferredWidth: animeCheckboxRow.implicitWidth
Layout.preferredHeight: animeCheckboxRow.implicitHeight
RowLayout {
id: animeCheckboxRow
anchors.fill: parent
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.categories-anime")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
Rectangle {
id: animeBox
implicitWidth: Math.round(Style.baseWidgetSize * 0.7)
implicitHeight: Math.round(Style.baseWidgetSize * 0.7)
radius: Style.radiusXS
color: animeToggle.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NIcon {
visible: animeToggle.checked
anchors.centerIn: parent
anchors.horizontalCenterOffset: -1
icon: "check"
color: Color.mOnPrimary
pointSize: Math.max(Style.fontSizeXS, animeBox.width * 0.5)
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: animeToggle.toggled(!animeToggle.checked)
}
}
}
}
// People checkbox
Item {
Layout.preferredWidth: peopleCheckboxRow.implicitWidth
Layout.preferredHeight: peopleCheckboxRow.implicitHeight
RowLayout {
id: peopleCheckboxRow
anchors.fill: parent
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.categories-people")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
Rectangle {
id: peopleBox
implicitWidth: Math.round(Style.baseWidgetSize * 0.7)
implicitHeight: Math.round(Style.baseWidgetSize * 0.7)
radius: Style.radiusXS
color: peopleToggle.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NIcon {
visible: peopleToggle.checked
anchors.centerIn: parent
anchors.horizontalCenterOffset: -1
icon: "check"
color: Color.mOnPrimary
pointSize: Math.max(Style.fontSizeXS, peopleBox.width * 0.5)
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: peopleToggle.toggled(!peopleToggle.checked)
}
}
}
}
// Invisible checkboxes to maintain the signal handlers
QtObject {
id: generalToggle
property bool checked: false
signal toggled(bool checked)
onToggled: checked => {
categoriesRow.updateCategories(checked, categoriesRow.getCategoryValue(1), categoriesRow.getCategoryValue(2));
}
}
QtObject {
id: animeToggle
property bool checked: false
signal toggled(bool checked)
onToggled: checked => {
categoriesRow.updateCategories(categoriesRow.getCategoryValue(0), checked, categoriesRow.getCategoryValue(2));
}
}
QtObject {
id: peopleToggle
property bool checked: false
signal toggled(bool checked)
onToggled: checked => {
categoriesRow.updateCategories(categoriesRow.getCategoryValue(0), categoriesRow.getCategoryValue(1), checked);
}
}
}
}
// Resolution filter
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginS
NText {
text: I18n.tr("wallpaper.panel.resolution-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
}
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NText {
text: I18n.tr("wallpaper.panel.resolution-mode-label")
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
NComboBox {
id: resolutionModeComboBox
Layout.fillWidth: true
Layout.minimumWidth: 200
model: [
{
"key": "atleast",
"name": I18n.tr("wallpaper.panel.resolution-atleast")
},
{
"key": "exact",
"name": I18n.tr("wallpaper.panel.resolution-exact")
}
]
currentKey: Settings.data.wallpaper.wallhavenResolutionMode || "atleast"
Connections {
target: Settings.data.wallpaper
function onWallhavenResolutionModeChanged() {
if (resolutionModeComboBox.currentKey !== Settings.data.wallpaper.wallhavenResolutionMode) {
resolutionModeComboBox.currentKey = Settings.data.wallpaper.wallhavenResolutionMode || "atleast";
}
}
}
onSelected: key => {
Settings.data.wallpaper.wallhavenResolutionMode = key;
updateResolution(false);
}
}
}
RowLayout {
Layout.fillWidth: true
spacing: Style.marginS
NTextInput {
id: resolutionWidthInput
Layout.preferredWidth: 80
placeholderText: I18n.tr("common.width")
inputMethodHints: Qt.ImhDigitsOnly
text: Settings.data.wallpaper.wallhavenResolutionWidth || ""
Component.onCompleted: {
if (resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.focusPolicy = Qt.StrongFocus;
// Ensure the TextField can receive keyboard input
resolutionWidthInput.inputItem.activeFocusOnPress = true;
}
}
// Ensure focus when clicked
onActiveFocusChanged: {
if (activeFocus && resolutionWidthInput.inputItem) {
resolutionWidthInput.inputItem.forceActiveFocus();
}
}
Connections {
target: Settings.data.wallpaper
function onWallhavenResolutionWidthChanged() {
if (resolutionWidthInput.text !== Settings.data.wallpaper.wallhavenResolutionWidth) {
resolutionWidthInput.text = Settings.data.wallpaper.wallhavenResolutionWidth || "";
}
}
}
onEditingFinished: {
Settings.data.wallpaper.wallhavenResolutionWidth = text;
updateResolution(false);
}
}
NText {
text: "×"
color: Color.mOnSurface
pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
NTextInput {
id: resolutionHeightInput
Layout.preferredWidth: 80
placeholderText: I18n.tr("common.height")
inputMethodHints: Qt.ImhDigitsOnly
text: Settings.data.wallpaper.wallhavenResolutionHeight || ""
Component.onCompleted: {
if (resolutionHeightInput.inputItem) {
resolutionHeightInput.inputItem.focusPolicy = Qt.StrongFocus;
resolutionHeightInput.inputItem.activeFocusOnPress = true;
}
}
// Ensure focus when clicked
onActiveFocusChanged: {
if (activeFocus && resolutionHeightInput.inputItem) {
resolutionHeightInput.inputItem.forceActiveFocus();
}
}
Connections {
target: Settings.data.wallpaper
function onWallhavenResolutionHeightChanged() {
if (resolutionHeightInput.text !== Settings.data.wallpaper.wallhavenResolutionHeight) {
resolutionHeightInput.text = Settings.data.wallpaper.wallhavenResolutionHeight || "";
}
}
}
onEditingFinished: {
Settings.data.wallpaper.wallhavenResolutionHeight = text;
updateResolution(false);
}
}
}
}
// Apply button
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginM
}
NButton {
Layout.fillWidth: true
text: I18n.tr("common.apply")
onClicked: {
// Ensure all settings are synced to the service
if (typeof WallhavenService !== "undefined" && Settings.data.wallpaper.useWallhaven) {
// Sync all settings to the service
WallhavenService.categories = Settings.data.wallpaper.wallhavenCategories;
WallhavenService.purity = Settings.data.wallpaper.wallhavenPurity;
WallhavenService.sorting = Settings.data.wallpaper.wallhavenSorting;
WallhavenService.order = Settings.data.wallpaper.wallhavenOrder;
WallhavenService.ratios = Settings.data.wallpaper.wallhavenRatios;
WallhavenService.apiKey = Settings.data.wallpaper.wallhavenApiKey;
// Update resolution settings (without triggering search)
updateResolution(false);
// Refresh the wallpaper search with current settings
WallhavenService.search(Settings.data.wallpaper.wallhavenQuery || "", 1);
// Close the popup after applying (delay to prevent click propagation)
Qt.callLater(() => {
root.hide();
});
}
}
}
}
}