SchemeDownloader: download schemes to ~/.config/noctalia/colorschemes/

ColorSchemeService: check said folder for theming
TemplateProcessor: check said folder for theming
This commit is contained in:
Ly-sec
2025-11-21 15:32:02 +01:00
parent fe40758d4e
commit d3c200f50c
3 changed files with 57 additions and 9 deletions

View File

@@ -521,7 +521,7 @@ Popup {
return;
}
var targetDir = ColorSchemeService.schemesDirectory + "/" + schemeName;
var targetDir = ColorSchemeService.downloadedSchemesDirectory + "/" + schemeName;
var downloadScript = "mkdir -p '" + targetDir + "'\n";
// Build download script for all files
@@ -612,6 +612,17 @@ Popup {
return false;
}
function isSchemeDownloaded(schemeName) {
// Check if scheme is in the downloaded directory (not preinstalled)
for (var i = 0; i < ColorSchemeService.schemes.length; i++) {
var path = ColorSchemeService.schemes[i];
if ((path.indexOf("/" + schemeName + "/") !== -1 || path.indexOf("/" + schemeName + ".json") !== -1) && path.indexOf(ColorSchemeService.downloadedSchemesDirectory) !== -1) {
return true;
}
}
return false;
}
function deleteScheme(schemeName) {
if (downloading) {
return;
@@ -624,7 +635,8 @@ Popup {
var deletedSchemeDisplayName = ColorSchemeService.getBasename(schemeName);
var needsReset = (currentScheme === deletedSchemeDisplayName);
var targetDir = ColorSchemeService.schemesDirectory + "/" + schemeName;
// Only allow deleting downloaded schemes, not preinstalled ones
var targetDir = ColorSchemeService.downloadedSchemesDirectory + "/" + schemeName;
var deleteScript = "rm -rf '" + targetDir + "'";
var deleteProcess = Qt.createQmlObject(`
@@ -897,12 +909,14 @@ Popup {
NIconButton {
property bool isDownloading: downloading && downloadingScheme === schemeRow.schemeName
property bool isInstalled: root.isSchemeInstalled(schemeRow.schemeName)
property bool isDownloaded: root.isSchemeDownloaded(schemeRow.schemeName)
icon: isDownloading ? "" : (isInstalled ? "trash" : "download")
tooltipText: isDownloading ? I18n.tr("settings.color-scheme.download.downloading") : (isInstalled ? I18n.tr("settings.color-scheme.download.delete") : I18n.tr("settings.color-scheme.download.download"))
icon: isDownloading ? "" : (isDownloaded ? "trash" : "download")
tooltipText: isDownloading ? I18n.tr("settings.color-scheme.download.downloading") : (isDownloaded ? I18n.tr("settings.color-scheme.download.delete") : I18n.tr("settings.color-scheme.download.download"))
enabled: !downloading
Layout.alignment: Qt.AlignVCenter
onClicked: isInstalled ? root.deleteScheme(schemeRow.schemeName) : root.downloadScheme(modelData)
visible: !isInstalled || isDownloaded // Show button only if not installed (can download) or if downloaded (can delete)
onClicked: isDownloaded ? root.deleteScheme(schemeRow.schemeName) : root.downloadScheme(modelData)
NBusyIndicator {
anchors.centerIn: parent

View File

@@ -13,6 +13,7 @@ Singleton {
property var schemes: []
property bool scanning: false
property string schemesDirectory: Quickshell.shellDir + "/Assets/ColorScheme"
property string downloadedSchemesDirectory: Settings.configDir + "colorschemes"
property string colorsJsonFilePath: Settings.configDir + "colors.json"
Connections {
@@ -43,8 +44,11 @@ Singleton {
Logger.d("ColorScheme", "Load colorScheme");
scanning = true;
schemes = [];
// Use find command to locate all scheme.json files
findProcess.command = ["find", schemesDirectory, "-name", "*.json", "-type", "f"];
// Use find command to locate all scheme.json files in both directories
// First ensure the downloaded schemes directory exists
Quickshell.execDetached(["mkdir", "-p", downloadedSchemesDirectory]);
// Find in both preinstalled and downloaded directories
findProcess.command = ["find", schemesDirectory, downloadedSchemesDirectory, "-name", "*.json", "-type", "f"];
findProcess.running = true;
}
@@ -81,7 +85,17 @@ Singleton {
} else if (schemeName === "Tokyo Night") {
schemeName = "Tokyo-Night";
}
return schemesDirectory + "/" + schemeName + "/" + schemeName + ".json";
// Check preinstalled directory first, then downloaded directory
var preinstalledPath = schemesDirectory + "/" + schemeName + "/" + schemeName + ".json";
var downloadedPath = downloadedSchemesDirectory + "/" + schemeName + "/" + schemeName + ".json";
// Try to find the scheme in the loaded schemes list to determine which directory it's in
for (var i = 0; i < schemes.length; i++) {
if (schemes[i].indexOf("/" + schemeName + "/") !== -1 || schemes[i].indexOf("/" + schemeName + ".json") !== -1) {
return schemes[i];
}
}
// Fallback: prefer preinstalled, then downloaded
return preinstalledPath;
}
function applyScheme(nameOrPath) {

View File

@@ -5,6 +5,7 @@ import Quickshell
import Quickshell.Io
import qs.Commons
import qs.Services.System
import qs.Services.Theming
import qs.Services.UI
Singleton {
@@ -329,7 +330,26 @@ Singleton {
extension = ".toml";
}
return `${Quickshell.shellDir}/Assets/ColorScheme/${colorScheme}/terminal/${terminal}/${colorScheme}-${mode}${extension}`;
const fileName = `${colorScheme}-${mode}${extension}`;
const relativePath = `terminal/${terminal}/${fileName}`;
// Try to find the scheme in the loaded schemes list to determine which directory it's in
for (let i = 0; i < ColorSchemeService.schemes.length; i++) {
const schemeJsonPath = ColorSchemeService.schemes[i];
// Check if this is the scheme we're looking for
if (schemeJsonPath.indexOf(`/${colorScheme}/`) !== -1 || schemeJsonPath.indexOf(`/${colorScheme}.json`) !== -1) {
// Extract the scheme directory from the JSON path
// JSON path is like: /path/to/scheme/SchemeName/SchemeName.json
// We need: /path/to/scheme/SchemeName/terminal/...
const schemeDir = schemeJsonPath.substring(0, schemeJsonPath.lastIndexOf('/'));
return `${schemeDir}/${relativePath}`;
}
}
// Fallback: try downloaded first, then preinstalled
const downloadedPath = `${ColorSchemeService.downloadedSchemesDirectory}/${colorScheme}/${relativePath}`;
const preinstalledPath = `${ColorSchemeService.schemesDirectory}/${colorScheme}/${relativePath}`;
return preinstalledPath;
}
// ================================================================================