From 0120391418fcf1335eae2cf025e57ed31b69c592 Mon Sep 17 00:00:00 2001 From: Diogo Oliveira Date: Mon, 30 Jan 2023 17:49:04 +0000 Subject: [PATCH 01/14] Fix album not updating on playlists --- src/preload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preload.js b/src/preload.js index e23d6ed..2a1401d 100644 --- a/src/preload.js +++ b/src/preload.js @@ -38,7 +38,7 @@ const elements = { bar: '*[data-test="progress-bar"]', footer: "#footerPlayer", album_header_title: '.header-details [data-test="title"]', - playing_title: 'span[data-test="table-cell-title"].css-geqnfr', + playing_title: 'span[data-test="table-cell-title"].css-1vjc1xk', album_name_cell: '[data-test="table-cell-album"]', tracklist_row: '[data-test="tracklist-row"]', volume: '*[data-test="volume"]', From 21d6e57cb90b27309f5ba06a547aeaf4e4efd386 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 7 May 2023 15:48:00 +0200 Subject: [PATCH 02/14] set up css folder --- .gitignore | 1 + src/themes/test.css | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 src/themes/test.css diff --git a/.gitignore b/.gitignore index be23b05..d9b91de 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ build/linux/arch/* !build/linux/arch/install.sh *.css *.css.map +!src/themes/**/**.css # JetBrains IDE configuration .idea diff --git a/src/themes/test.css b/src/themes/test.css new file mode 100644 index 0000000..6345fd3 --- /dev/null +++ b/src/themes/test.css @@ -0,0 +1,3 @@ +h1 { + color: green; +} From a1c02dfed33e4e88de8a8b49342a7f8d49036a2f Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 7 May 2023 16:13:30 +0200 Subject: [PATCH 03/14] last files transformed from js -> ts --- src/constants/{flags.js => flags.ts} | 4 +--- src/constants/{globalEvents.js => globalEvents.ts} | 4 +--- src/constants/{mediaKeys.js => mediaKeys.ts} | 6 ++---- src/constants/{statuses.js => statuses.ts} | 2 +- src/constants/{values.js => values.ts} | 2 +- src/main.ts | 12 ++++++------ src/pages/settings/preload.ts | 2 +- src/preload.ts | 6 +++--- src/scripts/discord.ts | 2 +- src/scripts/express.ts | 4 ++-- src/scripts/mediaInfo.ts | 2 +- src/scripts/menu.ts | 4 ++-- 12 files changed, 22 insertions(+), 28 deletions(-) rename src/constants/{flags.js => flags.ts} (70%) rename src/constants/{globalEvents.js => globalEvents.ts} (83%) rename src/constants/{mediaKeys.js => mediaKeys.ts} (56%) rename src/constants/{statuses.js => statuses.ts} (63%) rename src/constants/{values.js => values.ts} (56%) diff --git a/src/constants/flags.js b/src/constants/flags.ts similarity index 70% rename from src/constants/flags.js rename to src/constants/flags.ts index 88813ae..64c36ae 100644 --- a/src/constants/flags.js +++ b/src/constants/flags.ts @@ -1,6 +1,4 @@ -const flags = { +export const flags: { [key: string]: { flag: string; value?: any }[] } = { gpuRasterization: [{ flag: "enable-gpu-rasterization", value: undefined }], disableHardwareMediaKeys: [{ flag: "disable-features", value: "HardwareMediaKeyHandling" }], }; - -module.exports = flags; diff --git a/src/constants/globalEvents.js b/src/constants/globalEvents.ts similarity index 83% rename from src/constants/globalEvents.js rename to src/constants/globalEvents.ts index c330be4..b60b5c9 100644 --- a/src/constants/globalEvents.js +++ b/src/constants/globalEvents.ts @@ -1,4 +1,4 @@ -const globalEvents = { +export const globalEvents = { play: "play", pause: "pause", playPause: "playPause", @@ -11,5 +11,3 @@ const globalEvents = { storeChanged: "storeChanged", error: "error", }; - -module.exports = globalEvents; diff --git a/src/constants/mediaKeys.js b/src/constants/mediaKeys.ts similarity index 56% rename from src/constants/mediaKeys.js rename to src/constants/mediaKeys.ts index cc0828a..ba8b719 100644 --- a/src/constants/mediaKeys.js +++ b/src/constants/mediaKeys.ts @@ -1,9 +1,7 @@ -const globalEvents = require("./globalEvents"); +import { globalEvents } from "./globalEvents"; -const mediaKeys = { +export const mediaKeys = { MediaPlayPause: globalEvents.playPause, MediaNextTrack: globalEvents.next, MediaPreviousTrack: globalEvents.previous, }; - -module.exports = mediaKeys; diff --git a/src/constants/statuses.js b/src/constants/statuses.ts similarity index 63% rename from src/constants/statuses.js rename to src/constants/statuses.ts index 33ae17a..3209307 100644 --- a/src/constants/statuses.js +++ b/src/constants/statuses.ts @@ -1,4 +1,4 @@ -module.exports = { +export const statuses = { playing: "playing", paused: "paused", }; diff --git a/src/constants/values.js b/src/constants/values.ts similarity index 56% rename from src/constants/values.js rename to src/constants/values.ts index 267a8b4..a4e2764 100644 --- a/src/constants/values.js +++ b/src/constants/values.ts @@ -1,3 +1,3 @@ -module.exports = { +export default { name: "tidal-hifi", }; diff --git a/src/main.ts b/src/main.ts index 9d7ea4f..6a040e7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,9 +9,9 @@ import { session, } from "electron"; import path from "path"; -import flagValues from "./constants/flags"; -import globalEvents from "./constants/globalEvents"; -import mediaKeys from "./constants/mediaKeys"; +import { flags } from "./constants/flags"; +import { globalEvents } from "./constants/globalEvents"; +import { mediaKeys } from "./constants/mediaKeys"; import { initRPC, rpc, unRPC } from "./scripts/discord"; import { startExpress } from "./scripts/express"; import { updateMediaInfo } from "./scripts/mediaInfo"; @@ -37,11 +37,11 @@ const PROTOCOL_PREFIX = "tidal"; setFlags(); function setFlags() { - const flags = settingsStore.get(settings.flags.root); - if (flags) { + const flagsFromSettings = settingsStore.get(settings.flags.root); + if (flagsFromSettings) { for (const [key, value] of Object.entries(flags)) { if (value) { - (flagValues as any)[key].forEach((flag: any) => { + flags[key].forEach((flag) => { console.log(`enabling command line switch ${flag.flag} with value ${flag.value}`); app.commandLine.appendSwitch(flag.flag, flag.value); }); diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index c2e569d..fb64769 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -1,6 +1,6 @@ import remote from "@electron/remote"; import { ipcRenderer, shell } from "electron"; -import globalEvents from "../../constants/globalEvents"; +import { globalEvents } from "../../constants/globalEvents"; import { settings } from "../../constants/settings"; import { settingsStore } from "./../../scripts/settings"; diff --git a/src/preload.ts b/src/preload.ts index 5e17004..f35474f 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -1,15 +1,15 @@ import { Notification, app, dialog } from "@electron/remote"; import { ipcRenderer } from "electron"; import Player from "mpris-service"; -import globalEvents from "./constants/globalEvents"; +import { globalEvents } from "./constants/globalEvents"; import { settings } from "./constants/settings"; -import statuses from "./constants/statuses"; +import { statuses } from "./constants/statuses"; import { Options } from "./models/options"; import { downloadFile } from "./scripts/download"; import { addHotkey } from "./scripts/hotkeys"; -import { setTitle } from "./scripts/window-functions"; import { settingsStore } from "./scripts/settings"; +import { setTitle } from "./scripts/window-functions"; const notificationPath = `${app.getPath("userData")}/notification.jpg`; const appName = "Tidal Hifi"; let currentSong = ""; diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index 4d07a21..909c5b8 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -1,6 +1,6 @@ import { Client } from "discord-rpc"; import { app, ipcMain } from "electron"; -import globalEvents from "../constants/globalEvents"; +import { globalEvents } from "../constants/globalEvents"; import { MediaStatus } from "../models/mediaStatus"; import { mediaInfo } from "./mediaInfo"; diff --git a/src/scripts/express.ts b/src/scripts/express.ts index 3667621..6097a6f 100644 --- a/src/scripts/express.ts +++ b/src/scripts/express.ts @@ -1,8 +1,8 @@ import { BrowserWindow, dialog } from "electron"; import express, { Response } from "express"; import fs from "fs"; -import globalEvents from "./../constants/globalEvents"; -import statuses from "./../constants/statuses"; +import { globalEvents } from "./../constants/globalEvents"; +import { statuses } from "./../constants/statuses"; import { mediaInfo } from "./mediaInfo"; import { settingsStore } from "./settings"; import { settings } from "../constants/settings"; diff --git a/src/scripts/mediaInfo.ts b/src/scripts/mediaInfo.ts index e35f7cc..1341a08 100644 --- a/src/scripts/mediaInfo.ts +++ b/src/scripts/mediaInfo.ts @@ -1,5 +1,5 @@ import { MediaInfo } from "../models/mediaInfo"; -import statuses from "./../constants/statuses"; +import { statuses } from "./../constants/statuses"; export const mediaInfo = { title: "", diff --git a/src/scripts/menu.ts b/src/scripts/menu.ts index 9319b42..786842b 100644 --- a/src/scripts/menu.ts +++ b/src/scripts/menu.ts @@ -1,7 +1,7 @@ import { BrowserWindow, Menu, app } from "electron"; -const { showSettingsWindow } = require("./settings"); +import { showSettingsWindow } from "./settings"; const isMac = process.platform === "darwin"; -const { name } = require("./../constants/values"); +import name from "./../constants/values"; const settingsMenuEntry = { label: "Settings", From 32ade76ae3dd4a2ef1f252ed9703c46600e75f34 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 7 May 2023 23:25:35 +0200 Subject: [PATCH 04/14] chore: compile sass themes --- package-lock.json | 394 ++++++++++++++++++++++++++++++++++++++++- package.json | 4 +- src/themes/csstest.css | 3 + src/themes/test.css | 3 - src/themes/test.scss | 7 + 5 files changed, 405 insertions(+), 6 deletions(-) create mode 100644 src/themes/csstest.css delete mode 100644 src/themes/test.css create mode 100644 src/themes/test.scss diff --git a/package-lock.json b/package-lock.json index 39afe00..00a6e83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "eslint": "^8.39.0", "js-yaml": "^4.1.0", "markdown-toc": "^1.2.0", + "node-sass": "^8.0.0", "prettier": "^2.8.8", "stylelint": "^15.6.0", "stylelint-config-standard": "^33.0.0", @@ -1770,6 +1771,15 @@ "node": ">=0.12.0" } }, + "node_modules/async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -4086,6 +4096,18 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "dependencies": { + "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -4108,6 +4130,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -4330,6 +4361,62 @@ "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", "dev": true }, + "node_modules/globule": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", + "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", + "dev": true, + "dependencies": { + "glob": "~7.1.1", + "lodash": "^4.17.21", + "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/globule/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/globule/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globule/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/got": { "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", @@ -5079,6 +5166,12 @@ "node": "*" } }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "dev": true + }, "node_modules/js-sdsl": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", @@ -5831,7 +5924,7 @@ "version": "2.17.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "optional": true + "devOptional": true }, "node_modules/nanoid": { "version": "3.3.6", @@ -5992,6 +6085,253 @@ "node": ">=10" } }, + "node_modules/node-sass": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-8.0.0.tgz", + "integrity": "sha512-jPzqCF2/e6JXw6r3VxfIqYc8tKQdkj5Z/BDATYyG6FL6b/LuYBNFGFVhus0mthcWifHm/JzBpKAd+3eXsWeK/A==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "async-foreach": "^0.1.3", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "lodash": "^4.17.15", + "make-fetch-happen": "^10.0.4", + "meow": "^9.0.0", + "nan": "^2.17.0", + "node-gyp": "^8.4.1", + "sass-graph": "^4.0.1", + "stdout-stream": "^1.4.0", + "true-case-path": "^2.2.1" + }, + "bin": { + "node-sass": "bin/node-sass" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/node-sass/node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/node-sass/node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-sass/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/node-sass/node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-sass/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/node-sass/node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "dev": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/node-sass/node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-sass/node_modules/node-gyp/node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-sass/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/node-sass/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-sass/node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-sass/node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/node-sass/node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/node-sass/node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, "node_modules/nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", @@ -7244,11 +7584,48 @@ "node": ">=14.0.0" } }, + "node_modules/sass-graph": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz", + "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "lodash": "^4.17.11", + "scss-tokenizer": "^0.4.3", + "yargs": "^17.2.1" + }, + "bin": { + "sassgraph": "bin/sassgraph" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "node_modules/scss-tokenizer": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz", + "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==", + "dev": true, + "dependencies": { + "js-base64": "^2.4.9", + "source-map": "^0.7.3" + } + }, + "node_modules/scss-tokenizer/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -7639,6 +8016,15 @@ "node": ">= 0.8" } }, + "node_modules/stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, "node_modules/stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", @@ -8255,6 +8641,12 @@ "node": ">=8" } }, + "node_modules/true-case-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", + "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", + "dev": true + }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", diff --git a/package.json b/package.json index c377e6c..b1a68d7 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "build-base": "npm run builder -- -c ./build/electron-builder.base.yml", "prebuilder": "npm run compile", "builder": "electron-builder --publish=never", - "sass": "sass ./src/pages/settings/settings.scss ./src/pages/settings/settings.css", + "sass": "sass ./src/pages/settings/settings.scss ./src/pages/settings/settings.css && sass src/themes:ts-dist/themes", "style-lint": "npx stylelint **/*.scss", "style-lint-fix": "npx stylelint --fix **/*.scss" }, @@ -64,4 +64,4 @@ "typescript": "^5.0.4" }, "prettier": "@mastermindzh/prettier-config" -} +} \ No newline at end of file diff --git a/src/themes/csstest.css b/src/themes/csstest.css new file mode 100644 index 0000000..f331fdf --- /dev/null +++ b/src/themes/csstest.css @@ -0,0 +1,3 @@ +h2 { + color: black; +} diff --git a/src/themes/test.css b/src/themes/test.css deleted file mode 100644 index 6345fd3..0000000 --- a/src/themes/test.css +++ /dev/null @@ -1,3 +0,0 @@ -h1 { - color: green; -} diff --git a/src/themes/test.scss b/src/themes/test.scss new file mode 100644 index 0000000..2de34b6 --- /dev/null +++ b/src/themes/test.scss @@ -0,0 +1,7 @@ +h1 { + color: black; + + .title { + color: blue; + } +} From 757f8511c029201033cdd3fcde7508158997c9ab Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Mon, 8 May 2023 00:03:05 +0200 Subject: [PATCH 05/14] ci: added theme files to resources --- .gitignore | 1 + build/electron-builder.base.yml | 2 ++ package.json | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d9b91de..cb592b4 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ build/linux/arch/* .idea ts-dist/** ts-dist +themes diff --git a/build/electron-builder.base.yml b/build/electron-builder.base.yml index b35a36c..27f2319 100644 --- a/build/electron-builder.base.yml +++ b/build/electron-builder.base.yml @@ -7,6 +7,8 @@ snap: plugs: - default - screen-inhibit-control +extraResources: + - "themes/**" linux: category: AudioVideo icon: assets/icons diff --git a/package.json b/package.json index 09cbece..6a1ed92 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "build-base": "npm run builder -- -c ./build/electron-builder.base.yml", "prebuilder": "npm run compile", "builder": "electron-builder --publish=never", - "sass": "sass ./src/pages/settings/settings.scss ./src/pages/settings/settings.css && sass src/themes:ts-dist/themes", + "sass": "sass ./src/pages/settings/settings.scss ./src/pages/settings/settings.css && sass --no-source-map src/themes:themes", "style-lint": "npx stylelint **/*.scss", "style-lint-fix": "npx stylelint --fix **/*.scss" }, From 77a853e98045c647c754e76361104806ab43e920 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Mon, 8 May 2023 22:31:22 +0200 Subject: [PATCH 06/14] feat: add .css theme file upload and a unstyled theme selector --- CHANGELOG.md | 2 + src/pages/settings/preload.ts | 34 +++++++++++++ src/pages/settings/settings.html | 87 +++++++++++++++++++++++--------- src/pages/settings/settings.scss | 56 +++++++++++++++++++- 4 files changed, 154 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24397c2..5fa7a58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 - use `npm run watch` to watch for changes & recompile typescript and sass files +- Added support for theming the application + ## 5.1.0 ### New features diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index fb64769..830c5e4 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -1,5 +1,6 @@ import remote 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"; @@ -24,6 +25,36 @@ let adBlock: HTMLInputElement, trayIcon: 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 */ @@ -79,6 +110,9 @@ window.addEventListener("DOMContentLoaded", () => { return document.getElementById(id) as HTMLInputElement; } + getThemeFiles(); + handleFileUploads(); + document.getElementById("close").addEventListener("click", hide); document.getElementById("restart").addEventListener("click", restart); document.querySelectorAll(".external-link").forEach((elem) => diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index b784a02..63b2599 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -35,6 +35,9 @@ + + + @@ -226,6 +229,49 @@ +
+

Flags

+
+
+

Disable hardware built-in media keys

+

+ Also prevents certain desktop environments from recognizing the chrome MPRIS + client separately from the custom MPRIS client. +

+
+ +
+
+
+

Enable GPU rasterization

+

Move a part of the rendering to the GPU for increased performance.

+
+ +
+
+
+

Disable Background Throttling

+

+ Makes app more responsive while in the background, at the cost of performance. +

+
+ +
+
+ + +
+
+

Theming

Custom CSS

@@ -238,41 +284,34 @@
-

Flags

+

Theme files

-

Disable hardware built-in media keys

+

Current theme

- Also prevents certain desktop environments from recognizing the chrome MPRIS - client separately from the custom MPRIS client. + Select a theme below or "Tidal - Default" to return to the original Tidal look.

+
-
+
-

Enable GPU rasterization

-

Move a part of the rendering to the GPU for increased performance.

-
- -
-
-
-

Disable Background Throttling

+

Upload new themes

- Makes app more responsive while in the background, at the cost of performance. + Click the button and select the css files to import. They will be added to the theme list + automatically.

+
+
+ Choose files + or drag and drop files here + +
+
-
diff --git a/src/pages/settings/settings.scss b/src/pages/settings/settings.scss index 537dbd5..8813c6a 100644 --- a/src/pages/settings/settings.scss +++ b/src/pages/settings/settings.scss @@ -156,7 +156,7 @@ html { 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}) { 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; + } +} From 4350ab9bd9908cdb494c3a81a383271884684b60 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Tue, 9 May 2023 23:28:45 +0200 Subject: [PATCH 07/14] added styling on theme selector --- package.json | 3 ++- src/pages/settings/preload.ts | 8 ++++++-- src/pages/settings/settings.html | 2 +- src/pages/settings/settings.scss | 25 +++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 6a1ed92..11d102b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "compile": "tsc && npm run sass-and-copy", "watch": "tsc-watch --onSuccess \"npm run sass-and-copy\"", "copy-files": "copyfiles -u 1 --exclude './src/**/*.ts' --exclude './src/**/*.scss' \"./src/**/*\" ts-dist", - "sass-and-copy": "npm run sass && npm run copy-files", + "copy-themes-dev": "copyfiles -u 1 \"./themes/*\" node_modules/electron/dist/resources", + "sass-and-copy": "npm run sass && npm run copy-files && npm run copy-themes-dev", "build": "npm run builder -- -c ./build/electron-builder.yml", "build-deb": "npm run builder -- -c ./build/electron-builder.deb.yml", "build-unpacked": "npm run builder -- -c ./build/electron-builder.unpacked.yml", diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index 830c5e4..b91479b 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -27,9 +27,13 @@ let adBlock: HTMLInputElement, function getThemeFiles() { const selectElement = document.getElementById("themesList") as HTMLSelectElement; - const fileNames = fs.readdirSync(process.resourcesPath).filter((file) => file.endsWith(".css")); + const fileNames = fs + .readdirSync(process.resourcesPath) + .filter((file) => file.endsWith(".css")) + .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); + const options = fileNames.map((name) => { - return new Option(name, name); + return new Option(name.replace(".css", ""), name); }); // empty old options diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index 63b2599..583b24b 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -291,7 +291,7 @@

Select a theme below or "Tidal - Default" to return to the original Tidal look.

- diff --git a/src/pages/settings/settings.scss b/src/pages/settings/settings.scss index 8813c6a..75c99b1 100644 --- a/src/pages/settings/settings.scss +++ b/src/pages/settings/settings.scss @@ -230,8 +230,6 @@ html { border-color: $tidal-blue; color: $white; } - - // --- Switch slider component --- } } } @@ -415,3 +413,26 @@ html { outline: none; } } + +.select-input { + display: block; + width: 100%; + margin-bottom: 10px; + padding: 5px 0; + transition: 0.2s; + border: 0; + border-bottom: solid 1px $grey-333; + outline: none; + background: transparent; + color: $tidal-grey; + font-size: 14px; + + &:focus { + border-color: $tidal-blue; + color: $white; + } + + option { + background-color: $tidal-grey-darkest; + } +} From 6e5a2c626c612f42b52fa82f6a93fa63f9718b8a Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Tue, 9 May 2023 23:57:16 +0200 Subject: [PATCH 08/14] feat: theme selection is now stored in the config file --- src/constants/settings.ts | 1 + src/pages/settings/preload.ts | 15 +++++++++++++-- src/scripts/settings.ts | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 04444e6..df2c39f 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -33,6 +33,7 @@ export const settings = { singleInstance: "singleInstance", skipArtists: "skipArtists", skippedArtists: "skippedArtists", + theme: "theme", trayIcon: "trayIcon", updateFrequency: "updateFrequency", windowBounds: { diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index b91479b..b693af4 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -22,6 +22,7 @@ let adBlock: HTMLInputElement, singleInstance: HTMLInputElement, skipArtists: HTMLInputElement, skippedArtists: HTMLInputElement, + theme: HTMLSelectElement, trayIcon: HTMLInputElement, updateFrequency: HTMLInputElement; @@ -79,6 +80,7 @@ function refreshSettings() { port.value = settingsStore.get(settings.apiSettings.port); singleInstance.checked = settingsStore.get(settings.singleInstance); skipArtists.checked = settingsStore.get(settings.skipArtists); + theme.value = settingsStore.get(settings.theme); skippedArtists.value = settingsStore.get(settings.skippedArtists).join("\n"); trayIcon.checked = settingsStore.get(settings.trayIcon); updateFrequency.value = settingsStore.get(settings.updateFrequency); @@ -110,8 +112,8 @@ function restart() { * Bind UI components to functions after DOMContentLoaded */ window.addEventListener("DOMContentLoaded", () => { - function get(id: string): HTMLInputElement { - return document.getElementById(id) as HTMLInputElement; + function get(id: string): T { + return document.getElementById(id) as T; } getThemeFiles(); @@ -143,6 +145,13 @@ window.addEventListener("DOMContentLoaded", () => { }); } + function addSelectListener(source: HTMLSelectElement, key: string) { + source.addEventListener("change", () => { + settingsStore.set(key, source.value); + ipcRenderer.send(globalEvents.storeChanged); + }); + } + ipcRenderer.on("refreshData", () => { refreshSettings(); }); @@ -165,6 +174,7 @@ window.addEventListener("DOMContentLoaded", () => { notifications = get("notifications"); playBackControl = get("playBackControl"); port = get("port"); + theme = get("themesList"); trayIcon = get("trayIcon"); skipArtists = get("skipArtists"); skippedArtists = get("skippedArtists"); @@ -190,6 +200,7 @@ window.addEventListener("DOMContentLoaded", () => { addInputListener(skipArtists, settings.skipArtists); addTextAreaListener(skippedArtists, settings.skippedArtists); addInputListener(singleInstance, settings.singleInstance); + addSelectListener(theme, settings.theme); addInputListener(trayIcon, settings.trayIcon); addInputListener(updateFrequency, settings.updateFrequency); }); diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 8697d6c..b20b6ae 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -30,6 +30,7 @@ export const settingsStore = new Store({ singleInstance: true, skipArtists: false, skippedArtists: [""], + theme: "none", trayIcon: true, updateFrequency: 500, windowBounds: { width: 800, height: 600 }, From a408a6a8ccd2120fb62eb84e6c68a618f29fb3f5 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Wed, 10 May 2023 00:02:19 +0200 Subject: [PATCH 09/14] theme: added Tokyo Night by https://github.com/wojciech-zurek --- .gitignore | 2 +- src/themes/Tokyo Night.scss | 82 +++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/themes/Tokyo Night.scss diff --git a/.gitignore b/.gitignore index cb592b4..42ce16d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,10 +9,10 @@ build/linux/arch/* !build/linux/arch/install.sh *.css *.css.map -!src/themes/**/**.css # JetBrains IDE configuration .idea ts-dist/** ts-dist themes +!src/themes diff --git a/src/themes/Tokyo Night.scss b/src/themes/Tokyo Night.scss new file mode 100644 index 0000000..b9f6a73 --- /dev/null +++ b/src/themes/Tokyo Night.scss @@ -0,0 +1,82 @@ +:root { + --footer-player-background: #1a1b26; + --sidebar-background: #1a1b26; + --sidebar-hover-background: #414868; + --sidebar-menu-top-text: #565f89; + --sidebar-menu-playlist-text: #565f89; + --search-background: #1a1b26; + --main-background: #16161e; + --main-navigation-control-background: #1a1b26; + --main-feed-button-background: #1a1b26; + --player-control-background: #24283b; + --player-control-active-button: #ff9e64; + --player-progress-bar: #ff9e64; + --indicator-hifi-background: #9ece6a; + --indicator-hifi-span: #1a1b26; + --player-control-favorite: #f7768e; + --search-dialog-background: #24283b; + --right-queue-background: #24283b; +} +.player--fNPGt.notFullscreen--ugyc2 { + background-color: var(--footer-player-background); +} +.sidebar--WvRg_ { + background-color: var(--sidebar-background); + contain: strict; + flex-grow: 1; + overflow-y: auto; +} +.item--VTpWS:hover { + background-color: var(--sidebar-hover-background); +} +.main--LUnJp { + background-color: var(--main-background); +} +button.button--ncJwL { + background-color: var(--main-navigation-control-background); +} +.player--fNPGt.lossLess--g5Jss button.withBackground[aria-checked="true"] path { + fill: var(--player-control-active-button); +} +.player--fNPGt.lossLess--g5Jss button.withBackground[aria-checked="true"] { + background-color: var(--player-control-background); +} +.activeItem--qV6eL .activeItem--qV6eL .playlistItem--YARJh .section--FI41E.playingItem--eWkYS { + color: #565f89; +} +.progressBarWrapper--WZfox { + color: var(--player-progress-bar); +} +.playbackControls--FLeZA button .tidal-ui__icon { + transform: scale(1); +} +.css-11m9iw3 { + background-color: var(--indicator-hifi-background); +} +.css-11m9iw3 span { + color: var(--indicator-hifi-span); +} +.activeItem--qV6eL { + color: var(--sidebar-menu-top-text); +} +.activeItem--qV6eL .playlistItem--YARJh { + color: var(--sidebar-menu-playlist-text); +} +button.feedBell--B8anb { + background-color: var(--main-feed-button-background); +} +.baseContainer--cbf17 { + background-color: var(--search-dialog-background); +} +.favoriteButton--TtBlM.is-favorite path { + fill: var(--player-control-favorite); +} +.container--mkEWd { + background-color: var(--right-queue-background); +} +.container--vJVjO { + background-color: var(--search-background); +} +.searchFieldHighlighted--Fitvs { + color: var(--snow-white); +} From 1761c8dd40a033c95979dc8c1ee5b22c14fc5844 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Wed, 10 May 2023 22:07:11 +0200 Subject: [PATCH 10/14] feat: theme files are now loaded & applied on startup --- src/pages/settings/preload.ts | 2 +- src/preload.ts | 19 ++++++++++++++++++- src/themes/Blood.scss | 10 ++++++++++ src/themes/csstest.css | 3 --- src/themes/test.scss | 7 ------- 5 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 src/themes/Blood.scss delete mode 100644 src/themes/csstest.css delete mode 100644 src/themes/test.scss diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index b693af4..d6f51f6 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -66,7 +66,7 @@ function handleFileUploads() { function refreshSettings() { adBlock.checked = settingsStore.get(settings.adBlock); api.checked = settingsStore.get(settings.api); - customCSS.value = settingsStore.get(settings.customCSS); + customCSS.value = settingsStore.get(settings.customCSS).join("\n"); disableBackgroundThrottle.checked = settingsStore.get(settings.disableBackgroundThrottle); disableHardwareMediaKeys.checked = settingsStore.get(settings.flags.disableHardwareMediaKeys); enableCustomHotkeys.checked = settingsStore.get(settings.enableCustomHotkeys); diff --git a/src/preload.ts b/src/preload.ts index f35474f..cc6a682 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -1,5 +1,6 @@ import { Notification, app, dialog } from "@electron/remote"; import { ipcRenderer } from "electron"; +import fs from "fs"; import Player from "mpris-service"; import { globalEvents } from "./constants/globalEvents"; import { settings } from "./constants/settings"; @@ -147,8 +148,24 @@ const elements = { function addCustomCss() { window.addEventListener("DOMContentLoaded", () => { + const selectedTheme = settingsStore.get(settings.theme); + if (selectedTheme !== "none") { + const themeFile = `${process.resourcesPath}/${selectedTheme}`; + fs.readFile(themeFile, "utf-8", (err, data) => { + if (err) { + alert("An error ocurred reading the theme file."); + 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(settings.customCSS); + style.innerHTML = settingsStore.get(settings.customCSS).join("\n"); document.head.appendChild(style); }); } diff --git a/src/themes/Blood.scss b/src/themes/Blood.scss new file mode 100644 index 0000000..b7dfd6e --- /dev/null +++ b/src/themes/Blood.scss @@ -0,0 +1,10 @@ +$foreground: red; +$background: black; + +span { + color: $foreground; +} + +.sidebar--WvRg_ { + background-color: $background; +} diff --git a/src/themes/csstest.css b/src/themes/csstest.css deleted file mode 100644 index f331fdf..0000000 --- a/src/themes/csstest.css +++ /dev/null @@ -1,3 +0,0 @@ -h2 { - color: black; -} diff --git a/src/themes/test.scss b/src/themes/test.scss deleted file mode 100644 index 2de34b6..0000000 --- a/src/themes/test.scss +++ /dev/null @@ -1,7 +0,0 @@ -h1 { - color: black; - - .title { - color: blue; - } -} From 90cf231c767cface34cc56bed5501e4ea23f8b5c Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 14 May 2023 23:48:13 +0200 Subject: [PATCH 11/14] fix: user uploaded themes are now stored in the config directory. Missing directories will be created and added docs for theming --- README.md | 131 +++++++++++++------------ docs/images/customcss-config.png | Bin 0 -> 39062 bytes docs/images/customcss.png | Bin 0 -> 37046 bytes docs/images/discord.png | Bin 0 -> 4606 bytes docs/{ => images}/integrations.png | Bin docs/{ => images}/preview.png | Bin docs/{ => images}/settings-preview.png | Bin docs/{ => images}/settings.png | Bin docs/images/theming.png | Bin 0 -> 50228 bytes docs/theming.md | 38 +++++++ src/pages/settings/preload.ts | 25 ++--- src/pages/settings/settings.scss | 7 ++ src/pages/settings/theming.ts | 55 +++++++++++ src/scripts/settings.ts | 2 +- 14 files changed, 185 insertions(+), 73 deletions(-) create mode 100644 docs/images/customcss-config.png create mode 100644 docs/images/customcss.png create mode 100644 docs/images/discord.png rename docs/{ => images}/integrations.png (100%) rename docs/{ => images}/preview.png (100%) rename docs/{ => images}/settings-preview.png (100%) rename docs/{ => images}/settings.png (100%) create mode 100644 docs/images/theming.png create mode 100644 docs/theming.md create mode 100644 src/pages/settings/theming.ts diff --git a/README.md b/README.md index f187f6a..00d4ec0 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,80 @@ # Tidal-hifi -![GitHub release](https://img.shields.io/github/release/Mastermindzh/tidal-hifi.svg) +![GitHub release](https://img.shields.io/github/release/Mastermindzh/tidal-hifi.svg) [![Discord logo](./docs/images/discord.png)](https://discord.gg/yhNwf4v4He) The web version of [listen.tidal.com](https://listen.tidal.com) running in electron with hifi support thanks to widevine. -![tidal-hifi preview](./docs/preview.png) +![tidal-hifi preview](./docs/images/preview.png) ## Table of Contents -- [Installation](#installation) - - [Dependencies](#dependencies) - - [Using releases](#using-releases) - - [Snap](#snap) - - [Arch Linux](#arch-linux) - - [Flatpak](#flatpak) - - [Nix](#nix) - - [Using source](#using-source) -- [Features](#features) -- [Integrations](#integrations) - - [Known bugs](#known-bugs) - - [last.fm doesn't work out of the box. Use rescrobbler as a workaround](#lastfm-doesnt-work-out-of-the-box-use-rescrobbler-as-a-workaround) -- [Why](#why) -- [Why not extend existing projects?](#why-not-extend-existing-projects) -- [Special thanks to](#special-thanks-to) -- [Buy me a coffee? Please don't](#buy-me-a-coffee-please-dont) -- [Images](#images) - - [Settings window](#settings-window) - - [User setups](#user-setups) +- [Tidal-hifi](#tidal-hifi) + - [Table of Contents](#table-of-contents) + - [Features](#features) + - [Contributions](#contributions) + - [Why did I create tidal-hifi?](#why-did-i-create-tidal-hifi) + - [Why not extend existing projects?](#why-not-extend-existing-projects) + - [Installation](#installation) + - [Dependencies](#dependencies) + - [Using releases](#using-releases) + - [Snap](#snap) + - [Arch Linux](#arch-linux) + - [Flatpak](#flatpak) + - [Nix](#nix) + - [Using source](#using-source) + - [Integrations](#integrations) + - [Known bugs](#known-bugs) + - [last.fm doesn't work out of the box. Use rescrobbler as a workaround](#lastfm-doesnt-work-out-of-the-box-use-rescrobbler-as-a-workaround) + - [Special thanks to](#special-thanks-to) + - [Donations](#donations) + - [Images](#images) + - [Settings window](#settings-window) + - [User setups](#user-setups) +## Features + +- HiFi playback +- Notifications +- Custom [theming](./docs/theming.md) +- Custom hotkeys ([source](https://defkey.com/tidal-desktop-shortcuts)) +- API for status and playback +- Disabled audio & visual ads, unlocked lyrics, suggested track, track info, and unlimited skips thanks to uBlockOrigin custom filters ([source](https://github.com/uBlockOrigin/uAssets/issues/17495)) +- Custom [integrations](#integrations) +- [Settings feature](./docs/images/settings.png) to disable certain functionality. (`ctrl+=` or `ctrl+0`) +- AlbumArt in integrations ([best-effort](https://github.com/Mastermindzh/tidal-hifi/pull/88#pullrequestreview-840814847)) + +## Contributions + +To contribute you can use the standard GitHub features (issues, prs, etc) or join the discord server to talk with like-minded individuals. + +- ![Discord logo](./docs/images/discord.png) [Join the Discord server](https://discord.gg/yhNwf4v4He) + +## Why did I create tidal-hifi? + +I moved from Spotify over to Tidal and found Linux support to be lacking. + +When I started this project there weren't any Linux apps that offered Tidal's "hifi" options nor any scripts to control it. + +### Why not extend existing projects? + +Whilst there are a handful of projects attempting to run Tidal on Electron they are all unappealing to me because of various reasons: + +- Lack of maintainers/developers. (no hotfixes, no issues being handled etc) +- Most are simple web wrappers, not my cup of tea. +- Some are DE oriented. I want this to work on WM's too. +- None have widevine working at the moment + +Sometimes it's just easier to start over, cover my own needs and then making it available to the public :) + ## Installation ### Dependencies -Note that you **need** a notification library such as [libnotify](https://github.com/GNOME/libnotify) or [dunst](https://github.com/dunst-project/dunst) in order for the software to work properly. +Note that you **need** a notification library such as [libnotify](https://github.com/GNOME/libnotify) or [dunst](https://github.com/dunst-project/dunst) for the software to work properly. ### Using releases @@ -48,15 +86,15 @@ To install with `snap` you need to download the pre-packaged snap-package from t 1. Download -```sh -wget #for instance: https://github.com/Mastermindzh/tidal-hifi/releases/download/1.0/tidal-hifi_1.0.0_amd64.snap -``` + ```sh + wget #for instance: https://github.com/Mastermindzh/tidal-hifi/releases/download/1.0/tidal-hifi_1.0.0_amd64.snap + ``` 2. Install -```sh -snap install --dangerous #for instance: tidal-hifi_1.0.0_amd64.snap -``` + ```sh + snap install --dangerous #for instance: tidal-hifi_1.0.0_amd64.snap + ``` ### Arch Linux @@ -91,23 +129,12 @@ To install and work with the code on this project follow these steps: - npm install - npm start -## Features - -- HiFi playback -- Notifications -- Custom hotkeys ([source](https://defkey.com/tidal-desktop-shortcuts)) -- API for status and playback -- Disabled audio & visual ads, unlocked lyrics, suggested track, track info, and unlimited skips thanks to uBlockOrigin custom filters ([source](https://github.com/uBlockOrigin/uAssets/issues/17495)) -- Custom [integrations](#integrations) -- [Settings feature](./docs/settings.png) to disable certain functionality. (`ctrl+=` or `ctrl+0`) -- AlbumArt in integrations ([best-effort](https://github.com/Mastermindzh/tidal-hifi/pull/88#pullrequestreview-840814847)) - ## Integrations Tidal-hifi comes with several integrations out of the box. You can find these in the settings menu (`ctrl + =` by default) under the "integrations" tab. -![integrations menu, showing a list of integrations](./docs/integrations.png) +![integrations menu, showing a list of integrations](./docs/images/integrations.png) It currently includes: @@ -126,38 +153,20 @@ The last.fm login doesn't work, as is evident from the following issue: [Last.fm However, in that same issue you can read about a workaround using [rescrobbler](https://github.com/InputUsername/rescrobbled). For now that will be the default workaround. -## Why - -I moved from Spotify over to Tidal and found Linux support to be lacking. - -When I started this project there weren't any Linux apps that offered Tidal's "hifi" options nor any scripts to control it. - -## Why not extend existing projects? - -Whilst there are a handful of projects attempting to run Tidal on Electron they are all unappealing to me because of various reasons: - -- Lack of a maintainers/developers. (no hotfixes, no issues being handled etc) -- Most are simple web wrappers, not my cup of tea. -- Some are DE oriented. I want this to work on WM's too. -- None have widevine working at the moment - -Sometimes it's just easier to start over, cover my own needs and then making it available to the public :) - ## Special thanks to - [Castlabs](https://castlabs.com/) For maintaining Electron with Widevine CDM installation, Verified Media Path (VMP), and persistent licenses (StorageID) -## Buy me a coffee? Please don't +## Donations -Instead spend some money on a charity I care for: [kwf.nl](https://www.kwf.nl/donatie/donation). -Inspired by [haydenjames' issue](https://github.com/Mastermindzh/tidal-hifi/issues/27#issuecomment-704198429) +You can find my Github sponsorship page at: [https://github.com/sponsors/Mastermindzh](https://github.com/sponsors/Mastermindzh) ## Images ### Settings window -![settings window](./docs/settings-preview.png) +![settings window](./docs/images/settings-preview.png) ### User setups diff --git a/docs/images/customcss-config.png b/docs/images/customcss-config.png new file mode 100644 index 0000000000000000000000000000000000000000..4104a2a0303e3c0c87a3e58f5a358c090b39d1ab GIT binary patch literal 39062 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 F{|CE}iERJ? literal 0 HcmV?d00001 diff --git a/docs/images/customcss.png b/docs/images/customcss.png new file mode 100644 index 0000000000000000000000000000000000000000..8cff474c3716eb1081996246a976eddce9c389e6 GIT binary patch literal 37046 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]ZF@*pL_jGR=l>zYMkg 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�ODgHdmj_&1$Qzs!a6#pt6m*j)$vopwW&Mjh6n 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 literal 0 HcmV?d00001 diff --git a/docs/theming.md b/docs/theming.md new file mode 100644 index 0000000..2599ca4 --- /dev/null +++ b/docs/theming.md @@ -0,0 +1,38 @@ +# Theming tidal-hifi + +## Table of contents + + + +- [Theming tidal-hifi](#theming-tidal-hifi) + - [Table of contents](#table-of-contents) + - [Custom CSS](#custom-css) + - [config](#config) + - [Warning! Themes might break](#warning-themes-might-break) + + + +By default tidal-hifi comes with a few themes. +You can select these in the settings window under the theming tab as shown below. + +![Settings window with the theming tab opened](./images/theming.png) + +## Custom CSS + +The custom CSS will be added to the HTML document last. +This means that it will overwrite any existing CSS, even that of themes, unless the original has an access modifier such as `$important`. + +![settings window on the theming tab with a custom CSS override](./images/customcss.png) + +## config + +The theme selector and customCSS are stored in the config file. +The custom CSS is stored as a list of lines. + +![settings window on the theming tab next to the config file](./images/customcss-config.png) + +## Warning! Themes might break + +Themes might break at any point. Tidal changes their webpage structure a ton (they probably generate classNames and don't provide roles/ids/attributes.) + +If one breaks you can create an Issue on GitHub or ask for assistance in the [Discord channel](https://discord.gg/yhNwf4v4He). diff --git a/src/pages/settings/preload.ts b/src/pages/settings/preload.ts index d6f51f6..965ccf8 100644 --- a/src/pages/settings/preload.ts +++ b/src/pages/settings/preload.ts @@ -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`; diff --git a/src/pages/settings/settings.scss b/src/pages/settings/settings.scss index 75c99b1..8e7318a 100644 --- a/src/pages/settings/settings.scss +++ b/src/pages/settings/settings.scss @@ -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; + } } } diff --git a/src/pages/settings/theming.ts b/src/pages/settings/theming.ts new file mode 100644 index 0000000..1eb10e2 --- /dev/null +++ b/src/pages/settings/theming.ts @@ -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); + } +}; diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 9fa27b4..2d4ed7b 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -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, From a7dee5c2c940eb3a8e9e5a507cbf2debfe64b248 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Tue, 16 May 2023 23:41:00 +0200 Subject: [PATCH 12/14] fix: settings window was unresponsive on first start because of fs.mkdir that wasn't awaited --- src/pages/settings/theming.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/settings/theming.ts b/src/pages/settings/theming.ts index 1eb10e2..b35cfcc 100644 --- a/src/pages/settings/theming.ts +++ b/src/pages/settings/theming.ts @@ -31,12 +31,13 @@ export const getOptions = (array: string[]) => { * @param directory to read from. Will be created if it doesn't exist * @returns */ -export const getThemeListFromDirectory = (directory: string) => { +export const getThemeListFromDirectory = (directory: string): string[] => { try { makeUserThemesDirectory(directory); return fs.readdirSync(directory).filter(cssFilter).sort(sort); } catch (err) { console.error(err); + return []; } }; @@ -46,9 +47,7 @@ export const getThemeListFromDirectory = (directory: string) => { */ export const makeUserThemesDirectory = (directory: string) => { try { - fs.mkdir(directory, { recursive: true }, (err) => { - if (err) throw err; - }); + fs.mkdirSync(directory, { recursive: true }); } catch (err) { console.error(err); } From 194de286c8fb9cb5f5d74fd7f0719b99407d052b Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Thu, 18 May 2023 17:56:45 +0200 Subject: [PATCH 13/14] fix: customCSS default value was still a string, causing new users to have settings issues --- src/scripts/settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/settings.ts b/src/scripts/settings.ts index 2d4ed7b..614f8d1 100644 --- a/src/scripts/settings.ts +++ b/src/scripts/settings.ts @@ -13,7 +13,7 @@ export const settingsStore = new Store({ apiSettings: { port: 47836, }, - customCSS: "", + customCSS: [], disableBackgroundThrottle: true, disableHardwareMediaKeys: false, enableCustomHotkeys: false, From 3c835077d521fe5298390c0edbf26ead5c8560d4 Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 18 Jun 2023 15:39:14 +0200 Subject: [PATCH 14/14] added drone builds --- .drone.yml | 16 ++++++++++++++++ CHANGELOG.md | 2 ++ README.md | 14 +++++++------- 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..e74f2f7 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,16 @@ +kind: pipeline +type: docker +name: default + +steps: + - name: install + image: node:19.4.0 + commands: + - npm install + + - name: build_with_linux + image: node:19.4.0 + commands: + - apt-get update && apt-get upgrade -y + - apt-get install -y libarchive-tools rpm + - npm run build diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fa7a58..6f2b6e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 5.2.0 - moved from Javascript to Typescript for all files + - use `npm run watch` to watch for changes & recompile typescript and sass files - Added support for theming the application +- Added drone build file use `drone exec` or drone.ci to build it ## 5.1.0 diff --git a/README.md b/README.md index 00d4ec0..6fc5c6a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Tidal-hifi -![GitHub release](https://img.shields.io/github/release/Mastermindzh/tidal-hifi.svg) [![Discord logo](./docs/images/discord.png)](https://discord.gg/yhNwf4v4He) +![GitHub release](https://img.shields.io/github/release/Mastermindzh/tidal-hifi.svg) [![github builds](https://github.com/mastermindzh/tidal-hifi/actions/workflows/build.yml/badge.svg)](https://github.com/Mastermindzh/tidal-hifi/actions) [![Build Status](https://ci.mastermindzh.tech/api/badges/Mastermindzh/tidal-hifi/status.svg)](https://ci.mastermindzh.tech/Mastermindzh/tidal-hifi) [![Discord logo](./docs/images/discord.png)](https://discord.gg/yhNwf4v4He) The web version of [listen.tidal.com](https://listen.tidal.com) running in electron with hifi support thanks to widevine. @@ -86,15 +86,15 @@ To install with `snap` you need to download the pre-packaged snap-package from t 1. Download - ```sh - wget #for instance: https://github.com/Mastermindzh/tidal-hifi/releases/download/1.0/tidal-hifi_1.0.0_amd64.snap - ``` + ```sh + wget #for instance: https://github.com/Mastermindzh/tidal-hifi/releases/download/1.0/tidal-hifi_1.0.0_amd64.snap + ``` 2. Install - ```sh - snap install --dangerous #for instance: tidal-hifi_1.0.0_amd64.snap - ``` + ```sh + snap install --dangerous #for instance: tidal-hifi_1.0.0_amd64.snap + ``` ### Arch Linux