Settings: migration for shellstate is now handled in Settings.qml

This commit is contained in:
Ly-sec
2025-11-22 15:40:53 +01:00
parent 83d1cbacc7
commit 8eaa5cc034
7 changed files with 221 additions and 137 deletions

View File

@@ -794,6 +794,220 @@ Singleton {
Logger.w("Settings", "Failed to read raw JSON for dimDesktop migration:", error);
}
}
// -----------------
// 8th. Migrate ShellState-related files from old cache files to ShellState
// This consolidates migrations that were previously in individual service files
if (typeof ShellState !== 'undefined' && ShellState.isLoaded) {
migrateShellStateFiles();
} else {
// Wait for ShellState to be ready
Qt.callLater(() => {
if (typeof ShellState !== 'undefined' && ShellState.isLoaded) {
migrateShellStateFiles();
}
});
}
}
// -----------------------------------------------------
// Migrate old cache files to ShellState
function migrateShellStateFiles() {
// Migrate display.json → ShellState (CompositorService)
migrateDisplayFile();
// Migrate notifications-state.json → ShellState (NotificationService)
migrateNotificationsStateFile();
// Migrate changelog-state.json → ShellState (UpdateService)
migrateChangelogStateFile();
// Migrate color-schemes-list.json → ShellState (SchemeDownloader)
migrateColorSchemesListFile();
// Migrate wallpaper paths from Settings → ShellState (WallpaperService)
migrateWallpaperPaths();
}
function migrateDisplayFile() {
// Check if ShellState already has display data
const cached = ShellState.getDisplay();
if (cached && Object.keys(cached).length > 0) {
return; // Already migrated
}
const oldDisplayPath = cacheDir + "display.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
import qs.Commons
FileView {
id: migrationView
path: "${oldDisplayPath}"
printErrors: false
adapter: JsonAdapter {
property var displays: ({})
}
onLoaded: {
if (adapter.displays && Object.keys(adapter.displays).length > 0) {
ShellState.setDisplay(adapter.displays);
Logger.i("Settings", "Migrated display.json to ShellState");
}
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "displayMigrationView");
}
function migrateNotificationsStateFile() {
// Check if ShellState already has notifications state
const cached = ShellState.getNotificationsState();
if (cached && cached.lastSeenTs && cached.lastSeenTs > 0) {
return; // Already migrated
}
// Also check Settings for lastSeenTs
if (adapter.notifications && adapter.notifications.lastSeenTs) {
ShellState.setNotificationsState({
lastSeenTs: adapter.notifications.lastSeenTs
});
Logger.i("Settings", "Migrated notifications lastSeenTs from Settings to ShellState");
return;
}
const oldStatePath = cacheDir + "notifications-state.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
import qs.Commons
FileView {
id: migrationView
path: "${oldStatePath}"
printErrors: false
adapter: JsonAdapter {
property real lastSeenTs: 0
}
onLoaded: {
if (adapter.lastSeenTs && adapter.lastSeenTs > 0) {
ShellState.setNotificationsState({
lastSeenTs: adapter.lastSeenTs
});
Logger.i("Settings", "Migrated notifications-state.json to ShellState");
}
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "notificationsMigrationView");
}
function migrateChangelogStateFile() {
// Check if ShellState already has changelog state
const cached = ShellState.getChangelogState();
if (cached && cached.lastSeenVersion && cached.lastSeenVersion !== "") {
return; // Already migrated
}
// Also check Settings for lastSeenVersion
if (adapter.changelog && adapter.changelog.lastSeenVersion) {
ShellState.setChangelogState({
lastSeenVersion: adapter.changelog.lastSeenVersion
});
Logger.i("Settings", "Migrated changelog lastSeenVersion from Settings to ShellState");
return;
}
const oldChangelogPath = cacheDir + "changelog-state.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
import qs.Commons
FileView {
id: migrationView
path: "${oldChangelogPath}"
printErrors: false
adapter: JsonAdapter {
property string lastSeenVersion: ""
}
onLoaded: {
if (adapter.lastSeenVersion && adapter.lastSeenVersion !== "") {
ShellState.setChangelogState({
lastSeenVersion: adapter.lastSeenVersion
});
Logger.i("Settings", "Migrated changelog-state.json to ShellState");
}
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "changelogMigrationView");
}
function migrateColorSchemesListFile() {
// Check if ShellState already has color schemes list
const cached = ShellState.getColorSchemesList();
if (cached && cached.schemes && cached.schemes.length > 0) {
return; // Already migrated
}
const oldSchemesPath = cacheDir + "color-schemes-list.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
import qs.Commons
FileView {
id: migrationView
path: "${oldSchemesPath}"
printErrors: false
adapter: JsonAdapter {
property var schemes: []
property real timestamp: 0
}
onLoaded: {
if (adapter.schemes && adapter.schemes.length > 0) {
ShellState.setColorSchemesList({
schemes: adapter.schemes,
timestamp: adapter.timestamp || 0
});
Logger.i("Settings", "Migrated color-schemes-list.json to ShellState");
}
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "schemesMigrationView");
}
function migrateWallpaperPaths() {
// Check if ShellState already has wallpaper paths
const cached = ShellState.getWallpapers();
if (cached && Object.keys(cached).length > 0) {
return; // Already migrated
}
// Migrate from Settings wallpaper.monitors
var monitors = adapter.wallpaper.monitors || [];
if (monitors.length > 0) {
var wallpapers = {};
for (var i = 0; i < monitors.length; i++) {
if (monitors[i].name && monitors[i].wallpaper) {
wallpapers[monitors[i].name] = monitors[i].wallpaper;
}
}
if (Object.keys(wallpapers).length > 0) {
ShellState.setWallpapers(wallpapers);
Logger.i("Settings", "Migrated wallpaper paths from Settings to ShellState");
}
}
}
// -----------------------------------------------------

View File

@@ -114,10 +114,7 @@ Popup {
// Check if cache is expired or missing
if (!cachedTimestamp || (now >= cachedTimestamp + schemesCacheUpdateFrequency)) {
// Try migration first if cache is empty
if (cachedSchemes.length === 0) {
migrateFromOldSchemesList();
}
// Migration is now handled in Settings.qml
// Only fetch from API if we haven't fetched recently (prevent rapid repeated calls)
const timeSinceLastFetch = now - lastApiFetchTime;
@@ -160,32 +157,6 @@ Popup {
}
}
function migrateFromOldSchemesList() {
const oldSchemesPath = Settings.cacheDir + "color-schemes-list.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
FileView {
id: migrationView
path: "${oldSchemesPath}"
printErrors: false
adapter: JsonAdapter {
property var schemes: []
property real timestamp: 0
}
onLoaded: {
root.availableSchemes = adapter.schemes || [];
root.saveSchemesToCache();
Logger.i("ColorSchemeDownload", "Migrated color-schemes-list.json to ShellState");
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "schemesMigrationView");
}
function saveSchemesToCache() {
try {
ShellState.setColorSchemesList({

View File

@@ -113,8 +113,8 @@ Singleton {
displayScalesLoaded = true;
Logger.d("CompositorService", "Loaded display scales from ShellState");
} else {
// Try to migrate from old display.json if it exists
migrateFromOldDisplayFile();
// Migration is now handled in Settings.qml
displayScalesLoaded = true;
}
} catch (error) {
Logger.e("CompositorService", "Failed to load display scales:", error);
@@ -122,34 +122,6 @@ Singleton {
}
}
// Migration from old display.json file
function migrateFromOldDisplayFile() {
const oldDisplayPath = Settings.cacheDir + "display.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
FileView {
id: migrationView
path: "${oldDisplayPath}"
printErrors: false
adapter: JsonAdapter {
property var displays: ({})
}
onLoaded: {
parent.displayScales = adapter.displays || {};
parent.displayScalesLoaded = true;
parent.saveDisplayScalesToCache();
Logger.i("CompositorService", "Migrated display.json to ShellState");
migrationView.destroy();
}
onLoadFailed: {
parent.displayScalesLoaded = true;
migrationView.destroy();
}
}
`, root, "migrationFileView");
}
// Hyprland backend component
Component {
id: hyprlandComponent

View File

@@ -319,17 +319,7 @@ Singleton {
const changelog = ShellState.getChangelogState();
changelogLastSeenVersion = changelog.lastSeenVersion || "";
if (!changelogLastSeenVersion) {
// Try to migrate from old changelog-state.json
migrateFromOldChangelogFile();
// Also try settings migration
if (!changelogLastSeenVersion && Settings.data && Settings.data.changelog && Settings.data.changelog.lastSeenVersion) {
changelogLastSeenVersion = Settings.data.changelog.lastSeenVersion;
debouncedSaveChangelogState();
Logger.i("UpdateService", "Migrated changelog lastSeenVersion from settings to ShellState");
}
}
// Migration is now handled in Settings.qml
Logger.d("UpdateService", "Loaded changelog state from ShellState");
} catch (error) {
Logger.e("UpdateService", "Failed to load changelog state:", error);
@@ -341,31 +331,6 @@ Singleton {
}
}
function migrateFromOldChangelogFile() {
const oldChangelogPath = Settings.cacheDir + "changelog-state.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
FileView {
id: migrationView
path: "${oldChangelogPath}"
printErrors: false
adapter: JsonAdapter {
property string lastSeenVersion: ""
}
onLoaded: {
parent.changelogLastSeenVersion = adapter.lastSeenVersion || "";
parent.debouncedSaveChangelogState();
Logger.i("UpdateService", "Migrated changelog-state.json to ShellState");
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "changelogMigrationView");
}
function debouncedSaveChangelogState() {
// Queue a save and restart the debounce timer
pendingSave = true;

View File

@@ -547,48 +547,13 @@ Singleton {
const notifState = ShellState.getNotificationsState();
root.lastSeenTs = notifState.lastSeenTs || 0;
if (root.lastSeenTs === 0) {
// Try to migrate from old notifications-state.json
migrateFromOldStateFile();
// Also try settings migration
if (root.lastSeenTs === 0 && Settings.data.notifications && Settings.data.notifications.lastSeenTs) {
root.lastSeenTs = Settings.data.notifications.lastSeenTs;
saveState();
Logger.i("Notifications", "Migrated lastSeenTs from settings to ShellState");
}
}
// Migration is now handled in Settings.qml
Logger.d("Notifications", "Loaded state from ShellState");
} catch (e) {
Logger.e("Notifications", "Load state failed:", e);
}
}
function migrateFromOldStateFile() {
const oldStatePath = Settings.cacheDir + "notifications-state.json";
const migrationFileView = Qt.createQmlObject(`
import QtQuick
import Quickshell.Io
FileView {
id: migrationView
path: "${oldStatePath}"
printErrors: false
adapter: JsonAdapter {
property real lastSeenTs: 0
}
onLoaded: {
parent.lastSeenTs = adapter.lastSeenTs || 0;
parent.saveState();
Logger.i("Notifications", "Migrated notifications-state.json to ShellState");
migrationView.destroy();
}
onLoadFailed: {
migrationView.destroy();
}
}
`, root, "notificationMigrationView");
}
function saveState() {
try {
ShellState.setNotificationsState({

View File

@@ -213,6 +213,7 @@ Singleton {
FileView {
id: colorsWriter
path: colorsJsonFilePath
printErrors: false
onSaved:
// Logger.i("ColorScheme", "Colors saved")

View File

@@ -114,11 +114,7 @@ Singleton {
}
Logger.d("Wallpaper", "Loaded wallpapers from Settings");
// Migrate to ShellState if we loaded from Settings
if (typeof ShellState !== 'undefined' && ShellState.isLoaded && Object.keys(currentWallpapers).length > 0) {
ShellState.setWallpapers(currentWallpapers);
Logger.i("Wallpaper", "Migrated wallpaper paths from Settings to ShellState");
}
// Migration is now handled in Settings.qml
}
// -------------------------------------------------