diff --git a/packages/common/src/models/PlaylistLibrary.ts b/packages/common/src/models/PlaylistLibrary.ts index 66b4ad2bc7..ca09c7d25b 100644 --- a/packages/common/src/models/PlaylistLibrary.ts +++ b/packages/common/src/models/PlaylistLibrary.ts @@ -24,17 +24,10 @@ export type AudioNftPlaylistIdentifier = { playlist_id: SmartCollectionVariant.AUDIO_NFT_PLAYLIST } -// Never written to backends -export type TempPlaylistIdentifier = { - type: 'temp_playlist' - playlist_id: string -} - export type PlaylistLibraryIdentifier = | PlaylistIdentifier | ExplorePlaylistIdentifier | AudioNftPlaylistIdentifier - | TempPlaylistIdentifier export type PlaylistLibraryFolder = { id: string diff --git a/packages/common/src/store/playlist-library/helpers.test.js b/packages/common/src/store/playlist-library/helpers.test.js index 0ce1672149..51ffda2488 100644 --- a/packages/common/src/store/playlist-library/helpers.test.js +++ b/packages/common/src/store/playlist-library/helpers.test.js @@ -1,6 +1,5 @@ import { addFolderToLibrary, - containsTempPlaylist, findIndexInPlaylistLibrary, findInPlaylistLibrary, removeFromPlaylistLibrary, @@ -9,8 +8,6 @@ import { renamePlaylistFolderInLibrary, reorderPlaylistLibrary, addPlaylistToFolder, - extractTempPlaylistsFromLibrary, - replaceTempWithResolvedPlaylists, getPlaylistsNotInLibrary } from './helpers' @@ -127,15 +124,13 @@ describe('findIndexInPlaylistLibrary', () => { contents: [ { type: 'playlist', playlist_id: 7 }, { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: '33' }, { type: 'folder', name: 'favorites 2', id: 'fake-uuid-2', contents: [ { type: 'playlist', playlist_id: 11 }, - { type: 'playlist', playlist_id: 12 }, - { type: 'temp_playlist', playlist_id: 13 } + { type: 'playlist', playlist_id: 12 } ] } ] @@ -166,15 +161,13 @@ describe('findIndexInPlaylistLibrary', () => { contents: [ { type: 'playlist', playlist_id: 7 }, { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: '33' }, { type: 'folder', name: 'favorites 2', id: 'fake-uuid-2', contents: [ { type: 'playlist', playlist_id: 11 }, - { type: 'playlist', playlist_id: 12 }, - { type: 'temp_playlist', playlist_id: 13 } + { type: 'playlist', playlist_id: 12 } ] } ] @@ -489,7 +482,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -508,7 +500,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -530,7 +521,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -549,7 +539,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -568,7 +557,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -588,7 +576,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -608,7 +595,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -622,7 +608,6 @@ describe('reorderPlaylistLibrary', () => { contents: [ { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, - { type: 'temp_playlist', playlist_id: '10' }, { type: 'folder', name: 'favorites', @@ -648,7 +633,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -668,7 +652,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -688,7 +671,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -698,7 +680,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites 2', id: 'my-uuid-2', contents: [ - { type: 'temp_playlist', playlist_id: '100' }, { type: 'explore_playlist', playlist_id: 'Best New Releases' }, { type: 'playlist', playlist_id: 120 } ] @@ -718,7 +699,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -728,7 +708,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites 2', id: 'my-uuid-2', contents: [ - { type: 'temp_playlist', playlist_id: '100' }, { type: 'explore_playlist', playlist_id: 'Best New Releases' }, { type: 'playlist', playlist_id: 120 } ] @@ -748,8 +727,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, - { type: 'temp_playlist', playlist_id: '100' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -778,7 +755,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -797,7 +773,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'playlist', playlist_id: 12 }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' } ] @@ -819,7 +794,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -838,7 +812,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -858,7 +831,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -878,7 +850,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -897,7 +868,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 22 }, { type: 'playlist', playlist_id: 12 } @@ -919,7 +889,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -947,7 +916,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -975,7 +943,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -997,7 +964,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1020,7 +986,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1041,7 +1006,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1060,7 +1024,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1080,7 +1043,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1100,7 +1062,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1142,7 +1103,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1169,7 +1129,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1191,7 +1150,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1223,7 +1181,6 @@ describe('reorderPlaylistLibrary', () => { name: 'favorites', id: 'my-uuid', contents: [ - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1252,7 +1209,6 @@ describe('reorderPlaylistLibrary', () => { id: 'my-uuid', contents: [ { type: 'playlist', playlist_id: 1 }, - { type: 'temp_playlist', playlist_id: '10' }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, { type: 'playlist', playlist_id: 12 } ] @@ -1274,61 +1230,13 @@ describe('reorderPlaylistLibrary', () => { }) }) -describe('containsTempPlaylist', () => { - it('finds a temp', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } - ] - } - const ret = containsTempPlaylist(library) - expect(ret).toEqual(true) - }) - - it('finds a temp in a folder', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { - type: 'folder', - name: 'favorites', - contents: [ - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } - ] - }, - { type: 'playlist', playlist_id: 4 } - ] - } - const ret = containsTempPlaylist(library) - expect(ret).toEqual(true) - }) - - it('finds no temp', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'playlist', playlist_id: 3 } - ] - } - const ret = containsTempPlaylist(library) - expect(ret).toEqual(false) - }) -}) - describe('addFolderToLibrary', () => { it('Adds a new folder to the end of a playlist library and returns the result', () => { const library = { contents: [ { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } const folder = { @@ -1343,7 +1251,6 @@ describe('addFolderToLibrary', () => { { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' }, { id: 'fake-uuid', name: 'Foldero', @@ -1423,8 +1330,7 @@ describe('renamePlaylistFolderInLibrary', () => { { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, { type: 'folder', name: 'Foldero', id: 'fake-uuid', contents: [] }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } @@ -1443,8 +1349,7 @@ describe('renamePlaylistFolderInLibrary', () => { contents: [], type: 'folder' }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } expect(result).toEqual(expectedResult) @@ -1456,8 +1361,7 @@ describe('renamePlaylistFolderInLibrary', () => { { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, { type: 'folder', name: 'Foldero', id: 'fake-uuid', contents: [] }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } const result = renamePlaylistFolderInLibrary( @@ -1476,8 +1380,7 @@ describe('removePlaylistFolderInLibrary', () => { { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, { type: 'folder', name: 'Foldero', id: 'fake-uuid', contents: [] }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } @@ -1486,8 +1389,7 @@ describe('removePlaylistFolderInLibrary', () => { contents: [ { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } expect(result).toEqual(expectedResult) @@ -1505,7 +1407,6 @@ describe('removePlaylistFolderInLibrary', () => { contents: [ { type: 'playlist', playlist_id: 4 }, { type: 'playlist', playlist_id: 5 }, - { type: 'temp_playlist', playlist_id: 'ghji' }, { type: 'folder', name: 'Folderino', @@ -1514,8 +1415,7 @@ describe('removePlaylistFolderInLibrary', () => { } ] }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } const result = removePlaylistFolderInLibrary(library, 'fake-uuid') @@ -1525,10 +1425,8 @@ describe('removePlaylistFolderInLibrary', () => { { type: 'playlist', playlist_id: 2 }, { type: 'playlist', playlist_id: 4 }, { type: 'playlist', playlist_id: 5 }, - { type: 'temp_playlist', playlist_id: 'ghji' }, { type: 'folder', name: 'Folderino', id: 'fake-uuid-2', contents: [] }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } expect(result).toEqual(expectedResult) @@ -1540,8 +1438,7 @@ describe('removePlaylistFolderInLibrary', () => { { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, { type: 'folder', name: 'Foldero', id: 'fake-uuid', contents: [] }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } const result = removePlaylistFolderInLibrary( @@ -1562,10 +1459,7 @@ describe('addPlaylistToFolder', () => { type: 'folder', name: 'Foldero', id: 'fake-uuid', - contents: [ - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } - ] + contents: [{ type: 'playlist', playlist_id: 3 }] } ] } @@ -1581,8 +1475,7 @@ describe('addPlaylistToFolder', () => { id: 'fake-uuid', contents: [ { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } ] @@ -1599,10 +1492,7 @@ describe('addPlaylistToFolder', () => { type: 'folder', name: 'Foldero', id: 'fake-uuid', - contents: [ - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } - ] + contents: [{ type: 'playlist', playlist_id: 3 }] } ] } @@ -1620,10 +1510,7 @@ describe('addPlaylistToFolder', () => { type: 'folder', name: 'Foldero', id: 'fake-uuid', - contents: [ - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } - ] + contents: [{ type: 'playlist', playlist_id: 3 }] } ] } @@ -1652,10 +1539,7 @@ describe('addPlaylistToFolder', () => { type: 'folder', name: 'Foldero', id: 'fake-uuid', - contents: [ - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } - ] + contents: [{ type: 'playlist', playlist_id: 3 }] } ] } @@ -1670,8 +1554,7 @@ describe('addPlaylistToFolder', () => { id: 'fake-uuid', contents: [ { type: 'playlist', playlist_id: 2 }, - { type: 'playlist', playlist_id: 3 }, - { type: 'temp_playlist', playlist_id: 'asdf' } + { type: 'playlist', playlist_id: 3 } ] } ] @@ -1680,260 +1563,6 @@ describe('addPlaylistToFolder', () => { }) }) -describe('extractTempPlaylistsFromLibrary', () => { - it('returns all temp playlists in library', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'temp_playlist', playlist_id: 'e' }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: 'a' }, - { type: 'temp_playlist', playlist_id: 'b' }, - { type: 'playlist', playlist_id: 11 }, - { type: 'temp_playlist', playlist_id: 'c' }, - { type: 'temp_playlist', playlist_id: 'd' } - ] - } - ] - } - const ret = extractTempPlaylistsFromLibrary(library) - expect(ret).toEqual([ - { type: 'temp_playlist', playlist_id: 'e' }, - { type: 'temp_playlist', playlist_id: 'a' }, - { type: 'temp_playlist', playlist_id: 'b' }, - { type: 'temp_playlist', playlist_id: 'c' }, - { type: 'temp_playlist', playlist_id: 'd' } - ]) - }) - - it('can deal with empty libraries', () => { - const ret = extractTempPlaylistsFromLibrary({ - contents: [] - }) - expect(ret).toEqual([]) - - const ret2 = extractTempPlaylistsFromLibrary({}) - expect(ret2).toEqual([]) - }) - - it('returns empty array if no temp playlists in library', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'playlist', playlist_id: 11 } - ] - } - ] - } - const ret = extractTempPlaylistsFromLibrary(library) - expect(ret).toEqual([]) - }) -}) - -describe('replaceTempWithResolvedPlaylists', () => { - it('returns all temp playlists in library', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'temp_playlist', playlist_id: 'e' }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: 'a' }, - { type: 'temp_playlist', playlist_id: 'b' }, - { type: 'playlist', playlist_id: 11 }, - { type: 'temp_playlist', playlist_id: 'c' }, - { type: 'temp_playlist', playlist_id: 'd' } - ] - } - ] - } - const tempPlaylistIdToResolvedPlaylist = { - e: { type: 'playlist', playlist_id: 12 }, - a: { type: 'playlist', playlist_id: 13 }, - b: { type: 'playlist', playlist_id: 14 }, - c: { type: 'playlist', playlist_id: 15 }, - d: { type: 'playlist', playlist_id: 16 } - } - - const ret = replaceTempWithResolvedPlaylists( - library, - tempPlaylistIdToResolvedPlaylist - ) - expect(ret).toEqual({ - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'playlist', playlist_id: 12 }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'playlist', playlist_id: 13 }, - { type: 'playlist', playlist_id: 14 }, - { type: 'playlist', playlist_id: 11 }, - { type: 'playlist', playlist_id: 15 }, - { type: 'playlist', playlist_id: 16 } - ] - } - ] - }) - }) - - it('can deal with empty libraries', () => { - const ret = replaceTempWithResolvedPlaylists( - { - contents: [] - }, - {} - ) - expect(ret).toEqual({ - contents: [] - }) - - const ret2 = replaceTempWithResolvedPlaylists({}) - expect(ret2).toEqual({}) - }) - - it('can deal with empty folders', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'temp_playlist', playlist_id: 'e' }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: 'a' }, - { type: 'temp_playlist', playlist_id: 'b' }, - { type: 'playlist', playlist_id: 11 }, - { type: 'temp_playlist', playlist_id: 'c' }, - { type: 'temp_playlist', playlist_id: 'd' } - ] - }, - { type: 'folder', id: 'my id 2', name: 'Favorites 2', contents: [] } - ] - } - const tempPlaylistIdToResolvedPlaylist = { - e: { type: 'playlist', playlist_id: 12 }, - a: { type: 'playlist', playlist_id: 13 }, - b: { type: 'playlist', playlist_id: 14 }, - c: { type: 'playlist', playlist_id: 15 }, - d: { type: 'playlist', playlist_id: 16 } - } - - const ret = replaceTempWithResolvedPlaylists( - library, - tempPlaylistIdToResolvedPlaylist - ) - expect(ret).toEqual({ - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'playlist', playlist_id: 12 }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'playlist', playlist_id: 13 }, - { type: 'playlist', playlist_id: 14 }, - { type: 'playlist', playlist_id: 11 }, - { type: 'playlist', playlist_id: 15 }, - { type: 'playlist', playlist_id: 16 } - ] - }, - { type: 'folder', id: 'my id 2', name: 'Favorites 2', contents: [] } - ] - }) - }) - - it('can deal with missing temp playlist mapping', () => { - const library = { - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'temp_playlist', playlist_id: 'e' }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: 'a' }, - { type: 'temp_playlist', playlist_id: 'b' }, - { type: 'playlist', playlist_id: 11 }, - { type: 'temp_playlist', playlist_id: 'c' }, - { type: 'temp_playlist', playlist_id: 'd' } - ] - } - ] - } - const tempPlaylistIdToResolvedPlaylist = { - e: { type: 'playlist', playlist_id: 12 }, - b: { type: 'playlist', playlist_id: 14 }, - c: { type: 'playlist', playlist_id: 15 }, - d: { type: 'playlist', playlist_id: 16 } - } - - const ret = replaceTempWithResolvedPlaylists( - library, - tempPlaylistIdToResolvedPlaylist - ) - expect(ret).toEqual({ - contents: [ - { type: 'playlist', playlist_id: 1 }, - { type: 'playlist', playlist_id: 2 }, - { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'playlist', playlist_id: 12 }, - { - type: 'folder', - id: 'my id', - name: 'Favorites', - contents: [ - { type: 'playlist', playlist_id: 10 }, - { type: 'temp_playlist', playlist_id: 'a' }, - { type: 'playlist', playlist_id: 14 }, - { type: 'playlist', playlist_id: 11 }, - { type: 'playlist', playlist_id: 15 }, - { type: 'playlist', playlist_id: 16 } - ] - } - ] - }) - }) -}) - describe('getPlaylistsNotInLibrary', () => { it('returns the playlists that are not already in the library', () => { const library = { @@ -1941,15 +1570,13 @@ describe('getPlaylistsNotInLibrary', () => { { type: 'playlist', playlist_id: 1 }, { type: 'playlist', playlist_id: 2 }, { type: 'explore_playlist', playlist_id: 'Heavy Rotation' }, - { type: 'temp_playlist', playlist_id: 'e' }, { type: 'folder', id: 'my id', name: 'Favorites', contents: [ { type: 'playlist', playlist_id: 10 }, - { type: 'playlist', playlist_id: 11 }, - { type: 'temp_playlist', playlist_id: 'd' } + { type: 'playlist', playlist_id: 11 } ] } ] diff --git a/packages/common/src/store/playlist-library/helpers.ts b/packages/common/src/store/playlist-library/helpers.ts index 2e44268c0d..543daa3db5 100644 --- a/packages/common/src/store/playlist-library/helpers.ts +++ b/packages/common/src/store/playlist-library/helpers.ts @@ -1,5 +1,4 @@ -import { isEmpty } from 'lodash' - +import { Nullable } from 'utils/typeUtils' import { uuid } from 'utils/uid' import { ID } from '../../models/Identifiers' @@ -34,7 +33,6 @@ export const findInPlaylistLibrary = ( } case 'playlist': case 'explore_playlist': - case 'temp_playlist': if (item.playlist_id === playlistId) return item break } @@ -69,7 +67,6 @@ export const findIndexInPlaylistLibrary = ( } case 'playlist': case 'explore_playlist': - case 'temp_playlist': if (item.playlist_id === entityId) return i break } @@ -118,7 +115,6 @@ export const removeFromPlaylistLibrary = ( } case 'playlist': case 'explore_playlist': - case 'temp_playlist': if (item.playlist_id === entityId) { removed = item newItem = null @@ -152,7 +148,7 @@ export const constructPlaylistFolder = ( const playlistIdToPlaylistLibraryIdentifier = ( playlistId: ID | SmartCollectionVariant | string -): PlaylistLibraryIdentifier => { +): Nullable => { if (typeof playlistId === 'number') { return { type: 'playlist', @@ -165,13 +161,8 @@ const playlistIdToPlaylistLibraryIdentifier = ( type: 'explore_playlist', playlist_id: playlistId as SmartCollectionVariant } - } else { - // This is a temp ID which requires special attention - return { - type: 'temp_playlist', - playlist_id: playlistId - } } + return null } /** @@ -267,7 +258,7 @@ export const renamePlaylistFolderInLibrary = ( /** * Removes folder with given id from the library. - * Any playlists or temporary playlists in the deleted + * Any playlists in the deleted * folder are moved out of the folder. * Note that this assumes that folders cannot be nested within one another. * If we enable nesting folders in the future, this function must be updated. @@ -344,7 +335,6 @@ export const removePlaylistLibraryDuplicates = ( } case 'playlist': case 'explore_playlist': - case 'temp_playlist': // If we've seen this playlist already, don't include it in our final result. if (ids.has(`${item.playlist_id}`)) { break @@ -393,6 +383,8 @@ export const reorderPlaylistLibrary = ( const newContents = [...newLibrary.contents] + if (!entry) return { ...library, contents: newContents } + let index: number | number[] // We are dropping to the top if (droppingId === -1) { @@ -428,33 +420,6 @@ export const reorderPlaylistLibrary = ( } } -/** - * Determines whether or not a library contains a temp playlist - * @param library - * @returns boolean - */ -export const containsTempPlaylist = ( - library: PlaylistLibrary | PlaylistLibraryFolder -): boolean => { - if (!library.contents) return false - - // Simple DFS (this likely is very small, so this is fine) - for (const item of library.contents) { - switch (item.type) { - case 'folder': { - const contains = containsTempPlaylist(item) - if (contains) return contains - break - } - case 'temp_playlist': - return true - default: - break - } - } - return false -} - /** * Determines whether or not a playlist or folder is inside a folder * @param library @@ -468,56 +433,6 @@ export const isInsideFolder = ( return Array.isArray(findIndexInPlaylistLibrary(library, id)) } -/** - * Takes a library and returns a list of all temporary playlists from that library - * @param library - * @returns PlaylistLibraryIdentifier[] - */ -export const extractTempPlaylistsFromLibrary = ( - library: PlaylistLibrary | PlaylistLibraryFolder -): PlaylistLibraryIdentifier[] => { - if (isEmpty(library.contents)) return [] - return library.contents.reduce((prevResult, nextContent) => { - if (nextContent.type === 'folder') { - return prevResult.concat(extractTempPlaylistsFromLibrary(nextContent)) - } else if (nextContent.type === 'temp_playlist') { - return prevResult.concat(nextContent) - } else { - return prevResult - } - }, [] as PlaylistLibraryIdentifier[]) -} - -/** - * Takes a library and mapping of temporary playlist ids to their resolved - * playlist identifiers, then returns the library (does not mutate original) - * with temporary playlists replaced by their resolved playlist identifiers. - * @param library - * @param tempPlaylistIdToResolvedPlaylist object that maps temporary playlist ids to their resolved playlist identifiers - * @returns PlaylistLibrary | PlaylistLibraryFolder - */ -export const replaceTempWithResolvedPlaylists = < - T extends PlaylistLibrary | PlaylistLibraryFolder ->( - library: T, - tempPlaylistIdToResolvedPlaylist: Record -): T => { - if (isEmpty(library.contents)) return library - const newContents = library.contents.map((c) => { - if (c.type === 'folder') { - return replaceTempWithResolvedPlaylists( - c, - tempPlaylistIdToResolvedPlaylist - ) - } else if (c.type === 'temp_playlist') { - return tempPlaylistIdToResolvedPlaylist[c.playlist_id] ?? c - } else { - return c - } - }) - return { ...library, contents: newContents } -} - /* Returns playlists in `playlists` that are not in the given playlist library `library`. */ export const getPlaylistsNotInLibrary = ( library: PlaylistLibrary | null, @@ -530,7 +445,7 @@ export const getPlaylistsNotInLibrary = ( libraryContentsLevel: PlaylistLibrary['contents'] ) => { libraryContentsLevel.forEach((content) => { - if (content.type === 'temp_playlist' || content.type === 'playlist') { + if (content.type === 'playlist') { const playlist = playlists[Number(content.playlist_id)] if (playlist) { delete result[Number(content.playlist_id)] diff --git a/packages/web/src/common/store/playlist-library/sagas.ts b/packages/web/src/common/store/playlist-library/sagas.ts index 23b91b6741..75045d0617 100644 --- a/packages/web/src/common/store/playlist-library/sagas.ts +++ b/packages/web/src/common/store/playlist-library/sagas.ts @@ -1,28 +1,15 @@ import { Kind, PlaylistIdentifier, - PlaylistLibraryFolder, - PlaylistLibraryIdentifier, - makeKindId, accountSelectors, AccountCollection, cacheActions, - waitForValue, playlistLibraryHelpers, playlistLibraryActions, PlaylistLibraryID } from '@audius/common' -import { - all, - call, - fork, - put, - select, - takeEvery, - takeLatest -} from 'typed-redux-saga' +import { fork, put, select, takeEvery } from 'typed-redux-saga' -import { getResult } from 'common/store/confirmer/selectors' import { updateProfileAsync } from 'common/store/profile/sagas' import { waitForWrite } from 'utils/sagaHelpers' @@ -31,46 +18,14 @@ import { watchReorderLibrarySaga } from './watchReorderLibrarySaga' const { update } = playlistLibraryActions const { - containsTempPlaylist, - extractTempPlaylistsFromLibrary, getPlaylistsNotInLibrary, removePlaylistLibraryDuplicates, - replaceTempWithResolvedPlaylists, removeFromPlaylistLibrary } = playlistLibraryHelpers const { getAccountNavigationPlaylists, getAccountUser, getPlaylistLibrary } = accountSelectors -const TEMP_PLAYLIST_UPDATE_HELPER = 'TEMP_PLAYLIST_UPDATE_HELPER' - -/** - * Given a temp playlist, resolves it to a proper playlist - * @param playlist - * @returns a playlist library identifier - */ -function* resolveTempPlaylists( - playlist: PlaylistLibraryIdentifier | PlaylistLibraryFolder -) { - if (playlist.type === 'temp_playlist') { - const { playlist_id } = yield* call( - waitForValue, - getResult, - { - uid: makeKindId(Kind.COLLECTIONS, playlist.playlist_id), - index: 0 - }, - // The playlist has been created - (res) => Object.keys(res).length > 0 - ) - return { - type: 'playlist', - playlist_id - } - } - return playlist -} - function* watchUpdatePlaylistLibrary() { yield* takeEvery( update.type, @@ -92,62 +47,7 @@ function* watchUpdatePlaylistLibrary() { ]) ) - const containsTemps = containsTempPlaylist(playlistLibrary) - if (containsTemps) { - // Deal with temp playlists - // If there's a temp playlist, write to the cache, but dispatch - // to a helper to watch for the update. - yield* put({ - type: TEMP_PLAYLIST_UPDATE_HELPER, - payload: { playlistLibrary } - }) - } else { - // Otherwise, just write the profile update - yield* fork(updateProfileAsync, { metadata: account }) - } - } - ) -} - -/** - * Helper to watch for updates to the library with temp playlits in it. - * Here we intentionally take latest so that we only do one write to the - * backend once we've resolved the temp playlist ids to actual ids - */ -function* watchUpdatePlaylistLibraryWithTempPlaylist() { - yield* takeLatest( - TEMP_PLAYLIST_UPDATE_HELPER, - function* makeUpdate(action: ReturnType) { - yield* waitForWrite() - const { playlistLibrary: rawPlaylistLibrary } = action.payload - const playlistLibrary = - removePlaylistLibraryDuplicates(rawPlaylistLibrary) - - const account = yield* select(getAccountUser) - if (!account) return - - // Map over playlist library contents and resolve each temp id playlist - // to one with an actual id. Once we have the actual id, we can proceed - // with writing the library to the user metadata (profile update) - const tempPlaylists = extractTempPlaylistsFromLibrary(playlistLibrary) - const resolvedPlaylists = (yield* all( - tempPlaylists.map((playlist) => call(resolveTempPlaylists, playlist)) - )) as PlaylistLibraryIdentifier[] - const tempPlaylistIdToResolvedPlaylist = tempPlaylists.reduce( - (result, nextTempPlaylist, index) => ({ - ...result, - [nextTempPlaylist.playlist_id]: resolvedPlaylists[index] - }), - {} as { [key: string]: PlaylistLibraryIdentifier } - ) - - playlistLibrary.contents = replaceTempWithResolvedPlaylists( - playlistLibrary, - tempPlaylistIdToResolvedPlaylist - ).contents - account.playlist_library = playlistLibrary - // Update playlist library on chain via an account profile update - yield* call(updateProfileAsync, { metadata: account }) + yield* fork(updateProfileAsync, { metadata: account }) } ) } @@ -188,7 +88,6 @@ export function* removePlaylistFromLibrary(id: PlaylistLibraryID) { export default function sagas() { const sagas = [ watchUpdatePlaylistLibrary, - watchUpdatePlaylistLibraryWithTempPlaylist, watchReorderLibrarySaga, watchAddToFolderSaga ] diff --git a/packages/web/src/components/nav/desktop/PlaylistLibrary/PlaylistLibrary.tsx b/packages/web/src/components/nav/desktop/PlaylistLibrary/PlaylistLibrary.tsx index 32b4d6d73d..15571a0306 100644 --- a/packages/web/src/components/nav/desktop/PlaylistLibrary/PlaylistLibrary.tsx +++ b/packages/web/src/components/nav/desktop/PlaylistLibrary/PlaylistLibrary.tsx @@ -25,6 +25,7 @@ import { EmptyLibraryNavLink } from './EmptyLibraryNavLink' import styles from './PlaylistLibrary.module.css' import { PlaylistLibraryNavItem, keyExtractor } from './PlaylistLibraryNavItem' import { useAddAudioNftPlaylistToLibrary } from './useAddAudioNftPlaylistToLibrary' +import { useSanitizePlaylistLibrary } from './useSanitizePlaylistLibrary' const { getPlaylistLibrary, getHasAccount } = accountSelectors const { saveCollection } = collectionsSocialActions @@ -51,6 +52,7 @@ export const PlaylistLibrary = (props: PlaylistLibraryProps) => { const record = useRecord() useAddAudioNftPlaylistToLibrary() + useSanitizePlaylistLibrary() const handleDrop = useCallback( (collectionId: number) => { diff --git a/packages/web/src/components/nav/desktop/PlaylistLibrary/useSanitizePlaylistLibrary.ts b/packages/web/src/components/nav/desktop/PlaylistLibrary/useSanitizePlaylistLibrary.ts new file mode 100644 index 0000000000..bd1ef5d171 --- /dev/null +++ b/packages/web/src/components/nav/desktop/PlaylistLibrary/useSanitizePlaylistLibrary.ts @@ -0,0 +1,39 @@ +import { useEffect } from 'react' + +import { + PlaylistLibraryFolder, + accountSelectors, + playlistLibraryActions +} from '@audius/common' +import { useDispatch } from 'react-redux' + +import { useSelector } from 'utils/reducer' +const { getPlaylistLibrary } = accountSelectors +const { update: updatePlaylistLibrary } = playlistLibraryActions + +export const useSanitizePlaylistLibrary = () => { + const library = useSelector(getPlaylistLibrary) + const dispatch = useDispatch() + + useEffect(() => { + if (!library) return + let hasIssue = false + + const newLibrary = { ...library } + + // checks for issue where folders are incorrectly represented as playlists + newLibrary.contents = newLibrary.contents.map((content) => { + if ('contents' in content && content.type !== 'folder') { + hasIssue = true + const { id, name, contents } = content as PlaylistLibraryFolder + return { id, name, contents, type: 'folder' } + } + return content + }) + + if (hasIssue) { + dispatch(updatePlaylistLibrary({ playlistLibrary: newLibrary })) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [!library, dispatch]) +}