From 0a8efc730dec084dbd4dc64288bf486dbe525e78 Mon Sep 17 00:00:00 2001 From: Rick van Lieshout Date: Sun, 9 Jun 2024 12:33:48 +0200 Subject: [PATCH] simplified mediaInfo & Options --- .vscode/settings.json | 1 + CHANGELOG.md | 6 ++++ scripts/verifyElements.js | 3 +- src/models/mediaInfo.ts | 3 +- src/models/options.ts | 15 --------- src/preload.ts | 64 +++++++++++++++++++-------------------- src/scripts/mediaInfo.ts | 40 ++++++------------------ 7 files changed, 52 insertions(+), 80 deletions(-) delete mode 100644 src/models/options.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 74f8aa3..c37b15f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "Brainz", "Castlabs", + "Fi's", "flac", "Flatpak", "geqnfr", diff --git a/CHANGELOG.md b/CHANGELOG.md index 28453d7..82ade28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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/), 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] - removed Swagger generation step in favor of pre-generated file. diff --git a/scripts/verifyElements.js b/scripts/verifyElements.js index fc96477..be19e5a 100644 --- a/scripts/verifyElements.js +++ b/scripts/verifyElements.js @@ -25,7 +25,8 @@ bar: '*[data-test="progress-bar"]', footer: "#footerPlayer", 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']", album_name_cell: '[class^="album"]', tracklist_row: '[data-test="tracklist-row"]', diff --git a/src/models/mediaInfo.ts b/src/models/mediaInfo.ts index c2a59eb..f7c2e5e 100644 --- a/src/models/mediaInfo.ts +++ b/src/models/mediaInfo.ts @@ -1,5 +1,5 @@ -import { MediaStatus } from "./mediaStatus"; import { MediaPlayerInfo } from "./mediaPlayerInfo"; +import { MediaStatus } from "./mediaStatus"; export interface MediaInfo { title: string; @@ -8,6 +8,7 @@ export interface MediaInfo { icon: string; status: MediaStatus; url: string; + playingFrom: string; current: string; currentInSeconds?: number; duration: string; diff --git a/src/models/options.ts b/src/models/options.ts deleted file mode 100644 index 1aece34..0000000 --- a/src/models/options.ts +++ /dev/null @@ -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; -} diff --git a/src/preload.ts b/src/preload.ts index eb01332..6bcfa51 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -13,16 +13,15 @@ import { Logger } from "./features/logger"; import { Songwhip } from "./features/songwhip/songwhip"; import { addCustomCss } from "./features/theming/theming"; import { convertDurationToSeconds } from "./features/time/parse"; +import { MediaInfo } from "./models/mediaInfo"; import { MediaStatus } from "./models/mediaStatus"; -import { Options } from "./models/options"; +import { RepeatState } from "./models/repeatState"; import { downloadFile } from "./scripts/download"; import { addHotkey } from "./scripts/hotkeys"; import { settingsStore } from "./scripts/settings"; import { setTitle } from "./scripts/window-functions"; -import { RepeatState } from "./models/repeatState"; const notificationPath = `${app.getPath("userData")}/notification.jpg`; -const appName = "TIDAL Hi-Fi"; let currentSong = ""; let player: Player; let currentPlayStatus = MediaStatus.paused; @@ -32,7 +31,7 @@ let scrobbleWaitingForDelay = false; let currentlyPlaying = MediaStatus.paused; let currentRepeatState: RepeatState = RepeatState.off; let currentShuffleState = false; -let currentMediaInfo: Options; +let currentMediaInfo: MediaInfo; let currentNotification: Electron.Notification; const elements = { @@ -57,7 +56,8 @@ const elements = { bar: '*[data-test="progress-bar"]', footer: "#footerPlayer", 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']", album_name_cell: '[class^="album"]', tracklist_row: '[data-test="tracklist-row"]', @@ -380,23 +380,24 @@ function convertDuration(duration: string) { /** * Update Tidal-hifi's media info * - * @param {*} options + * @param {*} mediaInfo */ -function updateMediaInfo(options: Options, notify: boolean) { - if (options) { - currentMediaInfo = options; - ipcRenderer.send(globalEvents.updateInfo, options); +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(); currentNotification = new Notification({ - title: options.title, - body: options.artists, - icon: options.icon, + title: mediaInfo.title, + body: mediaInfo.artists, + icon: mediaInfo.icon, }); 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) { player.metadata = { ...player.metadata, ...{ - "xesam:title": options.title, - "xesam:artist": [options.artists], - "xesam:album": options.album, - "mpris:artUrl": options.image, - "mpris:length": convertDuration(options.duration) * 1000 * 1000, + "xesam:title": mediaInfo.title, + "xesam:artist": [mediaInfo.artists], + "xesam:album": mediaInfo.album, + "mpris:artUrl": mediaInfo.image, + "mpris:length": convertDuration(mediaInfo.duration) * 1000 * 1000, "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 */ -function updateListenBrainz(options: Options) { +function updateListenBrainz(mediaInfo: MediaInfo) { if (settingsStore.get(settings.ListenBrainz.enabled)) { const oldData = ListenBrainzStore.get(ListenBrainzConstants.oldData) as StoreData; if ( - (!oldData && options.status === MediaStatus.playing) || - (oldData && oldData.title !== options.title) + (!oldData && mediaInfo.status === MediaStatus.playing) || + (oldData && oldData.title !== mediaInfo.title) ) { if (!scrobbleWaitingForDelay) { scrobbleWaitingForDelay = true; @@ -487,10 +488,10 @@ function updateListenBrainz(options: Options) { currentListenBrainzDelayId = setTimeout( () => { ListenBrainz.scrobble( - options.title, - options.artists, - options.status, - convertDuration(options.duration) + mediaInfo.title, + mediaInfo.artists, + mediaInfo.status, + convertDuration(mediaInfo.duration) ); scrobbleWaitingForDelay = false; }, @@ -547,20 +548,19 @@ setInterval(function () { if (repeatStateChanged) currentRepeatState = repeatState; skipArtistsIfFoundInSkippedArtistsList(artistsArray); - const album = elements.getAlbumName(); const duration = elements.getText("duration"); - const options = { + const options: MediaInfo = { title, artists: artistsString, album: album, + playingFrom: elements.getText("playing_from"), status: currentStatus, url: getTrackURL(), current, currentInSeconds: convertDurationToSeconds(current), duration, durationInSeconds: convertDurationToSeconds(duration), - "app-name": appName, image: "", icon: "", favorite: elements.isFavorite(), diff --git a/src/scripts/mediaInfo.ts b/src/scripts/mediaInfo.ts index 2fe4127..7352bce 100644 --- a/src/scripts/mediaInfo.ts +++ b/src/scripts/mediaInfo.ts @@ -2,12 +2,13 @@ import { MediaInfo } from "../models/mediaInfo"; import { MediaStatus } from "../models/mediaStatus"; import { RepeatState } from "../models/repeatState"; -export const mediaInfo = { +const defaultInfo: MediaInfo = { title: "", artists: "", album: "", icon: "", - status: MediaStatus.paused as string, + playingFrom: "", + status: MediaStatus.paused, url: "", current: "", currentInSeconds: 0, @@ -17,42 +18,19 @@ export const mediaInfo = { favorite: false, player: { - status: MediaStatus.paused as string, + status: MediaStatus.paused, shuffle: false, - repeat: RepeatState.off as string, + repeat: RepeatState.off, }, }; +export let mediaInfo: MediaInfo = { ...defaultInfo }; + export const updateMediaInfo = (arg: MediaInfo) => { - mediaInfo.title = propOrDefault(arg.title); - mediaInfo.artists = propOrDefault(arg.artists); - 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), - }; + mediaInfo = { ...defaultInfo, ...arg }; + mediaInfo.url = toUniversalUrl(mediaInfo.url); }; -/** - * 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 * @param url url to append the universal link syntax to