Show track duration in activity when enabled
- Add track duration to activity large_text when showTimestamp is true - Fetch track duration from Last.fm API and calculate end time - Change Last.fm API base URL to use http instead of https
This commit is contained in:
parent
c325b7d4be
commit
e70872d84d
3 changed files with 44 additions and 5 deletions
|
|
@ -10,7 +10,7 @@ const Constants = {
|
||||||
/** Retry delay in milliseconds */
|
/** Retry delay in milliseconds */
|
||||||
RETRY_DELAY: 5000,
|
RETRY_DELAY: 5000,
|
||||||
/** Base URL for Last.fm API */
|
/** Base URL for Last.fm API */
|
||||||
LFM_API_BASE_URL: "https://ws.audioscrobbler.com/2.0",
|
LFM_API_BASE_URL: "http://ws.audioscrobbler.com/2.0",
|
||||||
/** These are the default album covers that are used by Last.fm */
|
/** These are the default album covers that are used by Last.fm */
|
||||||
LFM_DEFAULT_COVER_HASHES: [
|
LFM_DEFAULT_COVER_HASHES: [
|
||||||
"2a96cbd8b46e442fc41c2b86b821562f",
|
"2a96cbd8b46e442fc41c2b86b821562f",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@ import Constants from "./constants";
|
||||||
import { SelfPresenceStore } from "./modules";
|
import { SelfPresenceStore } from "./modules";
|
||||||
import { clearActivity, fetchAsset, sendRequest } from "./utils/activity";
|
import { clearActivity, fetchAsset, sendRequest } from "./utils/activity";
|
||||||
import { setDebugInfo } from "./utils/debug";
|
import { setDebugInfo } from "./utils/debug";
|
||||||
|
|
||||||
|
function formatTime(seconds: number): string {
|
||||||
|
const minutes = Math.floor(seconds / 60);
|
||||||
|
const remainingSeconds = Math.floor(seconds % 60);
|
||||||
|
return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
|
||||||
|
}
|
||||||
import { lastfmClient } from "./utils/lastfm";
|
import { lastfmClient } from "./utils/lastfm";
|
||||||
|
|
||||||
enum ActivityType {
|
enum ActivityType {
|
||||||
|
|
@ -116,7 +122,11 @@ class PluginManager {
|
||||||
if (asset[0]) {
|
if (asset[0]) {
|
||||||
activity.assets = {
|
activity.assets = {
|
||||||
large_image: asset[0],
|
large_image: asset[0],
|
||||||
large_text: `on ${lastTrack.album}`,
|
large_text: `on ${lastTrack.album}${
|
||||||
|
currentSettings.showTimestamp && lastTrack.to
|
||||||
|
? ` • ${formatTime((lastTrack.to - lastTrack.from) / 1000)}`
|
||||||
|
: ""
|
||||||
|
}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ interface LastFMResponse {
|
||||||
recenttracks?: {
|
recenttracks?: {
|
||||||
track: LastFMTrack[];
|
track: LastFMTrack[];
|
||||||
};
|
};
|
||||||
|
track?: {
|
||||||
|
duration: string;
|
||||||
|
};
|
||||||
error?: number;
|
error?: number;
|
||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +105,9 @@ class LastFMClient {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchLatestScrobble(): Promise<Track> {
|
public async fetchLatestScrobble(): Promise<
|
||||||
|
Track & { from: number; to: number | null }
|
||||||
|
> {
|
||||||
try {
|
try {
|
||||||
this.validateSettings();
|
this.validateSettings();
|
||||||
|
|
||||||
|
|
@ -123,6 +128,28 @@ class LastFMClient {
|
||||||
// Reset retry count on successful request
|
// Reset retry count on successful request
|
||||||
this.retryCount = 0;
|
this.retryCount = 0;
|
||||||
|
|
||||||
|
const isNowPlaying = Boolean(lastTrack["@attr"]?.nowplaying);
|
||||||
|
const from = isNowPlaying
|
||||||
|
? Math.floor(Date.now() / 1000)
|
||||||
|
: parseInt(lastTrack?.date?.uts);
|
||||||
|
|
||||||
|
let to: number | null = null;
|
||||||
|
try {
|
||||||
|
const trackInfo = await this.makeRequest({
|
||||||
|
method: "track.getInfo",
|
||||||
|
track: lastTrack.name,
|
||||||
|
artist: lastTrack.artist.name,
|
||||||
|
username: currentSettings.username,
|
||||||
|
});
|
||||||
|
|
||||||
|
const duration = parseInt(trackInfo?.track?.duration);
|
||||||
|
if (duration > 0) {
|
||||||
|
to = from + Math.floor(duration / 1000);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("Failed to fetch track duration", err);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: lastTrack.name,
|
name: lastTrack.name,
|
||||||
artist: lastTrack.artist.name,
|
artist: lastTrack.artist.name,
|
||||||
|
|
@ -132,9 +159,11 @@ class LastFMClient {
|
||||||
),
|
),
|
||||||
url: lastTrack.url,
|
url: lastTrack.url,
|
||||||
date: lastTrack.date?.["#text"] ?? "now",
|
date: lastTrack.date?.["#text"] ?? "now",
|
||||||
nowPlaying: Boolean(lastTrack["@attr"]?.nowplaying),
|
nowPlaying: isNowPlaying,
|
||||||
loved: lastTrack.loved === "1",
|
loved: lastTrack.loved === "1",
|
||||||
} as Track;
|
from,
|
||||||
|
to,
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Increment retry count and throw if we've exceeded max retries
|
// Increment retry count and throw if we've exceeded max retries
|
||||||
this.retryCount++;
|
this.retryCount++;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue