diff --git a/.github/workflows/build-artifacts.yml b/.github/workflows/build-artifacts.yml index 917c056..eaad276 100644 --- a/.github/workflows/build-artifacts.yml +++ b/.github/workflows/build-artifacts.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: install_deps run: make install_deps diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0a0cff1..441602f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: install_deps run: make install_deps diff --git a/.gitignore b/.gitignore index 0eb3fb8..f78a66d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ -node_modules -flatpak -source -app +source/ +node_modules/ +flatpak/ +app/ +artifacts/ +.vscode/ package-lock.json yarn.lock -artifacts -package.json -.vscode/launch.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..689c248 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "semi": true, + "singleQuote": false, + "trailingComma": "es5", + "tabWidth": 2, + "useTabs": false, + "arrowParens": "always" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0fec26..51ab15e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ By participating in this project, you agree to maintain a respectful and inclusi Ensure you have all required dependencies: -- Node.js (20 recommended) +- Node.js (22 recommended) - npm - 7z - make @@ -63,12 +63,21 @@ Edit the files you want to change in the `app` directory. > [!TIP] > You do not need to generate a patch file to test your changes. Open the `app` folder after running `make patch-new` and make your changes. Then run `make build_{target}_{arch}` to try your changes. -When you are done, commit your changes, and then generate the patch: +When you are done, make sure that the only files you modified are the ones you want to include in the patch. You can check this by running: + +```sh +git status +``` + +Then, generate the patch: ```sh make patch-gen ``` +> [!NOTE] +> This command will take care of pretty printing your patch and creating a patch file. + The patch will be saved in the `patches` directory. Make sure to rename the patch file to something meaningful and follow the naming convention. Add the patch to the echoed list in the `Makefile`. > [!TIP] diff --git a/Makefile b/Makefile index b871f65..422a04c 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,7 @@ PACKAGE_MANAGER_INSTALL_CMD ?= install PACKAGE_MANAGER_ADD_CMD ?= install install_build_deps: - @$(PACKAGE_MANAGER) $(PACKAGE_MANAGER_ADD_CMD) @electron/asar@3.2.18 --engine-strict - @$(PACKAGE_MANAGER) $(PACKAGE_MANAGER_ADD_CMD) prettier@2.8.8 + @$(PACKAGE_MANAGER) $(PACKAGE_MANAGER_INSTALL_CMD) prepare: clean install_build_deps @mkdir -p $(SOURCE_DIR) @@ -32,11 +31,11 @@ prepare: clean install_build_deps @cd $(SOURCE_DIR) && 7z x -y -bsp0 -bso0 app-32.7z @echo "Extract app sources from the app" - @node_modules/@electron/asar/bin/asar.js extract $(SOURCE_DIR)/resources/app.asar $(APP_DIR) + @npm run asar extract "$(SOURCE_DIR)/resources/app.asar" "$(APP_DIR)" @echo "Prettier the sources to patch successfully" - @node_modules/prettier/bin-prettier.js --write "$(APP_DIR)/build/*.js" - @node_modules/prettier/bin-prettier.js --write "$(APP_DIR)/build/*.html" + @cp .prettierrc.json $(APP_DIR)/ + @npm run prettier -- --write "$(APP_DIR)/build/*.{js,html}" --config .prettierrc.json --ignore-path /dev/null @echo "Apply patches from ./patches:" @echo "01 - Hide to tray when closing (https://github.com/SibrenVasse/deezer/issues/4)" @@ -45,12 +44,11 @@ prepare: clean install_build_deps @echo "04 - Disable auto updater (https://github.com/aunetx/deezer-linux/pull/95)" @echo "05 - Remove OS information (https://github.com/aunetx/deezer-linux/pull/95)" @echo "06 - Add a better management of MPRIS (https://github.com/aunetx/deezer-linux/pull/61)" - @echo "07 - Add Discord Rich Presence (https://github.com/aunetx/deezer-linux/pull/82)" - @echo "08 - Add option to disable Discord Rich Presence (https://github.com/aunetx/deezer-linux/pull/95)" - @echo "09 - Add environment variable to change log level (https://github.com/aunetx/deezer-linux/pull/95)" - @echo "10 - Add track duration and url, various fixes (https://github.com/aunetx/deezer-linux/pull/95)" - @echo "11 - Improve responsiveness on small devices (https://github.com/aunetx/deezer-linux/pull/107)" - $(foreach p, $(wildcard ./patches/*), patch -p 1 -d $(APP_DIR) < $(p);) + @echo "07 - Add environment variable to change log level (https://github.com/aunetx/deezer-linux/pull/95)" + @echo "08 - Provide additional metadata (https://github.com/aunetx/deezer-linux/pull/95)" + @echo "09 - Add Discord Rich Presence (https://github.com/aunetx/deezer-linux/pull/82)" + @echo "10 - Improve responsiveness on small devices (https://github.com/aunetx/deezer-linux/pull/107)" + @$(foreach p, $(wildcard ./patches/*), patch -p 1 -d $(APP_DIR) < $(p);) @echo "Append `package-append.json` to the `package.json` of the app" @echo "Adds electron, elecron-builder dependencies, prod and build directives" @@ -118,6 +116,9 @@ patch-new: install_deps @echo "Don't forget to rename your patch." patch-gen: + @npm run prettier -- --write "$(APP_DIR)/build/*.{js,html}" --config .prettierrc.json --ignore-path /dev/null + @cd $(APP_DIR) && git add . + @cd $(APP_DIR) && git commit @cd $(APP_DIR) && git format-patch -1 HEAD --stdout > ../patches/$(shell date +%y%m%d-%s).patch #! UTILS @@ -138,4 +139,4 @@ release: prepare-release clean: - @rm -rf ./$(APP_DIR) flatpak node_modules ./$(SOURCE_DIR) artifacts package.json + @rm -rf ./$(APP_DIR) flatpak node_modules ./$(SOURCE_DIR) artifacts package-lock.json yarn.lock diff --git a/README.md b/README.md index 6b9da55..f203c20 100644 --- a/README.md +++ b/README.md @@ -36,16 +36,17 @@ Other packages can be installed from you package manager, either by clicking on ## Usage -| Option | Description | -| ----------------------- | ----------------------------------------------------------------------------------------------- | -| `--start-in-tray` | Start the app in the tray (see [patch](./patches/01-start-hidden-in-tray.patch)) | -| `--disable-systray` | Quit the app when the window is closed (see [patch](./patches/03-quit.patch)) | -| `--disable-features` | Disable some features (see [patch](./patches/06-better-management-of-MPRIS.patch)) | -| `--enable-discord-rpc` | Enable Discord RPC integration (see [patch](./patches/08-discord-rich-presence-disable.patch)) | +| Option | Description | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `--start-in-tray` | Start the app in the tray (see [patch](./patches/01-start-hidden-in-tray.patch)) | +| `--disable-systray` | Quit the app when the window is closed (see [patch](./patches/03-quit.patch)) | +| `--keep-kernel` | Use the exact kernel version (see [patch](./patches/05-remove-os-information.patch))
_This feature impacts privacy._ | +| `--disable-features` | Disable some features (see [patch](./patches/06-better-management-of-MPRIS.patch)) | +| `--enable-discord-rpc` | Enable Discord RPC integration (see [patch](./patches/09-discord-rich-presence.patch)) | | Environment variable | Options | Description | | -------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------- | -| `LOG_LEVEL` | `silly`,`debug`,`verbose`,`info`,`warning`,`error` | Set the log level (see [patch](./patches/09-log-level-environment-variable.patch)) | +| `LOG_LEVEL` | `silly`,`debug`,`verbose`,`info`,`warning`,`error` | Set the log level (see [patch](./patches/07-log-level-environment-variable.patch)) | | `DZ_DEVTOOLS` | `yes`,`no` | Enable the developer console (ctrl+shift+i) | ## Building from source @@ -145,7 +146,7 @@ Deezer can be used on Linux through the web interface, but it does not allow dow Please see [this issue](https://github.com/babluboy/bookworm/issues/178) or [this issue](https://github.com/babluboy/nutty/issues/68). Prefer using Flatpak or AppImage. -### Why are the patches published but not the app's source code? patches? +### Why are the patches published but not the app's source code? patches? The source code of the Deezer app is not open-source. Reverse-engineering the app would be illegal and would violate the Deezer EULA. This project is a port of the official Windows app, and does not contain any reverse-engineered code, rather it bundles the official Windows app with a compatibility layer. diff --git a/dev.aunetx.deezer.desktop b/dev.aunetx.deezer.desktop index aca6700..0ea9bd5 100644 --- a/dev.aunetx.deezer.desktop +++ b/dev.aunetx.deezer.desktop @@ -4,12 +4,11 @@ Name=Deezer GenericName=Online music streaming service Comment=Listen and download all your favorite music StartupNotify=true -Icon=dev.aunetx.deezer -TryExec=run.sh -Exec=run.sh %U +Icon=dev.aunetx.deezer.svg Terminal=false MimeType=x-scheme-handler/deezer; Categories=Audio;Music;Player;AudioVideo; Keywords=Music;Player;Streaming;Online; StartupWMClass=Deezer +SingleMainWindow=true X-GNOME-UsesNotifications=true \ No newline at end of file diff --git a/package-append.json b/package-append.json index a083776..caff523 100644 --- a/package-append.json +++ b/package-append.json @@ -17,8 +17,8 @@ "build-appimage-arm64": "electron-builder --arm64 --linux AppImage" }, "devDependencies": { - "electron": "^33.2.0", - "electron-builder": "^23.0.3" + "electron": "^35.0.0", + "electron-builder": "^26.0.0" }, "build": { "files": ["**"], @@ -41,15 +41,22 @@ "linux": { "maintainer": "aunetx ", "icon": "../icons", - "category": "Utility;AudioVideo;Audio;Player;Music;", + "category": "AudioVideo;Audio;Player;Music;", "desktop": { - "Name": "Deezer", - "Type": "Application", - "GenericName": "Online music streaming service", - "Comment": "Listen and download all your favorite music", - "MimeType": "x-scheme-handler/deezer;", - "Keywords": "Music;Player;Streaming;Online;", - "StartupWMClass": "Deezer" + "entry": { + "Type": "Application", + "Name": "Deezer", + "GenericName": "Online music streaming service", + "Comment": "Listen and download all your favorite music", + "StartupNotify": "true", + "Terminal": "false", + "MimeType": "x-scheme-handler/deezer;", + "Categories": "Audio;Music;Player;AudioVideo;", + "Keywords": "Music;Player;Streaming;Online;", + "StartupWMClass": "Deezer", + "SingleMainWindow": "true", + "X-GNOME-UsesNotifications": "true" + } }, "artifactName": "${productName}-${version}-${arch}.${ext}" }, diff --git a/package.json b/package.json new file mode 100644 index 0000000..117cc4d --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "@electron/asar": "3.4.1", + "prettier": "3.5.3" + }, + "scripts": { + "asar": "asar", + "prettier": "prettier" + } +} diff --git a/patches/01-start-hidden-in-tray.patch b/patches/01-start-hidden-in-tray.patch index 00a8956..5cd66aa 100644 --- a/patches/01-start-hidden-in-tray.patch +++ b/patches/01-start-hidden-in-tray.patch @@ -1,6 +1,6 @@ -From 9c19490f706350a2ca8cceae7a998916d21de89b Mon Sep 17 00:00:00 2001 +From 7e317aa696aa2c1a69f2df0e4d7bb3b3df41d4df Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Sun, 19 Jan 2025 22:59:38 +0100 +Date: Mon, 21 Apr 2025 00:37:21 +0900 Subject: [PATCH] fix: reduce to systray on close Original patch: Dorian Stoll @@ -8,14 +8,14 @@ This stops the excessive logging, since parts of the app will not run in develop mode anymore. It also stops the app from logging the urls for the mp3 files, which is against the Deezer TOS. --- - build/main.js | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) + build/main.js | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build/main.js b/build/main.js -index c15e2c3..b883a28 100644 +index 7349ee9..9284b6b 100644 --- a/build/main.js +++ b/build/main.js -@@ -3085,10 +3085,13 @@ +@@ -3097,24 +3097,24 @@ finalMinSize[1] ); } @@ -23,16 +23,35 @@ index c15e2c3..b883a28 100644 - ? this.window.showInactive() - : this.window.show(), - this.thumbar.init(); -+ if (!process.argv.some(arg => arg === '--start-in-tray')) ++ if (!process.argv.some((arg) => arg === "--start-in-tray")) + isDev(external_electron_namespaceObject.app) + ? this.window.showInactive() + : this.window.show(), + this.thumbar.init(); -+ else -+ this.window.hide(); ++ else this.window.hide(); }), this.appService.enableDevMode(); } + _adjustViewToContentSize() { + if (!this.isFrameless) return; + const currentSize = this.window.getContentSize(); +- this.appService +- .getViewContainer() +- .setBounds({ +- x: 0, +- y: 32, +- width: currentSize[0], +- height: currentSize[1] - 32, +- }); ++ this.appService.getViewContainer().setBounds({ ++ x: 0, ++ y: 32, ++ width: currentSize[0], ++ height: currentSize[1] - 32, ++ }); + } + loadWindow() { + const report = () => { -- 2.43.0 diff --git a/patches/02-avoid-change-default-texthtml-mime-type.patch b/patches/02-avoid-change-default-texthtml-mime-type.patch index 6d826c6..f3cfeb4 100644 --- a/patches/02-avoid-change-default-texthtml-mime-type.patch +++ b/patches/02-avoid-change-default-texthtml-mime-type.patch @@ -1,6 +1,6 @@ -From e45c184e8c23aa72f77767c09e6051363806b5f5 Mon Sep 17 00:00:00 2001 +From 3255d0db5760601c9a16fb4b175085cc40b27df2 Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Sun, 19 Jan 2025 23:18:25 +0100 +Date: Mon, 21 Apr 2025 00:47:43 +0900 Subject: [PATCH] fix: unset text/html as default mimetype --- @@ -8,10 +8,10 @@ Subject: [PATCH] fix: unset text/html as default mimetype 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/build/main.js b/build/main.js -index b883a28..60117e3 100644 +index 9284b6b..9623b50 100644 --- a/build/main.js +++ b/build/main.js -@@ -2854,12 +2854,7 @@ +@@ -2851,12 +2851,7 @@ this.tray.init(), this.updater.init(), this.network.watch(), diff --git a/patches/03-quit.patch b/patches/03-quit.patch index 742f828..5474684 100644 --- a/patches/03-quit.patch +++ b/patches/03-quit.patch @@ -1,6 +1,6 @@ -From ef715c38d754bbed026a4e6c3e9cae0180eeeb4b Mon Sep 17 00:00:00 2001 +From 4dbe17674fef2f48b638cd4dc164b66042d03213 Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Sun, 19 Jan 2025 23:27:32 +0100 +Date: Mon, 21 Apr 2025 00:50:26 +0900 Subject: [PATCH] fix: reduce to systray on close with respect to execution option @@ -9,17 +9,17 @@ Subject: [PATCH] fix: reduce to systray on close with respect to execution 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/main.js b/build/main.js -index 60117e3..9ea7c18 100644 +index 9623b50..c904158 100644 --- a/build/main.js +++ b/build/main.js -@@ -3037,7 +3037,10 @@ +@@ -3049,7 +3049,10 @@ this._adjustViewToContentSize(), mainView.setAutoResize({ width: !0, height: !0 }); } else this.appService.setWindow(this.window, void 0); - if ((this.appService.setUserAgent(), isPlatform(PLATFORM.DARWIN))) { + if ( -+ (this.appService.setUserAgent(), isPlatform(PLATFORM.LINUX)) -+ && !process.argv.some(arg => arg === '--disable-systray') ++ (this.appService.setUserAgent(), isPlatform(PLATFORM.LINUX)) && ++ !process.argv.some((arg) => arg === "--disable-systray") + ) { let isQuitting = !1; external_electron_namespaceObject.app.on( diff --git a/patches/04-disable-auto-updater.patch b/patches/04-disable-auto-updater.patch index a0b1dbb..1ceef0f 100644 --- a/patches/04-disable-auto-updater.patch +++ b/patches/04-disable-auto-updater.patch @@ -1,25 +1,24 @@ -From 864e07d4bac769cbc077a4a3d50a431f2158080c Mon Sep 17 00:00:00 2001 +From 7a0b04d742ca93adcf73c0d520e877f0c4bef6d4 Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Mon, 20 Jan 2025 00:46:23 +0100 +Date: Mon, 21 Apr 2025 00:54:17 +0900 Subject: [PATCH] fix: disable autoupdater for linux --- - build/main.js | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) + build/main.js | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/main.js b/build/main.js -index 9ea7c18..10a80fa 100644 +index c904158..a667632 100644 --- a/build/main.js +++ b/build/main.js -@@ -2322,9 +2322,8 @@ - } +@@ -2320,8 +2320,8 @@ } init() { -- this.arch && + this.arch && - ((isPlatform(PLATFORM.LINUX) && !process.env.APPIMAGE) || - isWindowsStore() || -+ this.arch && !isPlatform(PLATFORM.LINUX) && ( -+ isWindowsStore() || ++ !isPlatform(PLATFORM.LINUX) && ++ (isWindowsStore() || "yes" === process.env.DZ_DISABLE_UPDATE || ((external_electron_updater_namespaceObject.autoUpdater.autoDownload = !0), diff --git a/patches/05-remove-os-information.patch b/patches/05-remove-os-information.patch index 2884c40..3e12852 100644 --- a/patches/05-remove-os-information.patch +++ b/patches/05-remove-os-information.patch @@ -1,7 +1,8 @@ -From 08ea86075592efe9c02c4beb7cbdfc6935ca0b1c Mon Sep 17 00:00:00 2001 +From 9250fb3bf514256f68ad844b53e7345b2efc4b37 Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Fri, 24 Jan 2025 16:03:43 +0100 -Subject: [PATCH] fix: ensure os release is valid +Date: Mon, 21 Apr 2025 01:08:23 +0900 +Subject: [PATCH] fix: ensure os release is valid; add cli argument to use + exact kernel version Original patch: Dorian Stoll The application sends the kernel version as part of the User-Agent. @@ -14,17 +15,17 @@ e.g: 5.11.0-16-generic works, while 5.15.14-200.fc35.x86_64 doesn't. The solution is to ignore the actual version and send bogus data that is known to work. --- - build/main.js | 11 ++++++++++- - build/preload.js | 10 +++++++++- - build/renderer.js | 10 +++++++++- - build/titlebar.js | 11 ++++++++++- - 4 files changed, 38 insertions(+), 4 deletions(-) + build/main.js | 12 +++++++++++- + build/preload.js | 12 +++++++++++- + build/renderer.js | 12 +++++++++++- + build/titlebar.js | 12 +++++++++++- + 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/build/main.js b/build/main.js -index 10a80fa..9219f4f 100644 +index a667632..e03556c 100644 --- a/build/main.js +++ b/build/main.js -@@ -5,7 +5,16 @@ +@@ -5,7 +5,17 @@ module.exports = require("macos-version"); }, 857: (module) => { @@ -32,21 +33,22 @@ index 10a80fa..9219f4f 100644 + var __module_os = require("os"); + const release = __module_os.release(); + __module_os.release = () => { -+ const matcher = /(\d+\.\d+\.\d+)\.*/ ++ if (!process.argv.some((arg) => arg === "--keep-kernel")) ++ return "6.1.0"; ++ ++ const matcher = /(\d+\.\d+\.\d+)\.*/; + var result = release.match(matcher); -+ //if (result[1]) -+ // return result[1]; -+ return "6.1.0"; -+ } ++ return result ? result[1] : "6.1.0"; ++ }; + module.exports = __module_os; }, }, __webpack_module_cache__ = {}; diff --git a/build/preload.js b/build/preload.js -index 9716411..ec603d0 100644 +index 4029c6d..f625122 100644 --- a/build/preload.js +++ b/build/preload.js -@@ -5,7 +5,15 @@ +@@ -5,7 +5,17 @@ module.exports = require("macos-version"); }, 857: (module) => { @@ -54,20 +56,22 @@ index 9716411..ec603d0 100644 + var __module_os = require("os"); + const release = __module_os.release(); + __module_os.release = () => { ++ if (!process.argv.some((arg) => arg === "--keep-kernel")) ++ return "6.1.0"; ++ + const matcher = /(\d+\.\d+\.\d+)\.*/; + var result = release.match(matcher); -+ //if (result[1]) return result[1]; -+ return "6.1.0"; ++ return result ? result[1] : "6.1.0"; + }; + module.exports = __module_os; }, }, __webpack_module_cache__ = {}; diff --git a/build/renderer.js b/build/renderer.js -index 7241bcb..fb02453 100644 +index ca6c307..24b119f 100644 --- a/build/renderer.js +++ b/build/renderer.js -@@ -5,7 +5,15 @@ +@@ -5,7 +5,17 @@ module.exports = require("macos-version"); }, 857: (module) => { @@ -75,20 +79,22 @@ index 7241bcb..fb02453 100644 + var __module_os = require("os"); + const release = __module_os.release(); + __module_os.release = () => { ++ if (!process.argv.some((arg) => arg === "--keep-kernel")) ++ return "6.1.0"; ++ + const matcher = /(\d+\.\d+\.\d+)\.*/; + var result = release.match(matcher); -+ //if (result[1]) return result[1]; -+ return "6.1.0"; ++ return result ? result[1] : "6.1.0"; + }; + module.exports = __module_os; }, }, __webpack_module_cache__ = {}; diff --git a/build/titlebar.js b/build/titlebar.js -index 65520fb..7919288 100644 +index 5414c90..4f3c6a3 100644 --- a/build/titlebar.js +++ b/build/titlebar.js -@@ -5,7 +5,16 @@ +@@ -5,7 +5,17 @@ module.exports = require("macos-version"); }, 857: (module) => { @@ -96,12 +102,13 @@ index 65520fb..7919288 100644 + var __module_os = require("os"); + const release = __module_os.release(); + __module_os.release = () => { -+ const matcher = /(\d+\.\d+\.\d+)\.*/ ++ if (!process.argv.some((arg) => arg === "--keep-kernel")) ++ return "6.1.0"; ++ ++ const matcher = /(\d+\.\d+\.\d+)\.*/; + var result = release.match(matcher); -+ //if (result[1]) -+ // return result[1]; -+ return "6.1.0"; -+ } ++ return result ? result[1] : "6.1.0"; ++ }; + module.exports = __module_os; }, }, diff --git a/patches/06-better-management-of-MPRIS.patch b/patches/06-better-management-of-MPRIS.patch index 4671cb8..c75a6f1 100644 --- a/patches/06-better-management-of-MPRIS.patch +++ b/patches/06-better-management-of-MPRIS.patch @@ -1,18 +1,18 @@ -From 16026d3b586904af7d8ca32248abe0be9eddaa84 Mon Sep 17 00:00:00 2001 +From a808839d950d6f4ad50763d7255a7edbbd32e516 Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Fri, 31 Jan 2025 11:55:37 +0100 -Subject: [PATCH] fix: update deps for mpris patch - @jellybrick/mpris-service +Date: Mon, 21 Apr 2025 01:43:50 +0900 +Subject: [PATCH] fix: add better management of MPRIS --- - build/main.js | 72 ++++++++++++++++++++++++++++++++++++++++++--------- + build/main.js | 65 +++++++++++++++++++++++++++++++++++++++++++-------- package.json | 1 + - 2 files changed, 61 insertions(+), 12 deletions(-) + 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/build/main.js b/build/main.js -index 9219f4f..34be768 100644 +index e03556c..1878712 100644 --- a/build/main.js +++ b/build/main.js -@@ -88,6 +88,10 @@ +@@ -89,6 +89,10 @@ external_semver_default = __webpack_require__.n( external_semver_namespaceObject ); @@ -23,7 +23,7 @@ index 9219f4f..34be768 100644 function isPlatform(platform) { switch (platform) { case PLATFORM.WINDOWS: -@@ -1188,8 +1192,9 @@ +@@ -1187,8 +1191,9 @@ }; }; let MediaService = class extends external_events_namespaceObject.EventEmitter { @@ -34,65 +34,66 @@ index 9219f4f..34be768 100644 (this.smtc = null), (this.track = {}), (this.player = {}), -@@ -1197,6 +1202,11 @@ +@@ -1196,6 +1201,11 @@ (this.debounceOptions = { leading: !0, maxWait: 500 }), (this.ipc = ipc), (this.user = user), + (this.mprisPlayer = new external_electron_mpris_namespaceObject({ -+ name: 'deezer', -+ identity: 'Deezer', -+ supportedInterfaces: ['player'] ++ name: "deezer", ++ identity: "Deezer", ++ supportedInterfaces: ["player"], + })), isPlatform(PLATFORM.LINUX) && (this.user.addListener(UserEvents.LoggedIn, () => { this.start(); -@@ -1204,6 +1214,19 @@ +@@ -1203,6 +1213,21 @@ this.user.addListener(UserEvents.LoggedOut, () => { this.stop(); })); -+ this.initMprisPlayerControls(); -+ } ++ this.initMprisPlayerControls(); ++ } + initMprisPlayerControls() { + // Events => ['raise', 'quit', 'next', 'previous', 'pause', 'playpause', 'stop', 'play', 'seek', 'position', 'open', 'volume', 'loopStatus', 'shuffle']; -+ this.mprisPlayer.on('play', this.play.bind(this)); -+ this.mprisPlayer.on('pause', this.pause.bind(this)); -+ this.mprisPlayer.on('playpause', () => this.player.state === 'playing' ? this.pause() : this.play()); -+ this.mprisPlayer.on('stop', this.stop.bind(this)); -+ this.mprisPlayer.on('next', this.next.bind(this)); -+ this.mprisPlayer.on('previous', this.prev.bind(this)); -+ this.mprisPlayer.on('shuffle', this.setSuffle.bind(this)); -+ this.mprisPlayer.on('loopStatus', this.setRepeatMode.bind(this)); -+ this.mprisPlayer.on('raise', () => this.app.getWindow().show()) ++ this.mprisPlayer.on("play", this.play.bind(this)); ++ this.mprisPlayer.on("pause", this.pause.bind(this)); ++ this.mprisPlayer.on("playpause", () => ++ this.player.state === "playing" ? this.pause() : this.play() ++ ); ++ this.mprisPlayer.on("stop", this.stop.bind(this)); ++ this.mprisPlayer.on("next", this.next.bind(this)); ++ this.mprisPlayer.on("previous", this.prev.bind(this)); ++ this.mprisPlayer.on("shuffle", this.setSuffle.bind(this)); ++ this.mprisPlayer.on("loopStatus", this.setRepeatMode.bind(this)); ++ this.mprisPlayer.on("raise", () => this.app.getWindow().show()); } play() { this.ipc.send("channel-player-media-control", MediaPlayerControl.Play); -@@ -1231,11 +1254,23 @@ +@@ -1230,11 +1255,22 @@ } setTrackInfo(track) { (this.track = Object.assign(this.track, track)), - this.emit(MediaEvents.TrackUpdated, this.track); + this.emit(MediaEvents.TrackUpdated, this.track), + (this.mprisPlayer.metadata = { -+ 'mpris:trackid': this.mprisPlayer.objectPath('track/0'), -+ 'mpris:artUrl': track.coverUrl, -+ 'xesam:title': track.title, -+ 'xesam:album': track.album, -+ 'xesam:artist': [track.artist] ++ "mpris:trackid": this.mprisPlayer.objectPath("track/0"), ++ "mpris:artUrl": track.coverUrl, ++ "xesam:title": track.title, ++ "xesam:album": track.album, ++ "xesam:artist": [track.artist], + }); } setPlayerInfo(player) { (this.player = Object.assign(this.player, player)), - this.emit(MediaEvents.PlayerUpdated, this.player); + this.emit(MediaEvents.PlayerUpdated, this.player), -+ (this.mprisPlayer.playbackStatus = -+ this.player.state === 'playing' -+ ? external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PLAYING -+ : external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PAUSED -+ ); ++ (this.mprisPlayer.playbackStatus = ++ this.player.state === "playing" ++ ? external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PLAYING ++ : external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PAUSED); } getTrackInfo() { return this.track; -@@ -1295,7 +1330,11 @@ +@@ -1294,7 +1330,11 @@ 1, (0, external_inversify_namespaceObject.inject)(SERVICE_USER) ), @@ -105,7 +106,7 @@ index 9219f4f..34be768 100644 ], MediaService ); -@@ -2733,14 +2772,20 @@ +@@ -2732,15 +2772,16 @@ const PlayerIpc_ipc = main_di.get(SERVICE_IPC), media = main_di.get(SERVICE_MEDIA), powerSave = main_di.get(SERVICE_POWER_SAVE); @@ -113,39 +114,34 @@ index 9219f4f..34be768 100644 - "channel-player-state-update", - external_lodash_debounce_default()((event, state) => { - media.setPlayerInfo({ state }), -- state === MediaPlayerState.Playing -- ? powerSave.start() -- : powerSave.stop(); ++ var powerSaveTimeoutId; ++ PlayerIpc_ipc.on("channel-player-state-update", (event, state) => { ++ media.setPlayerInfo({ state }), ++ clearTimeout(powerSaveTimeoutId), ++ (powerSaveTimeoutId = setTimeout(() => { + state === MediaPlayerState.Playing + ? powerSave.start() + : powerSave.stop(); - }, 3e3) -+ var powerSaveTimeoutId; -+ PlayerIpc_ipc.on( -+ "channel-player-state-update", -+ (event, state) => { -+ media.setPlayerInfo({ state }), -+ clearTimeout(powerSaveTimeoutId), -+ powerSaveTimeoutId = setTimeout( -+ () => { -+ state === MediaPlayerState.Playing -+ ? powerSave.start() -+ : powerSave.stop(); -+ }, 3e3 -+ ); -+ } - ), +- ), ++ }, 3e3)); ++ }), PlayerIpc_ipc.on( "channel-player-track-update", -@@ -2828,6 +2873,9 @@ + (event, track, player) => { +@@ -2827,6 +2868,10 @@ "autoplay-policy", "no-user-gesture-required" ), + external_electron_namespaceObject.app.commandLine.appendSwitch( -+ "disable-features", "HardwareMediaKeyHandling" ++ "disable-features", ++ "HardwareMediaKeyHandling" + ), external_electron_namespaceObject.app.on( "second-instance", (event, argv) => { diff --git a/package.json b/package.json -index 290f49a..394b4f4 100644 +index cec017c..2182f77 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ @@ -155,7 +151,7 @@ index 290f49a..394b4f4 100644 + "@jellybrick/mpris-service": "2.1.5", "electron-log": "^5.1.2", "electron-settings": "4.0.4", - "electron-updater": "^6.1.8", + "electron-updater": "^6.3.9", -- 2.43.0 diff --git a/patches/07-discord-rich-presence.patch b/patches/07-discord-rich-presence.patch deleted file mode 100644 index 267f54c..0000000 --- a/patches/07-discord-rich-presence.patch +++ /dev/null @@ -1,97 +0,0 @@ -From dac6e3d0e3ca49ef6f123a6f6595cd37578913be Mon Sep 17 00:00:00 2001 -From: josselinonduty -Date: Fri, 31 Jan 2025 16:43:09 +0100 -Subject: [PATCH] feat(patch): add discord rich presence support - ---- - build/main.js | 33 +++++++++++++++++++++++++++++++-- - package.json | 1 + - 2 files changed, 32 insertions(+), 2 deletions(-) - -diff --git a/build/main.js b/build/main.js -index 34be768..69ce1f1 100644 ---- a/build/main.js -+++ b/build/main.js -@@ -92,6 +92,11 @@ - var external_electron_mpris_default = __webpack_require__.n( - external_electron_mpris_namespaceObject - ); -+ const external_rich_presence_builder_namespaceObject = require("rich-presence-builder"); -+ var external_rich_presence_builder_default = __webpack_require__.n( -+ external_rich_presence_builder_namespaceObject -+ ); -+ var rpcConnection; - function isPlatform(platform) { - switch (platform) { - case PLATFORM.WINDOWS: -@@ -1215,6 +1220,7 @@ - this.stop(); - })); - this.initMprisPlayerControls(); -+ this.initDiscordRichPresence(); - } - initMprisPlayerControls() { - // Events => ['raise', 'quit', 'next', 'previous', 'pause', 'playpause', 'stop', 'play', 'seek', 'position', 'open', 'volume', 'loopStatus', 'shuffle']; -@@ -1228,6 +1234,27 @@ - this.mprisPlayer.on('loopStatus', this.setRepeatMode.bind(this)); - this.mprisPlayer.on('raise', () => this.app.getWindow().show()) - } -+ initDiscordRichPresence() { -+ rpcConnection = new external_rich_presence_builder_namespaceObject({ -+ clientID: "1244016234203185183", -+ }); -+ }; -+ updateDiscordRichPresence(track) { -+ if (!rpcConnection) return; -+ rpcConnection.setSmallImage( -+ this.player.state === "playing" ? "play" : "pause", -+ this.player.state === "playing" ? "Playing" : "Paused" -+ ); -+ if (track) { -+ rpcConnection.setLargeImage(track.coverUrl); -+ rpcConnection.setDescription(track.title); -+ if (track.title === track.album) -+ rpcConnection.setState(`${track.artist}`); -+ else -+ rpcConnection.setState(`${track.artist} - ${track.album}`); -+ } -+ rpcConnection.go().catch(); -+ } - play() { - this.ipc.send("channel-player-media-control", MediaPlayerControl.Play); - } -@@ -1261,7 +1288,8 @@ - 'xesam:title': track.title, - 'xesam:album': track.album, - 'xesam:artist': [track.artist] -- }); -+ }), -+ this.updateDiscordRichPresence(track); - } - setPlayerInfo(player) { - (this.player = Object.assign(this.player, player)), -@@ -1270,7 +1298,8 @@ - this.player.state === 'playing' - ? external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PLAYING - : external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PAUSED -- ); -+ ), -+ this.updateDiscordRichPresence(); - } - getTrackInfo() { - return this.track; -diff --git a/package.json b/package.json -index 394b4f4..1d48b24 100644 ---- a/package.json -+++ b/package.json -@@ -14,6 +14,7 @@ - "dependencies": { - "@electron/remote": "2.1.2", - "@jellybrick/mpris-service": "2.1.5", -+ "rich-presence-builder": "0.1.1", - "electron-log": "^5.1.2", - "electron-settings": "4.0.4", - "electron-updater": "^6.1.8", --- -2.43.0 - diff --git a/patches/07-log-level-environment-variable.patch b/patches/07-log-level-environment-variable.patch new file mode 100644 index 0000000..fda53f3 --- /dev/null +++ b/patches/07-log-level-environment-variable.patch @@ -0,0 +1,42 @@ +From 5cc1a232e85c96163cba700321df9079ea4e4379 Mon Sep 17 00:00:00 2001 +From: josselinonduty +Date: Wed, 14 May 2025 14:55:20 +0900 +Subject: [PATCH] fix: set default log level to "warn" to respect Deezer TOS; + control log level from environment variable + +Original patch: Dorian Stoll +This stops the excessive logging, since parts of the app will not run in development +mode anymore. It also stops the app from logging the urls for the mp3 files, which is +against the Deezer TOS. +--- + build/main.js | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/build/main.js b/build/main.js +index eabc5e1..485b953 100644 +--- a/build/main.js ++++ b/build/main.js +@@ -3305,12 +3305,14 @@ + processType: isProcessMain() ? "main" : process.type, + }), + (external_electron_log_default().transports.console.format = `{h}:{i}:{s}.{ms} ({processType}/{level}) ${isPlatform(PLATFORM.WINDOWS) ? ">" : "›"} {text}`), +- (external_electron_log_default().transports.console.level = isDev +- ? "silly" +- : "warn"), +- (external_electron_log_default().transports.file.level = isDev +- ? "silly" +- : "warn"), ++ (external_electron_log_default().transports.console.level = ++ isDev({ isPackaged: true }) || process.env.LOG_LEVEL ++ ? process.env.LOG_LEVEL ++ : "warn"), ++ (external_electron_log_default().transports.file.level = ++ isDev({ isPackaged: true }) || !process.env.LOG_LEVEL ++ ? process.env.LOG_LEVEL ++ : "warn"), + (external_electron_log_default().transports.sentry = function (msg) { + "error" === msg.level && + (msg.data[0] instanceof Error +-- +2.43.0 + diff --git a/patches/08-additional-metadata.patch b/patches/08-additional-metadata.patch new file mode 100644 index 0000000..f758dad --- /dev/null +++ b/patches/08-additional-metadata.patch @@ -0,0 +1,184 @@ +From ff697a112f235e1b973bcadb304ba21aed8dcb71 Mon Sep 17 00:00:00 2001 +From: josselinonduty +Date: Wed, 14 May 2025 15:12:49 +0900 +Subject: [PATCH] feat: provide additional information to mpris (and future + patches) + +--- + build/main.js | 42 +++++++++++++++++++++++++--------------- + build/renderer.js | 49 +++++++++++++++++++++++++++++++---------------- + 2 files changed, 60 insertions(+), 31 deletions(-) + +diff --git a/build/main.js b/build/main.js +index 485b953..2f616b1 100644 +--- a/build/main.js ++++ b/build/main.js +@@ -1253,18 +1253,24 @@ + setRepeatMode(repeatMode) { + this.ipc.send("channel-player-repeat-mode-update", repeatMode); + } +- setTrackInfo(track) { ++ setTrackInfo(track, data) { + (this.track = Object.assign(this.track, track)), + this.emit(MediaEvents.TrackUpdated, this.track), + (this.mprisPlayer.metadata = { ++ "mpris:length": data?.trackInfo?.song?.DURATION ++ ? data.trackInfo.song.DURATION * 1000 ++ : undefined, + "mpris:trackid": this.mprisPlayer.objectPath("track/0"), + "mpris:artUrl": track.coverUrl, + "xesam:title": track.title, + "xesam:album": track.album, + "xesam:artist": [track.artist], ++ "xesam:url": data?.trackInfo?.song ++ ? `https://deezer.com/track/${data.trackInfo.song.SNG_ID}` ++ : undefined, + }); + } +- setPlayerInfo(player) { ++ setPlayerInfo(player, data) { + (this.player = Object.assign(this.player, player)), + this.emit(MediaEvents.PlayerUpdated, this.player), + (this.mprisPlayer.playbackStatus = +@@ -2530,7 +2536,7 @@ + (this.ipc = ipc), + (this.app = app); + } +- setUserInfo(userInfo) { ++ setUserInfo(userInfo, data) { + const previousUserID = this.user.id; + (this.user = Object.assign(this.user, userInfo)), + previousUserID !== this.user.id && +@@ -2773,8 +2779,8 @@ + media = main_di.get(SERVICE_MEDIA), + powerSave = main_di.get(SERVICE_POWER_SAVE); + var powerSaveTimeoutId; +- PlayerIpc_ipc.on("channel-player-state-update", (event, state) => { +- media.setPlayerInfo({ state }), ++ PlayerIpc_ipc.on("channel-player-state-update", (event, state, data) => { ++ media.setPlayerInfo({ state }, data), + clearTimeout(powerSaveTimeoutId), + (powerSaveTimeoutId = setTimeout(() => { + state === MediaPlayerState.Playing +@@ -2784,16 +2790,22 @@ + }), + PlayerIpc_ipc.on( + "channel-player-track-update", +- (event, track, player) => { +- media.setPlayerInfo(player), media.setTrackInfo(track); ++ (event, track, player, data) => { ++ media.setPlayerInfo(player, data), media.setTrackInfo(track, data); + } + ), +- PlayerIpc_ipc.on("channel-player-shuffle-update", (event, player) => { +- media.setPlayerInfo(player); +- }), +- PlayerIpc_ipc.on("channel-player-repeat-mode-update", (event, player) => { +- media.setPlayerInfo(player); +- }); ++ PlayerIpc_ipc.on( ++ "channel-player-shuffle-update", ++ (event, player, data) => { ++ media.setPlayerInfo(player, data); ++ } ++ ), ++ PlayerIpc_ipc.on( ++ "channel-player-repeat-mode-update", ++ (event, player, data) => { ++ media.setPlayerInfo(player, data); ++ } ++ ); + const UpdaterIpc_ipc = main_di.get(SERVICE_IPC), + autoUpdater = main_di.get(SERVICE_UPDATER); + UpdaterIpc_ipc.on("channel-updater-install", () => { +@@ -2801,8 +2813,8 @@ + }); + const UserIpc_ipc = main_di.get(SERVICE_IPC), + user = main_di.get(SERVICE_USER); +- UserIpc_ipc.on("channel-user-store-updated", (event, userData) => { +- user.setUserInfo(userData); ++ UserIpc_ipc.on("channel-user-store-updated", (event, userData, data) => { ++ user.setUserInfo(userData, data); + }); + var application_awaiter = function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { +diff --git a/build/renderer.js b/build/renderer.js +index 212c12d..1f7b1b7 100644 +--- a/build/renderer.js ++++ b/build/renderer.js +@@ -349,23 +349,31 @@ + isFamily = + multiAccount && + (multiAccount.ENABLED || multiAccount.CHILD_COUNT > 0); +- renderer_ipc.send("channel-user-store-updated", { +- id: userMetadata.USER_ID, +- isFamily, +- isEmployee: userMetadata.SETTING.global.is_employee, +- offerId: user.OFFER_ID, +- country: user.COUNTRY, +- gatekeeps: user.__DZR_GATEKEEPS__, +- }); ++ renderer_ipc.send( ++ "channel-user-store-updated", ++ { ++ id: userMetadata.USER_ID, ++ isFamily, ++ isEmployee: userMetadata.SETTING.global.is_employee, ++ offerId: user.OFFER_ID, ++ country: user.COUNTRY, ++ gatekeeps: user.__DZR_GATEKEEPS__, ++ }, ++ event.data ++ ); + break; + } + case "player-repeat-changed": +- renderer_ipc.send("channel-player-repeat-mode-update", { +- repeatMode: event.data.player.repeat, +- canPrev: event.data.player.hasPrev, +- canNext: event.data.player.hasNext, +- canRepeat: event.data.player.hasRepeat, +- }); ++ renderer_ipc.send( ++ "channel-player-repeat-mode-update", ++ { ++ repeatMode: event.data.player.repeat, ++ canPrev: event.data.player.hasPrev, ++ canNext: event.data.player.hasNext, ++ canRepeat: event.data.player.hasRepeat, ++ }, ++ event.data ++ ); + break; + case "player-shuffle-changed": + renderer_ipc.send("channel-player-shuffle-update", { +@@ -380,7 +388,11 @@ + !0 === event.data.isPlaying + ? MediaPlayerState.Playing + : MediaPlayerState.Paused; +- renderer_ipc.send("channel-player-state-update", state); ++ renderer_ipc.send( ++ "channel-player-state-update", ++ state, ++ event.data ++ ); + break; + } + case "player-track-updated": { +@@ -409,7 +421,12 @@ + canRepeat: event.data.player.hasRepeat, + canShuffle: event.data.player.hasShuffle, + }; +- renderer_ipc.send("channel-player-track-update", track, player); ++ renderer_ipc.send( ++ "channel-player-track-update", ++ track, ++ player, ++ event.data ++ ); + break; + } + } +-- +2.43.0 + diff --git a/patches/08-discord-rich-presence-disable.patch b/patches/08-discord-rich-presence-disable.patch deleted file mode 100644 index a9cff86..0000000 --- a/patches/08-discord-rich-presence-disable.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0fe9042e22b8c8c05d0d3aed550d18b511e0abd5 Mon Sep 17 00:00:00 2001 -From: josselinonduty -Date: Fri, 31 Jan 2025 17:56:13 +0100 -Subject: [PATCH] feat: add cli argument to disable discord rpc - ---- - build/main.js | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/build/main.js b/build/main.js -index 69ce1f1..8b645c6 100644 ---- a/build/main.js -+++ b/build/main.js -@@ -1235,6 +1235,7 @@ - this.mprisPlayer.on('raise', () => this.app.getWindow().show()) - } - initDiscordRichPresence() { -+ if (process.argv.some(arg => arg === '--disable-discord-rpc')) return; - rpcConnection = new external_rich_presence_builder_namespaceObject({ - clientID: "1244016234203185183", - }); --- -2.43.0 - diff --git a/patches/09-discord-rich-presence.patch b/patches/09-discord-rich-presence.patch new file mode 100644 index 0000000..db8156d --- /dev/null +++ b/patches/09-discord-rich-presence.patch @@ -0,0 +1,146 @@ +From af93b7484e0eaba07cadf7dbfd075b4c604813a2 Mon Sep 17 00:00:00 2001 +From: josselinonduty +Date: Wed, 14 May 2025 16:49:24 +0900 +Subject: [PATCH] add discord rich presence support (opt-in with arg.) + +--- + build/main.js | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++- + package.json | 1 + + 2 files changed, 89 insertions(+), 1 deletion(-) + +diff --git a/build/main.js b/build/main.js +index 2f616b1..ddfc552 100644 +--- a/build/main.js ++++ b/build/main.js +@@ -93,6 +93,11 @@ + var external_electron_mpris_default = __webpack_require__.n( + external_electron_mpris_namespaceObject + ); ++ const external_rich_presence_builder_namespaceObject = require("@josselinonduty/rich-presence-builder"); ++ var external_rich_presence_builder_default = __webpack_require__.n( ++ external_rich_presence_builder_namespaceObject ++ ); ++ var rpcConnection, rpcData, rpcStartedAt, rpcPausedAt; + function isPlatform(platform) { + switch (platform) { + case PLATFORM.WINDOWS: +@@ -1229,6 +1234,86 @@ + this.mprisPlayer.on("loopStatus", this.setRepeatMode.bind(this)); + this.mprisPlayer.on("raise", () => this.app.getWindow().show()); + } ++ updateDiscordRichPresence(track, data) { ++ if (!process.argv.some((arg) => arg === "--enable-discord-rpc")) return; ++ ++ try { ++ if (track && data) { ++ const duration = data?.trackInfo?.song?.DURATION; ++ if (!duration) return; ++ ++ rpcStartedAt = Date.now(); ++ rpcPausedAt = null; ++ rpcData = { ++ type: 2, ++ smallImage: { ++ image: "play", ++ text: "Playing", ++ }, ++ largeImage: track.coverUrl, ++ description: track.title, ++ state: ++ track.title === track.album ++ ? `${track.artist}` ++ : `${track.artist} - ${track.album}`, ++ startTimestamp: rpcStartedAt, ++ button: { ++ label: "Listen on Deezer", ++ url: `https://deezer.com/track/${data.trackInfo.song.SNG_ID}`, ++ }, ++ }; ++ ++ rpcConnection = new external_rich_presence_builder_namespaceObject({ ++ clientID: "1244016234203185183", ++ }) ++ .setType(rpcData.type) ++ .setSmallImage(rpcData.smallImage.image, rpcData.smallImage.text) ++ .setLargeImage(rpcData.largeImage) ++ .setDescription(rpcData.description) ++ .setState(rpcData.state) ++ .setStartTimestamp(rpcData.startTimestamp) ++ .addButton(rpcData.button.label, rpcData.button.url); ++ rpcConnection.go().catch(); ++ } else { ++ if (!rpcConnection) return; ++ ++ if (this.player.state === "playing") { ++ if (rpcPausedAt) { ++ const elapsed = rpcPausedAt - rpcStartedAt; ++ rpcStartedAt = Date.now() - elapsed; ++ rpcData.startTimestamp = rpcStartedAt; ++ } ++ rpcPausedAt = undefined; ++ rpcData.smallImage = { ++ image: "play", ++ text: "Playing", ++ }; ++ } else { ++ rpcData.startTimestamp = undefined; ++ rpcPausedAt = Date.now(); ++ rpcData.smallImage = { ++ image: "pause", ++ text: "Paused", ++ }; ++ } ++ ++ rpcConnection = new external_rich_presence_builder_namespaceObject({ ++ clientID: "1244016234203185183", ++ }) ++ .setType(rpcData.type) ++ .setSmallImage(rpcData.smallImage.image, rpcData.smallImage.text) ++ .setLargeImage(rpcData.largeImage) ++ .setDescription(rpcData.description) ++ .setState(rpcData.state) ++ .addButton(rpcData.button.label, rpcData.button.url); ++ ++ if (rpcData.startTimestamp) ++ rpcConnection.setStartTimestamp(rpcData.startTimestamp); ++ ++ rpcConnection.go().catch(); ++ } ++ } catch (e) {} ++ } + play() { + this.ipc.send("channel-player-media-control", MediaPlayerControl.Play); + } +@@ -1269,6 +1354,7 @@ + ? `https://deezer.com/track/${data.trackInfo.song.SNG_ID}` + : undefined, + }); ++ this.updateDiscordRichPresence(track, data); + } + setPlayerInfo(player, data) { + (this.player = Object.assign(this.player, player)), +@@ -1276,7 +1362,8 @@ + (this.mprisPlayer.playbackStatus = + this.player.state === "playing" + ? external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PLAYING +- : external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PAUSED); ++ : external_electron_mpris_namespaceObject.PLAYBACK_STATUS_PAUSED), ++ this.updateDiscordRichPresence(); + } + getTrackInfo() { + return this.track; +diff --git a/package.json b/package.json +index 2182f77..0268f62 100644 +--- a/package.json ++++ b/package.json +@@ -14,6 +14,7 @@ + "dependencies": { + "@electron/remote": "2.1.2", + "@jellybrick/mpris-service": "2.1.5", ++ "@josselinonduty/rich-presence-builder": "0.1.2", + "electron-log": "^5.1.2", + "electron-settings": "4.0.4", + "electron-updater": "^6.3.9", +-- +2.43.0 + diff --git a/patches/09-log-level-environment-variable.patch b/patches/09-log-level-environment-variable.patch deleted file mode 100644 index fd30c7e..0000000 --- a/patches/09-log-level-environment-variable.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 43e2a95ada8852ffda95a9ea08bb7914d26c6d2f Mon Sep 17 00:00:00 2001 -From: josselinonduty -Date: Sat, 1 Feb 2025 19:05:39 +0100 -Subject: [PATCH] fix: set default log level to "warn" to respect Deezer TOS - -Original patch: Dorian Stoll -This stops the excessive logging, since parts of the app will not run in development -mode anymore. It also stops the app from logging the urls for the mp3 files, which is -against the Deezer TOS. ---- - build/main.js | 39 ++++++++++++++++++++++++++++++++++----- - 1 file changed, 34 insertions(+), 5 deletions(-) - -diff --git a/build/main.js b/build/main.js -index 8b645c6..686ac80 100644 ---- a/build/main.js -+++ b/build/main.js -@@ -67,6 +67,35 @@ - var external_electron_log_default = __webpack_require__.n( - external_electron_log_namespaceObject - ); -+ // function updateLogLevel() { -+ // const level = process.env.LOG_LEVEL; -+ // if (level) { -+ // if (level !== "silly") -+ // external_electron_log_default().silly = () => {}; -+ // else return; -+ -+ // if (level !== "debug") -+ // external_electron_log_default().debug = () => {}; -+ // else return; -+ -+ // if (level !== "verbose") -+ // external_electron_log_default().verbose = () => {}; -+ // else return; -+ -+ // if (level !== "info") -+ // external_electron_log_default().info = () => {}; -+ // else return; -+ -+ // if (level !== "warn") -+ // external_electron_log_default().warn = () => {}; -+ // else return; -+ -+ // if (level !== "error") -+ // external_electron_log_default().error = () => {}; -+ // else return; -+ // } -+ // } -+ // updateLogLevel(); - const external_electron_settings_namespaceObject = require("electron-settings"); - var external_electron_settings_default = __webpack_require__.n( - external_electron_settings_namespaceObject -@@ -3329,11 +3358,11 @@ - (external_electron_log_default().transports.console.format = `{h}:{i}:{s}.{ms} ({processType}/{level}) ${ - isPlatform(PLATFORM.WINDOWS) ? ">" : "›" - } {text}`), -- (external_electron_log_default().transports.console.level = isDev -- ? "silly" -+ (external_electron_log_default().transports.console.level = isDev({isPackaged: true}) || process.env.LOG_LEVEL -+ ? process.env.LOG_LEVEL - : "warn"), -- (external_electron_log_default().transports.file.level = isDev -- ? "silly" -+ (external_electron_log_default().transports.file.level = isDev({isPackaged: true}) || !process.env.LOG_LEVEL -+ ? process.env.LOG_LEVEL - : "warn"), - (external_electron_log_default().transports.sentry = function (msg) { - "error" === msg.level && --- -2.43.0 - diff --git a/patches/10-additional-metadata.patch b/patches/10-additional-metadata.patch deleted file mode 100644 index 11d4e86..0000000 --- a/patches/10-additional-metadata.patch +++ /dev/null @@ -1,288 +0,0 @@ -From 493f6f6a6433882cc2d50b4ae352cd808bf0c23e Mon Sep 17 00:00:00 2001 -From: josselinonduty -Date: Sat, 1 Feb 2025 17:34:11 +0100 -Subject: [PATCH] feat: provide duration and url information to mpris and - discord rpc; update rich-presence-builder; make discord rpc opt-in - ---- - build/main.js | 144 ++++++++++++++++++++++++++++++++++------------ - build/renderer.js | 10 ++-- - package.json | 2 +- - 3 files changed, 113 insertions(+), 43 deletions(-) - -diff --git a/build/main.js b/build/main.js -index c62943b..66c1a45 100644 ---- a/build/main.js -+++ b/build/main.js -@@ -120,11 +120,11 @@ - var external_electron_mpris_default = __webpack_require__.n( - external_electron_mpris_namespaceObject - ); -- const external_rich_presence_builder_namespaceObject = require("rich-presence-builder"); -+ const external_rich_presence_builder_namespaceObject = require("@josselinonduty/rich-presence-builder"); - var external_rich_presence_builder_default = __webpack_require__.n( - external_rich_presence_builder_namespaceObject - ); -- var rpcConnection; -+ var rpcConnection, rpcData, rpcStartedAt, rpcPausedAt; - function isPlatform(platform) { - switch (platform) { - case PLATFORM.WINDOWS: -@@ -1248,7 +1248,6 @@ - this.stop(); - })); - this.initMprisPlayerControls(); -- this.initDiscordRichPresence(); - } - initMprisPlayerControls() { - // Events => ['raise', 'quit', 'next', 'previous', 'pause', 'playpause', 'stop', 'play', 'seek', 'position', 'open', 'volume', 'loopStatus', 'shuffle']; -@@ -1262,27 +1261,92 @@ - this.mprisPlayer.on('loopStatus', this.setRepeatMode.bind(this)); - this.mprisPlayer.on('raise', () => this.app.getWindow().show()) - } -- initDiscordRichPresence() { -- if (process.argv.some(arg => arg === '--disable-discord-rpc')) return; -- rpcConnection = new external_rich_presence_builder_namespaceObject({ -- clientID: "1244016234203185183", -- }); -- }; -- updateDiscordRichPresence(track) { -- if (!rpcConnection) return; -- rpcConnection.setSmallImage( -- this.player.state === "playing" ? "play" : "pause", -- this.player.state === "playing" ? "Playing" : "Paused" -- ); -- if (track) { -- rpcConnection.setLargeImage(track.coverUrl); -- rpcConnection.setDescription(track.title); -- if (track.title === track.album) -- rpcConnection.setState(`${track.artist}`); -- else -- rpcConnection.setState(`${track.artist} - ${track.album}`); -+ updateDiscordRichPresence(track, data) { -+ if (!process.argv.some(arg => arg === '--enable-discord-rpc')) return; -+ -+ if (track && data) { -+ // Update track information -+ const duration = data?.trackInfo?.song?.DURATION; -+ if (!duration) return; -+ -+ rpcStartedAt = Date.now(); -+ rpcPausedAt = undefined; -+ rpcData = { -+ type: 2, -+ smallImage: { -+ image: "play", -+ text: "Playing" -+ }, -+ largeImage: track.coverUrl, -+ description: track.title, -+ state: track.title === track.album ? -+ `${track.artist}` -+ : `${track.artist} - ${track.album}`, -+ startTimestamp: rpcStartedAt, -+ button: { -+ label: "Listen on Deezer", -+ url: `https://deezer.com/track/${data.trackInfo.song.SNG_ID}` -+ } -+ } -+ -+ rpcConnection = new external_rich_presence_builder_namespaceObject({ -+ clientID: "1244016234203185183", -+ }) -+ .setType(rpcData.type) -+ .setSmallImage( -+ rpcData.smallImage.image, -+ rpcData.smallImage.text -+ ) -+ .setLargeImage(rpcData.largeImage) -+ .setDescription(rpcData.description) -+ .setState(rpcData.state) -+ .setStartTimestamp(rpcData.startTimestamp) -+ .addButton(rpcData.button.label, rpcData.button.url); -+ rpcConnection -+ .go().catch() -+ } else { -+ // Update playing state only -+ if (!rpcConnection) return; -+ -+ if (this.player.state === "playing") { -+ if (rpcPausedAt) { -+ const elapsed = rpcPausedAt - rpcStartedAt; -+ rpcStartedAt = Date.now() - elapsed; -+ rpcData.startTimestamp = rpcStartedAt; -+ } -+ rpcPausedAt = undefined; -+ rpcData.smallImage = { -+ image: "play", -+ text: "Playing" -+ } -+ } else { -+ rpcData.startTimestamp = undefined; -+ rpcPausedAt = Date.now(); -+ rpcData.smallImage = { -+ image: "pause", -+ text: "Paused" -+ } -+ } -+ -+ rpcConnection = new external_rich_presence_builder_namespaceObject({ -+ clientID: "1244016234203185183", -+ }) -+ .setType(rpcData.type) -+ .setSmallImage( -+ rpcData.smallImage.image, -+ rpcData.smallImage.text -+ ) -+ .setLargeImage(rpcData.largeImage) -+ .setDescription(rpcData.description) -+ .setState(rpcData.state) -+ .addButton(rpcData.button.label, rpcData.button.url); -+ -+ if (rpcData.startTimestamp) -+ rpcConnection.setStartTimestamp(rpcData.startTimestamp); -+ -+ rpcConnection -+ .go().catch() - } -- rpcConnection.go().catch(); - } - play() { - this.ipc.send("channel-player-media-control", MediaPlayerControl.Play); -@@ -1308,19 +1372,25 @@ - setRepeatMode(repeatMode) { - this.ipc.send("channel-player-repeat-mode-update", repeatMode); - } -- setTrackInfo(track) { -+ setTrackInfo(track, data) { - (this.track = Object.assign(this.track, track)), - this.emit(MediaEvents.TrackUpdated, this.track), - (this.mprisPlayer.metadata = { -+ 'mpris:length': data?.trackInfo?.song?.DURATION -+ ? data.trackInfo.song.DURATION * 1000 -+ : undefined, - 'mpris:trackid': this.mprisPlayer.objectPath('track/0'), - 'mpris:artUrl': track.coverUrl, - 'xesam:title': track.title, - 'xesam:album': track.album, -- 'xesam:artist': [track.artist] -- }), -- this.updateDiscordRichPresence(track); -+ 'xesam:artist': [track.artist], -+ 'xesam:url': data?.trackInfo?.song -+ ? `https://deezer.com/track/${data.trackInfo.song.SNG_ID}` -+ : undefined -+ }); -+ this.updateDiscordRichPresence(track, data); - } -- setPlayerInfo(player) { -+ setPlayerInfo(player, data) { - (this.player = Object.assign(this.player, player)), - this.emit(MediaEvents.PlayerUpdated, this.player), - (this.mprisPlayer.playbackStatus = -@@ -2833,8 +2903,8 @@ - var powerSaveTimeoutId; - PlayerIpc_ipc.on( - "channel-player-state-update", -- (event, state) => { -- media.setPlayerInfo({ state }), -+ (event, state, data) => { -+ media.setPlayerInfo({ state }, data), - clearTimeout(powerSaveTimeoutId), - powerSaveTimeoutId = setTimeout( - () => { -@@ -2847,15 +2917,15 @@ - ), - PlayerIpc_ipc.on( - "channel-player-track-update", -- (event, track, player) => { -- media.setPlayerInfo(player), media.setTrackInfo(track); -+ (event, track, player, data) => { -+ media.setPlayerInfo(player, data), media.setTrackInfo(track, data); - } - ), -- PlayerIpc_ipc.on("channel-player-shuffle-update", (event, player) => { -- media.setPlayerInfo(player); -+ PlayerIpc_ipc.on("channel-player-shuffle-update", (event, player, data) => { -+ media.setPlayerInfo(player, data); - }), -- PlayerIpc_ipc.on("channel-player-repeat-mode-update", (event, player) => { -- media.setPlayerInfo(player); -+ PlayerIpc_ipc.on("channel-player-repeat-mode-update", (event, player, data) => { -+ media.setPlayerInfo(player, data); - }); - const UpdaterIpc_ipc = main_di.get(SERVICE_IPC), - autoUpdater = main_di.get(SERVICE_UPDATER); -@@ -2864,7 +2934,7 @@ - }); - const UserIpc_ipc = main_di.get(SERVICE_IPC), - user = main_di.get(SERVICE_USER); -- UserIpc_ipc.on("channel-user-store-updated", (event, userData) => { -+ UserIpc_ipc.on("channel-user-store-updated", (event, userData, data) => { - user.setUserInfo(userData); - }); - var application_awaiter = function (thisArg, _arguments, P, generator) { -diff --git a/build/renderer.js b/build/renderer.js -index fb02453..4328ccd 100644 ---- a/build/renderer.js -+++ b/build/renderer.js -@@ -354,7 +354,7 @@ - offerId: user.OFFER_ID, - country: user.COUNTRY, - gatekeeps: user.__DZR_GATEKEEPS__, -- }); -+ }, event.data); - break; - } - case "player-repeat-changed": -@@ -363,7 +363,7 @@ - canPrev: event.data.player.hasPrev, - canNext: event.data.player.hasNext, - canRepeat: event.data.player.hasRepeat, -- }); -+ }, event.data); - break; - case "player-shuffle-changed": - renderer_ipc.send("channel-player-shuffle-update", { -@@ -371,14 +371,14 @@ - canPrev: event.data.player.hasPrev, - canNext: event.data.player.hasNext, - canShuffle: event.data.player.hasShuffle, -- }); -+ }, event.data); - break; - case "player-playing-changed": { - const state = - !0 === event.data.isPlaying - ? MediaPlayerState.Playing - : MediaPlayerState.Paused; -- renderer_ipc.send("channel-player-state-update", state); -+ renderer_ipc.send("channel-player-state-update", state, event.data); - break; - } - case "player-track-updated": { -@@ -414,7 +414,7 @@ - canRepeat: event.data.player.hasRepeat, - canShuffle: event.data.player.hasShuffle, - }; -- renderer_ipc.send("channel-player-track-update", track, player); -+ renderer_ipc.send("channel-player-track-update", track, player, event.data); - break; - } - } -diff --git a/package.json b/package.json -index 6c78c7d..cee7ce4 100644 ---- a/package.json -+++ b/package.json -@@ -14,7 +14,7 @@ - "dependencies": { - "@electron/remote": "2.1.2", - "@jellybrick/mpris-service": "2.1.5", -- "rich-presence-builder": "0.1.1", -+ "@josselinonduty/rich-presence-builder": "0.1.2", - "electron-log": "^5.1.2", - "electron-settings": "4.0.4", - "electron-updater": "^6.1.8", --- -2.43.0 - diff --git a/patches/11-improve-responsiveness.patch b/patches/10-improve-responsiveness.patch similarity index 86% rename from patches/11-improve-responsiveness.patch rename to patches/10-improve-responsiveness.patch index ab38e7a..0dcc8cb 100644 --- a/patches/11-improve-responsiveness.patch +++ b/patches/10-improve-responsiveness.patch @@ -1,6 +1,6 @@ -From 6cbd417ecc4fbd278e24bb202671b13c93064d95 Mon Sep 17 00:00:00 2001 +From 46f790ebaf646c5cd0e34c2aa72196e033e0646d Mon Sep 17 00:00:00 2001 From: josselinonduty -Date: Sat, 12 Apr 2025 01:08:14 +0900 +Date: Wed, 14 May 2025 17:15:31 +0900 Subject: [PATCH] feat: improve responsiveness on small devices --- @@ -9,7 +9,7 @@ Subject: [PATCH] feat: improve responsiveness on small devices 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/build/index.html b/build/index.html -index aa761a2..0e14653 100644 +index 8016bc8..82f692e 100644 --- a/build/index.html +++ b/build/index.html @@ -4,6 +4,15 @@ @@ -29,10 +29,10 @@ index aa761a2..0e14653 100644
diff --git a/build/main.js b/build/main.js -index e3f2b78..d9e3185 100644 +index ddfc552..136f0e7 100644 --- a/build/main.js +++ b/build/main.js -@@ -3206,8 +3206,8 @@ +@@ -3169,8 +3169,8 @@ }, windowOptions = { title: "Deezer Desktop",