fix: user uploaded themes are now stored in the config directory. Missing directories will be created and added docs for theming

This commit is contained in:
2023-05-14 23:48:13 +02:00
parent 822bdf401e
commit 90cf231c76
14 changed files with 185 additions and 73 deletions

View File

@@ -1,9 +1,10 @@
import remote from "@electron/remote";
import remote, { app } from "@electron/remote";
import { ipcRenderer, shell } from "electron";
import fs from "fs";
import { globalEvents } from "../../constants/globalEvents";
import { settings } from "../../constants/settings";
import { settingsStore } from "./../../scripts/settings";
import { getOptions, getOptionsHeader, getThemeListFromDirectory } from "./theming";
let adBlock: HTMLInputElement,
api: HTMLInputElement,
@@ -25,23 +26,25 @@ let adBlock: HTMLInputElement,
theme: HTMLSelectElement,
trayIcon: HTMLInputElement,
updateFrequency: HTMLInputElement;
function getThemeFiles() {
const selectElement = document.getElementById("themesList") as HTMLSelectElement;
const fileNames = fs
.readdirSync(process.resourcesPath)
.filter((file) => file.endsWith(".css"))
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
const builtInThemes = getThemeListFromDirectory(process.resourcesPath);
const userThemes = getThemeListFromDirectory(`${app.getPath("userData")}/themes`);
const options = fileNames.map((name) => {
return new Option(name.replace(".css", ""), name);
});
let allThemes = [
getOptionsHeader("Built-in Themes"),
new Option("Tidal - Default", "none"),
].concat(getOptions(builtInThemes));
if (userThemes.length >= 1) {
allThemes = allThemes.concat([getOptionsHeader("User Themes")]).concat(getOptions(userThemes));
}
// empty old options
const oldOptions = document.querySelectorAll("#themesList option");
oldOptions.forEach((o) => o.remove());
[new Option("Tidal - Default", "none")].concat(options).forEach((option) => {
allThemes.forEach((option) => {
selectElement.add(option, null);
});
}
@@ -52,7 +55,7 @@ function handleFileUploads() {
document.getElementById("theme-files").addEventListener("change", function (e: any) {
Array.from(e.target.files).forEach((file: File) => {
const destination = `${process.resourcesPath}/${file.name}`;
const destination = `${app.getPath("userData")}/themes/${file.name}`;
fs.copyFileSync(file.path, destination, null);
});
fileMessage.innerText = `${e.target.files.length} files successfully uploaded`;

View File

@@ -434,5 +434,12 @@ html {
option {
background-color: $tidal-grey-darkest;
&:disabled {
font-size: 1.2em;
line-height: 1.5em;
text-align: center;
color: $white;
}
}
}

View File

@@ -0,0 +1,55 @@
import fs from "fs";
const cssFilter = (file: string) => file.endsWith(".css");
const sort = (a: string, b: string) => a.toLowerCase().localeCompare(b.toLowerCase());
/**
* Create an "options header" (disabled option) based on a bit of text
* @param text of the header
* @returns
*/
export const getOptionsHeader = (text: string): HTMLOptionElement => {
const opt = new Option(text, undefined, false, false);
opt.disabled = true;
return opt;
};
/**
* Maps a list of filenames to a list of HTMLOptionElements
* Will strip ".css" from the name but keeps it in the value
* @param array array of filenames
* @returns
*/
export const getOptions = (array: string[]) => {
return array.map((name) => {
return new Option(name.replace(".css", ""), name);
});
};
/**
* Read .css files from a directory and return them in a sorted array.
* @param directory to read from. Will be created if it doesn't exist
* @returns
*/
export const getThemeListFromDirectory = (directory: string) => {
try {
makeUserThemesDirectory(directory);
return fs.readdirSync(directory).filter(cssFilter).sort(sort);
} catch (err) {
console.error(err);
}
};
/**
* Create the directory to store user themes in
* @param directory directory to create
*/
export const makeUserThemesDirectory = (directory: string) => {
try {
fs.mkdir(directory, { recursive: true }, (err) => {
if (err) throw err;
});
} catch (err) {
console.error(err);
}
};

View File

@@ -55,7 +55,7 @@ export const createSettingsWindow = function () {
settingsWindow = new BrowserWindow({
width: 700,
height: 600,
resizable: false,
resizable: true,
show: false,
transparent: true,
frame: false,