Skip to content

Commit

Permalink
Self populating TrackItemCache
Browse files Browse the repository at this point in the history
  • Loading branch information
Inrixia committed Jun 21, 2024
1 parent 29f204c commit 8422acb
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 34 deletions.
28 changes: 13 additions & 15 deletions lib/Caches/ExtendedTrackItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,46 @@ import { libTrace } from "../trace";

export class ExtendedTrackItem {
public readonly trackId: ItemId;
private _trackItem?: TrackItem;
public readonly trackItem: TrackItem;
private _album?: Album;
private _recording?: Recording;
private _releaseAlbum?: Release;

private static readonly _cache: Record<ItemId, ExtendedTrackItem> = {};

private constructor(trackId: ItemId) {
private constructor(trackId: ItemId, trackItem: TrackItem) {
this.trackId = trackId;
this.trackItem = trackItem;
}

public static get(trackId: ItemId) {
public static async get(trackId: ItemId) {
if (trackId === undefined) return undefined;
return this._cache[trackId] ?? (this._cache[trackId] = new this(trackId));
const trackItem = await TrackItemCache.ensure(trackId);
if (trackItem === undefined) return undefined;
return this._cache[trackId] ?? (this._cache[trackId] = new this(trackId, trackItem));
}
public async isrcs(): Promise<Set<string> | undefined> {
let isrcs = [];

const recording = await this.recording();
if (recording?.isrcs) isrcs.push(...recording.isrcs);

const trackItem = this.trackItem();
if (trackItem?.isrc) isrcs.push(trackItem.isrc);
const trackItem = this.trackItem;
if (trackItem.isrc) isrcs.push(trackItem.isrc);

return new Set(isrcs);
}
public trackItem(): TrackItem | undefined {
if (this._trackItem !== undefined) return this._trackItem;

return (this._trackItem = TrackItemCache.get(this.trackId));
}
public async album(): Promise<Album | undefined> {
if (this._album !== undefined) return this._album;
return (this._album = await AlbumCache.get(this.trackItem()?.album?.id));
return (this._album = await AlbumCache.get(this.trackItem.album?.id));
}
public async recording(): Promise<Recording | undefined> {
if (this._recording !== undefined) return this._recording;

this._recording = await MusicBrainz.getRecording(this.trackItem()?.isrc).catch(libTrace.warn.withContext("MusicBrainz.getRecording"));
this._recording = await MusicBrainz.getRecording(this.trackItem.isrc).catch(libTrace.warn.withContext("MusicBrainz.getRecording"));
if (this._recording !== undefined) return this._recording;

const trackItem = this.trackItem();
const trackItem = this.trackItem;
if (trackItem === undefined) return undefined;

const releaseAlbum = await this.releaseAlbum();
Expand All @@ -73,7 +71,7 @@ export class ExtendedTrackItem {

public async everything() {
return {
trackItem: this.trackItem(),
trackItem: this.trackItem,
album: await this.album(),
releaseAlbum: await this.releaseAlbum(),
recording: await this.recording(),
Expand Down
12 changes: 11 additions & 1 deletion lib/Caches/TrackItemCache.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { store } from "@neptune";
import type { TrackItem, MediaItem, ItemId } from "neptune-types/tidal";
import { interceptPromise } from "../intercept/interceptPromise";

export class TrackItemCache {
private static readonly _cache: Record<ItemId, TrackItem> = {};
public static get(trackId?: ItemId) {
public static async ensure(trackId?: ItemId) {
if (trackId === undefined) return undefined;

let mediaItem = this._cache[trackId];
Expand All @@ -16,6 +17,15 @@ export class TrackItemCache {
this._cache[itemId] = item;
}

if (this._cache[trackId] === undefined) {
const currentPage = window.location.pathname;
await interceptPromise(() => neptune.actions.router.replace(<any>`/track/${trackId}`), ["page/IS_DONE_LOADING"], []);
neptune.actions.router.replace(<any>currentPage);
const mediaItems: Record<number, MediaItem> = store.getState().content.mediaItems;
const trackItem = mediaItems[+trackId]?.item;
if (trackItem?.contentType === "track") this._cache[trackId] = trackItem;
}

return this._cache[trackId];
}
}
16 changes: 8 additions & 8 deletions plugins/LastFM/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const intercepters = [
.then((res) => trace.log("scrobbled", res));
});
} else {
const trackTitle = currentTrack.extTrackItem.trackItem()?.title;
const trackTitle = currentTrack.extTrackItem.trackItem.title;
const noScrobbleMessage = `skipped scrobbling ${trackTitle} - Listened for ${(totalPlayTime / 1000).toFixed(0)}s, need ${(minPlayTime / 1000).toFixed(0)}s`;
if (storage.displaySkippedScrobbles) trace.msg.log(`${noScrobbleMessage}`);
}
Expand All @@ -90,13 +90,13 @@ const getTrackParams = async ({ extTrackItem, playbackContext, playbackStart }:
const { trackItem, releaseAlbum, recording, album } = await extTrackItem.everything();

let artist;
const sharedAlbumArtist = trackItem?.artists?.find((artist) => artist?.id === album?.artist?.id);
const sharedAlbumArtist = trackItem.artists?.find((artist) => artist?.id === album?.artist?.id);
if (sharedAlbumArtist?.name !== undefined) artist = formatArtists([sharedAlbumArtist.name]);
else if (trackItem?.artist?.name !== undefined) artist = formatArtists([trackItem.artist.name]);
else if ((trackItem?.artists?.length ?? -1) > 0) artist = formatArtists(trackItem?.artists?.map(({ name }) => name));
else if (trackItem.artist?.name !== undefined) artist = formatArtists([trackItem.artist.name]);
else if ((trackItem.artists?.length ?? -1) > 0) artist = formatArtists(trackItem.artists?.map(({ name }) => name));

const params: ScrobbleOpts = {
track: recording?.title ?? fullTitle(<TrackItem>trackItem),
track: recording?.title ?? fullTitle(trackItem),
artist: artist!,
timestamp: (playbackStart / 1000).toFixed(0),
};
Expand All @@ -109,9 +109,9 @@ const getTrackParams = async ({ extTrackItem, playbackContext, playbackStart }:
if (!!releaseAlbum?.title) {
params.album = releaseAlbum?.title;
if (!!releaseAlbum.disambiguation) params.album += ` (${releaseAlbum.disambiguation})`;
} else if (!!trackItem?.album?.title) params.album = trackItem.album.title;
} else if (!!trackItem.album?.title) params.album = trackItem.album.title;

if (!!trackItem?.trackNumber) params.trackNumber = trackItem.trackNumber.toString();
if (!!trackItem.trackNumber) params.trackNumber = trackItem.trackNumber.toString();
if (!!playbackContext.actualDuration) params.duration = playbackContext.actualDuration.toFixed(0);

return params;
Expand All @@ -131,7 +131,7 @@ const getCurrentTrack = async (playbackContext?: PlaybackContext): Promise<Curre
playbackContext ??= <PlaybackContext>store.getState().playbackControls.playbackContext;
if (!playbackContext) throw new Error("No playbackContext found");

const extTrackItem = ExtendedTrackItem.get(playbackContext.actualProductId);
const extTrackItem = await ExtendedTrackItem.get(playbackContext.actualProductId);
if (extTrackItem === undefined) throw new Error("Failed to get extTrackItem");

const currentTrack = { extTrackItem, playbackContext, playbackStart };
Expand Down
11 changes: 3 additions & 8 deletions plugins/RealMAX/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MaxTrack {
if (idMapping !== undefined) return idMapping;

const extTrackItem = await ExtendedTrackItem.get(itemId);
const trackItem = extTrackItem?.trackItem();
const trackItem = extTrackItem?.trackItem;
if (trackItem !== undefined && hasHiRes(trackItem)) return false;

const isrcs = await extTrackItem?.isrcs();
Expand All @@ -39,7 +39,7 @@ class MaxTrack {
for await (const { resource } of fetchIsrcIterable(isrc)) {
if (resource?.id !== undefined && hasHiRes(<TrackItem>resource)) {
if (resource.artifactType !== "track") continue;
const maxTrackItem = TrackItemCache.get(resource?.id);
const maxTrackItem = await TrackItemCache.ensure(resource?.id);
if (maxTrackItem !== undefined && !hasHiRes(maxTrackItem)) continue;
else return resource;
}
Expand All @@ -60,12 +60,7 @@ export const onUnload = intercept(
const maxItem = await MaxTrack.getMaxId(queueId);
if (maxItem === false) return;
if (maxItem.id !== undefined && nextQueueId !== maxItem.id) {
if (TrackItemCache.get(maxItem.id) === undefined) {
// Force load
const currentPage = window.location.pathname;
actions.router.replace(<any>`/album/${maxItem.album!.id}`);
setTimeout(() => actions.router.replace(<any>currentPage), 50);
}
await TrackItemCache.ensure(maxItem.id);
trace.msg.log(`Found Max quality for ${maxItem.title}! Adding to queue and skipping...`);
actions.playQueue.addNext({ mediaItemIds: [maxItem.id], context: { type: "user" } });
actions.playQueue.moveNext();
Expand Down
4 changes: 3 additions & 1 deletion plugins/SongDownloader/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ const onPlaylist = async (playlistUUID: ItemId) => {
};

const queueMediaIds = (mediaIds: ItemId[]) => {
downloadItems(mediaIds.map((mediaId) => TrackItemCache.get(mediaId)).filter((item) => item !== undefined));
Promise.all(mediaIds.map(TrackItemCache.ensure))
.then((tracks) => tracks.filter((item) => item !== undefined))
.then(downloadItems);
};

const downloadItems = (items: (TrackItem | VideoItem)[]) =>
Expand Down
2 changes: 1 addition & 1 deletion plugins/TidalTags/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const updateTrackRows = async (trackRows: NodeListOf<Element>) => {
const trackId = trackRow.getAttribute("data-track-id");
if (trackId == null) return;

const trackItem = TrackItemCache.get(trackId);
const trackItem = await TrackItemCache.ensure(trackId);
if (trackItem?.contentType !== "track") continue;

if (storage.showTags) setQualityTags(trackRow, trackId, trackItem);
Expand Down

0 comments on commit 8422acb

Please sign in to comment.