mirror of
				https://github.com/Mastermindzh/tidal-hifi.git
				synced 2025-10-31 16:59:09 +01:00 
			
		
		
		
	Compare commits
	
		
			205 Commits
		
	
	
		
			develop
			...
			c89fe5e573
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c89fe5e573 | |||
|  | 255b59c87c | ||
| 2bbca7df24 | |||
| eecae61405 | |||
|  | 15dbadcc73 | ||
|  | 14b92cc5de | ||
| 959fc6631f | |||
| 91f70752c8 | |||
|  | 4f0dcee359 | ||
|  | a4a963c17b | ||
| 2ecacff0e1 | |||
|  | b426f0857e | ||
| 36c9887552 | |||
|  | 9efdbb8234 | ||
| 4d5b6a35e2 | |||
|  | 7923303e18 | ||
| cc95089201 | |||
| 9b010ea2bf | |||
| 3828591177 | |||
|  | 1e471df549 | ||
|  | 96acbd3559 | ||
|  | 224689b15b | ||
| 5f1fc8731a | |||
| 02ad1289c5 | |||
| b684d290bd | |||
|  | f35fd542b2 | ||
|  | 6831e55681 | ||
| 69ad060485 | |||
| 985831e961 | |||
|  | 218f7652cd | ||
|  | e46b34e076 | ||
|  | 5f49d0d3a9 | ||
| c1850436e1 | |||
|  | 7efbd52553 | ||
| 5ea91bbfde | |||
| 76b8adb038 | |||
| a746e53f7a | |||
|  | 149c0c975f | ||
|  | 98339444f7 | ||
|  | fd5bc505da | ||
| 5f94cfbf63 | |||
| 466c39134f | |||
| da8baebf29 | |||
|  | aa6a8b3417 | ||
| 4a1152175c | |||
|  | 721c3f5047 | ||
|  | d4b0552c14 | ||
|  | 44c8c01b8b | ||
| 8d4dd1ec9d | |||
| d012ecb04e | |||
|  | fa4b4da9a5 | ||
|  | 8f1a5dc344 | ||
| 604f34b31f | |||
| 3ff37f78e8 | |||
| 8eaca2221f | |||
| 8e9e9fed4f | |||
|  | d839dba58d | ||
| bbbd919655 | |||
| d4104b21e4 | |||
| 6a23873d3d | |||
| 8d6f08a7bb | |||
| 521b8b2170 | |||
|  | 99e4cb7f48 | ||
|  | 4cd130ee0d | ||
|  | a2a2c800b6 | ||
|  | 83210f9e1d | ||
| 5d40d2d736 | |||
| 405c2d7c9f | |||
|  | 9f860d2eec | ||
|  | 86487863f8 | ||
| 3312211df2 | |||
|  | a84bb9efde | ||
| 31c37b6c7f | |||
| be9724f0cb | |||
|  | 7277482c06 | ||
|  | 323b591f4f | ||
| c63b46ee06 | |||
|  | b4a8e155af | ||
| 2702d99aca | |||
|  | 7cf9ae5c36 | ||
| 3a1402b47a | |||
|  | 4366caa16a | ||
|  | 9389b4195e | ||
| 87d8bc07ad | |||
|  | 316bf054f5 | ||
| 0d4975ce62 | |||
|  | 912f064fed | ||
| bff95bcf10 | |||
| b59dce9c9b | |||
|  | f71fb60d38 | ||
|  | fab566e9da | ||
| d2e93e7062 | |||
|  | 52a78a6a01 | ||
| f878371fab | |||
| e81aaf1384 | |||
|  | 98b4068b62 | ||
|  | b7c1cee64d | ||
| 350b4434be | |||
| 702a16357f | |||
| c6619be068 | |||
| bf7cd70f20 | |||
| 03cb14e31e | |||
| 697298da38 | |||
| 5f5b3b11a8 | |||
| d474b7b78f | |||
| ef374ea283 | |||
|  | 96ff46737b | ||
|  | dee0044876 | ||
| 3b1f456d4c | |||
|  | f380839631 | ||
| fca5194873 | |||
|  | 92d1fc159d | ||
| b632c287b0 | |||
| 5a98b13e70 | |||
| 3543253f3a | |||
|  | fff8399c9b | ||
|  | 78b9b32dbd | ||
|  | c773e59432 | ||
| 535de65e17 | |||
| b80599eab2 | |||
| c161ef8f60 | |||
| 7ed160f266 | |||
| b23975227f | |||
| 314e69dd4b | |||
|  | 10251e2f30 | ||
|  | cf06655008 | ||
|  | d5804ed4da | ||
|  | 76500ca6b8 | ||
|  | f5c80e97c5 | ||
|  | 154698c084 | ||
| 9837e77768 | |||
| 340bd82fe6 | |||
| b765ab9f48 | |||
| 6562549897 | |||
| 9089bc1d4e | |||
| 5a3609676e | |||
| 76c3082d5c | |||
| 7f7a8b7f5b | |||
|  | 2d49504818 | ||
|  | 5f4f0c67d5 | ||
|  | 3a5f1f155a | ||
|  | 3c9328fb92 | ||
|  | f262c54be2 | ||
|  | cb6e3e8b18 | ||
|  | 7f9b8dcee4 | ||
|  | 99740f4335 | ||
| 985bc0f1d5 | |||
| 1f9b3a297a | |||
| 98ca73d17d | |||
| 396ed223d3 | |||
|  | b0458f4de5 | ||
|  | b875d091ec | ||
|  | 1a0b69d042 | ||
|  | e23a71a1a6 | ||
| 510ffa1509 | |||
|  | e17ef32cde | ||
| d4c3999d9c | |||
| b0695600b1 | |||
|  | 22ecc7ade7 | ||
| a5102ebd03 | |||
|  | d01f08508f | ||
| e87d8f6922 | |||
|  | c044476014 | ||
| 75df43864b | |||
|  | 174d0a38a1 | ||
|  | cf1aeefe67 | ||
| 280d927a03 | |||
|  | f62294ef20 | ||
| 237e354f80 | |||
|  | 3a5172cb23 | ||
|  | f8f12cca62 | ||
| 79bbab6a82 | |||
| 7376df7f30 | |||
| 7f8760c4e9 | |||
|  | 1cf5a01ad7 | ||
| 8fc49f500e | |||
|  | 49f5a01b58 | ||
| 48f4fe47ef | |||
| a819e1eb45 | |||
| 57e6342b5f | |||
| 58a543a3c8 | |||
| 1c915d99fe | |||
|  | 8994360415 | ||
| a5c0d9e6e8 | |||
| f8eb36f4c7 | |||
| 5ca90c25d3 | |||
| cf86969cfc | |||
| afd05ae88b | |||
| 72c25dfdc1 | |||
|  | 25b30edf31 | ||
| 35ed4807e3 | |||
| deff9524a8 | |||
| 34c7777eeb | |||
| 048e949f30 | |||
|  | 4a976bc58c | ||
| ff4c51234b | |||
|  | c4ee6b51b9 | ||
| 45fe336598 | |||
|  | fe9f50aaf5 | ||
| aaf7a1b662 | |||
| 755be0ee30 | |||
|  | 9d736b2bd9 | ||
| f4d4b1a1df | |||
|  | 0c27c815f5 | ||
|  | a3aa45a96b | 
| @@ -4,12 +4,12 @@ name: default | |||||||
|  |  | ||||||
| steps: | steps: | ||||||
|   - name: install |   - name: install | ||||||
|     image: node:19.4.0 |     image: node:22.17.0 | ||||||
|     commands: |     commands: | ||||||
|       - npm install |       - npm install | ||||||
|  |  | ||||||
|   - name: build_with_linux |   - name: build_with_linux | ||||||
|     image: node:19.4.0 |     image: node:22.17.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,26 +21,30 @@ jobs: | |||||||
|       - 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.12.0 | ||||||
|       - 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.4 |           node-version: 22.12.0 | ||||||
|       - 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,7 +1,13 @@ | |||||||
| { | { | ||||||
|   "plugins": ["stylelint-prettier"], |   "plugins": [ | ||||||
|   "extends": ["stylelint-config-standard-scss"], |     "stylelint-prettier" | ||||||
|   "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,7 +17,9 @@ | |||||||
|     "trackid", |     "trackid", | ||||||
|     "tracklist", |     "tracklist", | ||||||
|     "widevine", |     "widevine", | ||||||
|     "xesam" |     "wvcus", | ||||||
|  |     "xesam", | ||||||
|  |     "xhayper" | ||||||
|   ], |   ], | ||||||
|   "sonarlint.connectedMode.project": { |   "sonarlint.connectedMode.project": { | ||||||
|     "connectionId": "public-sonarcloud", |     "connectionId": "public-sonarcloud", | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -4,6 +4,42 @@ 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) | ||||||
| @@ -21,7 +57,6 @@ 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 | ||||||
| @@ -113,12 +148,10 @@ 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,3 +8,4 @@ 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: 28.1.1 | electronVersion: 37.2.5 | ||||||
| electronDownload: | electronDownload: | ||||||
|   version: 28.1.1+wvcus |   version: 37.2.5+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,24 +17,25 @@ 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: | ||||||
|     Encoding: UTF-8 |     entry: | ||||||
|     Name: TIDAL Hi-Fi |       Encoding: "UTF-8" | ||||||
|     GenericName: TIDAL Hi-Fi |       Name: "TIDAL Hi-Fi" | ||||||
|     Comment: The web version of listen.tidal.com running in electron with hifi support thanks to widevine. |       GenericName: "TIDAL Hi-Fi" | ||||||
|     Icon: tidal-hifi |       Comment: "The web version of listen.tidal.com running in electron with hifi support thanks to widevine." | ||||||
|     StartupNotify: true |       Icon: "tidal-hifi" | ||||||
|     Terminal: false |       StartupNotify: "true" | ||||||
|     Type: Application |       Terminal: "false" | ||||||
|     Categories: Network;Application;AudioVideo;Audio;Video |       Type: "Application" | ||||||
|     StartupWMClass: tidal-hifi |       Categories: "Network;Application;AudioVideo;Audio;Video" | ||||||
|     X-PulseAudio-Properties: media.role=music |       StartupWMClass: "tidal-hifi" | ||||||
|     MimeType: x-scheme-handler/tidal; |       X-PulseAudio-Properties: "media.role=music" | ||||||
|  |       MimeType: "x-scheme-handler/tidal;" | ||||||
| mac: | mac: | ||||||
|   category: public.app-category.entertainment |   category: public.app-category.entertainment | ||||||
| win: | win: | ||||||
|   | |||||||
							
								
								
									
										5617
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5617
									
								
								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.17.0", |   "version": "5.20.1", | ||||||
|   "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 .", |     "start": "electron --inspect=0.0.0.0:5858 --remote-debugging-port=8315 --remote-allow-origins=* .", | ||||||
|     "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,7 +23,6 @@ | |||||||
|     "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", | ||||||
| @@ -41,44 +40,45 @@ | |||||||
|   "homepage": "https://github.com/Mastermindzh/tidal-hifi", |   "homepage": "https://github.com/Mastermindzh/tidal-hifi", | ||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@electron/remote": "^2.1.2", |     "@electron/remote": "^2.1.3", | ||||||
|     "@types/swagger-jsdoc": "^6.0.4", |     "@types/swagger-jsdoc": "^6.0.4", | ||||||
|     "@xhayper/discord-rpc": "^1.2.0", |     "@xhayper/discord-rpc": "1.3.0", | ||||||
|     "axios": "^1.7.7", |     "axios": "^1.12.0", | ||||||
|     "cors": "^2.8.5", |     "cors": "^2.8.5", | ||||||
|     "electron-store": "^8.2.0", |     "electron-store": "^8.2.0", | ||||||
|     "express": "^4.21.1", |     "express": "^5.1.0", | ||||||
|     "hotkeys-js": "^3.13.7", |     "hotkeys-js": "^3.13.15", | ||||||
|     "mpris-service": "^2.1.2", |     "mpris-service": "^2.1.2", | ||||||
|     "request": "^2.88.2", |     "request": "^2.88.2", | ||||||
|     "sass": "^1.79.4", |     "sass": "1.93.2", | ||||||
|     "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.17", |     "@types/cors": "^2.8.19", | ||||||
|     "@types/express": "^4.17.21", |     "@types/express": "^5.0.3", | ||||||
|     "@types/node": "^20.14.10", |     "@types/node": "^22.16.2", | ||||||
|     "@types/request": "^2.48.12", |     "@types/request": "^2.48.12", | ||||||
|     "@types/swagger-ui-express": "^4.1.6", |     "@types/swagger-ui-express": "^4.1.8", | ||||||
|     "@typescript-eslint/eslint-plugin": "^7.16.0", |     "@typescript-eslint/eslint-plugin": "^8.36.0", | ||||||
|     "@typescript-eslint/parser": "^7.15.0", |     "@typescript-eslint/parser": "^8.36.0", | ||||||
|     "copyfiles": "^2.4.1", |     "copyfiles": "^2.4.1", | ||||||
|     "electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus", |     "electron": "github:castlabs/electron-releases#v37.2.5+wvcus", | ||||||
|     "electron-builder": "~24.9.4", |     "electron-builder": "~26.0.12", | ||||||
|     "eslint": "^8.57.0", |     "eslint": "^9.30.1", | ||||||
|     "js-yaml": "^4.1.0", |     "js-yaml": "^4.1.0", | ||||||
|     "markdown-toc": "^1.2.0", |     "markdown-toc": "^1.2.0", | ||||||
|     "nodemon": "^3.1.4", |     "node-abi": "^4.12.0", | ||||||
|     "prettier": "^3.3.2", |     "nodemon": "^3.1.10", | ||||||
|     "stylelint": "^16.6.1", |     "prettier": "^3.6.2", | ||||||
|     "stylelint-config-standard": "^36.0.1", |     "stylelint": "^16.21.1", | ||||||
|     "stylelint-config-standard-scss": "^13.1.0", |     "stylelint-config-standard": "^39.0.0", | ||||||
|     "stylelint-prettier": "^5.0.0", |     "stylelint-config-standard-scss": "^16.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": "^6.2.0", |     "tsc-watch": "^7.1.1", | ||||||
|     "typescript": "^5.5.3" |     "typescript": "^5.8.3" | ||||||
|   }, |   }, | ||||||
|   "prettier": "@mastermindzh/prettier-config" |   "prettier": "@mastermindzh/prettier-config" | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								renovate.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								renovate.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |   "$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||||||
|  |   "ignoreDeps": ["@types/node", "electron-store", "@xhayper/discord-rpc"] | ||||||
|  | } | ||||||
| @@ -22,12 +22,13 @@ | |||||||
|     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)', | ||||||
|     playingFrom: '*[class^="playingFrom"] span:nth-child(2)', |     playing_from: '*[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,8 +88,9 @@ export const addCurrentInfo = (expressApp: Router) => { | |||||||
|    *             schema: |    *             schema: | ||||||
|    *               $ref: '#/components/schemas/MediaInfo' |    *               $ref: '#/components/schemas/MediaInfo' | ||||||
|    */ |    */ | ||||||
|   expressApp.get("/current", (req, res) => res.json({ ...mediaInfo, artist: mediaInfo.artists })); |   expressApp.get("/current", (_req, res) => { | ||||||
|  |     res.json({ ...mediaInfo, artist: mediaInfo.artists }); | ||||||
|  |   }); | ||||||
|   /** |   /** | ||||||
|    * @swagger |    * @swagger | ||||||
|    * /current/image: |    * /current/image: | ||||||
|   | |||||||
| @@ -21,8 +21,12 @@ 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) => res.send("Hello World!")); |   expressApp.get("/", (req, res) => { | ||||||
|   expressApp.get("/swagger.json", (req, res) => res.json(swaggerSpec)); |     res.send("Hello World!"); | ||||||
|  |   }); | ||||||
|  |   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.17.0", |     "version": "5.20.1", | ||||||
|     "description": "", |     "description": "", | ||||||
|     "license": { |     "license": { | ||||||
|       "name": "MIT", |       "name": "MIT", | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ 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"; | ||||||
| @@ -98,6 +97,7 @@ function createWindow(options = { x: 0, y: 0, backgroundColor: "white" }) { | |||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   enable(mainWindow.webContents); |   enable(mainWindow.webContents); | ||||||
|   registerHttpProtocols(); |   registerHttpProtocols(); | ||||||
|   syncMenuBarWithStore(); |   syncMenuBarWithStore(); | ||||||
| @@ -126,6 +126,7 @@ 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); | ||||||
| @@ -178,6 +179,7 @@ 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)) { | ||||||
| @@ -188,6 +190,8 @@ app.on("ready", async () => { | |||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     Logger.log("components ready:", components.status()); | ||||||
|  |  | ||||||
|     createWindow(); |     createWindow(); | ||||||
|     addMenu(mainWindow); |     addMenu(mainWindow); | ||||||
|     createSettingsWindow(); |     createSettingsWindow(); | ||||||
|   | |||||||
| @@ -1,34 +1,25 @@ | |||||||
| <!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 |   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/font-awesome.min.css"> | ||||||
|       rel="stylesheet" | </head> | ||||||
|       href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" |  | ||||||
|     /> |  | ||||||
|   </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 |       <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348.333 348.334" class="settings-window__svg-icon"> | ||||||
|           xmlns="http://www.w3.org/2000/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 | ||||||
|           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> | ||||||
|  |  | ||||||
| @@ -75,13 +66,7 @@ | |||||||
|                 <span class="switch__slider"></span> |                 <span class="switch__slider"></span> | ||||||
|               </label> |               </label> | ||||||
|             </div> |             </div> | ||||||
|               <textarea |             <textarea id="skippedArtists" class="textarea" cols="40" rows="5" spellcheck="false"></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> | ||||||
| @@ -124,10 +109,7 @@ | |||||||
|             <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> |                 <p>Makes the window title "TIDAL Hi-Fi" instead of changing to the currently playing song.</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" /> | ||||||
| @@ -149,9 +131,7 @@ | |||||||
|                 <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" |                   <a class="external-link" data-url="https://defkey.com/tidal-desktop-shortcuts">desktop apps</a>. | ||||||
|                       >desktop apps</a |  | ||||||
|                     >. |  | ||||||
|                 </p> |                 </p> | ||||||
|               </div> |               </div> | ||||||
|               <label class="switch"> |               <label class="switch"> | ||||||
| @@ -177,8 +157,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 |                 TIDAL Hi-Fi has a built-in web API to allow users to get current media information. | ||||||
|                   information. You can optionally enable playback control as well. |                 You can optionally enable playback control as well. | ||||||
|               </p> |               </p> | ||||||
|             </div> |             </div> | ||||||
|             <div class="group__option"> |             <div class="group__option"> | ||||||
| @@ -200,8 +180,7 @@ | |||||||
|             <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> |                 <p>By default (127.0.0.1) only local apps can interface with the API. <br /> | ||||||
|                     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> | ||||||
| @@ -257,6 +236,7 @@ | |||||||
|               </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> | ||||||
| @@ -272,27 +252,15 @@ | |||||||
|                 <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 |                   <input id="discord_idle_text" type="text" class="text-input" name="discord_idle_text" /> | ||||||
|                       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> |                   <p>The text displayed on Discord's rich presence while "showSong" is turned off</p> | ||||||
|                       The text displayed on Discord's rich presence while "showSong" is turned off |                   <input id="discord_using_text" type="text" class="text-input" name="discord_using_text" /> | ||||||
|                     </p> |  | ||||||
|                     <input |  | ||||||
|                       id="discord_using_text" |  | ||||||
|                       type="text" |  | ||||||
|                       class="text-input" |  | ||||||
|                       name="discord_using_text" |  | ||||||
|                     /> |  | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
|  |  | ||||||
| @@ -308,6 +276,7 @@ | |||||||
|               </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> | ||||||
| @@ -323,12 +292,7 @@ | |||||||
|                   <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 |                     <input id="discord_details_prefix" type="text" class="text-input" name="discord_details_prefix" /> | ||||||
|                         id="discord_details_prefix" |  | ||||||
|                         type="text" |  | ||||||
|                         class="text-input" |  | ||||||
|                         name="discord_details_prefix" |  | ||||||
|                       /> |  | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
| @@ -336,15 +300,11 @@ | |||||||
|                   <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 |                     <input id="discord_button_text" type="text" class="text-input" name="discord_button_text" /> | ||||||
|                         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"> | ||||||
| @@ -363,43 +323,23 @@ | |||||||
|               <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> |                   <p>There are multiple instances for ListenBrainz you can set the corresponding API url below.</p> | ||||||
|                       There are multiple instances for ListenBrainz you can set the corresponding |                   <input id="ListenBrainzAPI" type="text" class="text-input" name="ListenBrainzAPI" /> | ||||||
|                       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 |                   <input id="ListenBrainzToken" type="text" class="text-input" name="ListenBrainzToken" /> | ||||||
|                       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> |               <p>The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when you fast forward | ||||||
|                   The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when |                 immediately</p> | ||||||
|                   you fast forward immediately |               <input id="listenbrainz_delay" type="number" class="text-input" name="listenbrainz_delay" /> | ||||||
|                 </p> |  | ||||||
|                 <input |  | ||||||
|                   id="listenbrainz_delay" |  | ||||||
|                   type="number" |  | ||||||
|                   class="text-input" |  | ||||||
|                   name="listenbrainz_delay" |  | ||||||
|                 /> |  | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|         </section> |         </section> | ||||||
| @@ -411,16 +351,12 @@ | |||||||
|               <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 |                   The amount of time, in milliseconds, that TIDAL Hi-Fi will refresh its playback info by scraping the | ||||||
|                     info by scraping the website. The default of 500 seems to work in more cases but |                   website. | ||||||
|                     if you are fine with a bit more resource usage you can decrease it as well. |                   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. | ||||||
|                 </p> |                 </p> | ||||||
|                   <input |                 <input id="updateFrequency" type="number" class="text-input" name="updateFrequency" /> | ||||||
|                     id="updateFrequency" |  | ||||||
|                     type="number" |  | ||||||
|                     class="text-input" |  | ||||||
|                     name="updateFrequency" |  | ||||||
|                   /> |  | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
| @@ -433,9 +369,7 @@ | |||||||
|                 </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"> |                   <option value="https://listen.stage.tidal.com">Staging (listen.stage.tidal.com)</option> | ||||||
|                       Staging (listen.stage.tidal.com) |  | ||||||
|                     </option> |  | ||||||
|                 </select> |                 </select> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
| @@ -481,8 +415,7 @@ | |||||||
|               <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 |                   Adds a couple of Electron flags to help TIDAL Hi-Fi run smoothly on the Wayland window system. | ||||||
|                     window system. |  | ||||||
|                 </p> |                 </p> | ||||||
|               </div> |               </div> | ||||||
|               <label class="switch"> |               <label class="switch"> | ||||||
| @@ -500,19 +433,12 @@ | |||||||
|               <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 css that you put in here will be injected into a style tag in the head of the document. | ||||||
|                     the document. |  | ||||||
|                 </p> |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|             <textarea |           <textarea id="customCSS" class="textarea" cols="40" rows="8" spellcheck="false"></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> | ||||||
| @@ -522,7 +448,9 @@ | |||||||
|                 <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> |                 <select class="select-input" id="themesList" name="themesList"> | ||||||
|  |  | ||||||
|  |                 </select> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
| @@ -530,20 +458,14 @@ | |||||||
|               <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 |                   Click the button and select the css files to import. They will be added to the theme list | ||||||
|                     theme list automatically. |                   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 |                     <input id="theme-files" class="file-input" type="file" accept=".css" multiple> | ||||||
|                         id="theme-files" |  | ||||||
|                         class="file-input" |  | ||||||
|                         type="file" |  | ||||||
|                         accept=".css" |  | ||||||
|                         multiple |  | ||||||
|                       /> |  | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|               </div> |               </div> | ||||||
| @@ -555,35 +477,17 @@ | |||||||
|           <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 |             <a target="_blank" rel="noopener" | ||||||
|                 target="_blank" |               href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.20.1">5.20.1</a> | ||||||
|                 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 |             <a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/" | ||||||
|                 target="_blank" |               class="about-section__button">Github | ||||||
|                 rel="noopener" |               <i class="fa fa-external-link"></i></a> | ||||||
|                 href="https://github.com/mastermindzh/tidal-hifi/" |             <a target="_blank" rel="noopener" href="https://github.com/Mastermindzh/tidal-hifi/issues" | ||||||
|                 class="about-section__button" |               class="about-section__button">Report an issue <i class="fa fa-external-link"></i></a> | ||||||
|                 >Github <i class="fa fa-external-link"></i |             <a target="_blank" rel="noopener" href="https://github.com/Mastermindzh/tidal-hifi/graphs/contributors" | ||||||
|               ></a> |               class="about-section__button">Contributors <i class="fa fa-external-link"></i></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> | ||||||
|  |  | ||||||
| @@ -595,5 +499,6 @@ | |||||||
|       </div> |       </div> | ||||||
|     </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,18 +115,19 @@ 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 (window.location.href.includes("/album/")) { |       if (globalThis.location.href.includes("/album/")) { | ||||||
|       const albumName = window.document.querySelector(this.album_header_title); |         const albumName = globalThis.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 ( | ||||||
|       window.location.href.includes("/playlist/") || |         globalThis.location.href.includes("/playlist/") || | ||||||
|       window.location.href.includes("/mix/") |         globalThis.location.href.includes("/mix/") | ||||||
|       ) { |       ) { | ||||||
|       if (currentPlayStatus === MediaStatus.playing) { |         if (this.currentlyPlaying === 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); | ||||||
| @@ -137,12 +138,15 @@ 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 = elements.getText("queue_album"); |       const queueAlbumName = this.getText("queue_album"); | ||||||
|       if (queueAlbumName) { |       if (queueAlbumName) { | ||||||
|         return queueAlbumName; |         return queueAlbumName; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       return ""; |       return ""; | ||||||
|  |     } catch { | ||||||
|  |       return ""; | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   isMuted: function () { |   isMuted: function () { | ||||||
| @@ -483,6 +487,7 @@ 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,8 +103,7 @@ 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 date = new Date(); |       const now = Math.trunc((Date.now() + 500) / 1000); | ||||||
|       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; | ||||||
|     } |     } | ||||||
| @@ -118,17 +117,15 @@ 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( |       Logger.log(`Failed to connect to Discord, retrying in ${RETRY_DELAY/1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})`); | ||||||
|         `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'); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| @@ -137,7 +134,7 @@ const connectWithRetry = async (retryCount = 0) => { | |||||||
|  * Set up the discord rpc and listen on globalEvents.updateInfo |  * Set up the discord rpc and listen on globalEvents.updateInfo | ||||||
|  */ |  */ | ||||||
| export const initRPC = () => { | export const initRPC = () => { | ||||||
|   rpc = new Client({ transport: { type: "ipc" }, clientId }); |   rpc = new Client({ transport: {type: "ipc"}, clientId }); | ||||||
|   connectWithRetry(); |   connectWithRetry(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user