diff --git a/.stylelintrc.json b/.stylelintrc.json index f1bc932..c1f1b1b 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,16 +1,10 @@ { - "plugins": [ - "stylelint-prettier" - ], - "extends": [ - "stylelint-config-standard-scss" - ], - "ignoreFiles": [ - "src/themes/**.scss" - ], + "plugins": ["stylelint-prettier"], + "extends": ["stylelint-config-standard-scss"], + "ignoreFiles": ["src/themes/**.scss"], "rules": { "prettier/prettier": true, "scss/at-extend-no-missing-placeholder": null, "no-descending-specificity": null } -} \ No newline at end of file +} diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb0e02..d19b93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added all missing swagger/openApi info with the help of [Times-Z](https://github.com/Times-Z) - Updated most dependency versions + - This includes Electron 31! - Added a channel selector so we can now use Tidal's staging environment directly from the app @@ -112,10 +113,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated Electron to 28.1.1 (fixes [325](https://github.com/Mastermindzh/tidal-hifi/issues/325)) - Updated dependencies to latest + - added theme files to stylelint ignore - fixed other stylelint errors - Added functionality to favorite a song (fixes [#323](https://github.com/Mastermindzh/tidal-hifi/issues/323)) + - Added a hotkey to favorite ("Add to collection") songs: Control+a - Added the "favorite" field in the `mediaInfo` and the API `/current` endpoint - Added an endpoint to toggle favoriting a song: `http://localhost:47836/favorite/toggle` @@ -136,10 +139,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 new about page](./docs/images/new-about.png) + ![The new about page](./docs/images/new-about.png) - 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 - ![Tokyo Night theme on settings window](./docs/images/customcss-menu.png) + ![Tokyo Night theme on settings window](./docs/images/customcss-menu.png) ## [5.6.0] diff --git a/SECURITY.md b/SECURITY.md index 5d558f4..7db40f6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,4 +8,3 @@ Only the very latest 😄. If you find a vulnerability just add it as an issue. If there's an especially bad vulnerability that you don't want to make public just send me a private message (email, discord, wherever). - diff --git a/package.json b/package.json index 05a4597..e9fc043 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "build-mac": "npm run builder -- -c ./build/electron-builder.yml -m", "build-base": "npm run builder -- -c ./build/electron-builder.base.yml", "prebuilder": "npm run compile", + "prettier": "prettier . --write", "builder": "electron-builder --publish=never", "sass": "sass ./src/pages/settings/settings.scss ./src/pages/settings/settings.css && sass --no-source-map src/themes:themes", "style-lint": "npx stylelint **/*.scss", @@ -80,4 +81,4 @@ "typescript": "^5.5.3" }, "prettier": "@mastermindzh/prettier-config" -} \ No newline at end of file +} diff --git a/src/features/api/swagger.json b/src/features/api/swagger.json index bac2fc9..30d5f98 100644 --- a/src/features/api/swagger.json +++ b/src/features/api/swagger.json @@ -21,9 +21,7 @@ "/current": { "get": { "summary": "Get current media info", - "tags": [ - "current" - ], + "tags": ["current"], "responses": { "200": { "description": "Current media info", @@ -41,9 +39,7 @@ "/current/image": { "get": { "summary": "Get current media image", - "tags": [ - "current" - ], + "tags": ["current"], "responses": { "200": { "description": "Current media image", @@ -65,9 +61,7 @@ "/player/play": { "post": { "summary": "Play the current media", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -85,9 +79,7 @@ "/player/favorite/toggle": { "post": { "summary": "Add the current media to your favorites, or remove it if its already added to your favorites", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -105,9 +97,7 @@ "/player/pause": { "post": { "summary": "Pause the current media", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -125,9 +115,7 @@ "/player/next": { "post": { "summary": "Play the next song", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -145,9 +133,7 @@ "/player/previous": { "post": { "summary": "Play the previous song", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -165,9 +151,7 @@ "/player/shuffle/toggle": { "post": { "summary": "Play the previous song", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -185,9 +169,7 @@ "/player/repeat/toggle": { "post": { "summary": "Toggle the repeat status, toggles between \"off\" , \"single\" and \"all\"", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -205,9 +187,7 @@ "/player/playpause": { "post": { "summary": "Start playing the media if paused, or pause the media if playing", - "tags": [ - "player" - ], + "tags": ["player"], "responses": { "200": { "description": "Ok", @@ -225,9 +205,7 @@ "/settings/skipped-artists": { "get": { "summary": "get a list of artists that TIDAL Hi-Fi will skip if skipping is enabled", - "tags": [ - "settings" - ], + "tags": ["settings"], "responses": { "200": { "description": "The list book.", @@ -243,9 +221,7 @@ }, "post": { "summary": "Add new artists to the list of skipped artists", - "tags": [ - "settings" - ], + "tags": ["settings"], "requestBody": { "required": true, "content": { @@ -266,9 +242,7 @@ "/settings/skipped-artists/delete": { "post": { "summary": "Remove artists from the list of skipped artists", - "tags": [ - "settings" - ], + "tags": ["settings"], "requestBody": { "required": true, "content": { @@ -289,9 +263,7 @@ "/settings/skipped-artists/current": { "post": { "summary": "Add the current artist to the list of skipped artists", - "tags": [ - "settings" - ], + "tags": ["settings"], "responses": { "200": { "description": "Ok" @@ -300,9 +272,7 @@ }, "delete": { "summary": "Remove the current artist from the list of skipped artists", - "tags": [ - "settings" - ], + "tags": ["settings"], "responses": { "200": { "description": "Ok" @@ -313,9 +283,7 @@ "/image": { "get": { "summary": "Get current image", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -338,9 +306,7 @@ "/play": { "get": { "summary": "Play the current media", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -359,9 +325,7 @@ "/favorite/toggle": { "get": { "summary": "Add the current media to your favorites, or remove it if its already added to your favorites", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -380,9 +344,7 @@ "/pause": { "get": { "summary": "Pause the current media", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -401,9 +363,7 @@ "/next": { "get": { "summary": "Play the next song", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -422,9 +382,7 @@ "/previous": { "get": { "summary": "Play the previous song", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -443,9 +401,7 @@ "/playpause": { "get": { "summary": "Toggle play/pause", - "tags": [ - "legacy" - ], + "tags": ["legacy"], "deprecated": true, "responses": { "200": { @@ -558,10 +514,7 @@ "items": { "type": "string" }, - "example": [ - "Artist1", - "Artist2" - ] + "example": ["Artist1", "Artist2"] } } }, @@ -579,4 +532,4 @@ "description": "The settings management API" } ] -} \ No newline at end of file +} diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html index 2dd2879..051f79a 100644 --- a/src/pages/settings/settings.html +++ b/src/pages/settings/settings.html @@ -1,504 +1,599 @@ - + + + Tidal Hi-Fi settings + + + + + + - - Tidal Hi-Fi settings - - - - - - - - -
-
- - - +
+
+
+ + - - + L279.721,11.767c15.705-15.687,41.139-15.687,56.832,0C352.258,27.466,352.258,52.912,336.559,68.611z" + /> + + -
- - +
+ + - - + + - - + + - - + + - - + + - - + + -
-
-
-

Playback

-
-
-

Notifications

-

Show a notification when new media starts.

-
- -
-
-
-

Skip Artists automatically

-

The following list of artists (1 per line) will be skipped automatically.

-
- -
- -
-
-

Block ads

-

- Disabled audio & visual ads, unlocked lyrics, suggested track, track info, - unlimited skips -

-
- -
-
-
-

UI

-
-
-

Fixed menubar

-

Always show TIDAL Hi-Fi's menu bar.

-
- -
-
-
-

System

-
-
-

Tray icon

-

Show TIDAL Hi-Fi's tray icon.

-
- -
-
-
-

Static Window Title

-

Makes the window title "TIDAL Hi-Fi" instead of changing to the currently playing song.

-
- -
-
-
-

Minimize on Close

-

Minimize window on close instead.

-
- -
-
-
-

Hotkeys

-

- Enable extra hotkeys to achieve feature parity with the - desktop apps. -

-
- -
-
-
-

Single instance

-

Prevent opening multiple TIDAL Hi-Fi's instances.

-
- -
-
-
- -
-
-

API

-
-

- TIDAL Hi-Fi has a built-in web API to allow users to get current media information. - You can optionally enable playback control as well. -

-
-
-
-

Web API

-

Enable the TIDAL Hi-Fi web API.

-
- -
-
-
- - -
-
-
-
-

API hostname

-

By default (127.0.0.1) only local apps can interface with the API.
- Change to 0.0.0.0 to allow anyone to interact with it.
- Other options are available -

- -
-
-
-
-

Playback control

-

Enable playback control from the web API.

-
- -
-
-
- -
-
-

Integrations

-
-

- TIDAL Hi-Fi is extensible through the use of integrations. You can enable or - disable them here. -

-
-
-
-

MPRIS

-

- Enable MPRIS interface which provides a mechanism for discovery, querying and - basic playback control on Linux systems. -

-
- -
-
-
-

Discord

-
-
-

Discord RPC

-

Show what you're listening to on Discord.

-
- -
-
- -
+
+
+
+

Playback

+
-

Show Idle Text

-

Should the idle text be shown when idle?

+

Notifications

+

Show a notification when new media starts.

- -
+
-

Idle Text

-

The text displayed on Discord's rich presence while idling in the app.

- -
-
- -
-
-

Using Tidal Text

-

The text displayed on Discord's rich presence while "showSong" is turned off

- -
-
- -
-
-

Show media

-

Show the current media in the Discord client

+

Skip Artists automatically

+

The following list of artists (1 per line) will be skipped automatically.

+ +
+
+

Block ads

+

+ Disabled audio & visual ads, unlocked lyrics, suggested track, track info, + unlimited skips +

+
+ +
+
+
+

UI

+
+
+

Fixed menubar

+

Always show TIDAL Hi-Fi's menu bar.

+
+ +
+
+
+

System

+
+
+

Tray icon

+

Show TIDAL Hi-Fi's tray icon.

+
+ +
+
+
+

Static Window Title

+

+ Makes the window title "TIDAL Hi-Fi" instead of changing to the currently + playing song. +

+
+ +
+
+
+

Minimize on Close

+

Minimize window on close instead.

+
+ +
+
+
+

Hotkeys

+

+ Enable extra hotkeys to achieve feature parity with the + desktop apps. +

+
+ +
+
+
+

Single instance

+

Prevent opening multiple TIDAL Hi-Fi's instances.

+
+ +
+
+
- -
-

ListenBrainz

-
-

Enable ListenBrainz

-

Scrobble your listens directly to ListenBrainz.

+

ScrobbleDelay

+

+ The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when + you fast forward immediately +

+
-
-
+ +
+
+

Settings

-

ListenBrainz API Url

-

There are multiple instances for ListenBrainz you can set the corresponding API url below.

- +

Update frequency

+

+ The amount of time, in milliseconds, that TIDAL Hi-Fi will refresh its playback + info by scraping the website. The default of 500 seems to work in more cases but + if you are fine with a bit more resource usage you can decrease it as well. +

+
+
-

ListenBrainz User Token

-

Provide the user token you can get from the settings page.

- +

Tidal channel / URL

+

+ Which URL Tidal Hi-Fi should use. + note! Beta might break at any time +

+
-
-

ScrobbleDelay

-

The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when you fast forward - immediately

- +
+

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. +

+
+ +
+
+
+

Wayland support

+

+ Adds a couple of Electron flags to help TIDAL Hi-Fi run smoothly on the Wayland + window system. +

+
+ +
-
-
+ -
-
-

Settings

-
-
-

Update frequency

-

- The amount of time, in milliseconds, that TIDAL Hi-Fi will refresh its playback info by scraping the - website. - The default of 500 seems to work in more cases but if you are fine with a bit more resource usage you - can decrease it as well. -

- +
+
+

Theming

+
+
+

Custom CSS

+

+ The css that you put in here will be injected into a style tag in the head of + the document. +

+
+ -
-
-

Tidal channel / URL

-

- Which URL Tidal Hi-Fi should use. - note! Beta might break at any time -

- +
+

Theme files

+
+
+

Current theme

+

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

+ +
-
-
-
-

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. -

-
- -
-
-
-

Wayland support

-

- Adds a couple of Electron flags to help TIDAL Hi-Fi run smoothly on the Wayland window system. -

-
- -
-
-
-
-
-

Theming

-
-
-

Custom CSS

-

- The css that you put in here will be injected into a style tag in the head of the document. -

-
-
-
- - -
-

Theme files

-
-
-

Current theme

-

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

- -
-
- -
-
-

Upload new themes

-

- 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 - +
+
+

Upload new themes

+

+ 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 + +
-
-
+
-
- tidal icon -

TIDAL Hi-Fi

-
- 5.17.0 -
- -
+
+ tidal icon +

TIDAL Hi-Fi

+
+ 5.17.0 +
+ +
-
- -
-
-
-
- - - \ No newline at end of file + +
+ + + + diff --git a/src/scripts/discord.ts b/src/scripts/discord.ts index 9da1387..2efe69b 100644 --- a/src/scripts/discord.ts +++ b/src/scripts/discord.ts @@ -26,7 +26,7 @@ const defaultPresence = { largeImageKey: "tidal-hifi-icon", largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, instance: false, - type: ACTIVITY_LISTENING + type: ACTIVITY_LISTENING, }; const updateActivity = () => { @@ -118,15 +118,17 @@ const getActivity = (): SetActivity => { const connectWithRetry = async (retryCount = 0) => { try { await rpc.login(); - Logger.log('Connected to Discord'); + Logger.log("Connected to Discord"); rpc.on("ready", updateActivity); - Object.values(globalEvents).forEach(event => ipcMain.on(event, observer)); + Object.values(globalEvents).forEach((event) => ipcMain.on(event, observer)); } catch (error) { if (retryCount < MAX_RETRIES) { - Logger.log(`Failed to connect to Discord, retrying in ${RETRY_DELAY/1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})`); + Logger.log( + `Failed to connect to Discord, retrying in ${RETRY_DELAY / 1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})` + ); setTimeout(() => connectWithRetry(retryCount + 1), RETRY_DELAY); } else { - Logger.log('Failed to connect to Discord after maximum retry attempts'); + Logger.log("Failed to connect to Discord after maximum retry attempts"); } } }; @@ -135,7 +137,7 @@ const connectWithRetry = async (retryCount = 0) => { * Set up the discord rpc and listen on globalEvents.updateInfo */ export const initRPC = () => { - rpc = new Client({ transport: {type: "ipc"}, clientId }); + rpc = new Client({ transport: { type: "ipc" }, clientId }); connectWithRetry(); };