Remove recently played from music
This commit is contained in:
1 parent
90d61c48e2
commit
f5df946e0b
5 files changed
+7
-206
No files matched your search
@@ -121,13 +121,6 @@ export async function fetchRecentTracksPage(
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchNowPlaying(userName: string): Promise<PlayedTrack | null> {
|
||||
const { recenttracks } = await callLastfm<RawRecentTracks>('user.getrecenttracks', { user: userName, limit: '1' });
|
||||
const rawTracks = Array.isArray(recenttracks.track) ? recenttracks.track : [recenttracks.track];
|
||||
const nowPlayingRaw = rawTracks.find((raw) => raw['@attr']?.nowplaying === 'true');
|
||||
return nowPlayingRaw ? toPlayedTrack(nowPlayingRaw) : null;
|
||||
}
|
||||
|
||||
export async function fetchTrackImage(artist: string, track: string): Promise<string | null> {
|
||||
const { track: info } = await callLastfm<RawTrackInfo>('track.getinfo', { artist, track, autocorrect: '1' });
|
||||
return largestImage(info?.album?.image);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ListeningProfile, PlayedTrack } from '#lib/lastfm/types';
|
||||
import { fetchNowPlaying, fetchUserInfo, hasLastfmKey, type UserInfo } from './api';
|
||||
import type { ListeningProfile } from '#lib/lastfm/types';
|
||||
import { fetchUserInfo, hasLastfmKey, type UserInfo } from './api';
|
||||
import { loadScrobbleStore, storedScrobbles } from './store';
|
||||
import { coverFor, coversVersion, loadCovers, requestTrackCovers } from './covers';
|
||||
import { coversVersion, loadCovers, requestTrackCovers } from './covers';
|
||||
import { lastfmSyncedAt } from './sync';
|
||||
import {
|
||||
countsByDay,
|
||||
@@ -14,14 +14,11 @@ import {
|
||||
} from './trends';
|
||||
|
||||
const userInfoDuration = 30 * 60 * 1000;
|
||||
const nowPlayingDuration = 60 * 1000;
|
||||
const summaryDuration = 5 * 60 * 1000;
|
||||
const recentCount = 8;
|
||||
|
||||
type Summary = Omit<ListeningProfile, 'userName' | 'profileUrl' | 'registeredAt' | 'totals' | 'nowPlaying' | 'syncedAt'>;
|
||||
type Summary = Omit<ListeningProfile, 'userName' | 'profileUrl' | 'registeredAt' | 'totals' | 'syncedAt'>;
|
||||
|
||||
let userInfoCache: { info: UserInfo; fetchedAt: number } | null = null;
|
||||
let nowPlayingCache: { track: PlayedTrack | null; fetchedAt: number } | null = null;
|
||||
let summaryCache: { summary: Summary; scrobbleCount: number; coversVersion: number; builtAt: number } | null = null;
|
||||
|
||||
async function cachedUserInfo(userName: string): Promise<UserInfo | null> {
|
||||
@@ -34,27 +31,6 @@ async function cachedUserInfo(userName: string): Promise<UserInfo | null> {
|
||||
return userInfoCache?.info ?? null;
|
||||
}
|
||||
|
||||
async function cachedNowPlaying(userName: string): Promise<PlayedTrack | null> {
|
||||
if (nowPlayingCache && Date.now() - nowPlayingCache.fetchedAt < nowPlayingDuration) return nowPlayingCache.track;
|
||||
try {
|
||||
nowPlayingCache = { track: await fetchNowPlaying(userName), fetchedAt: Date.now() };
|
||||
} catch (error) {
|
||||
console.error('Last.fm now playing failed:', error instanceof Error ? error.message : error);
|
||||
}
|
||||
return nowPlayingCache?.track ?? null;
|
||||
}
|
||||
|
||||
function recentTracks(): PlayedTrack[] {
|
||||
return storedScrobbles()
|
||||
.slice(-recentCount)
|
||||
.reverse()
|
||||
.map((scrobble) => ({
|
||||
...scrobble,
|
||||
url: `https://www.last.fm/music/${encodeURIComponent(scrobble.artist)}/_/${encodeURIComponent(scrobble.track)}`,
|
||||
image: coverFor(scrobble.artist, scrobble.album, scrobble.track)
|
||||
}));
|
||||
}
|
||||
|
||||
function buildSummary(): Summary {
|
||||
const scrobbles = storedScrobbles();
|
||||
const nowSeconds = Math.floor(Date.now() / 1000);
|
||||
@@ -63,7 +39,6 @@ function buildSummary(): Summary {
|
||||
const streaks = listeningStreaks(dayCounts);
|
||||
|
||||
return {
|
||||
recentTracks: recentTracks(),
|
||||
daily,
|
||||
monthly: monthlyBuckets(dayCounts),
|
||||
hourly: hourlyBuckets(scrobbles),
|
||||
@@ -79,7 +54,6 @@ function buildSummary(): Summary {
|
||||
function tracksMissingCovers(summary: Summary) {
|
||||
return Object.values(summary.top)
|
||||
.flatMap((charts) => charts.tracks)
|
||||
.concat(summary.recentTracks.map((track) => ({ ...track, name: track.track, count: 0 })))
|
||||
.filter((item) => !item.image && item.artist)
|
||||
.map((item) => ({ artist: item.artist!, track: item.name }));
|
||||
}
|
||||
@@ -105,7 +79,7 @@ export async function getListeningProfile(userName: string): Promise<ListeningPr
|
||||
if (!hasLastfmKey()) return null;
|
||||
|
||||
await Promise.all([loadScrobbleStore(), loadCovers()]);
|
||||
const [info, nowPlaying] = await Promise.all([cachedUserInfo(userName), cachedNowPlaying(userName)]);
|
||||
const info = await cachedUserInfo(userName);
|
||||
if (!info && !storedScrobbles().length) return null;
|
||||
|
||||
const summary = cachedSummary();
|
||||
@@ -119,7 +93,6 @@ export async function getListeningProfile(userName: string): Promise<ListeningPr
|
||||
albums: info?.albums ?? 0,
|
||||
tracks: info?.tracks ?? 0
|
||||
},
|
||||
nowPlaying,
|
||||
syncedAt: lastfmSyncedAt(),
|
||||
...summary
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user