make persistent states persistent

This commit is contained in:
end-4 2025-05-10 23:05:32 +02:00
parent 9d51815661
commit f13912a027
5 changed files with 126 additions and 32 deletions

View file

@ -1,7 +1,3 @@
function trimFileProtocol(str) {
return str.startsWith("file://") ? str.slice(7) : str;
}
function toPlainObject(qtObj) {
if (qtObj === null || typeof qtObj !== "object") return qtObj;
@ -26,4 +22,24 @@ function toPlainObject(qtObj) {
}
}
return result;
}
}
function applyToQtObject(qtObj, jsonObj) {
if (!qtObj || typeof jsonObj !== "object" || jsonObj === null) return;
for (let key in jsonObj) {
if (!qtObj.hasOwnProperty(key)) continue;
// Check if the property is a QtObject (not a value)
const value = qtObj[key];
const jsonValue = jsonObj[key];
// If it's an object and not an array, recurse
if (value && typeof value === "object" && !Array.isArray(value)) {
applyToQtObject(value, jsonValue);
} else {
// Otherwise, assign the value
qtObj[key] = jsonValue;
}
}
}

View file

@ -29,13 +29,8 @@ Rectangle {
}
}
Component.onCompleted: {
bottomWidgetGroupRow.opacity = !collapsed
collapsedBottomWidgetGroupRow.opacity = collapsed
}
function setCollapsed(state) {
PersistentStates.sidebar.bottomGroup.collapsed = state
PersistentStateManager.setState("sidebar.bottomGroup.collapsed", state)
if (collapsed) {
bottomWidgetGroupRow.opacity = 0
}
@ -70,6 +65,7 @@ Rectangle {
// The thing when collapsed
RowLayout {
id: collapsedBottomWidgetGroupRow
opacity: collapsed ? 1 : 0
visible: opacity > 0
Behavior on opacity {
NumberAnimation {
@ -111,6 +107,7 @@ Rectangle {
RowLayout {
id: bottomWidgetGroupRow
opacity: collapsed ? 0 : 1
visible: opacity > 0
Behavior on opacity {
NumberAnimation {

View file

@ -25,27 +25,7 @@ Singleton {
try {
const json = JSON.parse(fileContent);
function applyToQtObject(qtObj, jsonObj) {
if (!qtObj || typeof jsonObj !== "object" || jsonObj === null) return;
for (let key in jsonObj) {
if (!qtObj.hasOwnProperty(key)) continue;
// Check if the property is a QtObject (not a value)
const value = qtObj[key];
const jsonValue = jsonObj[key];
// If it's an object and not an array, recurse
if (value && typeof value === "object" && !Array.isArray(value)) {
applyToQtObject(value, jsonValue);
} else {
// Otherwise, assign the value
qtObj[key] = jsonValue;
}
}
}
applyToQtObject(ConfigOptions, json);
ObjectUtils.applyToQtObject(ConfigOptions, json);
if (root.firstLoad) {
root.firstLoad = false;
} else {

View file

@ -0,0 +1,100 @@
pragma Singleton
pragma ComponentBehavior: Bound
import "root:/modules/common"
import "root:/modules/common/functions/object_utils.js" as ObjectUtils
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import Qt.labs.platform
Singleton {
id: root
property string fileDir: `${StandardPaths.standardLocations(StandardPaths.StateLocation)[0]}`
property string fileName: "states.json"
property string filePath: `${root.fileDir}/${root.fileName}`
function getState(nestedKey) {
let keys = nestedKey.split(".");
let obj = PersistentStates;
for (let i = 0; i < keys.length; ++i) {
if (obj[keys[i]] === undefined) {
console.error(`[PersistentStateManager] Key "${keys[i]}" not found in PersistentStates`);
return null;
}
obj = obj[keys[i]];
}
return obj;
}
function setState(nestedKey, value) {
let keys = nestedKey.split(".");
let obj = PersistentStates;
let parents = [obj];
// Traverse and collect parent objects
for (let i = 0; i < keys.length - 1; ++i) {
if (!obj[keys[i]] || typeof obj[keys[i]] !== "object") {
obj[keys[i]] = {};
}
obj = obj[keys[i]];
parents.push(obj);
}
// Set the value at the innermost key
obj[keys[keys.length - 1]] = value;
saveStates()
}
function loadStates() {
stateFileView.reload()
}
function saveStates() {
console.log("[PersistentStateManager] Saving states to file:", root.filePath)
const plainStates = ObjectUtils.toPlainObject(PersistentStates)
stateFileView.setText(JSON.stringify(plainStates, null, 2))
}
function applyStates(fileContent) {
try {
const json = JSON.parse(fileContent);
ObjectUtils.applyToQtObject(PersistentStates, json);
} catch (e) {
console.error("[PersistentStateManager] Error reading file:", e);
return;
}
}
Timer {
id: delayedFileRead
interval: ConfigOptions.hacks.arbitraryRaceConditionDelay
repeat: false
running: false
onTriggered: {
root.applyStates(stateFileView.text())
}
}
FileView {
id: stateFileView
path: root.filePath
watchChanges: true
// onFileChanged: {
// console.log("[PersistentStateManager] File changed, reloading...")
// this.reload()
// delayedFileRead.start()
// }
onLoadedChanged: {
const fileContent = stateFileView.text()
root.applyStates(fileContent)
}
onLoadFailed: (error) => {
console.log("[PersistentStateManager] File not found, creating new file")
root.saveStates()
}
}
}

View file

@ -19,6 +19,7 @@ ShellRoot {
Component.onCompleted: {
MaterialThemeLoader.reapplyTheme()
ConfigLoader.loadConfig()
PersistentStateManager.loadStates()
}
Bar {}