import _ from 'lodash'; import $ from 'jquery'; import { batchActions } from 'redux-batched-actions'; import getNewSeries from 'Utilities/Series/getNewSeries'; import * as types from './actionTypes'; import { set, updateItem, removeItem } from './baseActions'; import { startLookupArtist } from './importArtistActions'; import { fetchRootFolders } from './rootFolderActions'; const section = 'importArtist'; let concurrentLookups = 0; const importArtistActionHandlers = { [types.QUEUE_LOOKUP_ARTIST]: function(payload) { return function(dispatch, getState) { const { name, path, term } = payload; const state = getState().importArtist; const item = _.find(state.items, { id: name }) || { id: name, term, path, isFetching: false, isPopulated: false, error: null }; dispatch(updateItem({ section, ...item, term, queued: true, items: [] })); if (term && term.length > 2) { dispatch(startLookupArtist()); } }; }, [types.START_LOOKUP_ARTIST]: function(payload) { return function(dispatch, getState) { if (concurrentLookups >= 1) { return; } const state = getState().importArtist; const queued = _.find(state.items, { queued: true }); if (!queued) { return; } concurrentLookups++; dispatch(updateItem({ section, id: queued.id, isFetching: true })); const promise = $.ajax({ url: '/artist/lookup', data: { term: queued.term } }); promise.done((data) => { dispatch(updateItem({ section, id: queued.id, isFetching: false, isPopulated: true, error: null, items: data, queued: false, selectedArtist: queued.selectedArtist || data[0] })); }); promise.fail((xhr) => { dispatch(updateItem({ section, id: queued.id, isFetching: false, isPopulated: false, error: xhr, queued: false })); }); promise.always(() => { concurrentLookups--; dispatch(startLookupArtist()); }); }; }, [types.IMPORT_ARTIST]: function(payload) { return function(dispatch, getState) { dispatch(set({ section, isImporting: true })); const ids = payload.ids; const items = getState().importArtist.items; const addedIds = []; const allNewSeries = ids.reduce((acc, id) => { const item = _.find(items, { id }); const selectedArtist = item.selectedArtist; // Make sure we have a selected artist and // the same artist hasn't been added yet. if (selectedArtist && !_.some(acc, { foreignArtistId: selectedArtist.foreignArtistId })) { const newSeries = getNewSeries(_.cloneDeep(selectedArtist), item); newSeries.path = item.path; addedIds.push(id); acc.push(newSeries); } return acc; }, []); const promise = $.ajax({ url: '/artist/import', method: 'POST', contentType: 'application/json', data: JSON.stringify(allNewSeries) }); promise.done((data) => { dispatch(batchActions([ set({ section, isImporting: false, isImported: true }), ...data.map((artist) => updateItem({ section: 'artist', ...artist })), ...addedIds.map((id) => removeItem({ section, id })) ])); dispatch(fetchRootFolders()); }); promise.fail((xhr) => { dispatch(batchActions( set({ section, isImporting: false, isImported: true }), addedIds.map((id) => updateItem({ section, id, importError: xhr })) )); }); }; } }; export default importArtistActionHandlers;