mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2025-09-17 09:09:19 +02:00
Compare commits
6 Commits
3df82b93db
...
5.7.1
Author | SHA1 | Date | |
---|---|---|---|
0dadce4596 | |||
9e2cbaed38 | |||
33070c157a | |||
eb91b66ac6 | |||
68f76a9e63 | |||
cbb22ba688 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -6,8 +6,10 @@
|
||||
"Flatpak",
|
||||
"geqnfr",
|
||||
"hifi",
|
||||
"libnotify",
|
||||
"listenbrainz",
|
||||
"playpause",
|
||||
"prs",
|
||||
"rescrobbler",
|
||||
"scrobble",
|
||||
"scrobbling",
|
||||
|
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [5.7.1]
|
||||
|
||||
- Fixed mpris not being set up correctly due to capitalization of the instance name.
|
||||
|
||||
## [5.7.0]
|
||||
|
||||
- Renamed app to TIDAL Hi-Fi.
|
||||
@@ -12,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added settings to customize the Discord rich presence information
|
||||
- Discord settings are now also collapsible like the ListenBrainz ones are
|
||||
- Restyled settings menu to include version number and useful links on the about page
|
||||

|
||||
- The ListenBrainz integration has been extended with a configurable (5 seconds by default) delay in song reporting so that it doesn't spam the API when you are cycling through songs.
|
||||
- Custom CSS now also applies to settings window
|
||||

|
||||
|
||||
## [5.6.0]
|
||||
|
||||
|
@@ -51,10 +51,11 @@ The web version of [listen.tidal.com](https://listen.tidal.com) running in elect
|
||||
- Songwhip.com integration (hotkey `ctrl + w`)
|
||||
- Discord RPC integration (showing "now listening", "Browsing", etc)
|
||||
- MPRIS integration
|
||||
- UI + Json config (`~/.config/tidal-hifi/`, or `~/.var/app/com.mastermindzh.tidal-hifi/` for Flatpak)
|
||||
|
||||
## Contributions
|
||||
|
||||
To contribute you can use the standard GitHub features (issues, prs, etc) or join the discord server to talk with like-minded individuals.
|
||||
To contribute you can use the standard GitHub features (issues, prs, etc.) or join the discord server to talk with like-minded individuals.
|
||||
|
||||
-  [Join the Discord server](https://discord.gg/yhNwf4v4He)
|
||||
|
||||
|
BIN
docs/images/customcss-menu.png
Normal file
BIN
docs/images/customcss-menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 KiB |
BIN
docs/images/new-about.png
Normal file
BIN
docs/images/new-about.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "TIDAL Hi-Fi",
|
||||
"version": "5.6.0",
|
||||
"version": "5.7.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "TIDAL Hi-Fi",
|
||||
"version": "5.6.0",
|
||||
"version": "5.7.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.0.10",
|
||||
@@ -9340,4 +9340,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tidal-hifi",
|
||||
"version": "5.6.0",
|
||||
"version": "5.7.1",
|
||||
"description": "Tidal on Electron with widevine(hifi) support",
|
||||
"main": "ts-dist/main.js",
|
||||
"scripts": {
|
||||
|
@@ -29,6 +29,7 @@ export const settings = {
|
||||
enabled: "ListenBrainz.enabled",
|
||||
api: "ListenBrainz.api",
|
||||
token: "ListenBrainz.token",
|
||||
delay: "ListenBrainz.delay",
|
||||
},
|
||||
flags: {
|
||||
root: "flags",
|
||||
|
31
src/features/theming/theming.ts
Normal file
31
src/features/theming/theming.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import fs from "fs";
|
||||
import { settings } from "../../constants/settings";
|
||||
import { settingsStore } from "../../scripts/settings";
|
||||
import { Logger } from "../logger";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function addCustomCss(app: any) {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const selectedTheme = settingsStore.get<string, string>(settings.theme);
|
||||
if (selectedTheme !== "none") {
|
||||
const userThemePath = `${app.getPath("userData")}/themes/${selectedTheme}`;
|
||||
const resourcesThemePath = `${process.resourcesPath}/${selectedTheme}`;
|
||||
const themeFile = fs.existsSync(userThemePath) ? userThemePath : resourcesThemePath;
|
||||
fs.readFile(themeFile, "utf-8", (err, data) => {
|
||||
if (err) {
|
||||
Logger.alert("An error ocurred reading the theme file.", err, alert);
|
||||
return;
|
||||
}
|
||||
|
||||
const themeStyle = document.createElement("style");
|
||||
themeStyle.innerHTML = data;
|
||||
document.head.appendChild(themeStyle);
|
||||
});
|
||||
}
|
||||
|
||||
// read customCSS (it will override the theme)
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = settingsStore.get<string, string[]>(settings.customCSS).join("\n");
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
}
|
@@ -4,6 +4,7 @@ import fs from "fs";
|
||||
import { globalEvents } from "../../constants/globalEvents";
|
||||
import { settings } from "../../constants/settings";
|
||||
import { Logger } from "../../features/logger";
|
||||
import { addCustomCss } from "../../features/theming/theming";
|
||||
import { settingsStore } from "./../../scripts/settings";
|
||||
import { getOptions, getOptionsHeader, getThemeListFromDirectory } from "./theming";
|
||||
|
||||
@@ -44,10 +45,13 @@ let adBlock: HTMLInputElement,
|
||||
enableListenBrainz: HTMLInputElement,
|
||||
ListenBrainzAPI: HTMLInputElement,
|
||||
ListenBrainzToken: HTMLInputElement,
|
||||
listenbrainz_delay: HTMLInputElement,
|
||||
enableWaylandSupport: HTMLInputElement,
|
||||
discord_details_prefix: HTMLInputElement,
|
||||
discord_button_text: HTMLInputElement;
|
||||
|
||||
addCustomCss(app);
|
||||
|
||||
function getThemeFiles() {
|
||||
const selectElement = document.getElementById("themesList") as HTMLSelectElement;
|
||||
const builtInThemes = getThemeListFromDirectory(process.resourcesPath);
|
||||
@@ -75,6 +79,7 @@ function handleFileUploads() {
|
||||
const fileMessage = document.getElementById("file-message");
|
||||
fileMessage.innerText = "or drag and drop files here";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
document.getElementById("theme-files").addEventListener("change", function (e: any) {
|
||||
Array.from(e.target.files).forEach((file: File) => {
|
||||
const destination = `${app.getPath("userData")}/themes/${file.name}`;
|
||||
@@ -128,6 +133,7 @@ function refreshSettings() {
|
||||
enableListenBrainz.checked = settingsStore.get(settings.ListenBrainz.enabled);
|
||||
ListenBrainzAPI.value = settingsStore.get(settings.ListenBrainz.api);
|
||||
ListenBrainzToken.value = settingsStore.get(settings.ListenBrainz.token);
|
||||
listenbrainz_delay.value = settingsStore.get(settings.ListenBrainz.delay);
|
||||
discord_details_prefix.value = settingsStore.get(settings.discord.detailsPrefix);
|
||||
discord_button_text.value = settingsStore.get(settings.discord.buttonText);
|
||||
|
||||
@@ -154,14 +160,6 @@ function hide() {
|
||||
ipcRenderer.send(globalEvents.hideSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart TIDAL Hi-Fi after changes
|
||||
*/
|
||||
function restart() {
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind UI components to functions after DOMContentLoaded
|
||||
*/
|
||||
@@ -174,7 +172,6 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
handleFileUploads();
|
||||
|
||||
document.getElementById("close").addEventListener("click", hide);
|
||||
document.getElementById("restart").addEventListener("click", restart);
|
||||
document.querySelectorAll(".external-link").forEach((elem) =>
|
||||
elem.addEventListener("click", function (event) {
|
||||
openExternal((event.target as HTMLElement).getAttribute("data-url"));
|
||||
@@ -249,6 +246,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
ListenBrainzAPI = get("ListenBrainzAPI");
|
||||
ListenBrainzToken = get("ListenBrainzToken");
|
||||
discord_details_prefix = get("discord_details_prefix");
|
||||
listenbrainz_delay = get("listenbrainz_delay");
|
||||
discord_button_text = get("discord_button_text");
|
||||
|
||||
refreshSettings();
|
||||
@@ -278,8 +276,9 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
settings.ListenBrainz.enabled,
|
||||
switchesWithSettings.listenBrainz
|
||||
);
|
||||
addTextAreaListener(ListenBrainzAPI, settings.ListenBrainz.api);
|
||||
addTextAreaListener(ListenBrainzToken, settings.ListenBrainz.token);
|
||||
addInputListener(ListenBrainzAPI, settings.ListenBrainz.api);
|
||||
addInputListener(ListenBrainzToken, settings.ListenBrainz.token);
|
||||
addInputListener(listenbrainz_delay, settings.ListenBrainz.delay);
|
||||
addInputListener(discord_details_prefix, settings.discord.detailsPrefix);
|
||||
addInputListener(discord_button_text, settings.discord.buttonText);
|
||||
});
|
||||
|
@@ -250,16 +250,22 @@
|
||||
<div class="group__description">
|
||||
<h4>ListenBrainz API Url</h4>
|
||||
<p>There are multiple instances for ListenBrainz you can set the corresponding API url below.</p>
|
||||
<input id="ListenBrainzAPI" type="text" class="text-input" name="ListenBrainzAPI" />
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="ListenBrainzAPI" class="textarea" cols="1" rows="1" spellcheck="false"></textarea>
|
||||
<div class="group__option">
|
||||
<div class="group__description">
|
||||
<h4>ListenBrainz User Token</h4>
|
||||
<p>Provide the user token you can get from the settings page.</p>
|
||||
<input id="ListenBrainzToken" type="text" class="text-input" name="ListenBrainzToken" />
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="ListenBrainzToken" class="textarea" cols="1" rows="1" spellcheck="false"></textarea>
|
||||
</div>
|
||||
<div class="group__description">
|
||||
<h4>ScrobbleDelay</h4>
|
||||
<p>The delay (in ms) to send a song to ListenBrainz. Prevents spamming the API when you fast forward
|
||||
immediately</p>
|
||||
<input id="listenbrainz_delay" type="number" class="text-input" name="listenbrainz_delay" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
165
src/preload.ts
165
src/preload.ts
@@ -1,6 +1,5 @@
|
||||
import { app, dialog, Notification } from "@electron/remote";
|
||||
import { clipboard, ipcRenderer } from "electron";
|
||||
import fs from "fs";
|
||||
import Player from "mpris-service";
|
||||
import { globalEvents } from "./constants/globalEvents";
|
||||
import { settings } from "./constants/settings";
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
import { StoreData } from "./features/listenbrainz/models/storeData";
|
||||
import { Logger } from "./features/logger";
|
||||
import { Songwhip } from "./features/songwhip/songwhip";
|
||||
import { addCustomCss } from "./features/theming/theming";
|
||||
import { MediaStatus } from "./models/mediaStatus";
|
||||
import { Options } from "./models/options";
|
||||
import { downloadFile } from "./scripts/download";
|
||||
@@ -24,6 +24,8 @@ const appName = "TIDAL Hi-Fi";
|
||||
let currentSong = "";
|
||||
let player: Player;
|
||||
let currentPlayStatus = MediaStatus.paused;
|
||||
let currentListenBrainzDelayId: ReturnType<typeof setTimeout>;
|
||||
let scrobbleWaitingForDelay = false;
|
||||
|
||||
const elements = {
|
||||
play: '*[data-test="play"]',
|
||||
@@ -156,32 +158,6 @@ const elements = {
|
||||
},
|
||||
};
|
||||
|
||||
function addCustomCss() {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const selectedTheme = settingsStore.get<string, string>(settings.theme);
|
||||
if (selectedTheme !== "none") {
|
||||
const userThemePath = `${app.getPath("userData")}/themes/${selectedTheme}`;
|
||||
const resourcesThemePath = `${process.resourcesPath}/${selectedTheme}`;
|
||||
const themeFile = fs.existsSync(userThemePath) ? userThemePath : resourcesThemePath;
|
||||
fs.readFile(themeFile, "utf-8", (err, data) => {
|
||||
if (err) {
|
||||
Logger.alert("An error ocurred reading the theme file.", err, alert);
|
||||
return;
|
||||
}
|
||||
|
||||
const themeStyle = document.createElement("style");
|
||||
themeStyle.innerHTML = data;
|
||||
document.head.appendChild(themeStyle);
|
||||
});
|
||||
}
|
||||
|
||||
// read customCSS (it will override the theme)
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = settingsStore.get<string, string[]>(settings.customCSS).join("\n");
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the update frequency from the store
|
||||
* make sure it returns a number, if not use the default
|
||||
@@ -378,6 +354,60 @@ function updateMediaInfo(options: Options, notify: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
function addMPRIS() {
|
||||
if (process.platform === "linux" && settingsStore.get(settings.mpris)) {
|
||||
try {
|
||||
player = Player({
|
||||
name: "tidal-hifi",
|
||||
identity: "tidal-hifi",
|
||||
supportedUriSchemes: ["file"],
|
||||
supportedMimeTypes: [
|
||||
"audio/mpeg",
|
||||
"audio/flac",
|
||||
"audio/x-flac",
|
||||
"application/ogg",
|
||||
"audio/wav",
|
||||
],
|
||||
supportedInterfaces: ["player"],
|
||||
desktopEntry: "tidal-hifi",
|
||||
});
|
||||
// Events
|
||||
const events = {
|
||||
next: "next",
|
||||
previous: "previous",
|
||||
pause: "pause",
|
||||
playpause: "playpause",
|
||||
stop: "stop",
|
||||
play: "play",
|
||||
loopStatus: "repeat",
|
||||
shuffle: "shuffle",
|
||||
seek: "seek",
|
||||
} as { [key: string]: string };
|
||||
Object.keys(events).forEach(function (eventName) {
|
||||
player.on(eventName, function () {
|
||||
const eventValue = events[eventName];
|
||||
switch (events[eventValue]) {
|
||||
case events.playpause:
|
||||
playPause();
|
||||
break;
|
||||
default:
|
||||
elements.click(eventValue);
|
||||
}
|
||||
});
|
||||
});
|
||||
// Override get position function
|
||||
player.getPosition = function () {
|
||||
return convertDuration(elements.getText("current")) * 1000 * 1000;
|
||||
};
|
||||
player.on("quit", function () {
|
||||
app.quit();
|
||||
});
|
||||
} catch (exception) {
|
||||
Logger.log("MPRIS player api not working", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateMpris(options: Options) {
|
||||
if (player) {
|
||||
player.metadata = {
|
||||
@@ -395,6 +425,9 @@ function updateMpris(options: Options) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the listenbrainz service with new data based on a few conditions
|
||||
*/
|
||||
function updateListenBrainz(options: Options) {
|
||||
if (settingsStore.get(settings.ListenBrainz.enabled)) {
|
||||
const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData;
|
||||
@@ -402,12 +435,22 @@ function updateListenBrainz(options: Options) {
|
||||
(!oldData && options.status === MediaStatus.playing) ||
|
||||
(oldData && oldData.title !== options.title)
|
||||
) {
|
||||
ListenBrainz.scrobble(
|
||||
options.title,
|
||||
options.artists,
|
||||
options.status,
|
||||
convertDuration(options.duration)
|
||||
);
|
||||
if (!scrobbleWaitingForDelay) {
|
||||
scrobbleWaitingForDelay = true;
|
||||
clearTimeout(currentListenBrainzDelayId);
|
||||
currentListenBrainzDelayId = setTimeout(
|
||||
() => {
|
||||
ListenBrainz.scrobble(
|
||||
options.title,
|
||||
options.artists,
|
||||
options.status,
|
||||
convertDuration(options.duration)
|
||||
);
|
||||
scrobbleWaitingForDelay = false;
|
||||
},
|
||||
settingsStore.get(settings.ListenBrainz.delay) ?? 0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -528,60 +571,8 @@ setInterval(function () {
|
||||
}
|
||||
}, getUpdateFrequency());
|
||||
|
||||
if (process.platform === "linux" && settingsStore.get(settings.mpris)) {
|
||||
try {
|
||||
player = Player({
|
||||
name: "TIDAL Hi-Fi",
|
||||
identity: "TIDAL Hi-Fi",
|
||||
supportedUriSchemes: ["file"],
|
||||
supportedMimeTypes: [
|
||||
"audio/mpeg",
|
||||
"audio/flac",
|
||||
"audio/x-flac",
|
||||
"application/ogg",
|
||||
"audio/wav",
|
||||
],
|
||||
supportedInterfaces: ["player"],
|
||||
desktopEntry: "tidal-hifi",
|
||||
});
|
||||
// Events
|
||||
const events = {
|
||||
next: "next",
|
||||
previous: "previous",
|
||||
pause: "pause",
|
||||
playpause: "playpause",
|
||||
stop: "stop",
|
||||
play: "play",
|
||||
loopStatus: "repeat",
|
||||
shuffle: "shuffle",
|
||||
seek: "seek",
|
||||
} as { [key: string]: string };
|
||||
Object.keys(events).forEach(function (eventName) {
|
||||
player.on(eventName, function () {
|
||||
const eventValue = events[eventName];
|
||||
switch (events[eventValue]) {
|
||||
case events.playpause:
|
||||
playPause();
|
||||
break;
|
||||
|
||||
default:
|
||||
elements.click(eventValue);
|
||||
}
|
||||
});
|
||||
});
|
||||
// Override get position function
|
||||
player.getPosition = function () {
|
||||
return convertDuration(elements.getText("current")) * 1000 * 1000;
|
||||
};
|
||||
|
||||
player.on("quit", function () {
|
||||
app.quit();
|
||||
});
|
||||
} catch (exception) {
|
||||
console.log("player api not working");
|
||||
}
|
||||
}
|
||||
addCustomCss();
|
||||
addMPRIS();
|
||||
addCustomCss(app);
|
||||
addHotKeys();
|
||||
addIPCEventListeners();
|
||||
addFullScreenListeners();
|
||||
|
@@ -26,6 +26,7 @@ export const settingsStore = new Store({
|
||||
enabled: false,
|
||||
api: "https://api.listenbrainz.org",
|
||||
token: "",
|
||||
delay: 5000,
|
||||
},
|
||||
flags: {
|
||||
disableHardwareMediaKeys: false,
|
||||
@@ -53,6 +54,13 @@ export const settingsStore = new Store({
|
||||
migrationStore.get("disableHardwareMediaKeys") ?? false
|
||||
);
|
||||
},
|
||||
"5.7.0": (migrationStore) => {
|
||||
console.log("running migrations for 5.7.0");
|
||||
migrationStore.set(
|
||||
settings.ListenBrainz.delay,
|
||||
migrationStore.get(settings.ListenBrainz.delay) ?? 5000
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -74,7 +74,7 @@ button.feedBell--kvAbD {
|
||||
.container--PFTHk {
|
||||
background-color: var(--right-queue-background);
|
||||
}
|
||||
.container--cl4MJ{
|
||||
.container--cl4MJ {
|
||||
background-color: var(--search-background);
|
||||
}
|
||||
.searchFieldHighlighted--Fitvs {
|
||||
@@ -83,3 +83,122 @@ button.feedBell--kvAbD {
|
||||
.searchField--EGBSq {
|
||||
background-color: var(--search-background);
|
||||
}
|
||||
|
||||
// Settings window styling
|
||||
|
||||
.settings-window {
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
.settings-window__wrapper {
|
||||
background: var(--main-background);
|
||||
box-shadow: inset 0 0 2px 0 var(--main-feed-button-background);
|
||||
}
|
||||
|
||||
.settings-window__close-button:hover {
|
||||
background: var(--main-feed-button-background);
|
||||
}
|
||||
|
||||
.settings input:checked + label {
|
||||
border-bottom: 2px solid var(--player-control-active-button);
|
||||
color: var(--player-control-active-button);
|
||||
}
|
||||
|
||||
.tabs::-webkit-scrollbar-thumb {
|
||||
background-color: #404248;
|
||||
box-shadow: inset 0 0 10px 2px var(--search-background);
|
||||
}
|
||||
|
||||
.group {
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
.group__description p {
|
||||
color: var(--sidebar-menu-top-text);
|
||||
}
|
||||
.group__description .text-input {
|
||||
border-bottom: solid 1px #333;
|
||||
color: var(--sidebar-menu-top-text);
|
||||
}
|
||||
.group__description .text-input:focus {
|
||||
border-color: var(--player-control-active-button);
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
|
||||
.switch input:checked + .switch__slider {
|
||||
background-color: var(--player-control-active-button);
|
||||
}
|
||||
.switch input:checked + .switch__slider::before {
|
||||
background-color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
.switch input:focus + .switch__slider {
|
||||
box-shadow: inset 0 0 0 1px var(--player-control-active-button);
|
||||
}
|
||||
.switch__slider {
|
||||
background-color: var(--search-background);
|
||||
}
|
||||
.switch__slider::before {
|
||||
background-color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
|
||||
.textarea {
|
||||
background: var(--search-background);
|
||||
color: var(--sidebar-menu-top-text);
|
||||
}
|
||||
.textarea:focus {
|
||||
border-color: var(--player-control-active-button);
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
|
||||
.about-section__version a {
|
||||
background-color: #404248;
|
||||
color: var(--player-control-active-button);
|
||||
}
|
||||
.about-section__links a {
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
|
||||
background-color: var(--search-background);
|
||||
}
|
||||
.about-section__links a i {
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
.about-section__links a:hover {
|
||||
background-color: var(--player-control-favorite);
|
||||
}
|
||||
|
||||
.footer__note {
|
||||
color: var(--sidebar-menu-top-text);
|
||||
}
|
||||
.footer__button {
|
||||
background: #404248;
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
.footer__button:hover {
|
||||
background: #55585f;
|
||||
}
|
||||
|
||||
.file-drop-area {
|
||||
border: 1px dashed var(--sidebar-menu-top-text);
|
||||
}
|
||||
.file-drop-area.is-active {
|
||||
background-color: #17171a;
|
||||
}
|
||||
|
||||
.file-btn {
|
||||
background-color: #17171a;
|
||||
border: 1px solid var(--sidebar-menu-top-text);
|
||||
}
|
||||
|
||||
.select-input {
|
||||
border-bottom: solid 1px #333;
|
||||
color: var(--sidebar-menu-top-text);
|
||||
}
|
||||
.select-input:focus {
|
||||
border-color: var(--player-control-active-button);
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
.select-input option {
|
||||
background-color: var(--search-background);
|
||||
}
|
||||
.select-input option:disabled {
|
||||
color: var(--sidebar-menu-playlist-text);
|
||||
}
|
||||
|
Reference in New Issue
Block a user