mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2025-09-19 18:19:18 +02:00
Compare commits
5 Commits
bce768fde3
...
5.12.0
Author | SHA1 | Date | |
---|---|---|---|
3740ce5a12 | |||
a0f9faa753 | |||
5e3583534b | |||
|
5f8cf33249 | ||
|
2d94b4bf49 |
@@ -4,6 +4,10 @@ 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.12.0]
|
||||||
|
|
||||||
|
- Added Shuffle and Repeat state to API response - By [ThatGravyBoat](https://github.com/ThatGravyBoat)
|
||||||
|
|
||||||
## [5.11.0]
|
## [5.11.0]
|
||||||
|
|
||||||
- Re-implemented the API, added support for duration/current in seconds & shuffle+repeat
|
- Re-implemented the API, added support for duration/current in seconds & shuffle+repeat
|
||||||
|
37
package-lock.json
generated
37
package-lock.json
generated
@@ -1,17 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "tidal-hifi",
|
"name": "tidal-hifi",
|
||||||
"version": "5.11.0",
|
"version": "5.12.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "tidal-hifi",
|
"name": "tidal-hifi",
|
||||||
"version": "5.11.0",
|
"version": "5.12.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron/remote": "^2.1.2",
|
"@electron/remote": "^2.1.2",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"cors": "^2.8.5",
|
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
"electron-store": "^8.2.0",
|
"electron-store": "^8.2.0",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mastermindzh/prettier-config": "^1.0.0",
|
"@mastermindzh/prettier-config": "^1.0.0",
|
||||||
"@types/cors": "^2.8.17",
|
|
||||||
"@types/discord-rpc": "^4.0.8",
|
"@types/discord-rpc": "^4.0.8",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/node": "^20.10.6",
|
"@types/node": "^20.10.6",
|
||||||
@@ -1032,15 +1030,6 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/cors": {
|
|
||||||
"version": "2.8.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
|
|
||||||
"integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/debug": {
|
"node_modules/@types/debug": {
|
||||||
"version": "4.1.12",
|
"version": "4.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
||||||
@@ -2690,18 +2679,6 @@
|
|||||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/cors": {
|
|
||||||
"version": "2.8.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
|
||||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
|
||||||
"dependencies": {
|
|
||||||
"object-assign": "^4",
|
|
||||||
"vary": "^1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cosmiconfig": {
|
"node_modules/cosmiconfig": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
|
||||||
@@ -6006,14 +5983,6 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object-assign": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.1",
|
"version": "1.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
||||||
@@ -8595,4 +8564,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tidal-hifi",
|
"name": "tidal-hifi",
|
||||||
"version": "5.11.0",
|
"version": "5.12.0",
|
||||||
"description": "Tidal on Electron with widevine(hifi) support",
|
"description": "Tidal on Electron with widevine(hifi) support",
|
||||||
"main": "ts-dist/main.js",
|
"main": "ts-dist/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -41,7 +41,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron/remote": "^2.1.2",
|
"@electron/remote": "^2.1.2",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"cors": "^2.8.5",
|
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
"electron-store": "^8.2.0",
|
"electron-store": "^8.2.0",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
@@ -52,7 +51,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mastermindzh/prettier-config": "^1.0.0",
|
"@mastermindzh/prettier-config": "^1.0.0",
|
||||||
"@types/cors": "^2.8.17",
|
|
||||||
"@types/discord-rpc": "^4.0.8",
|
"@types/discord-rpc": "^4.0.8",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/node": "^20.10.6",
|
"@types/node": "^20.10.6",
|
||||||
@@ -75,4 +73,4 @@
|
|||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
},
|
},
|
||||||
"prettier": "@mastermindzh/prettier-config"
|
"prettier": "@mastermindzh/prettier-config"
|
||||||
}
|
}
|
@@ -5,14 +5,12 @@ import { settingsStore } from "../../scripts/settings";
|
|||||||
import { addCurrentInfo } from "./features/current";
|
import { addCurrentInfo } from "./features/current";
|
||||||
import { addPlaybackControl } from "./features/player";
|
import { addPlaybackControl } from "./features/player";
|
||||||
import { addLegacyApi } from "./legacy";
|
import { addLegacyApi } from "./legacy";
|
||||||
import cors from "cors";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to enable TIDAL Hi-Fi's express api
|
* Function to enable TIDAL Hi-Fi's express api
|
||||||
*/
|
*/
|
||||||
export const startApi = (mainWindow: BrowserWindow) => {
|
export const startApi = (mainWindow: BrowserWindow) => {
|
||||||
const expressApp = express();
|
const expressApp = express();
|
||||||
expressApp.use(cors());
|
|
||||||
expressApp.get("/", (req, res) => res.send("Hello World!"));
|
expressApp.get("/", (req, res) => res.send("Hello World!"));
|
||||||
|
|
||||||
// add features
|
// add features
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { MediaStatus } from "./mediaStatus";
|
import { MediaStatus } from "./mediaStatus";
|
||||||
|
import { MediaPlayerInfo } from "./mediaPlayerInfo";
|
||||||
|
|
||||||
export interface MediaInfo {
|
export interface MediaInfo {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -13,4 +14,5 @@ export interface MediaInfo {
|
|||||||
durationInSeconds?: number;
|
durationInSeconds?: number;
|
||||||
image: string;
|
image: string;
|
||||||
favorite: boolean;
|
favorite: boolean;
|
||||||
|
player: MediaPlayerInfo;
|
||||||
}
|
}
|
||||||
|
8
src/models/mediaPlayerInfo.ts
Normal file
8
src/models/mediaPlayerInfo.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { RepeatState } from "./repeatState";
|
||||||
|
import { MediaStatus } from "./mediaStatus";
|
||||||
|
|
||||||
|
export interface MediaPlayerInfo {
|
||||||
|
status: MediaStatus;
|
||||||
|
shuffle: boolean;
|
||||||
|
repeat: RepeatState;
|
||||||
|
}
|
5
src/models/repeatState.ts
Normal file
5
src/models/repeatState.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export enum RepeatState {
|
||||||
|
off = "off",
|
||||||
|
all = "all",
|
||||||
|
single = "single",
|
||||||
|
}
|
@@ -433,7 +433,7 @@
|
|||||||
<h4>TIDAL Hi-Fi</h4>
|
<h4>TIDAL Hi-Fi</h4>
|
||||||
<div class="about-section__version">
|
<div class="about-section__version">
|
||||||
<a target="_blank" rel="noopener"
|
<a target="_blank" rel="noopener"
|
||||||
href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.11.0">5.11.0</a>
|
href="https://github.com/Mastermindzh/tidal-hifi/releases/tag/5.12.0">5.12.0</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="about-section__links">
|
<div class="about-section__links">
|
||||||
<a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/"
|
<a target="_blank" rel="noopener" href="https://github.com/mastermindzh/tidal-hifi/"
|
||||||
|
@@ -19,6 +19,7 @@ import { downloadFile } from "./scripts/download";
|
|||||||
import { addHotkey } from "./scripts/hotkeys";
|
import { addHotkey } from "./scripts/hotkeys";
|
||||||
import { settingsStore } from "./scripts/settings";
|
import { settingsStore } from "./scripts/settings";
|
||||||
import { setTitle } from "./scripts/window-functions";
|
import { setTitle } from "./scripts/window-functions";
|
||||||
|
import { RepeatState } from "./models/repeatState";
|
||||||
|
|
||||||
const notificationPath = `${app.getPath("userData")}/notification.jpg`;
|
const notificationPath = `${app.getPath("userData")}/notification.jpg`;
|
||||||
const appName = "TIDAL Hi-Fi";
|
const appName = "TIDAL Hi-Fi";
|
||||||
@@ -29,6 +30,8 @@ let currentListenBrainzDelayId: ReturnType<typeof setTimeout>;
|
|||||||
let scrobbleWaitingForDelay = false;
|
let scrobbleWaitingForDelay = false;
|
||||||
|
|
||||||
let currentlyPlaying = MediaStatus.paused;
|
let currentlyPlaying = MediaStatus.paused;
|
||||||
|
let currentRepeatState: RepeatState = RepeatState.off;
|
||||||
|
let currentShuffleState = false;
|
||||||
let currentMediaInfo: Options;
|
let currentMediaInfo: Options;
|
||||||
let currentNotification: Electron.Notification;
|
let currentNotification: Electron.Notification;
|
||||||
|
|
||||||
@@ -348,6 +351,23 @@ function getCurrentlyPlayingStatus() {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentShuffleState() {
|
||||||
|
const shuffle = elements.get("shuffle");
|
||||||
|
return shuffle?.getAttribute("aria-checked") === "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentRepeatState() {
|
||||||
|
const repeat = elements.get("repeat");
|
||||||
|
switch (repeat?.getAttribute("data-type")) {
|
||||||
|
case "button__repeatAll":
|
||||||
|
return RepeatState.all;
|
||||||
|
case "button__repeatSingle":
|
||||||
|
return RepeatState.single;
|
||||||
|
default:
|
||||||
|
return RepeatState.off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the duration from MM:SS to seconds
|
* Convert the duration from MM:SS to seconds
|
||||||
* @param {*} duration
|
* @param {*} duration
|
||||||
@@ -511,14 +531,21 @@ setInterval(function () {
|
|||||||
const titleOrArtistsChanged = currentSong !== songDashArtistTitle;
|
const titleOrArtistsChanged = currentSong !== songDashArtistTitle;
|
||||||
const current = elements.getText("current");
|
const current = elements.getText("current");
|
||||||
const currentStatus = getCurrentlyPlayingStatus();
|
const currentStatus = getCurrentlyPlayingStatus();
|
||||||
|
const shuffleState = getCurrentShuffleState();
|
||||||
|
const repeatState = getCurrentRepeatState();
|
||||||
|
|
||||||
const playStateChanged = currentStatus != currentlyPlaying;
|
const playStateChanged = currentStatus != currentlyPlaying;
|
||||||
|
const shuffleStateChanged = shuffleState != currentShuffleState;
|
||||||
|
const repeatStateChanged = repeatState != currentRepeatState;
|
||||||
|
|
||||||
|
const hasStateChanged = playStateChanged || shuffleStateChanged || repeatStateChanged;
|
||||||
|
|
||||||
// update info if song changed or was just paused/resumed
|
// update info if song changed or was just paused/resumed
|
||||||
if (titleOrArtistsChanged || playStateChanged) {
|
if (titleOrArtistsChanged || hasStateChanged) {
|
||||||
if (playStateChanged) {
|
if (playStateChanged) currentlyPlaying = currentStatus;
|
||||||
currentlyPlaying = currentStatus;
|
if (shuffleStateChanged) currentShuffleState = shuffleState;
|
||||||
}
|
if (repeatStateChanged) currentRepeatState = repeatState;
|
||||||
|
|
||||||
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
|
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
|
||||||
|
|
||||||
const album = elements.getAlbumName();
|
const album = elements.getAlbumName();
|
||||||
@@ -537,6 +564,12 @@ setInterval(function () {
|
|||||||
image: "",
|
image: "",
|
||||||
icon: "",
|
icon: "",
|
||||||
favorite: elements.isFavorite(),
|
favorite: elements.isFavorite(),
|
||||||
|
|
||||||
|
player: {
|
||||||
|
status: currentStatus,
|
||||||
|
shuffle: shuffleState,
|
||||||
|
repeat: repeatState,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// update title, url and play info with new info
|
// update title, url and play info with new info
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { MediaInfo } from "../models/mediaInfo";
|
import { MediaInfo } from "../models/mediaInfo";
|
||||||
import { MediaStatus } from "../models/mediaStatus";
|
import { MediaStatus } from "../models/mediaStatus";
|
||||||
|
import { RepeatState } from "../models/repeatState";
|
||||||
|
|
||||||
export const mediaInfo = {
|
export const mediaInfo = {
|
||||||
title: "",
|
title: "",
|
||||||
@@ -14,6 +15,12 @@ export const mediaInfo = {
|
|||||||
durationInSeconds: 0,
|
durationInSeconds: 0,
|
||||||
image: "tidal-hifi-icon",
|
image: "tidal-hifi-icon",
|
||||||
favorite: false,
|
favorite: false,
|
||||||
|
|
||||||
|
player: {
|
||||||
|
status: MediaStatus.paused as string,
|
||||||
|
shuffle: false,
|
||||||
|
repeat: RepeatState.off as string,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateMediaInfo = (arg: MediaInfo) => {
|
export const updateMediaInfo = (arg: MediaInfo) => {
|
||||||
@@ -29,6 +36,10 @@ export const updateMediaInfo = (arg: MediaInfo) => {
|
|||||||
mediaInfo.durationInSeconds = arg.durationInSeconds ?? 0;
|
mediaInfo.durationInSeconds = arg.durationInSeconds ?? 0;
|
||||||
mediaInfo.image = propOrDefault(arg.image);
|
mediaInfo.image = propOrDefault(arg.image);
|
||||||
mediaInfo.favorite = arg.favorite;
|
mediaInfo.favorite = arg.favorite;
|
||||||
|
|
||||||
|
mediaInfo.player.status = propOrDefault(arg.player?.status);
|
||||||
|
mediaInfo.player.shuffle = arg.player.shuffle;
|
||||||
|
mediaInfo.player.repeat = propOrDefault(arg.player?.repeat);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user