Cards & Settings refactoring

- All cards now live in Modules/Cards
- CalendarPanel is now called ClockPanel
- Added a way to ease settings migration in separate QML files
This commit is contained in:
ItsLemmy
2025-11-30 14:26:09 -05:00
parent 087c9b4ced
commit e972e1f7aa
20 changed files with 738 additions and 686 deletions
+46 -30
View File
@@ -5,6 +5,7 @@ import Quickshell
import Quickshell.Io
import "../Helpers/QtObj2JS.js" as QtObj2JS
import qs.Commons
import qs.Commons.Migrations
import qs.Modules.OSD
import qs.Services.UI
@@ -21,7 +22,7 @@ Singleton {
- Default cache directory: ~/.cache/noctalia
*/
readonly property alias data: adapter // Used to access via Settings.data.xxx.yyy
readonly property int settingsVersion: 25
readonly property int settingsVersion: 26
readonly property bool isDebug: Quickshell.env("NOCTALIA_DEBUG") === "1"
readonly property string shellName: "noctalia"
readonly property string configDir: Quickshell.env("NOCTALIA_CONFIG_DIR") || (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/"
@@ -100,6 +101,10 @@ Singleton {
if (!isLoaded) {
Logger.i("Settings", "Settings loaded");
// -----------------
// Run versioned migrations from MigrationRegistry
runVersionedMigrations();
upgradeSettingsData();
root.isLoaded = true;
@@ -267,11 +272,11 @@ Singleton {
property JsonObject calendar: JsonObject {
property list<var> cards: [
{
"id": "banner-card",
"id": "calendar-header-card",
"enabled": true
},
{
"id": "calendar-card",
"id": "calendar-month-card",
"enabled": true
},
{
@@ -627,6 +632,41 @@ Singleton {
}
}
// -----------------------------------------------------
// Run versioned migrations using MigrationRegistry
function runVersionedMigrations() {
const currentVersion = adapter.settingsVersion;
const migrations = MigrationRegistry.migrations;
// Get all migration versions and sort them
const versions = Object.keys(migrations).map(v => parseInt(v)).sort((a, b) => a - b);
// Run migrations in order for versions newer than current
for (var i = 0; i < versions.length; i++) {
const version = versions[i];
if (currentVersion < version) {
// Create migration instance and run it
const migrationComponent = migrations[version];
const migration = migrationComponent.createObject(root);
if (migration && typeof migration.migrate === "function") {
const success = migration.migrate(adapter, Logger);
if (!success) {
Logger.e("Settings", "Migration to v" + version + " failed");
}
} else {
Logger.e("Settings", "Invalid migration for v" + version);
}
// Clean up migration instance
if (migration) {
migration.destroy();
}
}
}
}
// -----------------------------------------------------
// Function to clean up deprecated user/custom bar widgets settings
function upgradeWidget(widget) {
@@ -677,31 +717,7 @@ Singleton {
const sections = ["left", "center", "right"];
// -----------------
// 1st. convert old widget id to new id
for (var s = 0; s < sections.length; s++) {
const sectionName = sections[s];
for (var i = 0; i < adapter.bar.widgets[sectionName].length; i++) {
var widget = adapter.bar.widgets[sectionName][i];
switch (widget.id) {
case "DarkModeToggle":
widget.id = "DarkMode";
break;
case "PowerToggle":
widget.id = "SessionMenu";
break;
case "ScreenRecorderIndicator":
widget.id = "ScreenRecorder";
break;
case "SidePanelToggle":
widget.id = "ControlCenter";
break;
}
}
}
// -----------------
// 2nd. remove any non existing widget type
// 1. remove any non existing widget type
var removedWidget = false;
for (var s = 0; s < sections.length; s++) {
const sectionName = sections[s];
@@ -718,7 +734,7 @@ Singleton {
}
// -----------------
// 3nd. upgrade widget settings
// 2. upgrade user widget settings
for (var s = 0; s < sections.length; s++) {
const sectionName = sections[s];
for (var i = 0; i < adapter.bar.widgets[sectionName].length; i++) {
@@ -737,7 +753,7 @@ Singleton {
}
// -----------------
// 4th. safety check
// 3. safety check
// if a widget was deleted, ensure we still have a control center
if (removedWidget) {
var gotControlCenter = false;