mirror of
https://github.com/Mastermindzh/tidal-hifi.git
synced 2024-11-22 21:42:46 +01:00
simplified mediaInfo & Options
This commit is contained in:
parent
b49bd925da
commit
0a8efc730d
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -2,6 +2,7 @@
|
|||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Brainz",
|
"Brainz",
|
||||||
"Castlabs",
|
"Castlabs",
|
||||||
|
"Fi's",
|
||||||
"flac",
|
"flac",
|
||||||
"Flatpak",
|
"Flatpak",
|
||||||
"geqnfr",
|
"geqnfr",
|
||||||
|
@ -4,6 +4,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/),
|
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).
|
||||||
|
|
||||||
|
## [Next]
|
||||||
|
|
||||||
|
- Simplified `MediaInfo` & `Options` types
|
||||||
|
- Added `playingFrom` information to the info API
|
||||||
|
- also changed the way we update Album info since Playing From now shows the correct Album.
|
||||||
|
|
||||||
## [5.13.1]
|
## [5.13.1]
|
||||||
|
|
||||||
- removed Swagger generation step in favor of pre-generated file.
|
- removed Swagger generation step in favor of pre-generated file.
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
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: '.header-details [data-test="title"]',
|
album_header_title: '*[class^="playingFrom"] span:nth-child(2)',
|
||||||
|
playingFrom: '*[class^="playingFrom"] 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"]',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { MediaStatus } from "./mediaStatus";
|
|
||||||
import { MediaPlayerInfo } from "./mediaPlayerInfo";
|
import { MediaPlayerInfo } from "./mediaPlayerInfo";
|
||||||
|
import { MediaStatus } from "./mediaStatus";
|
||||||
|
|
||||||
export interface MediaInfo {
|
export interface MediaInfo {
|
||||||
title: string;
|
title: string;
|
||||||
@ -8,6 +8,7 @@ export interface MediaInfo {
|
|||||||
icon: string;
|
icon: string;
|
||||||
status: MediaStatus;
|
status: MediaStatus;
|
||||||
url: string;
|
url: string;
|
||||||
|
playingFrom: string;
|
||||||
current: string;
|
current: string;
|
||||||
currentInSeconds?: number;
|
currentInSeconds?: number;
|
||||||
duration: string;
|
duration: string;
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
export interface Options {
|
|
||||||
title: string;
|
|
||||||
artists: string;
|
|
||||||
album: string;
|
|
||||||
status: string;
|
|
||||||
url: string;
|
|
||||||
current: string;
|
|
||||||
currentInSeconds: number;
|
|
||||||
duration: string;
|
|
||||||
durationInSeconds: number;
|
|
||||||
"app-name": string;
|
|
||||||
image: string;
|
|
||||||
icon: string;
|
|
||||||
favorite: boolean;
|
|
||||||
}
|
|
@ -13,16 +13,15 @@ import { Logger } from "./features/logger";
|
|||||||
import { Songwhip } from "./features/songwhip/songwhip";
|
import { Songwhip } from "./features/songwhip/songwhip";
|
||||||
import { addCustomCss } from "./features/theming/theming";
|
import { addCustomCss } from "./features/theming/theming";
|
||||||
import { convertDurationToSeconds } from "./features/time/parse";
|
import { convertDurationToSeconds } from "./features/time/parse";
|
||||||
|
import { MediaInfo } from "./models/mediaInfo";
|
||||||
import { MediaStatus } from "./models/mediaStatus";
|
import { MediaStatus } from "./models/mediaStatus";
|
||||||
import { Options } from "./models/options";
|
import { RepeatState } from "./models/repeatState";
|
||||||
import { downloadFile } from "./scripts/download";
|
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";
|
|
||||||
let currentSong = "";
|
let currentSong = "";
|
||||||
let player: Player;
|
let player: Player;
|
||||||
let currentPlayStatus = MediaStatus.paused;
|
let currentPlayStatus = MediaStatus.paused;
|
||||||
@ -32,7 +31,7 @@ let scrobbleWaitingForDelay = false;
|
|||||||
let currentlyPlaying = MediaStatus.paused;
|
let currentlyPlaying = MediaStatus.paused;
|
||||||
let currentRepeatState: RepeatState = RepeatState.off;
|
let currentRepeatState: RepeatState = RepeatState.off;
|
||||||
let currentShuffleState = false;
|
let currentShuffleState = false;
|
||||||
let currentMediaInfo: Options;
|
let currentMediaInfo: MediaInfo;
|
||||||
let currentNotification: Electron.Notification;
|
let currentNotification: Electron.Notification;
|
||||||
|
|
||||||
const elements = {
|
const elements = {
|
||||||
@ -57,7 +56,8 @@ const elements = {
|
|||||||
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: '.header-details [data-test="title"]',
|
album_header_title: '*[class^="playingFrom"] span:nth-child(2)',
|
||||||
|
playing_from: '*[class^="playingFrom"] 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"]',
|
||||||
@ -380,23 +380,24 @@ function convertDuration(duration: string) {
|
|||||||
/**
|
/**
|
||||||
* Update Tidal-hifi's media info
|
* Update Tidal-hifi's media info
|
||||||
*
|
*
|
||||||
* @param {*} options
|
* @param {*} mediaInfo
|
||||||
*/
|
*/
|
||||||
function updateMediaInfo(options: Options, notify: boolean) {
|
function updateMediaInfo(mediaInfo: MediaInfo, notify: boolean) {
|
||||||
if (options) {
|
if (mediaInfo) {
|
||||||
currentMediaInfo = options;
|
currentMediaInfo = mediaInfo;
|
||||||
ipcRenderer.send(globalEvents.updateInfo, options);
|
ipcRenderer.send(globalEvents.updateInfo, mediaInfo);
|
||||||
if (settingsStore.get(settings.notifications) && notify) {
|
if (settingsStore.get(settings.notifications) && notify) {
|
||||||
if (currentNotification) currentNotification.close();
|
if (currentNotification) currentNotification.close();
|
||||||
currentNotification = new Notification({
|
currentNotification = new Notification({
|
||||||
title: options.title,
|
title: mediaInfo.title,
|
||||||
body: options.artists,
|
body: mediaInfo.artists,
|
||||||
icon: options.icon,
|
icon: mediaInfo.icon,
|
||||||
});
|
});
|
||||||
currentNotification.show();
|
currentNotification.show();
|
||||||
}
|
}
|
||||||
updateMpris(options);
|
|
||||||
updateListenBrainz(options);
|
updateMpris(mediaInfo);
|
||||||
|
updateListenBrainz(mediaInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,32 +455,32 @@ function addMPRIS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMpris(options: Options) {
|
function updateMpris(mediaInfo: MediaInfo) {
|
||||||
if (player) {
|
if (player) {
|
||||||
player.metadata = {
|
player.metadata = {
|
||||||
...player.metadata,
|
...player.metadata,
|
||||||
...{
|
...{
|
||||||
"xesam:title": options.title,
|
"xesam:title": mediaInfo.title,
|
||||||
"xesam:artist": [options.artists],
|
"xesam:artist": [mediaInfo.artists],
|
||||||
"xesam:album": options.album,
|
"xesam:album": mediaInfo.album,
|
||||||
"mpris:artUrl": options.image,
|
"mpris:artUrl": mediaInfo.image,
|
||||||
"mpris:length": convertDuration(options.duration) * 1000 * 1000,
|
"mpris:length": convertDuration(mediaInfo.duration) * 1000 * 1000,
|
||||||
"mpris:trackid": "/org/mpris/MediaPlayer2/track/" + getTrackID(),
|
"mpris:trackid": "/org/mpris/MediaPlayer2/track/" + getTrackID(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
player.playbackStatus = options.status === MediaStatus.paused ? "Paused" : "Playing";
|
player.playbackStatus = mediaInfo.status === MediaStatus.paused ? "Paused" : "Playing";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the listenbrainz service with new data based on a few conditions
|
* Update the listenbrainz service with new data based on a few conditions
|
||||||
*/
|
*/
|
||||||
function updateListenBrainz(options: Options) {
|
function updateListenBrainz(mediaInfo: MediaInfo) {
|
||||||
if (settingsStore.get(settings.ListenBrainz.enabled)) {
|
if (settingsStore.get(settings.ListenBrainz.enabled)) {
|
||||||
const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData;
|
const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData;
|
||||||
if (
|
if (
|
||||||
(!oldData && options.status === MediaStatus.playing) ||
|
(!oldData && mediaInfo.status === MediaStatus.playing) ||
|
||||||
(oldData && oldData.title !== options.title)
|
(oldData && oldData.title !== mediaInfo.title)
|
||||||
) {
|
) {
|
||||||
if (!scrobbleWaitingForDelay) {
|
if (!scrobbleWaitingForDelay) {
|
||||||
scrobbleWaitingForDelay = true;
|
scrobbleWaitingForDelay = true;
|
||||||
@ -487,10 +488,10 @@ function updateListenBrainz(options: Options) {
|
|||||||
currentListenBrainzDelayId = setTimeout(
|
currentListenBrainzDelayId = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
ListenBrainz.scrobble(
|
ListenBrainz.scrobble(
|
||||||
options.title,
|
mediaInfo.title,
|
||||||
options.artists,
|
mediaInfo.artists,
|
||||||
options.status,
|
mediaInfo.status,
|
||||||
convertDuration(options.duration)
|
convertDuration(mediaInfo.duration)
|
||||||
);
|
);
|
||||||
scrobbleWaitingForDelay = false;
|
scrobbleWaitingForDelay = false;
|
||||||
},
|
},
|
||||||
@ -547,20 +548,19 @@ setInterval(function () {
|
|||||||
if (repeatStateChanged) currentRepeatState = repeatState;
|
if (repeatStateChanged) currentRepeatState = repeatState;
|
||||||
|
|
||||||
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
|
skipArtistsIfFoundInSkippedArtistsList(artistsArray);
|
||||||
|
|
||||||
const album = elements.getAlbumName();
|
const album = elements.getAlbumName();
|
||||||
const duration = elements.getText("duration");
|
const duration = elements.getText("duration");
|
||||||
const options = {
|
const options: MediaInfo = {
|
||||||
title,
|
title,
|
||||||
artists: artistsString,
|
artists: artistsString,
|
||||||
album: album,
|
album: album,
|
||||||
|
playingFrom: elements.getText("playing_from"),
|
||||||
status: currentStatus,
|
status: currentStatus,
|
||||||
url: getTrackURL(),
|
url: getTrackURL(),
|
||||||
current,
|
current,
|
||||||
currentInSeconds: convertDurationToSeconds(current),
|
currentInSeconds: convertDurationToSeconds(current),
|
||||||
duration,
|
duration,
|
||||||
durationInSeconds: convertDurationToSeconds(duration),
|
durationInSeconds: convertDurationToSeconds(duration),
|
||||||
"app-name": appName,
|
|
||||||
image: "",
|
image: "",
|
||||||
icon: "",
|
icon: "",
|
||||||
favorite: elements.isFavorite(),
|
favorite: elements.isFavorite(),
|
||||||
|
@ -2,12 +2,13 @@ import { MediaInfo } from "../models/mediaInfo";
|
|||||||
import { MediaStatus } from "../models/mediaStatus";
|
import { MediaStatus } from "../models/mediaStatus";
|
||||||
import { RepeatState } from "../models/repeatState";
|
import { RepeatState } from "../models/repeatState";
|
||||||
|
|
||||||
export const mediaInfo = {
|
const defaultInfo: MediaInfo = {
|
||||||
title: "",
|
title: "",
|
||||||
artists: "",
|
artists: "",
|
||||||
album: "",
|
album: "",
|
||||||
icon: "",
|
icon: "",
|
||||||
status: MediaStatus.paused as string,
|
playingFrom: "",
|
||||||
|
status: MediaStatus.paused,
|
||||||
url: "",
|
url: "",
|
||||||
current: "",
|
current: "",
|
||||||
currentInSeconds: 0,
|
currentInSeconds: 0,
|
||||||
@ -17,41 +18,18 @@ export const mediaInfo = {
|
|||||||
favorite: false,
|
favorite: false,
|
||||||
|
|
||||||
player: {
|
player: {
|
||||||
status: MediaStatus.paused as string,
|
status: MediaStatus.paused,
|
||||||
shuffle: false,
|
shuffle: false,
|
||||||
repeat: RepeatState.off as string,
|
repeat: RepeatState.off,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export let mediaInfo: MediaInfo = { ...defaultInfo };
|
||||||
|
|
||||||
export const updateMediaInfo = (arg: MediaInfo) => {
|
export const updateMediaInfo = (arg: MediaInfo) => {
|
||||||
mediaInfo.title = propOrDefault(arg.title);
|
mediaInfo = { ...defaultInfo, ...arg };
|
||||||
mediaInfo.artists = propOrDefault(arg.artists);
|
mediaInfo.url = toUniversalUrl(mediaInfo.url);
|
||||||
mediaInfo.album = propOrDefault(arg.album);
|
|
||||||
mediaInfo.icon = propOrDefault(arg.icon);
|
|
||||||
mediaInfo.url = toUniversalUrl(propOrDefault(arg.url));
|
|
||||||
mediaInfo.status = propOrDefault(arg.status);
|
|
||||||
mediaInfo.current = propOrDefault(arg.current);
|
|
||||||
mediaInfo.currentInSeconds = arg.currentInSeconds ?? 0;
|
|
||||||
mediaInfo.duration = propOrDefault(arg.duration);
|
|
||||||
mediaInfo.durationInSeconds = arg.durationInSeconds ?? 0;
|
|
||||||
mediaInfo.image = propOrDefault(arg.image);
|
|
||||||
mediaInfo.favorite = arg.favorite;
|
|
||||||
|
|
||||||
mediaInfo.player = {
|
|
||||||
status: propOrDefault(arg.player?.status),
|
|
||||||
shuffle: arg.player?.shuffle ?? false,
|
|
||||||
repeat: propOrDefault(arg.player?.repeat),
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the property or a default value
|
|
||||||
* @param {*} prop property to check
|
|
||||||
* @param {*} defaultValue defaults to ""
|
|
||||||
*/
|
|
||||||
function propOrDefault(prop: string, defaultValue = "") {
|
|
||||||
return prop || defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append the universal link syntax (?u) to any url
|
* Append the universal link syntax (?u) to any url
|
||||||
|
Loading…
Reference in New Issue
Block a user