1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00
Files
DankMaterialShell/Modules/Plugins/ListSettingWithInput.qml
Bruno Cesar Rocha 16055fe96e fix: Plugin settings not loading existing settings (#294)
I notice the plugin settings tab was not loading the
existing plugin settings from the settings file.

It was properly writting to the file, but not reloading
on initialization.

added a loadValue() function so PluginSettings can call when the
pluginService is injected. Added isLoading state flag to prevent
the onItemsChanged from saving back settings when loading is happening.
Added null wise checks for properties that may be not ready yet
when loading.
2025-10-02 14:24:28 -04:00

257 lines
7.0 KiB
QML

import QtQuick
import qs.Common
import qs.Widgets
Column {
id: root
required property string settingKey
required property string label
property string description: ""
property var fields: []
property var defaultValue: []
property var items: defaultValue
width: parent.width
spacing: Theme.spacingM
property bool isLoading: false
Component.onCompleted: {
loadValue()
}
function loadValue() {
const settings = findSettings()
if (settings) {
isLoading = true
items = settings.loadValue(settingKey, defaultValue)
isLoading = false
}
}
onItemsChanged: {
if (isLoading) {
return
}
const settings = findSettings()
if (settings) {
settings.saveValue(settingKey, items)
}
}
function findSettings() {
let item = parent
while (item) {
if (item.saveValue !== undefined && item.loadValue !== undefined) {
return item
}
item = item.parent
}
return null
}
function addItem(item) {
items = items.concat([item])
}
function removeItem(index) {
const newItems = items.slice()
newItems.splice(index, 1)
items = newItems
}
StyledText {
text: root.label
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: root.description
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
width: parent.width
wrapMode: Text.WordWrap
visible: root.description !== ""
}
Flow {
width: parent.width
spacing: Theme.spacingS
Repeater {
model: root.fields
StyledText {
text: modelData.label
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
width: modelData.width || 200
}
}
}
Flow {
id: inputRow
width: parent.width
spacing: Theme.spacingS
property var inputFields: []
Repeater {
id: inputRepeater
model: root.fields
DankTextField {
width: modelData.width || 200
placeholderText: modelData.placeholder || ""
Component.onCompleted: {
inputRow.inputFields.push(this)
}
Keys.onReturnPressed: {
addButton.clicked()
}
}
}
DankButton {
id: addButton
width: 50
height: 36
text: "Add"
onClicked: {
let newItem = {}
let hasValue = false
for (let i = 0; i < root.fields.length; i++) {
const field = root.fields[i]
const input = inputRow.inputFields[i]
const value = input.text.trim()
if (value !== "") {
hasValue = true
}
if (field.required && value === "") {
return
}
newItem[field.id] = value || (field.default || "")
}
if (hasValue) {
root.addItem(newItem)
for (let i = 0; i < inputRow.inputFields.length; i++) {
inputRow.inputFields[i].text = ""
}
if (inputRow.inputFields.length > 0) {
inputRow.inputFields[0].forceActiveFocus()
}
}
}
}
}
StyledText {
text: "Current Items"
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
visible: root.items.length > 0
}
Column {
width: parent.width
spacing: Theme.spacingS
Repeater {
model: root.items
StyledRect {
width: parent.width
height: 40
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
border.width: 0
required property int index
required property var modelData
Row {
id: itemRow
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
property var itemData: parent.modelData
Repeater {
model: root.fields
StyledText {
required property int index
required property var modelData
text: {
const field = modelData
const item = itemRow.itemData
if (!field || !field.id || !item) {
return ""
}
const value = item[field.id]
return value || ""
}
color: Theme.surfaceText
font.pixelSize: Theme.fontSizeMedium
width: modelData ? (modelData.width || 200) : 200
elide: Text.ElideRight
}
}
}
Rectangle {
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
width: 60
height: 28
color: removeArea.containsMouse ? Theme.errorHover : Theme.error
radius: Theme.cornerRadius
StyledText {
anchors.centerIn: parent
text: "Remove"
color: Theme.onError
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
}
MouseArea {
id: removeArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.removeItem(index)
}
}
}
}
}
StyledText {
text: "No items added yet"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
visible: root.items.length === 0
}
}
}