New: Header search for quick manual search

pull/40/head
Qstick 3 years ago
parent 867b61e4aa
commit 82eb6495d4

@ -1,4 +1,3 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Autosuggest from 'react-autosuggest';
@ -7,7 +6,6 @@ import keyboardShortcuts, { shortcuts } from 'Components/keyboardShortcuts';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import FuseWorker from './fuse.worker';
import MovieSearchResult from './MovieSearchResult';
import styles from './MovieSearchInput.css';
@ -22,7 +20,6 @@ class MovieSearchInput extends Component {
super(props, context);
this._autosuggest = null;
this._worker = null;
this.state = {
value: '',
@ -42,15 +39,6 @@ class MovieSearchInput extends Component {
}
}
getWorker() {
if (!this._worker) {
this._worker = new FuseWorker();
this._worker.addEventListener('message', this.onSuggestionsReceived, false);
}
return this._worker;
}
//
// Control
@ -105,11 +93,6 @@ class MovieSearchInput extends Component {
);
}
goToMovie(item) {
this.setState({ value: '' });
this.props.onGoToMovie(item.item.titleSlug);
}
reset() {
this.setState({
value: '',
@ -149,8 +132,7 @@ class MovieSearchInput extends Component {
} = this.state;
const {
highlightedSectionIndex,
highlightedSuggestionIndex
highlightedSectionIndex
} = this._autosuggest.state;
if (!suggestions.length || highlightedSectionIndex) {
@ -161,15 +143,6 @@ class MovieSearchInput extends Component {
return;
}
// If an suggestion is not selected go to the first movie,
// otherwise go to the selected movie.
if (highlightedSuggestionIndex == null) {
this.goToMovie(suggestions[0]);
} else {
this.goToMovie(suggestions[highlightedSuggestionIndex]);
}
this._autosuggest.input.blur();
this.reset();
}
@ -178,71 +151,6 @@ class MovieSearchInput extends Component {
this.reset();
}
onSuggestionsFetchRequested = ({ value }) => {
if (!this.state.loading) {
this.setState({
loading: true
});
}
this.requestSuggestions(value);
};
requestSuggestions = _.debounce((value) => {
if (!this.state.loading) {
return;
}
const requestLoading = this.state.requestLoading;
this.setState({
requestValue: value,
requestLoading: true
});
if (!requestLoading) {
const payload = {
value,
movies: this.props.movies
};
this.getWorker().postMessage(payload);
}
}, 250);
onSuggestionsReceived = (message) => {
const {
value,
suggestions
} = message.data;
if (!this.state.loading) {
this.setState({
requestValue: null,
requestLoading: false
});
} else if (value === this.state.requestValue) {
this.setState({
suggestions,
requestValue: null,
requestLoading: false,
loading: false
});
} else {
this.setState({
suggestions,
requestLoading: true
});
const payload = {
value: this.state.requestValue,
movies: this.props.movies
};
this.getWorker().postMessage(payload);
}
}
onSuggestionsClearRequested = () => {
this.setState({
suggestions: [],
@ -253,8 +161,6 @@ class MovieSearchInput extends Component {
onSuggestionSelected = (event, { suggestion }) => {
if (suggestion.type === ADD_NEW_TYPE) {
this.props.onGoToAddNewMovie(this.state.value);
} else {
this.goToMovie(suggestion);
}
}
@ -263,23 +169,13 @@ class MovieSearchInput extends Component {
render() {
const {
value,
loading,
suggestions
value
} = this.state;
const suggestionGroups = [];
if (suggestions.length || loading) {
suggestionGroups.push({
title: translate('ExistingMovies'),
loading,
suggestions
});
}
suggestionGroups.push({
title: translate('AddNewMovie'),
title: translate('SearchIndexers'),
suggestions: [
{
type: ADD_NEW_TYPE,
@ -328,8 +224,6 @@ class MovieSearchInput extends Component {
getSuggestionValue={this.getSuggestionValue}
renderSuggestion={this.renderSuggestion}
onSuggestionSelected={this.onSuggestionSelected}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
/>
</div>
);
@ -337,8 +231,6 @@ class MovieSearchInput extends Component {
}
MovieSearchInput.propTypes = {
movies: PropTypes.arrayOf(PropTypes.object).isRequired,
onGoToMovie: PropTypes.func.isRequired,
onGoToAddNewMovie: PropTypes.func.isRequired,
bindShortcut: PropTypes.func.isRequired
};

@ -1,6 +1,7 @@
import { push } from 'connected-react-router';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { setSearchDefault } from 'Store/Actions/releaseActions';
import createAllIndexersSelector from 'Store/Selectors/createAllIndexersSelector';
import createDeepEqualSelector from 'Store/Selectors/createDeepEqualSelector';
import createTagsSelector from 'Store/Selectors/createTagsSelector';
@ -58,12 +59,9 @@ function createMapStateToProps() {
function createMapDispatchToProps(dispatch, props) {
return {
onGoToMovie(titleSlug) {
dispatch(push(`${window.Prowlarr.urlBase}/movie/${titleSlug}`));
},
onGoToAddNewMovie(query) {
dispatch(push(`${window.Prowlarr.urlBase}/add/new?term=${encodeURIComponent(query)}`));
dispatch(setSearchDefault({ searchQuery: query, searchIndexerIds: [-1, -2] }));
dispatch(push(`${window.Prowlarr.urlBase}search`));
}
};
}

@ -1,68 +0,0 @@
import Fuse from 'fuse.js';
const fuseOptions = {
shouldSort: true,
includeMatches: true,
ignoreLocation: true,
threshold: 0.3,
minMatchCharLength: 1,
keys: [
'title',
'alternateTitles.title',
'tags.label'
]
};
function getSuggestions(movies, value) {
const limit = 10;
let suggestions = [];
if (value.length === 1) {
for (let i = 0; i < movies.length; i++) {
const s = movies[i];
if (s.firstCharacter === value.toLowerCase()) {
suggestions.push({
item: movies[i],
indices: [
[0, 0]
],
matches: [
{
value: s.title,
key: 'title'
}
],
arrayIndex: 0
});
if (suggestions.length > limit) {
break;
}
}
}
} else {
const fuse = new Fuse(movies, fuseOptions);
suggestions = fuse.search(value, { limit });
}
return suggestions;
}
onmessage = function(e) {
if (!e) {
return;
}
const {
movies,
value
} = e.data;
const suggestions = getSuggestions(movies, value);
const results = {
value,
suggestions
};
self.postMessage(results);
};

@ -321,6 +321,7 @@
"TestAllClients": "Test All Clients",
"Time": "Time",
"Title": "Title",
"SearchIndexers": "Search all Indexers",
"Today": "Today",
"Tomorrow": "Tomorrow",
"Type": "Type",

Loading…
Cancel
Save