diff --git a/frontend/src/Store/Actions/Creators/createHandleActions.js b/frontend/src/Store/Actions/Creators/createHandleActions.js index 0883f8e08..744186483 100644 --- a/frontend/src/Store/Actions/Creators/createHandleActions.js +++ b/frontend/src/Store/Actions/Creators/createHandleActions.js @@ -65,18 +65,31 @@ export default function createHandleActions(handlers, defaultState, section) { if (section === baseSection) { const newState = getSectionState(state, payloadSection); const items = newState.items; - const index = _.findIndex(items, { id: payload.id }); + + if (!newState.itemMap) { + newState.itemMap = _.zipObject(_.map(items, 'id'), _.range(items.length)); + } + + const index = payload.id in newState.itemMap ? newState.itemMap[payload.id] : -1; newState.items = [...items]; // TODO: Move adding to it's own reducer if (index >= 0) { const item = items[index]; + const newItem = { ...item, ...otherProps }; - newState.items.splice(index, 1, { ...item, ...otherProps }); + // if the item to update is equal to existing, then don't actually update + // to prevent costly reselections + if (_.isEqual(item, newItem)) { + return state; + } + + newState.items.splice(index, 1, newItem); } else if (!updateOnly) { - newState.items.push({ ...otherProps }); - newState.itemMap = _.zipObject(_.map(newState.items, 'id'), _.range(newState.items.length)); + const newIndex = newState.items.push({ ...otherProps }) - 1; + + newState.itemMap[payload.id] = newIndex; } return updateSectionState(state, payloadSection, newState); diff --git a/frontend/src/Store/Selectors/createArtistClientSideCollectionItemsSelector.js b/frontend/src/Store/Selectors/createArtistClientSideCollectionItemsSelector.js index 38300bd9d..0f443612b 100644 --- a/frontend/src/Store/Selectors/createArtistClientSideCollectionItemsSelector.js +++ b/frontend/src/Store/Selectors/createArtistClientSideCollectionItemsSelector.js @@ -1,6 +1,6 @@ -import { createSelector } from 'reselect'; -import createDeepEqualSelector from './createDeepEqualSelector'; +import { createSelector, createSelectorCreator, defaultMemoize } from 'reselect'; import createClientSideCollectionSelector from './createClientSideCollectionSelector'; +import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder'; function createUnoptimizedSelector(uiSection) { return createSelector( @@ -26,8 +26,17 @@ function createUnoptimizedSelector(uiSection) { ); } +function artistListEqual(a, b) { + return hasDifferentItemsOrOrder(a, b); +} + +const createArtistEqualSelector = createSelectorCreator( + defaultMemoize, + artistListEqual +); + function createArtistClientSideCollectionItemsSelector(uiSection) { - return createDeepEqualSelector( + return createArtistEqualSelector( createUnoptimizedSelector(uiSection), (artist) => artist ); diff --git a/src/Lidarr.Api.V1/Artist/ArtistResource.cs b/src/Lidarr.Api.V1/Artist/ArtistResource.cs index d80ffd6b0..52e19540b 100644 --- a/src/Lidarr.Api.V1/Artist/ArtistResource.cs +++ b/src/Lidarr.Api.V1/Artist/ArtistResource.cs @@ -20,8 +20,6 @@ namespace Lidarr.Api.V1.Artist public bool Ended => Status == ArtistStatusType.Ended; - public DateTime? LastInfoSync { get; set; } - public string ArtistName { get; set; } public string ForeignArtistId { get; set; } public string MBId { get; set; } @@ -96,8 +94,6 @@ namespace Lidarr.Api.V1.Artist AlbumFolder = model.AlbumFolder, Monitored = model.Monitored, - LastInfoSync = model.LastInfoSync, - CleanName = model.CleanName, ForeignArtistId = model.Metadata.Value.ForeignArtistId, @@ -146,7 +142,6 @@ namespace Lidarr.Api.V1.Artist AlbumFolder = resource.AlbumFolder, Monitored = resource.Monitored, - LastInfoSync = resource.LastInfoSync, CleanName = resource.CleanName, RootFolderPath = resource.RootFolderPath,