import Gdk from 'gi://Gdk?version=4.0'; import Gio from 'gi://Gio'; const CITADEL_SETTINGS_SCHEMA = 'com.subgraph.citadel'; const LABEL_COLOR_LIST_KEY = 'label-color-list'; const REALM_LABEL_COLORS_KEY = 'realm-label-colors'; const DEFAULT_LABEL_COLOR = new Gdk.RGBA({ red: 153, green: 193, blue: 241, }); export class LabelColorManager { constructor() { this._citadelSettings = new Gio.Settings({ schema_id: CITADEL_SETTINGS_SCHEMA }); this._defaultColors = []; this._realmLabelColors = new Map(); this._loadColors(); } _loadColors() { let entries = this._citadelSettings.get_strv(LABEL_COLOR_LIST_KEY); entries.forEach(entry => { let c = new Gdk.RGBA(); if (c.parse(entry)) { this._defaultColors.push(c); } }); entries = this._citadelSettings.get_strv(REALM_LABEL_COLORS_KEY); entries.forEach(entry => { let parts = entry.split(":"); if (parts.length === 2) { let c = new Gdk.RGBA(); if (c.parse(parts[1])) { this._realmLabelColors.set(parts[0], c); } } }); } updateRealmColor(realm, color) { this._realmLabelColors.set(realm.name, color); this._storeRealmColors(); } lookupRealmColor(realm) { let c = this._realmLabelColors.get(realm.name); if (c) { return c; } let newColor = this._allocateColor(); this.updateRealmColor(realm, newColor); return newColor; } _storeRealmColors() { let entries = []; this._realmLabelColors.forEach((v, k) => { entries.push(`${k}:${v.to_string()}`); }); entries.sort(); this._citadelSettings.set_strv(REALM_LABEL_COLORS_KEY, entries); } _allocateColor() { // 1) No default colors? return a built in color if (this._defaultColors.length === 0) { return DEFAULT_LABEL_COLOR; } // 2) Find first color on default color list that isn't used already let usedColors = Array.from(this._realmLabelColors.values()); let defaultColor = this._defaultColors.find(color => !usedColors.some(c => c.equal(color))); if (defaultColor) { return defaultColor; } // 3) Choose a random element of the default list let index = Math.floor(Math.random() * this._defaultColors.length); return this._defaultColors[index]; } }