pragma Singleton import Quickshell import QtQuick import Quickshell.Io Singleton { id: settings // Prevent auto-saving during initial load property bool isLoading: true // Settings persistence with atomic writes FileView { id: settingsFile path: "settings.json" blockWrites: true atomicWrites: true watchChanges: false onLoaded: { settings.isLoading = true; // Disable auto-save during loading try { var content = JSON.parse(text()); if (content) { // Load with fallback defaults settings.isDarkTheme = content.isDarkTheme ?? true; settings.currentTheme = content.currentTheme ?? (content.isDarkTheme !== false ? "oxocarbon_dark" : "oxocarbon_light"); settings.useCustomAccent = content.useCustomAccent ?? false; settings.avatarSource = content.avatarSource ?? "/home/imxyy/Pictures/icon.jpg"; settings.weatherLocation = content.weatherLocation ?? "Dinslaken"; settings.useFahrenheit = content.useFahrenheit ?? false; settings.displayTime = content.displayTime ?? 6000; settings.videoPath = content.videoPath ?? "~/Videos/"; settings.customDarkAccent = content.customDarkAccent ?? "#be95ff"; settings.customLightAccent = content.customLightAccent ?? "#8a3ffc"; settings.autoSwitchPlayer = content.autoSwitchPlayer ?? true; settings.alwaysShowPlayerDropdown = content.alwaysShowPlayerDropdown ?? true; settings.historyLimit = content.historyLimit ?? 25; settings.nightLightEnabled = content.nightLightEnabled ?? false; settings.nightLightWarmth = content.nightLightWarmth ?? 0.4; settings.nightLightAuto = content.nightLightAuto ?? false; settings.nightLightStartHour = content.nightLightStartHour ?? 20; settings.nightLightEndHour = content.nightLightEndHour ?? 6; settings.nightLightManualOverride = content.nightLightManualOverride ?? false; settings.nightLightManuallyEnabled = content.nightLightManuallyEnabled ?? false; settings.ignoredApps = content.ignoredApps ?? []; settings.workspaceBurstEnabled = content.workspaceBurstEnabled ?? true; settings.workspaceGlowEnabled = content.workspaceGlowEnabled ?? true; } } catch (e) { console.log("Error parsing user settings:", e); } // Re-enable auto-save after loading is complete settings.isLoading = false; } } // User-configurable settings property string avatarSource: "/home/imxyy/Pictures/icon.jpg" property bool isDarkTheme: true // Keep for backwards compatibility property string currentTheme: "oxocarbon_dark" // New theme system property bool useCustomAccent: false // Whether to use custom accent colors property string weatherLocation: "Dinslaken" property bool useFahrenheit: false // Temperature unit setting property int displayTime: 6000 // Notification display time in ms property var ignoredApps: [] // Apps to ignore notifications from (case-insensitive) property int historyLimit: 25 // Notification history limit property string videoPath: "~/Videos/" property string customDarkAccent: "#be95ff" property string customLightAccent: "#8a3ffc" // Music Player settings property bool autoSwitchPlayer: true property bool alwaysShowPlayerDropdown: true // Night Light settings property bool nightLightEnabled: false property real nightLightWarmth: 0.4 property bool nightLightAuto: false property int nightLightStartHour: 20 // 8 PM property int nightLightEndHour: 6 // 6 AM property bool nightLightManualOverride: false // Track manual user actions property bool nightLightManuallyEnabled: false // Track if user manually enabled it // Animation settings property bool workspaceBurstEnabled: true property bool workspaceGlowEnabled: true // UI constants readonly property real borderWidth: 9 readonly property real cornerRadius: 20 signal settingsChanged // Helper functions for managing ignored apps function addIgnoredApp(appName) { if (appName && appName.trim() !== "") { var trimmedName = appName.trim(); // Case-insensitive check for existing apps var exists = false; for (var i = 0; i < ignoredApps.length; i++) { if (ignoredApps[i].toLowerCase() === trimmedName.toLowerCase()) { exists = true; break; } } if (!exists) { var newApps = ignoredApps.slice(); // Create a copy newApps.push(trimmedName); ignoredApps = newApps; console.log("Added ignored app:", trimmedName, "Current list:", ignoredApps); // Force save immediately (only if not loading) if (!isLoading) { saveSettings(); } return true; } } return false; } function removeIgnoredApp(appName) { var index = ignoredApps.indexOf(appName); if (index > -1) { var newApps = ignoredApps.slice(); // Create a copy newApps.splice(index, 1); ignoredApps = newApps; console.log("Removed ignored app:", appName, "Current list:", ignoredApps); // Force save immediately (only if not loading) if (!isLoading) { saveSettings(); } return true; } return false; } function saveSettings() { try { var content = { isDarkTheme: settings.isDarkTheme, currentTheme: settings.currentTheme, useCustomAccent: settings.useCustomAccent, avatarSource: settings.avatarSource, weatherLocation: settings.weatherLocation, useFahrenheit: settings.useFahrenheit, displayTime: settings.displayTime, videoPath: settings.videoPath, customDarkAccent: settings.customDarkAccent, customLightAccent: settings.customLightAccent, autoSwitchPlayer: settings.autoSwitchPlayer, alwaysShowPlayerDropdown: settings.alwaysShowPlayerDropdown, historyLimit: settings.historyLimit, nightLightEnabled: settings.nightLightEnabled, nightLightWarmth: settings.nightLightWarmth, nightLightAuto: settings.nightLightAuto, nightLightStartHour: settings.nightLightStartHour, nightLightEndHour: settings.nightLightEndHour, nightLightManualOverride: settings.nightLightManualOverride, nightLightManuallyEnabled: settings.nightLightManuallyEnabled, ignoredApps: settings.ignoredApps, workspaceBurstEnabled: settings.workspaceBurstEnabled, workspaceGlowEnabled: settings.workspaceGlowEnabled }; var jsonContent = JSON.stringify(content, null, 4); settingsFile.setText(jsonContent); } catch (e) { console.log("Error saving user settings:", e); } } // Auto-save watchers (only save when not loading) onIsDarkThemeChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onCurrentThemeChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onUseCustomAccentChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onAvatarSourceChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onWeatherLocationChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onUseFahrenheitChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onDisplayTimeChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onHistoryLimitChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onVideoPathChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onCustomDarkAccentChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onCustomLightAccentChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onAutoSwitchPlayerChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onAlwaysShowPlayerDropdownChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightEnabledChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightWarmthChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightAutoChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightStartHourChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightEndHourChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightManualOverrideChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onNightLightManuallyEnabledChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onIgnoredAppsChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onWorkspaceBurstEnabledChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } onWorkspaceGlowEnabledChanged: { if (!isLoading) { settingsChanged(); saveSettings(); } } Component.onCompleted: { settingsFile.reload(); } }