Compare commits

..

20 Commits

Author SHA1 Message Date
ef13933c66 Merge pull request #456 from Mastermindzh/develop
Develop
2024-08-10 14:49:42 +02:00
4f72e1b35d fix: Notifications are now send at the end of the update process, allowing other events to happen sooner. 2024-08-10 14:46:08 +02:00
2c1c76d2d0 fix: all discord fields are now padded to 2+ chars 2024-08-10 14:20:13 +02:00
e2a84e119a Merge pull request #448 from autumn-puffin/master
Add option to disable the discord rpc idle text
2024-08-05 18:28:53 +02:00
5b85e59fc3 Merge pull request #450 from HurleybirdJr/master
Fix issue #449 Discord RPC stuck on "Browsing Tidal"
2024-08-05 18:28:44 +02:00
c3b772919a Merge pull request #451 from Mastermindzh/snyk-upgrade-ceb71bfecd1c7652906d5640e4d56a9b
[Snyk] Upgrade sass from 1.77.6 to 1.77.8
2024-08-02 14:27:00 +02:00
snyk-bot
70f2f5c248 fix: upgrade sass from 1.77.6 to 1.77.8
Snyk has created this PR to upgrade sass from 1.77.6 to 1.77.8.

See this package in npm:
sass

See this project in Snyk:
https://app.snyk.io/org/mastermindzh/project/dade8f03-2064-49a3-8957-edbacec3887c?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-08-02 08:17:34 +00:00
Will Hurley
ffcb563b35 Fix Discord RPC album length < 2 2024-08-01 12:10:37 +01:00
Autumn
2dd96dd48e Add option to disable the discord rpc idle text 2024-07-30 21:26:35 +10:00
65f3b251f4 Merge pull request #435 from Mastermindzh/feature/docs
feat: dependency udpate & openapi extension
2024-07-15 23:54:03 +02:00
45f8c13c5b feat: Added a channel selector so we can now use Tidal's staging environment directly from the app 2024-07-15 12:36:55 +02:00
9dc7267a4d renamed 'song' to 'media' in html 2024-07-15 09:40:08 +02:00
f5c56ae8c5 deps: bumpies 2024-07-10 14:57:00 +02:00
308b527469 Merge branch 'master' of github.com:Mastermindzh/tidal-hifi into feature/docs 2024-07-10 14:56:07 +02:00
f4aa8e070e Merge pull request #434 from Mastermindzh/snyk-upgrade-ef2733c0cae4459854fe8a974ba4cb47
[Snyk] Upgrade sass from 1.77.5 to 1.77.6
2024-07-10 08:53:12 +02:00
19c12b57de ci: change to node 22.4 2024-07-09 11:06:57 +02:00
b5713651de Merge branch 'feature/docs' of github.com:Mastermindzh/tidal-hifi into feature/docs 2024-07-09 10:51:53 +02:00
268027734c feat: dependency udpate & openapi extension 2024-07-09 10:51:40 +02:00
f711ea9000 feat: dependency udpate & openapi extension 2024-07-09 10:41:31 +02:00
snyk-bot
506f86f014 fix: upgrade sass from 1.77.5 to 1.77.6
Snyk has created this PR to upgrade sass from 1.77.5 to 1.77.6.

See this package in npm:
sass

See this project in Snyk:
https://app.snyk.io/org/mastermindzh/project/dade8f03-2064-49a3-8957-edbacec3887c?utm_source=github&utm_medium=referral&page=upgrade-pr
2024-07-09 06:24:36 +00:00
14 changed files with 812 additions and 1377 deletions

View File

@@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 20
node-version: 22.4
- run: npm install
- run: npm run build
@@ -41,6 +41,6 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 20
node-version: 22.4
- run: npm install
- run: npm run build

View File

@@ -35,7 +35,7 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 20
node-version: 22.4
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@master
@@ -49,7 +49,7 @@ jobs:
- uses: actions/checkout@master
- uses: actions/setup-node@master
with:
node-version: 20
node-version: 22.4
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@master

View File

@@ -3,7 +3,12 @@
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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
<https://github.com/Times-Z>
## [5.16.0]
- Fix issue #449 Discord RPC stuck on "Browsing Tidal".
- Fix issue #448 Add option to disable the discord rpc idle text
- Notifications are now send at the end of the update process, allowing other events to happen sooner.
## [5.15.0]
@@ -11,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated most dependency versions
- This includes Electron 31!
- Added a channel selector so we can now use Tidal's staging environment directly from the app
- implements [#437](https://github.com/Mastermindzh/tidal-hifi/issues/437)
## [5.14.1]
- Fixed `getAlbumName` not finding album name whilst on queue page

2004
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "tidal-hifi",
"version": "5.15.0",
"version": "5.16.0",
"description": "Tidal on Electron with widevine(hifi) support",
"main": "ts-dist/main.js",
"scripts": {
@@ -45,12 +45,12 @@
"axios": "^1.7.2",
"cors": "^2.8.5",
"discord-rpc": "^4.0.1",
"electron-store": "^8.0.0",
"electron-store": "^8.2.0",
"express": "^4.19.2",
"hotkeys-js": "^3.13.7",
"mpris-service": "^2.1.2",
"request": "^2.88.2",
"sass": "^1.77.6",
"sass": "^1.77.8",
"swagger-ui-express": "^5.0.1"
},
"devDependencies": {
@@ -61,12 +61,12 @@
"@types/node": "^20.14.10",
"@types/request": "^2.48.12",
"@types/swagger-ui-express": "^4.1.6",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.15.0",
"copyfiles": "^2.4.1",
"electron": "git+https://github.com/castlabs/electron-releases#v31.1.0+wvcus",
"electron-builder": "^24.13.3",
"eslint": "^8.56.0",
"electron-builder": "~24.9.4",
"eslint": "^8.57.0",
"js-yaml": "^4.1.0",
"markdown-toc": "^1.2.0",
"nodemon": "^3.1.4",

View File

@@ -10,6 +10,10 @@
*/
export const settings = {
adBlock: "adBlock",
advanced: {
root: "advanced",
tidalUrl: "advanced.tidalUrl",
},
api: "api",
apiSettings: {
root: "apiSettings",
@@ -26,6 +30,7 @@ export const settings = {
buttonText: "discord.buttonText",
includeTimestamps: "discord.includeTimestamps",
showSong: "discord.showSong",
showIdle: "discord.showIdle",
idleText: "discord.idleText",
usingText: "discord.usingText",
},

View File

@@ -2,7 +2,7 @@
"openapi": "3.1.0",
"info": {
"title": "TIDAL Hi-Fi API",
"version": "5.15.0",
"version": "5.16.0",
"description": "",
"license": {
"name": "MIT",

View File

@@ -48,6 +48,9 @@ export class ListenBrainz {
} else {
// Fetches the oldData required for scrobbling and proceeds to construct a playing_now data payload for the Playing Now area
const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData;
const tidalUrl =
settingsStore.get<string, string>(settings.advanced.tidalUrl) ||
"https://listen.tidal.com";
const playing_data = {
listen_type: "playing_now",
payload: [
@@ -95,7 +98,7 @@ export class ListenBrainz {
additional_info: {
media_player: "Tidal Hi-Fi",
submission_client: "Tidal Hi-Fi",
music_service: "listen.tidal.com",
music_service: tidalUrl,
duration: oldData.duration,
},
artist_name: oldData.artists,

View File

@@ -24,7 +24,6 @@ import {
showSettingsWindow,
} from "./scripts/settings";
import { addTray, refreshTray } from "./scripts/tray";
const tidalUrl = "https://listen.tidal.com";
let mainInhibitorId = -1;
initialize();
@@ -40,6 +39,9 @@ const windowPreferences = {
setDefaultFlags(app);
setManagedFlagsFromSettings(app);
const tidalUrl =
settingsStore.get<string, string>(settings.advanced.tidalUrl) || "https://listen.tidal.com";
/**
* Update the menuBarVisibility according to the store value
*

View File

@@ -29,6 +29,7 @@ const switchesWithSettings = {
let adBlock: HTMLInputElement,
api: HTMLInputElement,
channel: HTMLSelectElement,
customCSS: HTMLInputElement,
disableBackgroundThrottle: HTMLInputElement,
disableHardwareMediaKeys: HTMLInputElement,
@@ -57,6 +58,7 @@ let adBlock: HTMLInputElement,
discord_include_timestamps: HTMLInputElement,
discord_button_text: HTMLInputElement,
discord_show_song: HTMLInputElement,
discord_show_idle: HTMLInputElement,
discord_idle_text: HTMLInputElement,
discord_using_text: HTMLInputElement;
@@ -121,6 +123,7 @@ function refreshSettings() {
try {
adBlock.checked = settingsStore.get(settings.adBlock);
api.checked = settingsStore.get(settings.api);
channel.value = settingsStore.get(settings.advanced.tidalUrl);
customCSS.value = settingsStore.get<string, string[]>(settings.customCSS).join("\n");
disableBackgroundThrottle.checked = settingsStore.get(settings.disableBackgroundThrottle);
disableHardwareMediaKeys.checked = settingsStore.get(settings.flags.disableHardwareMediaKeys);
@@ -149,6 +152,7 @@ function refreshSettings() {
discord_include_timestamps.checked = settingsStore.get(settings.discord.includeTimestamps);
discord_button_text.value = settingsStore.get(settings.discord.buttonText);
discord_show_song.checked = settingsStore.get(settings.discord.showSong);
discord_show_idle.checked = settingsStore.get(settings.discord.showIdle);
discord_idle_text.value = settingsStore.get(settings.discord.idleText);
discord_using_text.value = settingsStore.get(settings.discord.usingText);
@@ -238,6 +242,7 @@ window.addEventListener("DOMContentLoaded", () => {
adBlock = get("adBlock");
api = get("apiCheckbox");
channel = get<HTMLSelectElement>("channel");
customCSS = get("customCSS");
disableBackgroundThrottle = get("disableBackgroundThrottle");
disableHardwareMediaKeys = get("disableHardwareMediaKeys");
@@ -266,12 +271,14 @@ window.addEventListener("DOMContentLoaded", () => {
listenbrainz_delay = get("listenbrainz_delay");
discord_button_text = get("discord_button_text");
discord_show_song = get("discord_show_song");
discord_show_idle = get("discord_show_idle");
discord_using_text = get("discord_using_text");
discord_idle_text = get("discord_idle_text");
refreshSettings();
addInputListener(adBlock, settings.adBlock);
addInputListener(api, settings.api);
addSelectListener(channel, settings.advanced.tidalUrl);
addTextAreaListener(customCSS, settings.customCSS);
addInputListener(disableBackgroundThrottle, settings.disableBackgroundThrottle);
addInputListener(disableHardwareMediaKeys, settings.flags.disableHardwareMediaKeys);
@@ -308,6 +315,7 @@ window.addEventListener("DOMContentLoaded", () => {
settings.discord.showSong,
switchesWithSettings.discord_show_song
);
addInputListener(discord_show_idle, settings.discord.showIdle);
addInputListener(discord_idle_text, settings.discord.idleText);
addInputListener(discord_using_text, settings.discord.usingText);
});

View File

@@ -49,7 +49,7 @@
<div class="group__option">
<div class="group__description">
<h4>Notifications</h4>
<p>Show a notification when a new song starts.</p>
<p>Show a notification when new media starts.</p>
</div>
<label class="switch">
<input id="notifications" type="checkbox" />
@@ -227,6 +227,17 @@
</div>
<div id="discord_options">
<div class="group__option" class="hidden">
<div class="group__description">
<h4>Show Idle Text</h4>
<p>Should the idle text be shown when idle?</p>
</div>
<label class="switch">
<input id="discord_show_idle" type="checkbox" />
<span class="switch__slider"></span>
</label>
</div>
<div class="group__option" class="hidden">
<div class="group__description">
<h4>Idle Text</h4>
@@ -245,7 +256,7 @@
<div class="group__option" class="hidden">
<div class="group__description">
<h4>Show song</h4>
<h4>Show media</h4>
<p>Show the current media in the Discord client</p>
</div>
<label class="switch">
@@ -278,7 +289,7 @@
<div class="group__option">
<div class="group__description">
<h4>Button text</h4>
<p>Text to display on the button below the song information.</p>
<p>Text to display on the button below the media information.</p>
<input id="discord_button_text" type="text" class="text-input" name="discord_button_text" />
</div>
</div>
@@ -316,7 +327,7 @@
</div>
<div class="group__description">
<h4>ScrobbleDelay</h4>
<p>The delay (in ms) to send a song to ListenBrainz. Prevents spamming the API when you fast forward
<p>The delay (in ms) to send a listen to ListenBrainz. Prevents spamming the API when you fast forward
immediately</p>
<input id="listenbrainz_delay" type="number" class="text-input" name="listenbrainz_delay" />
</div>
@@ -338,6 +349,20 @@
<input id="updateFrequency" type="number" class="text-input" name="updateFrequency" />
</div>
</div>
<div class="group__option">
<div class="group__description">
<h4>Tidal channel / URL</h4>
<p>
Which URL Tidal Hi-Fi should use.
<strong>note! Beta might break at any time</strong>
</p>
<select class="select-input" id="channel" name="channel">
<option value="https://listen.tidal.com">Stable (listen.tidal.com)</option>
<option value="https://listen.stage.tidal.com">Staging (listen.stage.tidal.com)</option>
</select>
</div>
</div>
</div>
<div class="group">
<p class="group__title">Flags</p>
@@ -443,7 +468,7 @@
<h4>TIDAL Hi-Fi</h4>
<div class="about-section__version">
<a target="_blank" rel="noopener"
href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.15.0">5.15.0</a>
href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.16.0">5.16.0</a>
</div>
<div class="about-section__links">
<a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/"

View File

@@ -394,8 +394,24 @@ function updateMediaInfo(mediaInfo: MediaInfo, notify: boolean) {
if (mediaInfo) {
currentMediaInfo = mediaInfo;
ipcRenderer.send(globalEvents.updateInfo, mediaInfo);
if (settingsStore.get(settings.notifications) && notify) {
if (currentNotification) currentNotification.close();
updateMpris(mediaInfo);
updateListenBrainz(mediaInfo);
if (notify) {
sendNotification(mediaInfo);
}
}
}
/**
* send a desktop notification if enabled in settings
* @param mediaInfo
* @param notify Whether to notify
*/
async function sendNotification(mediaInfo: MediaInfo) {
if (settingsStore.get(settings.notifications)) {
if (currentNotification) {
currentNotification.close();
}
currentNotification = new Notification({
title: mediaInfo.title,
body: mediaInfo.artists,
@@ -403,10 +419,6 @@ function updateMediaInfo(mediaInfo: MediaInfo, notify: boolean) {
});
currentNotification.show();
}
updateMpris(mediaInfo);
updateListenBrainz(mediaInfo);
}
}
function addMPRIS() {

View File

@@ -14,7 +14,7 @@ export let rpc: Client;
const observer = () => {
if (rpc) {
rpc.setActivity(getActivity());
updateActivity();
}
};
@@ -24,6 +24,15 @@ const defaultPresence = {
instance: false,
};
const updateActivity = () => {
const showIdle = settingsStore.get<string, boolean>(settings.discord.showIdle) ?? true;
if (mediaInfo.status === MediaStatus.paused && !showIdle) {
rpc.clearActivity();
} else {
rpc.setActivity(getActivity());
}
};
const getActivity = (): Presence => {
const presence: Presence = { ...defaultPresence };
@@ -54,18 +63,33 @@ const getActivity = (): Presence => {
return { includeTimestamps, detailsPrefix, buttonText };
}
function setPresenceFromMediaInfo(detailsPrefix: string, buttonText: string) {
if (mediaInfo.url) {
presence.details = `${detailsPrefix}${mediaInfo.title}`;
presence.state = mediaInfo.artists ? mediaInfo.artists : "unknown artist(s)";
presence.largeImageKey = mediaInfo.image;
if (mediaInfo.album) {
presence.largeImageText = mediaInfo.album;
/**
* Pad a string using spaces to at least 2 characters
* @param input string to pad with 2 characters
* @returns
*/
function pad(input: string): string {
return input.padEnd(2, " ");
}
function setPresenceFromMediaInfo(detailsPrefix: string, buttonText: string) {
// discord requires a minimum of 2 characters
const title = pad(mediaInfo.title);
const album = pad(mediaInfo.album);
const artists = pad(mediaInfo.artists);
if (mediaInfo.url) {
presence.details = `${detailsPrefix}${title}`;
presence.state = artists ? artists : "unknown artist(s)";
presence.largeImageKey = mediaInfo.image;
if (album) {
presence.largeImageText = album;
}
presence.buttons = [{ label: buttonText, url: mediaInfo.url }];
} else {
presence.details = `Watching ${mediaInfo.title}`;
presence.state = mediaInfo.artists;
presence.details = `Watching ${title}`;
presence.state = artists;
}
}
@@ -90,9 +114,13 @@ export const initRPC = () => {
rpc.login({ clientId }).then(
() => {
rpc.on("ready", () => {
rpc.setActivity(getActivity());
updateActivity();
});
const { updateInfo, play, pause, playPause } = globalEvents;
[updateInfo, play, pause, playPause].forEach((status) => {
ipcMain.on(status, observer);
});
ipcMain.on(globalEvents.updateInfo, observer);
},
() => {
Logger.log("Can't connect to Discord, is it running?");

View File

@@ -28,6 +28,9 @@ const buildMigration = (
export const settingsStore = new Store({
defaults: {
adBlock: false,
advanced: {
tidalUrl: "https://listen.tidal.com",
},
api: true,
apiSettings: {
port: 47836,
@@ -40,6 +43,7 @@ export const settingsStore = new Store({
enableDiscord: false,
discord: {
showSong: true,
showIdle: true,
idleText: "Browsing Tidal",
usingText: "Playing media on TIDAL",
includeTimestamps: true,
@@ -107,6 +111,14 @@ export const settingsStore = new Store({
{ key: settings.apiSettings.hostname, value: "127.0.0.1" },
]);
},
"5.15.0": (migrationStore) => {
buildMigration("5.15.0", migrationStore, [
{ key: settings.advanced.tidalUrl, value: "https://listen.tidal.com" },
]);
},
"5.16.0": (migrationStore) => {
buildMigration("5.16.0", migrationStore, [{ key: settings.discord.showIdle, value: "true" }]);
},
},
});