Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Track.artist and Track.extraArtists with Track.artists #1681

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions packages/app/app/actions/downloads.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import _ from 'lodash';
import { isEqual } from 'lodash';
import { store, StreamProvider } from '@nuclear/core';
import { getTrackItem } from '@nuclear/ui';
import { safeAddUuid } from './helpers';
import { rewriteTrackArtists, safeAddUuid } from './helpers';
import { Download, DownloadStatus, Track, TrackItem } from '@nuclear/ui/lib/types';
import { createStandardAction } from 'typesafe-actions';
import { Download as DownloadActionTypes } from './actionTypes';
Expand All @@ -24,19 +25,19 @@ const changePropertyForItem = ({downloads, uuid, propertyName='status', value}:C

export const readDownloads = createStandardAction(DownloadActionTypes.READ_DOWNLOADS).map(
() => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
return { payload: downloads };
}
);

export const addToDownloads = createStandardAction(DownloadActionTypes.ADD_TO_DOWNLOADS).map(
(_:StreamProvider[], track: Track) => {
const clonedTrack: TrackItem = safeAddUuid(getTrackItem(track));
let downloads: Download[] = store.get('downloads');
let downloads: Download[] = getDownloadsBackwardsCompatible();

const existingTrack = downloads.find(({track}) => {
const {name, artist} = track;
return artist === clonedTrack.artist && name === clonedTrack.name;
const {name, artists} = track;
return isEqual(artists, clonedTrack.artists) && name === clonedTrack.name;
});

if (!existingTrack ){
Expand All @@ -60,7 +61,7 @@ export const addToDownloads = createStandardAction(DownloadActionTypes.ADD_TO_DO

export const onDownloadStarted = createStandardAction(DownloadActionTypes.DOWNLOAD_STARTED).map(
(uuid: string) => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
const payload = changePropertyForItem({
downloads,
uuid,
Expand All @@ -73,7 +74,7 @@ export const onDownloadStarted = createStandardAction(DownloadActionTypes.DOWNLO

export const onDownloadPause = createStandardAction(DownloadActionTypes.DOWNLOAD_PAUSED).map(
(uuid: string) => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
const payload = changePropertyForItem({
downloads,
uuid,
Expand All @@ -86,7 +87,7 @@ export const onDownloadPause = createStandardAction(DownloadActionTypes.DOWNLOA

export const onDownloadResume = createStandardAction(DownloadActionTypes.DOWNLOAD_RESUMED).map(
(uuid: string) => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
const payload = changePropertyForItem({
downloads,
uuid,
Expand Down Expand Up @@ -131,7 +132,7 @@ export const onDownloadProgress = createStandardAction(DownloadActionTypes.DOWNL

export const onDownloadError = createStandardAction(DownloadActionTypes.DOWNLOAD_ERROR).map(
(uuid: string) => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
const payload = changePropertyForItem({
downloads,
uuid,
Expand All @@ -146,7 +147,7 @@ export const onDownloadError = createStandardAction(DownloadActionTypes.DOWNLOAD

export const onDownloadRemoved = createStandardAction(DownloadActionTypes.DOWNLOAD_REMOVED).map(
(uuid: string) => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
const filteredTracks = downloads.filter(item => item.track.uuid !== uuid);
return {
payload: filteredTracks
Expand All @@ -155,7 +156,7 @@ export const onDownloadRemoved = createStandardAction(DownloadActionTypes.DOWNLO

export const onDownloadFinished = createStandardAction(DownloadActionTypes.DOWNLOAD_FINISHED).map(
(uuid: string) => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();
const payload = changePropertyForItem({
downloads,
uuid,
Expand All @@ -169,7 +170,7 @@ export const onDownloadFinished = createStandardAction(DownloadActionTypes.DOWNL

export const clearFinishedDownloads = createStandardAction(DownloadActionTypes.CLEAR_FINISHED_DOWNLOADS).map(
() => {
const downloads: Download[] = store.get('downloads');
const downloads: Download[] = getDownloadsBackwardsCompatible();

const filteredTracks = downloads.filter(( item ) =>
item.status !== DownloadStatus.FINISHED && item.status !== DownloadStatus.ERROR
Expand All @@ -180,6 +181,19 @@ export const clearFinishedDownloads = createStandardAction(DownloadActionTypes.C
};
});

/**
* Helper function to read the old track format into the new format.
*
* `Track.artist` and `Track.extraArtists` are written into {@link Track.artists}
*/
function getDownloadsBackwardsCompatible(): Download[] {
const downloads: Download[] = store.get('downloads');
return downloads.map(download => ({
...download,
track: rewriteTrackArtists(download.track)
}));
}

export const resumeDownloads = createStandardAction(DownloadActionTypes.RESUME_DOWNLOADS).map(
() => {
const downloads: Download[] = store.get('downloads');
Expand Down
53 changes: 39 additions & 14 deletions packages/app/app/actions/favorites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ import _, { flow, omit, unionWith } from 'lodash';
import { store, Track } from '@nuclear/core';
import { areTracksEqualByName, getTrackItem } from '@nuclear/ui';

import { safeAddUuid } from './helpers';
import { rewriteTrackArtists, safeAddUuid } from './helpers';
import { createStandardAction } from 'typesafe-actions';

export type FavoriteArtist = {
id: string;
name: string;
source: string;
coverImage: string;
thumb: string;
}

export const READ_FAVORITES = 'READ_FAVORITES';
export const ADD_FAVORITE_TRACK = 'ADD_FAVORITE_TRACK';
export const REMOVE_FAVORITE_TRACK = 'REMOVE_FAVORITE_TRACK';
Expand All @@ -17,7 +25,7 @@ export const ADD_FAVORITE_ARTIST = 'ADD_FAVORITE_ARTIST';
export const REMOVE_FAVORITE_ARTIST = 'REMOVE_FAVORITE_ARTIST';

export function readFavorites() {
const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
return {
type: READ_FAVORITES,
payload: favorites
Expand All @@ -27,10 +35,10 @@ export function readFavorites() {
export function addFavoriteTrack(track) {
const clonedTrack = flow(safeAddUuid, getTrackItem)(track);

const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
const filteredTracks = favorites.tracks.filter(t => !areTracksEqualByName(t, track));
favorites.tracks = [...filteredTracks, omit(clonedTrack, 'streams')];

favorites.tracks = [...filteredTracks, omit(clonedTrack, 'streams')];
store.set('favorites', favorites);

return {
Expand All @@ -39,18 +47,18 @@ export function addFavoriteTrack(track) {
};
}

const bulkAddFavoriteTracksAction = createStandardAction(BULK_ADD_FAVORITE_TRACKS)<Track[]>();
const bulkAddFavoriteTracksAction = createStandardAction(BULK_ADD_FAVORITE_TRACKS)<ReturnType<typeof getFavoritesBackwardsCompatible>>();

export const bulkAddFavoriteTracks = (tracks: Track[]) => {
const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
favorites.tracks = unionWith(favorites.tracks, tracks, areTracksEqualByName);
store.set('favorites', favorites);

return bulkAddFavoriteTracksAction(favorites);
};

export function removeFavoriteTrack(track) {
const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
favorites.tracks = favorites.tracks.filter(t => !areTracksEqualByName(t, track));

store.set('favorites', favorites);
Expand All @@ -62,7 +70,7 @@ export function removeFavoriteTrack(track) {
}

export function addFavoriteAlbum(album) {
const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
favorites.albums = _.concat(favorites.albums, album);
store.set('favorites', favorites);

Expand All @@ -73,7 +81,7 @@ export function addFavoriteAlbum(album) {
}

export function removeFavoriteAlbum(album) {
const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
_.remove(favorites.albums, {
artist: album.artist,
title: album.title
Expand All @@ -86,9 +94,8 @@ export function removeFavoriteAlbum(album) {
};
}

export function addFavoriteArtist(artist) {

const favorites = store.get('favorites');
export function addFavoriteArtist(artist: FavoriteArtist) {
const favorites = getFavoritesBackwardsCompatible();
const savedArtist = {
id: artist.id,
name: artist.name,
Expand All @@ -97,7 +104,7 @@ export function addFavoriteArtist(artist) {
thumb: artist.thumb
};

favorites.artists = _.concat(favorites.artists || [], savedArtist);
favorites.artists = [...(favorites.artists ?? []), savedArtist];
store.set('favorites', favorites);

return {
Expand All @@ -107,7 +114,7 @@ export function addFavoriteArtist(artist) {
}

export function removeFavoriteArtist(artist) {
const favorites = store.get('favorites');
const favorites = getFavoritesBackwardsCompatible();
_.remove(favorites.artists, {
id: artist.id,
name: artist.name
Expand All @@ -119,3 +126,21 @@ export function removeFavoriteArtist(artist) {
payload: favorites
};
}

/**
* Helper function to read the old track format into the new format.
*
* `Track.artist` and `Track.extraArtists` are written into {@link Track.artists}
*/
function getFavoritesBackwardsCompatible() {
const favorites = store.get('favorites');

return {
...favorites,
tracks: favorites.tracks?.map(rewriteTrackArtists),
albums: favorites.albums?.map(album => ({
...album,
tracklist: album.tracklist?.map(rewriteTrackArtists)
}))
};
}
18 changes: 18 additions & 0 deletions packages/app/app/actions/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { v4 } from 'uuid';
import _ from 'lodash';
import { createAction } from 'redux-actions';
import { PlaylistTrack, Track } from '@nuclear/core';
import { TrackItem } from '@nuclear/ui/lib/types';

type ActionsBasicType = {
[k: string]: (...payload: any) => any;
Expand All @@ -22,3 +24,19 @@ export const safeAddUuid = track => {

return clonedTrack;
};

export function rewriteTrackArtists<T extends PlaylistTrack | Track | TrackItem>(track: T): T {
const clonedTrack = _.cloneDeep(track);

// @ts-expect-error For backwards compatibility we're trying to parse an invalid field
if (clonedTrack.artists || !clonedTrack.artist) {
return clonedTrack;
}

// @ts-expect-error For backwards compatibility we're trying to parse an invalid field
clonedTrack.artists = _.isString(clonedTrack.artist) ? [clonedTrack.artist] : [clonedTrack.artist.name];
// @ts-expect-error For backwards compatibility we're trying to parse an invalid field
clonedTrack.artists = clonedTrack.artists.concat(clonedTrack.extraArtists?.map(artist));

return clonedTrack;
}
2 changes: 1 addition & 1 deletion packages/app/app/actions/lyrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function lyricsSearch(track: Track) {
const selectedProvider = getState().plugin.selected.lyricsProviders;
const lyricsProvider = _.find(providers, {sourceName: selectedProvider});

lyricsProvider.search(track.artist, track.name)
lyricsProvider.search(track.artists?.[0], track.name)
.then(result => {
dispatch(lyricsSearchSuccess(result));
})
Expand Down
22 changes: 19 additions & 3 deletions packages/app/app/actions/playlists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { v4 } from 'uuid';
import { remote } from 'electron';
import { createAsyncAction, createStandardAction } from 'typesafe-actions';

import { store, PlaylistHelper, Playlist, PlaylistTrack, rest } from '@nuclear/core';
import { store, PlaylistHelper, Playlist, PlaylistTrack, Track, rest } from '@nuclear/core';
import { GetPlaylistsByUserIdResponseBody } from '@nuclear/core/src/rest/Nuclear/Playlists.types';
import { ErrorBody } from '@nuclear/core/src/rest/Nuclear/types';

Expand All @@ -18,6 +18,7 @@ import { success, error } from './toasts';
import { IdentityStore } from '../reducers/nuclear/identity';
import { PlaylistsStore } from '../reducers/playlists';
import { isEmpty } from 'lodash';
import { rewriteTrackArtists } from './helpers';

export const updatePlaylistsAction = createStandardAction(Playlists.UPDATE_LOCAL_PLAYLISTS)<PlaylistsStore['localPlaylists']['data']>();

Expand Down Expand Up @@ -55,7 +56,7 @@ export const loadLocalPlaylists = () => dispatch => {
dispatch(loadLocalPlaylistsAction.request());

try {
const playlists: Playlist[] = store.get('playlists');
const playlists: Playlist[] = getPlaylistsBackwardsCompatible();
dispatch(loadLocalPlaylistsAction.success(isEmpty(playlists) ? [] : playlists));
} catch (error) {
dispatch(loadLocalPlaylistsAction.failure());
Expand Down Expand Up @@ -147,7 +148,7 @@ export function addPlaylistFromFile(filePath, t) {
throw new Error('missing tracks or name');
}

let playlists = store.get('playlists') || [];
let playlists = getPlaylistsBackwardsCompatible() || [];
const playlist = PlaylistHelper.formatPlaylistForStorage(name, tracks, v4(), source);

if (!(tracks?.length > 0)) {
Expand All @@ -167,3 +168,18 @@ export function addPlaylistFromFile(filePath, t) {
});
};
}

/**
* Helper function to read the old track format into the new format.
*
* `Track.artist` and `Track.extraArtists` are written into {@link Track.artists}
*/
function getPlaylistsBackwardsCompatible(): Playlist[] {
const playlists: Playlist[] = store.get('playlists');
return playlists.map(playlist => {
return {
...playlist,
tracks: playlist.tracks?.map(rewriteTrackArtists)
};
});
}
2 changes: 1 addition & 1 deletion packages/app/app/actions/queue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('Queue actions tests', () => {
const trackIndex = 123;
const queueItems: QueueItem[] = [];
queueItems[trackIndex] = {
artist: 'Artist Name',
artists: ['Artist Name'],
name: 'Track Name',
local: false,
streams: null
Expand Down
10 changes: 5 additions & 5 deletions packages/app/app/actions/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createStandardAction } from 'typesafe-actions';
import { v4 } from 'uuid';

import { rest, StreamProvider } from '@nuclear/core';
import { getTrackArtist } from '@nuclear/ui';
import { getTrackArtists } from '@nuclear/ui';
import { Track } from '@nuclear/ui/lib/types';

import { safeAddUuid } from './helpers';
Expand Down Expand Up @@ -46,7 +46,7 @@ const localTrackToQueueItem = (track: LocalTrack, local: LocalLibraryState): Que

export const toQueueItem = (track: Track): QueueItem => ({
...track,
artist: isString(track.artist) ? track.artist : track.artist.name,
artists: track.artists,
name: track.title ? track.title : track.name,
streams: track.streams ?? []
});
Expand All @@ -72,7 +72,7 @@ export const resolveTrackStreams = async (
return track.streams.filter((stream) => stream.source === 'Local');
} else {
return selectedStreamProvider.search({
artist: getTrackArtist(track),
artist: getTrackArtists(track)?.[0],
track: track.name
});
}
Expand Down Expand Up @@ -186,7 +186,7 @@ export const findStreamsForTrack = (index: number) => async (dispatch, getState)
try {
const StreamMappingsService = new rest.NuclearStreamMappingsService(process.env.NUCLEAR_VERIFICATION_SERVICE_URL);
const topStream = await StreamMappingsService.getTopStream(
track.artist,
track.artists?.[0],
track.name,
selectedStreamProvider.sourceName,
settings?.userId
Expand Down Expand Up @@ -226,7 +226,7 @@ export const findStreamsForTrack = (index: number) => async (dispatch, getState)
}
} catch (e) {
logger.error(
`An error has occurred when searching for streams with ${selectedStreamProvider.sourceName} for "${track.artist} - ${track.name}."`
`An error has occurred when searching for streams with ${selectedStreamProvider.sourceName} for "${track.artists?.[0]} - ${track.name}."`
);
logger.error(e);
dispatch(
Expand Down
Loading
Loading