feat: add unknown option toasts

This commit is contained in:
2 * r + 2 * t 2026-04-12 03:12:13 +10:00
parent ee9dce0268
commit 5a13cc22f6
4 changed files with 49 additions and 1 deletions

View file

@ -18,6 +18,10 @@ Scope {
Toaster.toast(qsTr("Failed to save config%1").arg(screen ? " for " + screen : ""), error, "settings_alert", Toast.Error);
}
function onUnknownOption(key: string, screen: string): void {
Toaster.toast(qsTr("Unknown option in%1 config").arg(screen ? " " + screen : ""), key, "question_mark", Toast.Warning);
}
target: GlobalConfig
}
@ -26,6 +30,10 @@ Scope {
Toaster.toast(qsTr("Failed to parse token config%1").arg(screen ? "for " + screen : ""), error, "settings_alert", Toast.Warning);
}
function onUnknownOption(key: string, screen: string): void {
Toaster.toast(qsTr("Unknown option in%1 token config").arg(screen ? " " + screen : ""), key, "question_mark", Toast.Warning);
}
target: TokenConfig
}
}

View file

@ -39,6 +39,7 @@ GlobalConfig* MonitorConfigManager::configForScreen(const QString& screen) {
connect(overlay.config, &GlobalConfig::saved, global, &GlobalConfig::saved);
connect(overlay.config, &GlobalConfig::loadFailed, global, &GlobalConfig::loadFailed);
connect(overlay.config, &GlobalConfig::saveFailed, global, &GlobalConfig::saveFailed);
connect(overlay.config, &GlobalConfig::unknownOption, global, &GlobalConfig::unknownOption);
}
return overlay.config;
}
@ -55,6 +56,7 @@ TokenConfig* MonitorConfigManager::tokensForScreen(const QString& screen) {
connect(overlay.tokens, &TokenConfig::saved, global, &TokenConfig::saved);
connect(overlay.tokens, &TokenConfig::loadFailed, global, &TokenConfig::loadFailed);
connect(overlay.tokens, &TokenConfig::saveFailed, global, &TokenConfig::saveFailed);
connect(overlay.tokens, &TokenConfig::unknownOption, global, &TokenConfig::unknownOption);
}
return overlay.tokens;
}

View file

@ -4,6 +4,7 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qjsondocument.h>
#include <qmetaobject.h>
#include <qstandardpaths.h>
namespace caelestia::config {
@ -19,6 +20,35 @@ QString watchRoot() {
RootConfig::RootConfig(QObject* parent)
: ConfigObject(parent) {}
QStringList RootConfig::collectUnknownKeys(const ConfigObject* obj, const QJsonObject& json) {
QStringList unknown;
const auto* meta = obj->metaObject();
QSet<QString> known;
for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i)
known.insert(QString::fromUtf8(meta->property(i).name()));
for (auto it = json.begin(); it != json.end(); ++it) {
if (!known.contains(it.key())) {
unknown.append(it.key());
} else if (it.value().isObject()) {
int idx = meta->indexOfProperty(it.key().toUtf8().constData());
if (idx >= 0) {
auto prop = meta->property(idx);
auto value = prop.read(obj);
auto* subObj = value.value<ConfigObject*>();
if (subObj) {
const auto subUnknown = collectUnknownKeys(subObj, it.value().toObject());
for (const auto& subKey : subUnknown)
unknown.append(it.key() + QStringLiteral(".") + subKey);
}
}
}
}
return unknown;
}
void RootConfig::setupFileBackend(const QString& path, const QString& screen) {
m_filePath = path;
m_screen = screen;
@ -157,7 +187,13 @@ std::optional<QString> RootConfig::reloadFromFile() {
qCDebug(lcConfig) << "Reloading" << metaObject()->className() << "from" << m_filePath;
clearLoadedKeys();
loadFromJson(doc.object());
auto jsonObj = doc.object();
const auto unknownKeys = collectUnknownKeys(this, jsonObj);
for (const auto& key : unknownKeys)
emit unknownOption(key, m_screen);
loadFromJson(jsonObj);
return QString(); // success
}

View file

@ -31,8 +31,10 @@ signals:
void loadFailed(const QString& error, const QString& screen);
void saved(const QString& screen);
void saveFailed(const QString& error, const QString& screen);
void unknownOption(const QString& key, const QString& screen);
private:
static QStringList collectUnknownKeys(const ConfigObject* obj, const QJsonObject& json);
void updateWatch();
void onWatcherEvent();