feat: add .css theme file upload and a unstyled theme selector

This commit is contained in:
Rick van Lieshout 2023-05-08 22:31:22 +02:00
parent 757f8511c0
commit 77a853e980
4 changed files with 154 additions and 25 deletions

View File

@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- moved from Javascript to Typescript for all files - moved from Javascript to Typescript for all files
- use `npm run watch` to watch for changes & recompile typescript and sass files - use `npm run watch` to watch for changes & recompile typescript and sass files
- Added support for theming the application
## 5.1.0 ## 5.1.0
### New features ### New features

View File

@ -1,5 +1,6 @@
import remote from "@electron/remote"; import remote from "@electron/remote";
import { ipcRenderer, shell } from "electron"; import { ipcRenderer, shell } from "electron";
import fs from "fs";
import { globalEvents } from "../../constants/globalEvents"; import { globalEvents } from "../../constants/globalEvents";
import { settings } from "../../constants/settings"; import { settings } from "../../constants/settings";
import { settingsStore } from "./../../scripts/settings"; import { settingsStore } from "./../../scripts/settings";
@ -24,6 +25,36 @@ let adBlock: HTMLInputElement,
trayIcon: HTMLInputElement, trayIcon: HTMLInputElement,
updateFrequency: HTMLInputElement; updateFrequency: HTMLInputElement;
function getThemeFiles() {
const selectElement = document.getElementById("themesList") as HTMLSelectElement;
const fileNames = fs.readdirSync(process.resourcesPath).filter((file) => file.endsWith(".css"));
const options = fileNames.map((name) => {
return new Option(name, name);
});
// empty old options
const oldOptions = document.querySelectorAll("#themesList option");
oldOptions.forEach((o) => o.remove());
[new Option("Tidal - Default", "none")].concat(options).forEach((option) => {
selectElement.add(option, null);
});
}
function handleFileUploads() {
const fileMessage = document.getElementById("file-message");
fileMessage.innerText = "or drag and drop files here";
document.getElementById("theme-files").addEventListener("change", function (e: any) {
Array.from(e.target.files).forEach((file: File) => {
const destination = `${process.resourcesPath}/${file.name}`;
fs.copyFileSync(file.path, destination, null);
});
fileMessage.innerText = `${e.target.files.length} files successfully uploaded`;
getThemeFiles();
});
}
/** /**
* Sync the UI forms with the current settings * Sync the UI forms with the current settings
*/ */
@ -79,6 +110,9 @@ window.addEventListener("DOMContentLoaded", () => {
return document.getElementById(id) as HTMLInputElement; return document.getElementById(id) as HTMLInputElement;
} }
getThemeFiles();
handleFileUploads();
document.getElementById("close").addEventListener("click", hide); document.getElementById("close").addEventListener("click", hide);
document.getElementById("restart").addEventListener("click", restart); document.getElementById("restart").addEventListener("click", restart);
document.querySelectorAll(".external-link").forEach((elem) => document.querySelectorAll(".external-link").forEach((elem) =>

View File

@ -35,6 +35,9 @@
<input type="radio" name="tab" id="advanced" /> <input type="radio" name="tab" id="advanced" />
<label for="advanced">Advanced</label> <label for="advanced">Advanced</label>
<input type="radio" name="tab" id="theming" />
<label for="theming">Theming</label>
<input type="radio" name="tab" id="about" /> <input type="radio" name="tab" id="about" />
<label for="about">About</label> <label for="about">About</label>
@ -226,17 +229,6 @@
<input id="updateFrequency" type="number" class="text-input" name="updateFrequency" /> <input id="updateFrequency" type="number" class="text-input" name="updateFrequency" />
</div> </div>
</div> </div>
<div class="group__option">
<div class="group__description">
<h4>Custom CSS</h4>
<p>
The css that you put in here will be injected into a style tag in the head of the document.
</p>
</div>
</div>
</div>
<textarea id="customCSS" class="textarea" cols="40" rows="8" spellcheck="false"></textarea>
<div class="group"> <div class="group">
<p class="group__title">Flags</p> <p class="group__title">Flags</p>
<div class="group__option"> <div class="group__option">
@ -277,6 +269,53 @@
</div> </div>
</section> </section>
<section id="theming-section" class="tabs__section">
<div class="group">
<p class="group__title">Theming</p>
<div class="group__option">
<div class="group__description">
<h4>Custom CSS</h4>
<p>
The css that you put in here will be injected into a style tag in the head of the document.
</p>
</div>
</div>
</div>
<textarea id="customCSS" class="textarea" cols="40" rows="8" spellcheck="false"></textarea>
<div class="group">
<p class="group__title">Theme files</p>
<div class="group__option">
<div class="group__description">
<h4>Current theme</h4>
<p>
Select a theme below or "Tidal - Default" to return to the original Tidal look.
</p>
<select id="themesList" name="themesList">
</select>
</div>
</div>
<div class="group__option">
<div class="group__description">
<h4>Upload new themes</h4>
<p>
Click the button and select the css files to import. They will be added to the theme list
automatically.
</p>
<div class="file-drop-area">
<div>
<span class="file-btn">Choose files</span>
<span id="file-message" class="file-msg">or drag and drop files here</span>
<input id="theme-files" class="file-input" type="file" accept=".css" multiple>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="about-section" class="tabs__section about-section"> <section id="about-section" class="tabs__section about-section">
<img alt="tidal icon" class="about-section__icon" src="./icon.png" /> <img alt="tidal icon" class="about-section__icon" src="./icon.png" />
<p class="about-section__text"> <p class="about-section__text">

View File

@ -156,7 +156,7 @@ html {
display: none; display: none;
} }
@for $i from 1 to 6 { @for $i from 1 to 7 {
.settings > input:nth-child(#{$i * 2 - 1}):checked ~ & > .tabs__section:nth-child(#{$i}) { .settings > input:nth-child(#{$i * 2 - 1}):checked ~ & > .tabs__section:nth-child(#{$i}) {
display: block; display: block;
} }
@ -361,3 +361,57 @@ html {
} }
} }
} }
// file upload
.file-drop-area {
position: relative;
display: flex;
align-items: center;
width: 100%;
max-width: 100%;
padding: 25px 0 25px 0px;
border: 1px dashed $tidal-grey;
border-radius: 3px;
transition: 0.2s;
&.is-active {
background-color: $black;
}
div {
padding-left: 25px;
}
}
.file-btn {
flex-shrink: 0;
background-color: $black;
border: 1px solid $tidal-grey;
border-radius: 3px;
padding: 8px 15px;
margin-right: 10px;
font-size: 12px;
text-transform: uppercase;
}
.file-msg {
font-size: small;
font-weight: 300;
line-height: 1.4;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.file-input {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
cursor: pointer;
opacity: 0;
&:focus {
outline: none;
}
}