From bcfc355aec18b2b030cb0b7d8673b5859619d734 Mon Sep 17 00:00:00 2001 From: Lucki Date: Wed, 21 Aug 2024 02:26:08 +0200 Subject: [PATCH] Adjust reading the config into the new format --- packages/app/app/actions/downloads.ts | 51 +++++++++++++++++----- packages/app/app/actions/favorites.ts | 61 +++++++++++++++++++++++---- packages/app/app/actions/playlists.ts | 35 ++++++++++++++- 3 files changed, 127 insertions(+), 20 deletions(-) diff --git a/packages/app/app/actions/downloads.ts b/packages/app/app/actions/downloads.ts index af9d5fb86a..e15e1add46 100644 --- a/packages/app/app/actions/downloads.ts +++ b/packages/app/app/actions/downloads.ts @@ -24,7 +24,7 @@ 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 }; } ); @@ -32,7 +32,7 @@ export const readDownloads = createStandardAction(DownloadActionTypes.READ_DOWNL 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, artists} = track; @@ -60,7 +60,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, @@ -73,7 +73,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, @@ -86,7 +86,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, @@ -101,7 +101,7 @@ export const onDownloadResume = createStandardAction(DownloadActionTypes.DOWNLOA export const onDownloadProgress = createStandardAction(DownloadActionTypes.DOWNLOAD_PROGRESS).map( (uuid: string, progress: number) => { - const downloads = store.get('downloads'); + const downloads = getDownloadsBackwardsCompatible(); let payload = changePropertyForItem({ downloads, uuid, @@ -122,7 +122,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, @@ -137,7 +137,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 @@ -146,7 +146,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, @@ -160,7 +160,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 @@ -170,3 +170,34 @@ export const clearFinishedDownloads = createStandardAction(DownloadActionTypes.C payload: filteredTracks }; }); + +/** +* 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'); + + downloads.forEach(download => { + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + if (download.track.artists || !download.track.artist) { + return; + } + + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + if (download.track.artist) { + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + download.track.artists = _.isString(download.track.artist) ? [download.track.artist] : [download.track.artist.name]; + } + + // Assuming we have `extraArtists` on a track, we must had an `artist` which + // was already saved into `artists`, so this `track.artists` shouldn't be undefined + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + download.track.extraArtists?.forEach(artist => { + download.track.artists.push(artist); + }); + }); + + return downloads; +} diff --git a/packages/app/app/actions/favorites.ts b/packages/app/app/actions/favorites.ts index 1fb8f246ca..7e4f91f314 100644 --- a/packages/app/app/actions/favorites.ts +++ b/packages/app/app/actions/favorites.ts @@ -17,7 +17,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 @@ -27,7 +27,7 @@ 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')]; @@ -42,7 +42,7 @@ export function addFavoriteTrack(track) { const bulkAddFavoriteTracksAction = createStandardAction(BULK_ADD_FAVORITE_TRACKS)(); export const bulkAddFavoriteTracks = (tracks: Track[]) => { - const favorites = store.get('favorites'); + const favorites = getFavoritesBackwardsCompatible(); favorites.tracks = unionWith(favorites.tracks, tracks, areTracksEqualByName); store.set('favorites', favorites); @@ -50,7 +50,7 @@ export const bulkAddFavoriteTracks = (tracks: Track[]) => { }; 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); @@ -62,7 +62,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); @@ -73,7 +73,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 @@ -88,7 +88,7 @@ export function removeFavoriteAlbum(album) { export function addFavoriteArtist(artist) { - const favorites = store.get('favorites'); + const favorites = getFavoritesBackwardsCompatible(); const savedArtist = { id: artist.id, name: artist.name, @@ -107,7 +107,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 @@ -119,3 +119,48 @@ 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'); + + favorites.tracks?.forEach(track => { + if (track.artists || !track.artist) { + return; + } + + if (track.artist) { + track.artists = _.isString(track.artist) ? [track.artist] : [track.artist.name]; + } + + // Assuming we have `extraArtists` on a track, we must had an `artist` which + // was already saved into `artists`, so this `track.artists` shouldn't be undefined + track.extraArtists?.forEach(artist => { + track.artists.push(artist); + }); + }); + + favorites.albums?.forEach(album => { + album.tracklist?.forEach(track => { + if (track.artists || !track.artist) { + return; + } + + if (track.artist) { + track.artists = _.isString(track.artist) ? [track.artist] : [track.artist.name]; + } + + // Assuming we have `extraArtists` on a track, we must had an `artist` which + // was already saved into `artists`, so this `track.artists` shouldn't be undefined + track.extraArtists?.forEach(artist => { + track.artists.push(artist); + }); + }); + }); + + return favorites; +} diff --git a/packages/app/app/actions/playlists.ts b/packages/app/app/actions/playlists.ts index 6b0f2ce14c..de806eea0b 100644 --- a/packages/app/app/actions/playlists.ts +++ b/packages/app/app/actions/playlists.ts @@ -55,7 +55,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()); @@ -147,7 +147,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)) { @@ -167,3 +167,34 @@ 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'); + + playlists?.forEach(playlist => { + playlist.tracks?.forEach(track => { + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + if (track.artists || !track.artist) { + // New format already present, do nothing + return; + } + + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + track.artists = _.isString(track.artist) ? [track.artist] : [track.artist.name]; + + // Assuming we have `extraArtists` on a track, we must had an `artist` which + // was already saved into `artists`, so this `track.artists` shouldn't be undefined + // @ts-expect-error For backwards compatibility we're trying to parse an invalid field + track.extraArtists?.forEach(artist => { + track.artists.push(artist); + }); + }); + }); + + return playlists; +}