lbry-desktop/ui/redux/reducers/search.js
2020-07-27 16:37:36 -04:00

118 lines
3.8 KiB
JavaScript

// @flow
import * as ACTIONS from 'constants/action_types';
import { handleActions } from 'util/redux-utils';
import { SEARCH_OPTIONS } from 'constants/search';
const defaultState = {
isActive: false, // does the user have any typed text in the search input
focused: false, // is the search input focused
searchQuery: '', // needs to be an empty string for input focusing
options: {
[SEARCH_OPTIONS.RESULT_COUNT]: 30,
[SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS,
[SEARCH_OPTIONS.MEDIA_AUDIO]: true,
[SEARCH_OPTIONS.MEDIA_VIDEO]: true,
[SEARCH_OPTIONS.MEDIA_TEXT]: true,
[SEARCH_OPTIONS.MEDIA_IMAGE]: true,
[SEARCH_OPTIONS.MEDIA_APPLICATION]: true,
},
suggestions: {},
urisByQuery: {},
resolvedResultsByQuery: {},
resolvedResultsByQueryLastPageReached: {},
};
export default handleActions(
{
[ACTIONS.SEARCH_START]: (state: SearchState): SearchState => ({
...state,
searching: true,
}),
[ACTIONS.SEARCH_SUCCESS]: (state: SearchState, action: SearchSuccess): SearchState => {
const { query, uris } = action.data;
return {
...state,
searching: false,
urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }),
};
},
[ACTIONS.SEARCH_FAIL]: (state: SearchState): SearchState => ({
...state,
searching: false,
}),
[ACTIONS.RESOLVED_SEARCH_START]: (state: SearchState): SearchState => ({
...state,
searching: true,
}),
[ACTIONS.RESOLVED_SEARCH_SUCCESS]: (state: SearchState, action: ResolvedSearchSuccess): SearchState => {
const resolvedResultsByQuery = Object.assign({}, state.resolvedResultsByQuery);
const resolvedResultsByQueryLastPageReached = Object.assign({}, state.resolvedResultsByQueryLastPageReached);
const { append, query, results, pageSize } = action.data;
if (append) {
// todo: check for duplicates when concatenating?
resolvedResultsByQuery[query] =
resolvedResultsByQuery[query] && resolvedResultsByQuery[query].length
? resolvedResultsByQuery[query].concat(results)
: results;
} else {
resolvedResultsByQuery[query] = results;
}
// the returned number of urls is less than the page size, so we're on the last page
resolvedResultsByQueryLastPageReached[query] = results.length < pageSize;
return {
...state,
searching: false,
resolvedResultsByQuery,
resolvedResultsByQueryLastPageReached,
};
},
[ACTIONS.RESOLVED_SEARCH_FAIL]: (state: SearchState): SearchState => ({
...state,
searching: false,
}),
[ACTIONS.UPDATE_SEARCH_QUERY]: (state: SearchState, action: UpdateSearchQuery): SearchState => ({
...state,
searchQuery: action.data.query,
isActive: true,
}),
[ACTIONS.UPDATE_SEARCH_SUGGESTIONS]: (state: SearchState, action: UpdateSearchSuggestions): SearchState => ({
...state,
suggestions: {
...state.suggestions,
[action.data.query]: action.data.suggestions,
},
}),
// sets isActive to false so the uri will be populated correctly if the
// user is on a file page. The search query will still be present on any
// other page
[ACTIONS.SEARCH_FOCUS]: (state: SearchState): SearchState => ({
...state,
focused: true,
}),
[ACTIONS.SEARCH_BLUR]: (state: SearchState): SearchState => ({
...state,
focused: false,
}),
[ACTIONS.UPDATE_SEARCH_OPTIONS]: (state: SearchState, action: UpdateSearchOptions): SearchState => {
const { options: oldOptions } = state;
const newOptions = action.data;
const options = { ...oldOptions, ...newOptions };
return {
...state,
options,
};
},
},
defaultState
);