mirror of
				https://github.com/Mastermindzh/tidal-hifi.git
				synced 2025-10-31 16:59:09 +01:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			c89fe5e573
			...
			develop
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d67f62c0dc | |||
| b2afd44dd6 | 
| @@ -4,12 +4,12 @@ name: default | |||||||
|  |  | ||||||
| steps: | steps: | ||||||
|   - name: install |   - name: install | ||||||
|     image: node:22.17.0 |     image: node:19.4.0 | ||||||
|     commands: |     commands: | ||||||
|       - npm install |       - npm install | ||||||
|  |  | ||||||
|   - name: build_with_linux |   - name: build_with_linux | ||||||
|     image: node:22.17.0 |     image: node:19.4.0 | ||||||
|     commands: |     commands: | ||||||
|       - apt-get update && apt-get upgrade -y |       - apt-get update && apt-get upgrade -y | ||||||
|       - apt-get install -y libarchive-tools rpm |       - apt-get install -y libarchive-tools rpm | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -21,30 +21,26 @@ jobs: | |||||||
|       - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|       - uses: actions/setup-node@master |       - uses: actions/setup-node@master | ||||||
|         with: |         with: | ||||||
|           node-version: 22.12.0 |           node-version: 22.4 | ||||||
|       - run: npm install |       - run: npm install | ||||||
|       - run: npm run build |       - run: npm run build | ||||||
|       # - uses: actions/upload-artifact@master |  | ||||||
|       #   with: |  | ||||||
|       #     name: linux-builds |  | ||||||
|       #     path: dist/ |  | ||||||
|  |  | ||||||
|   # build_on_mac: |   build_on_mac: | ||||||
|   #   runs-on: macos-latest |     runs-on: macos-latest | ||||||
|   #   steps: |     steps: | ||||||
|   #     - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|   #     - uses: actions/setup-node@master |       - uses: actions/setup-node@master | ||||||
|   #       with: |         with: | ||||||
|   #         node-version: 22.4 |           node-version: 22.4 | ||||||
|   #     - run: npm install |       - run: npm install | ||||||
|   #     - run: npm run build |       - run: npm run build | ||||||
|  |  | ||||||
|   # build_on_win: |   build_on_win: | ||||||
|   #   runs-on: windows-latest |     runs-on: windows-latest | ||||||
|   #   steps: |     steps: | ||||||
|   #     - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|   #     - uses: actions/setup-node@master |       - uses: actions/setup-node@master | ||||||
|   #       with: |         with: | ||||||
|   #         node-version: 22.4 |           node-version: 22.4 | ||||||
|   #     - run: npm install |       - run: npm install | ||||||
|   #     - run: npm run build |       - run: npm run build | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -21,7 +21,7 @@ jobs: | |||||||
|       - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|       - uses: actions/setup-node@master |       - uses: actions/setup-node@master | ||||||
|         with: |         with: | ||||||
|           node-version: 22.12.0 |           node-version: 22.4 | ||||||
|       - run: npm install |       - run: npm install | ||||||
|       - run: npm run build |       - run: npm run build | ||||||
|       - uses: actions/upload-artifact@master |       - uses: actions/upload-artifact@master | ||||||
| @@ -29,30 +29,30 @@ jobs: | |||||||
|           name: linux-builds |           name: linux-builds | ||||||
|           path: dist/ |           path: dist/ | ||||||
|  |  | ||||||
|   # build_on_mac: |   build_on_mac: | ||||||
|   #   runs-on: macos-latest |     runs-on: macos-latest | ||||||
|   #   steps: |     steps: | ||||||
|   #     - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|   #     - uses: actions/setup-node@master |       - uses: actions/setup-node@master | ||||||
|   #       with: |         with: | ||||||
|   #         node-version: 22.4 |           node-version: 22.4 | ||||||
|   #     - run: npm install |       - run: npm install | ||||||
|   #     - run: npm run build |       - run: npm run build | ||||||
|   #     - uses: actions/upload-artifact@master |       - uses: actions/upload-artifact@master | ||||||
|   #       with: |         with: | ||||||
|   #         name: mac-builds |           name: mac-builds | ||||||
|   #         path: ./dist/ |           path: ./dist/ | ||||||
|  |  | ||||||
|   # build_on_win: |   build_on_win: | ||||||
|   #   runs-on: windows-latest |     runs-on: windows-latest | ||||||
|   #   steps: |     steps: | ||||||
|   #     - uses: actions/checkout@master |       - uses: actions/checkout@master | ||||||
|   #     - uses: actions/setup-node@master |       - uses: actions/setup-node@master | ||||||
|   #       with: |         with: | ||||||
|   #         node-version: 22.4 |           node-version: 22.4 | ||||||
|   #     - run: npm install |       - run: npm install | ||||||
|   #     - run: npm run build |       - run: npm run build | ||||||
|   #     - uses: actions/upload-artifact@master |       - uses: actions/upload-artifact@master | ||||||
|   #       with: |         with: | ||||||
|   #         name: windows-builds |           name: windows-builds | ||||||
|   #         path: dist/ |           path: dist/ | ||||||
|   | |||||||
| @@ -1,13 +1,7 @@ | |||||||
| { | { | ||||||
|   "plugins": [ |   "plugins": ["stylelint-prettier"], | ||||||
|     "stylelint-prettier" |   "extends": ["stylelint-config-standard-scss"], | ||||||
|   ], |   "ignoreFiles": ["src/themes/**.scss"], | ||||||
|   "extends": [ |  | ||||||
|     "stylelint-config-standard-scss" |  | ||||||
|   ], |  | ||||||
|   "ignoreFiles": [ |  | ||||||
|     "src/themes/**.scss" |  | ||||||
|   ], |  | ||||||
|   "rules": { |   "rules": { | ||||||
|     "prettier/prettier": true, |     "prettier/prettier": true, | ||||||
|     "scss/at-extend-no-missing-placeholder": null, |     "scss/at-extend-no-missing-placeholder": null, | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -17,9 +17,7 @@ | |||||||
|     "trackid", |     "trackid", | ||||||
|     "tracklist", |     "tracklist", | ||||||
|     "widevine", |     "widevine", | ||||||
|     "wvcus", |     "xesam" | ||||||
|     "xesam", |  | ||||||
|     "xhayper" |  | ||||||
|   ], |   ], | ||||||
|   "sonarlint.connectedMode.project": { |   "sonarlint.connectedMode.project": { | ||||||
|     "connectionId": "public-sonarcloud", |     "connectionId": "public-sonarcloud", | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -4,42 +4,6 @@ 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/), | 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). | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||||||
|  |  | ||||||
| ## [5.20.1] |  | ||||||
|  |  | ||||||
| - Updated electron to 37.2.5 |  | ||||||
|  |  | ||||||
| ## [5.20.0] |  | ||||||
|  |  | ||||||
| - Removes the `--enable-features=UseOzonePlatform` flag, as the Ozone platform has been the default on Linux since Electron 28 and this flag is no longer necessary. |  | ||||||
| - Adds the `--enable-wayland-ime` flag to enable Input Method Editor (IME) support in Wayland environments, improving the input experience for CJK and other users. |  | ||||||
| - Updated various dependencies |  | ||||||
| - Updated Electron to 37, potentially fixing [#580](https://github.com/Mastermindzh/tidal-hifi/issues/580) |  | ||||||
|  |  | ||||||
| ## [5.19.0] |  | ||||||
|  |  | ||||||
| - Fixed the issue where media updates would cease to work after album names can't be found |  | ||||||
|   - Will simply report an empty string when it can't find the album |  | ||||||
| - Updated various dependencies |  | ||||||
|  |  | ||||||
| ## [5.18.2] |  | ||||||
|  |  | ||||||
| - Reverted to sass 1.79.4 to fix `Nix` builds |  | ||||||
| - Changed electron-builder.base.yml to now generate the correct .desktop entries again |  | ||||||
|   - Should fix flatpak build |  | ||||||
|  |  | ||||||
| ## [5.18.1] |  | ||||||
|  |  | ||||||
| - Fixed the login bug |  | ||||||
| - Upgraded electron to 35.1.1 |  | ||||||
| - Added Widevine/CDM info to startup |  | ||||||
| - delayed remote electron initializer |  | ||||||
|  |  | ||||||
| ## [5.18.0] |  | ||||||
|  |  | ||||||
| - [Dianoga](https://github.com/Dianoga) fixed the duration selector, restoring mpris & partial API data. |  | ||||||
|   - PR: #554 |  | ||||||
| - Added `xesam:url` property to mpris metadata fixes [#506](https://github.com/Mastermindzh/tidal-hifi/issues/506) |  | ||||||
|  |  | ||||||
| ## [5.17.0] | ## [5.17.0] | ||||||
|  |  | ||||||
| - Added an option to disable the dynamic title and set it to a static one, [#491](https://github.com/Mastermindzh/tidal-hifi/pull/491) | - Added an option to disable the dynamic title and set it to a static one, [#491](https://github.com/Mastermindzh/tidal-hifi/pull/491) | ||||||
| @@ -57,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) | - Added all missing swagger/openApi info with the help of [Times-Z](https://github.com/Times-Z) | ||||||
| - Updated most dependency versions | - Updated most dependency versions | ||||||
|  |  | ||||||
|   - This includes Electron 31! |   - This includes Electron 31! | ||||||
|  |  | ||||||
| - Added a channel selector so we can now use Tidal's staging environment directly from the app | - Added a channel selector so we can now use Tidal's staging environment directly from the app | ||||||
| @@ -148,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 Electron to 28.1.1 (fixes [325](https://github.com/Mastermindzh/tidal-hifi/issues/325)) | ||||||
| - Updated dependencies to latest | - Updated dependencies to latest | ||||||
|  |  | ||||||
|   - added theme files to stylelint ignore |   - added theme files to stylelint ignore | ||||||
|   - fixed other stylelint errors |   - fixed other stylelint errors | ||||||
|  |  | ||||||
| - Added functionality to favorite a song (fixes [#323](https://github.com/Mastermindzh/tidal-hifi/issues/323)) | - 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 a hotkey to favorite ("Add to collection") songs: Control+a | ||||||
|   - Added the "favorite" field in the `mediaInfo` and the API `/current` endpoint |   - 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` |   - Added an endpoint to toggle favoriting a song: `http://localhost:47836/favorite/toggle` | ||||||
|   | |||||||
| @@ -8,4 +8,3 @@ Only the very latest 😄. | |||||||
|  |  | ||||||
| If you find a vulnerability just add it as an issue. | 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). | If there's an especially bad vulnerability that you don't want to make public just send me a private message (email, discord, wherever). | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| appId: com.rickvanlieshout.tidal-hifi | appId: com.rickvanlieshout.tidal-hifi | ||||||
| electronVersion: 37.2.5 | electronVersion: 28.1.1 | ||||||
| electronDownload: | electronDownload: | ||||||
|   version: 37.2.5+wvcus |   version: 28.1.1+wvcus | ||||||
|   mirror: https://github.com/castlabs/electron-releases/releases/download/v |   mirror: https://github.com/castlabs/electron-releases/releases/download/v | ||||||
| snap: | snap: | ||||||
|   plugs: |   plugs: | ||||||
| @@ -17,25 +17,24 @@ linux: | |||||||
|   executableName: tidal-hifi |   executableName: tidal-hifi | ||||||
|   executableArgs: |   executableArgs: | ||||||
|     [ |     [ | ||||||
|  |       "--enable-features=UseOzonePlatform", | ||||||
|       "--ozone-platform-hint=auto", |       "--ozone-platform-hint=auto", | ||||||
|       "--enable-features=WaylandWindowDecorations", |       "--enable-features=WaylandWindowDecorations", | ||||||
|       "--enable-wayland-ime", |  | ||||||
|       "--use-angle", |  | ||||||
|     ] |     ] | ||||||
|   desktop: |   desktop: | ||||||
|     entry: |     Encoding: UTF-8 | ||||||
|       Encoding: "UTF-8" |     Name: TIDAL Hi-Fi | ||||||
|       Name: "TIDAL Hi-Fi" |     GenericName: TIDAL Hi-Fi | ||||||
|       GenericName: "TIDAL Hi-Fi" |     Comment: The web version of listen.tidal.com running in electron with hifi support thanks to widevine. | ||||||
|       Comment: "The web version of listen.tidal.com running in electron with hifi support thanks to widevine." |     Icon: tidal-hifi | ||||||
|       Icon: "tidal-hifi" |     StartupNotify: true | ||||||
|       StartupNotify: "true" |     Terminal: false | ||||||
|       Terminal: "false" |     Type: Application | ||||||
|       Type: "Application" |     Categories: Network;Application;AudioVideo;Audio;Video | ||||||
|       Categories: "Network;Application;AudioVideo;Audio;Video" |     StartupWMClass: tidal-hifi | ||||||
|       StartupWMClass: "tidal-hifi" |     X-PulseAudio-Properties: media.role=music | ||||||
|       X-PulseAudio-Properties: "media.role=music" |     MimeType: x-scheme-handler/tidal; | ||||||
|       MimeType: "x-scheme-handler/tidal;" |  | ||||||
| mac: | mac: | ||||||
|   category: public.app-category.entertainment |   category: public.app-category.entertainment | ||||||
| win: | win: | ||||||
|   | |||||||
							
								
								
									
										5543
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5543
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										52
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | |||||||
| { | { | ||||||
|   "name": "tidal-hifi", |   "name": "tidal-hifi", | ||||||
|   "version": "5.20.1", |   "version": "5.17.0", | ||||||
|   "description": "Tidal on Electron with widevine(hifi) support", |   "description": "Tidal on Electron with widevine(hifi) support", | ||||||
|   "main": "ts-dist/main.js", |   "main": "ts-dist/main.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start": "electron --inspect=0.0.0.0:5858 --remote-debugging-port=8315 --remote-allow-origins=* .", |     "start": "electron --inspect=0.0.0.0:5858 .", | ||||||
|     "watchStart": "nodemon dist -x \"npm run start\"", |     "watchStart": "nodemon dist -x \"npm run start\"", | ||||||
|     "compile": "tsc && npm run sass-and-copy", |     "compile": "tsc && npm run sass-and-copy", | ||||||
|     "deps": "npm run watch", |     "deps": "npm run watch", | ||||||
| @@ -23,6 +23,7 @@ | |||||||
|     "build-mac": "npm run builder -- -c ./build/electron-builder.yml -m", |     "build-mac": "npm run builder -- -c ./build/electron-builder.yml -m", | ||||||
|     "build-base": "npm run builder -- -c ./build/electron-builder.base.yml", |     "build-base": "npm run builder -- -c ./build/electron-builder.base.yml", | ||||||
|     "prebuilder": "npm run compile", |     "prebuilder": "npm run compile", | ||||||
|  |     "prettier": "prettier . --write", | ||||||
|     "builder": "electron-builder --publish=never", |     "builder": "electron-builder --publish=never", | ||||||
|     "sass": "sass ./src/pages/settings/settings.scss ./src/pages/settings/settings.css && sass --no-source-map src/themes: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": "npx stylelint **/*.scss", | ||||||
| @@ -40,45 +41,44 @@ | |||||||
|   "homepage": "https://github.com/Mastermindzh/tidal-hifi", |   "homepage": "https://github.com/Mastermindzh/tidal-hifi", | ||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@electron/remote": "^2.1.3", |     "@electron/remote": "^2.1.2", | ||||||
|     "@types/swagger-jsdoc": "^6.0.4", |     "@types/swagger-jsdoc": "^6.0.4", | ||||||
|     "@xhayper/discord-rpc": "1.3.0", |     "@xhayper/discord-rpc": "^1.2.0", | ||||||
|     "axios": "^1.12.0", |     "axios": "^1.7.7", | ||||||
|     "cors": "^2.8.5", |     "cors": "^2.8.5", | ||||||
|     "electron-store": "^8.2.0", |     "electron-store": "^8.2.0", | ||||||
|     "express": "^5.1.0", |     "express": "^4.21.1", | ||||||
|     "hotkeys-js": "^3.13.15", |     "hotkeys-js": "^3.13.7", | ||||||
|     "mpris-service": "^2.1.2", |     "mpris-service": "^2.1.2", | ||||||
|     "request": "^2.88.2", |     "request": "^2.88.2", | ||||||
|     "sass": "1.93.2", |     "sass": "^1.79.4", | ||||||
|     "swagger-ui-express": "^5.0.1" |     "swagger-ui-express": "^5.0.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@mastermindzh/prettier-config": "^1.0.0", |     "@mastermindzh/prettier-config": "^1.0.0", | ||||||
|     "@types/cors": "^2.8.19", |     "@types/cors": "^2.8.17", | ||||||
|     "@types/express": "^5.0.3", |     "@types/express": "^4.17.21", | ||||||
|     "@types/node": "^22.16.2", |     "@types/node": "^20.14.10", | ||||||
|     "@types/request": "^2.48.12", |     "@types/request": "^2.48.12", | ||||||
|     "@types/swagger-ui-express": "^4.1.8", |     "@types/swagger-ui-express": "^4.1.6", | ||||||
|     "@typescript-eslint/eslint-plugin": "^8.36.0", |     "@typescript-eslint/eslint-plugin": "^7.16.0", | ||||||
|     "@typescript-eslint/parser": "^8.36.0", |     "@typescript-eslint/parser": "^7.15.0", | ||||||
|     "copyfiles": "^2.4.1", |     "copyfiles": "^2.4.1", | ||||||
|     "electron": "github:castlabs/electron-releases#v37.2.5+wvcus", |     "electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", | ||||||
|     "electron-builder": "~26.0.12", |     "electron-builder": "~24.9.4", | ||||||
|     "eslint": "^9.30.1", |     "eslint": "^8.57.0", | ||||||
|     "js-yaml": "^4.1.0", |     "js-yaml": "^4.1.0", | ||||||
|     "markdown-toc": "^1.2.0", |     "markdown-toc": "^1.2.0", | ||||||
|     "node-abi": "^4.12.0", |     "nodemon": "^3.1.4", | ||||||
|     "nodemon": "^3.1.10", |     "prettier": "^3.3.2", | ||||||
|     "prettier": "^3.6.2", |     "stylelint": "^16.6.1", | ||||||
|     "stylelint": "^16.21.1", |     "stylelint-config-standard": "^36.0.1", | ||||||
|     "stylelint-config-standard": "^39.0.0", |     "stylelint-config-standard-scss": "^13.1.0", | ||||||
|     "stylelint-config-standard-scss": "^16.0.0", |     "stylelint-prettier": "^5.0.0", | ||||||
|     "stylelint-prettier": "^5.0.3", |  | ||||||
|     "swagger-jsdoc": "^6.2.8", |     "swagger-jsdoc": "^6.2.8", | ||||||
|     "ts-node": "^10.9.2", |     "ts-node": "^10.9.2", | ||||||
|     "tsc-watch": "^7.1.1", |     "tsc-watch": "^6.2.0", | ||||||
|     "typescript": "^5.8.3" |     "typescript": "^5.5.3" | ||||||
|   }, |   }, | ||||||
|   "prettier": "@mastermindzh/prettier-config" |   "prettier": "@mastermindzh/prettier-config" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +0,0 @@ | |||||||
| { |  | ||||||
|   "$schema": "https://docs.renovatebot.com/renovate-schema.json", |  | ||||||
|   "ignoreDeps": ["@types/node", "electron-store", "@xhayper/discord-rpc"] |  | ||||||
| } |  | ||||||
| @@ -22,13 +22,12 @@ | |||||||
|     media: '*[data-test="current-media-imagery"]', |     media: '*[data-test="current-media-imagery"]', | ||||||
|     image: "img", |     image: "img", | ||||||
|     current: '*[data-test="current-time"]', |     current: '*[data-test="current-time"]', | ||||||
|     duration: '*[class^=_playbackControlsContainer] *[data-test="duration"]', |     duration: '*[class^=playbackControlsContainer] *[data-test="duration"]', | ||||||
|     bar: '*[data-test="progress-bar"]', |     bar: '*[data-test="progress-bar"]', | ||||||
|     footer: "#footerPlayer", |     footer: "#footerPlayer", | ||||||
|     mediaItem: "[data-type='mediaItem']", |     mediaItem: "[data-type='mediaItem']", | ||||||
|     album_header_title: '*[class^="_playingFrom"] span:nth-child(2)', |     album_header_title: '*[class^="playingFrom"] span:nth-child(2)', | ||||||
|     playing_from: '*[class^="_playingFrom"] span:nth-child(2)', |     playingFrom: '*[class^="playingFrom"] span:nth-child(2)', | ||||||
|     queue_album: "*[class^=playQueueItemsContainer] *[class^=groupTitle] span:nth-child(2)", |  | ||||||
|     currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']", |     currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']", | ||||||
|     album_name_cell: '[class^="album"]', |     album_name_cell: '[class^="album"]', | ||||||
|     tracklist_row: '[data-test="tracklist-row"]', |     tracklist_row: '[data-test="tracklist-row"]', | ||||||
|   | |||||||
| @@ -88,9 +88,8 @@ export const addCurrentInfo = (expressApp: Router) => { | |||||||
|    *             schema: |    *             schema: | ||||||
|    *               $ref: '#/components/schemas/MediaInfo' |    *               $ref: '#/components/schemas/MediaInfo' | ||||||
|    */ |    */ | ||||||
|   expressApp.get("/current", (_req, res) => { |   expressApp.get("/current", (req, res) => res.json({ ...mediaInfo, artist: mediaInfo.artists })); | ||||||
|     res.json({ ...mediaInfo, artist: mediaInfo.artists }); |  | ||||||
|   }); |  | ||||||
|   /** |   /** | ||||||
|    * @swagger |    * @swagger | ||||||
|    * /current/image: |    * /current/image: | ||||||
|   | |||||||
| @@ -21,12 +21,8 @@ export const startApi = (mainWindow: BrowserWindow) => { | |||||||
|   expressApp.use(cors()); |   expressApp.use(cors()); | ||||||
|   expressApp.use(express.json()); |   expressApp.use(express.json()); | ||||||
|   expressApp.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec)); |   expressApp.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec)); | ||||||
|   expressApp.get("/", (req, res) => { |   expressApp.get("/", (req, res) => res.send("Hello World!")); | ||||||
|     res.send("Hello World!"); |   expressApp.get("/swagger.json", (req, res) => res.json(swaggerSpec)); | ||||||
|   }); |  | ||||||
|   expressApp.get("/swagger.json", (req, res) => { |  | ||||||
|     res.json(swaggerSpec); |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
|   // add features |   // add features | ||||||
|   addLegacyApi(expressApp, mainWindow); |   addLegacyApi(expressApp, mainWindow); | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|   "openapi": "3.1.0", |   "openapi": "3.1.0", | ||||||
|   "info": { |   "info": { | ||||||
|     "title": "TIDAL Hi-Fi API", |     "title": "TIDAL Hi-Fi API", | ||||||
|     "version": "5.20.1", |     "version": "5.17.0", | ||||||
|     "description": "", |     "description": "", | ||||||
|     "license": { |     "license": { | ||||||
|       "name": "MIT", |       "name": "MIT", | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ import { | |||||||
| import { addTray, refreshTray } from "./scripts/tray"; | import { addTray, refreshTray } from "./scripts/tray"; | ||||||
| let mainInhibitorId = -1; | let mainInhibitorId = -1; | ||||||
|  |  | ||||||
|  | initialize(); | ||||||
| let mainWindow: BrowserWindow; | let mainWindow: BrowserWindow; | ||||||
| const icon = path.join(__dirname, "../assets/icon.png"); | const icon = path.join(__dirname, "../assets/icon.png"); | ||||||
| const PROTOCOL_PREFIX = "tidal"; | const PROTOCOL_PREFIX = "tidal"; | ||||||
| @@ -97,7 +98,6 @@ function createWindow(options = { x: 0, y: 0, backgroundColor: "white" }) { | |||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   enable(mainWindow.webContents); |   enable(mainWindow.webContents); | ||||||
|   registerHttpProtocols(); |   registerHttpProtocols(); | ||||||
|   syncMenuBarWithStore(); |   syncMenuBarWithStore(); | ||||||
| @@ -126,7 +126,6 @@ function createWindow(options = { x: 0, y: 0, backgroundColor: "white" }) { | |||||||
|     } |     } | ||||||
|     return false; |     return false; | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   // Emitted when the window is closed. |   // Emitted when the window is closed. | ||||||
|   mainWindow.on("closed", function () { |   mainWindow.on("closed", function () { | ||||||
|     releaseInhibitorIfActive(mainInhibitorId); |     releaseInhibitorIfActive(mainInhibitorId); | ||||||
| @@ -179,7 +178,6 @@ app.on("ready", async () => { | |||||||
|  |  | ||||||
|   if (isMainInstance() || isMultipleInstancesAllowed()) { |   if (isMainInstance() || isMultipleInstancesAllowed()) { | ||||||
|     await components.whenReady(); |     await components.whenReady(); | ||||||
|     initialize(); |  | ||||||
|  |  | ||||||
|     // Adblock |     // Adblock | ||||||
|     if (settingsStore.get(settings.adBlock)) { |     if (settingsStore.get(settings.adBlock)) { | ||||||
| @@ -190,8 +188,6 @@ app.on("ready", async () => { | |||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Logger.log("components ready:", components.status()); |  | ||||||
|  |  | ||||||
|     createWindow(); |     createWindow(); | ||||||
|     addMenu(mainWindow); |     addMenu(mainWindow); | ||||||
|     createSettingsWindow(); |     createSettingsWindow(); | ||||||
|   | |||||||
| @@ -1,25 +1,34 @@ | |||||||
| <!DOCTYPE html> | <!doctype html> | ||||||
| <html lang="en"> | <html lang="en"> | ||||||
|  |  | ||||||
|   <head> |   <head> | ||||||
|     <title>Tidal Hi-Fi settings</title> |     <title>Tidal Hi-Fi settings</title> | ||||||
|     <meta charset="UTF-8" /> |     <meta charset="UTF-8" /> | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||||
|     <meta http-equiv="X-UA-Compatible" content="ie=edge" /> |     <meta http-equiv="X-UA-Compatible" content="ie=edge" /> | ||||||
|     <link rel="stylesheet" href="./settings.css" /> |     <link rel="stylesheet" href="./settings.css" /> | ||||||
|   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/font-awesome.min.css"> |     <link | ||||||
|  |       rel="stylesheet" | ||||||
|  |       href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" | ||||||
|  |     /> | ||||||
|   </head> |   </head> | ||||||
|  |  | ||||||
|   <body class="settings-window"> |   <body class="settings-window"> | ||||||
|     <div class="settings-window__wrapper"> |     <div class="settings-window__wrapper"> | ||||||
|       <div class="settings-window__drag-area"></div> |       <div class="settings-window__drag-area"></div> | ||||||
|       <a id="close" class="settings-window__close-button" title="Close settings"> |       <a id="close" class="settings-window__close-button" title="Close settings"> | ||||||
|       <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348.333 348.334" class="settings-window__svg-icon"> |         <svg | ||||||
|         <path fill="white" d="M336.559,68.611L231.016,174.165l105.543,105.549c15.699,15.705,15.699,41.145,0,56.85 |           xmlns="http://www.w3.org/2000/svg" | ||||||
|  |           viewBox="0 0 348.333 348.334" | ||||||
|  |           class="settings-window__svg-icon" | ||||||
|  |         > | ||||||
|  |           <path | ||||||
|  |             fill="white" | ||||||
|  |             d="M336.559,68.611L231.016,174.165l105.543,105.549c15.699,15.705,15.699,41.145,0,56.85 | ||||||
|             c-7.844,7.844-18.128,11.769-28.407,11.769c-10.296,0-20.581-3.919-28.419-11.769L174.167,231.003L68.609,336.563 |             c-7.844,7.844-18.128,11.769-28.407,11.769c-10.296,0-20.581-3.919-28.419-11.769L174.167,231.003L68.609,336.563 | ||||||
|             c-7.843,7.844-18.128,11.769-28.416,11.769c-10.285,0-20.563-3.919-28.413-11.769c-15.699-15.698-15.699-41.139,0-56.85 |             c-7.843,7.844-18.128,11.769-28.416,11.769c-10.285,0-20.563-3.919-28.413-11.769c-15.699-15.698-15.699-41.139,0-56.85 | ||||||
|             l105.54-105.549L11.774,68.611c-15.699-15.699-15.699-41.145,0-56.844c15.696-15.687,41.127-15.687,56.829,0l105.563,105.554 |             l105.54-105.549L11.774,68.611c-15.699-15.699-15.699-41.145,0-56.844c15.696-15.687,41.127-15.687,56.829,0l105.563,105.554 | ||||||
|             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" /> |             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" | ||||||
|  |           /> | ||||||
|         </svg> |         </svg> | ||||||
|       </a> |       </a> | ||||||
|  |  | ||||||
| @@ -66,7 +75,13 @@ | |||||||
|                   <span class="switch__slider"></span> |                   <span class="switch__slider"></span> | ||||||
|                 </label> |                 </label> | ||||||
|               </div> |               </div> | ||||||
|             <textarea id="skippedArtists" class="textarea" cols="40" rows="5" spellcheck="false"></textarea> |               <textarea | ||||||
|  |                 id="skippedArtists" | ||||||
|  |                 class="textarea" | ||||||
|  |                 cols="40" | ||||||
|  |                 rows="5" | ||||||
|  |                 spellcheck="false" | ||||||
|  |               ></textarea> | ||||||
|               <div class="group__option"> |               <div class="group__option"> | ||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>Block ads</h4> |                   <h4>Block ads</h4> | ||||||
| @@ -109,7 +124,10 @@ | |||||||
|               <div class="group__option"> |               <div class="group__option"> | ||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>Static Window Title</h4> |                   <h4>Static Window Title</h4> | ||||||
|                 <p>Makes the window title "TIDAL Hi-Fi" instead of changing to the currently playing song.</p> |                   <p> | ||||||
|  |                     Makes the window title "TIDAL Hi-Fi" instead of changing to the currently | ||||||
|  |                     playing song. | ||||||
|  |                   </p> | ||||||
|                 </div> |                 </div> | ||||||
|                 <label class="switch"> |                 <label class="switch"> | ||||||
|                   <input id="staticWindowTitle" type="checkbox" /> |                   <input id="staticWindowTitle" type="checkbox" /> | ||||||
| @@ -131,7 +149,9 @@ | |||||||
|                   <h4>Hotkeys</h4> |                   <h4>Hotkeys</h4> | ||||||
|                   <p> |                   <p> | ||||||
|                     Enable extra hotkeys to achieve feature parity with the |                     Enable extra hotkeys to achieve feature parity with the | ||||||
|                   <a class="external-link" data-url="https://defkey.com/tidal-desktop-shortcuts">desktop apps</a>. |                     <a class="external-link" data-url="https://defkey.com/tidal-desktop-shortcuts" | ||||||
|  |                       >desktop apps</a | ||||||
|  |                     >. | ||||||
|                   </p> |                   </p> | ||||||
|                 </div> |                 </div> | ||||||
|                 <label class="switch"> |                 <label class="switch"> | ||||||
| @@ -157,8 +177,8 @@ | |||||||
|               <p class="group__title">API</p> |               <p class="group__title">API</p> | ||||||
|               <div class="group__description"> |               <div class="group__description"> | ||||||
|                 <p> |                 <p> | ||||||
|                 TIDAL Hi-Fi has a built-in web API to allow users to get current media information. |                   TIDAL Hi-Fi has a built-in web API to allow users to get current media | ||||||
|                 You can optionally enable playback control as well. |                   information. You can optionally enable playback control as well. | ||||||
|                 </p> |                 </p> | ||||||
|               </div> |               </div> | ||||||
|               <div class="group__option"> |               <div class="group__option"> | ||||||
| @@ -180,7 +200,8 @@ | |||||||
|               <div class="group__option"> |               <div class="group__option"> | ||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>API hostname</h4> |                   <h4>API hostname</h4> | ||||||
|                 <p>By default (127.0.0.1) only local apps can interface with the API. <br /> |                   <p> | ||||||
|  |                     By default (127.0.0.1) only local apps can interface with the API. <br /> | ||||||
|                     Change to 0.0.0.0 to allow <strong>anyone</strong> to interact with it. <br /> |                     Change to 0.0.0.0 to allow <strong>anyone</strong> to interact with it. <br /> | ||||||
|                     Other options are available |                     Other options are available | ||||||
|                   </p> |                   </p> | ||||||
| @@ -236,7 +257,6 @@ | |||||||
|                 </label> |                 </label> | ||||||
|               </div> |               </div> | ||||||
|               <div id="discord_options"> |               <div id="discord_options"> | ||||||
|  |  | ||||||
|                 <div class="group__option" class="hidden"> |                 <div class="group__option" class="hidden"> | ||||||
|                   <div class="group__description"> |                   <div class="group__description"> | ||||||
|                     <h4>Show Idle Text</h4> |                     <h4>Show Idle Text</h4> | ||||||
| @@ -252,15 +272,27 @@ | |||||||
|                   <div class="group__description"> |                   <div class="group__description"> | ||||||
|                     <h4>Idle Text</h4> |                     <h4>Idle Text</h4> | ||||||
|                     <p>The text displayed on Discord's rich presence while idling in the app.</p> |                     <p>The text displayed on Discord's rich presence while idling in the app.</p> | ||||||
|                   <input id="discord_idle_text" type="text" class="text-input" name="discord_idle_text" /> |                     <input | ||||||
|  |                       id="discord_idle_text" | ||||||
|  |                       type="text" | ||||||
|  |                       class="text-input" | ||||||
|  |                       name="discord_idle_text" | ||||||
|  |                     /> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
|                 <div class="group__option" class="hidden"> |                 <div class="group__option" class="hidden"> | ||||||
|                   <div class="group__description"> |                   <div class="group__description"> | ||||||
|                     <h4>Using Tidal Text</h4> |                     <h4>Using Tidal Text</h4> | ||||||
|                   <p>The text displayed on Discord's rich presence while "showSong" is turned off</p> |                     <p> | ||||||
|                   <input id="discord_using_text" type="text" class="text-input" name="discord_using_text" /> |                       The text displayed on Discord's rich presence while "showSong" is turned off | ||||||
|  |                     </p> | ||||||
|  |                     <input | ||||||
|  |                       id="discord_using_text" | ||||||
|  |                       type="text" | ||||||
|  |                       class="text-input" | ||||||
|  |                       name="discord_using_text" | ||||||
|  |                     /> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
| @@ -276,7 +308,6 @@ | |||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
|                 <div id="discord_show_song_options" class="hidden"> |                 <div id="discord_show_song_options" class="hidden"> | ||||||
|  |  | ||||||
|                   <div class="group__option" class="hidden"> |                   <div class="group__option" class="hidden"> | ||||||
|                     <div class="group__description"> |                     <div class="group__description"> | ||||||
|                       <h4>Include timestamps</h4> |                       <h4>Include timestamps</h4> | ||||||
| @@ -292,7 +323,12 @@ | |||||||
|                     <div class="group__description"> |                     <div class="group__description"> | ||||||
|                       <h4>Details prefix</h4> |                       <h4>Details prefix</h4> | ||||||
|                       <p>Prefix for the "details" field of Discord's rich presence.</p> |                       <p>Prefix for the "details" field of Discord's rich presence.</p> | ||||||
|                     <input id="discord_details_prefix" type="text" class="text-input" name="discord_details_prefix" /> |                       <input | ||||||
|  |                         id="discord_details_prefix" | ||||||
|  |                         type="text" | ||||||
|  |                         class="text-input" | ||||||
|  |                         name="discord_details_prefix" | ||||||
|  |                       /> | ||||||
|                     </div> |                     </div> | ||||||
|                   </div> |                   </div> | ||||||
|  |  | ||||||
| @@ -300,11 +336,15 @@ | |||||||
|                     <div class="group__description"> |                     <div class="group__description"> | ||||||
|                       <h4>Button text</h4> |                       <h4>Button text</h4> | ||||||
|                       <p>Text to display on the button below the media information.</p> |                       <p>Text to display on the button below the media information.</p> | ||||||
|                     <input id="discord_button_text" type="text" class="text-input" name="discord_button_text" /> |                       <input | ||||||
|  |                         id="discord_button_text" | ||||||
|  |                         type="text" | ||||||
|  |                         class="text-input" | ||||||
|  |                         name="discord_button_text" | ||||||
|  |                       /> | ||||||
|                     </div> |                     </div> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="group"> |             <div class="group"> | ||||||
| @@ -323,23 +363,43 @@ | |||||||
|                 <div class="group__option"> |                 <div class="group__option"> | ||||||
|                   <div class="group__description"> |                   <div class="group__description"> | ||||||
|                     <h4>ListenBrainz API Url</h4> |                     <h4>ListenBrainz API Url</h4> | ||||||
|                   <p>There are multiple instances for ListenBrainz you can set the corresponding API url below.</p> |                     <p> | ||||||
|                   <input id="ListenBrainzAPI" type="text" class="text-input" name="ListenBrainzAPI" /> |                       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> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div class="group__option"> |                 <div class="group__option"> | ||||||
|                   <div class="group__description"> |                   <div class="group__description"> | ||||||
|                     <h4>ListenBrainz User Token</h4> |                     <h4>ListenBrainz User Token</h4> | ||||||
|                     <p>Provide the user token you can get from the settings page.</p> |                     <p>Provide the user token you can get from the settings page.</p> | ||||||
|                   <input id="ListenBrainzToken" type="text" class="text-input" name="ListenBrainzToken" /> |                     <input | ||||||
|  |                       id="ListenBrainzToken" | ||||||
|  |                       type="text" | ||||||
|  |                       class="text-input" | ||||||
|  |                       name="ListenBrainzToken" | ||||||
|  |                     /> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|               <div class="group__description"> |               <div class="group__description"> | ||||||
|                 <h4>ScrobbleDelay</h4> |                 <h4>ScrobbleDelay</h4> | ||||||
|               <p>The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when you fast forward |                 <p> | ||||||
|                 immediately</p> |                   The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when | ||||||
|               <input id="listenbrainz_delay" type="number" class="text-input" name="listenbrainz_delay" /> |                   you fast forward immediately | ||||||
|  |                 </p> | ||||||
|  |                 <input | ||||||
|  |                   id="listenbrainz_delay" | ||||||
|  |                   type="number" | ||||||
|  |                   class="text-input" | ||||||
|  |                   name="listenbrainz_delay" | ||||||
|  |                 /> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </section> |           </section> | ||||||
| @@ -351,12 +411,16 @@ | |||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>Update frequency</h4> |                   <h4>Update frequency</h4> | ||||||
|                   <p> |                   <p> | ||||||
|                   The amount of time, in milliseconds, that TIDAL Hi-Fi will refresh its playback info by scraping the |                     The amount of time, in milliseconds, that TIDAL Hi-Fi will refresh its playback | ||||||
|                   website. |                     info by scraping the website. The default of 500 seems to work in more cases but | ||||||
|                   The default of 500 seems to work in more cases but if you are fine with a bit more resource usage you |                     if you are fine with a bit more resource usage you can decrease it as well. | ||||||
|                   can decrease it as well. |  | ||||||
|                   </p> |                   </p> | ||||||
|                 <input id="updateFrequency" type="number" class="text-input" name="updateFrequency" /> |                   <input | ||||||
|  |                     id="updateFrequency" | ||||||
|  |                     type="number" | ||||||
|  |                     class="text-input" | ||||||
|  |                     name="updateFrequency" | ||||||
|  |                   /> | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|  |  | ||||||
| @@ -369,7 +433,9 @@ | |||||||
|                   </p> |                   </p> | ||||||
|                   <select class="select-input" id="channel" name="channel"> |                   <select class="select-input" id="channel" name="channel"> | ||||||
|                     <option value="https://listen.tidal.com">Stable (listen.tidal.com)</option> |                     <option value="https://listen.tidal.com">Stable (listen.tidal.com)</option> | ||||||
|                   <option value="https://listen.stage.tidal.com">Staging (listen.stage.tidal.com)</option> |                     <option value="https://listen.stage.tidal.com"> | ||||||
|  |                       Staging (listen.stage.tidal.com) | ||||||
|  |                     </option> | ||||||
|                   </select> |                   </select> | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
| @@ -415,7 +481,8 @@ | |||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>Wayland support</h4> |                   <h4>Wayland support</h4> | ||||||
|                   <p> |                   <p> | ||||||
|                   Adds a couple of Electron flags to help TIDAL Hi-Fi run smoothly on the Wayland window system. |                     Adds a couple of Electron flags to help TIDAL Hi-Fi run smoothly on the Wayland | ||||||
|  |                     window system. | ||||||
|                   </p> |                   </p> | ||||||
|                 </div> |                 </div> | ||||||
|                 <label class="switch"> |                 <label class="switch"> | ||||||
| @@ -433,12 +500,19 @@ | |||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>Custom CSS</h4> |                   <h4>Custom CSS</h4> | ||||||
|                   <p> |                   <p> | ||||||
|                   The css that you put in here will be injected into a style tag in the head of the document. |                     The css that you put in here will be injected into a style tag in the head of | ||||||
|  |                     the document. | ||||||
|                   </p> |                   </p> | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           <textarea id="customCSS" class="textarea" cols="40" rows="8" spellcheck="false"></textarea> |             <textarea | ||||||
|  |               id="customCSS" | ||||||
|  |               class="textarea" | ||||||
|  |               cols="40" | ||||||
|  |               rows="8" | ||||||
|  |               spellcheck="false" | ||||||
|  |             ></textarea> | ||||||
|  |  | ||||||
|             <div class="group"> |             <div class="group"> | ||||||
|               <p class="group__title">Theme files</p> |               <p class="group__title">Theme files</p> | ||||||
| @@ -448,9 +522,7 @@ | |||||||
|                   <p> |                   <p> | ||||||
|                     Select a theme below or "Tidal - Default" to return to the original Tidal look. |                     Select a theme below or "Tidal - Default" to return to the original Tidal look. | ||||||
|                   </p> |                   </p> | ||||||
|                 <select class="select-input" id="themesList" name="themesList"> |                   <select class="select-input" id="themesList" name="themesList"></select> | ||||||
|  |  | ||||||
|                 </select> |  | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|  |  | ||||||
| @@ -458,14 +530,20 @@ | |||||||
|                 <div class="group__description"> |                 <div class="group__description"> | ||||||
|                   <h4>Upload new themes</h4> |                   <h4>Upload new themes</h4> | ||||||
|                   <p> |                   <p> | ||||||
|                   Click the button and select the css files to import. They will be added to the theme list |                     Click the button and select the css files to import. They will be added to the | ||||||
|                   automatically. |                     theme list automatically. | ||||||
|                   </p> |                   </p> | ||||||
|                   <div class="file-drop-area"> |                   <div class="file-drop-area"> | ||||||
|                     <div> |                     <div> | ||||||
|                       <span class="file-btn">Choose files</span> |                       <span class="file-btn">Choose files</span> | ||||||
|                       <span id="file-message" class="file-msg">or drag and drop files here</span> |                       <span id="file-message" class="file-msg">or drag and drop files here</span> | ||||||
|                     <input id="theme-files" class="file-input" type="file" accept=".css" multiple> |                       <input | ||||||
|  |                         id="theme-files" | ||||||
|  |                         class="file-input" | ||||||
|  |                         type="file" | ||||||
|  |                         accept=".css" | ||||||
|  |                         multiple | ||||||
|  |                       /> | ||||||
|                     </div> |                     </div> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
| @@ -477,17 +555,35 @@ | |||||||
|             <img alt="tidal icon" class="about-section__icon" src="./icon.png" /> |             <img alt="tidal icon" class="about-section__icon" src="./icon.png" /> | ||||||
|             <h4>TIDAL Hi-Fi</h4> |             <h4>TIDAL Hi-Fi</h4> | ||||||
|             <div class="about-section__version"> |             <div class="about-section__version"> | ||||||
|             <a target="_blank" rel="noopener" |               <a | ||||||
|               href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.20.1">5.20.1</a> |                 target="_blank" | ||||||
|  |                 rel="noopener" | ||||||
|  |                 href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.17.0" | ||||||
|  |                 >5.17.0</a | ||||||
|  |               > | ||||||
|             </div> |             </div> | ||||||
|             <div class="about-section__links"> |             <div class="about-section__links"> | ||||||
|             <a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/" |               <a | ||||||
|               class="about-section__button">Github |                 target="_blank" | ||||||
|               <i class="fa fa-external-link"></i></a> |                 rel="noopener" | ||||||
|             <a target="_blank" rel="noopener" href="https://github.com/Mastermindzh/tidal-hifi/issues" |                 href="https://github.com/mastermindzh/tidal-hifi/" | ||||||
|               class="about-section__button">Report an issue <i class="fa fa-external-link"></i></a> |                 class="about-section__button" | ||||||
|             <a target="_blank" rel="noopener" href="https://github.com/Mastermindzh/tidal-hifi/graphs/contributors" |                 >Github <i class="fa fa-external-link"></i | ||||||
|               class="about-section__button">Contributors <i class="fa fa-external-link"></i></a> |               ></a> | ||||||
|  |               <a | ||||||
|  |                 target="_blank" | ||||||
|  |                 rel="noopener" | ||||||
|  |                 href="https://github.com/Mastermindzh/tidal-hifi/issues" | ||||||
|  |                 class="about-section__button" | ||||||
|  |                 >Report an issue <i class="fa fa-external-link"></i | ||||||
|  |               ></a> | ||||||
|  |               <a | ||||||
|  |                 target="_blank" | ||||||
|  |                 rel="noopener" | ||||||
|  |                 href="https://github.com/Mastermindzh/tidal-hifi/graphs/contributors" | ||||||
|  |                 class="about-section__button" | ||||||
|  |                 >Contributors <i class="fa fa-external-link"></i | ||||||
|  |               ></a> | ||||||
|             </div> |             </div> | ||||||
|           </section> |           </section> | ||||||
|  |  | ||||||
| @@ -500,5 +596,4 @@ | |||||||
|       </main> |       </main> | ||||||
|     </div> |     </div> | ||||||
|   </body> |   </body> | ||||||
|  |  | ||||||
| </html> | </html> | ||||||
| @@ -54,12 +54,12 @@ const elements = { | |||||||
|   media: '*[data-test="current-media-imagery"]', |   media: '*[data-test="current-media-imagery"]', | ||||||
|   image: "img", |   image: "img", | ||||||
|   current: '*[data-test="current-time"]', |   current: '*[data-test="current-time"]', | ||||||
|   duration: '*[class^=_playbackControlsContainer] *[data-test="duration"]', |   duration: '*[class^=playbackControlsContainer] *[data-test="duration"]', | ||||||
|   bar: '*[data-test="progress-bar"]', |   bar: '*[data-test="progress-bar"]', | ||||||
|   footer: "#footerPlayer", |   footer: "#footerPlayer", | ||||||
|   mediaItem: "[data-type='mediaItem']", |   mediaItem: "[data-type='mediaItem']", | ||||||
|   album_header_title: '*[class^="_playingFrom"] span:nth-child(2)', |   album_header_title: '*[class^="playingFrom"] span:nth-child(2)', | ||||||
|   playing_from: '*[class^="_playingFrom"] span:nth-child(2)', |   playing_from: '*[class^="playingFrom"] span:nth-child(2)', | ||||||
|   queue_album: "*[class^=playQueueItemsContainer] *[class^=groupTitle] span:nth-child(2)", |   queue_album: "*[class^=playQueueItemsContainer] *[class^=groupTitle] span:nth-child(2)", | ||||||
|   currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']", |   currentlyPlaying: "[class^='isPlayingIcon'], [data-test-is-playing='true']", | ||||||
|   album_name_cell: '[class^="album"]', |   album_name_cell: '[class^="album"]', | ||||||
| @@ -115,19 +115,18 @@ const elements = { | |||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   getAlbumName: function () { |   getAlbumName: function () { | ||||||
|     try { |  | ||||||
|     //If listening to an album, get its name from the header title |     //If listening to an album, get its name from the header title | ||||||
|       if (globalThis.location.href.includes("/album/")) { |     if (window.location.href.includes("/album/")) { | ||||||
|         const albumName = globalThis.document.querySelector(this.album_header_title); |       const albumName = window.document.querySelector(this.album_header_title); | ||||||
|       if (albumName) { |       if (albumName) { | ||||||
|         return albumName.textContent; |         return albumName.textContent; | ||||||
|       } |       } | ||||||
|       //If listening to a playlist or a mix, get album name from the list |       //If listening to a playlist or a mix, get album name from the list | ||||||
|     } else if ( |     } else if ( | ||||||
|         globalThis.location.href.includes("/playlist/") || |       window.location.href.includes("/playlist/") || | ||||||
|         globalThis.location.href.includes("/mix/") |       window.location.href.includes("/mix/") | ||||||
|     ) { |     ) { | ||||||
|         if (this.currentlyPlaying === MediaStatus.playing) { |       if (currentPlayStatus === MediaStatus.playing) { | ||||||
|         // find the currently playing element from the list (which might be in an album icon), traverse back up to the mediaItem (row) and select the album cell. |         // find the currently playing element from the list (which might be in an album icon), traverse back up to the mediaItem (row) and select the album cell. | ||||||
|         // document.querySelector("[class^='isPlayingIcon'], [data-test-is-playing='true']").closest('[data-type="mediaItem"]').querySelector('[class^="album"]').textContent |         // document.querySelector("[class^='isPlayingIcon'], [data-test-is-playing='true']").closest('[data-type="mediaItem"]').querySelector('[class^="album"]').textContent | ||||||
|         const row = window.document.querySelector(this.currentlyPlaying).closest(this.mediaItem); |         const row = window.document.querySelector(this.currentlyPlaying).closest(this.mediaItem); | ||||||
| @@ -138,15 +137,12 @@ const elements = { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // see whether we're on the queue page and get it from there |     // see whether we're on the queue page and get it from there | ||||||
|       const queueAlbumName = this.getText("queue_album"); |     const queueAlbumName = elements.getText("queue_album"); | ||||||
|     if (queueAlbumName) { |     if (queueAlbumName) { | ||||||
|       return queueAlbumName; |       return queueAlbumName; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ""; |     return ""; | ||||||
|     } catch { |  | ||||||
|       return ""; |  | ||||||
|     } |  | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   isMuted: function () { |   isMuted: function () { | ||||||
| @@ -487,7 +483,6 @@ function updateMpris(mediaInfo: MediaInfo) { | |||||||
|         "xesam:title": mediaInfo.title, |         "xesam:title": mediaInfo.title, | ||||||
|         "xesam:artist": [mediaInfo.artists], |         "xesam:artist": [mediaInfo.artists], | ||||||
|         "xesam:album": mediaInfo.album, |         "xesam:album": mediaInfo.album, | ||||||
|         "xesam:url": mediaInfo.url, |  | ||||||
|         "mpris:artUrl": mediaInfo.image, |         "mpris:artUrl": mediaInfo.image, | ||||||
|         "mpris:length": convertDuration(mediaInfo.duration) * 1000 * 1000, |         "mpris:length": convertDuration(mediaInfo.duration) * 1000 * 1000, | ||||||
|         "mpris:trackid": "/org/mpris/MediaPlayer2/track/" + getTrackID(), |         "mpris:trackid": "/org/mpris/MediaPlayer2/track/" + getTrackID(), | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ const defaultPresence = { | |||||||
|   largeImageKey: "tidal-hifi-icon", |   largeImageKey: "tidal-hifi-icon", | ||||||
|   largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, |   largeImageText: `TIDAL Hi-Fi ${app.getVersion()}`, | ||||||
|   instance: false, |   instance: false, | ||||||
|   type: ACTIVITY_LISTENING |   type: ACTIVITY_LISTENING, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const updateActivity = () => { | const updateActivity = () => { | ||||||
| @@ -103,7 +103,8 @@ const getActivity = (): SetActivity => { | |||||||
|     if (includeTimestamps) { |     if (includeTimestamps) { | ||||||
|       const currentSeconds = convertDurationToSeconds(mediaInfo.current); |       const currentSeconds = convertDurationToSeconds(mediaInfo.current); | ||||||
|       const durationSeconds = convertDurationToSeconds(mediaInfo.duration); |       const durationSeconds = convertDurationToSeconds(mediaInfo.duration); | ||||||
|       const now = Math.trunc((Date.now() + 500) / 1000); |       const date = new Date(); | ||||||
|  |       const now = Math.floor(date.getTime() / 1000); | ||||||
|       presence.startTimestamp = now - currentSeconds; |       presence.startTimestamp = now - currentSeconds; | ||||||
|       presence.endTimestamp = presence.startTimestamp + durationSeconds; |       presence.endTimestamp = presence.startTimestamp + durationSeconds; | ||||||
|     } |     } | ||||||
| @@ -117,15 +118,17 @@ const getActivity = (): SetActivity => { | |||||||
| const connectWithRetry = async (retryCount = 0) => { | const connectWithRetry = async (retryCount = 0) => { | ||||||
|   try { |   try { | ||||||
|     await rpc.login(); |     await rpc.login(); | ||||||
|     Logger.log('Connected to Discord'); |     Logger.log("Connected to Discord"); | ||||||
|     rpc.on("ready", updateActivity); |     rpc.on("ready", updateActivity); | ||||||
|     Object.values(globalEvents).forEach(event => ipcMain.on(event, observer)); |     Object.values(globalEvents).forEach((event) => ipcMain.on(event, observer)); | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     if (retryCount < MAX_RETRIES) { |     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); |       setTimeout(() => connectWithRetry(retryCount + 1), RETRY_DELAY); | ||||||
|     } else { |     } else { | ||||||
|       Logger.log('Failed to connect to Discord after maximum retry attempts'); |       Logger.log("Failed to connect to Discord after maximum retry attempts"); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user